diff options
author | John Wiegley <johnw@newartisans.com> | 2011-07-19 23:29:41 -0500 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2011-07-19 23:29:41 -0500 |
commit | cf35984971341b8a8688eb02a22bcbc1772991d1 (patch) | |
tree | 8defec43b26a6cf9a216dac8b41d79504c32ad93 /src | |
parent | 966b6fc359bacad6b22e79fd5afbec0ea80e8d6a (diff) | |
download | fork-ledger-cf35984971341b8a8688eb02a22bcbc1772991d1.tar.gz fork-ledger-cf35984971341b8a8688eb02a22bcbc1772991d1.tar.bz2 fork-ledger-cf35984971341b8a8688eb02a22bcbc1772991d1.zip |
Use Boost iterator_facade to create new iterators
Diffstat (limited to 'src')
-rw-r--r-- | src/convert.cc | 6 | ||||
-rw-r--r-- | src/filters.cc | 40 | ||||
-rw-r--r-- | src/filters.h | 42 | ||||
-rw-r--r-- | src/generate.cc | 10 | ||||
-rw-r--r-- | src/generate.h | 6 | ||||
-rw-r--r-- | src/iterators.cc | 111 | ||||
-rw-r--r-- | src/iterators.h | 110 | ||||
-rw-r--r-- | src/py_journal.cc | 2 | ||||
-rw-r--r-- | src/report.cc | 49 | ||||
-rw-r--r-- | src/system.hh.in | 1 |
10 files changed, 211 insertions, 166 deletions
diff --git a/src/convert.cc b/src/convert.cc index 3a9a143d..5d4925c4 100644 --- a/src/convert.cc +++ b/src/convert.cc @@ -62,10 +62,10 @@ value_t convert_command(call_scope_t& args) post_map_t post_map; xacts_iterator journal_iter(journal); - while (xact_t * xact = journal_iter()) { + while (xact_t * xact = *journal_iter++) { post_t * post = NULL; xact_posts_iterator xact_iter(*xact); - while ((post = xact_iter()) != NULL) { + while ((post = *xact_iter++) != NULL) { if (post->account == bucket) break; } @@ -137,7 +137,7 @@ value_t convert_command(call_scope_t& args) } else { xact_posts_iterator xact_iter(*xact); - while (post_t * post = xact_iter()) + while (post_t * post = *xact_iter++) formatter(*post); } } diff --git a/src/filters.cc b/src/filters.cc index 27227ee9..b7e96366 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -83,25 +83,6 @@ void post_splitter::operator()(post_t& post) } } -pass_down_posts::pass_down_posts(post_handler_ptr handler, - posts_iterator& iter) - : item_handler<post_t>(handler) -{ - TRACE_CTOR(pass_down_posts, "post_handler_ptr, posts_iterator"); - - for (post_t * post = iter(); post; post = iter()) { - try { - item_handler<post_t>::operator()(*post); - } - catch (const std::exception&) { - add_error_context(item_context(*post, _("While handling posting"))); - throw; - } - } - - item_handler<post_t>::flush(); -} - void truncate_xacts::flush() { if (! posts.size()) @@ -1419,25 +1400,4 @@ void inject_posts::operator()(post_t& post) item_handler<post_t>::operator()(post); } -pass_down_accounts::pass_down_accounts(acct_handler_ptr handler, - accounts_iterator& iter, - const optional<predicate_t>& _pred, - const optional<scope_t&>& _context) - : item_handler<account_t>(handler), pred(_pred), context(_context) -{ - TRACE_CTOR(pass_down_accounts, "acct_handler_ptr, accounts_iterator, ..."); - - for (account_t * account = iter(); account; account = iter()) { - if (! pred) { - item_handler<account_t>::operator()(*account); - } else { - bind_scope_t bound_scope(*context, *account); - if ((*pred)(bound_scope)) - item_handler<account_t>::operator()(*account); - } - } - - item_handler<account_t>::flush(); -} - } // namespace ledger diff --git a/src/filters.h b/src/filters.h index 2fcf0961..4c096571 100644 --- a/src/filters.h +++ b/src/filters.h @@ -146,14 +146,28 @@ public: } }; -class posts_iterator; - +template <typename Iterator> class pass_down_posts : public item_handler<post_t> { pass_down_posts(); public: - pass_down_posts(post_handler_ptr handler, posts_iterator& iter); + pass_down_posts(post_handler_ptr handler, Iterator& iter) + : item_handler<post_t>(handler) { + TRACE_CTOR(pass_down_posts, "post_handler_ptr, posts_iterator"); + + while (post_t * post = *iter++) { + try { + item_handler<post_t>::operator()(*post); + } + catch (const std::exception&) { + add_error_context(item_context(*post, _("While handling posting"))); + throw; + } + } + + item_handler<post_t>::flush(); + } virtual ~pass_down_posts() { TRACE_DTOR(pass_down_posts); @@ -986,8 +1000,7 @@ class inject_posts : public item_handler<post_t> // Account filters // -class accounts_iterator; - +template <typename Iterator> class pass_down_accounts : public item_handler<account_t> { pass_down_accounts(); @@ -997,9 +1010,24 @@ class pass_down_accounts : public item_handler<account_t> public: pass_down_accounts(acct_handler_ptr handler, - accounts_iterator& iter, + Iterator& iter, const optional<predicate_t>& _pred = none, - const optional<scope_t&>& _context = none); + const optional<scope_t&>& _context = none) + : item_handler<account_t>(handler), pred(_pred), context(_context) { + TRACE_CTOR(pass_down_accounts, "acct_handler_ptr, accounts_iterator, ..."); + + while (account_t * account = *iter++) { + if (! pred) { + item_handler<account_t>::operator()(*account); + } else { + bind_scope_t bound_scope(*context, *account); + if ((*pred)(bound_scope)) + item_handler<account_t>::operator()(*account); + } + } + + item_handler<account_t>::flush(); + } virtual ~pass_down_accounts() { TRACE_DTOR(pass_down_accounts); diff --git a/src/generate.cc b/src/generate.cc index 05f754e6..60c6955e 100644 --- a/src/generate.cc +++ b/src/generate.cc @@ -350,9 +350,10 @@ void generate_posts_iterator::generate_xact(std::ostream& out) out << '\n'; } -post_t * generate_posts_iterator::operator()() +void generate_posts_iterator::increment() { - post_t * post = posts(); + post_t * post = *posts++; + if (post == NULL && quantity > 0) { std::ostringstream buf; generate_xact(buf); @@ -364,7 +365,7 @@ post_t * generate_posts_iterator::operator()() if (session.journal->parse(in, session) != 0) { VERIFY(session.journal->xacts.back()->valid()); posts.reset(*session.journal->xacts.back()); - post = posts(); + post = *posts++; } } catch (std::exception&) { @@ -382,7 +383,8 @@ post_t * generate_posts_iterator::operator()() quantity--; } - return post; + + m_node = post; } } // namespace ledger diff --git a/src/generate.h b/src/generate.h index 25ad41ea..f9207ff5 100644 --- a/src/generate.h +++ b/src/generate.h @@ -48,7 +48,9 @@ namespace ledger { class session_t; -class generate_posts_iterator : public posts_iterator +class generate_posts_iterator + : public iterator_facade_base<generate_posts_iterator, post_t *, + boost::forward_traversal_tag> { session_t& session; unsigned int seed; @@ -105,7 +107,7 @@ public: TRACE_DTOR(generate_posts_iterator); } - virtual post_t * operator()(); + virtual void increment(); protected: void generate_string(std::ostream& out, int len, bool only_alpha = false); diff --git a/src/iterators.cc b/src/iterators.cc index b63a10e9..bb7a587c 100644 --- a/src/iterators.cc +++ b/src/iterators.cc @@ -41,37 +41,38 @@ void xacts_iterator::reset(journal_t& journal) { xacts_i = journal.xacts.begin(); xacts_end = journal.xacts.end(); + xacts_uninitialized = false; + + increment(); } -xact_t * xacts_iterator::operator()() +void xacts_iterator::increment() { if (xacts_i != xacts_end) - return *xacts_i++; + m_node = *xacts_i++; else - return NULL; + m_node = NULL; } void journal_posts_iterator::reset(journal_t& journal) { xacts.reset(journal); - - xact_t * xact = xacts(); - if (xact != NULL) - posts.reset(*xact); + increment(); } -post_t * journal_posts_iterator::operator()() +void journal_posts_iterator::increment() { - post_t * post = posts(); - if (post == NULL) { - xact_t * xact = xacts(); - if (xact != NULL) { - posts.reset(*xact); - post = posts(); - } + if (post_t * post = *posts++) { + m_node = post; + } + else if (xact_t * xact = *xacts++) { + posts.reset(*xact); + m_node = *posts++; + } + else { + m_node = NULL; } - return post; } void posts_commodities_iterator::reset(journal_t& journal) @@ -80,7 +81,7 @@ void posts_commodities_iterator::reset(journal_t& journal) std::set<commodity_t *> commodities; - for (post_t * post = journal_posts(); post; post = journal_posts()) { + while (const post_t * post = *journal_posts++) { commodity_t& comm(post->amount.commodity()); if (comm.flags() & COMMODITY_NOMARKET) continue; @@ -136,47 +137,44 @@ void posts_commodities_iterator::reset(journal_t& journal) } } - xacts.xacts_i = xact_temps.begin(); - xacts.xacts_end = xact_temps.end(); + xacts.reset(xact_temps.begin(), xact_temps.end()); - xacts.xacts_uninitialized = false; - - xact_t * xact = xacts(); - if (xact != NULL) - posts.reset(*xact); + increment(); } -post_t * posts_commodities_iterator::operator()() +void posts_commodities_iterator::increment() { - post_t * post = posts(); - if (post == NULL) { - xact_t * xact = xacts(); - if (xact != NULL) { - posts.reset(*xact); - post = posts(); - } + if (post_t * post = *posts++) { + m_node = post; + } + else if (xact_t * xact = *xacts++) { + posts.reset(*xact); + m_node = *posts++; + } + else { + m_node = NULL; } - return post; } -account_t * basic_accounts_iterator::operator()() +void basic_accounts_iterator::increment() { - while (! accounts_i.empty() && - accounts_i.back() == accounts_end.back()) { + while (! accounts_i.empty() && accounts_i.back() == accounts_end.back()) { accounts_i.pop_back(); accounts_end.pop_back(); } - if (accounts_i.empty()) - return NULL; - account_t * account = (*(accounts_i.back()++)).second; - assert(account); + if (accounts_i.empty()) { + m_node = NULL; + } else { + account_t * account = (*(accounts_i.back()++)).second; + assert(account); - // If this account has children, queue them up to be iterated next. - if (! account->accounts.empty()) - push_back(*account); + // If this account has children, queue them up to be iterated next. + if (! account->accounts.empty()) + push_back(*account); - return account; + m_node = account; + } } void sorted_accounts_iterator::push_back(account_t& account) @@ -231,7 +229,7 @@ void sorted_accounts_iterator::sort_accounts(account_t& account, #endif } -account_t * sorted_accounts_iterator::operator()() +void sorted_accounts_iterator::increment() { while (! sorted_accounts_i.empty() && sorted_accounts_i.back() == sorted_accounts_end.back()) { @@ -240,19 +238,22 @@ account_t * sorted_accounts_iterator::operator()() assert(! accounts_list.empty()); accounts_list.pop_back(); } - if (sorted_accounts_i.empty()) - return NULL; - account_t * account = *sorted_accounts_i.back()++; - assert(account); + if (sorted_accounts_i.empty()) { + m_node = NULL; + } else { + account_t * account = *sorted_accounts_i.back()++; + assert(account); + + // If this account has children, queue them up to be iterated next. + if (! flatten_all && ! account->accounts.empty()) + push_back(*account); - // If this account has children, queue them up to be iterated next. - if (! flatten_all && ! account->accounts.empty()) - push_back(*account); + // Make sure the sorting value gets recalculated for this account + account->xdata().drop_flags(ACCOUNT_EXT_SORT_CALC); - // Make sure the sorting value gets recalculated for this account - account->xdata().drop_flags(ACCOUNT_EXT_SORT_CALC); - return account; + m_node = account; + } } } // namespace ledger diff --git a/src/iterators.h b/src/iterators.h index 5113d3b2..696b5911 100644 --- a/src/iterators.h +++ b/src/iterators.h @@ -51,14 +51,35 @@ namespace ledger { class journal_t; -class posts_iterator : public noncopyable +template <typename Derived, typename Value, typename CategoryOrTraversal> +class iterator_facade_base + : public boost::iterator_facade<Derived, Value, CategoryOrTraversal> { + typedef Value node_base; + public: - virtual ~posts_iterator() throw() {} - virtual post_t * operator()() = 0; + iterator_facade_base() : m_node(NULL) {} + + explicit iterator_facade_base(node_base p) : m_node(p) {} + + void increment(); + +private: + friend class boost::iterator_core_access; + + bool equal(iterator_facade_base const& other) const { + return this->m_node == other.m_node; + } + + node_base& dereference() const { return const_cast<node_base&>(m_node); } + +protected: + node_base m_node; }; -class xact_posts_iterator : public posts_iterator +class xact_posts_iterator + : public iterator_facade_base<xact_posts_iterator, post_t *, + boost::forward_traversal_tag> { posts_list::iterator posts_i; posts_list::iterator posts_end; @@ -74,7 +95,7 @@ public: TRACE_CTOR(xact_posts_iterator, "xact_t&"); reset(xact); } - virtual ~xact_posts_iterator() throw() { + ~xact_posts_iterator() throw() { TRACE_DTOR(xact_posts_iterator); } @@ -83,16 +104,21 @@ public: posts_end = xact.posts.end(); posts_uninitialized = false; + + increment(); } - virtual post_t * operator()() { + void increment() { if (posts_uninitialized || posts_i == posts_end) - return NULL; - return *posts_i++; + m_node = NULL; + else + m_node = *posts_i++; } }; -class xacts_iterator : public noncopyable +class xacts_iterator + : public iterator_facade_base<xacts_iterator, xact_t *, + boost::forward_traversal_tag> { public: xacts_list::iterator xacts_i; @@ -103,22 +129,35 @@ public: xacts_iterator() : xacts_uninitialized(true) { TRACE_CTOR(xacts_iterator, ""); } - xacts_iterator(journal_t& journal) : xacts_uninitialized(true) { + xacts_iterator(journal_t& journal) : xacts_uninitialized(false) { TRACE_CTOR(xacts_iterator, "journal_t&"); reset(journal); } - virtual ~xacts_iterator() throw() { + xacts_iterator(xacts_list::iterator beg, + xacts_list::iterator end) : xacts_uninitialized(false) { + TRACE_CTOR(xacts_iterator, "xacts_list::iterator, xacts_list::iterator"); + reset(beg, end); + } + ~xacts_iterator() throw() { TRACE_DTOR(xacts_iterator); } void reset(journal_t& journal); - xact_t * operator()(); + void reset(xacts_list::iterator beg, xacts_list::iterator end) { + xacts_i = beg; + xacts_end = end; + increment(); + } + + void increment(); }; -class journal_posts_iterator : public posts_iterator +class journal_posts_iterator + : public iterator_facade_base<journal_posts_iterator, post_t *, + boost::forward_traversal_tag> { - xacts_iterator xacts; + xacts_iterator xacts; xact_posts_iterator posts; public: @@ -129,16 +168,18 @@ public: TRACE_CTOR(journal_posts_iterator, "journal_t&"); reset(journal); } - virtual ~journal_posts_iterator() throw() { + ~journal_posts_iterator() throw() { TRACE_DTOR(journal_posts_iterator); } void reset(journal_t& journal); - virtual post_t * operator()(); + void increment(); }; -class posts_commodities_iterator : public posts_iterator +class posts_commodities_iterator + : public iterator_facade_base<posts_commodities_iterator, post_t *, + boost::forward_traversal_tag> { protected: journal_posts_iterator journal_posts; @@ -155,23 +196,18 @@ public: TRACE_CTOR(posts_commodities_iterator, "journal_t&"); reset(journal); } - virtual ~posts_commodities_iterator() throw() { + ~posts_commodities_iterator() throw() { TRACE_DTOR(posts_commodities_iterator); } void reset(journal_t& journal); - virtual post_t * operator()(); -}; - -class accounts_iterator : public noncopyable -{ -public: - virtual ~accounts_iterator() throw() {} - virtual account_t * operator()() = 0; + void increment(); }; -class basic_accounts_iterator : public accounts_iterator +class basic_accounts_iterator + : public iterator_facade_base<basic_accounts_iterator, account_t *, + boost::forward_traversal_tag> { std::list<accounts_map::const_iterator> accounts_i; std::list<accounts_map::const_iterator> accounts_end; @@ -183,20 +219,24 @@ public: basic_accounts_iterator(account_t& account) { TRACE_CTOR(basic_accounts_iterator, "account_t&"); push_back(account); + increment(); } - virtual ~basic_accounts_iterator() throw() { + ~basic_accounts_iterator() throw() { TRACE_DTOR(basic_accounts_iterator); } + void increment(); + +private: void push_back(account_t& account) { accounts_i.push_back(account.accounts.begin()); accounts_end.push_back(account.accounts.end()); } - - virtual account_t * operator()(); }; -class sorted_accounts_iterator : public accounts_iterator +class sorted_accounts_iterator + : public iterator_facade_base<sorted_accounts_iterator, account_t *, + boost::forward_traversal_tag> { expr_t sort_cmp; bool flatten_all; @@ -213,16 +253,18 @@ public: : sort_cmp(_sort_cmp), flatten_all(_flatten_all) { TRACE_CTOR(sorted_accounts_iterator, "const expr_t&, bool, account_t&"); push_back(account); + increment(); } - virtual ~sorted_accounts_iterator() throw() { + ~sorted_accounts_iterator() throw() { TRACE_DTOR(sorted_accounts_iterator); } + void increment(); + +private: void push_back(account_t& account); void push_all(account_t& account, accounts_deque_t& deque); void sort_accounts(account_t& account, accounts_deque_t& deque); - - virtual account_t * operator()(); }; } // namespace ledger diff --git a/src/py_journal.cc b/src/py_journal.cc index a06ef8e2..cb629f62 100644 --- a/src/py_journal.cc +++ b/src/py_journal.cc @@ -191,7 +191,7 @@ namespace { coll->chain = chain_post_handlers(post_handler_ptr(coll->posts_collector), coll->report); - pass_down_posts(coll->chain, walker); + pass_down_posts<journal_posts_iterator>(coll->chain, walker); } catch (...) { current_report.session.journal.release(); diff --git a/src/report.cc b/src/report.cc index 5fff77c7..91b9025d 100644 --- a/src/report.cc +++ b/src/report.cc @@ -318,7 +318,7 @@ void report_t::posts_report(post_handler_ptr handler) handler = chain_pre_post_handlers(handler, *this); journal_posts_iterator walker(*session.journal.get()); - pass_down_posts(handler, walker); + pass_down_posts<journal_posts_iterator>(handler, walker); if (! HANDLED(group_by_)) posts_flusher(handler, *this)(value_t()); @@ -334,7 +334,7 @@ void report_t::generate_report(post_handler_ptr handler) HANDLED(head_) ? static_cast<unsigned int>(HANDLER(head_).value.to_long()) : 50); - pass_down_posts(handler, walker); + pass_down_posts<generate_posts_iterator>(handler, walker); } void report_t::xact_report(post_handler_ptr handler, xact_t& xact) @@ -342,7 +342,7 @@ void report_t::xact_report(post_handler_ptr handler, xact_t& xact) handler = chain_handlers(handler, *this); xact_posts_iterator walker(xact); - pass_down_posts(handler, walker); + pass_down_posts<xact_posts_iterator>(handler, walker); xact.clear_xdata(); } @@ -382,25 +382,34 @@ namespace { report.HANDLER(display_total_).expr.mark_uncompiled(); report.HANDLER(revalued_total_).expr.mark_uncompiled(); - scoped_ptr<accounts_iterator> iter; - if (! report.HANDLED(sort_)) { - iter.reset(new basic_accounts_iterator(*report.session.journal->master)); - } else { - expr_t sort_expr(report.HANDLER(sort_).str()); - sort_expr.set_context(&report); - iter.reset(new sorted_accounts_iterator(*report.session.journal->master, - sort_expr, report.HANDLED(flat))); - } - if (report.HANDLED(display_)) { DEBUG("report.predicate", "Display predicate = " << report.HANDLER(display_).str()); - pass_down_accounts(handler, *iter.get(), - predicate_t(report.HANDLER(display_).str(), - report.what_to_keep()), - report); + if (! report.HANDLED(sort_)) { + basic_accounts_iterator iter(*report.session.journal->master); + pass_down_accounts<basic_accounts_iterator> + (handler, iter, predicate_t(report.HANDLER(display_).str(), + report.what_to_keep()), report); + } else { + expr_t sort_expr(report.HANDLER(sort_).str()); + sort_expr.set_context(&report); + sorted_accounts_iterator iter(*report.session.journal->master, + sort_expr, report.HANDLED(flat)); + pass_down_accounts<sorted_accounts_iterator> + (handler, iter, predicate_t(report.HANDLER(display_).str(), + report.what_to_keep()), report); + } } else { - pass_down_accounts(handler, *iter.get()); + if (! report.HANDLED(sort_)) { + basic_accounts_iterator iter(*report.session.journal->master); + pass_down_accounts<basic_accounts_iterator>(handler, iter); + } else { + expr_t sort_expr(report.HANDLER(sort_).str()); + sort_expr.set_context(&report); + sorted_accounts_iterator iter(*report.session.journal->master, + sort_expr, report.HANDLED(flat)); + pass_down_accounts<sorted_accounts_iterator>(handler, iter); + } } report.session.journal->clear_xdata(); @@ -428,7 +437,7 @@ void report_t::accounts_report(acct_handler_ptr handler) // objects created within it during the call to pass_down_posts, which will // be needed later by the pass_down_accounts. journal_posts_iterator walker(*session.journal.get()); - pass_down_posts(chain, walker); + pass_down_posts<journal_posts_iterator>(chain, walker); if (! HANDLED(group_by_)) accounts_flusher(handler, *this)(value_t()); @@ -439,7 +448,7 @@ void report_t::commodities_report(post_handler_ptr handler) handler = chain_handlers(handler, *this); posts_commodities_iterator walker(*session.journal.get()); - pass_down_posts(handler, walker); + pass_down_posts<posts_commodities_iterator>(handler, walker); session.journal->clear_xdata(); } diff --git a/src/system.hh.in b/src/system.hh.in index f71dce68..2077d3a8 100644 --- a/src/system.hh.in +++ b/src/system.hh.in @@ -158,6 +158,7 @@ typedef std::ostream::pos_type ostream_pos_type; #include <boost/iostreams/write.hpp> #define BOOST_IOSTREAMS_USE_DEPRECATED 1 #include <boost/iostreams/device/file_descriptor.hpp> +#include <boost/iterator/iterator_facade.hpp> #include <boost/iterator/transform_iterator.hpp> #include <boost/lexical_cast.hpp> #include <boost/operators.hpp> |