// Purpose.?Composite, Builder, Iterator, Memento, Visitor demo
//
// Discussion.?Composite is a fairly fundamental pattern - it uses, or is
// used by, many other patterns.?Iterator can be used to traverse a
// Composite [GOF, p173].?Visitor can be used to apply an operation over
// an object structure defined by Composite [GOF, p344].?Builder often
// builds a Composite [GOF, p106].?Iterator can use Memento to capture
// the state of an iteration [GOF, p271].
//
// Input (composit.dat):
//牋?a 1 2 b 6 d 13 14 15 d 7 8 b 3 4 5 c 9 10 11
//牋? e 16 17 g 20 g 18 e 12 f 19 f c a
//
// In-memory structures:
//牋?a:牋 1牋 2?^b牋 3牋 4牋 5? ^c
//牋?b:牋 6? ^d牋 7牋 8牋
//牋?c:牋 9?10?11?^e?12? ^f
//牋?d:?13? 14?15牋牋牋牋牋牋牋牋牋
//牋? e:?16?17?^g?18
//牋?f:?19
//牋?g:? 20
//
// Output:
//牋? 1 2 6 13 14 15 7 8 3 4 5 9 10 11 16 17 20 18 12 19
//牋?a 1 2 b 6 d 13 14 15 7 8 3 4 5 c 9 10 11 e 16 17 g 20 18 12 f 19
//牋? composites = 7.?primitives = 20.?total value = 210.?average value = 10

#include <stdio.h>
#include <iostream.h>
#include <fstream.h>

class Composite;
class Primitive;

class Visitor {
public:
牋 virtual void visit( Composite* ) = 0;
牋 virtual void visit( Primitive* ) = 0;
};

class ListVisitor : public Visitor {
public:
牋 /* virtual */ void visit( Composite* );
牋 /* virtual */ void visit( Primitive* );
};

class TotalVisitor : public Visitor {
public:
牋 TotalVisitor() { totalComposites = totalPrimitives = totalValue = 0; }
牋 /* virtual */ void visit( Composite* c ) { totalComposites++; }
牋 /* virtual */ void visit( Primitive* );
牋 void reportTotals()?{
牋牋? cout << "composites = " << totalComposites
牋牋牋牋 << ".?primitives = " << totalPrimitives
牋牋牋牋 << ".?total value = " << totalValue
牋牋牋牋 << ".?average value = " << totalValue / totalPrimitives << endl; }
private:
牋 int? totalComposites;
牋 int?totalPrimitives;
牋 int? totalValue;
};

class Iterator;

class Component {
public:
牋 enum ComponentType { PrimitiveT, CompositeT };
牋 virtual void traverse()牋牋牋牋 = 0;
牋 virtual void add( Component* )?{ }
牋 virtual ComponentType getType() = 0;
牋 virtual void accept( Visitor& ) = 0;
};

class Primitive : public Component {
public:
牋 Primitive( int _value )牋牋牋牋牋牋牋牋 { value_ = _value; }
牋 void traverse()牋牋牋牋牋牋牋牋牋牋牋牋 { cout << value_ << " "; }
牋 ComponentType getType()牋牋牋牋牋牋牋牋 { return PrimitiveT; }
牋 int getValue()牋牋牋牋牋牋牋牋牋牋牋牋?{ return value_; }
牋 /* virtual */ void accept( Visitor& v ) { v.visit( this ); }
private:
牋 int牋? value_;
};

class Composite : public Component {
public:
牋 friend Iterator;
牋 Composite( char _name )牋牋牋牋牋牋牋牋 { name_ = _name;?index_ = 0; }
牋 void add( Component* ele )牋牋牋牋牋牋?{ children_[index_++] = ele; }
牋 ComponentType getType()牋牋牋牋牋牋牋牋 { return CompositeT; }
牋 void printName()牋牋牋牋牋牋牋牋牋牋牋?{ cout << name_ << " "; }
牋 /* virtual */ void accept( Visitor& v ) { v.visit( this ); }
牋 void traverse();
牋 Iterator*? createIterator();
private:
? ?/span>char牋牋牋?name_;
牋 int牋牋牋牋 index_;
牋 Component*? children_[99];
};

void Composite::traverse() {
牋 for (int i=0; i < index_; i++)
牋牋?children_[i]->traverse(); }

/* virtual */ void ListVisitor::visit( Composite* c ) { c->printName(); }
/* virtual */ void ListVisitor::visit( Primitive* p ) { p->traverse(); }
/* virtual */ void TotalVisitor::visit( Primitive* p ) {
牋 totalPrimitives++;
牋 totalValue += p->getValue(); }

class Memento {
public:
牋 void initialize( Composite* _root ) {
牋牋? compArr_[0] = _root;
牋牋? indxArr_[0] = -1;
牋牋? index_ = 0; }
牋 void pushCurrent( Composite* _composite, int _index ) {
牋牋?compArr_[index_+1] = _composite;
牋牋?indxArr_[++index_] = _index; }
牋 int popCurrent() {
牋牋?if (index_ == 0) return 1;
牋牋?index_--;
牋牋?return 0; }
牋 void getAndIncrement( Composite** _composite, int* _index ) {
牋牋? *_composite = compArr_[index_];
牋牋?*_index = indxArr_[index_];
牋牋?(*_index)++;
牋牋? indxArr_[index_]++; }
private:
牋 Composite*? compArr_[10];
牋 int牋牋牋牋 indxArr_[10];
牋 int牋牋牋牋 index_;
};

class Iterator {
public:
牋 Iterator( Composite* _root ) {
牋牋?root_ = _root;
牋牋?isDone_= 0; }
牋 Component* first() {
牋牋?isDone_= 0;
牋牋?memento_.initialize( root_ );
牋牋?return root_; }
牋 Component* next() {
牋牋?Composite* comp;
牋牋?int牋牋牋?indx;
牋牋? memento_.getAndIncrement( &comp, &indx );
牋牋?// if (and while) you are at end-of-composite, go back up
牋牋? while (indx == comp->index_)
牋牋?{
牋牋牋牋 int ret = memento_.popCurrent();
牋牋牋牋 if (ret) {
牋牋牋牋牋? isDone_ = 1;
牋牋牋牋牋? return 0; }
牋牋牋牋 memento_.getAndIncrement( &comp, &indx );
牋牋?}
牋牋?if (comp->children_[indx]->getType() == Component::CompositeT)
牋牋牋牋 memento_.pushCurrent( (Composite*) comp->children_[indx], -1 );
牋牋?return comp->children_[indx]; }
牋 int isDone() { return isDone_; }
private:
牋 Composite*? root_;
牋 Memento牋牋 memento_;
牋 int牋牋牋牋 isDone_;
};

Iterator*? Composite::createIterator() {
牋 return new Iterator( this ); }

class Builder;

class Reader {
public:
牋 Reader( Builder* _builder ) {
牋牋? builder_ = _builder;
牋牋? nextSlot_ = 0; }
牋 void construct();
private:
牋 Builder*?builder_;
牋 char牋牋? compNames_[20];
牋 int牋牋牋 nextSlot_;
牋 int isLower_( char ch ) {
牋牋?if ((ch >= 'a') && (ch <= 'z')) return 1;
牋牋?else return 0; }
牋 int findName_( char ch ) {
牋牋?for (int i=0; i < nextSlot_; i++)
牋牋牋牋 if (compNames_[i] == ch) return 1;
牋牋? compNames_[nextSlot_++] = ch;
牋牋? return 0; }
};

class Builder {
public:
牋 /**/ Builder()牋牋牋牋 { nextSlot_ = 0; }
牋 void buildComposite( char _name ) {
牋牋?// cout << _name << " at level " << nextSlot_ << endl;
牋牋? stack_[nextSlot_] = new Composite( _name );
牋牋?if (nextSlot_)
牋牋牋牋 stack_[nextSlot_ - 1]->add( stack_[nextSlot_] );
牋牋? nextSlot_++; }
牋 void buildPrimitive( int _value ) {
牋牋? stack_[nextSlot_ - 1]->add( new Primitive( _value ) ); }
牋 void closeComposite()?{ nextSlot_--; }
牋 Composite* getResult() { return stack_[0]; }
private:
牋 Composite* stack_[20];
牋 int牋牋牋?nextSlot_;
};

void Reader::construct() {
牋 char牋牋?buf[20];
牋 int牋牋牋 value;
牋 ifstream? inFile( "composit.dat", ios::in );

牋 while ( inFile >> buf )
牋 {
牋牋?if (isLower_( buf[0] ))
牋牋牋牋 if (findName_( buf[0] ))
牋牋牋牋牋?builder_->closeComposite();
牋牋牋牋 else
牋牋牋牋牋?builder_->buildComposite( buf[0] );
牋牋?else
牋牋?{
牋牋牋牋 sscanf( buf, "%d", &value );
牋牋牋牋 builder_->buildPrimitive( value );
牋牋?}
牋 }
}

void main( void ) {
牋 Builder 牋牋牋builder;
牋 Reader牋牋牋?reader( &builder );
牋 Composite*牋?root;
牋 Iterator*牋牋 it;
牋 ListVisitor牋 listV;
牋 TotalVisitor?totalV;

牋 reader.construct();
牋 root = builder.getResult();

牋 // Composite can traverse itself, but Composite nodes get "lost"
牋 root->traverse();牋 cout << endl;

牋 // If you don't want Composite nodes "lost", use an Iterator for traversal
牋 it = root->createIterator();
牋 for (Component* c = it->first(); ! it->isDone(); c = it->next())
牋牋?c->accept( listV );
?/span>?cout << endl;

牋 // Visitors can be designed to accumulate state over a Composite
牋 for (c = it->first(); ! it->isDone(); c = it->next())
牋牋? c->accept( totalV );
牋 totalV.reportTotals();
}

// ListVisitor replaces the following code:
// for (Component* c = it->first(); ! it->isDone(); c = it->next()) {
//牋?if (c->getType() == Component::PrimitiveT)
//牋牋牋 ((Primitive*) c)->traverse();
//牋?else
//牋牋牋 ((Composite*) c)->printName(); }