diff options
author | John Wiegley <johnw@newartisans.com> | 2010-05-30 02:27:46 -0600 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2010-05-30 02:47:35 -0600 |
commit | e86a4767bc93664893faa4d0f03619f57302c7d1 (patch) | |
tree | 8b315443d946558a0fd1909fb2f853dc6724acd0 | |
parent | f491979d5547742aae70b3f6dd5b4aa0eac36605 (diff) | |
download | ledger-e86a4767bc93664893faa4d0f03619f57302c7d1.tar.gz ledger-e86a4767bc93664893faa4d0f03619f57302c7d1.tar.bz2 ledger-e86a4767bc93664893faa4d0f03619f57302c7d1.zip |
Added new post_splitter posting handler
-rw-r--r-- | src/filters.cc | 43 | ||||
-rw-r--r-- | src/filters.h | 50 |
2 files changed, 92 insertions, 1 deletions
diff --git a/src/filters.cc b/src/filters.cc index 57c95cd3..6915144d 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -39,8 +39,49 @@ namespace ledger { +void post_splitter::print_title(const value_t& val) +{ + if (! report.HANDLED(no_titles)) { + std::ostringstream buf; + val.print(buf); + post_chain->title(buf.str()); + } +} + +void post_splitter::flush() +{ + foreach (value_to_posts_map::value_type pair, posts_map) { + preflush_func(pair.first); + + foreach (post_t * post, pair.second) + (*post_chain)(*post); + + post_chain->flush(); + post_chain->clear(); + + if (postflush_func) + (*postflush_func)(pair.first); + } +} + +void post_splitter::operator()(post_t& post) +{ + bind_scope_t bound_scope(report, post); + value_t result(group_by_expr.calc(bound_scope)); + + value_to_posts_map::iterator i = posts_map.find(result); + if (i != posts_map.end()) { + (*i).second.push_back(&post); + } else { + std::pair<value_to_posts_map::iterator, bool> inserted + = posts_map.insert(value_to_posts_map::value_type(result, posts_list())); + assert(inserted.second); + (*inserted.first).second.push_back(&post); + } +} + pass_down_posts::pass_down_posts(post_handler_ptr handler, - posts_iterator& iter) + posts_iterator& iter) : item_handler<post_t>(handler) { TRACE_CTOR(pass_down_posts, "post_handler_ptr, posts_iterator"); diff --git a/src/filters.h b/src/filters.h index 3f3e3d34..dd6b3b1a 100644 --- a/src/filters.h +++ b/src/filters.h @@ -52,6 +52,56 @@ namespace ledger { ////////////////////////////////////////////////////////////////////// // +// Posting collector +// + +class post_splitter : public item_handler<post_t> +{ +public: + typedef std::map<value_t, posts_list> value_to_posts_map; + typedef function<void (const value_t&)> custom_flusher_t; + +protected: + value_to_posts_map posts_map; + report_t& report; + post_handler_ptr post_chain; + expr_t group_by_expr; + custom_flusher_t preflush_func; + optional<custom_flusher_t> postflush_func; + +public: + post_splitter(report_t& _report, + post_handler_ptr _post_chain, + expr_t _group_by_expr) + : report(_report), post_chain(_post_chain), + group_by_expr(_group_by_expr), + preflush_func(bind(&post_splitter::print_title, this, _1)) { + TRACE_CTOR(post_splitter, "scope_t&, post_handler_ptr, expr_t"); + } + virtual ~post_splitter() { + TRACE_DTOR(post_splitter); + } + + void set_preflush_func(custom_flusher_t functor) { + preflush_func = functor; + } + void set_postflush_func(custom_flusher_t functor) { + postflush_func = functor; + } + + virtual void print_title(const value_t& val); + + virtual void flush(); + virtual void operator()(post_t& post); + + virtual void clear() { + posts_map.clear(); + post_chain->clear(); + } +}; + +////////////////////////////////////////////////////////////////////// +// // Posting filters // |