use polymorphism, instead of templates, for walking items
This commit is contained in:
parent
8792945e76
commit
a2efee0a8e
5 changed files with 102 additions and 114 deletions
13
format.cc
13
format.cc
|
|
@ -366,7 +366,7 @@ void format_transaction::operator()(transaction_t * xact) const
|
|||
xact->total += *xact;
|
||||
xact->index = last_xact ? last_xact->index + 1 : 0;
|
||||
|
||||
if (disp_pred_functor(xact)) {
|
||||
if (disp_pred(xact)) {
|
||||
xact->dflags |= TRANSACTION_DISPLAYED;
|
||||
|
||||
// This makes the assumption that transactions from a single entry
|
||||
|
|
@ -407,7 +407,7 @@ void format_transaction::operator()(transaction_t * xact) const
|
|||
|
||||
bool format_account::disp_subaccounts_p(const account_t * account,
|
||||
const item_predicate<account_t>&
|
||||
disp_pred_functor,
|
||||
disp_pred,
|
||||
const account_t *& to_show)
|
||||
{
|
||||
bool display = false;
|
||||
|
|
@ -423,7 +423,7 @@ bool format_account::disp_subaccounts_p(const account_t * account,
|
|||
// expression is equivalent between a parent account and a lone
|
||||
// displayed child, then don't display the parent."
|
||||
|
||||
if (! (*i).second->total || ! disp_pred_functor((*i).second))
|
||||
if (! (*i).second->total || ! disp_pred((*i).second))
|
||||
continue;
|
||||
|
||||
if ((*i).second->total != account->total || counted > 0) {
|
||||
|
|
@ -438,8 +438,7 @@ bool format_account::disp_subaccounts_p(const account_t * account,
|
|||
}
|
||||
|
||||
bool format_account::display_account(const account_t * account,
|
||||
const item_predicate<account_t>&
|
||||
disp_pred_functor)
|
||||
const item_predicate<account_t>& disp_pred)
|
||||
{
|
||||
// Never display the master account, or an account that has already
|
||||
// been displayed.
|
||||
|
|
@ -454,10 +453,10 @@ bool format_account::display_account(const account_t * account,
|
|||
// the predicate.
|
||||
|
||||
const account_t * account_to_show = NULL;
|
||||
if (disp_subaccounts_p(account, disp_pred_functor, account_to_show))
|
||||
if (disp_subaccounts_p(account, disp_pred, account_to_show))
|
||||
return true;
|
||||
|
||||
return ! account_to_show && disp_pred_functor(account);
|
||||
return ! account_to_show && disp_pred(account);
|
||||
}
|
||||
|
||||
} // namespace ledger
|
||||
|
|
|
|||
55
format.h
55
format.h
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "ledger.h"
|
||||
#include "valexpr.h"
|
||||
#include "walk.h"
|
||||
|
||||
namespace ledger {
|
||||
|
||||
|
|
@ -84,7 +85,7 @@ struct format_t
|
|||
|
||||
#define COLLAPSED_REGISTER 1 // support collapsed registers
|
||||
|
||||
class format_transaction
|
||||
class format_transaction : public item_handler<transaction_t>
|
||||
{
|
||||
std::ostream& output_stream;
|
||||
const format_t& first_line_format;
|
||||
|
|
@ -94,7 +95,7 @@ class format_transaction
|
|||
#endif
|
||||
const bool inverted;
|
||||
|
||||
item_predicate<transaction_t> disp_pred_functor;
|
||||
item_predicate<transaction_t> disp_pred;
|
||||
|
||||
#ifdef COLLAPSED_REGISTER
|
||||
mutable balance_pair_t subtotal;
|
||||
|
|
@ -118,14 +119,14 @@ class format_transaction
|
|||
#ifdef COLLAPSED_REGISTER
|
||||
collapsed(_collapsed),
|
||||
#endif
|
||||
inverted(_inverted), disp_pred_functor(display_predicate),
|
||||
inverted(_inverted), disp_pred(display_predicate),
|
||||
#ifdef COLLAPSED_REGISTER
|
||||
count(0),
|
||||
#endif
|
||||
last_entry(NULL), last_xact(NULL) {}
|
||||
|
||||
#ifdef COLLAPSED_REGISTER
|
||||
~format_transaction() {
|
||||
virtual ~format_transaction() {
|
||||
if (subtotal)
|
||||
report_cumulative_subtotal();
|
||||
}
|
||||
|
|
@ -133,27 +134,26 @@ class format_transaction
|
|||
void report_cumulative_subtotal() const;
|
||||
#endif
|
||||
|
||||
void operator()(transaction_t * xact) const;
|
||||
virtual void operator()(transaction_t * xact) const;
|
||||
};
|
||||
|
||||
|
||||
template <typename Function>
|
||||
class changed_value_filter
|
||||
class changed_value_filter : public item_handler<transaction_t>
|
||||
{
|
||||
const Function& functor;
|
||||
const item_handler<transaction_t>& handler;
|
||||
|
||||
mutable entry_t modified_entry;
|
||||
mutable transaction_t modified_xact;
|
||||
mutable transaction_t * last_xact;
|
||||
|
||||
public:
|
||||
changed_value_filter(const Function& _functor)
|
||||
: functor(_functor), modified_xact(&modified_entry, NULL),
|
||||
changed_value_filter(const item_handler<transaction_t>& _handler)
|
||||
: handler(_handler), modified_xact(&modified_entry, NULL),
|
||||
last_xact(NULL) {
|
||||
modified_entry.payee = "Commodities revalued";
|
||||
}
|
||||
|
||||
~changed_value_filter() {
|
||||
virtual ~changed_value_filter() {
|
||||
(*this)(NULL);
|
||||
}
|
||||
|
||||
|
|
@ -178,35 +178,35 @@ class changed_value_filter
|
|||
modified_xact.total = diff;
|
||||
modified_xact.total.negate();
|
||||
|
||||
functor(&modified_xact);
|
||||
handler(&modified_xact);
|
||||
}
|
||||
}
|
||||
|
||||
if (xact)
|
||||
functor(xact);
|
||||
handler(xact);
|
||||
|
||||
last_xact = xact;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class format_account
|
||||
class format_account : public item_handler<account_t>
|
||||
{
|
||||
std::ostream& output_stream;
|
||||
const format_t& format;
|
||||
|
||||
item_predicate<account_t> disp_pred_functor;
|
||||
item_predicate<account_t> disp_pred;
|
||||
|
||||
public:
|
||||
format_account(std::ostream& _output_stream,
|
||||
const format_t& _format,
|
||||
const std::string& display_predicate = NULL)
|
||||
: output_stream(_output_stream), format(_format),
|
||||
disp_pred_functor(display_predicate) {}
|
||||
disp_pred(display_predicate) {}
|
||||
virtual ~format_account() {}
|
||||
|
||||
static bool disp_subaccounts_p(const account_t * account,
|
||||
const item_predicate<account_t>&
|
||||
disp_pred_functor,
|
||||
const item_predicate<account_t>& disp_pred,
|
||||
const account_t *& to_show);
|
||||
static bool disp_subaccounts_p(const account_t * account) {
|
||||
const account_t * temp;
|
||||
|
|
@ -214,11 +214,10 @@ class format_account
|
|||
}
|
||||
|
||||
static bool display_account(const account_t * account,
|
||||
const item_predicate<account_t>&
|
||||
disp_pred_functor);
|
||||
const item_predicate<account_t>& disp_pred);
|
||||
|
||||
void operator()(const account_t * account) const {
|
||||
if (display_account(account, disp_pred_functor)) {
|
||||
virtual void operator()(account_t * account) const {
|
||||
if (display_account(account, disp_pred)) {
|
||||
format.format_elements(output_stream, details_t(account));
|
||||
account->dflags |= ACCOUNT_DISPLAYED;
|
||||
}
|
||||
|
|
@ -226,13 +225,13 @@ class format_account
|
|||
};
|
||||
|
||||
|
||||
class format_equity
|
||||
class format_equity : public item_handler<account_t>
|
||||
{
|
||||
std::ostream& output_stream;
|
||||
const format_t& first_line_format;
|
||||
const format_t& next_lines_format;
|
||||
|
||||
item_predicate<account_t> disp_pred_functor;
|
||||
item_predicate<account_t> disp_pred;
|
||||
|
||||
mutable balance_t total;
|
||||
|
||||
|
|
@ -244,21 +243,21 @@ class format_equity
|
|||
: output_stream(_output_stream),
|
||||
first_line_format(_first_line_format),
|
||||
next_lines_format(_next_lines_format),
|
||||
disp_pred_functor(display_predicate) {
|
||||
disp_pred(display_predicate) {
|
||||
entry_t header_entry;
|
||||
header_entry.payee = "Opening Balances";
|
||||
header_entry.date = std::time(NULL);
|
||||
first_line_format.format_elements(output_stream, details_t(&header_entry));
|
||||
}
|
||||
|
||||
~format_equity() {
|
||||
virtual ~format_equity() {
|
||||
account_t summary(NULL, "Equity:Opening Balances");
|
||||
summary.value = - total;
|
||||
next_lines_format.format_elements(output_stream, details_t(&summary));
|
||||
}
|
||||
|
||||
void operator()(const account_t * account) const {
|
||||
if (format_account::display_account(account, disp_pred_functor)) {
|
||||
virtual void operator()(account_t * account) const {
|
||||
if (format_account::display_account(account, disp_pred)) {
|
||||
next_lines_format.format_elements(output_stream, details_t(account));
|
||||
account->dflags |= ACCOUNT_DISPLAYED;
|
||||
total += account->value.quantity;
|
||||
|
|
|
|||
6
main.cc
6
main.cc
|
|
@ -626,8 +626,7 @@ int main(int argc, char * argv[])
|
|||
show_inverted);
|
||||
if (! sort_order.get()) {
|
||||
if (show_commodities_revalued) {
|
||||
changed_value_filter<format_transaction>
|
||||
filtered_formatter(formatter);
|
||||
changed_value_filter filtered_formatter(formatter);
|
||||
walk_entries(journal->entries.begin(), journal->entries.end(),
|
||||
filtered_formatter, predicate, xact_display_flags);
|
||||
} else {
|
||||
|
|
@ -643,8 +642,7 @@ int main(int argc, char * argv[])
|
|||
compare_items<transaction_t>(sort_order.get()));
|
||||
|
||||
if (show_commodities_revalued) {
|
||||
changed_value_filter<format_transaction>
|
||||
filtered_formatter(formatter);
|
||||
changed_value_filter filtered_formatter(formatter);
|
||||
walk_transactions(transactions_pool.begin(), transactions_pool.end(),
|
||||
filtered_formatter);
|
||||
} else {
|
||||
|
|
|
|||
16
walk.cc
16
walk.cc
|
|
@ -2,30 +2,28 @@
|
|||
|
||||
namespace ledger {
|
||||
|
||||
class sum_in_account
|
||||
{
|
||||
public:
|
||||
void operator()(transaction_t * xact) const {
|
||||
struct sum_in_account : public item_handler<transaction_t> {
|
||||
virtual void operator()(transaction_t * xact) const {
|
||||
xact->account->value += *xact;
|
||||
}
|
||||
};
|
||||
|
||||
void calc__accounts(account_t * account,
|
||||
const item_predicate<transaction_t>& pred_functor,
|
||||
const item_predicate<transaction_t>& pred,
|
||||
unsigned int flags)
|
||||
{
|
||||
sum_in_account functor;
|
||||
sum_in_account handler;
|
||||
|
||||
for (transactions_list::iterator i = account->transactions.begin();
|
||||
i != account->transactions.end();
|
||||
i++)
|
||||
if (pred_functor(*i))
|
||||
handle_transaction(*i, functor, flags);
|
||||
if (pred(*i))
|
||||
handle_transaction(*i, handler, flags);
|
||||
|
||||
for (accounts_map::iterator i = account->accounts.begin();
|
||||
i != account->accounts.end();
|
||||
i++)
|
||||
calc__accounts((*i).second, pred_functor, flags);
|
||||
calc__accounts((*i).second, pred, flags);
|
||||
}
|
||||
|
||||
} // namespace ledger
|
||||
|
|
|
|||
126
walk.h
126
walk.h
|
|
@ -10,6 +10,11 @@
|
|||
|
||||
namespace ledger {
|
||||
|
||||
template <typename T>
|
||||
struct item_handler {
|
||||
virtual void operator()(T * item) const = 0;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct compare_items {
|
||||
const node_t * sort_order;
|
||||
|
|
@ -32,15 +37,14 @@ struct compare_items {
|
|||
|
||||
typedef std::deque<transaction_t *> transactions_deque;
|
||||
|
||||
class collect_transactions
|
||||
{
|
||||
class collect_transactions : public item_handler<transaction_t> {
|
||||
transactions_deque& transactions;
|
||||
|
||||
public:
|
||||
collect_transactions(transactions_deque& _transactions)
|
||||
: transactions(_transactions) {}
|
||||
|
||||
void operator()(transaction_t * xact) const {
|
||||
virtual void operator()(transaction_t * xact) const {
|
||||
transactions.push_back(xact);
|
||||
}
|
||||
};
|
||||
|
|
@ -52,19 +56,16 @@ inline void sort_transactions(transactions_deque& transactions,
|
|||
compare_items<transaction_t>(sort_order));
|
||||
}
|
||||
|
||||
class ignore_transaction
|
||||
{
|
||||
public:
|
||||
void operator()(transaction_t * xact) const {}
|
||||
struct ignore_transaction : public item_handler<transaction_t> {
|
||||
virtual void operator()(transaction_t * xact) const {}
|
||||
};
|
||||
|
||||
#define MATCHING_TRANSACTIONS 0x01
|
||||
#define OTHER_TRANSACTIONS 0x02
|
||||
|
||||
template <typename Function>
|
||||
void handle_transaction(transaction_t * xact,
|
||||
const Function& functor,
|
||||
unsigned int flags)
|
||||
inline void handle_transaction(transaction_t * xact,
|
||||
const item_handler<transaction_t>& handler,
|
||||
unsigned int flags)
|
||||
{
|
||||
for (transactions_list::iterator i = xact->entry->transactions.begin();
|
||||
i != xact->entry->transactions.end();
|
||||
|
|
@ -75,42 +76,39 @@ void handle_transaction(transaction_t * xact,
|
|||
(*i == xact ?
|
||||
(flags & MATCHING_TRANSACTIONS) : (flags & OTHER_TRANSACTIONS))) {
|
||||
(*i)->dflags |= TRANSACTION_HANDLED;
|
||||
functor(*i);
|
||||
handler(*i);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Function>
|
||||
void walk_entries(entries_list::iterator begin,
|
||||
entries_list::iterator end,
|
||||
const Function& functor,
|
||||
const std::string& predicate,
|
||||
unsigned int flags)
|
||||
inline void walk_entries(entries_list::iterator begin,
|
||||
entries_list::iterator end,
|
||||
const item_handler<transaction_t>& handler,
|
||||
const std::string& predicate,
|
||||
unsigned int flags)
|
||||
{
|
||||
item_predicate<transaction_t> pred_functor(predicate);
|
||||
item_predicate<transaction_t> pred(predicate);
|
||||
|
||||
for (entries_list::iterator i = begin; i != end; i++)
|
||||
for (transactions_list::iterator j = (*i)->transactions.begin();
|
||||
j != (*i)->transactions.end();
|
||||
j++)
|
||||
if (pred_functor(*j))
|
||||
handle_transaction(*j, functor, flags);
|
||||
if (pred(*j))
|
||||
handle_transaction(*j, handler, flags);
|
||||
}
|
||||
|
||||
template <typename Function>
|
||||
void walk_entries(entries_list::iterator begin,
|
||||
entries_list::iterator end, const Function& functor)
|
||||
inline void walk_entries(entries_list::iterator begin,
|
||||
entries_list::iterator end,
|
||||
const item_handler<transaction_t>& handler)
|
||||
{
|
||||
for (entries_list::iterator i = begin; i != end; i++)
|
||||
for (transactions_list::iterator j = (*i)->transactions.begin();
|
||||
j != (*i)->transactions.end();
|
||||
j++)
|
||||
functor(*j);
|
||||
handler(*j);
|
||||
}
|
||||
|
||||
class clear_flags
|
||||
{
|
||||
public:
|
||||
void operator()(transaction_t * xact) const {
|
||||
struct clear_flags : public item_handler<transaction_t> {
|
||||
virtual void operator()(transaction_t * xact) const {
|
||||
xact->dflags = 0;
|
||||
}
|
||||
};
|
||||
|
|
@ -118,25 +116,23 @@ class clear_flags
|
|||
inline void clear_transaction_display_flags(entries_list::iterator begin,
|
||||
entries_list::iterator end)
|
||||
{
|
||||
walk_entries<clear_flags>(begin, end, clear_flags());
|
||||
walk_entries(begin, end, clear_flags());
|
||||
}
|
||||
|
||||
template <typename Function>
|
||||
void walk_transactions(transactions_list::iterator begin,
|
||||
transactions_list::iterator end,
|
||||
const Function& functor)
|
||||
inline void walk_transactions(transactions_list::iterator begin,
|
||||
transactions_list::iterator end,
|
||||
const item_handler<transaction_t>& handler)
|
||||
{
|
||||
for (transactions_list::iterator i = begin; i != end; i++)
|
||||
functor(*i);
|
||||
handler(*i);
|
||||
}
|
||||
|
||||
template <typename Function>
|
||||
void walk_transactions(transactions_deque::iterator begin,
|
||||
transactions_deque::iterator end,
|
||||
const Function& functor)
|
||||
inline void walk_transactions(transactions_deque::iterator begin,
|
||||
transactions_deque::iterator end,
|
||||
const item_handler<transaction_t>& handler)
|
||||
{
|
||||
for (transactions_deque::iterator i = begin; i != end; i++)
|
||||
functor(*i);
|
||||
handler(*i);
|
||||
}
|
||||
|
||||
typedef std::deque<account_t *> accounts_deque;
|
||||
|
|
@ -154,23 +150,22 @@ inline void sort_accounts(account_t * account,
|
|||
compare_items<account_t>(sort_order));
|
||||
}
|
||||
|
||||
template <typename Function>
|
||||
void walk__accounts(account_t * account, const Function& functor)
|
||||
inline void walk__accounts(account_t * account,
|
||||
const item_handler<account_t>& handler)
|
||||
{
|
||||
functor(account);
|
||||
handler(account);
|
||||
|
||||
for (accounts_map::const_iterator i = account->accounts.begin();
|
||||
i != account->accounts.end();
|
||||
i++)
|
||||
walk__accounts((*i).second, functor);
|
||||
walk__accounts((*i).second, handler);
|
||||
}
|
||||
|
||||
template <typename Function>
|
||||
void walk__accounts_sorted(account_t * account,
|
||||
const Function& functor,
|
||||
const node_t * sort_order)
|
||||
inline void walk__accounts_sorted(account_t * account,
|
||||
const item_handler<account_t>& handler,
|
||||
const node_t * sort_order)
|
||||
{
|
||||
functor(account);
|
||||
handler(account);
|
||||
|
||||
accounts_deque accounts;
|
||||
|
||||
|
|
@ -185,22 +180,22 @@ void walk__accounts_sorted(account_t * account,
|
|||
for (accounts_deque::const_iterator i = accounts.begin();
|
||||
i != accounts.end();
|
||||
i++)
|
||||
walk__accounts_sorted(*i, functor, sort_order);
|
||||
walk__accounts_sorted(*i, handler, sort_order);
|
||||
}
|
||||
|
||||
template <typename Function>
|
||||
void for_each_account(account_t * account, const Function& functor)
|
||||
inline void for_each_account(account_t * account,
|
||||
const item_handler<account_t>& handler)
|
||||
{
|
||||
functor(account);
|
||||
handler(account);
|
||||
|
||||
for (accounts_map::iterator i = account->accounts.begin();
|
||||
i != account->accounts.end();
|
||||
i++)
|
||||
walk__accounts((*i).second, functor);
|
||||
walk__accounts((*i).second, handler);
|
||||
}
|
||||
|
||||
void calc__accounts(account_t * account,
|
||||
const item_predicate<transaction_t>& pred_functor,
|
||||
const item_predicate<transaction_t>& pred,
|
||||
unsigned int flags);
|
||||
|
||||
inline void sum__accounts(account_t * account)
|
||||
|
|
@ -214,24 +209,23 @@ inline void sum__accounts(account_t * account)
|
|||
account->total += account->value;
|
||||
}
|
||||
|
||||
template <typename Function>
|
||||
void walk_accounts(account_t * account,
|
||||
const Function& functor,
|
||||
const std::string& predicate,
|
||||
unsigned int flags,
|
||||
const bool calc_subtotals,
|
||||
const node_t * sort_order = NULL)
|
||||
inline void walk_accounts(account_t * account,
|
||||
const item_handler<account_t>& handler,
|
||||
const std::string& predicate,
|
||||
unsigned int flags,
|
||||
const bool calc_subtotals,
|
||||
const node_t * sort_order = NULL)
|
||||
{
|
||||
item_predicate<transaction_t> pred_functor(predicate);
|
||||
item_predicate<transaction_t> pred(predicate);
|
||||
|
||||
calc__accounts(account, pred_functor, flags);
|
||||
calc__accounts(account, pred, flags);
|
||||
if (calc_subtotals)
|
||||
sum__accounts(account);
|
||||
|
||||
if (sort_order)
|
||||
walk__accounts_sorted<Function>(account, functor, sort_order);
|
||||
walk__accounts_sorted(account, handler, sort_order);
|
||||
else
|
||||
walk__accounts<Function>(account, functor);
|
||||
walk__accounts(account, handler);
|
||||
}
|
||||
|
||||
} // namespace ledger
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue