Added new post_splitter posting handler

This commit is contained in:
John Wiegley 2010-05-30 02:27:46 -06:00
parent f491979d55
commit e86a4767bc
2 changed files with 92 additions and 1 deletions

View file

@ -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");

View file

@ -50,6 +50,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