parse_tree.h

00001 #ifndef PARSE_TREE_HH
00002 #define PARSE_TREE_HH
00003 
00155 #include <vector>
00156 #include <utility> // for swap
00157 
00158 #ifdef _MSC_VER
00159 #pragma warning(disable : 4786) // disable this nagging warning about the limitations of the mirkosoft debugger
00160 #endif
00161 
00162 namespace gp_parse_tree
00163 {
00164 
00165 #include "node_pool.h"
00166 
00168 template <class T>
00169 inline void do_the_swap(T& a, T& b)
00170 {
00171   T tmp = a;
00172   a = b;
00173   b = tmp;
00174 }
00175 
00176 template <class T> class parse_tree
00177 {
00178   public :
00179 
00180 
00181 class subtree
00182 {
00183 
00184 /*
00185     a bit nasty way to use a pool allocator (which would otherwise use slooow new and delete)
00186     TODO: use the std::allocator interface
00187 */
00188 
00189 #if (defined(__GNUC__) || defined(_MSC_VER)) && !(defined(_MT) || defined(MACOSX) || defined(__APPLE__)) // not multithreaded (or MACOSX - J. Eggermont)
00190     Node_alloc<T>         node_allocator;
00191     Tree_alloc<subtree>   tree_allocator;
00192 #else
00193     Standard_Node_alloc<T>    node_allocator;
00194     Standard_alloc<subtree>   tree_allocator;
00195 #endif
00196 
00197 public :
00198 
00199     typedef subtree* iterator;
00200     typedef const subtree* const_iterator;
00201 
00202         /* Constructors, assignments */
00203 
00204     subtree(void) : content(node_allocator.allocate()), args(0), parent(0), _cumulative_size(0), _depth(0), _size(1)
00205                         {}
00206     subtree(const subtree& s)
00207         : content(node_allocator.allocate()),
00208           args(0),
00209           parent(0),
00210           _cumulative_size(1),
00211           _depth(1),
00212           _size(1)
00213     {
00214         copy(s);
00215     }
00216 
00217     subtree(const T& t) : content(node_allocator.allocate()), args(0), parent(0), _cumulative_size(0), _depth(0), _size(1)
00218                         { copy(t); }
00219 
00220     template <class It>
00221         subtree(It b, It e) : content(node_allocator.allocate()), args(0), parent(0), _cumulative_size(0), _depth(0), _size(1)
00222     { // initialize in prefix order for efficiency reasons
00223         init(b, --e);
00224     }
00225 
00226     virtual ~subtree(void)    { tree_allocator.deallocate(args, arity()); node_allocator.deallocate(content); }
00227 
00228     subtree& operator=(const subtree& s)
00229         {
00230             if (s.get_root() == get_root())
00231         { // from the same tree, maybe a child. Don't take any chances
00232             subtree anotherS = s;
00233             return copy(anotherS);
00234         }
00235 
00236                 copy(s);
00237         updateAfterInsert();
00238         return *this;
00239         }
00240 
00241     subtree& operator=(const T& t)       { copy(t); updateAfterInsert(); return *this; }
00242 
00243         /* Access to the nodes */
00244 
00245     T&       operator*(void)             { return *content; }
00246     const T& operator*(void) const       { return *content; }
00247     T*       operator->(void)            { return content; }
00248     const T* operator->(void) const      { return content; }
00249 
00250         /* Equality, inequality check, Node needs to implement operator== */
00251 
00252         bool operator==(const subtree& other) const
00253         {
00254                 if (! (*content == *other.content))
00255                         return false;
00256 
00257                 for (int i = 0; i < arity(); i++)
00258                 {
00259                         if (!(args[i] == other.args[i]))
00260                                 return false;
00261                 }
00262 
00263                 return true;
00264         }
00265 
00266         bool operator !=(const subtree& other) const
00267         {
00268                 return !operator==(other);
00269         }
00270 
00271         /* Arity */
00272     int arity(void) const                { return content->arity(); }
00273 
00274         /* Evaluation with an increasing amount of user defined arguments */
00275         template <class RetVal>
00276         void apply(RetVal& v) const                              { (*content)(v, begin()); }
00277 
00278         template <class RetVal, class It>
00279         void apply(RetVal& v, It values) const
00280     {
00281         (*content)(v, begin(), values);
00282     }
00283 
00284     template <class RetVal, class It>
00285     void apply_mem_func(RetVal& v, It misc, void (T::* f)(RetVal&, typename subtree::iterator, It))
00286     {
00287         (content->*f)(v, begin(), misc);
00288     }
00289 
00290 
00291 /*      template <class RetVal, class It, class It2>
00292         void apply(RetVal& v, It values, It2 moreValues) const
00293                 { (*content)(v, begin(), values, moreValues); }
00294 
00295         template <class RetVal, class It, class It2, class It3>
00296         void apply(RetVal& v, It values, It2 moreValues, It3 evenMoreValues) const
00297                 { (*content)(v, begin(), values, moreValues, evenMoreValues); }
00298 */
00299 
00300     template <class Pred>
00301     void find_nodes(std::vector<subtree*>& result, Pred& p)
00302     {
00303         if (p(*content))
00304         {
00305             result.push_back(this);
00306         }
00307 
00308         for (int i = 0; i < arity(); ++i)
00309         {
00310             args[i].find_nodes(result, p);
00311         }
00312     }
00313 
00314     template <class Pred>
00315     void find_nodes(std::vector<const subtree*>& result, Pred& p) const
00316     {
00317         if (p(*content))
00318         {
00319             result.push_back(this);
00320         }
00321 
00322         for (int i = 0; i < arity(); ++i)
00323         {
00324             args[i].find_nodes(result, p);
00325         }
00326     }
00327 
00328         /* Iterators */
00329 
00330     iterator begin(void)              { return args; }
00331     const_iterator begin(void) const  { return args; }
00332 
00333     iterator end(void)                { return args + arity(); }
00334     const_iterator end(void) const    { return args + arity(); }
00335 
00336         subtree& operator[](int i)                { return *(begin() + i); }
00337         const subtree& operator[](int i) const { return *(begin() + i); }
00338 
00339         /* Some statistics */
00340 
00341     size_t size(void) const { return _size; }
00342 
00343     size_t cumulative_size(void) const { return _cumulative_size; }
00344     size_t depth(void) const           { return _depth; }
00345 
00346     const subtree& select_cumulative(size_t which) const
00347     { return imp_select_cumulative(which); }
00348 
00349     subtree& select_cumulative(size_t which)
00350     { return const_cast<subtree&>(imp_select_cumulative(which)); }
00351 
00352     subtree& get_node(size_t which)
00353     { return const_cast<subtree&>(imp_get_node(which));}
00354     const subtree& get_node(size_t which) const
00355     { return imp_get_node(which); }
00356 
00357     subtree*       get_parent(void)        { return parent; }
00358     const subtree* get_parent(void) const  { return parent; }
00359 
00360         void clear(void)
00361         { tree_allocator.deallocate(args, arity()); args = 0; *content = T(); parent = 0; _cumulative_size = 0; _depth = 0; _size = 0; }
00362 
00363         void swap(subtree& y)
00364         {
00365         do_the_swap(content, y.content);
00366         do_the_swap(args, y.args);
00367 
00368         adopt();
00369         y.adopt();
00370 
00371         do_the_swap(parent, y.parent);
00372 
00373         do_the_swap(_cumulative_size, y._cumulative_size);
00374         do_the_swap(_depth, y._depth);
00375         do_the_swap(_size, y._size);
00376                 updateAfterInsert();
00377         }
00378 
00379 protected :
00380 
00381         virtual void updateAfterInsert(void)
00382     {
00383         _depth = 0;
00384         _size = 1;
00385         _cumulative_size = 0;
00386 
00387         for (iterator it = begin(); it != end(); ++it)
00388         {
00389             _size += it->size();
00390             _cumulative_size += it->_cumulative_size;
00391             _depth = it->_depth > _depth? it->_depth: _depth;
00392         }
00393         _cumulative_size += _size;
00394         _depth++;
00395 
00396         if (parent)
00397             parent->updateAfterInsert();
00398     }
00399 
00400 private :
00401 
00402     const subtree& imp_select_cumulative(size_t which) const
00403     {
00404         if (which >= (_cumulative_size - size()))
00405             return *this;
00406         // else
00407 
00408         for (int i = arity() - 1; i >= 0; --i)
00409                 {
00410             if (which < args[i]._cumulative_size)
00411                 return args[i].imp_select_cumulative(which);
00412             which -= args[i]._cumulative_size;
00413         }
00414 
00415         return *this; // error!
00416     }
00417 
00418     const subtree& imp_get_node(size_t which) const
00419     {
00420         if (which == size() - 1)
00421             return *this;
00422 
00423         for (int i = arity() - 1; i >= 0; --i)
00424                 {
00425             unsigned c_size = args[i].size();
00426             if (which < c_size)
00427                 return args[i].imp_get_node(which);
00428             which -= c_size;
00429         }
00430 
00431         return *this; // error!
00432     }
00433 
00434     const subtree* get_root(void) const
00435     {
00436         if (parent == 0)
00437             return this;
00438         // else
00439 
00440         return parent->get_root();
00441     }
00442     subtree& copy(const subtree& s)
00443     {
00444                 int old_arity = arity();
00445 
00446                 int new_arity = s.arity();
00447 
00448                 if (new_arity != old_arity)
00449                 {
00450                         tree_allocator.deallocate(args, old_arity);
00451 
00452             args = tree_allocator.allocate(new_arity);
00453                 }
00454 
00455                 switch(new_arity)
00456                 {
00457                 case 3 : args[2].copy(s.args[2]); args[2].parent = this; // no break!
00458                 case 2 : args[1].copy(s.args[1]); args[1].parent = this;
00459                 case 1 : args[0].copy(s.args[0]); args[0].parent = this;
00460                 case 0 : break;
00461                 default :
00462                         {
00463                                 for (int i = 0; i < new_arity; ++i)
00464                                 {
00465                                         args[i].copy(s.args[i]);
00466                     args[i].parent = this;
00467                                 }
00468                         }
00469                 }
00470 
00471                 *content = *s.content;
00472         _size = s._size;
00473         _depth = s._depth;
00474         _cumulative_size = s._cumulative_size;
00475 
00476         return *this;
00477     }
00478 
00479     subtree& copy(const T& t)
00480     {
00481         int oldArity = arity();
00482 
00483                 if (content != &t)
00484             *content = t;
00485                 else
00486                         oldArity = -1;
00487 
00488                 int ar = arity();
00489 
00490                 if (ar != oldArity)
00491                 {
00492             if (oldArity != -1)
00493                             tree_allocator.deallocate(args, oldArity);
00494 
00495             args = tree_allocator.allocate(ar);
00496 
00497             //if (ar > 0)
00498                         //      args = new subtree [ar];
00499                         //else
00500                         //      args = 0;
00501                 }
00502 
00503         adopt();
00504         updateAfterInsert();
00505                 return *this;
00506     }
00507 
00508         void disown(void)
00509         {
00510                 switch(arity())
00511                 {
00512                 case 3 : args[2].parent = 0; // no break!
00513                 case 2 : args[1].parent = 0;
00514                 case 1 : args[0].parent = 0; break;
00515                 case 0 : break;
00516                 default :
00517                         {
00518                                 for (iterator it = begin(); it != end(); ++it)
00519                                 {
00520                                         it->parent = 0;
00521                                 }
00522                         }
00523                 }
00524 
00525         }
00526 
00527     void adopt(void)
00528     {
00529                 switch(arity())
00530                 {
00531                 case 3 : args[2].parent = this; // no break!
00532                 case 2 : args[1].parent = this;
00533                 case 1 : args[0].parent = this; break;
00534                 case 0 : break;
00535                 default :
00536                         {
00537                                 for (iterator it = begin(); it != end(); ++it)
00538                                 {
00539                                         it->parent = this;
00540                                 }
00541                         }
00542                 }
00543     }
00544 
00545     template <class It>
00546     void init(It b, It& last)
00547     {
00548         *this = *last;
00549 
00550 #ifndef NDEBUG
00551         if (last == b && arity() > 0)
00552         {
00553             throw "subtree::init()";
00554         }
00555 #endif
00556 
00557         for (int i = 0; i < arity(); ++i)
00558         {
00559             args[i].parent = 0;
00560             args[i].init(b, --last);
00561             args[i].parent = this;
00562         }
00563 
00564         updateAfterInsert();
00565     }
00566 
00567     T* content;
00568     subtree*                    args;
00569     subtree*                    parent;
00570 
00571         size_t _cumulative_size;
00572     size_t _depth;
00573     size_t _size;
00574 };
00575 
00576 // Continuing with parse_tree
00577 
00578     typedef T value_type;
00579 
00580         /* Constructors and Assignments */
00581 
00582     parse_tree(void) : _root(), pushed() {}
00583     parse_tree(const parse_tree& org) : _root(org._root), pushed(org.pushed) { }
00584     parse_tree(const subtree& sub) : _root(sub), pushed() { }
00585 
00586     template <class It>
00587         parse_tree(It b, It e) : _root(b, e), pushed() {}
00588 
00589     virtual ~parse_tree(void) {}
00590 
00591     parse_tree& operator=(const parse_tree& org) { return copy(org); }
00592         parse_tree& operator=(const subtree& sub)
00593                 { return copy(sub); }
00594 
00595 
00596         /* Equality and inequality */
00597 
00598         bool operator==(const parse_tree& other) const
00599         { return _root == other._root; }
00600 
00601         bool operator !=(const parse_tree& other) const
00602         { return !operator==(other); }
00603 
00604         /* Simple tree statistics */
00605 
00606     size_t size(void) const  { return _root.size(); }
00607         size_t depth(void) const { return _root.depth(); }
00608     void clear(void)        { _root.clear(); pushed.resize(0); }
00609 
00610         /* Evaluation (application), with an increasing number of user defined arguments */
00611 
00612         template <class RetVal>
00613         void apply(RetVal& v) const
00614                 { _root.apply(v); }
00615 
00616         template <class RetVal, class It>
00617                 void apply(RetVal& v, It varValues) const
00618                 { _root.apply(v, varValues); }
00619 
00620     template <class RetVal, class It>
00621         void apply_mem_func(RetVal& v, It misc, void (T::* f)(RetVal&, typename subtree::iterator, It))
00622     {
00623         _root.apply_mem_func(v, misc, f);
00624     }
00625 
00626         //template <class RetVal, class It, class It2>
00627         //      void apply(RetVal& v, It varValues, It2 moreValues) const
00628         //      { _root.apply(v, varValues, moreValues); }
00629 
00630         //template <class RetVal, class It, class It2, class It3>
00631         //      void apply(RetVal& v, It varValues, It2 moreValues, It3 evenMoreValues) const
00632         //      { _root.apply(v, varValues, moreValues, evenMoreValues); }
00633 
00634     template <class Pred>
00635     void find_nodes(std::vector<subtree*>& result, Pred& p)
00636     {
00637         _root.find_nodes(result, p);
00638     }
00639 
00640     template <class Pred>
00641     void find_nodes(std::vector<const subtree*>& result, Pred& p) const
00642     {
00643         _root.find_nodes(p);
00644     }
00645 
00646         /* Customized Swap */
00647         void swap(parse_tree<T>& other)
00648         {
00649                 do_the_swap(pushed, other.pushed);
00650                 _root.swap(other._root);
00651         }
00652 
00653         /* Definitions of the iterators */
00654 
00655     class base_iterator
00656     {
00657     public :
00658 
00659         base_iterator() {}
00660         base_iterator(subtree* n)  { node = n; }
00661 
00662         base_iterator& operator=(const base_iterator& org)
00663         { node = org.node; return *this; }
00664 
00665         bool operator==(const base_iterator& org) const
00666         { return node == org.node; }
00667         bool operator!=(const base_iterator& org) const
00668         { return !operator==(org); }
00669 
00670                 base_iterator operator+(size_t n) const
00671                 {
00672                         base_iterator tmp = *this;
00673 
00674                         for(;n != 0; --n)
00675                         {
00676                                 ++tmp;
00677                         }
00678 
00679                         return tmp;
00680                 }
00681 
00682                 base_iterator& operator++(void)
00683         {
00684             subtree* parent = node->get_parent();
00685 
00686             if (parent == 0)
00687             {
00688                 node = 0;
00689                 return *this;
00690             }
00691             // else
00692             typename subtree::iterator it;
00693             for (it = parent->begin(); it != parent->end(); ++it)
00694             {
00695                 if (node == &(*it))
00696                     break;
00697             }
00698 
00699             if (it == parent->begin())
00700                 node = parent;
00701             else
00702             {
00703                 node = &(--it)->get_node(0);
00704             }
00705 
00706             return *this;
00707         }
00708 
00709         base_iterator operator++(int)
00710         {
00711             base_iterator tmp = *this;
00712             operator++();
00713             return tmp;
00714         }
00715 
00716     protected :
00717         subtree* node;
00718     };
00719 
00720     class iterator : public base_iterator
00721     {
00722     public:
00723 
00724         using base_iterator::node;
00725 
00726         typedef std::forward_iterator_tag iterator_category;
00727         typedef subtree value_type;
00728         typedef size_t distance_type;
00729         typedef size_t difference_type;
00730         typedef subtree* pointer;
00731         typedef subtree& reference;
00732 
00733         iterator() : base_iterator() {}
00734         iterator(subtree* n): base_iterator(n)  {}
00735         iterator& operator=(const iterator& org)
00736         { base_iterator::operator=(org); return *this; }
00737 
00738         subtree& operator*(void)  { return *node; }
00739         subtree* operator->(void) { return node; }
00740     };
00741 
00742 
00743 
00744     class embedded_iterator : public base_iterator
00745     {
00746     public:
00747 
00748         using base_iterator::node;
00749 
00750         typedef std::forward_iterator_tag iterator_category;
00751         typedef T value_type;
00752         typedef size_t distance_type;
00753         typedef size_t difference_type;
00754         typedef T* pointer;
00755         typedef T& reference;
00756 
00757         embedded_iterator() : base_iterator() {}
00758         embedded_iterator(subtree* n): base_iterator(n)  {}
00759         embedded_iterator& operator=(const embedded_iterator& org)
00760         { base_iterator::operator=(org); return *this; }
00761 
00762         T&  operator*(void)  { return **node; }
00763         T* operator->(void) { return &**node; }
00764     };
00765 
00766     class base_const_iterator
00767     {
00768     public:
00769 
00770         base_const_iterator() {}
00771         base_const_iterator(const subtree* n)  { node = n; }
00772 
00773         base_const_iterator& operator=(const base_const_iterator& org)
00774         { node = org.node; return *this; }
00775 
00776         bool operator==(const base_const_iterator& org) const
00777         { return node == org.node; }
00778         bool operator!=(const base_const_iterator& org) const
00779         { return !operator==(org); }
00780 
00781         base_const_iterator& operator++(void)
00782         {
00783             const subtree* parent = node->get_parent();
00784 
00785             if (parent == 0)
00786             {
00787                 node = 0;
00788                 return *this;
00789             }
00790             // else
00791             typename subtree::const_iterator it;
00792 
00793             for (it = parent->begin(); it != parent->end(); ++it)
00794             {
00795                 if (node == &(*it))
00796                     break;
00797             }
00798 
00799             if (it == parent->begin())
00800                 node = parent;
00801             else
00802                 node = &(--it)->get_node(0);
00803             return *this;
00804         }
00805 
00806         base_const_iterator operator++(int)
00807         {
00808             base_const_iterator tmp = *this;
00809             operator++();
00810             return tmp;
00811         }
00812 
00813     protected :
00814 
00815         const subtree* node;
00816     };
00817 
00818     class const_iterator : public base_const_iterator
00819     {
00820     public:
00821 
00822         using base_iterator::node;
00823 
00824         typedef std::forward_iterator_tag iterator_category;
00825         typedef const subtree value_type;
00826         typedef size_t distance_type;
00827         typedef size_t difference_type;
00828         typedef const subtree* pointer;
00829         typedef const subtree& reference;
00830 
00831         const_iterator() : base_const_iterator() {}
00832         const_iterator(const subtree* n): base_const_iterator(n)  {}
00833         const_iterator& operator=(const const_iterator& org)
00834         { base_const_iterator::operator=(org); return *this; }
00835 
00836         const subtree& operator*(void)  { return *node; }
00837         const subtree* operator->(void) { return node; }
00838     };
00839 
00840     class embedded_const_iterator : public base_const_iterator
00841     {
00842     public:
00843 
00844         using base_const_iterator::node;
00845 
00846                 typedef std::forward_iterator_tag iterator_category;
00847                 typedef const T value_type;
00848                 typedef size_t distance_type;
00849                 typedef size_t difference_type;
00850                 typedef const T* pointer;
00851                 typedef const T& reference;
00852 
00853         embedded_const_iterator() : base_const_iterator() {}
00854         embedded_const_iterator(const subtree* n): base_const_iterator(n)  {}
00855         embedded_const_iterator& operator=(const embedded_const_iterator& org)
00856         { base_const_iterator::operator=(org); return *this; }
00857 
00858                 embedded_const_iterator operator+(size_t n) const
00859                 {
00860                         embedded_const_iterator tmp = *this;
00861 
00862                         for(;n != 0; --n)
00863                         {
00864                                 ++tmp;
00865                         }
00866 
00867                         return tmp;
00868                 }
00869 
00870         const T&  operator*(void)  const { return **node; }
00871         const T*  operator->(void) const { return node->operator->(); }
00872     };
00873 
00874         /* Iterator access */
00875 
00876     iterator begin(void)            { return iterator(&operator[](0)); }
00877     const_iterator begin(void) const { return const_iterator(&operator[](0)); }
00878     iterator end(void)               { return iterator(0); }
00879     const_iterator end(void) const   { return const_iterator(0);}
00880 
00881     embedded_iterator       ebegin(void)       { return embedded_iterator(&operator[](0)); }
00882     embedded_const_iterator ebegin(void) const { return embedded_const_iterator(&operator[](0)); }
00883     embedded_iterator       eend(void)         { return embedded_iterator(0); }
00884     embedded_const_iterator eend(void) const   { return embedded_const_iterator(0);}
00885 
00886     bool empty(void) const { return size() == 0; }
00887     bool valid(void) const { return pushed.empty(); }
00888 
00889         /* push_back */
00890 
00891         void push_back(const parse_tree<T>& tree)
00892         {
00893                 if (!empty())
00894                         pushed.push_back(_root);
00895 
00896                 _root = tree.back();
00897         }
00898 
00899     void push_back(const T& t)
00900     {
00901         if (!empty())
00902             pushed.push_back(_root);
00903 
00904                 _root = t;
00905 
00906         for (typename subtree::iterator it = _root.begin(); it != _root.end(); it++)
00907         {
00908                         *it = pushed.back();
00909             pushed.pop_back();
00910         }
00911 
00912     }
00913 
00914         /* Access to subtrees */
00915 
00916     subtree& back(void)              { return _root; }
00917     const subtree& back(void) const  { return _root; }
00918     subtree& root(void)              { return _root; }
00919     const subtree& root(void) const  { return _root; }
00920 
00921     subtree& front(void)              { return _root[0]; }
00922     const subtree& front(void) const  { return _root[0]; }
00923 
00924     subtree& operator[](size_t i)
00925     { return const_cast<subtree&>(_root.get_node(i)); }
00926     const subtree& operator[](size_t i) const
00927     { return _root.get_node(i); }
00928 
00929     subtree& get_cumulative(size_t i)
00930     { return const_cast<subtree&>(_root.get_cumulative(i)); }
00931     const subtree& get_cumulative(size_t i) const
00932     { return get_cumulative(i); }
00933 
00934     private :
00935 
00936     parse_tree& copy(const parse_tree& org)
00937     {
00938         _root = org._root;
00939         pushed = org.pushed;
00940 
00941         return *this;
00942     }
00943 
00944         parse_tree& copy(const subtree& sub)
00945     { _root = sub; pushed.resize(0); return *this; }
00946 
00947     subtree _root;
00948     std::vector<subtree > pushed;
00949 }; // end class parse_tree
00950 
00951 
00952 } // end namespace gp_parse_tree
00953 
00954 namespace std
00955 { // for use with stlport on MSVC
00956 
00957 template <class T> inline
00958 std::forward_iterator_tag iterator_category(typename gp_parse_tree::parse_tree<T>::embedded_iterator)
00959 {
00960         return std::forward_iterator_tag();
00961 }
00962 
00963 template <class T> inline
00964 ptrdiff_t*  distance_type(typename gp_parse_tree::parse_tree<T>::embedded_iterator)
00965 {
00966         return 0;
00967 }
00968 
00969 template <class T> inline
00970 std::forward_iterator_tag iterator_category(typename gp_parse_tree::parse_tree<T>::iterator)
00971 {
00972         return std::forward_iterator_tag();
00973 }
00974 
00975 template <class T> inline
00976 ptrdiff_t*  distance_type(typename gp_parse_tree::parse_tree<T>::iterator)
00977 {
00978         return 0;
00979 }
00980 
00981 /* Put customized swaps also in std...
00982 
00983 template<class T> inline
00984 void swap(gp_parse_tree::parse_tree<T>& a, gp_parse_tree::parse_tree<T>& b)
00985 {
00986     a.swap(b);
00987 }
00988 
00989 template<class T> inline
00990 void iter_swap(std::vector<gp_parse_tree::parse_tree<T> >::iterator a, std::vector<gp_parse_tree::parse_tree<T> > b)
00991 {
00992     a->swap(*b);
00993 }*/
00994 
00995 
00996 } // namespace std
00997 
00998 
00999 #endif

Generated on Thu Oct 19 05:06:41 2006 for EO by  doxygen 1.3.9.1