summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--amount.cc267
-rw-r--r--amount.h34
-rw-r--r--balance.h2
-rw-r--r--journal.cc59
-rw-r--r--textual.cc23
-rw-r--r--valexpr.cc10
-rw-r--r--valexpr.h3
-rw-r--r--value.cc4
8 files changed, 190 insertions, 212 deletions
diff --git a/amount.cc b/amount.cc
index b84bc535..f2bbb614 100644
--- a/amount.cc
+++ b/amount.cc
@@ -378,8 +378,11 @@ amount_t& amount_t::operator+=(const amount_t& amt)
_dup();
- if (commodity_ != amt.commodity_)
- throw new amount_error("Adding amounts with different commodities");
+ if (commodity() != amt.commodity())
+ throw new amount_error
+ (std::string("Adding amounts with different commodities: ") +
+ commodity_->qualified_symbol + " != " +
+ amt.commodity_->qualified_symbol);
if (quantity->prec == amt.quantity->prec) {
mpz_add(MPZ(quantity), MPZ(quantity), MPZ(amt.quantity));
@@ -411,8 +414,11 @@ amount_t& amount_t::operator-=(const amount_t& amt)
_dup();
- if (commodity_ != amt.commodity_)
- throw new amount_error("Subtracting amounts with different commodities");
+ if (commodity() != amt.commodity())
+ throw new amount_error
+ (std::string("Subtracting amounts with different commodities: ") +
+ commodity_->qualified_symbol + " != " +
+ amt.commodity_->qualified_symbol);
if (quantity->prec == amt.quantity->prec) {
mpz_sub(MPZ(quantity), MPZ(quantity), MPZ(amt.quantity));
@@ -533,10 +539,10 @@ amount_t::operator bool() const
return mpz_sgn(MPZ(quantity)) != 0;
} else {
mpz_set(temp, MPZ(quantity));
- if (commodity_)
- mpz_ui_pow_ui(divisor, 10, quantity->prec - commodity().precision());
- else
+ if (quantity->flags & BIGINT_KEEP_PREC)
mpz_ui_pow_ui(divisor, 10, quantity->prec);
+ else
+ mpz_ui_pow_ui(divisor, 10, quantity->prec - commodity().precision());
mpz_tdiv_q(temp, temp, divisor);
bool zero = mpz_sgn(temp) == 0;
return ! zero;
@@ -600,22 +606,37 @@ amount_t amount_t::value(const std::time_t moment) const
amount_t amount_t::round(unsigned int prec) const
{
- if (! quantity || quantity->prec <= prec)
- return *this;
-
amount_t temp = *this;
+
+ if (! quantity || quantity->prec <= prec) {
+ if (quantity->flags & BIGINT_KEEP_PREC) {
+ temp._dup();
+ temp.quantity->flags &= ~BIGINT_KEEP_PREC;
+ }
+ return temp;
+ }
+
temp._dup();
mpz_round(MPZ(temp.quantity), MPZ(temp.quantity), temp.quantity->prec, prec);
+
temp.quantity->prec = prec;
+ temp.quantity->flags &= ~BIGINT_KEEP_PREC;
return temp;
}
amount_t amount_t::unround() const
{
- if (! quantity || quantity->flags & BIGINT_KEEP_PREC)
+ if (! quantity) {
+ amount_t temp(0L);
+ assert(temp.quantity);
+ temp.quantity->flags |= BIGINT_KEEP_PREC;
+ return temp;
+ }
+ else if (quantity->flags & BIGINT_KEEP_PREC) {
return *this;
+ }
amount_t temp = *this;
temp._dup();
@@ -731,7 +752,7 @@ std::ostream& operator<<(std::ostream& _out, const amount_t& amt)
last.commodity_ = last.commodity().larger()->commodity_;
if (ledger::abs(last) < 1)
break;
- base = last;
+ base = last.round();
}
}
@@ -849,8 +870,6 @@ std::ostream& operator<<(std::ostream& _out, const amount_t& amt)
}
if (precision) {
- out << ((comm.flags() & COMMODITY_STYLE_EUROPEAN) ? ',' : '.');
-
std::ostringstream final;
final.width(precision);
final.fill('0');
@@ -865,12 +884,18 @@ std::ostream& operator<<(std::ostream& _out, const amount_t& amt)
if (q[i - 1] != '0')
break;
+ std::string ender;
if (i == len)
- out << str;
+ ender = str;
else if (i < comm.precision())
- out << std::string(str, 0, comm.precision());
+ ender = std::string(str, 0, comm.precision());
else
- out << std::string(str, 0, i);
+ ender = std::string(str, 0, i);
+
+ if (! ender.empty()) {
+ out << ((comm.flags() & COMMODITY_STYLE_EUROPEAN) ? ',' : '.');
+ out << ender;
+ }
}
if (comm.flags() & COMMODITY_STYLE_SUFFIXED) {
@@ -889,6 +914,7 @@ std::ostream& operator<<(std::ostream& _out, const amount_t& amt)
if (comm.annotated) {
annotated_commodity_t& ann(static_cast<annotated_commodity_t&>(comm));
+ assert(&ann.price != &amt);
ann.write_annotations(out);
}
@@ -928,18 +954,14 @@ void parse_commodity(std::istream& in, std::string& symbol)
symbol = buf;
}
-void parse_annotations(std::istream& in, const std::string& symbol,
- std::string& name, std::string& price,
- std::string& date, std::string& tag)
+void parse_annotations(std::istream& in, amount_t& price,
+ std::time_t& date, std::string& tag)
{
- char buf[256];
-
- bool added_name = false;
- bool handled = false;
do {
+ char buf[256];
char c = peek_next_nonws(in);
if (c == '{') {
- if (! price.empty())
+ if (price)
throw new amount_error("Commodity specifies more than one price");
in.get(c);
@@ -948,21 +970,12 @@ void parse_annotations(std::istream& in, const std::string& symbol,
in.get(c);
else
throw new amount_error("Commodity price lacks closing brace");
- price = buf;
- if (! added_name) {
- added_name = true;
- if (commodity_t::needs_quotes(symbol)) {
- name = "\"";
- name += symbol;
- name += "\"";
- }
- }
- name += " {";
- name += price;
- name += "}";
+
+ price.parse(buf, AMOUNT_PARSE_NO_MIGRATE);
+ price.reduce();
}
else if (c == '[') {
- if (! date.empty())
+ if (date)
throw new amount_error("Commodity specifies more than one date");
in.get(c);
@@ -971,18 +984,8 @@ void parse_annotations(std::istream& in, const std::string& symbol,
in.get(c);
else
throw new amount_error("Commodity date lacks closing bracket");
- date = buf;
- if (! added_name) {
- added_name = true;
- if (commodity_t::needs_quotes(symbol)) {
- name = "\"";
- name += symbol;
- name += "\"";
- }
- }
- name += " [";
- name += date;
- name += "]";
+
+ parse_date(buf, &date);
}
else if (c == '(') {
if (! tag.empty())
@@ -994,27 +997,16 @@ void parse_annotations(std::istream& in, const std::string& symbol,
in.get(c);
else
throw new amount_error("Commodity tag lacks closing parenthesis");
+
tag = buf;
- if (! added_name) {
- added_name = true;
- if (commodity_t::needs_quotes(symbol)) {
- name = "\"";
- name += symbol;
- name += "\"";
- }
- }
- name += " (";
- name += tag;
- name += ")";
}
else {
break;
}
} while (true);
- DEBUG_PRINT("amounts.commodities", "Parsed commodity annotations: "
- << "name " << name << " "
- << "symbol " << symbol << std::endl
+ DEBUG_PRINT("amounts.commodities",
+ "Parsed commodity annotations: "
<< " price " << price << " "
<< " date " << date << " "
<< " tag " << tag);
@@ -1027,11 +1019,10 @@ void amount_t::parse(std::istream& in, unsigned char flags)
// [-]NUM[ ]SYM [@ AMOUNT]
// SYM[ ][-]NUM [@ AMOUNT]
- std::string name;
std::string symbol;
std::string quant;
- std::string price;
- std::string date;
+ amount_t price;
+ std::time_t date = 0;
std::string tag;
unsigned int comm_flags = COMMODITY_STYLE_DEFAULTS;
bool negative = false;
@@ -1052,17 +1043,15 @@ void amount_t::parse(std::istream& in, unsigned char flags)
comm_flags |= COMMODITY_STYLE_SEPARATED;
parse_commodity(in, symbol);
- name = symbol;
if (! symbol.empty())
comm_flags |= COMMODITY_STYLE_SUFFIXED;
if (! in.eof() && ((n = in.peek()) != '\n'))
- parse_annotations(in, symbol, name, price, date, tag);
+ parse_annotations(in, price, date, tag);
}
} else {
parse_commodity(in, symbol);
- name = symbol;
if (! in.eof() && ((n = in.peek()) != '\n')) {
if (std::isspace(in.peek()))
@@ -1071,7 +1060,7 @@ void amount_t::parse(std::istream& in, unsigned char flags)
parse_quantity(in, quant);
if (! in.eof() && ((n = in.peek()) != '\n'))
- parse_annotations(in, symbol, name, price, date, tag);
+ parse_annotations(in, price, date, tag);
}
}
@@ -1085,23 +1074,19 @@ void amount_t::parse(std::istream& in, unsigned char flags)
bool newly_created = false;
- commodity_ = commodity_t::find(name);
- if (! commodity_) {
- newly_created = true;
-
- if (! price.empty() || ! date.empty() || ! tag.empty()) {
- commodity_ = annotated_commodity_t::create(symbol, price, date, tag);
- } else {
- assert(name == symbol);
+ if (symbol.empty()) {
+ commodity_ = commodity_t::null_commodity;
+ } else {
+ commodity_ = commodity_t::find(symbol);
+ if (! commodity_) {
commodity_ = commodity_t::create(symbol);
+ newly_created = true;
}
-#ifdef DEBUG_ENABLED
- if (! commodity_)
- std::cerr << "Failed to find commodity for name "
- << name << " symbol " << symbol << std::endl;
-#endif
- if (! commodity_)
- commodity_ = commodity_t::null_commodity;
+ assert(commodity_);
+
+ if (price || date || ! tag.empty())
+ commodity_ =
+ annotated_commodity_t::find_or_create(*commodity_, price, date, tag);
}
// Determine the precision of the amount, based on the usage of
@@ -1327,10 +1312,13 @@ void amount_t::write_quantity(std::ostream& out) const
bool amount_t::valid() const
{
if (quantity) {
- if (quantity->ref == 0)
+ if (quantity->ref == 0) {
+ DEBUG_PRINT("ledger.validate", "amount_t: quantity->ref == 0");
return false;
+ }
}
else if (commodity_) {
+ DEBUG_PRINT("ledger.validate", "amount_t: commodity_ != NULL");
return false;
}
return true;
@@ -1448,16 +1436,21 @@ bool commodity_t::needs_quotes(const std::string& symbol)
bool commodity_t::valid() const
{
- if (symbol().empty() && this != null_commodity)
+ if (symbol().empty() && this != null_commodity) {
+ DEBUG_PRINT("ledger.validate",
+ "commodity_t: symbol().empty() && this != null_commodity");
return false;
+ }
-#if 0
- if (annotated && ! base)
+ if (annotated && ! base) {
+ DEBUG_PRINT("ledger.validate", "commodity_t: annotated && ! base");
return false;
-#endif
+ }
- if (precision() > 16)
+ if (precision() > 16) {
+ DEBUG_PRINT("ledger.validate", "commodity_t: precision() > 16");
return false;
+ }
return true;
}
@@ -1572,34 +1565,12 @@ annotated_commodity_t::write_annotations(std::ostream& out,
out << " (" << tag << ')';
}
-std::string
-annotated_commodity_t::make_qualified_name(const commodity_t& comm,
- const amount_t& price,
- const std::time_t date,
- const std::string& tag)
-{
- std::ostringstream name;
-
- comm.write(name);
- write_annotations(name, price, date, tag);
-
- DEBUG_PRINT("amounts.commodities", "make_qualified_name for "
- << comm.qualified_symbol << std::endl
- << " price " << price << " "
- << " date " << date << " "
- << " tag " << tag);
-
- DEBUG_PRINT("amounts.commodities", "qualified_name is " << name.str());
-
- return name.str();
-}
-
commodity_t *
annotated_commodity_t::create(const commodity_t& comm,
const amount_t& price,
const std::time_t date,
const std::string& tag,
- const std::string& entry_name)
+ const std::string& mapping_key)
{
std::auto_ptr<annotated_commodity_t> commodity(new annotated_commodity_t);
@@ -1615,12 +1586,6 @@ annotated_commodity_t::create(const commodity_t& comm,
commodity->qualified_symbol = comm.symbol();
- std::string mapping_key;
- if (entry_name.empty())
- mapping_key = make_qualified_name(comm, price, date, tag);
- else
- mapping_key = entry_name;
-
DEBUG_PRINT("amounts.commodities", "Creating annotated commodity "
<< "symbol " << commodity->symbol()
<< " key " << mapping_key << std::endl
@@ -1638,39 +1603,27 @@ annotated_commodity_t::create(const commodity_t& comm,
return commodity.release();
}
-commodity_t *
-annotated_commodity_t::create(const std::string& symbol,
- const amount_t& price,
- const std::time_t date,
- const std::string& tag)
-{
- commodity_t * comm = commodity_t::find_or_create(symbol);
- assert(comm);
-
- if (! price && ! date && tag.empty())
- return comm;
-
- return create(*comm, price, date, tag);
-}
+namespace {
+ std::string make_qualified_name(const commodity_t& comm,
+ const amount_t& price,
+ const std::time_t date,
+ const std::string& tag)
+ {
+ std::ostringstream name;
-commodity_t *
-annotated_commodity_t::create(const std::string& symbol,
- const std::string& price,
- const std::string& date,
- const std::string& tag)
-{
- commodity_t * comm = commodity_t::find_or_create(symbol);
- assert(comm);
+ comm.write(name);
+ annotated_commodity_t::write_annotations(name, price, date, tag);
- amount_t real_price;
- if (! price.empty())
- real_price.parse(price, AMOUNT_PARSE_NO_MIGRATE);
+ DEBUG_PRINT("amounts.commodities", "make_qualified_name for "
+ << comm.qualified_symbol << std::endl
+ << " price " << price << " "
+ << " date " << date << " "
+ << " tag " << tag);
- std::time_t real_date = 0;
- if (! date.empty())
- parse_date(date.c_str(), &real_date);
+ DEBUG_PRINT("amounts.commodities", "qualified_name is " << name.str());
- return create(*comm, real_price, real_date, tag);
+ return name.str();
+ }
}
commodity_t *
@@ -1681,14 +1634,12 @@ annotated_commodity_t::find_or_create(const commodity_t& comm,
{
std::string name = make_qualified_name(comm, price, date, tag);
- commodity_t * base = commodity_t::find(name);
- if (base)
- return base;
-
- base = commodity_t::find_or_create(comm.base_symbol());
- assert(base);
-
- return create(*base, price, date, tag, name);
+ commodity_t * ann_comm = commodity_t::find(name);
+ if (ann_comm) {
+ assert(ann_comm->annotated);
+ return ann_comm;
+ }
+ return create(comm, price, date, tag, name);
}
} // namespace ledger
diff --git a/amount.h b/amount.h
index 4db7a5eb..8019680c 100644
--- a/amount.h
+++ b/amount.h
@@ -551,40 +551,32 @@ class annotated_commodity_t : public commodity_t
std::time_t date;
std::string tag;
+ explicit annotated_commodity_t() {
+ annotated = true;
+ }
+
+ void write_annotations(std::ostream& out) const {
+ annotated_commodity_t::write_annotations(out, price, date, tag);
+ }
+
static void write_annotations(std::ostream& out,
const amount_t& price,
const std::time_t date,
const std::string& tag);
- static
- std::string make_qualified_name(const commodity_t& comm,
- const amount_t& price,
- const std::time_t date,
- const std::string& tag);
+
+ private:
static commodity_t * create(const commodity_t& comm,
const amount_t& price,
const std::time_t date,
const std::string& tag,
- const std::string& entry_name = "");
- static commodity_t * create(const std::string& symbol,
- const amount_t& price,
- const std::time_t date,
- const std::string& tag);
- static commodity_t * create(const std::string& symbol,
- const std::string& price,
- const std::string& date,
- const std::string& tag);
+ const std::string& mapping_key);
+
static commodity_t * find_or_create(const commodity_t& comm,
const amount_t& price,
const std::time_t date,
const std::string& tag);
- explicit annotated_commodity_t() {
- annotated = true;
- }
-
- void write_annotations(std::ostream& out) const {
- annotated_commodity_t::write_annotations(out, price, date, tag);
- }
+ friend class amount_t;
};
inline std::ostream& operator<<(std::ostream& out, const commodity_t& comm) {
diff --git a/balance.h b/balance.h
index 71929f13..c115ba45 100644
--- a/balance.h
+++ b/balance.h
@@ -101,7 +101,7 @@ class balance_t
if (i != amounts.end()) {
(*i).second -= amt;
if ((*i).second.realzero())
- amounts.erase(&amt.commodity());
+ amounts.erase(i);
}
else if (! amt.realzero()) {
amounts.insert(amounts_pair(&amt.commodity(), - amt));
diff --git a/journal.cc b/journal.cc
index b1292907..c326a223 100644
--- a/journal.cc
+++ b/journal.cc
@@ -36,11 +36,15 @@ std::time_t transaction_t::effective_date() const
bool transaction_t::valid() const
{
- if (! entry)
+ if (! entry) {
+ DEBUG_PRINT("ledger.validate", "transaction_t: ! entry");
return false;
+ }
- if (state != UNCLEARED && state != CLEARED && state != PENDING)
+ if (state != UNCLEARED && state != CLEARED && state != PENDING) {
+ DEBUG_PRINT("ledger.validate", "transaction_t: state is bad");
return false;
+ }
bool found = false;
for (transactions_list::const_iterator i = entry->transactions.begin();
@@ -50,20 +54,30 @@ bool transaction_t::valid() const
found = true;
break;
}
- if (! found)
+ if (! found) {
+ DEBUG_PRINT("ledger.validate", "transaction_t: ! found");
return false;
+ }
- if (! account)
+ if (! account) {
+ DEBUG_PRINT("ledger.validate", "transaction_t: ! account");
return false;
+ }
- if (! amount.valid())
+ if (! amount.valid()) {
+ DEBUG_PRINT("ledger.validate", "transaction_t: ! amount.valid()");
return false;
+ }
- if (cost && ! cost->valid())
+ if (cost && ! cost->valid()) {
+ DEBUG_PRINT("ledger.validate", "transaction_t: cost && ! cost->valid()");
return false;
+ }
- if (flags & ~0x001f)
+ if (flags & ~0x001f) {
+ DEBUG_PRINT("ledger.validate", "transaction_t: flags are bad");
return false;
+ }
return true;
}
@@ -158,7 +172,8 @@ bool entry_base_t::finalize()
entry_t * entry = dynamic_cast<entry_t *>(this);
- if (! (*x)->amount.commodity().annotated)
+ if ((*x)->amount.commodity() &&
+ ! (*x)->amount.commodity().annotated)
(*x)->amount.annotate_commodity(abs(per_unit_cost),
entry ? entry->actual_date() : 0,
entry ? entry->code : "");
@@ -271,14 +286,18 @@ void entry_t::add_transaction(transaction_t * xact)
bool entry_t::valid() const
{
- if (! _date || ! journal)
+ if (! _date || ! journal) {
+ DEBUG_PRINT("ledger.validate", "entry_t: ! _date || ! journal");
return false;
+ }
for (transactions_list::const_iterator i = transactions.begin();
i != transactions.end();
i++)
- if ((*i)->entry != this || ! (*i)->valid())
+ if ((*i)->entry != this || ! (*i)->valid()) {
+ DEBUG_PRINT("ledger.validate", "entry_t: transaction not valid");
return false;
+ }
return true;
}
@@ -434,14 +453,18 @@ std::ostream& operator<<(std::ostream& out, const account_t& account)
bool account_t::valid() const
{
- if (depth > 256 || ! journal)
+ if (depth > 256 || ! journal) {
+ DEBUG_PRINT("ledger.validate", "account_t: depth > 256 || ! journal");
return false;
+ }
for (accounts_map::const_iterator i = accounts.begin();
i != accounts.end();
i++)
- if (! (*i).second->valid())
+ if (! (*i).second->valid()) {
+ DEBUG_PRINT("ledger.validate", "account_t: child not valid");
return false;
+ }
return true;
}
@@ -528,20 +551,26 @@ bool journal_t::remove_entry(entry_t * entry)
bool journal_t::valid() const
{
- if (! master->valid())
+ if (! master->valid()) {
+ DEBUG_PRINT("ledger.validate", "journal_t: master not valid");
return false;
+ }
for (entries_list::const_iterator i = entries.begin();
i != entries.end();
i++)
- if (! (*i)->valid())
+ if (! (*i)->valid()) {
+ DEBUG_PRINT("ledger.validate", "journal_t: entry not valid");
return false;
+ }
for (commodities_map::const_iterator i = commodity_t::commodities.begin();
i != commodity_t::commodities.end();
i++)
- if (! (*i).second->valid())
+ if (! (*i).second->valid()) {
+ DEBUG_PRINT("ledger.validate", "journal_t: commodity not valid");
return false;
+ }
return true;
}
diff --git a/textual.cc b/textual.cc
index 29b548e5..4e2a12f4 100644
--- a/textual.cc
+++ b/textual.cc
@@ -229,16 +229,19 @@ transaction_t * parse_transaction(char * line, account_t * account,
else
per_unit_cost /= xact->amount;
- if (! xact->amount.commodity().annotated) {
- xact->amount.annotate_commodity(per_unit_cost,
- xact->entry->actual_date(),
- xact->entry->code);
- } else {
- annotated_commodity_t& ann(static_cast<annotated_commodity_t&>
- (xact->amount.commodity()));
- xact->amount.annotate_commodity(! ann.price ? per_unit_cost : amount_t(),
- ! ann.date ? xact->entry->actual_date() : 0,
- ann.tag.empty() ? xact->entry->code : "");
+ if (xact->amount.commodity()) {
+ if (! xact->amount.commodity().annotated) {
+ xact->amount.annotate_commodity(per_unit_cost,
+ xact->entry->actual_date(),
+ xact->entry->code);
+ } else {
+ annotated_commodity_t& ann(static_cast<annotated_commodity_t&>
+ (xact->amount.commodity()));
+ xact->amount.annotate_commodity
+ (! ann.price ? per_unit_cost : amount_t(),
+ ! ann.date ? xact->entry->actual_date() : 0,
+ ann.tag.empty() ? xact->entry->code : "");
+ }
}
DEBUG_PRINT("ledger.textual.parse", "line " << linenum << ": " <<
diff --git a/valexpr.cc b/valexpr.cc
index b3f7f80f..8de4571a 100644
--- a/valexpr.cc
+++ b/valexpr.cc
@@ -629,7 +629,10 @@ void value_expr_t::compute(value_t& result, const details_t& details,
case O_NOT:
left->compute(result, details, context);
- result.negate();
+ if (result.strip_annotations())
+ result = false;
+ else
+ result = true;
break;
case O_QUES: {
@@ -637,7 +640,7 @@ void value_expr_t::compute(value_t& result, const details_t& details,
assert(right);
assert(right->kind == O_COL);
left->compute(result, details, context);
- if (result)
+ if (result.strip_annotations())
right->left->compute(result, details, context);
else
right->right->compute(result, details, context);
@@ -648,6 +651,7 @@ void value_expr_t::compute(value_t& result, const details_t& details,
assert(left);
assert(right);
left->compute(result, details, context);
+ result = result.strip_annotations();
if (result)
right->compute(result, details, context);
break;
@@ -656,7 +660,7 @@ void value_expr_t::compute(value_t& result, const details_t& details,
assert(left);
assert(right);
left->compute(result, details, context);
- if (! result)
+ if (! result.strip_annotations())
right->compute(result, details, context);
break;
diff --git a/valexpr.h b/valexpr.h
index 87367fb0..429a35cf 100644
--- a/valexpr.h
+++ b/valexpr.h
@@ -491,7 +491,8 @@ class item_predicate
}
bool operator()(const T& item) const {
- return ! predicate || predicate->compute(details_t(item));
+ return (! predicate ||
+ predicate->compute(details_t(item)).strip_annotations());
}
};
diff --git a/value.cc b/value.cc
index 807926bc..9bb92e7d 100644
--- a/value.cc
+++ b/value.cc
@@ -1233,11 +1233,9 @@ value_t value_t::strip_annotations(const bool keep_price,
{
switch (type) {
case BOOLEAN:
- throw new value_error("Cannot strip commodity annotations from a boolean");
case INTEGER:
- return *this;
case DATETIME:
- throw new value_error("Cannot strip commodity annotations from a date/time");
+ return *this;
case AMOUNT:
return ((amount_t *) data)->strip_annotations