diff --git a/eo/gp/eoParseTree.h b/eo/gp/eoParseTree.h deleted file mode 100644 index 7bac6125..00000000 --- a/eo/gp/eoParseTree.h +++ /dev/null @@ -1,242 +0,0 @@ -#ifndef EO_PARSE_TREE_H -#define EO_PARSE_TREE_H - -#include - -#include "EO.h" -#include "eoOp.h" -#include "eoInserter.h" -#include "eoIndiSelector.h" -#include "parse_tree.h" -#include "eoRnd.h" - -using namespace gp_parse_tree; -using namespace std; - -template -class eoParseTree : public EO, public parse_tree -{ -public : - - typedef typename parse_tree::subtree Type; - - eoParseTree(void) : EO(), parse_tree() {} - eoParseTree(unsigned _size, eoRnd& _rnd) - : EO(), parse_tree(_rnd()) - { - pruneTree(_size); - } - eoParseTree(eoRnd& _rnd) - : EO(), parse_tree(_rnd()) - {} - - virtual void pruneTree(unsigned _size) - { - if (_size < 1) - return; - - if (size() > _size) - { - Type* sub = &operator[](size() - 2); // prune tree - - while (sub->size() > _size) - { - sub = &sub->operator[](0); - } - - back() = *sub; - } - } - - eoParseTree(std::istream& is) : EO(), parse_tree() - { - readFrom(is); - } - - string className(void) const { return "eoParseTree"; } - - void printOn(std::ostream& os) const - { - os << fitness() << ' '; - - std::copy(ebegin(), eend(), ostream_iterator(os)); - } - - void readFrom(std::istream& is) - { - FType fit; - - is >> fit; - - fitness(fit); - - std::copy(istream_iterator(is), istream_iterator(), back_inserter(*this)); - } -}; - -template -std::ostream& operator<<(std::ostream& os, const eoParseTree& eot) -{ - eot.printOn(os); - return os; -} - -template -std::istream& operator>>(std::istream& is, eoParseTree& eot) -{ - eot.readFrom(is); - return is; -} - - -template -class eoGpDepthInitializer : public eoRnd< eoParseTree::Type > -{ - public : - - typedef eoParseTree EoType; - - eoGpDepthInitializer( - unsigned _max_depth, - const vector& _initializor, - bool _grow = true) - : - eoRnd(), - max_depth(_max_depth), - initializor(_initializor), - grow(_grow) - {} - - virtual string className() const { return "eoDepthInitializer"; }; - - EoType::Type operator()(void) - { - list sequence; - - generate(sequence, max_depth); - - parse_tree tree(sequence.begin(), sequence.end()); - - return tree.root(); - } - - void generate(list& sequence, int the_max, int last_terminal = -1) - { - if (last_terminal == -1) - { // check where the last terminal in the sequence resides - vector::iterator it; - for (it = initializor.begin(); it != initializor.end(); ++it) - { - if (it->arity() > 0) - break; - } - - last_terminal = it - initializor.begin(); - } - - if (the_max == 1) - { // generate terminals only - vector::iterator it = initializor.begin() + rng.random(last_terminal); - sequence.push_front(*it); - return; - } - - vector::iterator what_it; - - if (grow) - { - what_it = initializor.begin() + rng.random(initializor.size()); - } - else // full - { - what_it = initializor.begin() + last_terminal + rng.random(initializor.size() - last_terminal); - } - - what_it->randomize(); - - sequence.push_front(*what_it); - - for (int i = 0; i < what_it->arity(); ++i) - generate(sequence, the_max - 1, last_terminal); - } - - -private : - - unsigned max_depth; - std::vector initializor; - bool grow; -}; - -template -class eoSubtreeXOver: public eoGeneralOp< eoParseTree > { -public: - - typedef eoParseTree EoType; - - eoSubtreeXOver( unsigned _max_length) - : eoGeneralOp(), max_length(_max_length) {}; - - virtual string className() const { return "eoSubtreeXOver"; }; - - /// Dtor - virtual ~eoSubtreeXOver () {}; - - void operator()(eoIndiSelector& _source, eoInserter& _sink ) const - { - EoType eo1 = _source.select(); - const EoType& eo2 = _source.select(); - - int i = rng.random(eo1.size()); - int j = rng.random(eo2.size()); - - eo1[i] = eo2[j]; // insert subtree - - eo1.pruneTree(max_length); - - eo1.invalidate(); - _sink.insert(eo1); - } - - unsigned max_length; -}; - -template -class eoBranchMutation: public eoGeneralOp< eoParseTree > -{ -public: - - typedef eoParseTree EoType; - - eoBranchMutation(eoRnd& _init, unsigned _max_length) - : eoGeneralOp(), max_length(_max_length), initializer(_init) - {}; - - virtual string className() const { return "eoBranchMutation"; }; - - /// Dtor - virtual ~eoBranchMutation() {}; - - void operator()(eoIndiSelector& _source, eoInserter& _sink ) const - { - EoType eo1 = _source.select(); - int i = rng.random(eo1.size()); - - EoType eo2(eo1[i].size(), initializer); // create random other to cross with - - eo1[i] = eo2.back(); // insert subtree - - eo1.pruneTree(max_length); - - eo1.invalidate(); - _sink.insert(eo1); - } - -private : - - unsigned max_length; - eoRnd& initializer; -}; - - -#endif diff --git a/eo/gp/node_pool.h b/eo/gp/node_pool.h deleted file mode 100644 index f541d5f0..00000000 --- a/eo/gp/node_pool.h +++ /dev/null @@ -1,297 +0,0 @@ - -#ifndef node_pool_h -#define node_pool_h - -class MemPool -{ -public : - - MemPool(unsigned int sz) : esize(sznext; - delete p; - } - } - - void* allocate() - { - if (head == 0) grow(); - Link* p = head; - head = p->next; - return static_cast(p); - } - - void deallocate(void* b) - { - Link* p = static_cast(b); - p->next = head; - head = p; - } - -private : - - void grow() - { - Chunk* n = new Chunk; - n->next = chunks; - chunks = n; - - const int nelem = Chunk::size/esize; - char* start = n->mem; - char* last = &start[(nelem-1)*esize]; - for (char* p = start; p < last; p += esize) - { - reinterpret_cast(p)->next = - reinterpret_cast(p + esize); - } - - reinterpret_cast(last)->next = 0; - head = reinterpret_cast(start); - } - - struct Link - { - Link* next; - }; - - struct Chunk - { - enum {size = 8 * 1024 - 16}; - Chunk* next; - char mem[size]; - }; - - Chunk* chunks; - const unsigned int esize; - Link* head; -}; - -template -class Node_alloc -{ -public : - - T* allocate(void) - { - T* t = static_cast(mem.allocate()); - t = new (t) T; - return t; - } - - T* construct(const T& org) - { - T* t = static_cast(mem.allocate()); - t = new (t) T(org); - return t; - } - - void deallocate(T* t) - { - t->~T(); // call destructor - mem.deallocate(static_cast(t)); - } - -private : - static MemPool mem; -}; - - -template -class Standard_alloc -{ -public : - Standard_alloc() {} - - T* allocate(size_t arity = 1) - { - if (arity == 0) - return 0; - - return new T [arity]; - } - - T* construct(size_t arity, T* org) - { - if (arity == 0) - return 0; - - T* t new T [arity]; - - for (int i = 0; i < arity; ++i) - { - t = T(org[i]); - } - } - - void deallocate(T* t, size_t arity = 1) - { - if (arity == 0) - return ; - - delete [] t; - } - -}; - -template -class Standard_Node_alloc -{ -public : - Standard_Node_alloc() {} - - T* allocate(void) - { - return new T;// [arity]; - } - - T* construct(const T& org) - { - return new T(org); - } - - void deallocate(T* t) - { - delete t; - } - -}; - -template -class Tree_alloc -{ -public : - Tree_alloc() {} - - T* allocate(size_t arity) - { - T* t; - - switch(arity) - { - - case 0 : return 0; - case 1 : - { - t = static_cast(mem1.allocate()); - new (t) T; - break; - } - case 2 : - { - t = static_cast(mem2.allocate()); - new (t) T; - new (&t[1]) T; - break; - } - case 3 : - { - t = static_cast(mem3.allocate()); - new (t) T; - new (&t[1]) T; - new (&t[2]) T; - break; - } - default : - { - return new T[arity]; - } - } - - return t; - } - - T* construct(size_t arity, T* org) - { - T* t; - - switch(arity) - { - - case 0 : return 0; - case 1 : - { - t = static_cast(mem1.allocate()); - new (t) T(*org); - break; - } - case 2 : - { - t = static_cast(mem2.allocate()); - new (t) T(*org); - new (&t[1]) T(org[1]); - break; - } - case 3 : - { - t = static_cast(mem3.allocate()); - new (t) T(*org); - new (&t[1]) T(org[1]); - new (&t[1]) T(org[2]); - break; - } - default : - { - t = new T[arity]; // does call default ctor - for (int i = 0; i < arity; ++i) - { - t[i] = T(org[i]); // constructs now - } - } - } - - return t; - } - - - - void deallocate(T* t, size_t arity) - { - switch(arity) - { - case 0: return; - case 3 : - { - t[2].~T(); t[1].~T(); t[0].~T(); - mem3.deallocate(static_cast(t)); - return; - } - case 2 : - { - t[1].~T(); t[0].~T(); - mem2.deallocate(static_cast(t)); - return; - } - case 1 : - { - t[0].~T(); - mem1.deallocate(static_cast(t)); - return; - } - default : - { - delete [] t; - return; - } - } - } - - -private : - static MemPool mem1; - static MemPool mem2; - static MemPool mem3; -}; - -// static (non thread_safe) memory pools -template MemPool Node_alloc::mem = sizeof(T); - -template MemPool Tree_alloc::mem1 = sizeof(T); -template MemPool Tree_alloc::mem2 = sizeof(T) * 2; -template MemPool Tree_alloc::mem3 = sizeof(T) * 3; - -#endif diff --git a/eo/gp/parse_tree.h b/eo/gp/parse_tree.h deleted file mode 100644 index e6c50723..00000000 --- a/eo/gp/parse_tree.h +++ /dev/null @@ -1,994 +0,0 @@ -#ifndef PARSE_TREE_HH -#define PARSE_TREE_HH - -/** - - * Parse_tree and subtree classes - * (c) Maarten Keijzer 1999, 2000 - - * These classes may be used for educational and - * other non-commercial purposes only. Even if I - * wanted to, I am not at liberty to place this file - * under the GNU Lesser Public Library License, as this - * would limit my and my institution's freedom to use - * this file in closed-source software. - - * This material is provided "as is", with absolutely no warranty expressed - * or implied. Any use is at your own risk. - * - * Permission to use or copy this software for non-commercial purpose is hereby granted - * without fee, provided the above notices are retained on all copies. - * Permission to modify the code and to distribute modified code is granted, - * provided the above notices are retained, and a notice that the code was - * modified is included with the above copyright notice. - * - - - Usage information. - - class Node (your node in the tree) must have the following implemented: - - ****** Arity ****** - - int arity(void) const - - Note: the default constructor of a Node should provide a - Node with arity 0! - - ****** Evaluation ****** - - A parse_tree is evaluated through one of it's apply() members: - - 1) parse_tree::apply(RetVal) - - is the simplest evaluation, it will call - - RetVal Node::operator()(RetVal, subtree::const_iterator) - - (Unfortunately the first RetVal argument is mandatory (although you - might not need it. This is because MSVC does not support member template - functions properly. If it cannot deduce the template arguments (as is - the case in templatizing over return value) you are not allowed to - specify them. calling tree.apply() would result in a syntax - error. That is why you have to call tree.apply(double()) instead.) - - - 2) parse_tree::apply(RetVal v, It values) - - will call: - - RetVal Node::operator()(RetVal, subtree<... , It values) - - where It is whatever type you desire (most of the time - this will be a vector containing the values of your - variables); - - 3) parse_tree::apply(RetVal, It values, It2 moreValues) - - will call: - - RetVal Node::operator()(RetVal, subtree<... , It values, It2 moreValues) - - although I do not see the immediate use of this, however... - - 4) parse_tree::apply(RetVal, It values, It2 args, It3 adfs) - - that calls: - - RetVal Node::operator()(subtree<... , It values, It2 args, It3 adfs) - - can be useful for implementing adfs. - - - In general it is a good idea to leave the specifics of the - arguments open so that different ways of evaluation remain - possible. Implement the simplest eval as: - - template - RetVal operator()(RetVal dummy, It begin) const - - ****** Internal Structure ****** - - A parse_tree has two template arguments: the Node and the ReturnValue - produced by evaluating the node. The structure of the tree is defined - through a subtree class that has the same two template arguments. - - The nodes are stored in a tree like : - - node4 - / \ - node3 node2 - / \ - node1 node0 - - where nodes 2 and 4 have arity 2 and nodes 0,1 and 3 arity 0 (terminals) - - The nodes are subtrees, containing the structure of the tree, together - with its size and depth. They contain a Node, the user defined template - argument. To access these nodes from a subtree, use operator-> or operator*. - - The numbers behind the nodes define a reverse-polish or postfix - traversel through the tree. The parse_tree defines iterators - on the tree such that - - tree.begin() points at the subtree at node0 and - tree.back() returns the subtree at node4, the complete tree - - Likewise operator[] is defined on the tree, such that: - - tree[0] will return the subtree at node0, while - tree[2] will return the subtree at node2 - - Assigments of subtrees is protected so that the code: - - tree[2] = tree[0]; - - will not crash and result in a tree structured as: - - node4 - / \ - node3 node0 - - Note that the rank numbers no longer specify their place in the tree: - - tree[0] still points at node0, but - tree[1] now points to node3 and - tree[2] points at the root node4 - - Embedded iterators are implemented to iterate over nodes rather - than subtrees. So an easy way to copy your tree to a vector is: - - vector vec(tree.size()); - copy(tree.ebegin(), tree.eend(), vec.begin()); - - You can also copy it to an ostream_iterator with this - technique, given that your Node implements an appropriate - operator<<. Reinitializing a tree with the vector is also - simple: - - tree.clear(); - copy(vec.begin(), vec.end(), back_inserter(tree)); - - or from an istream: - - copy(istream_iterator(my_stream), istream_iterator(), back_inserter(tree)); - - Note that the back_inserter must be used as there is no - resize member in the parse_tree. back_inserter will use - the push_back member from the parse_tree - -*/ - -#include -#include // for swap - -#ifdef _MSC_VER -#pragma warning(disable : 4786) // disable this nagging warning about the limitations of the mirkosoft debugger -#endif - -namespace gp_parse_tree -{ - -#include "node_pool.h" - - -template -inline void do_the_swap(T& a, T& b) -{ - T tmp = a; - a = b; - b = tmp; -} - -template class parse_tree -{ - public : - - -class subtree -{ - -/* - a bit nasty way to use a pool allocator (which would otherwise use slooow new and delete) - TODO: use the std::allocator interface -*/ - -#if (defined(__GNUC__) || defined(_MSC_VER)) && !defined(_MT) // not multithreaded - Node_alloc node_allocator; - Tree_alloc tree_allocator; -#else - Standard_Node_alloc node_allocator; - Standard_alloc tree_allocator; -#endif - -public : - - typedef subtree* iterator; - typedef const subtree* const_iterator; - - /* Constructors, assignments */ - - subtree(void) : content(node_allocator.allocate()), args(0), parent(0), _cumulative_size(0), _depth(0), _size(1) - {} - subtree(const subtree& s) - : content(node_allocator.allocate()), - args(0), - parent(0), - _cumulative_size(1), - _depth(1), - _size(1) - { - copy(s); - } - - subtree(const T& t) : content(node_allocator.allocate()), args(0), parent(0), _cumulative_size(0), _depth(0), _size(1) - { copy(t); } - - template - subtree(It b, It e) : content(node_allocator.allocate()), args(0), parent(0), _cumulative_size(0), _depth(0), _size(1) - { // initialize in prefix order for efficiency reasons - init(b, --e); - } - - virtual ~subtree(void) { tree_allocator.deallocate(args, arity()); node_allocator.deallocate(content); } - - subtree& operator=(const subtree& s) - { - if (s.get_root() == get_root()) - { // from the same tree, maybe a child. Don't take any chances - subtree anotherS = s; - return copy(anotherS); - } - - copy(s); - updateAfterInsert(); - return *this; - } - - subtree& operator=(const T& t) { copy(t); updateAfterInsert(); return *this; } - - /* Access to the nodes */ - - T& operator*(void) { return *content; } - const T& operator*(void) const { return *content; } - T* operator->(void) { return content; } - const T* operator->(void) const { return content; } - - /* Equality, inequality check, Node needs to implement operator== */ - - bool operator==(const subtree& other) const - { - if (! (*content == *other.content)) - return false; - - for (int i = 0; i < arity(); i++) - { - if (!(args[i] == other.args[i])) - return false; - } - - return true; - } - - bool operator !=(const subtree& other) const - { - return !operator==(other); - } - - /* Arity */ - int arity(void) const { return content->arity(); } - - /* Evaluation with an increasing amount of user defined arguments */ - template - void apply(RetVal& v) const { (*content)(v, begin()); } - - template - void apply(RetVal& v, It values) const - { - (*content)(v, begin(), values); - } - - template - void apply_mem_func(RetVal& v, It misc, void (T::* f)(RetVal&, subtree::iterator, It)) - { - (content->*f)(v, begin(), misc); - } - - -/* template - void apply(RetVal& v, It values, It2 moreValues) const - { (*content)(v, begin(), values, moreValues); } - - template - void apply(RetVal& v, It values, It2 moreValues, It3 evenMoreValues) const - { (*content)(v, begin(), values, moreValues, evenMoreValues); } -*/ - - template - void find_nodes(vector& result, Pred& p) - { - if (p(*content)) - { - result.push_back(this); - } - - for (int i = 0; i < arity(); ++i) - { - args[i].find_nodes(result, p); - } - } - - template - void find_nodes(vector& result, Pred& p) const - { - if (p(*content)) - { - result.push_back(this); - } - - for (int i = 0; i < arity(); ++i) - { - args[i].find_nodes(result, p); - } - } - - /* Iterators */ - - iterator begin(void) { return args; } - const_iterator begin(void) const { return args; } - - iterator end(void) { return args + arity(); } - const_iterator end(void) const { return args + arity(); } - - subtree& operator[](int i) { return *(begin() + i); } - const subtree& operator[](int i) const { return *(begin() + i); } - - /* Some statistics */ - - size_t size(void) const { return _size; } - - size_t cumulative_size(void) const { return _cumulative_size; } - size_t depth(void) const { return _depth; } - - const subtree& select_cumulative(size_t which) const - { return imp_select_cumulative(which); } - - subtree& select_cumulative(size_t which) - { return const_cast(imp_select_cumulative(which)); } - - subtree& get_node(size_t which) - { return const_cast(imp_get_node(which));} - const subtree& get_node(size_t which) const - { return imp_get_node(which); } - - subtree* get_parent(void) { return parent; } - const subtree* get_parent(void) const { return parent; } - - void clear(void) - { tree_allocator.deallocate(args, arity()); args = 0; *content = T(); parent = 0; _cumulative_size = 0; _depth = 0; _size = 0; } - - void swap(subtree& y) - { - do_the_swap(content, y.content); - do_the_swap(args, y.args); - do_the_swap(parent, y.parent); - - do_the_swap(_cumulative_size, y._cumulative_size); - do_the_swap(_depth, y._depth); - do_the_swap(_size, y._size); - updateAfterInsert(); - } - - friend void swap(subtree& x, subtree& y) - { - x.swap(y); - } - -protected : - - virtual void updateAfterInsert(void) - { - _depth = 0; - _size = 1; - _cumulative_size = 0; - - for (iterator it = begin(); it != end(); ++it) - { - _size += it->size(); - _cumulative_size += it->_cumulative_size; - _depth = it->_depth > _depth? it->_depth: _depth; - } - _cumulative_size += _size; - _depth++; - - content->updateAfterInsert(); - - if (parent) - parent->updateAfterInsert(); - } - -private : - - const subtree& imp_select_cumulative(size_t which) const - { - if (which >= (_cumulative_size - size())) - return *this; - // else - - for (int i = arity() - 1; i >= 0; --i) - { - if (which < args[i]._cumulative_size) - return args[i].imp_select_cumulative(which); - which -= args[i]._cumulative_size; - } - - return *this; // error! - } - - const subtree& imp_get_node(size_t which) const - { - if (which == size() - 1) - return *this; - - for (int i = arity() - 1; i >= 0; --i) - { - unsigned c_size = args[i].size(); - if (which < c_size) - return args[i].imp_get_node(which); - which -= c_size; - } - - return *this; // error! - } - - const subtree* get_root(void) const - { - if (parent == 0) - return this; - // else - - return parent->get_root(); - } - subtree& copy(const subtree& s) - { - int old_arity = arity(); - - int new_arity = s.arity(); - - if (new_arity != old_arity) - { - tree_allocator.deallocate(args, old_arity); - - args = tree_allocator.allocate(new_arity); - } - - switch(new_arity) - { - case 3 : args[2].copy(s.args[2]); args[2].parent = this; // no break! - case 2 : args[1].copy(s.args[1]); args[1].parent = this; - case 1 : args[0].copy(s.args[0]); args[0].parent = this; - case 0 : break; - default : - { - for (int i = 0; i < new_arity; ++i) - { - args[i].copy(s.args[i]); - args[i].parent = this; - } - } - } - - *content = *s.content; - _size = s._size; - _depth = s._depth; - _cumulative_size = s._cumulative_size; - - return *this; - } - - subtree& copy(const T& t) - { - int oldArity = arity(); - - if (content != &t) - *content = t; - else - oldArity = -1; - - int ar = arity(); - - if (ar != oldArity) - { - if (oldArity != -1) - tree_allocator.deallocate(args, oldArity); - - args = tree_allocator.allocate(ar); - - //if (ar > 0) - // args = new subtree [ar]; - //else - // args = 0; - } - - adopt(); - updateAfterInsert(); - return *this; - } - - void disown(void) - { - switch(arity()) - { - case 3 : args[2].parent = 0; // no break! - case 2 : args[1].parent = 0; - case 1 : args[0].parent = 0; break; - case 0 : break; - default : - { - for (iterator it = begin(); it != end(); ++it) - { - it->parent = 0; - } - } - } - - } - - void adopt(void) - { - switch(arity()) - { - case 3 : args[2].parent = this; // no break! - case 2 : args[1].parent = this; - case 1 : args[0].parent = this; break; - case 0 : break; - default : - { - for (iterator it = begin(); it != end(); ++it) - { - it->parent = this; - } - } - } - } - - template - void init(It b, It& last) - { - *this = *last; - -#ifndef NDEBUG - if (last == b && arity() > 0) - { - throw "subtree::init()"; - } -#endif - - for (int i = 0; i < arity(); ++i) - { - args[i].parent = 0; - args[i].init(b, --last); - args[i].parent = this; - } - - updateAfterInsert(); - } - - T* content; - subtree* args; - subtree* parent; - - size_t _cumulative_size; - size_t _depth; - size_t _size; -}; - -// Continuing with parse_tree - - typedef T value_type; - - /* Constructors and Assignments */ - - parse_tree(void) : _root(), pushed() {} - parse_tree(const parse_tree& org) : _root(org._root), pushed(org.pushed) { } - parse_tree(const subtree& sub) : _root(sub), pushed() { } - - template - parse_tree(It b, It e) : _root(b, e), pushed() {} - - virtual ~parse_tree(void) {} - - parse_tree& operator=(const parse_tree& org) { return copy(org); } - parse_tree& operator=(const subtree& sub) - { return copy(sub); } - - - /* Equality and inequality */ - - bool operator==(const parse_tree& other) const - { return _root == other._root; } - - bool operator !=(const parse_tree& other) const - { return !operator==(other); } - - /* Simple tree statistics */ - - size_t size(void) const { return _root.size(); } - size_t depth(void) const { return _root.depth(); } - void clear(void) { _root.clear(); pushed.resize(0); } - - /* Evaluation (application), with an increasing number of user defined arguments */ - - template - void apply(RetVal& v) const - { _root.apply(v); } - - template - void apply(RetVal& v, It varValues) const - { _root.apply(v, varValues); } - - template - void apply_mem_func(RetVal& v, It misc, void (T::* f)(RetVal&, subtree::iterator, It)) - { - _root.apply_mem_func(v, misc, f); - } - - //template - // void apply(RetVal& v, It varValues, It2 moreValues) const - // { _root.apply(v, varValues, moreValues); } - - //template - // void apply(RetVal& v, It varValues, It2 moreValues, It3 evenMoreValues) const - // { _root.apply(v, varValues, moreValues, evenMoreValues); } - - template - void find_nodes(vector& result, Pred& p) - { - _root.find_nodes(result, p); - } - - template - void find_nodes(vector& result, Pred& p) const - { - _root.find_nodes(p); - } - - /* Customized Swap */ - void swap(parse_tree& other) - { - do_the_swap(pushed, other.pushed); - _root.swap(other._root); - } - - /* Definitions of the iterators */ - - class base_iterator - { - public : - - base_iterator() {} - base_iterator(subtree* n) { node = n; } - - base_iterator& operator=(const base_iterator& org) - { node = org.node; return *this; } - - bool operator==(const base_iterator& org) const - { return node == org.node; } - bool operator!=(const base_iterator& org) const - { return !operator==(org); } - - base_iterator operator+(size_t n) const - { - base_iterator tmp = *this; - - for(;n != 0; --n) - { - ++tmp; - } - - return tmp; - } - - base_iterator& operator++(void) - { - subtree* parent = node->get_parent(); - - if (parent == 0) - { - node = 0; - return *this; - } - // else - subtree::iterator it; - for (it = parent->begin(); it != parent->end(); ++it) - { - if (node == &(*it)) - break; - } - - if (it == parent->begin()) - node = parent; - else - { - node = &(--it)->get_node(0); - } - - return *this; - } - - base_iterator operator++(int) - { - base_iterator tmp = *this; - operator++(); - return tmp; - } - - protected : - subtree* node; - }; - - class iterator : public base_iterator - { - public : - typedef std::forward_iterator_tag iterator_category; - typedef subtree value_type; - typedef size_t distance_type; - typedef size_t difference_type; - typedef subtree* pointer; - typedef subtree& reference; - - iterator() : base_iterator() {} - iterator(subtree* n): base_iterator(n) {} - iterator& operator=(const iterator& org) - { base_iterator::operator=(org); return *this; } - - subtree& operator*(void) { return *node; } - subtree* operator->(void) { return node; } - }; - - class embedded_iterator : public base_iterator - { - public : - typedef std::forward_iterator_tag iterator_category; - typedef T value_type; - typedef size_t distance_type; - typedef size_t difference_type; - typedef T* pointer; - typedef T& reference; - - embedded_iterator() : base_iterator() {} - embedded_iterator(subtree* n): base_iterator(n) {} - embedded_iterator& operator=(const embedded_iterator& org) - { base_iterator::operator=(org); return *this; } - - T& operator*(void) { return **node; } - T* operator->(void) { return &**node; } - }; - - class base_const_iterator - { - public : - base_const_iterator() {} - base_const_iterator(const subtree* n) { node = n; } - - base_const_iterator& operator=(const base_const_iterator& org) - { node = org.node; return *this; } - - bool operator==(const base_const_iterator& org) const - { return node == org.node; } - bool operator!=(const base_const_iterator& org) const - { return !operator==(org); } - - base_const_iterator& operator++(void) - { - const subtree* parent = node->get_parent(); - - if (parent == 0) - { - node = 0; - return *this; - } - // else - subtree::const_iterator it; - - for (it = parent->begin(); it != parent->end(); ++it) - { - if (node == &(*it)) - break; - } - - if (it == parent->begin()) - node = parent; - else - node = &(--it)->get_node(0); - return *this; - } - - base_const_iterator operator++(int) - { - base_const_iterator tmp = *this; - operator++(); - return tmp; - } - - protected : - - const subtree* node; - }; - - class const_iterator : public base_const_iterator - { - public : - typedef std::forward_iterator_tag iterator_category; - typedef const subtree value_type; - typedef size_t distance_type; - typedef size_t difference_type; - typedef const subtree* pointer; - typedef const subtree& reference; - - const_iterator() : base_const_iterator() {} - const_iterator(const subtree* n): base_const_iterator(n) {} - const_iterator& operator=(const const_iterator& org) - { base_const_iterator::operator=(org); return *this; } - - const subtree& operator*(void) { return *node; } - const subtree* operator->(void) { return node; } - }; - - class embedded_const_iterator : public base_const_iterator - { - public : - typedef std::forward_iterator_tag iterator_category; - typedef const T value_type; - typedef size_t distance_type; - typedef size_t difference_type; - typedef const T* pointer; - typedef const T& reference; - - embedded_const_iterator() : base_const_iterator() {} - embedded_const_iterator(const subtree* n): base_const_iterator(n) {} - embedded_const_iterator& operator=(const embedded_const_iterator& org) - { base_const_iterator::operator=(org); return *this; } - - embedded_const_iterator operator+(size_t n) const - { - embedded_const_iterator tmp = *this; - - for(;n != 0; --n) - { - ++tmp; - } - - return tmp; - } - - const T& operator*(void) const { return **node; } - const T* operator->(void) const { return node->operator->(); } - }; - - /* Iterator access */ - - iterator begin(void) { return iterator(&operator[](0)); } - const_iterator begin(void) const { return const_iterator(&operator[](0)); } - iterator end(void) { return iterator(0); } - const_iterator end(void) const { return const_iterator(0);} - - embedded_iterator ebegin(void) { return embedded_iterator(&operator[](0)); } - embedded_const_iterator ebegin(void) const { return embedded_const_iterator(&operator[](0)); } - embedded_iterator eend(void) { return embedded_iterator(0); } - embedded_const_iterator eend(void) const { return embedded_const_iterator(0);} - - bool empty(void) const { return size() == 0; } - bool valid(void) const { return pushed.empty(); } - - /* push_back */ - - void push_back(const parse_tree& tree) - { - if (!empty()) - pushed.push_back(_root); - - _root = tree.back(); - } - - void push_back(const T& t) - { - if (!empty()) - pushed.push_back(_root); - - _root = t; - - for (subtree::iterator it = _root.begin(); it != _root.end(); it++) - { - *it = pushed.back(); - pushed.pop_back(); - } - - } - - /* Access to subtrees */ - - subtree& back(void) { return _root; } - const subtree& back(void) const { return _root; } - subtree& root(void) { return _root; } - const subtree& root(void) const { return _root; } - - subtree& front(void) { return _root[0]; } - const subtree& front(void) const { return _root[0]; } - - subtree& operator[](size_t i) - { return const_cast(_root.get_node(i)); } - const subtree& operator[](size_t i) const - { return _root.get_node(i); } - - subtree& get_cumulative(size_t i) - { return const_cast(_root.get_cumulative(i)); } - const subtree& get_cumulative(size_t i) const - { return get_cumulative(i); } - - private : - - parse_tree& copy(const parse_tree& org) - { - _root = org._root; - pushed = org.pushed; - - return *this; - } - - parse_tree& copy(const subtree& sub) - { _root = sub; pushed.resize(0); return *this; } - - subtree _root; - std::vector pushed; -}; // end class parse_tree - - -} // end namespace gp_parse_tree - -namespace std -{ // for use with stlport on MSVC - -template inline -std::forward_iterator_tag iterator_category(gp_parse_tree::parse_tree::embedded_iterator) -{ - return std::forward_iterator_tag(); -} - -template inline -ptrdiff_t* distance_type(gp_parse_tree::parse_tree::embedded_iterator) -{ - return 0; -} - -template inline -std::forward_iterator_tag iterator_category(gp_parse_tree::parse_tree::iterator) -{ - return std::forward_iterator_tag(); -} - -template inline -ptrdiff_t* distance_type(gp_parse_tree::parse_tree::iterator) -{ - return 0; -} - -// Put customized swaps also in std... - -template inline -void swap(gp_parse_tree::parse_tree& a, gp_parse_tree::parse_tree& b) -{ - a.swap(b); -} - -template inline -void iter_swap(vector >::iterator a, vector > b) -{ - a->swap(*b); -} - - -} // namespace std - - -#endif