Use Boost iterator_facade to create new iterators
This commit is contained in:
parent
966b6fc359
commit
cf35984971
10 changed files with 211 additions and 166 deletions
|
|
@ -62,10 +62,10 @@ value_t convert_command(call_scope_t& args)
|
||||||
post_map_t post_map;
|
post_map_t post_map;
|
||||||
|
|
||||||
xacts_iterator journal_iter(journal);
|
xacts_iterator journal_iter(journal);
|
||||||
while (xact_t * xact = journal_iter()) {
|
while (xact_t * xact = *journal_iter++) {
|
||||||
post_t * post = NULL;
|
post_t * post = NULL;
|
||||||
xact_posts_iterator xact_iter(*xact);
|
xact_posts_iterator xact_iter(*xact);
|
||||||
while ((post = xact_iter()) != NULL) {
|
while ((post = *xact_iter++) != NULL) {
|
||||||
if (post->account == bucket)
|
if (post->account == bucket)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -137,7 +137,7 @@ value_t convert_command(call_scope_t& args)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
xact_posts_iterator xact_iter(*xact);
|
xact_posts_iterator xact_iter(*xact);
|
||||||
while (post_t * post = xact_iter())
|
while (post_t * post = *xact_iter++)
|
||||||
formatter(*post);
|
formatter(*post);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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()
|
void truncate_xacts::flush()
|
||||||
{
|
{
|
||||||
if (! posts.size())
|
if (! posts.size())
|
||||||
|
|
@ -1419,25 +1400,4 @@ void inject_posts::operator()(post_t& post)
|
||||||
item_handler<post_t>::operator()(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
|
} // namespace ledger
|
||||||
|
|
|
||||||
|
|
@ -146,14 +146,28 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class posts_iterator;
|
template <typename Iterator>
|
||||||
|
|
||||||
class pass_down_posts : public item_handler<post_t>
|
class pass_down_posts : public item_handler<post_t>
|
||||||
{
|
{
|
||||||
pass_down_posts();
|
pass_down_posts();
|
||||||
|
|
||||||
public:
|
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() {
|
virtual ~pass_down_posts() {
|
||||||
TRACE_DTOR(pass_down_posts);
|
TRACE_DTOR(pass_down_posts);
|
||||||
|
|
@ -986,8 +1000,7 @@ class inject_posts : public item_handler<post_t>
|
||||||
// Account filters
|
// Account filters
|
||||||
//
|
//
|
||||||
|
|
||||||
class accounts_iterator;
|
template <typename Iterator>
|
||||||
|
|
||||||
class pass_down_accounts : public item_handler<account_t>
|
class pass_down_accounts : public item_handler<account_t>
|
||||||
{
|
{
|
||||||
pass_down_accounts();
|
pass_down_accounts();
|
||||||
|
|
@ -997,9 +1010,24 @@ class pass_down_accounts : public item_handler<account_t>
|
||||||
|
|
||||||
public:
|
public:
|
||||||
pass_down_accounts(acct_handler_ptr handler,
|
pass_down_accounts(acct_handler_ptr handler,
|
||||||
accounts_iterator& iter,
|
Iterator& iter,
|
||||||
const optional<predicate_t>& _pred = none,
|
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() {
|
virtual ~pass_down_accounts() {
|
||||||
TRACE_DTOR(pass_down_accounts);
|
TRACE_DTOR(pass_down_accounts);
|
||||||
|
|
|
||||||
|
|
@ -350,9 +350,10 @@ void generate_posts_iterator::generate_xact(std::ostream& out)
|
||||||
out << '\n';
|
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) {
|
if (post == NULL && quantity > 0) {
|
||||||
std::ostringstream buf;
|
std::ostringstream buf;
|
||||||
generate_xact(buf);
|
generate_xact(buf);
|
||||||
|
|
@ -364,7 +365,7 @@ post_t * generate_posts_iterator::operator()()
|
||||||
if (session.journal->parse(in, session) != 0) {
|
if (session.journal->parse(in, session) != 0) {
|
||||||
VERIFY(session.journal->xacts.back()->valid());
|
VERIFY(session.journal->xacts.back()->valid());
|
||||||
posts.reset(*session.journal->xacts.back());
|
posts.reset(*session.journal->xacts.back());
|
||||||
post = posts();
|
post = *posts++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (std::exception&) {
|
catch (std::exception&) {
|
||||||
|
|
@ -382,7 +383,8 @@ post_t * generate_posts_iterator::operator()()
|
||||||
|
|
||||||
quantity--;
|
quantity--;
|
||||||
}
|
}
|
||||||
return post;
|
|
||||||
|
m_node = post;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ledger
|
} // namespace ledger
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,9 @@ namespace ledger {
|
||||||
|
|
||||||
class session_t;
|
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;
|
session_t& session;
|
||||||
unsigned int seed;
|
unsigned int seed;
|
||||||
|
|
@ -105,7 +107,7 @@ public:
|
||||||
TRACE_DTOR(generate_posts_iterator);
|
TRACE_DTOR(generate_posts_iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual post_t * operator()();
|
virtual void increment();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void generate_string(std::ostream& out, int len, bool only_alpha = false);
|
void generate_string(std::ostream& out, int len, bool only_alpha = false);
|
||||||
|
|
|
||||||
111
src/iterators.cc
111
src/iterators.cc
|
|
@ -41,37 +41,38 @@ void xacts_iterator::reset(journal_t& journal)
|
||||||
{
|
{
|
||||||
xacts_i = journal.xacts.begin();
|
xacts_i = journal.xacts.begin();
|
||||||
xacts_end = journal.xacts.end();
|
xacts_end = journal.xacts.end();
|
||||||
|
|
||||||
xacts_uninitialized = false;
|
xacts_uninitialized = false;
|
||||||
|
|
||||||
|
increment();
|
||||||
}
|
}
|
||||||
|
|
||||||
xact_t * xacts_iterator::operator()()
|
void xacts_iterator::increment()
|
||||||
{
|
{
|
||||||
if (xacts_i != xacts_end)
|
if (xacts_i != xacts_end)
|
||||||
return *xacts_i++;
|
m_node = *xacts_i++;
|
||||||
else
|
else
|
||||||
return NULL;
|
m_node = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void journal_posts_iterator::reset(journal_t& journal)
|
void journal_posts_iterator::reset(journal_t& journal)
|
||||||
{
|
{
|
||||||
xacts.reset(journal);
|
xacts.reset(journal);
|
||||||
|
increment();
|
||||||
xact_t * xact = xacts();
|
|
||||||
if (xact != NULL)
|
|
||||||
posts.reset(*xact);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
post_t * journal_posts_iterator::operator()()
|
void journal_posts_iterator::increment()
|
||||||
{
|
{
|
||||||
post_t * post = posts();
|
if (post_t * post = *posts++) {
|
||||||
if (post == NULL) {
|
m_node = post;
|
||||||
xact_t * xact = xacts();
|
}
|
||||||
if (xact != NULL) {
|
else if (xact_t * xact = *xacts++) {
|
||||||
posts.reset(*xact);
|
posts.reset(*xact);
|
||||||
post = posts();
|
m_node = *posts++;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
m_node = NULL;
|
||||||
}
|
}
|
||||||
return post;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void posts_commodities_iterator::reset(journal_t& journal)
|
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;
|
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());
|
commodity_t& comm(post->amount.commodity());
|
||||||
if (comm.flags() & COMMODITY_NOMARKET)
|
if (comm.flags() & COMMODITY_NOMARKET)
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -136,47 +137,44 @@ void posts_commodities_iterator::reset(journal_t& journal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
xacts.xacts_i = xact_temps.begin();
|
xacts.reset(xact_temps.begin(), xact_temps.end());
|
||||||
xacts.xacts_end = xact_temps.end();
|
|
||||||
|
|
||||||
xacts.xacts_uninitialized = false;
|
increment();
|
||||||
|
|
||||||
xact_t * xact = xacts();
|
|
||||||
if (xact != NULL)
|
|
||||||
posts.reset(*xact);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
post_t * posts_commodities_iterator::operator()()
|
void posts_commodities_iterator::increment()
|
||||||
{
|
{
|
||||||
post_t * post = posts();
|
if (post_t * post = *posts++) {
|
||||||
if (post == NULL) {
|
m_node = post;
|
||||||
xact_t * xact = xacts();
|
}
|
||||||
if (xact != NULL) {
|
else if (xact_t * xact = *xacts++) {
|
||||||
posts.reset(*xact);
|
posts.reset(*xact);
|
||||||
post = posts();
|
m_node = *posts++;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
m_node = NULL;
|
||||||
}
|
}
|
||||||
return post;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
account_t * basic_accounts_iterator::operator()()
|
void basic_accounts_iterator::increment()
|
||||||
{
|
{
|
||||||
while (! accounts_i.empty() &&
|
while (! accounts_i.empty() && accounts_i.back() == accounts_end.back()) {
|
||||||
accounts_i.back() == accounts_end.back()) {
|
|
||||||
accounts_i.pop_back();
|
accounts_i.pop_back();
|
||||||
accounts_end.pop_back();
|
accounts_end.pop_back();
|
||||||
}
|
}
|
||||||
if (accounts_i.empty())
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
account_t * account = (*(accounts_i.back()++)).second;
|
if (accounts_i.empty()) {
|
||||||
assert(account);
|
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 this account has children, queue them up to be iterated next.
|
||||||
if (! account->accounts.empty())
|
if (! account->accounts.empty())
|
||||||
push_back(*account);
|
push_back(*account);
|
||||||
|
|
||||||
return account;
|
m_node = account;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sorted_accounts_iterator::push_back(account_t& account)
|
void sorted_accounts_iterator::push_back(account_t& account)
|
||||||
|
|
@ -231,7 +229,7 @@ void sorted_accounts_iterator::sort_accounts(account_t& account,
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
account_t * sorted_accounts_iterator::operator()()
|
void sorted_accounts_iterator::increment()
|
||||||
{
|
{
|
||||||
while (! sorted_accounts_i.empty() &&
|
while (! sorted_accounts_i.empty() &&
|
||||||
sorted_accounts_i.back() == sorted_accounts_end.back()) {
|
sorted_accounts_i.back() == sorted_accounts_end.back()) {
|
||||||
|
|
@ -240,19 +238,22 @@ account_t * sorted_accounts_iterator::operator()()
|
||||||
assert(! accounts_list.empty());
|
assert(! accounts_list.empty());
|
||||||
accounts_list.pop_back();
|
accounts_list.pop_back();
|
||||||
}
|
}
|
||||||
if (sorted_accounts_i.empty())
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
account_t * account = *sorted_accounts_i.back()++;
|
if (sorted_accounts_i.empty()) {
|
||||||
assert(account);
|
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 this account has children, queue them up to be iterated next.
|
||||||
if (! flatten_all && ! account->accounts.empty())
|
if (! flatten_all && ! account->accounts.empty())
|
||||||
push_back(*account);
|
push_back(*account);
|
||||||
|
|
||||||
// Make sure the sorting value gets recalculated for this account
|
// Make sure the sorting value gets recalculated for this account
|
||||||
account->xdata().drop_flags(ACCOUNT_EXT_SORT_CALC);
|
account->xdata().drop_flags(ACCOUNT_EXT_SORT_CALC);
|
||||||
return account;
|
|
||||||
|
m_node = account;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ledger
|
} // namespace ledger
|
||||||
|
|
|
||||||
110
src/iterators.h
110
src/iterators.h
|
|
@ -51,14 +51,35 @@ namespace ledger {
|
||||||
|
|
||||||
class journal_t;
|
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:
|
public:
|
||||||
virtual ~posts_iterator() throw() {}
|
iterator_facade_base() : m_node(NULL) {}
|
||||||
virtual post_t * operator()() = 0;
|
|
||||||
|
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_i;
|
||||||
posts_list::iterator posts_end;
|
posts_list::iterator posts_end;
|
||||||
|
|
@ -74,7 +95,7 @@ public:
|
||||||
TRACE_CTOR(xact_posts_iterator, "xact_t&");
|
TRACE_CTOR(xact_posts_iterator, "xact_t&");
|
||||||
reset(xact);
|
reset(xact);
|
||||||
}
|
}
|
||||||
virtual ~xact_posts_iterator() throw() {
|
~xact_posts_iterator() throw() {
|
||||||
TRACE_DTOR(xact_posts_iterator);
|
TRACE_DTOR(xact_posts_iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -83,16 +104,21 @@ public:
|
||||||
posts_end = xact.posts.end();
|
posts_end = xact.posts.end();
|
||||||
|
|
||||||
posts_uninitialized = false;
|
posts_uninitialized = false;
|
||||||
|
|
||||||
|
increment();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual post_t * operator()() {
|
void increment() {
|
||||||
if (posts_uninitialized || posts_i == posts_end)
|
if (posts_uninitialized || posts_i == posts_end)
|
||||||
return NULL;
|
m_node = NULL;
|
||||||
return *posts_i++;
|
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:
|
public:
|
||||||
xacts_list::iterator xacts_i;
|
xacts_list::iterator xacts_i;
|
||||||
|
|
@ -103,22 +129,35 @@ public:
|
||||||
xacts_iterator() : xacts_uninitialized(true) {
|
xacts_iterator() : xacts_uninitialized(true) {
|
||||||
TRACE_CTOR(xacts_iterator, "");
|
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&");
|
TRACE_CTOR(xacts_iterator, "journal_t&");
|
||||||
reset(journal);
|
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);
|
TRACE_DTOR(xacts_iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset(journal_t& journal);
|
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;
|
xact_posts_iterator posts;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -129,16 +168,18 @@ public:
|
||||||
TRACE_CTOR(journal_posts_iterator, "journal_t&");
|
TRACE_CTOR(journal_posts_iterator, "journal_t&");
|
||||||
reset(journal);
|
reset(journal);
|
||||||
}
|
}
|
||||||
virtual ~journal_posts_iterator() throw() {
|
~journal_posts_iterator() throw() {
|
||||||
TRACE_DTOR(journal_posts_iterator);
|
TRACE_DTOR(journal_posts_iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset(journal_t& journal);
|
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:
|
protected:
|
||||||
journal_posts_iterator journal_posts;
|
journal_posts_iterator journal_posts;
|
||||||
|
|
@ -155,23 +196,18 @@ public:
|
||||||
TRACE_CTOR(posts_commodities_iterator, "journal_t&");
|
TRACE_CTOR(posts_commodities_iterator, "journal_t&");
|
||||||
reset(journal);
|
reset(journal);
|
||||||
}
|
}
|
||||||
virtual ~posts_commodities_iterator() throw() {
|
~posts_commodities_iterator() throw() {
|
||||||
TRACE_DTOR(posts_commodities_iterator);
|
TRACE_DTOR(posts_commodities_iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset(journal_t& journal);
|
void reset(journal_t& journal);
|
||||||
|
|
||||||
virtual post_t * operator()();
|
void increment();
|
||||||
};
|
};
|
||||||
|
|
||||||
class accounts_iterator : public noncopyable
|
class basic_accounts_iterator
|
||||||
{
|
: public iterator_facade_base<basic_accounts_iterator, account_t *,
|
||||||
public:
|
boost::forward_traversal_tag>
|
||||||
virtual ~accounts_iterator() throw() {}
|
|
||||||
virtual account_t * operator()() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class basic_accounts_iterator : public accounts_iterator
|
|
||||||
{
|
{
|
||||||
std::list<accounts_map::const_iterator> accounts_i;
|
std::list<accounts_map::const_iterator> accounts_i;
|
||||||
std::list<accounts_map::const_iterator> accounts_end;
|
std::list<accounts_map::const_iterator> accounts_end;
|
||||||
|
|
@ -183,20 +219,24 @@ public:
|
||||||
basic_accounts_iterator(account_t& account) {
|
basic_accounts_iterator(account_t& account) {
|
||||||
TRACE_CTOR(basic_accounts_iterator, "account_t&");
|
TRACE_CTOR(basic_accounts_iterator, "account_t&");
|
||||||
push_back(account);
|
push_back(account);
|
||||||
|
increment();
|
||||||
}
|
}
|
||||||
virtual ~basic_accounts_iterator() throw() {
|
~basic_accounts_iterator() throw() {
|
||||||
TRACE_DTOR(basic_accounts_iterator);
|
TRACE_DTOR(basic_accounts_iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void increment();
|
||||||
|
|
||||||
|
private:
|
||||||
void push_back(account_t& account) {
|
void push_back(account_t& account) {
|
||||||
accounts_i.push_back(account.accounts.begin());
|
accounts_i.push_back(account.accounts.begin());
|
||||||
accounts_end.push_back(account.accounts.end());
|
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;
|
expr_t sort_cmp;
|
||||||
bool flatten_all;
|
bool flatten_all;
|
||||||
|
|
@ -213,16 +253,18 @@ public:
|
||||||
: sort_cmp(_sort_cmp), flatten_all(_flatten_all) {
|
: sort_cmp(_sort_cmp), flatten_all(_flatten_all) {
|
||||||
TRACE_CTOR(sorted_accounts_iterator, "const expr_t&, bool, account_t&");
|
TRACE_CTOR(sorted_accounts_iterator, "const expr_t&, bool, account_t&");
|
||||||
push_back(account);
|
push_back(account);
|
||||||
|
increment();
|
||||||
}
|
}
|
||||||
virtual ~sorted_accounts_iterator() throw() {
|
~sorted_accounts_iterator() throw() {
|
||||||
TRACE_DTOR(sorted_accounts_iterator);
|
TRACE_DTOR(sorted_accounts_iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void increment();
|
||||||
|
|
||||||
|
private:
|
||||||
void push_back(account_t& account);
|
void push_back(account_t& account);
|
||||||
void push_all(account_t& account, accounts_deque_t& deque);
|
void push_all(account_t& account, accounts_deque_t& deque);
|
||||||
void sort_accounts(account_t& account, accounts_deque_t& deque);
|
void sort_accounts(account_t& account, accounts_deque_t& deque);
|
||||||
|
|
||||||
virtual account_t * operator()();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ledger
|
} // namespace ledger
|
||||||
|
|
|
||||||
|
|
@ -191,7 +191,7 @@ namespace {
|
||||||
coll->chain =
|
coll->chain =
|
||||||
chain_post_handlers(post_handler_ptr(coll->posts_collector),
|
chain_post_handlers(post_handler_ptr(coll->posts_collector),
|
||||||
coll->report);
|
coll->report);
|
||||||
pass_down_posts(coll->chain, walker);
|
pass_down_posts<journal_posts_iterator>(coll->chain, walker);
|
||||||
}
|
}
|
||||||
catch (...) {
|
catch (...) {
|
||||||
current_report.session.journal.release();
|
current_report.session.journal.release();
|
||||||
|
|
|
||||||
|
|
@ -318,7 +318,7 @@ void report_t::posts_report(post_handler_ptr handler)
|
||||||
handler = chain_pre_post_handlers(handler, *this);
|
handler = chain_pre_post_handlers(handler, *this);
|
||||||
|
|
||||||
journal_posts_iterator walker(*session.journal.get());
|
journal_posts_iterator walker(*session.journal.get());
|
||||||
pass_down_posts(handler, walker);
|
pass_down_posts<journal_posts_iterator>(handler, walker);
|
||||||
|
|
||||||
if (! HANDLED(group_by_))
|
if (! HANDLED(group_by_))
|
||||||
posts_flusher(handler, *this)(value_t());
|
posts_flusher(handler, *this)(value_t());
|
||||||
|
|
@ -334,7 +334,7 @@ void report_t::generate_report(post_handler_ptr handler)
|
||||||
HANDLED(head_) ?
|
HANDLED(head_) ?
|
||||||
static_cast<unsigned int>(HANDLER(head_).value.to_long()) : 50);
|
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)
|
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);
|
handler = chain_handlers(handler, *this);
|
||||||
|
|
||||||
xact_posts_iterator walker(xact);
|
xact_posts_iterator walker(xact);
|
||||||
pass_down_posts(handler, walker);
|
pass_down_posts<xact_posts_iterator>(handler, walker);
|
||||||
|
|
||||||
xact.clear_xdata();
|
xact.clear_xdata();
|
||||||
}
|
}
|
||||||
|
|
@ -382,25 +382,34 @@ namespace {
|
||||||
report.HANDLER(display_total_).expr.mark_uncompiled();
|
report.HANDLER(display_total_).expr.mark_uncompiled();
|
||||||
report.HANDLER(revalued_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_)) {
|
if (report.HANDLED(display_)) {
|
||||||
DEBUG("report.predicate",
|
DEBUG("report.predicate",
|
||||||
"Display predicate = " << report.HANDLER(display_).str());
|
"Display predicate = " << report.HANDLER(display_).str());
|
||||||
pass_down_accounts(handler, *iter.get(),
|
if (! report.HANDLED(sort_)) {
|
||||||
predicate_t(report.HANDLER(display_).str(),
|
basic_accounts_iterator iter(*report.session.journal->master);
|
||||||
report.what_to_keep()),
|
pass_down_accounts<basic_accounts_iterator>
|
||||||
report);
|
(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 {
|
} 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();
|
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
|
// objects created within it during the call to pass_down_posts, which will
|
||||||
// be needed later by the pass_down_accounts.
|
// be needed later by the pass_down_accounts.
|
||||||
journal_posts_iterator walker(*session.journal.get());
|
journal_posts_iterator walker(*session.journal.get());
|
||||||
pass_down_posts(chain, walker);
|
pass_down_posts<journal_posts_iterator>(chain, walker);
|
||||||
|
|
||||||
if (! HANDLED(group_by_))
|
if (! HANDLED(group_by_))
|
||||||
accounts_flusher(handler, *this)(value_t());
|
accounts_flusher(handler, *this)(value_t());
|
||||||
|
|
@ -439,7 +448,7 @@ void report_t::commodities_report(post_handler_ptr handler)
|
||||||
handler = chain_handlers(handler, *this);
|
handler = chain_handlers(handler, *this);
|
||||||
|
|
||||||
posts_commodities_iterator walker(*session.journal.get());
|
posts_commodities_iterator walker(*session.journal.get());
|
||||||
pass_down_posts(handler, walker);
|
pass_down_posts<posts_commodities_iterator>(handler, walker);
|
||||||
|
|
||||||
session.journal->clear_xdata();
|
session.journal->clear_xdata();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -158,6 +158,7 @@ typedef std::ostream::pos_type ostream_pos_type;
|
||||||
#include <boost/iostreams/write.hpp>
|
#include <boost/iostreams/write.hpp>
|
||||||
#define BOOST_IOSTREAMS_USE_DEPRECATED 1
|
#define BOOST_IOSTREAMS_USE_DEPRECATED 1
|
||||||
#include <boost/iostreams/device/file_descriptor.hpp>
|
#include <boost/iostreams/device/file_descriptor.hpp>
|
||||||
|
#include <boost/iterator/iterator_facade.hpp>
|
||||||
#include <boost/iterator/transform_iterator.hpp>
|
#include <boost/iterator/transform_iterator.hpp>
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
#include <boost/operators.hpp>
|
#include <boost/operators.hpp>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue