#include <iostream>
#include <memory>
#include <utility>
#include <vector>
struct Shape
{
virtual void draw() = 0;
};
template<typename T>
struct ShapeAdapter:
Shape
{
template<typename... Args>
ShapeAdapter(Args&&... args):
data(std::forward<Args>(args)...)
{}
virtual void draw() override
{
data.draw();
}
T data;
};
struct ShapeCollection
{
template<typename T, typename... Args>
void add(Args&&... args)
{
auto ptr = new ShapeAdapter<T>{ std::forward<Args>(args)... };
shapes.emplace_back(ptr);
}
void draw()
{
for (auto&& shape: shapes)
{
shape->draw();
}
}
std::vector<std::unique_ptr<Shape>> shapes;
};
struct Circle
{
Circle(int x, int y, int radius) {}
void draw()
{
std::cout << "draw circle\n";
}
};
struct Square
{
Square(int x, int y, int height, int length) {}
void draw()
{
std::cout << "draw square\n";
}
};
int main()
{
ShapeCollection collection;
collection.add<Circle>(2, 3, 5);
collection.add<Square>(1, 2, 8, 9);
collection.draw();
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bWVtb3J5PgojaW5jbHVkZSA8dXRpbGl0eT4KI2luY2x1ZGUgPHZlY3Rvcj4KCnN0cnVjdCBTaGFwZQp7CiAgICB2aXJ0dWFsIHZvaWQgZHJhdygpID0gMDsKfTsKCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CnN0cnVjdCBTaGFwZUFkYXB0ZXI6CiAgICBTaGFwZQp7Cgl0ZW1wbGF0ZTx0eXBlbmFtZS4uLiBBcmdzPgogICAgU2hhcGVBZGFwdGVyKEFyZ3MmJi4uLiBhcmdzKToKICAgICAgICBkYXRhKHN0ZDo6Zm9yd2FyZDxBcmdzPihhcmdzKS4uLikKICAgIHt9CiAgICAKICAgIHZpcnR1YWwgdm9pZCBkcmF3KCkgb3ZlcnJpZGUKICAgIHsKICAgICAgICBkYXRhLmRyYXcoKTsKICAgIH0KICAgIAogICAgVCBkYXRhOwp9OwoKc3RydWN0IFNoYXBlQ29sbGVjdGlvbgp7CiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBULCB0eXBlbmFtZS4uLiBBcmdzPgogICAgdm9pZCBhZGQoQXJncyYmLi4uIGFyZ3MpCiAgICB7CiAgICAgICAgYXV0byBwdHIgPSBuZXcgU2hhcGVBZGFwdGVyPFQ+eyBzdGQ6OmZvcndhcmQ8QXJncz4oYXJncykuLi4gfTsKICAgICAgICBzaGFwZXMuZW1wbGFjZV9iYWNrKHB0cik7CiAgICB9CiAgICAKICAgIHZvaWQgZHJhdygpCiAgICB7CiAgICAJZm9yIChhdXRvJiYgc2hhcGU6IHNoYXBlcykKICAgIAl7CiAgICAJCXNoYXBlLT5kcmF3KCk7CiAgICAJfQogICAgfQogICAgCiAgICBzdGQ6OnZlY3RvcjxzdGQ6OnVuaXF1ZV9wdHI8U2hhcGU+PiBzaGFwZXM7ICAKfTsKCgpzdHJ1Y3QgQ2lyY2xlCnsKCUNpcmNsZShpbnQgeCwgaW50IHksIGludCByYWRpdXMpIHt9CgkKCXZvaWQgZHJhdygpCgl7CgkJc3RkOjpjb3V0IDw8ICJkcmF3IGNpcmNsZVxuIjsKCX0KfTsKCnN0cnVjdCBTcXVhcmUKewoJU3F1YXJlKGludCB4LCBpbnQgeSwgaW50IGhlaWdodCwgaW50IGxlbmd0aCkge30KCQoJdm9pZCBkcmF3KCkKCXsKCQlzdGQ6OmNvdXQgPDwgImRyYXcgc3F1YXJlXG4iOwoJfQp9OwoKCmludCBtYWluKCkKewoJU2hhcGVDb2xsZWN0aW9uIGNvbGxlY3Rpb247CgkKCWNvbGxlY3Rpb24uYWRkPENpcmNsZT4oMiwgMywgNSk7Cgljb2xsZWN0aW9uLmFkZDxTcXVhcmU+KDEsIDIsIDgsIDkpOwoJCgljb2xsZWN0aW9uLmRyYXcoKTsgCn0K