Sorting expr now uses "-" to indicate descending

For example: -S payee,-date sorts 1) ascending by payee, then 2)
descending by date.
This commit is contained in:
John Wiegley 2009-02-12 20:45:33 -04:00
parent e0e181d2af
commit 092542a3bf
6 changed files with 79 additions and 46 deletions

View file

@ -126,12 +126,13 @@ class account_t : public scope_t
value_t value; value_t value;
value_t total; value_t total;
value_t sort_value;
std::size_t count; // xacts counted toward amount std::size_t count; // xacts counted toward amount
std::size_t total_count; // xacts counted toward total std::size_t total_count; // xacts counted toward total
std::size_t virtuals; std::size_t virtuals;
uint_least8_t dflags; uint_least8_t dflags;
std::list<sort_value_t> sort_values;
xdata_t() xdata_t()
: supports_flags<>(), count(0), total_count(0), : supports_flags<>(), count(0), total_count(0),
virtuals(0), dflags(0) virtuals(0), dflags(0)
@ -142,11 +143,11 @@ class account_t : public scope_t
: supports_flags<>(other.flags()), : supports_flags<>(other.flags()),
value(other.value), value(other.value),
total(other.total), total(other.total),
sort_value(other.sort_value),
count(other.count), count(other.count),
total_count(other.total_count), total_count(other.total_count),
virtuals(other.virtuals), virtuals(other.virtuals),
dflags(other.dflags) dflags(other.dflags),
sort_values(other.sort_values)
{ {
TRACE_CTOR(account_t::xdata_t, "copy"); TRACE_CTOR(account_t::xdata_t, "copy");
} }

View file

@ -30,38 +30,41 @@
*/ */
#include "compare.h" #include "compare.h"
#include "op.h"
namespace ledger { namespace ledger {
bool value_is_less_than(const value_t& left, const value_t& right) namespace {
{ template <typename T>
if (left.is_sequence()) { void push_sort_value(std::list<sort_value_t>& sort_values,
assert(right.is_sequence()); expr_t::ptr_op_t node, T * scope)
{
const value_t::sequence_t& left_seq(left.as_sequence()); if (node->kind == expr_t::op_t::O_COMMA) {
value_t::sequence_t::const_iterator left_iter = left_seq.begin(); push_sort_value(sort_values, node->left(), scope);
push_sort_value(sort_values, node->right(), scope);
const value_t::sequence_t& right_seq(right.as_sequence());
value_t::sequence_t::const_iterator right_iter = right_seq.begin();
while (left_iter != left_seq.end() &&
right_iter != right_seq.end()) {
if (*left_iter < *right_iter)
return true;
else if (*left_iter > *right_iter)
return false;
left_iter++; right_iter++;
} }
else {
bool inverted = false;
assert(left_iter == left_seq.end()); if (node->kind == expr_t::op_t::O_NEG) {
assert(right_iter == right_seq.end()); inverted = true;
node = node->left();
}
return true; sort_values.push_back(sort_value_t());
} else { sort_values.back().inverted = inverted;
return left < right; sort_values.back().value = expr_t(node).calc(*scope).reduced();
}
} }
} }
template <typename T>
void compare_items<T>::find_sort_values(std::list<sort_value_t>& sort_values,
T * scope)
{
push_sort_value(sort_values, sort_order.get_op(), scope);
}
template <> template <>
bool compare_items<xact_t>::operator()(xact_t * left, xact_t * right) bool compare_items<xact_t>::operator()(xact_t * left, xact_t * right)
{ {
@ -70,24 +73,17 @@ bool compare_items<xact_t>::operator()(xact_t * left, xact_t * right)
xact_t::xdata_t& lxdata(left->xdata()); xact_t::xdata_t& lxdata(left->xdata());
if (! lxdata.has_flags(XACT_EXT_SORT_CALC)) { if (! lxdata.has_flags(XACT_EXT_SORT_CALC)) {
lxdata.sort_value = sort_order.calc(*left); find_sort_values(lxdata.sort_values, left);
lxdata.sort_value.reduce();
lxdata.add_flags(XACT_EXT_SORT_CALC); lxdata.add_flags(XACT_EXT_SORT_CALC);
} }
xact_t::xdata_t& rxdata(right->xdata()); xact_t::xdata_t& rxdata(right->xdata());
if (! rxdata.has_flags(XACT_EXT_SORT_CALC)) { if (! rxdata.has_flags(XACT_EXT_SORT_CALC)) {
rxdata.sort_value = sort_order.calc(*right); find_sort_values(rxdata.sort_values, right);
rxdata.sort_value.reduce();
rxdata.add_flags(XACT_EXT_SORT_CALC); rxdata.add_flags(XACT_EXT_SORT_CALC);
} }
DEBUG("ledger.walk.compare_items_xact", return value_is_less_than(lxdata.sort_values, rxdata.sort_values);
"lxdata.sort_value = " << lxdata.sort_value);
DEBUG("ledger.walk.compare_items_xact",
"rxdata.sort_value = " << rxdata.sort_value);
return value_is_less_than(lxdata.sort_value, rxdata.sort_value);
} }
template <> template <>
@ -98,17 +94,17 @@ bool compare_items<account_t>::operator()(account_t * left, account_t * right)
account_t::xdata_t& lxdata(left->xdata()); account_t::xdata_t& lxdata(left->xdata());
if (! lxdata.has_flags(ACCOUNT_EXT_SORT_CALC)) { if (! lxdata.has_flags(ACCOUNT_EXT_SORT_CALC)) {
lxdata.sort_value = sort_order.calc(*left); find_sort_values(lxdata.sort_values, left);
lxdata.add_flags(ACCOUNT_EXT_SORT_CALC); lxdata.add_flags(ACCOUNT_EXT_SORT_CALC);
} }
account_t::xdata_t& rxdata(right->xdata()); account_t::xdata_t& rxdata(right->xdata());
if (! rxdata.has_flags(ACCOUNT_EXT_SORT_CALC)) { if (! rxdata.has_flags(ACCOUNT_EXT_SORT_CALC)) {
rxdata.sort_value = sort_order.calc(*right); find_sort_values(rxdata.sort_values, right);
rxdata.add_flags(ACCOUNT_EXT_SORT_CALC); rxdata.add_flags(ACCOUNT_EXT_SORT_CALC);
} }
return value_is_less_than(lxdata.sort_value, rxdata.sort_value); return value_is_less_than(lxdata.sort_values, rxdata.sort_values);
} }
} // namespace ledger } // namespace ledger

