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:
parent
e0e181d2af
commit
092542a3bf
6 changed files with 79 additions and 46 deletions
|
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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 <>
|
||||||
|
|
|
||||||
21
src/value.cc
21
src/value.cc
|
|
@ -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
|
||||||
|
|
|
||||||
11
src/value.h
11
src/value.h
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue