From 6cdca190d9bcd417eb9ee26b0d4cc0f455e86d82 Mon Sep 17 00:00:00 2001 From: Christian Bauer Date: Tue, 25 May 2004 19:03:42 +0000 Subject: [PATCH] synced to HEAD (pre/postorder iterators) --- ginac/ex.h | 75 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 46 insertions(+), 29 deletions(-) diff --git a/ginac/ex.h b/ginac/ex.h index 95115a30..473b2700 100644 --- a/ginac/ex.h +++ b/ginac/ex.h @@ -55,14 +55,15 @@ static library_init library_initializer; class scalar_products; class const_iterator; +class const_preorder_iterator; +class const_postorder_iterator; /** Lightweight wrapper for GiNaC's symbolic objects. Basically all it does is * to hold a pointer to the other objects, manage the reference counting and * provide methods for manipulation of these objects. (Some people call such * a thing a proxy class.) */ -class ex -{ +class ex { friend class archive_node; friend inline bool are_ex_trivially_equal(const ex &, const ex &); template friend inline const T &ex_to(const ex &); @@ -106,6 +107,10 @@ public: // iterators const_iterator begin() const throw(); const_iterator end() const throw(); + const_preorder_iterator preorder_begin() const; + const_preorder_iterator preorder_end() const throw(); + const_postorder_iterator postorder_begin() const; + const_postorder_iterator postorder_end() const throw(); // evaluation ex eval(int level = 0) const { return bp->eval(level); } @@ -381,8 +386,7 @@ bool ex::is_equal(const ex & other) const // Iterators -class const_iterator : public std::iterator -{ +class const_iterator : public std::iterator { friend class ex; friend class const_preorder_iterator; friend class const_postorder_iterator; @@ -528,27 +532,24 @@ struct _iter_rep { } // namespace internal -class const_preorder_iterator : public std::iterator -{ +class const_preorder_iterator : public std::iterator { public: const_preorder_iterator() throw() {} - // Provide implicit conversion from const_iterator, so ex::begin() and - // ex::end() can be used to create const_preorder_iterators - const_preorder_iterator(const const_iterator & cit) + const_preorder_iterator(const ex &e, size_t n) { - s.push(internal::_iter_rep(cit.e, cit.i, cit.e.nops())); + s.push(internal::_iter_rep(e, 0, n)); } public: - ex operator*() const + reference operator*() const { return s.top().e; } - std::auto_ptr operator->() const + pointer operator->() const { - return std::auto_ptr(new ex(operator*())); + return &(s.top().e); } const_preorder_iterator &operator++() @@ -566,7 +567,7 @@ public: bool operator==(const const_preorder_iterator &other) const throw() { - return s.top() == other.s.top(); + return s == other.s; } bool operator!=(const const_preorder_iterator &other) const throw() @@ -579,8 +580,10 @@ private: void increment() { - while (s.top().i == s.top().i_end && s.size() > 1) { + while (!s.empty() && s.top().i == s.top().i_end) { s.pop(); + if (s.empty()) + return; ++s.top().i; } @@ -593,31 +596,25 @@ private: } }; -class const_postorder_iterator : public std::iterator -{ +class const_postorder_iterator : public std::iterator { public: const_postorder_iterator() throw() {} - // Provide implicit conversion from const_iterator, so ex::begin() and - // ex::end() can be used to create const_postorder_iterators - const_postorder_iterator(const const_iterator & cit) + const_postorder_iterator(const ex &e, size_t n) { - size_t n = cit.e.nops(); - if (cit.i != n) { - s.push(internal::_iter_rep(cit.e, cit.i, n)); - descend(); - } + s.push(internal::_iter_rep(e, 0, n)); + descend(); } public: - ex operator*() const + reference operator*() const { return s.top().e; } - std::auto_ptr operator->() const + pointer operator->() const { - return std::auto_ptr(new ex(operator*())); + return &(s.top().e); } const_postorder_iterator &operator++() @@ -659,7 +656,7 @@ private: { if (s.top().i == s.top().i_end) s.pop(); - if (s.size() > 0) { + if (!s.empty()) { ++s.top().i; descend(); } @@ -676,6 +673,26 @@ inline const_iterator ex::end() const throw() return const_iterator(*this, nops()); } +inline const_preorder_iterator ex::preorder_begin() const +{ + return const_preorder_iterator(*this, nops()); +} + +inline const_preorder_iterator ex::preorder_end() const throw() +{ + return const_preorder_iterator(); +} + +inline const_postorder_iterator ex::postorder_begin() const +{ + return const_postorder_iterator(*this, nops()); +} + +inline const_postorder_iterator ex::postorder_end() const throw() +{ + return const_postorder_iterator(); +} + // utility functions -- 2.49.0