diff options
author | John Wiegley <johnw@newartisans.com> | 2004-08-05 21:47:53 -0400 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2004-08-05 21:47:53 -0400 |
commit | 50f75e0a5c3ee31c2bcc1fcbd8da42e24ccf072f (patch) | |
tree | 1ebf3b1adf32c537b95cce4f3074cde2eebc7147 | |
parent | 7e87a0a0b1a8b76c44f4f678d8bfb5129ba6c5da (diff) | |
download | fork-ledger-50f75e0a5c3ee31c2bcc1fcbd8da42e24ccf072f.tar.gz fork-ledger-50f75e0a5c3ee31c2bcc1fcbd8da42e24ccf072f.tar.bz2 fork-ledger-50f75e0a5c3ee31c2bcc1fcbd8da42e24ccf072f.zip |
added support for account sorting
-rw-r--r-- | ledger.h | 14 | ||||
-rw-r--r-- | main.cc | 4 | ||||
-rw-r--r-- | valexpr.cc | 42 | ||||
-rw-r--r-- | valexpr.h | 19 | ||||
-rw-r--r-- | walk.h | 173 |
5 files changed, 123 insertions, 129 deletions
@@ -34,12 +34,14 @@ class account_t; class transaction_t { public: - entry_t * entry; - account_t * account; - amount_t amount; - amount_t cost; - unsigned int flags; - std::string note; + entry_t * entry; + account_t * account; + amount_t amount; + amount_t cost; + unsigned int flags; + std::string note; + balance_pair_t total; + unsigned int index; transaction_t(entry_t * _entry, account_t * _account) : entry(_entry), account(_account), flags(TRANSACTION_NORMAL) {} @@ -822,7 +822,7 @@ int main(int argc, char * argv[]) format_t format(f); walk_accounts(journal->master, format_account(std::cout, format), predicate.get(), show_related, show_inverted, - show_subtotals, display_predicate.get()); + show_subtotals, display_predicate.get(), sort_order.get()); if (! display_predicate.get() || item_predicate(display_predicate.get())(journal->master)) { @@ -856,7 +856,7 @@ int main(int argc, char * argv[]) collect_transactions(transactions_pool), predicate.get(), show_related, show_inverted, display_predicate.get()); std::stable_sort(transactions_pool.begin(), transactions_pool.end(), - compare_transactions(sort_order.get())); + compare_items<transaction_t>(sort_order.get())); walk_transactions(transactions_pool.begin(), transactions_pool.end(), formatter, NULL, show_related, show_inverted, display_predicate.get()); @@ -116,34 +116,36 @@ void node_t::compute(balance_t& result, const details_t& details) const break; case BALANCE: - if (details.balance) { - result = details.balance->quantity; - if (details.xact) - result -= details.xact->amount; - else if (details.account) - result -= details.account->value.quantity; + if (details.xact) { + result = details.xact->total.quantity; + result -= details.xact->amount; + } + else if (details.account) { + result = details.account->total.quantity; + result -= details.account->value.quantity; } break; case COST_BALANCE: - if (details.balance) { - result = details.balance->cost; - if (details.xact) - result -= details.xact->cost; - else if (details.account) - result -= details.account->value.cost; + if (details.xact) { + result = details.xact->total.cost; + result -= details.xact->cost; + } + else if (details.account) { + result = details.account->total.cost; + result -= details.account->value.cost; } break; case TOTAL: - if (details.balance) - result = details.balance->quantity; + if (details.xact) + result = details.xact->total.quantity; else if (details.account) result = details.account->total.quantity; break; case COST_TOTAL: - if (details.balance) - result = details.balance->cost; + if (details.xact) + result = details.xact->total.cost; else if (details.account) result = details.account->total.cost; break; @@ -164,15 +166,15 @@ void node_t::compute(balance_t& result, const details_t& details) const break; case INDEX: - if (details.index) - result = *details.index + 1; + if (details.xact) + result = details.xact->index + 1; break; case F_ARITH_MEAN: - if (details.index) { + if (details.xact) { assert(left); left->compute(result, details); - result /= amount_t(*details.index + 1); + result /= amount_t(details.xact->index + 1); } break; @@ -33,26 +33,17 @@ struct details_t const entry_t * entry; const transaction_t * xact; const account_t * account; - const balance_pair_t * balance; - const unsigned int * index; const unsigned int depth; - details_t(const entry_t * _entry, - const balance_pair_t * _balance = NULL, - const unsigned int * _index = NULL) - : entry(_entry), xact(NULL), account(NULL), - balance(_balance), index(_index), depth(0) {} + details_t(const entry_t * _entry) + : entry(_entry), xact(NULL), account(NULL), depth(0) {} - details_t(const transaction_t * _xact, - const balance_pair_t * _balance = NULL, - const unsigned int * _index = NULL) - : entry(_xact->entry), xact(_xact), account(_xact->account), - balance(_balance), index(_index), depth(0) {} + details_t(const transaction_t * _xact) + : entry(_xact->entry), xact(_xact), account(_xact->account), depth(0) {} details_t(const account_t * _account, const unsigned int _depth = 0) - : entry(NULL), xact(NULL), account(_account), - balance(NULL), index(NULL), depth(_depth) {} + : entry(NULL), xact(NULL), account(_account), depth(_depth) {} }; struct node_t @@ -14,19 +14,14 @@ namespace ledger { class item_predicate { const node_t * predicate; - balance_pair_t * balance; - unsigned int * index; public: - item_predicate(const node_t * _predicate, - balance_pair_t * _balance = NULL, - unsigned int * _index = NULL) - : predicate(_predicate), balance(_balance), index(_index) {} + item_predicate(const node_t * _predicate) : predicate(_predicate) {} bool operator()(const entry_t * entry) const { if (predicate) { balance_t result; - predicate->compute(result, details_t(entry, balance, index)); + predicate->compute(result, details_t(entry)); return result; } else { return true; @@ -36,7 +31,7 @@ class item_predicate bool operator()(const transaction_t * xact) const { if (predicate) { balance_t result; - predicate->compute(result, details_t(xact, balance, index)); + predicate->compute(result, details_t(xact)); return result; } else { return true; @@ -68,10 +63,11 @@ inline void add_to_balance_pair(balance_pair_t& balance, class format_transaction { - std::ostream& output_stream; - const format_t& first_line_format; - const format_t& next_lines_format; - mutable entry_t * last_entry; + std::ostream& output_stream; + const format_t& first_line_format; + const format_t& next_lines_format; + unsigned int index; + entry_t * last_entry; public: format_transaction(std::ostream& _output_stream, @@ -80,24 +76,21 @@ class format_transaction : output_stream(_output_stream), first_line_format(_first_line_format), next_lines_format(_next_lines_format), - last_entry(NULL) {} + index(0), last_entry(NULL) {} - void operator()(transaction_t * xact, - balance_pair_t * balance, - unsigned int * index, - const bool inverted) const; + void operator()(transaction_t * xact, const bool inverted); }; -struct compare_transactions { +template <typename T> +struct compare_items { const node_t * sort_order; - compare_transactions(const node_t * _sort_order) + compare_items(const node_t * _sort_order) : sort_order(_sort_order) { assert(sort_order); } - bool operator()(const transaction_t * left, - const transaction_t * right) const { + bool operator()(const T * left, const T * right) const { assert(left); assert(right); balance_t left_result; @@ -118,21 +111,22 @@ class collect_transactions collect_transactions(transactions_deque& _transactions) : transactions(_transactions) {} - void operator()(transaction_t * xact, - balance_pair_t * balance, - unsigned int * index, - const bool inverted) { + void operator()(transaction_t * xact, const bool inverted) { transactions.push_back(xact); } }; +inline void sort_transactions(transactions_deque& transactions, + const node_t * sort_order) +{ + std::stable_sort(transactions.begin(), transactions.end(), + compare_items<transaction_t>(sort_order)); +} + class ignore_transaction { public: - void operator()(transaction_t * xact, - balance_pair_t * balance, - unsigned int * index, - const bool inverted) const {} + void operator()(transaction_t * xact, const bool inverted) const {} }; template <typename Function> @@ -140,16 +134,14 @@ void handle_transaction(transaction_t * xact, Function functor, item_predicate& pred_functor, const bool related, - const bool inverted, - balance_pair_t * balance = NULL, - unsigned int * index = NULL) + const bool inverted) { // If inverted is true, it implies related. if (! inverted && ! (xact->flags & TRANSACTION_HANDLED)) { xact->flags |= TRANSACTION_HANDLED; if (pred_functor(xact)) { xact->flags |= TRANSACTION_DISPLAYED; - functor(xact, balance, index, inverted); + functor(xact, inverted); } } @@ -164,7 +156,7 @@ void handle_transaction(transaction_t * xact, (*i)->flags |= TRANSACTION_HANDLED; if (pred_functor(xact)) { xact->flags |= TRANSACTION_DISPLAYED; - functor(*i, balance, index, inverted); + functor(*i, inverted); } } } @@ -178,18 +170,15 @@ void walk_entries(entries_list::iterator begin, const bool inverted, const node_t * display_predicate = NULL) { - balance_pair_t balance; - unsigned int index; - item_predicate pred_functor(predicate, &balance, &index); - item_predicate disp_pred_functor(display_predicate, &balance, &index); + item_predicate pred_functor(predicate); + item_predicate disp_pred_functor(display_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, disp_pred_functor, - related, inverted, &balance, &index); + handle_transaction(*j, functor, disp_pred_functor, related, inverted); } template <typename Function> @@ -201,11 +190,8 @@ void walk_transactions(transactions_list::iterator begin, const bool inverted, const node_t * display_predicate = NULL) { - balance_pair_t balance; - unsigned int index; - for (transactions_list::iterator i = begin; i != end; i++) - functor(*i, &balance, &index, inverted); + functor(*i, inverted); } template <typename Function> @@ -217,19 +203,15 @@ void walk_transactions(transactions_deque::iterator begin, const bool inverted, const node_t * display_predicate = NULL) { - balance_pair_t balance; - unsigned int index; - for (transactions_deque::iterator i = begin; i != end; i++) - functor(*i, &balance, &index, inverted); + functor(*i, inverted); } class format_account { - std::ostream& output_stream; - const format_t& format; - - mutable const account_t * last_account; + std::ostream& output_stream; + const format_t& format; + const account_t * last_account; public: format_account(std::ostream& _output_stream, const format_t& _format) @@ -238,11 +220,20 @@ class format_account void operator()(const account_t * account, bool report_top = false); }; -void calc__accounts(account_t * account, - const node_t * predicate, - const bool related, - const bool inverted, - const bool calc_subtotals); +typedef std::deque<account_t *> accounts_deque; + +inline void sort_accounts(account_t * account, + accounts_deque& accounts, + const node_t * sort_order) +{ + for (accounts_map::iterator i = account->accounts.begin(); + i != account->accounts.end(); + i++) + accounts.push_back((*i).second); + + std::stable_sort(accounts.begin(), accounts.end(), + compare_items<account_t>(sort_order)); +} template <typename Function> void walk__accounts(const account_t * account, @@ -259,47 +250,55 @@ void walk__accounts(const account_t * account, } template <typename Function> +void walk__accounts_sorted(const account_t * account, + Function functor, + const node_t * sort_order, + const node_t * display_predicate) +{ + if (! display_predicate || item_predicate(display_predicate)(account)) + functor(account); + + accounts_deque accounts; + + for (accounts_map::const_iterator i = account->accounts.begin(); + i != account->accounts.end(); + i++) + accounts.push_back((*i).second); + + std::stable_sort(accounts.begin(), accounts.end(), + compare_items<account_t>(sort_order)); + + for (accounts_deque::const_iterator i = accounts.begin(); + i != accounts.end(); + i++) + walk__accounts_sorted(*i, functor, sort_order, display_predicate); +} + +void calc__accounts(account_t * account, + const node_t * predicate, + const bool related, + const bool inverted, + const bool calc_subtotals); + +template <typename Function> void walk_accounts(account_t * account, Function functor, const node_t * predicate, const bool related, const bool inverted, const bool calc_subtotals, - const node_t * display_predicate = NULL) + const node_t * display_predicate = NULL, + const node_t * sort_order = NULL) { calc__accounts(account, predicate, related, inverted, calc_subtotals); - walk__accounts<Function>(account, functor, display_predicate); -} -#if 0 - -void sum_entries(entries_list& entries, - account_t * account, - const bool show_subtotals) -{ - for (entries_list::const_iterator i = entries.begin(); - i != entries.end(); - i++) - for (transactions_list::const_iterator j = (*i)->transactions.begin(); - j != (*i)->transactions.end(); - j++) - if ((*j)->account == account) { - account->value += *(*j); - if (show_subtotals) - for (account_t * a = account; - a; - a = a->parent) - a->total += *(*j); - } - - for (accounts_map::iterator i = account->accounts.begin(); - i != account->accounts.end(); - i++) - sum_items(entries, *i, show_subtotals); + if (sort_order) + walk__accounts_sorted<Function>(account, functor, sort_order, + display_predicate); + else + walk__accounts<Function>(account, functor, display_predicate); } -#endif - } // namespace ledger #endif // _WALK_H |