use value_t instead of balance_pair_t; gains for 10% binary, 2% textual

This commit is contained in:
John Wiegley 2004-08-21 23:18:45 -04:00
parent 3ff84b7363
commit 6d5333b896
21 changed files with 629 additions and 851 deletions

View file

@ -5,10 +5,9 @@
namespace ledger {
account_t::ident_t account_t::next_ident;
account_t::~account_t()
{
DEBUG_PRINT("ledger.memory.ctors", "dtor account_t");
for (accounts_map::iterator i = accounts.begin();
i != accounts.end();
i++)

View file

@ -10,21 +10,6 @@
namespace ledger {
#ifdef DEBUG_ENABLED
int bigint_ctors = 0;
int bigint_dtors = 0;
#endif
#ifdef DEBUG_ENABLED
static struct ctor_dtor_info {
~ctor_dtor_info() {
DEBUG_CLASS("ledger.amount.bigint");
DEBUG_PRINT_("bigint_t ctor count = " << bigint_ctors);
DEBUG_PRINT_("bigint_t dtor count = " << bigint_dtors);
}
} __info;
#endif
class amount_t::bigint_t {
public:
mpz_t val;
@ -33,37 +18,21 @@ class amount_t::bigint_t {
unsigned int index;
bigint_t() : prec(0), ref(1), index(0) {
DEBUG_PRINT("ledger.memory.ctors", "ctor amount_t::bigint_t");
mpz_init(val);
#ifdef DEBUG_ENABLED
DEBUG_PRINT("ledger.amount.bigint-show",
"ctor " << this << " " << bigint_ctors);
bigint_ctors++;
#endif
}
bigint_t(mpz_t _val) : prec(0), ref(1), index(0) {
DEBUG_PRINT("ledger.memory.ctors", "ctor amount_t::bigint_t");
mpz_init_set(val, _val);
#ifdef DEBUG_ENABLED
DEBUG_PRINT("ledger.amount.bigint-show",
"ctor " << this << " " << bigint_ctors);
bigint_ctors++;
#endif
}
bigint_t(const bigint_t& other)
: prec(other.prec), ref(1), index(0) {
DEBUG_PRINT("ledger.memory.ctors", "ctor amount_t::bigint_t");
mpz_init_set(val, other.val);
#ifdef DEBUG_ENABLED
DEBUG_PRINT("ledger.amount.bigint-show",
"ctor " << this << " " << bigint_ctors);
bigint_ctors++;
#endif
}
~bigint_t() {
DEBUG_PRINT("ledger.memory.dtors", "dtor amount_t::bigint_t");
assert(ref == 0);
#ifdef DEBUG_ENABLED
DEBUG_PRINT("ledger.amount.bigint-show",
"dtor " << this << " " << bigint_dtors);
bigint_dtors++;
#endif
mpz_clear(val);
}
};
@ -150,6 +119,7 @@ static void mpz_round(mpz_t out, mpz_t value, int value_prec, int round_prec)
amount_t::amount_t(const bool value)
{
DEBUG_PRINT("ledger.memory.ctors", "ctor amount_t");
if (value) {
quantity = new bigint_t(true_value);
commodity = commodity_t::null_commodity;
@ -161,6 +131,7 @@ amount_t::amount_t(const bool value)
amount_t::amount_t(const int value)
{
DEBUG_PRINT("ledger.memory.ctors", "ctor amount_t");
if (value != 0) {
quantity = new bigint_t;
mpz_set_si(MPZ(quantity), value);
@ -173,6 +144,7 @@ amount_t::amount_t(const int value)
amount_t::amount_t(const unsigned int value)
{
DEBUG_PRINT("ledger.memory.ctors", "ctor amount_t");
if (value != 0) {
quantity = new bigint_t;
mpz_set_ui(MPZ(quantity), value);
@ -185,6 +157,7 @@ amount_t::amount_t(const unsigned int value)
amount_t::amount_t(const double value)
{
DEBUG_PRINT("ledger.memory.ctors", "ctor amount_t");
if (value != 0.0) {
quantity = new bigint_t;
mpz_set_d(MPZ(quantity), value);

View file

@ -7,6 +7,8 @@
#include <iostream>
#include <sstream>
#include "debug.h"
namespace ledger {
class commodity_t;
@ -41,18 +43,23 @@ class amount_t
// constructors
amount_t(commodity_t * _commodity = NULL)
: quantity(NULL), commodity(_commodity) {}
: quantity(NULL), commodity(_commodity) {
DEBUG_PRINT("ledger.memory.ctors", "ctor amount_t");
}
amount_t(const amount_t& amt) : quantity(NULL) {
DEBUG_PRINT("ledger.memory.ctors", "ctor amount_t");
if (amt.quantity)
_copy(amt);
else
commodity = NULL;
}
amount_t(const std::string& value) : quantity(NULL) {
DEBUG_PRINT("ledger.memory.ctors", "ctor amount_t");
parse(value);
}
amount_t(const char * value) : quantity(NULL) {
DEBUG_PRINT("ledger.memory.ctors", "ctor amount_t");
parse(value);
}
amount_t(const bool value);
@ -62,6 +69,7 @@ class amount_t
// destructor
~amount_t() {
DEBUG_PRINT("ledger.memory.dtors", "dtor amount_t");
if (quantity)
_release();
}
@ -253,8 +261,14 @@ class commodity_t
unsigned int _flags = COMMODITY_STYLE_DEFAULTS)
: symbol(_symbol), quote(false), precision(_precision),
flags(_flags), last_lookup(0) {
DEBUG_PRINT("ledger.memory.ctors", "ctor commodity_t");
check_symbol();
}
#ifdef DEBUG_ENABLED
~commodity_t() {
DEBUG_PRINT("ledger.memory.dtors", "dtor commodity_t");
}
#endif
void check_symbol() {
for (const char * p = symbol.c_str(); *p; p++)

View file

@ -19,6 +19,7 @@ public:
automated_transaction_t(const std::string& _predicate,
transactions_deque& _transactions)
: predicate(_predicate) {
DEBUG_PRINT("ledger.memory.ctors", "ctor automated_transaction_t");
transactions.insert(transactions.begin(),
_transactions.begin(), _transactions.end());
// Take over ownership of the pointers
@ -26,6 +27,7 @@ public:
}
~automated_transaction_t() {
DEBUG_PRINT("ledger.memory.dtors", "dtor automated_transaction_t");
for (transactions_deque::iterator i = transactions.begin();
i != transactions.end();
i++)
@ -43,7 +45,13 @@ class automated_transactions_t
public:
automated_transactions_deque automated_transactions;
#ifdef DEBUG_ENABLED
automated_transactions_t() {
DEBUG_PRINT("ledger.memory.ctors", "ctor automated_transactions_t");
}
#endif
~automated_transactions_t() {
DEBUG_PRINT("ledger.memory.dtors", "dtor automated_transactions_t");
for (automated_transactions_deque::iterator i
= automated_transactions.begin();
i != automated_transactions.end();

View file

@ -1,3 +1,4 @@
#include "balance.h"
#include "ledger.h"
#include <deque>
@ -87,6 +88,7 @@ void balance_t::write(std::ostream& out,
balance_pair_t::balance_pair_t(const transaction_t& xact)
: quantity(xact.amount), cost(NULL)
{
DEBUG_PRINT("ledger.memory.ctors", "ctor balance_pair_t");
if (xact.cost)
cost = new balance_t(*xact.cost);
}

View file

@ -27,28 +27,39 @@ class balance_t
}
// constructors
balance_t() {}
balance_t() {
DEBUG_PRINT("ledger.memory.ctors", "ctor balance_t");
}
balance_t(const balance_t& bal) {
DEBUG_PRINT("ledger.memory.ctors", "ctor balance_t");
for (amounts_map::const_iterator i = bal.amounts.begin();
i != bal.amounts.end();
i++)
*this += (*i).second;
}
balance_t(const amount_t& amt) {
DEBUG_PRINT("ledger.memory.ctors", "ctor balance_t");
*this += amt;
}
balance_t(const int value) {
DEBUG_PRINT("ledger.memory.ctors", "ctor balance_t");
*this += amount_t(value);
}
balance_t(const unsigned int value) {
DEBUG_PRINT("ledger.memory.ctors", "ctor balance_t");
*this += amount_t(value);
}
balance_t(const double value) {
DEBUG_PRINT("ledger.memory.ctors", "ctor balance_t");
*this += amount_t(value);
}
// destructor
~balance_t() {}
#ifdef DEBUG_ENABLED
~balance_t() {
DEBUG_PRINT("ledger.memory.dtors", "dtor balance_t");
}
#endif
// assignment operator
balance_t& operator=(const balance_t& bal) {
@ -394,34 +405,40 @@ class balance_pair_t
}
// constructors
balance_pair_t() : cost(NULL) {}
balance_pair_t() : cost(NULL) {
DEBUG_PRINT("ledger.memory.ctors", "ctor balance_pair_t");
}
balance_pair_t(const balance_pair_t& bal_pair)
: quantity(bal_pair.quantity), cost(NULL) {
DEBUG_PRINT("ledger.memory.ctors", "ctor balance_pair_t");
if (bal_pair.cost)
cost = new balance_t(*bal_pair.cost);
}
#if 0
balance_pair_t(const balance_t& _quantity, const balance_t& _cost)
: quantity(_quantity), cost(_cost) {}
#endif
balance_pair_t(const balance_t& _quantity)
: quantity(_quantity), cost(NULL) {}
#if 0
balance_pair_t(const amount_t& _quantity, const amount_t& _cost)
: quantity(_quantity), cost(_cost) {}
#endif
: quantity(_quantity), cost(NULL) {
DEBUG_PRINT("ledger.memory.ctors", "ctor balance_pair_t");
}
balance_pair_t(const amount_t& _quantity)
: quantity(_quantity), cost(NULL) {}
: quantity(_quantity), cost(NULL) {
DEBUG_PRINT("ledger.memory.ctors", "ctor balance_pair_t");
}
balance_pair_t(const int value)
: quantity(value), cost(NULL) {}
: quantity(value), cost(NULL) {
DEBUG_PRINT("ledger.memory.ctors", "ctor balance_pair_t");
}
balance_pair_t(const unsigned int value)
: quantity(value), cost(NULL) {}
: quantity(value), cost(NULL) {
DEBUG_PRINT("ledger.memory.ctors", "ctor balance_pair_t");
}
balance_pair_t(const double value)
: quantity(value), cost(NULL) {}
: quantity(value), cost(NULL) {
DEBUG_PRINT("ledger.memory.ctors", "ctor balance_pair_t");
}
balance_pair_t(const transaction_t& xact);
// destructor
~balance_pair_t() {
DEBUG_PRINT("ledger.memory.dtors", "dtor balance_pair_t");
if (cost)
delete cost;
}
@ -723,15 +740,24 @@ class balance_pair_t
operator bool() const {
return quantity;
}
operator balance_t() const {
return quantity;
}
operator amount_t() const {
assert(0);
return quantity.amount();
}
void abs() {
quantity.abs();
if (cost)
cost->abs();
}
};
inline balance_pair_t abs(const balance_pair_t& bal_pair) {
balance_pair_t temp;
temp.quantity = abs(bal_pair.quantity);
if (bal_pair.cost) {
temp.cost = new balance_t;
*temp.cost = abs(*bal_pair.cost);
}
temp.abs();
return temp;
}

View file

@ -9,7 +9,7 @@
namespace ledger {
const unsigned long binary_magic_number = 0xFFEED765;
static const unsigned long format_version = 0x00020010;
static const unsigned long format_version = 0x00020011;
bool binary_parser_t::test(std::istream& in) const
{
@ -21,9 +21,9 @@ bool binary_parser_t::test(std::istream& in) const
}
static std::deque<account_t *> accounts;
static account_t::ident_t ident;
static unsigned int account_index;
static std::deque<commodity_t *> commodities;
static commodity_t::ident_t c_ident;
static unsigned int commodity_index;
std::deque<amount_t::bigint_t *> bigints;
#if DEBUG_LEVEL >= ALPHA
@ -84,12 +84,12 @@ inline std::string read_binary_string(std::istream& in)
void read_binary_amount(std::istream& in, amount_t& amt)
{
commodity_t::ident_t id;
read_binary_number(in, id);
if (id == 0xffffffff)
commodity_t::ident_t ident;
read_binary_number(in, ident);
if (ident == 0xffffffff)
amt.commodity = NULL;
else
amt.commodity = commodities[id];
amt.commodity = commodities[ident - 1];
amt.read_quantity(in);
}
@ -98,7 +98,7 @@ transaction_t * read_binary_transaction(std::istream& in, entry_t * entry)
{
transaction_t * xact = new transaction_t(NULL);
xact->account = accounts[read_binary_number<account_t::ident_t>(in)];
xact->account = accounts[read_binary_number<account_t::ident_t>(in) - 1];
xact->account->add_transaction(xact);
read_binary_amount(in, xact->amount);
@ -137,7 +137,7 @@ commodity_t * read_binary_commodity(std::istream& in)
commodities.push_back(commodity);
commodity->ident = read_binary_number<commodity_t::ident_t>(in);
assert(commodity->ident == commodities.size() - 1);
assert(commodity->ident == commodities.size());
read_binary_string(in, commodity->symbol);
read_binary_string(in, commodity->name);
@ -154,8 +154,8 @@ commodity_t * read_binary_commodity(std::istream& in)
read_binary_amount(in, amt);
commodity->history.insert(history_pair(when, amt));
}
read_binary_number(in, commodity->last_lookup);
read_binary_number(in, commodity->last_lookup);
read_binary_amount(in, commodity->conversion);
return commodity;
@ -167,14 +167,14 @@ account_t * read_binary_account(std::istream& in, account_t * master = NULL)
accounts.push_back(acct);
acct->ident = read_binary_number<account_t::ident_t>(in);
assert(acct->ident == accounts.size() - 1);
assert(acct->ident == accounts.size());
account_t::ident_t id;
read_binary_number(in, id); // parent id
if (id == 0xffffffff)
acct->parent = NULL;
else
acct->parent = accounts[id];
acct->parent = accounts[id - 1];
read_binary_string(in, acct->name);
read_binary_string(in, acct->note);
@ -206,8 +206,8 @@ unsigned int read_binary_journal(std::istream& in,
journal_t * journal,
account_t * master)
{
ident = 0;
c_ident = 0;
account_index =
commodity_index = 0;
if (read_binary_number<unsigned long>(in) != binary_magic_number ||
read_binary_number<unsigned long>(in) != format_version)
@ -343,10 +343,9 @@ void write_binary_entry(std::ostream& out, entry_t * entry)
void write_binary_commodity(std::ostream& out, commodity_t * commodity)
{
write_binary_number(out, c_ident);
commodity->ident = c_ident;
++c_ident;
commodity->ident = ++commodity_index;
write_binary_number(out, commodity->ident);
write_binary_string(out, commodity->symbol);
write_binary_string(out, commodity->name);
write_binary_string(out, commodity->note);
@ -360,17 +359,16 @@ void write_binary_commodity(std::ostream& out, commodity_t * commodity)
write_binary_number(out, (*i).first);
write_binary_amount(out, (*i).second);
}
write_binary_number(out, commodity->last_lookup);
write_binary_number(out, commodity->last_lookup);
write_binary_amount(out, commodity->conversion);
}
void write_binary_account(std::ostream& out, account_t * account)
{
write_binary_number(out, ident);
account->ident = ident;
++ident;
account->ident = ++account_index;
write_binary_number(out, account->ident);
if (account->parent)
write_binary_number(out, account->parent->ident);
else

View file

@ -14,7 +14,14 @@ struct interval_t
int seconds;
interval_t(int _seconds = 0, int _months = 0, int _years = 0)
: years(_years), months(_months), seconds(_seconds) {}
: years(_years), months(_months), seconds(_seconds) {
DEBUG_PRINT("ledger.memory.ctors", "ctor interval_t");
}
#ifdef DEBUG_ENABLED
~interval_t() {
DEBUG_PRINT("ledger.memory.dtors", "dtor interval_t");
}
#endif
operator bool() const {
return seconds > 0 || months > 0 || years > 0;

View file

@ -216,6 +216,11 @@ void format_t::format_elements(std::ostream& out,
(elem->max_width > 0 ?
elem->max_width : elem->min_width));
break;
case value_t::BALANCE_PAIR:
((balance_pair_t *) value.data)->quantity.write(out, elem->min_width,
(elem->max_width > 0 ?
elem->max_width : elem->min_width));
break;
default:
assert(0);
break;
@ -353,9 +358,9 @@ bool format_account::disp_subaccounts_p(const account_t * account,
{
bool display = false;
unsigned int counted = 0;
bool computed = false;
bool matches = disp_pred(account);
balance_t acct_total;
value_t acct_total;
bool computed = false;
to_show = NULL;
@ -365,7 +370,7 @@ bool format_account::disp_subaccounts_p(const account_t * account,
if (! disp_pred((*i).second))
continue;
balance_t result;
value_t result;
format_t::compute_total(result, details_t((*i).second));
if (! computed) {

View file

@ -79,7 +79,7 @@ struct format_t
void format_elements(std::ostream& out, const details_t& details) const;
static void compute_value(balance_t& result, const details_t& details) {
static void compute_value(value_t& result, const details_t& details) {
#ifdef NO_CLEANUP
if (value_expr)
#else
@ -88,7 +88,7 @@ struct format_t
value_expr->compute(result, details);
}
static void compute_total(balance_t& result, const details_t& details) {
static void compute_total(value_t& result, const details_t& details) {
#ifdef NO_CLEANUP
if (total_expr)
#else
@ -179,7 +179,7 @@ class format_equity : public item_handler<account_t>
item_predicate<account_t> disp_pred;
mutable balance_t total;
mutable value_t total;
public:
format_equity(std::ostream& _output_stream,
@ -198,7 +198,8 @@ class format_equity : public item_handler<account_t>
virtual void flush() {
account_t summary(NULL, "Equity:Opening Balances");
summary.value = - total;
summary.value = total;
summary.value.negate();
next_lines_format.format_elements(output_stream, details_t(&summary));
output_stream.flush();
}
@ -207,7 +208,7 @@ class format_equity : public item_handler<account_t>
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;
total += account->value;
}
}
};

View file

@ -10,6 +10,8 @@ const std::string version = "2.0b";
journal_t::~journal_t()
{
DEBUG_PRINT("ledger.memory.dtors", "dtor journal_t");
delete master;
// Don't bother unhooking each entry's transactions from the

View file

@ -25,7 +25,7 @@
#endif
#include "amount.h"
#include "balance.h"
#include "value.h"
namespace ledger {
@ -53,7 +53,7 @@ class transaction_t
unsigned short flags;
std::string note;
mutable balance_pair_t total;
mutable value_t total;
mutable unsigned int index;
mutable unsigned short dflags;
@ -69,6 +69,7 @@ class transaction_t
cost(NULL), flags(_flags), note(_note), index(0), dflags(0) {}
~transaction_t() {
DEBUG_PRINT("ledger.memory.dtors", "dtor transaction_t");
if (cost)
delete cost;
}
@ -90,9 +91,12 @@ class entry_t
std::string payee;
transactions_list transactions;
entry_t() : date(-1), state(UNCLEARED) {}
entry_t() : date(-1), state(UNCLEARED) {
DEBUG_PRINT("ledger.memory.ctors", "ctor entry_t");
}
~entry_t() {
DEBUG_PRINT("ledger.memory.dtors", "dtor entry_t");
for (transactions_list::iterator i = transactions.begin();
i != transactions.end();
i++)
@ -128,8 +132,8 @@ class account_t
accounts_map accounts;
transactions_list transactions;
mutable balance_pair_t value;
mutable balance_pair_t total;
mutable value_t value;
mutable value_t total;
mutable unsigned int count; // transactions counted toward total
mutable unsigned int subcount;
mutable ident_t ident;
@ -143,14 +147,15 @@ class account_t
const std::string& _note = "")
: parent(_parent), name(_name), note(_note),
depth(parent ? parent->depth + 1 : 0),
count(0), subcount(0), dflags(0) {}
subcount(0), ident(0), dflags(0) {
DEBUG_PRINT("ledger.memory.ctors", "ctor account_t");
}
~account_t();
std::string fullname() const;
void add_account(account_t * acct) {
acct->ident = next_ident++;
accounts.insert(accounts_pair(acct->name, acct));
}
bool remove_account(account_t * acct) {
@ -193,9 +198,8 @@ class journal_t
mutable accounts_map accounts_cache;
journal_t() {
DEBUG_PRINT("ledger.memory.ctors", "ctor journal_t");
master = new account_t(NULL, "");
master->ident = 0;
account_t::next_ident = 1;
}
~journal_t();

View file

@ -9,6 +9,8 @@ option_handler::option_handler(const std::string& label,
const std::string& opt_chars)
: handled(false)
{
DEBUG_PRINT("ledger.memory.ctors", "ctor option_handler");
option_t opt;
static char buf[128];

2
qif.cc
View file

@ -43,7 +43,7 @@ unsigned int qif_parser_t::parse(std::istream& in,
std::auto_ptr<entry_t> entry;
std::auto_ptr<amount_t> amount;
transaction_t * xact;
unsigned int count;
unsigned int count = 0;
account_t * misc = NULL;
commodity_t * def_commodity = NULL;

View file

@ -146,7 +146,7 @@ bool finalize_entry(entry_t * entry)
// is used for auto-calculating the value of entries with no cost,
// and the per-unit price of unpriced commodities.
balance_t balance;
value_t balance;
for (transactions_list::const_iterator x = entry->transactions.begin();
x != entry->transactions.end();
@ -155,7 +155,9 @@ bool finalize_entry(entry_t * entry)
((*x)->flags & TRANSACTION_BALANCE)) {
DEBUG_PRINT("ledger.textual.finalize",
"item cost is " << ((*x)->cost ? *(*x)->cost : (*x)->amount));
balance += (*x)->cost ? *(*x)->cost : (*x)->amount;
amount_t * p = (*x)->cost ? (*x)->cost : &(*x)->amount;
if (*p)
balance += *p;
}
// If one transaction of a two-line transaction is of a different
@ -163,15 +165,17 @@ bool finalize_entry(entry_t * entry)
// determine its price by dividing the unit count into the value of
// the balance. This is done for the last eligible commodity.
if (balance.amounts.size() == 2)
if (balance.type == value_t::BALANCE &&
((balance_t *) balance.data)->amounts.size() == 2)
for (transactions_list::const_iterator x = entry->transactions.begin();
x != entry->transactions.end();
x++) {
if ((*x)->cost || ((*x)->flags & TRANSACTION_VIRTUAL))
continue;
for (amounts_map::const_iterator i = balance.amounts.begin();
i != balance.amounts.end();
for (amounts_map::const_iterator i
= ((balance_t *) balance.data)->amounts.begin();
i != ((balance_t *) balance.data)->amounts.end();
i++)
if ((*i).second.commodity != (*x)->amount.commodity) {
assert((*x)->amount);
@ -196,8 +200,7 @@ bool finalize_entry(entry_t * entry)
if ((*x)->amount || ((*x)->flags & TRANSACTION_VIRTUAL))
continue;
if (! empty_allowed || balance.amounts.empty() ||
balance.amounts.size() != 1)
if (! empty_allowed || ! balance || balance.type != value_t::AMOUNT)
return false;
empty_allowed = false;
@ -206,13 +209,15 @@ bool finalize_entry(entry_t * entry)
// rest are of the same commodity -- then its value is the
// inverse of the computed value of the others.
amounts_map::const_iterator i = balance.amounts.begin();
(*x)->amount = - balance.amount((*i).first);
(*x)->amount = *((amount_t *) balance.data);
(*x)->amount.negate();
balance = 0;
balance = 0U;
}
#if 0
DEBUG_PRINT("ledger.textual.finalize", "balance is " << balance);
#endif
return ! balance;
}

View file

@ -13,6 +13,8 @@ namespace ledger {
mask_t::mask_t(const std::string& pat) : exclude(false)
{
DEBUG_PRINT("ledger.memory.ctors", "ctor mask_t");
const char * p = pat.c_str();
if (*p == '-') {
exclude = true;
@ -40,6 +42,8 @@ mask_t::mask_t(const std::string& pat) : exclude(false)
mask_t::mask_t(const mask_t& m) : exclude(m.exclude), pattern(m.pattern)
{
DEBUG_PRINT("ledger.memory.ctors", "ctor mask_t");
const char *error;
int erroffset;
regexp = pcre_compile(pattern.c_str(), PCRE_CASELESS,
@ -47,6 +51,11 @@ mask_t::mask_t(const mask_t& m) : exclude(m.exclude), pattern(m.pattern)
assert(regexp);
}
mask_t::~mask_t() {
DEBUG_PRINT("ledger.memory.dtors", "dtor mask_t");
pcre_free((pcre *)regexp);
}
bool mask_t::match(const std::string& str) const
{
static int ovec[30];
@ -55,10 +64,6 @@ bool mask_t::match(const std::string& str) const
return result >= 0 && ! exclude;
}
mask_t::~mask_t() {
pcre_free((pcre *)regexp);
}
void value_expr_t::compute(value_t& result, const details_t& details,
value_t::type_t type) const
@ -79,7 +84,7 @@ void value_expr_t::compute(value_t& result, const details_t& details,
if (details.xact)
result = details.xact->amount;
else if (details.account)
result = details.account->value.quantity;
result = details.account->value;
break;
case COST:
@ -90,32 +95,21 @@ void value_expr_t::compute(value_t& result, const details_t& details,
result = details.xact->amount;
}
else if (details.account) {
if (details.account->value.cost)
result = *details.account->value.cost;
else
result = details.account->value.quantity;
result = details.account->value.cost();
}
break;
case TOTAL:
if (details.xact)
result = details.xact->total.quantity;
result = details.xact->total;
else if (details.account)
result = details.account->total.quantity;
result = details.account->total;
break;
case COST_TOTAL:
if (details.xact) {
if (details.xact->total.cost)
result = *details.xact->total.cost;
else
result = details.xact->total.quantity;
}
else if (details.account) {
if (details.account->total.cost)
result = *details.account->total.cost;
else
result = details.account->total.quantity;
}
if (details.xact)
result = details.xact->total.cost();
else if (details.account)
result = details.account->total.cost();
break;
case VALUE_EXPR:
@ -227,7 +221,8 @@ void value_expr_t::compute(value_t& result, const details_t& details,
case F_STRIP: {
assert(left);
left->compute(result, details);
if (result.type == value_t::BALANCE) {
if (result.type == value_t::BALANCE ||
result.type == value_t::BALANCE_PAIR) {
// jww (2004-08-17): do something smarter here?
result.cast(value_t::AMOUNT);
}

View file

@ -16,12 +16,12 @@ class mask_t
explicit mask_t(const std::string& pattern);
mask_t(const mask_t&);
~mask_t();
bool match(const std::string& str) const;
};
//////////////////////////////////////////////////////////////////////
struct details_t
{
@ -30,13 +30,22 @@ struct details_t
const account_t * account;
details_t(const entry_t * _entry)
: entry(_entry), xact(NULL), account(NULL) {}
: entry(_entry), xact(NULL), account(NULL) {
DEBUG_PRINT("ledger.memory.ctors", "ctor details_t");
}
details_t(const transaction_t * _xact)
: entry(_xact->entry), xact(_xact), account(_xact->account) {}
: entry(_xact->entry), xact(_xact), account(_xact->account) {
DEBUG_PRINT("ledger.memory.ctors", "ctor details_t");
}
details_t(const account_t * _account)
: entry(NULL), xact(NULL), account(_account) {}
: entry(NULL), xact(NULL), account(_account) {
DEBUG_PRINT("ledger.memory.ctors", "ctor details_t");
}
#ifdef DEBUG_ENABLED
~details_t() {
DEBUG_PRINT("ledger.memory.dtors", "dtor details_t");
}
#endif
};
struct value_expr_t
@ -106,9 +115,12 @@ struct value_expr_t
mask_t * mask;
value_expr_t(const kind_t _kind)
: kind(_kind), left(NULL), right(NULL), mask(NULL) {}
: kind(_kind), left(NULL), right(NULL), mask(NULL) {
DEBUG_PRINT("ledger.memory.ctors", "ctor value_expr_t");
}
~value_expr_t() {
DEBUG_PRINT("ledger.memory.dtors", "dtor value_expr_t");
if (mask) delete mask;
if (left) delete left;
if (right) delete right;
@ -116,12 +128,6 @@ struct value_expr_t
void compute(value_t& result, const details_t& details,
value_t::type_t type = value_t::ANY) const;
void compute(balance_t& result, const details_t& details) const {
value_t value;
compute(value, details, value_t::BALANCE);
result = value.operator balance_t();
}
};
value_expr_t * parse_value_expr(std::istream& in);
@ -139,6 +145,8 @@ inline value_expr_t * parse_value_expr(const std::string& str) {
void dump_value_expr(std::ostream& out, const value_expr_t * node);
#endif
//////////////////////////////////////////////////////////////////////
template <typename T>
class item_predicate
{
@ -146,6 +154,7 @@ class item_predicate
public:
item_predicate(const std::string& _predicate) {
DEBUG_PRINT("ledger.memory.ctors", "ctor item_predicate<T>");
predicate = NULL;
if (! _predicate.empty()) {
try {
@ -172,9 +181,12 @@ class item_predicate
}
}
item_predicate(const value_expr_t * _predicate)
: predicate(_predicate) {}
: predicate(_predicate) {
DEBUG_PRINT("ledger.memory.ctors", "ctor item_predicate<T>");
}
~item_predicate() {
DEBUG_PRINT("ledger.memory.dtors", "dtor item_predicate<T>");
if (predicate)
delete predicate;
}

1072
value.cc

File diff suppressed because it is too large Load diff

35
value.h
View file

@ -16,49 +16,66 @@ namespace ledger {
// fact that logic chains only need boolean values to continue, no
// memory allocations need to take place at all.
class transaction_t;
class value_t
{
value_t(const value_t& copy);
public:
char data[sizeof(balance_t)];
char data[sizeof(balance_pair_t)];
enum type_t {
BOOLEAN,
INTEGER,
AMOUNT,
BALANCE,
BALANCE_PAIR,
ANY
} type;
value_t() {
DEBUG_PRINT("ledger.memory.ctors", "ctor value_t");
*((unsigned int *) data) = 0;
type = INTEGER;
}
value_t(const value_t& value) {
DEBUG_PRINT("ledger.memory.ctors", "ctor value_t");
*this = value;
}
value_t(const bool value) {
DEBUG_PRINT("ledger.memory.ctors", "ctor value_t");
*((bool *) data) = value;
type = BOOLEAN;
}
value_t(const unsigned int value) {
DEBUG_PRINT("ledger.memory.ctors", "ctor value_t");
*((unsigned int *) data) = value;
type = INTEGER;
}
value_t(const amount_t& value) {
DEBUG_PRINT("ledger.memory.ctors", "ctor value_t");
new((amount_t *)data) amount_t(value);
type = AMOUNT;
}
value_t(const balance_t& value) {
DEBUG_PRINT("ledger.memory.ctors", "ctor value_t");
new((balance_t *)data) balance_t(value);
type = BALANCE;
}
value_t(const balance_pair_t& value) {
DEBUG_PRINT("ledger.memory.ctors", "ctor value_t");
new((balance_pair_t *)data) balance_pair_t(value);
type = BALANCE_PAIR;
}
~value_t() {
DEBUG_PRINT("ledger.memory.dtors", "dtor value_t");
destroy();
}
void destroy();
value_t& operator=(const value_t& value);
value_t& operator=(const bool value) {
destroy();
*((bool *) data) = value;
@ -83,12 +100,20 @@ class value_t
type = BALANCE;
return *this;
}
value_t& operator=(const balance_pair_t& value) {
destroy();
new((balance_pair_t *)data) balance_pair_t(value);
type = BALANCE_PAIR;
return *this;
}
value_t& operator+=(const value_t& value);
value_t& operator-=(const value_t& value);
value_t& operator*=(const value_t& value);
value_t& operator/=(const value_t& value);
value_t& operator+=(const transaction_t& xact);
bool operator==(const value_t& value);
bool operator!=(const value_t& value) {
return ! (*this == value);
@ -105,6 +130,8 @@ class value_t
void cast(type_t cast_type);
void negate();
void abs();
value_t cost() const;
};
template <typename T>
@ -119,6 +146,8 @@ value_t::operator T() const
return *((amount_t *) data);
case BALANCE:
return *((balance_t *) data);
case BALANCE_PAIR:
return *((balance_pair_t *) data);
default:
assert(0);

17
walk.cc
View file

@ -55,9 +55,10 @@ void collapse_transactions::report_cumulative_subtotal()
assert(count > 1);
totals_account->total = subtotal;
balance_t result;
value_t result;
format_t::compute_total(result, details_t(totals_account));
#if 0
for (amounts_map::const_iterator i = result.amounts.begin();
i != result.amounts.end();
i++) {
@ -69,6 +70,7 @@ void collapse_transactions::report_cumulative_subtotal()
(*handler)(total_xact);
}
#endif
}
subtotal = 0;
@ -78,8 +80,8 @@ void collapse_transactions::report_cumulative_subtotal()
void changed_value_transactions::operator()(transaction_t * xact)
{
if (last_xact) {
balance_t prev_bal;
balance_t cur_bal;
value_t prev_bal;
value_t cur_bal;
std::time_t current = xact ? xact->entry->date : std::time(NULL);
std::time_t prev_date = last_xact->entry->date;
@ -89,13 +91,15 @@ void changed_value_transactions::operator()(transaction_t * xact)
format_t::compute_total(cur_bal, details_t(last_xact));
last_xact->entry->date = prev_date;
if (balance_t diff = cur_bal - prev_bal) {
cur_bal -= prev_bal;
if (cur_bal) {
entry_t * entry = new entry_t;
entry_temps.push_back(entry);
entry->payee = "Commodities revalued";
entry->date = current;
#if 0
for (amounts_map::const_iterator i = diff.amounts.begin();
i != diff.amounts.end();
i++) {
@ -108,6 +112,7 @@ void changed_value_transactions::operator()(transaction_t * xact)
(*handler)(temp_xact);
}
#endif
}
}
@ -150,10 +155,11 @@ void subtotal_transactions::flush(const char * spec_fmt)
transaction_t temp((*i).first);
temp.entry = entry;
temp.total = (*i).second;
balance_t result;
value_t result;
format_t::compute_total(result, details_t(&temp));
entry->date = start;
#if 0
for (amounts_map::const_iterator j = result.amounts.begin();
j != result.amounts.end();
j++) {
@ -165,6 +171,7 @@ void subtotal_transactions::flush(const char * spec_fmt)
(*handler)(xact);
}
#endif
}
balances.clear();

9
walk.h
View file

@ -16,10 +16,15 @@ struct item_handler {
item_handler * handler;
public:
item_handler() : handler(NULL) {}
item_handler(item_handler * _handler) : handler(_handler) {}
item_handler() : handler(NULL) {
DEBUG_PRINT("ledger.memory.ctors", "ctor item_handler<T>");
}
item_handler(item_handler * _handler) : handler(_handler) {
DEBUG_PRINT("ledger.memory.ctors", "ctor item_handler<T>");
}
virtual ~item_handler() {
DEBUG_PRINT("ledger.memory.dtors", "dtor item_handler<T>");
if (handler)
delete handler;
}