// From
// http://en.wikipedia.org/wiki/Composite_pattern

#include <vector>
#include <iostream> // std::cout
#include <memory> // std::auto_ptr
#include <algorithm> // std::for_each
#include <functional> // std::mem_fun
using namespace std;

class Shape
{
public:
    virtual void print() const = 0;
    virtual ~Shape() {}
};

class ShapeEllipse : public Shape
{
public:
    void print() const {
        cout << " ShapeEllipse " << hex << this << '\n';
    }
};

class ShapeComposite : public Shape
{
public:
    void print() const {
        // for each element in shapeList_, call the print member function
        cout << "ShapeComposite " << hex << this << "{\n";
        for_each(shapeList_.begin(), shapeList_.end(), mem_fun(&Shape::print));
        cout << "}\n";
    }

    void add(Shape *aShape) {
        shapeList_.push_back(aShape);
    }

private:
    vector<Shape*>  shapeList_;
};

int main()
{
    // Initialize four ellipses
    const auto_ptr<ShapeEllipse> ellipse1(new ShapeEllipse());
    const auto_ptr<ShapeEllipse> ellipse2(new ShapeEllipse());
    const auto_ptr<ShapeEllipse> ellipse3(new ShapeEllipse());
    const auto_ptr<ShapeEllipse> ellipse4(new ShapeEllipse());

    // Initialize three composite shapes
    const auto_ptr<ShapeComposite> composite1(new ShapeComposite());
    const auto_ptr<ShapeComposite> composite2(new ShapeComposite());
    const auto_ptr<ShapeComposite> composite3(new ShapeComposite());

    // Composes the shapes
    composite2->add(ellipse1.get());
    composite2->add(ellipse2.get());
    composite2->add(ellipse3.get());

    composite3->add(ellipse4.get());

    composite1->add(composite2.get());
    composite1->add(composite3.get());

    // Prints the complete shape (four times the string "ShapeEllipse")
    composite1->print();
    return 0;
}

/*Sample output
ShapeComposite 00A13DD0{
ShapeComposite 00A13E18{
 ShapeEllipse 00A13D10
 ShapeEllipse 00A13D40
 ShapeEllipse 00A13D70
}
ShapeComposite 00A13E60{
 ShapeEllipse 00A13DA0
}
}
*/