View file

@ -74,17 +74,20 @@ public:
~compare_items() throw() { ~compare_items() throw() {
TRACE_DTOR(compare_items); TRACE_DTOR(compare_items);
} }
void find_sort_values(std::list<sort_value_t>& sort_values, T * scope);
bool operator()(T * left, T * right); bool operator()(T * left, T * right);
}; };
bool value_is_less_than(const value_t& left, const value_t& right); sort_value_t calc_sort_value(const expr_t::ptr_op_t op);
template <typename T> template <typename T>
bool compare_items<T>::operator()(T * left, T * right) bool compare_items<T>::operator()(T * left, T * right)
{ {
assert(left); assert(left); assert(right);
assert(right); return value_is_less_than(find_sort_values(left),
return sort_order.calc(*left) < sort_order.calc(*right); find_sort_values(right));
} }
template <> template <>

View file

@ -1409,4 +1409,25 @@ bool value_t::valid() const
return true; return true;
} }
bool value_is_less_than(const std::list<sort_value_t>& left_values,
const std::list<sort_value_t>& right_values)
{
std::list<sort_value_t>::const_iterator left_iter = left_values.begin();
std::list<sort_value_t>::const_iterator right_iter = right_values.begin();
while (left_iter != left_values.end() &&
right_iter != right_values.end()) {
if ((*left_iter).value < (*right_iter).value)
return ! (*left_iter).inverted;
else if ((*left_iter).value > (*right_iter).value)
return (*left_iter).inverted;
left_iter++; right_iter++;
}
assert(left_iter == left_values.end());
assert(right_iter == right_values.end());
return true;
}
} // namespace ledger } // namespace ledger

View file

@ -931,6 +931,17 @@ inline value_t& add_or_set_value(value_t& lhs, const T& rhs) {
return lhs; return lhs;
} }
struct sort_value_t
{
bool inverted;
value_t value;
sort_value_t() : inverted(false) {}
};
bool value_is_less_than(const std::list<sort_value_t>& left_values,
const std::list<sort_value_t>& right_values);
} // namespace ledger } // namespace ledger
#endif // _VALUE_H #endif // _VALUE_H

View file

@ -132,23 +132,24 @@ public:
#define XACT_EXT_MATCHES 0x80 #define XACT_EXT_MATCHES 0x80
value_t total; value_t total;
value_t sort_value;
value_t value; value_t value;
date_t date; date_t date;
account_t * account; account_t * account;
void * ptr; void * ptr;
std::list<sort_value_t> sort_values;
xdata_t() : supports_flags<>(), account(NULL), ptr(NULL) { xdata_t() : supports_flags<>(), account(NULL), ptr(NULL) {
TRACE_CTOR(xact_t::xdata_t, ""); TRACE_CTOR(xact_t::xdata_t, "");
} }
xdata_t(const xdata_t& other) xdata_t(const xdata_t& other)
: supports_flags<>(other.flags()), : supports_flags<>(other.flags()),
total(other.total), total(other.total),
sort_value(other.sort_value),
value(other.value), value(other.value),
date(other.date), date(other.date),
account(other.account), account(other.account),
ptr(NULL) ptr(NULL),
sort_values(other.sort_values)
{ {
TRACE_CTOR(xact_t::xdata_t, "copy"); TRACE_CTOR(xact_t::xdata_t, "copy");
} }