diff options
Diffstat (limited to 'src/value.cc')
-rw-r--r-- | src/value.cc | 2065 |
1 files changed, 682 insertions, 1383 deletions
diff --git a/src/value.cc b/src/value.cc index e155d0d7..c4d22f60 100644 --- a/src/value.cc +++ b/src/value.cc @@ -34,115 +34,94 @@ namespace ledger { -bool& value_t::to_boolean() +bool value_t::to_boolean() const { if (type == BOOLEAN) { - return *(bool *) data; + return as_boolean(); } else { - throw_(value_error, "Value is not a boolean"); value_t temp(*this); temp.in_place_cast(BOOLEAN); - return *(bool *) temp.data; + return temp.as_boolean(); } } -long& value_t::to_long() +long value_t::to_long() const { if (type == INTEGER) { - return *(long *) data; + return as_long(); } else { - throw_(value_error, "Value is not an integer"); value_t temp(*this); temp.in_place_cast(INTEGER); - return *(long *) temp.data; + return temp.as_long(); } } -moment_t& value_t::to_datetime() +moment_t value_t::to_datetime() const { if (type == DATETIME) { - return *(moment_t *) data; + return as_datetime(); } else { - throw_(value_error, "Value is not a date/time"); value_t temp(*this); temp.in_place_cast(DATETIME); - return *(moment_t *) temp.data; + return temp.as_datetime(); } } -amount_t& value_t::to_amount() +amount_t value_t::to_amount() const { if (type == AMOUNT) { - return *(amount_t *) data; + return as_amount(); } else { - throw_(value_error, "Value is not an amount"); value_t temp(*this); temp.in_place_cast(AMOUNT); - return *(amount_t *) temp.data; + return temp.as_amount(); } } -balance_t& value_t::to_balance() +balance_t value_t::to_balance() const { if (type == BALANCE) { - return *(balance_t *) data; + return as_balance(); } else { - throw_(value_error, "Value is not a balance"); value_t temp(*this); temp.in_place_cast(BALANCE); - return *(balance_t *) temp.data; + return temp.as_balance(); } } -balance_pair_t& value_t::to_balance_pair() +balance_pair_t value_t::to_balance_pair() const { if (type == BALANCE_PAIR) { - return *(balance_pair_t *) data; + return as_balance_pair(); } else { - throw_(value_error, "Value is not a balance pair"); value_t temp(*this); temp.in_place_cast(BALANCE_PAIR); - return *(balance_pair_t *) temp.data; + return temp.as_balance_pair(); } } -string& value_t::to_string() +string value_t::to_string() const { if (type == STRING) { - return **(string **) data; + return as_string(); } else { - throw_(value_error, "Value is not a string"); -#if 0 - std::ostringstream out; - out << *this; - return out.str(); -#endif + value_t temp(*this); + temp.in_place_cast(STRING); + return temp.as_string(); } } -xml::node_t *& value_t::to_xml_node() +value_t::sequence_t value_t::to_sequence() const { - if (type == XML_NODE) - return *(xml::node_t **) data; - else - throw_(value_error, "Value is not an XML node"); -} - -void *& value_t::to_pointer() -{ - if (type == POINTER) - return *(void **) data; - else - throw_(value_error, "Value is not a pointer"); + if (type == SEQUENCE) { + return as_sequence(); + } else { + value_t temp(*this); + temp.in_place_cast(SEQUENCE); + return temp.as_sequence(); + } } -value_t::sequence_t *& value_t::to_sequence() -{ - if (type == SEQUENCE) - return *(sequence_t **) data; - else - throw_(value_error, "Value is not a sequence"); -} void value_t::destroy() { @@ -157,40 +136,43 @@ void value_t::destroy() ((balance_pair_t *)data)->~balance_pair_t(); break; case STRING: - checked_delete(*(string **) data); + ((string *)data)->~string(); break; case SEQUENCE: - checked_delete(*(sequence_t **) data); + ((sequence_t *)data)->~sequence_t(); break; + default: break; } } -void value_t::simplify() +void value_t::in_place_simplify() { + LOGGER("amounts.values.simplify"); + if (is_realzero()) { - DEBUG("amounts.values.simplify", "Zeroing type " << type); - *this = 0L; + DEBUG_("Zeroing type " << type); + destroy(); + type = INTEGER; + as_long() = 0L; return; } if (type == BALANCE_PAIR && - (! ((balance_pair_t *) data)->cost || - ((balance_pair_t *) data)->cost->is_realzero())) { - DEBUG("amounts.values.simplify", "Reducing balance pair to balance"); + (! as_balance_pair().cost || as_balance_pair().cost->is_realzero())) { + DEBUG_("Reducing balance pair to balance"); in_place_cast(BALANCE); } - if (type == BALANCE && - ((balance_t *) data)->amounts.size() == 1) { - DEBUG("amounts.values.simplify", "Reducing balance to amount"); + if (type == BALANCE && as_balance().amounts.size() == 1) { + DEBUG_("Reducing balance to amount"); in_place_cast(AMOUNT); } - if (type == AMOUNT && - ! ((amount_t *) data)->commodity()) { - DEBUG("amounts.values.simplify", "Reducing amount to integer"); + if (type == AMOUNT && ! as_amount().has_commodity() && + as_amount().fits_in_long()) { + DEBUG_("Reducing amount to integer"); in_place_cast(INTEGER); } } @@ -200,504 +182,415 @@ value_t& value_t::operator=(const value_t& val) if (this == &val) return *this; - if (type == BOOLEAN && val.type == BOOLEAN) { - *((bool *) data) = *((bool *) val.data); - return *this; - } - else if (type == INTEGER && val.type == INTEGER) { - *((long *) data) = *((long *) val.data); - return *this; - } - else if (type == DATETIME && val.type == DATETIME) { - *((moment_t *) data) = *((moment_t *) val.data); - return *this; - } - else if (type == AMOUNT && val.type == AMOUNT) { - *(amount_t *) data = *(amount_t *) val.data; - return *this; - } - else if (type == BALANCE && val.type == BALANCE) { - *(balance_t *) data = *(balance_t *) val.data; - return *this; - } - else if (type == BALANCE_PAIR && val.type == BALANCE_PAIR) { - *(balance_pair_t *) data = *(balance_pair_t *) val.data; - return *this; - } - else if (type == STRING && val.type == STRING) { - **(string **) data = **(string **) val.data; - return *this; - } - else if (type == SEQUENCE && val.type == SEQUENCE) { - **(sequence_t **) data = **(sequence_t **) val.data; - return *this; - } + if (type == val.type) + switch (type) { + case BOOLEAN: + as_boolean() = val.as_boolean(); + return *this; + case INTEGER: + as_long() = val.as_long(); + return *this; + case DATETIME: + as_datetime() = val.as_datetime(); + return *this; + case AMOUNT: + as_amount() = val.as_amount(); + return *this; + case BALANCE: + as_balance() = val.as_balance(); + return *this; + case BALANCE_PAIR: + as_balance_pair() = val.as_balance_pair(); + return *this; + case STRING: + as_string() = val.as_string(); + return *this; + case SEQUENCE: + as_sequence() = val.as_sequence(); + return *this; + } destroy(); + type = val.type; + switch (val.type) { + case VOID: + break; + case BOOLEAN: - *((bool *) data) = *((bool *) val.data); + as_boolean() = val.as_boolean(); break; case INTEGER: - *((long *) data) = *((long *) val.data); + as_long() = val.as_long(); break; case DATETIME: - *((moment_t *) data) = *((moment_t *) val.data); + new((moment_t *) data) moment_t(val.as_datetime()); break; case AMOUNT: - new((amount_t *)data) amount_t(*((amount_t *) val.data)); + new((amount_t *)data) amount_t(val.as_amount()); break; case BALANCE: - new((balance_t *)data) balance_t(*((balance_t *) val.data)); + new((balance_t *)data) balance_t(val.as_balance()); break; case BALANCE_PAIR: - new((balance_pair_t *)data) balance_pair_t(*((balance_pair_t *) val.data)); + new((balance_pair_t *)data) balance_pair_t(val.as_balance_pair()); break; case STRING: - *(string **) data = new string(**(string **) val.data); + new((string *)data) string(val.as_string()); break; - case XML_NODE: - *(xml::node_t **) data = *(xml::node_t **) val.data; + case SEQUENCE: + new((sequence_t *)data) sequence_t(val.as_sequence()); break; - case POINTER: - *(void **) data = *(void **) val.data; + case XML_NODE: + as_xml_node() = val.as_xml_node(); break; - case SEQUENCE: - *(sequence_t **) data = new sequence_t(**(sequence_t **) val.data); + case POINTER: + as_pointer() = val.as_pointer(); break; default: - assert(0); + assert(false); break; } - type = val.type; - return *this; } value_t& value_t::operator+=(const value_t& val) { - if (val.type == BOOLEAN) - throw_(value_error, "Cannot add a boolean to a value"); - else if (val.type == DATETIME) - throw_(value_error, "Cannot add a date/time to a value"); - else if (val.type == POINTER) - throw_(value_error, "Cannot add a pointer to a value"); - else if (val.type == SEQUENCE) - throw_(value_error, "Cannot add a sequence to a value"); - else if (val.type == XML_NODE) // recurse - return *this += (*(xml::node_t **) val.data)->to_value(); + if (type == STRING) { + if (val.type == STRING) + as_string() += val.as_string(); + else + as_string() += val.to_string(); + return *this; + } + else if (type == SEQUENCE) { + if (val.type == SEQUENCE) + as_sequence().insert(as_sequence().end(), + val.as_sequence().begin(), + val.as_sequence().end()); + else + as_sequence().push_back(val); + return *this; + } - switch (type) { - case BOOLEAN: - throw_(value_error, "Cannot add a value to a boolean"); + if (val.type == XML_NODE) // recurse + return *this += val.as_xml_node()->to_value(); - case INTEGER: + switch (type) { + case DATETIME: switch (val.type) { case INTEGER: - *((long *) data) += *((long *) val.data); - break; + as_datetime() += date_duration(val.as_long()); + return *this; case AMOUNT: - in_place_cast(AMOUNT); - *((amount_t *) data) += *((amount_t *) val.data); - break; - case BALANCE: - in_place_cast(BALANCE); - *((balance_t *) data) += *((balance_t *) val.data); - break; - case BALANCE_PAIR: - in_place_cast(BALANCE_PAIR); - *((balance_pair_t *) data) += *((balance_pair_t *) val.data); - break; - case STRING: - throw_(value_error, "Cannot add a string to an integer"); - default: - assert(0); - break; + as_datetime() += date_duration(val.as_amount().to_long()); + return *this; } break; - case DATETIME: + case INTEGER: switch (val.type) { case INTEGER: - *((moment_t *) data) += date_duration(*((long *) val.data)); - break; + as_long() += val.as_long(); + return *this; case AMOUNT: - *((moment_t *) data) += date_duration(long(*((amount_t *) val.data))); - break; + in_place_cast(AMOUNT); + as_amount() += val.as_amount(); + return *this; case BALANCE: - *((moment_t *) data) += date_duration(long(*((balance_t *) val.data))); - break; + in_place_cast(BALANCE); + as_balance() += val.as_balance(); + return *this; case BALANCE_PAIR: - *((moment_t *) data) += date_duration(long(*((balance_pair_t *) val.data))); - break; - case STRING: - throw_(value_error, "Cannot add a string to an date/time"); - default: - assert(0); - break; + in_place_cast(BALANCE_PAIR); + as_balance_pair() += val.as_balance_pair(); + return *this; } break; case AMOUNT: switch (val.type) { case INTEGER: - if (*((long *) val.data) && - ((amount_t *) data)->commodity()) { + if (as_amount().has_commodity()) { in_place_cast(BALANCE); return *this += val; + } else { + as_amount() += val.as_long(); + return *this; } - *((amount_t *) data) += *((long *) val.data); break; case AMOUNT: - if (((amount_t *) data)->commodity() != - ((amount_t *) val.data)->commodity()) { + if (as_amount().commodity() != val.as_amount().commodity()) { in_place_cast(BALANCE); return *this += val; + } else { + as_amount() += val.as_amount(); + return *this; } - *((amount_t *) data) += *((amount_t *) val.data); break; case BALANCE: in_place_cast(BALANCE); - *((balance_t *) data) += *((balance_t *) val.data); - break; + as_balance() += val.as_balance(); + return *this; case BALANCE_PAIR: in_place_cast(BALANCE_PAIR); - *((balance_pair_t *) data) += *((balance_pair_t *) val.data); - break; - - case STRING: - throw_(value_error, "Cannot add a string to an amount"); - - default: - assert(0); - break; + as_balance_pair() += val.as_balance_pair(); + return *this; } break; case BALANCE: switch (val.type) { case INTEGER: - *((balance_t *) data) += amount_t(*((long *) val.data)); - break; + as_balance() += val.to_amount(); + return *this; case AMOUNT: - *((balance_t *) data) += *((amount_t *) val.data); - break; + as_balance() += val.as_amount(); + return *this; case BALANCE: - *((balance_t *) data) += *((balance_t *) val.data); - break; + as_balance() += val.as_balance(); + return *this; case BALANCE_PAIR: in_place_cast(BALANCE_PAIR); - *((balance_pair_t *) data) += *((balance_pair_t *) val.data); - break; - case STRING: - throw_(value_error, "Cannot add a string to an balance"); - default: - assert(0); - break; + as_balance_pair() += val.as_balance_pair(); + return *this; } break; case BALANCE_PAIR: switch (val.type) { case INTEGER: - *((balance_pair_t *) data) += amount_t(*((long *) val.data)); - break; - case AMOUNT: - *((balance_pair_t *) data) += *((amount_t *) val.data); - break; - case BALANCE: - *((balance_pair_t *) data) += *((balance_t *) val.data); - break; - case BALANCE_PAIR: - *((balance_pair_t *) data) += *((balance_pair_t *) val.data); - break; - case STRING: - throw_(value_error, "Cannot add a string to an balance pair"); - default: - assert(0); - break; - } - break; - - case STRING: - switch (val.type) { - case INTEGER: - throw_(value_error, "Cannot add an integer to a string"); + as_balance_pair() += val.to_amount(); + return *this; case AMOUNT: - throw_(value_error, "Cannot add an amount to a string"); + as_balance_pair() += val.as_amount(); + return *this; case BALANCE: - throw_(value_error, "Cannot add a balance to a string"); + as_balance_pair() += val.as_balance(); + return *this; case BALANCE_PAIR: - throw_(value_error, "Cannot add a balance pair to a string"); - case STRING: - **(string **) data += **(string **) val.data; - break; - default: - assert(0); - break; + as_balance_pair() += val.as_balance_pair(); + return *this; } break; - - case XML_NODE: - throw_(value_error, "Cannot add a value to an XML node"); - - case POINTER: - throw_(value_error, "Cannot add a value to a pointer"); - - case SEQUENCE: - throw_(value_error, "Cannot add a value to a sequence"); - - default: - assert(0); - break; } - return *this; + + throw_(value_error, + "Cannot add " << label() << " to " << val.label()); } value_t& value_t::operator-=(const value_t& val) { - if (val.type == BOOLEAN) - throw_(value_error, "Cannot subtract a boolean from a value"); - else if (val.type == DATETIME && type != DATETIME) - throw_(value_error, "Cannot subtract a date/time from a value"); - else if (val.type == STRING) - throw_(value_error, "Cannot subtract a string from a value"); - else if (val.type == POINTER) - throw_(value_error, "Cannot subtract a pointer from a value"); - else if (val.type == SEQUENCE) - throw_(value_error, "Cannot subtract a sequence from a value"); - else if (val.type == XML_NODE) // recurse - return *this -= (*(xml::node_t **) val.data)->to_value(); + if (type == SEQUENCE) { + if (val.type == SEQUENCE) { + for (sequence_t::const_iterator i = val.as_sequence().begin(); + i != val.as_sequence().end(); + i++) { + sequence_t::iterator j = + std::find(as_sequence().begin(), as_sequence().end(), *i); + if (j != as_sequence().end()) + as_sequence().erase(j); + } + } else { + sequence_t::iterator i = + std::find(as_sequence().begin(), as_sequence().end(), val); + if (i != as_sequence().end()) + as_sequence().erase(i); + } + return *this; + } - switch (type) { - case BOOLEAN: - throw_(value_error, "Cannot subtract a value from a boolean"); + if (val.type == XML_NODE) // recurse + return *this -= val.as_xml_node()->to_value(); - case INTEGER: + switch (type) { + case DATETIME: switch (val.type) { case INTEGER: - *((long *) data) -= *((long *) val.data); - break; + as_datetime() -= date_duration(val.as_long()); + return *this; case AMOUNT: - in_place_cast(AMOUNT); - *((amount_t *) data) -= *((amount_t *) val.data); - break; - case BALANCE: - in_place_cast(BALANCE); - *((balance_t *) data) -= *((balance_t *) val.data); - break; - case BALANCE_PAIR: - in_place_cast(BALANCE_PAIR); - *((balance_pair_t *) data) -= *((balance_pair_t *) val.data); - break; - default: - assert(0); - break; + as_datetime() -= date_duration(val.as_amount().to_long()); + return *this; } break; - case DATETIME: + case INTEGER: switch (val.type) { case INTEGER: - *((moment_t *) data) -= date_duration(*((long *) val.data)); - break; - case DATETIME: { - duration_t tval = ((moment_t *) data)->operator-(*((moment_t *) val.data)); - in_place_cast(INTEGER); - *((long *) data) = tval.total_seconds() / 86400L; - break; - } + as_long() -= val.as_long(); + return *this; case AMOUNT: - *((moment_t *) data) -= date_duration(long(*((amount_t *) val.data))); - break; + in_place_cast(AMOUNT); + as_amount() -= val.as_amount(); + in_place_simplify(); + return *this; case BALANCE: - *((moment_t *) data) -= date_duration(long(*((balance_t *) val.data))); - break; + in_place_cast(BALANCE); + as_balance() -= val.as_balance(); + in_place_simplify(); + return *this; case BALANCE_PAIR: - *((moment_t *) data) -= date_duration(long(*((balance_pair_t *) val.data))); - break; - default: - assert(0); - break; + in_place_cast(BALANCE_PAIR); + as_balance_pair() -= val.as_balance_pair(); + in_place_simplify(); + return *this; } break; case AMOUNT: switch (val.type) { case INTEGER: - if (*((long *) val.data) && - ((amount_t *) data)->commodity()) { + if (as_amount().has_commodity()) { in_place_cast(BALANCE); - return *this -= val; + *this -= val; + in_place_simplify(); + return *this; + } else { + as_amount() -= val.as_long(); + in_place_simplify(); + return *this; } - *((amount_t *) data) -= *((long *) val.data); break; case AMOUNT: - if (((amount_t *) data)->commodity() != - ((amount_t *) val.data)->commodity()) { + if (as_amount().commodity() != val.as_amount().commodity()) { in_place_cast(BALANCE); - return *this -= val; + *this -= val; + in_place_simplify(); + return *this; + } else { + as_amount() -= val.as_amount(); + in_place_simplify(); + return *this; } - *((amount_t *) data) -= *((amount_t *) val.data); break; case BALANCE: in_place_cast(BALANCE); - *((balance_t *) data) -= *((balance_t *) val.data); - break; + as_balance() -= val.as_balance(); + in_place_simplify(); + return *this; case BALANCE_PAIR: in_place_cast(BALANCE_PAIR); - *((balance_pair_t *) data) -= *((balance_pair_t *) val.data); - break; - - default: - assert(0); - break; + as_balance_pair() -= val.as_balance_pair(); + in_place_simplify(); + return *this; } break; case BALANCE: switch (val.type) { case INTEGER: - *((balance_t *) data) -= amount_t(*((long *) val.data)); - break; + as_balance() -= val.to_amount(); + in_place_simplify(); + return *this; case AMOUNT: - *((balance_t *) data) -= *((amount_t *) val.data); - break; + as_balance() -= val.as_amount(); + in_place_simplify(); + return *this; case BALANCE: - *((balance_t *) data) -= *((balance_t *) val.data); - break; + as_balance() -= val.as_balance(); + in_place_simplify(); + return *this; case BALANCE_PAIR: in_place_cast(BALANCE_PAIR); - *((balance_pair_t *) data) -= *((balance_pair_t *) val.data); - break; - default: - assert(0); - break; + as_balance_pair() -= val.as_balance_pair(); + in_place_simplify(); + return *this; } break; case BALANCE_PAIR: switch (val.type) { case INTEGER: - *((balance_pair_t *) data) -= amount_t(*((long *) val.data)); - break; + as_balance_pair() -= val.to_amount(); + in_place_simplify(); + return *this; case AMOUNT: - *((balance_pair_t *) data) -= *((amount_t *) val.data); - break; + as_balance_pair() -= val.as_amount(); + in_place_simplify(); + return *this; case BALANCE: - *((balance_pair_t *) data) -= *((balance_t *) val.data); - break; + as_balance_pair() -= val.as_balance(); + in_place_simplify(); + return *this; case BALANCE_PAIR: - *((balance_pair_t *) data) -= *((balance_pair_t *) val.data); - break; - default: - assert(0); - break; + as_balance_pair() -= val.as_balance_pair(); + in_place_simplify(); + return *this; } break; - - case STRING: - throw_(value_error, "Cannot subtract a value from a string"); - case XML_NODE: - throw_(value_error, "Cannot subtract a value from an XML node"); - case POINTER: - throw_(value_error, "Cannot subtract a value from a pointer"); - case SEQUENCE: - throw_(value_error, "Cannot subtract a value from a sequence"); - - default: - assert(0); - break; } - simplify(); - - return *this; + throw_(value_error, + "Cannot subtract " << label() << " from " << val.label()); } value_t& value_t::operator*=(const value_t& val) { - if (val.type == BOOLEAN) - throw_(value_error, "Cannot multiply a value by a boolean"); - else if (val.type == DATETIME) - throw_(value_error, "Cannot multiply a value by a date/time"); - else if (val.type == STRING) - throw_(value_error, "Cannot multiply a value by a string"); - else if (val.type == POINTER) - throw_(value_error, "Cannot multiply a value by a pointer"); - else if (val.type == SEQUENCE) - throw_(value_error, "Cannot multiply a value by a sequence"); - else if (val.type == XML_NODE) // recurse - return *this *= (*(xml::node_t **) val.data)->to_value(); - - if (val.is_realzero() && type != STRING) { - *this = 0L; + if (type == STRING) { + string temp; + long count = val.to_long(); + for (long i = 0; i < count; i++) + temp += as_string(); + as_string() = temp; return *this; } + else if (type == SEQUENCE) { + value_t temp; + long count = val.to_long(); + for (long i = 0; i < count; i++) + temp += as_sequence(); + return *this = temp; + } - switch (type) { - case BOOLEAN: - throw_(value_error, "Cannot multiply a value by a boolean"); + if (val.type == XML_NODE) // recurse + return *this *= val.as_xml_node()->to_value(); + switch (type) { case INTEGER: switch (val.type) { case INTEGER: - *((long *) data) *= *((long *) val.data); - break; - case AMOUNT: + as_long() *= val.as_long(); + return *this; + case AMOUNT: { + long temp = as_long(); in_place_cast(AMOUNT); - *((amount_t *) data) *= *((amount_t *) val.data); - break; - case BALANCE: - in_place_cast(BALANCE); - *((balance_t *) data) *= *((balance_t *) val.data); - break; - case BALANCE_PAIR: - in_place_cast(BALANCE_PAIR); - *((balance_pair_t *) data) *= *((balance_pair_t *) val.data); - break; - default: - assert(0); - break; + as_amount() = val.as_amount() * temp; + return *this; + } } break; case AMOUNT: switch (val.type) { case INTEGER: - *((amount_t *) data) *= *((long *) val.data); - break; + as_amount() *= val.as_long(); + return *this; + case AMOUNT: - *((amount_t *) data) *= *((amount_t *) val.data); - break; - case BALANCE: - in_place_cast(BALANCE); - *((balance_t *) data) *= *((balance_t *) val.data); - break; - case BALANCE_PAIR: - in_place_cast(BALANCE_PAIR); - *((balance_pair_t *) data) *= *((balance_pair_t *) val.data); - break; - default: - assert(0); + if (as_amount().commodity() == val.as_amount().commodity() || + ! val.as_amount().has_commodity()) { + as_amount() *= val.as_amount(); + return *this; + } break; } break; @@ -705,20 +598,13 @@ value_t& value_t::operator*=(const value_t& val) case BALANCE: switch (val.type) { case INTEGER: - *((balance_t *) data) *= *((long *) val.data); - break; + as_balance() *= val.to_amount(); + return *this; case AMOUNT: - *((balance_t *) data) *= *((amount_t *) val.data); - break; - case BALANCE: - *((balance_t *) data) *= *((balance_t *) val.data); - break; - case BALANCE_PAIR: - in_place_cast(BALANCE_PAIR); - *((balance_pair_t *) data) *= *((balance_pair_t *) val.data); - break; - default: - assert(0); + if (! val.as_amount().has_commodity()) { + as_balance() *= val.as_amount(); + return *this; + } break; } break; @@ -726,125 +612,54 @@ value_t& value_t::operator*=(const value_t& val) case BALANCE_PAIR: switch (val.type) { case INTEGER: - *((balance_pair_t *) data) *= amount_t(*((long *) val.data)); - break; + as_balance_pair() *= val.to_amount(); + return *this; case AMOUNT: - *((balance_pair_t *) data) *= *((amount_t *) val.data); - break; - case BALANCE: - *((balance_pair_t *) data) *= *((balance_t *) val.data); - break; - case BALANCE_PAIR: - *((balance_pair_t *) data) *= *((balance_pair_t *) val.data); - break; - default: - assert(0); - break; - } - break; - - case STRING: - switch (val.type) { - case INTEGER: { - string temp; - for (long i = 0; i < *(long *) val.data; i++) - temp += **(string **) data; - **(string **) data = temp; - break; - } - case AMOUNT: { - string temp; - value_t num(val); - num.in_place_cast(INTEGER); - for (long i = 0; i < *(long *) num.data; i++) - temp += **(string **) data; - **(string **) data = temp; - break; - } - case BALANCE: - throw_(value_error, "Cannot multiply a string by a balance"); - case BALANCE_PAIR: - throw_(value_error, "Cannot multiply a string by a balance pair"); - default: - assert(0); + if (! val.as_amount().has_commodity()) { + as_balance_pair() *= val.as_amount(); + return *this; + } break; } break; - - case XML_NODE: - throw_(value_error, "Cannot multiply an XML node by a value"); - case POINTER: - throw_(value_error, "Cannot multiply a pointer by a value"); - case SEQUENCE: - throw_(value_error, "Cannot multiply a sequence by a value"); - - default: - assert(0); - break; } - return *this; + + throw_(value_error, + "Cannot multiply " << label() << " with " << val.label()); } value_t& value_t::operator/=(const value_t& val) { - if (val.type == BOOLEAN) - throw_(value_error, "Cannot divide a boolean by a value"); - else if (val.type == DATETIME) - throw_(value_error, "Cannot divide a date/time by a value"); - else if (val.type == STRING) - throw_(value_error, "Cannot divide a string by a value"); - else if (val.type == POINTER) - throw_(value_error, "Cannot divide a pointer by a value"); - else if (val.type == SEQUENCE) - throw_(value_error, "Cannot divide a value by a sequence"); - else if (val.type == XML_NODE) // recurse - return *this /= (*(xml::node_t **) val.data)->to_value(); + if (val.type == XML_NODE) // recurse + return *this /= val.as_xml_node()->to_value(); switch (type) { - case BOOLEAN: - throw_(value_error, "Cannot divide a value by a boolean"); - case INTEGER: switch (val.type) { case INTEGER: - *((long *) data) /= *((long *) val.data); - break; - case AMOUNT: + as_long() /= val.as_long(); + return *this; + case AMOUNT: { + long temp = as_long(); in_place_cast(AMOUNT); - *((amount_t *) data) /= *((amount_t *) val.data); - break; - case BALANCE: - in_place_cast(BALANCE); - *((balance_t *) data) /= *((balance_t *) val.data); - break; - case BALANCE_PAIR: - in_place_cast(BALANCE_PAIR); - *((balance_pair_t *) data) /= *((balance_pair_t *) val.data); - break; - default: - assert(0); - break; + as_amount() = val.as_amount() / temp; + return *this; + } } break; case AMOUNT: switch (val.type) { case INTEGER: - *((amount_t *) data) /= *((long *) val.data); - break; + as_amount() /= val.as_long(); + return *this; + case AMOUNT: - *((amount_t *) data) /= *((amount_t *) val.data); - break; - case BALANCE: - in_place_cast(BALANCE); - *((balance_t *) data) /= *((balance_t *) val.data); - break; - case BALANCE_PAIR: - in_place_cast(BALANCE_PAIR); - *((balance_pair_t *) data) /= *((balance_pair_t *) val.data); - break; - default: - assert(0); + if (as_amount().commodity() == val.as_amount().commodity() || + ! val.as_amount().has_commodity()) { + as_amount() /= val.as_amount(); + return *this; + } break; } break; @@ -852,20 +667,13 @@ value_t& value_t::operator/=(const value_t& val) case BALANCE: switch (val.type) { case INTEGER: - *((balance_t *) data) /= *((long *) val.data); - break; + as_balance() /= val.to_amount(); + return *this; case AMOUNT: - *((balance_t *) data) /= *((amount_t *) val.data); - break; - case BALANCE: - *((balance_t *) data) /= *((balance_t *) val.data); - break; - case BALANCE_PAIR: - in_place_cast(BALANCE_PAIR); - *((balance_pair_t *) data) /= *((balance_pair_t *) val.data); - break; - default: - assert(0); + if (! val.as_amount().has_commodity()) { + as_balance() /= val.as_amount(); + return *this; + } break; } break; @@ -873,1102 +681,594 @@ value_t& value_t::operator/=(const value_t& val) case BALANCE_PAIR: switch (val.type) { case INTEGER: - *((balance_pair_t *) data) /= amount_t(*((long *) val.data)); - break; + as_balance_pair() /= val.to_amount(); + return *this; case AMOUNT: - *((balance_pair_t *) data) /= *((amount_t *) val.data); - break; - case BALANCE: - *((balance_pair_t *) data) /= *((balance_t *) val.data); - break; - case BALANCE_PAIR: - *((balance_pair_t *) data) /= *((balance_pair_t *) val.data); - break; - default: - assert(0); + if (! val.as_amount().has_commodity()) { + as_balance_pair() /= val.as_amount(); + return *this; + } break; } break; - - case STRING: - throw_(value_error, "Cannot divide a value from a string"); - case XML_NODE: - throw_(value_error, "Cannot divide a value from an XML node"); - case POINTER: - throw_(value_error, "Cannot divide a value from a pointer"); - case SEQUENCE: - throw_(value_error, "Cannot divide a value from a sequence"); - - default: - assert(0); - break; } - return *this; -} - -value_t::operator bool() const -{ - switch (type) { - case BOOLEAN: - return *(bool *) data; - case INTEGER: - return *(long *) data; - case DATETIME: - return is_valid_moment(*((moment_t *) data)); - case AMOUNT: - return *(amount_t *) data; - case BALANCE: - return *(balance_t *) data; - case BALANCE_PAIR: - return *(balance_pair_t *) data; - case STRING: - return ! (**((string **) data)).empty(); - case XML_NODE: - return (*(xml::node_t **) data)->to_value().to_boolean(); - case POINTER: - return *(void **) data != NULL; - case SEQUENCE: - return (*(sequence_t **) data != NULL && - ! (*(sequence_t **) data)->empty()); - default: - assert(0); - break; - } - assert(0); - return 0; + throw_(value_error, + "Cannot divide " << label() << " by " << val.label()); } -#if 0 -template <> -value_t::operator long() const -{ - switch (type) { - case BOOLEAN: - throw_(value_error, "Cannot convert a boolean to an integer"); - case INTEGER: - return *((long *) data); - case DATETIME: - throw_(value_error, "Cannot convert a date/time to an integer"); - case AMOUNT: - return *((amount_t *) data); - case BALANCE: - throw_(value_error, "Cannot convert a balance to an integer"); - case BALANCE_PAIR: - throw_(value_error, "Cannot convert a balance pair to an integer"); - case STRING: - throw_(value_error, "Cannot convert a string to an integer"); - case XML_NODE: - return (*(xml::node_t **) data)->to_value().to_integer(); - case POINTER: - throw_(value_error, "Cannot convert a pointer to an integer"); - case SEQUENCE: - throw_(value_error, "Cannot convert a sequence to an integer"); - - default: - assert(0); - break; - } - assert(0); - return 0; -} -template <> -value_t::operator moment_t() const +bool value_t::operator==(const value_t& val) const { - switch (type) { - case BOOLEAN: - throw_(value_error, "Cannot convert a boolean to a date/time"); - case INTEGER: - throw_(value_error, "Cannot convert an integer to a date/time"); - case DATETIME: - return *((moment_t *) data); - case AMOUNT: - throw_(value_error, "Cannot convert an amount to a date/time"); - case BALANCE: - throw_(value_error, "Cannot convert a balance to a date/time"); - case BALANCE_PAIR: - throw_(value_error, "Cannot convert a balance pair to a date/time"); - case STRING: - throw_(value_error, "Cannot convert a string to a date/time"); - case XML_NODE: - return (*(xml::node_t **) data)->to_value().to_datetime(); - case POINTER: - throw_(value_error, "Cannot convert a pointer to a date/time"); - case SEQUENCE: - throw_(value_error, "Cannot convert a sequence to a date/time"); - - default: - assert(0); - break; - } - assert(0); - return moment_t(); -} + if (type == XML_NODE && val.type == XML_NODE) + return as_xml_node() == val.as_xml_node(); + else if (type == XML_NODE) + return as_xml_node()->to_value() == val; + else if (val.type == XML_NODE) + return *this == val.as_xml_node()->to_value(); -template <> -value_t::operator double() const -{ switch (type) { case BOOLEAN: - throw_(value_error, "Cannot convert a boolean to a double"); - case INTEGER: - return *((long *) data); - case DATETIME: - throw_(value_error, "Cannot convert a date/time to a double"); - case AMOUNT: - return *((amount_t *) data); - case BALANCE: - throw_(value_error, "Cannot convert a balance to a double"); - case BALANCE_PAIR: - throw_(value_error, "Cannot convert a balance pair to a double"); - case STRING: - throw_(value_error, "Cannot convert a string to a double"); - case XML_NODE: - return (*(xml::node_t **) data)->to_value().to_amount().number(); - case POINTER: - throw_(value_error, "Cannot convert a pointer to a double"); - case SEQUENCE: - throw_(value_error, "Cannot convert a sequence to a double"); - - default: - assert(0); + if (val.type == BOOLEAN) + return as_boolean() == val.as_boolean(); break; - } - assert(0); - return 0; -} -template <> -value_t::operator string() const -{ - switch (type) { - case BOOLEAN: - case INTEGER: case DATETIME: - case AMOUNT: - case BALANCE: - case BALANCE_PAIR: { - value_t temp(*this); - temp.in_place_cast(STRING); - return temp; - } - case STRING: - return **(string **) data; - case XML_NODE: - return (*(xml::node_t **) data)->to_value().to_string(); - - case POINTER: - throw_(value_error, "Cannot convert a pointer to a string"); - case SEQUENCE: - throw_(value_error, "Cannot convert a sequence to a string"); - - default: - assert(0); + if (val.type == DATETIME) + return as_datetime() == val.as_datetime(); break; - } - assert(0); - return 0; -} -#endif -template <typename T> -inline int compare_bool(const T& left, const T& right) { - return (! left && right ? -1 : (left && ! right ? 1 : 0)); -} - -// jww (2007-05-01): This is going to be slow as hell for two -// balance_t objects -template <typename T> -inline int compare_equality(const T& left, const T& right) { - return (left < right ? -1 : (left > right ? 1 : 0)); -} - -int value_t::compare(const value_t& val) const -{ - if (val.type == XML_NODE) - return compare((*(xml::node_t **) data)->to_value()); - - switch (type) { - case BOOLEAN: + case INTEGER: switch (val.type) { - case BOOLEAN: - return compare_bool(*((bool *) data), *((bool *) val.data)); - case INTEGER: - return compare_bool(*((bool *) data), bool(*((long *) val.data))); - - case DATETIME: - throw_(value_error, "Cannot compare a boolean to a date/time"); - + return as_long() == val.as_long(); case AMOUNT: - return compare_bool(*((bool *) data), bool(*((amount_t *) val.data))); - + return val.as_amount() == as_amount(); case BALANCE: - return compare_bool(*((bool *) data), bool(*((balance_t *) val.data))); - + return val.as_balance() == to_amount(); case BALANCE_PAIR: - return compare_bool(*((bool *) data), bool(*((balance_pair_t *) val.data))); - - case STRING: - throw_(value_error, "Cannot compare a boolean to a string"); - case POINTER: - throw_(value_error, "Cannot compare a boolean to a pointer"); - case SEQUENCE: - throw_(value_error, "Cannot compare a boolean to a sequence"); - + return val.as_balance_pair() == to_balance(); default: - assert(0); break; } break; - case INTEGER: + case AMOUNT: switch (val.type) { - case BOOLEAN: - return *((long *) data) - ((long) *((bool *) val.data)); - case INTEGER: - return *((long *) data) - *((long *) val.data); - - case DATETIME: - throw_(value_error, "Cannot compare an integer to a date/time"); - + return as_amount() == val.as_long(); case AMOUNT: - return amount_t(*((long *) data)).compare(*((amount_t *) val.data)); - + return as_amount() == val.as_amount(); case BALANCE: - return compare_equality(balance_t(*((long *) data)), - *((balance_t *) val.data)); - + return val.as_balance() == as_amount(); case BALANCE_PAIR: - return compare_equality(balance_pair_t(*((long *) data)), - *((balance_pair_t *) val.data)); - - case STRING: - throw_(value_error, "Cannot compare an integer to a string"); - case POINTER: - throw_(value_error, "Cannot compare an integer to a pointer"); - case SEQUENCE: - throw_(value_error, "Cannot compare an integer to a sequence"); - + return val.as_balance_pair() == to_balance(); default: - assert(0); break; } break; - case DATETIME: + case BALANCE: switch (val.type) { - case BOOLEAN: - throw_(value_error, "Cannot compare a date/time to a boolean"); case INTEGER: - throw_(value_error, "Cannot compare a date/time to an integer"); - - case DATETIME: - return compare_equality(*((moment_t *) data), *((moment_t *) val.data)); - + return as_balance() == val.to_amount(); case AMOUNT: - throw_(value_error, "Cannot compare a date/time to an amount"); + return as_balance() == val.as_amount(); case BALANCE: - throw_(value_error, "Cannot compare a date/time to a balance"); + return as_balance() == val.as_balance(); case BALANCE_PAIR: - throw_(value_error, "Cannot compare a date/time to a balance pair"); - case STRING: - throw_(value_error, "Cannot compare a date/time to a string"); - case POINTER: - throw_(value_error, "Cannot compare a date/time to a pointer"); - case SEQUENCE: - throw_(value_error, "Cannot compare a date/time to a sequence"); - + return val.as_balance_pair() == as_balance(); default: - assert(0); break; } break; - case AMOUNT: + case BALANCE_PAIR: switch (val.type) { - case BOOLEAN: - throw_(value_error, "Cannot compare an amount to a boolean"); - case INTEGER: - return ((amount_t *) data)->compare(*((long *) val.data)); - - case DATETIME: - throw_(value_error, "Cannot compare an amount to a date/time"); - + return as_balance_pair() == val.to_balance(); case AMOUNT: - return ((amount_t *) data)->compare(*((amount_t *) val.data)); - + return as_balance_pair() == val.to_balance(); case BALANCE: - return compare_equality(balance_t(*((amount_t *) data)), - *((balance_t *) val.data)); - + return as_balance_pair() == val.as_balance(); case BALANCE_PAIR: - return compare_equality(balance_pair_t(*((amount_t *) data)), - *((balance_pair_t *) val.data)); - - case STRING: - throw_(value_error, "Cannot compare an amount to a string"); - case POINTER: - throw_(value_error, "Cannot compare an amount to a pointer"); - case SEQUENCE: - throw_(value_error, "Cannot compare an amount to a sequence"); - + return as_balance_pair() == val.as_balance_pair(); default: - assert(0); break; } break; - case BALANCE: - switch (val.type) { - case BOOLEAN: - throw_(value_error, "Cannot compare a balance to a boolean"); + case STRING: + if (val.type == STRING) + return as_string() == val.as_string(); + break; - case INTEGER: - return compare_equality(*(balance_t *) data, - balance_t(*((long *) val.data))); + case SEQUENCE: + if (val.type == SEQUENCE) + return as_sequence() == val.as_sequence(); + break; - case DATETIME: - throw_(value_error, "Cannot compare a balance to a date/time"); + case POINTER: + if (val.type == POINTER) + return as_pointer() == val.as_pointer(); + break; - case AMOUNT: - return compare_equality(*(balance_t *) data, - balance_t(*((amount_t *) val.data))); + default: + break; + } - case BALANCE: - return compare_equality(*(balance_t *) data, *((balance_t *) val.data)); + throw_(value_error, + "Cannot compare " << label() << " to " << val.label()); - case BALANCE_PAIR: - return compare_equality(balance_pair_t(*((balance_t *) data)), - *(balance_pair_t *) val.data); + return *this; +} - case STRING: - throw_(value_error, "Cannot compare a balance to a string"); - case POINTER: - throw_(value_error, "Cannot compare a balance to a pointer"); - case SEQUENCE: - throw_(value_error, "Cannot compare a balance to a sequence"); +bool value_t::operator<(const value_t& val) const +{ + if (type == XML_NODE && val.type == XML_NODE) + return as_xml_node() < val.as_xml_node(); + else if (type == XML_NODE) + return as_xml_node()->to_value() < val; + else if (val.type == XML_NODE) + return *this < val.as_xml_node()->to_value(); + switch (type) { + case DATETIME: + if (val.type == DATETIME) + return as_datetime() < val.as_datetime(); + break; + + case INTEGER: + switch (val.type) { + case INTEGER: + return as_long() < val.as_long(); + case AMOUNT: + return val.as_amount() < as_long(); default: - assert(0); break; } break; - case BALANCE_PAIR: + case AMOUNT: switch (val.type) { - case BOOLEAN: - throw_(value_error, "Cannot compare a balance pair to a boolean"); - case INTEGER: - return compare_equality(*(balance_pair_t *) data, - balance_pair_t(amount_t(*((long *) val.data)))); - - case DATETIME: - throw_(value_error, "Cannot compare a balance pair to a date/time"); - + return as_amount() < val.as_long(); case AMOUNT: - return compare_equality(*(balance_pair_t *) data, - balance_pair_t(*((amount_t *) val.data))); - - case BALANCE: - return compare_equality(*(balance_pair_t *) data, - balance_pair_t(*((balance_t *) val.data))); - - case BALANCE_PAIR: - return compare_equality(*(balance_pair_t *) data, - *((balance_pair_t *) val.data)); - - case STRING: - throw_(value_error, "Cannot compare a balance pair to a string"); - case POINTER: - throw_(value_error, "Cannot compare a balance pair to a pointer"); - case SEQUENCE: - throw_(value_error, "Cannot compare a balance pair to a sequence"); - + return as_amount() < val.as_amount(); default: - assert(0); break; } break; case STRING: - switch (val.type) { - case BOOLEAN: - throw_(value_error, "Cannot compare a string to a boolean"); - case INTEGER: - throw_(value_error, "Cannot compare a string to an integer"); - case DATETIME: - throw_(value_error, "Cannot compare a string to a date/time"); - case AMOUNT: - throw_(value_error, "Cannot compare a string to an amount"); - case BALANCE: - throw_(value_error, "Cannot compare a string to a balance"); - case BALANCE_PAIR: - throw_(value_error, "Cannot compare a string to a balance pair"); + if (val.type == STRING) + return as_string() < val.as_string(); + break; - case STRING: - return (**((string **) data)).compare(**((string **) val.data)); + case POINTER: + if (val.type == POINTER) + return as_pointer() < val.as_pointer(); + break; - case POINTER: - throw_(value_error, "Cannot compare a string to a pointer"); - case SEQUENCE: - throw_(value_error, "Cannot compare a string to a sequence"); + default: + break; + } - default: - assert(0); - break; - } + throw_(value_error, + "Cannot compare " << label() << " to " << val.label()); + + return *this; +} + +#if 0 +bool value_t::operator>(const value_t& val) const +{ + if (type == XML_NODE && val.type == XML_NODE) + return as_xml_node() > val.as_xml_node(); + else if (type == XML_NODE) + return as_xml_node()->to_value() > val; + else if (val.type == XML_NODE) + return *this > val.as_xml_node()->to_value(); + + switch (type) { + case DATETIME: + if (val.type == DATETIME) + return as_datetime() > val.as_datetime(); break; - case XML_NODE: + case INTEGER: switch (val.type) { - case BOOLEAN: - return (*(xml::node_t **) data)->to_value().compare(*this); case INTEGER: - return (*(xml::node_t **) data)->to_value().compare(*this); - case DATETIME: - return (*(xml::node_t **) data)->to_value().compare(*this); + return as_long() > val.as_long(); case AMOUNT: - return (*(xml::node_t **) data)->to_value().compare(*this); - case BALANCE: - return (*(xml::node_t **) data)->to_value().compare(*this); - case BALANCE_PAIR: - return (*(xml::node_t **) data)->to_value().compare(*this); - case STRING: - return (*(xml::node_t **) data)->to_value().compare(*this); - - case POINTER: - throw_(value_error, "Cannot compare an XML node to a pointer"); - case SEQUENCE: - throw_(value_error, "Cannot compare an XML node to a sequence"); - + return val.as_amount() > as_long(); default: - assert(0); break; } break; - case POINTER: + case AMOUNT: switch (val.type) { - case BOOLEAN: - throw_(value_error, "Cannot compare a pointer to a boolean"); case INTEGER: - throw_(value_error, "Cannot compare a pointer to an integer"); - case DATETIME: - throw_(value_error, "Cannot compare a pointer to a date/time"); + return as_amount() > val.as_long(); case AMOUNT: - throw_(value_error, "Cannot compare a pointer to an amount"); - case BALANCE: - throw_(value_error, "Cannot compare a pointer to a balance"); - case BALANCE_PAIR: - throw_(value_error, "Cannot compare a pointer to a balance pair"); - case STRING: - throw_(value_error, "Cannot compare a pointer to a string node"); - case POINTER: - throw_(value_error, "Cannot compare two pointers"); - case SEQUENCE: - throw_(value_error, "Cannot compare a pointer to a sequence"); - + return as_amount() > val.as_amount(); default: - assert(0); break; } break; - case SEQUENCE: - throw_(value_error, "Cannot compare a value to a sequence"); + case STRING: + if (val.type == STRING) + return as_string() > val.as_string(); + break; + + case POINTER: + if (val.type == POINTER) + return as_pointer() > val.as_pointer(); + break; default: - assert(0); break; } + + throw_(value_error, + "Cannot compare " << label() << " to " << val.label()); + return *this; } - -#if 0 -DEF_VALUE_CMP_OP(==) -DEF_VALUE_CMP_OP(<) -DEF_VALUE_CMP_OP(<=) -DEF_VALUE_CMP_OP(>) -DEF_VALUE_CMP_OP(>=) #endif -void value_t::in_place_cast(type_t cast_type) +value_t::operator bool() const { switch (type) { case BOOLEAN: - switch (cast_type) { - case BOOLEAN: - break; - case INTEGER: - throw_(value_error, "Cannot convert a boolean to an integer"); - case DATETIME: - throw_(value_error, "Cannot convert a boolean to a date/time"); - case AMOUNT: - throw_(value_error, "Cannot convert a boolean to an amount"); - case BALANCE: - throw_(value_error, "Cannot convert a boolean to a balance"); - case BALANCE_PAIR: - throw_(value_error, "Cannot convert a boolean to a balance pair"); - case STRING: - *(string **) data = new string(*((bool *) data) ? "true" : "false"); - break; - case XML_NODE: - throw_(value_error, "Cannot convert a boolean to an XML node"); - case POINTER: - throw_(value_error, "Cannot convert a boolean to a pointer"); - case SEQUENCE: - throw_(value_error, "Cannot convert a boolean to a sequence"); - - default: - assert(0); - break; - } + return as_boolean(); + case INTEGER: + return as_long(); + case DATETIME: + return is_valid_moment(as_datetime()); + case AMOUNT: + return as_amount(); + case BALANCE: + return as_balance(); + case BALANCE_PAIR: + return as_balance_pair(); + case STRING: + return ! as_string().empty(); + case SEQUENCE: + return ! as_sequence().empty(); + case XML_NODE: + return as_xml_node()->to_value(); + case POINTER: + return as_pointer() != NULL; + default: + assert(false); break; + } + assert(false); + return 0; +} - case INTEGER: - switch (cast_type) { - case BOOLEAN: - *((bool *) data) = *((long *) data); - break; - case INTEGER: - break; - case DATETIME: - throw_(value_error, "Cannot convert an integer to a date/time"); +void value_t::in_place_cast(type_t cast_type) +{ + if (type == cast_type) + return; - case AMOUNT: - new((amount_t *)data) amount_t(*((long *) data)); - break; - case BALANCE: - new((balance_t *)data) balance_t(*((long *) data)); - break; - case BALANCE_PAIR: - new((balance_pair_t *)data) balance_pair_t(*((long *) data)); - break; - case STRING: { - char buf[32]; - std::sprintf(buf, "%ld", *(long *) data); - *(string **) data = new string(buf); - break; - } - case XML_NODE: - throw_(value_error, "Cannot convert an integer to an XML node"); - case POINTER: - throw_(value_error, "Cannot convert an integer to a pointer"); - case SEQUENCE: - throw_(value_error, "Cannot convert an integer to a sequence"); + if (cast_type == BOOLEAN) { + bool truth(*this); + destroy(); + type = BOOLEAN; + as_boolean() = truth; + return; + } + else if (cast_type == SEQUENCE) { + value_t temp(*this); + destroy(); + type = SEQUENCE; + new((sequence_t *)data) sequence_t; + as_sequence().push_back(temp); + return; + } - default: - assert(0); - break; + // This must came after the if's above, otherwise it would be + // impossible to turn an XML node into a sequence containing that + // same XML node. + if (type == XML_NODE) { + *this = as_xml_node()->to_value().cast(cast_type); + return; + } + + switch (type) { + case BOOLEAN: + switch (cast_type) { + case STRING: + new((string *)data) string(as_boolean() ? "true" : "false"); + type = cast_type; + return; } break; - case DATETIME: + case INTEGER: switch (cast_type) { - case BOOLEAN: - *((bool *) data) = is_valid_moment(*((moment_t *) data)); - break; - case INTEGER: - throw_(value_error, "Cannot convert a date/time to an integer"); - case DATETIME: - break; case AMOUNT: - throw_(value_error, "Cannot convert a date/time to an amount"); + new((amount_t *)data) amount_t(as_long()); + type = cast_type; + return; case BALANCE: - throw_(value_error, "Cannot convert a date/time to a balance"); + new((balance_t *)data) balance_t(as_long()); + type = cast_type; + return; case BALANCE_PAIR: - throw_(value_error, "Cannot convert a date/time to a balance pair"); + new((balance_pair_t *)data) balance_pair_t(as_long()); + type = cast_type; + return; case STRING: - throw_(value_error, "Cannot convert a date/time to a string"); - case XML_NODE: - throw_(value_error, "Cannot convert a date/time to an XML node"); - case POINTER: - throw_(value_error, "Cannot convert a date/time to a pointer"); - case SEQUENCE: - throw_(value_error, "Cannot convert a date/time to a sequence"); - - default: - assert(0); - break; + new((string *)data) string(lexical_cast<string>(as_long())); + type = cast_type; + return; } break; case AMOUNT: switch (cast_type) { - case BOOLEAN: { - bool temp = *((amount_t *) data); - destroy(); - *((bool *)data) = temp; - break; - } case INTEGER: { - long temp = *((amount_t *) data); + long temp = as_amount().to_long(); destroy(); - *((long *)data) = temp; - break; + type = cast_type; + as_long() = temp; + return; } - case DATETIME: - throw_(value_error, "Cannot convert an amount to a date/time"); - case AMOUNT: - break; case BALANCE: { - amount_t temp = *((amount_t *) data); + amount_t temp = as_amount(); destroy(); + type = cast_type; new((balance_t *)data) balance_t(temp); - break; + return; } case BALANCE_PAIR: { - amount_t temp = *((amount_t *) data); + amount_t temp = as_amount(); destroy(); + type = cast_type; new((balance_pair_t *)data) balance_pair_t(temp); - break; + return; } case STRING: { - std::ostringstream out; - out << *(amount_t *) data; + amount_t temp = as_amount(); destroy(); - *(string **) data = new string(out.str()); - break; + type = cast_type; + new((string *)data) string(temp.to_string()); + return; } - case XML_NODE: - throw_(value_error, "Cannot convert an amount to an XML node"); - case POINTER: - throw_(value_error, "Cannot convert an amount to a pointer"); - case SEQUENCE: - throw_(value_error, "Cannot convert an amount to a sequence"); - - default: - assert(0); - break; } break; case BALANCE: switch (cast_type) { - case BOOLEAN: { - bool temp = *((balance_t *) data); - destroy(); - *((bool *)data) = temp; - break; - } - case INTEGER: - throw_(value_error, "Cannot convert a balance to an integer"); - case DATETIME: - throw_(value_error, "Cannot convert a balance to a date/time"); - case AMOUNT: { - balance_t * temp = (balance_t *) data; - if (temp->amounts.size() == 1) { - amount_t amt = (*temp->amounts.begin()).second; + balance_t& temp(as_balance()); + if (temp.amounts.size() == 1) { + amount_t amt = (*temp.amounts.begin()).second; destroy(); + type = cast_type; new((amount_t *)data) amount_t(amt); + return; } - else if (temp->amounts.size() == 0) { - new((amount_t *)data) amount_t(); + else if (temp.amounts.size() == 0) { + destroy(); + type = cast_type; + new((amount_t *)data) amount_t(0L); + return; } else { - throw_(value_error, "Cannot convert a balance with " - "multiple commodities to an amount"); + throw_(value_error, + "Cannot convert " << label() << + " with multiple commodities to " << label(cast_type)); } break; } - case BALANCE: - break; case BALANCE_PAIR: { - balance_t temp = *((balance_t *) data); + balance_t temp = as_balance(); destroy(); + type = cast_type; new((balance_pair_t *)data) balance_pair_t(temp); - break; + return; } - case STRING: - throw_(value_error, "Cannot convert a balance to a string"); - case XML_NODE: - throw_(value_error, "Cannot convert a balance to an XML node"); - case POINTER: - throw_(value_error, "Cannot convert a balance to a pointer"); - case SEQUENCE: - throw_(value_error, "Cannot convert a balance to a sequence"); - - default: - assert(0); - break; } break; case BALANCE_PAIR: switch (cast_type) { - case BOOLEAN: { - bool temp = *((balance_pair_t *) data); - destroy(); - *((bool *)data) = temp; - break; - } - case INTEGER: - throw_(value_error, "Cannot convert a balance pair to an integer"); - case DATETIME: - throw_(value_error, "Cannot convert a balance pair to a date/time"); - case AMOUNT: { - balance_t * temp = &((balance_pair_t *) data)->quantity; - if (temp->amounts.size() == 1) { - amount_t amt = (*temp->amounts.begin()).second; + balance_t& temp(as_balance_pair().quantity); + if (temp.amounts.size() == 1) { + amount_t amt = (*temp.amounts.begin()).second; destroy(); + type = cast_type; new((amount_t *)data) amount_t(amt); + return; } - else if (temp->amounts.size() == 0) { - new((amount_t *)data) amount_t(); + else if (temp.amounts.size() == 0) { + type = cast_type; + new((amount_t *)data) amount_t(0L); + return; } else { - throw_(value_error, "Cannot convert a balance pair with " - "multiple commodities to an amount"); + throw_(value_error, + "Cannot convert " << label() << + " with multiple commodities to " << label(cast_type)); } break; } case BALANCE: { - balance_t temp = ((balance_pair_t *) data)->quantity; + balance_t temp = as_balance_pair().quantity; destroy(); + type = cast_type; new((balance_t *)data) balance_t(temp); - break; + return; } - case BALANCE_PAIR: - break; - case STRING: - throw_(value_error, "Cannot convert a balance pair to a string"); - case XML_NODE: - throw_(value_error, "Cannot convert a balance pair to an XML node"); - case POINTER: - throw_(value_error, "Cannot convert a balance pair to a pointer"); - case SEQUENCE: - throw_(value_error, "Cannot convert a balance pair to a sequence"); - - default: - assert(0); - break; } break; case STRING: switch (cast_type) { - case BOOLEAN: { - if (**(string **) data == "true") { - destroy(); - *(bool *) data = true; - } - else if (**(string **) data == "false") { - destroy(); - *(bool *) data = false; - } - else { - throw_(value_error, "Cannot convert string to an boolean"); - } - break; - } case INTEGER: { - int l = (*(string **) data)->length(); - const char * p = (*(string **) data)->c_str(); - bool alldigits = true; - for (int i = 0; i < l; i++) - if (! std::isdigit(p[i])) { - alldigits = false; - break; - } - if (alldigits) { - long temp = lexical_cast<long>((*(string **) data)->c_str()); + if (all(as_string(), is_digit())) { + long temp = lexical_cast<long>(as_string()); destroy(); - *(long *) data = temp; + type = cast_type; + as_long() = temp; + return; } else { - throw_(value_error, "Cannot convert string to an integer"); + throw_(value_error, + "Cannot convert string '" << *this << "' to an integer"); } break; } - case DATETIME: - throw_(value_error, "Cannot convert a string to a date/time"); - case AMOUNT: { - amount_t temp = **(string **) data; + amount_t temp(as_string()); destroy(); + type = cast_type; new((amount_t *)data) amount_t(temp); - break; + return; } - case BALANCE: - throw_(value_error, "Cannot convert a string to a balance"); - case BALANCE_PAIR: - throw_(value_error, "Cannot convert a string to a balance pair"); - case STRING: - break; - case XML_NODE: - throw_(value_error, "Cannot convert a string to an XML node"); - case POINTER: - throw_(value_error, "Cannot convert a string to a pointer"); - case SEQUENCE: - throw_(value_error, "Cannot convert a string to a sequence"); - - default: - assert(0); - break; } break; - - case XML_NODE: - switch (cast_type) { - case BOOLEAN: - case INTEGER: - case DATETIME: - case AMOUNT: - case BALANCE: - case BALANCE_PAIR: - case STRING: - *this = (*(xml::node_t **) data)->to_value(); - break; - case XML_NODE: - break; - case POINTER: - throw_(value_error, "Cannot convert an XML node to a pointer"); - case SEQUENCE: - throw_(value_error, "Cannot convert an XML node to a sequence"); - - default: - assert(0); - break; - } - break; - - case POINTER: - switch (cast_type) { - case BOOLEAN: - throw_(value_error, "Cannot convert a pointer to a boolean"); - case INTEGER: - throw_(value_error, "Cannot convert a pointer to an integer"); - case DATETIME: - throw_(value_error, "Cannot convert a pointer to a date/time"); - case AMOUNT: - throw_(value_error, "Cannot convert a pointer to an amount"); - case BALANCE: - throw_(value_error, "Cannot convert a pointer to a balance"); - case BALANCE_PAIR: - throw_(value_error, "Cannot convert a pointer to a balance pair"); - case STRING: - throw_(value_error, "Cannot convert a pointer to a string"); - case XML_NODE: - throw_(value_error, "Cannot convert a pointer to an XML node"); - case POINTER: - break; - case SEQUENCE: - throw_(value_error, "Cannot convert a pointer to a sequence"); - - default: - assert(0); - break; - } - break; - - case SEQUENCE: - switch (cast_type) { - case BOOLEAN: - throw_(value_error, "Cannot convert a sequence to a boolean"); - case INTEGER: - throw_(value_error, "Cannot convert a sequence to an integer"); - case DATETIME: - throw_(value_error, "Cannot convert a sequence to a date/time"); - case AMOUNT: - throw_(value_error, "Cannot convert a sequence to an amount"); - case BALANCE: - throw_(value_error, "Cannot convert a sequence to a balance"); - case BALANCE_PAIR: - throw_(value_error, "Cannot convert a sequence to a balance pair"); - case STRING: - throw_(value_error, "Cannot convert a sequence to a string"); - case XML_NODE: - throw_(value_error, "Cannot compare a sequence to an XML node"); - case POINTER: - throw_(value_error, "Cannot convert a sequence to a pointer"); - case SEQUENCE: - break; - - default: - assert(0); - break; - } - break; - - default: - assert(0); - break; } - type = cast_type; + + throw_(value_error, + "Cannot convert " << label() << " to " << label(cast_type)); } void value_t::in_place_negate() { switch (type) { case BOOLEAN: - *((bool *) data) = ! *((bool *) data); - break; + as_boolean() = ! as_boolean(); + return; case INTEGER: - *((long *) data) = - *((long *) data); - break; - case DATETIME: - throw_(value_error, "Cannot negate a date/time"); + as_long() = - as_long(); + return; case AMOUNT: - ((amount_t *) data)->in_place_negate(); - break; + as_amount().in_place_negate(); + return; case BALANCE: - ((balance_t *) data)->in_place_negate(); - break; + as_balance().in_place_negate(); + return; case BALANCE_PAIR: - ((balance_pair_t *) data)->in_place_negate(); - break; - case STRING: - throw_(value_error, "Cannot negate a string"); + as_balance_pair().in_place_negate(); + return; case XML_NODE: - *this = (*(xml::node_t **) data)->to_value(); + *this = as_xml_node()->to_value(); in_place_negate(); - break; - case POINTER: - throw_(value_error, "Cannot negate a pointer"); - case SEQUENCE: - throw_(value_error, "Cannot negate a sequence"); - - default: - assert(0); - break; + return; } + + throw_(value_error, "Cannot negate " << label()); } bool value_t::is_realzero() const { switch (type) { case BOOLEAN: - return ! *((bool *) data); + return ! as_boolean(); case INTEGER: - return *((long *) data) == 0; + return as_long() == 0; case DATETIME: - return ! is_valid_moment(*((moment_t *) data)); + return ! is_valid_moment(as_datetime()); case AMOUNT: - return ((amount_t *) data)->is_realzero(); + return as_amount().is_realzero(); case BALANCE: - return ((balance_t *) data)->is_realzero(); + return as_balance().is_realzero(); case BALANCE_PAIR: - return ((balance_pair_t *) data)->is_realzero(); + return as_balance_pair().is_realzero(); case STRING: - return ((string *) data)->empty(); + return as_string().empty(); + case SEQUENCE: + return as_sequence().empty(); + case XML_NODE: + return as_xml_node() == NULL; case POINTER: - case SEQUENCE: - return *(void **) data == NULL; + return as_pointer() == NULL; default: - assert(0); + assert(false); break; } - assert(0); - return 0; + assert(false); + return true; } value_t value_t::value(const optional<moment_t>& moment) const { switch (type) { - case BOOLEAN: - throw_(value_error, "Cannot find the value of a boolean"); - case DATETIME: - throw_(value_error, "Cannot find the value of a date/time"); case INTEGER: return *this; case AMOUNT: { - if (optional<amount_t> val = ((amount_t *) data)->value(moment)) + if (optional<amount_t> val = as_amount().value(moment)) return *val; return false; } case BALANCE: { - if (optional<balance_t> bal = ((balance_t *) data)->value(moment)) + if (optional<balance_t> bal = as_balance().value(moment)) return *bal; return false; } case BALANCE_PAIR: { - if (optional<balance_t> bal = - ((balance_pair_t *) data)->quantity.value(moment)) - return *bal; + if (optional<balance_t> bal_pair = + as_balance_pair().quantity.value(moment)) + return *bal_pair; return false; } - - case STRING: - throw_(value_error, "Cannot find the value of a string"); - case XML_NODE: - return (*(xml::node_t **) data)->to_value().value(moment); - - case POINTER: - throw_(value_error, "Cannot find the value of a pointer"); - case SEQUENCE: - throw_(value_error, "Cannot find the value of a sequence"); - default: - assert(0); - return value_t(); + return as_xml_node()->to_value().value(moment); } + + throw_(value_error, "Cannot find the value of " << label()); } void value_t::in_place_reduce() { switch (type) { - case BOOLEAN: - case DATETIME: case INTEGER: break; case AMOUNT: - ((amount_t *) data)->in_place_reduce(); + as_amount().in_place_reduce(); break; case BALANCE: - ((balance_t *) data)->in_place_reduce(); + as_balance().in_place_reduce(); break; case BALANCE_PAIR: - ((balance_pair_t *) data)->in_place_reduce(); + as_balance_pair().in_place_reduce(); break; - case STRING: - throw_(value_error, "Cannot reduce a string"); case XML_NODE: - *this = (*(xml::node_t **) data)->to_value(); + *this = as_xml_node()->to_value(); in_place_reduce(); // recurse break; - case POINTER: - throw_(value_error, "Cannot reduce a pointer"); - case SEQUENCE: - throw_(value_error, "Cannot reduce a sequence"); } + + throw_(value_error, "Cannot reduce " << label()); } value_t value_t::round() const { switch (type) { - case BOOLEAN: - throw_(value_error, "Cannot round a boolean"); - case DATETIME: - throw_(value_error, "Cannot round a date/time"); case INTEGER: return *this; case AMOUNT: - return ((amount_t *) data)->round(); + return as_amount().round(); case BALANCE: - return ((balance_t *) data)->round(); + return as_balance().round(); case BALANCE_PAIR: - return ((balance_pair_t *) data)->round(); - case STRING: - throw_(value_error, "Cannot round a string"); + return as_balance_pair().round(); case XML_NODE: - return (*(xml::node_t **) data)->to_value().round(); - case POINTER: - throw_(value_error, "Cannot round a pointer"); - case SEQUENCE: - throw_(value_error, "Cannot round a sequence"); + return as_xml_node()->to_value().round(); } - assert(0); - return value_t(); + + throw_(value_error, "Cannot round " << label()); } value_t value_t::unround() const @@ -1981,21 +1281,21 @@ value_t value_t::unround() const case INTEGER: return *this; case AMOUNT: - return ((amount_t *) data)->unround(); + return as_amount().unround(); case BALANCE: - return ((balance_t *) data)->unround(); + return as_balance().unround(); case BALANCE_PAIR: - return ((balance_pair_t *) data)->unround(); + return as_balance_pair().unround(); case STRING: throw_(value_error, "Cannot un-round a string"); case XML_NODE: - return (*(xml::node_t **) data)->to_value().unround(); + return as_xml_node()->to_value().unround(); case POINTER: throw_(value_error, "Cannot un-round a pointer"); case SEQUENCE: throw_(value_error, "Cannot un-round a sequence"); } - assert(0); + assert(false); return value_t(); } @@ -2010,7 +1310,7 @@ value_t value_t::annotated_price() const throw_(value_error, "Cannot find the annotated price of a date/time"); case AMOUNT: { - optional<amount_t> temp = ((amount_t *) data)->annotation_details().price; + optional<amount_t> temp = as_amount().annotation_details().price; if (! temp) return false; return *temp; @@ -2024,7 +1324,7 @@ value_t value_t::annotated_price() const throw_(value_error, "Cannot find the annotated price of a string"); case XML_NODE: - return (*(xml::node_t **) data)->to_value().annotated_price(); + return as_xml_node()->to_value().annotated_price(); case POINTER: throw_(value_error, "Cannot find the annotated price of a pointer"); @@ -2032,10 +1332,10 @@ value_t value_t::annotated_price() const throw_(value_error, "Cannot find the annotated price of a sequence"); default: - assert(0); + assert(false); break; } - assert(0); + assert(false); return value_t(); } @@ -2051,7 +1351,7 @@ value_t value_t::annotated_date() const return *this; case AMOUNT: { - optional<moment_t> temp = ((amount_t *) data)->annotation_details().date; + optional<moment_t> temp = as_amount().annotation_details().date; if (! temp) return false; return *temp; @@ -2065,7 +1365,7 @@ value_t value_t::annotated_date() const throw_(value_error, "Cannot find the annotated date of a string"); case XML_NODE: - return (*(xml::node_t **) data)->to_value().annotated_date(); + return as_xml_node()->to_value().annotated_date(); case POINTER: throw_(value_error, "Cannot find the annotated date of a pointer"); @@ -2073,10 +1373,10 @@ value_t value_t::annotated_date() const throw_(value_error, "Cannot find the annotated date of a sequence"); default: - assert(0); + assert(false); break; } - assert(0); + assert(false); return value_t(); } @@ -2092,7 +1392,7 @@ value_t value_t::annotated_tag() const return *this; case AMOUNT: { - optional<string> temp = ((amount_t *) data)->annotation_details().tag; + optional<string> temp = as_amount().annotation_details().tag; if (! temp) return false; return *temp; @@ -2106,7 +1406,7 @@ value_t value_t::annotated_tag() const throw_(value_error, "Cannot find the annotated tag of a string"); case XML_NODE: - return (*(xml::node_t **) data)->to_value().annotated_tag(); + return as_xml_node()->to_value().annotated_tag(); case POINTER: throw_(value_error, "Cannot find the annotated tag of a pointer"); @@ -2114,10 +1414,10 @@ value_t value_t::annotated_tag() const throw_(value_error, "Cannot find the annotated tag of a sequence"); default: - assert(0); + assert(false); break; } - assert(0); + assert(false); return value_t(); } @@ -2135,24 +1435,24 @@ value_t value_t::strip_annotations(const bool keep_price, return *this; case SEQUENCE: - assert(0); // jww (2006-09-28): strip them all! + assert(false); // jww (2006-09-28): strip them all! break; case AMOUNT: - return ((amount_t *) data)->strip_annotations + return as_amount().strip_annotations (keep_price, keep_date, keep_tag); case BALANCE: - return ((balance_t *) data)->strip_annotations + return as_balance().strip_annotations (keep_price, keep_date, keep_tag); case BALANCE_PAIR: - return ((balance_pair_t *) data)->quantity.strip_annotations + return as_balance_pair().quantity.strip_annotations (keep_price, keep_date, keep_tag); default: - assert(0); + assert(false); break; } - assert(0); + assert(false); return value_t(); } @@ -2169,26 +1469,26 @@ value_t value_t::cost() const throw_(value_error, "Cannot find the cost of a date/time"); case BALANCE_PAIR: - assert(((balance_pair_t *) data)->cost); - if (((balance_pair_t *) data)->cost) - return *(((balance_pair_t *) data)->cost); + assert(as_balance_pair().cost); + if (as_balance_pair().cost) + return *(as_balance_pair().cost); else - return ((balance_pair_t *) data)->quantity; + return as_balance_pair().quantity; case STRING: throw_(value_error, "Cannot find the cost of a string"); case XML_NODE: - return (*(xml::node_t **) data)->to_value().cost(); + return as_xml_node()->to_value().cost(); case POINTER: throw_(value_error, "Cannot find the cost of a pointer"); case SEQUENCE: throw_(value_error, "Cannot find the cost of a sequence"); default: - assert(0); + assert(false); break; } - assert(0); + assert(false); return value_t(); } @@ -2206,7 +1506,7 @@ value_t& value_t::add(const amount_t& amount, const optional<amount_t>& tcost) return add(amount, tcost); } else if ((type == AMOUNT && - ((amount_t *) data)->commodity() != amount.commodity()) || + as_amount().commodity() != amount.commodity()) || (type != AMOUNT && amount.commodity())) { in_place_cast(BALANCE); return add(amount, tcost); @@ -2214,7 +1514,7 @@ value_t& value_t::add(const amount_t& amount, const optional<amount_t>& tcost) else if (type != AMOUNT) { in_place_cast(AMOUNT); } - *((amount_t *) data) += amount; + as_amount() += amount; break; case BALANCE: @@ -2222,11 +1522,11 @@ value_t& value_t::add(const amount_t& amount, const optional<amount_t>& tcost) in_place_cast(BALANCE_PAIR); return add(amount, tcost); } - *((balance_t *) data) += amount; + as_balance() += amount; break; case BALANCE_PAIR: - ((balance_pair_t *) data)->add(amount, tcost); + as_balance_pair().add(amount, tcost); break; case STRING: @@ -2239,7 +1539,7 @@ value_t& value_t::add(const amount_t& amount, const optional<amount_t>& tcost) throw_(value_error, "Cannot add an amount to a sequence"); default: - assert(0); + assert(false); break; } @@ -2260,18 +1560,18 @@ void value_t::print(std::ostream& out, const int first_width, break; case XML_NODE: - (*(xml::node_t **) data)->print(out); + as_xml_node()->print(out); break; case SEQUENCE: - assert(0); // jww (2006-09-28): write them all out! + assert(false); // jww (2006-09-28): write them all out! throw_(value_error, "Cannot write out a sequence"); case BALANCE: - ((balance_t *) data)->print(out, first_width, latter_width); + as_balance().print(out, first_width, latter_width); break; case BALANCE_PAIR: - ((balance_pair_t *) data)->print(out, first_width, latter_width); + as_balance_pair().print(out, first_width, latter_width); break; } } @@ -2280,31 +1580,31 @@ std::ostream& operator<<(std::ostream& out, const value_t& val) { switch (val.type) { case value_t::BOOLEAN: - out << (*((bool *) val.data) ? "true" : "false"); + out << (val.as_boolean() ? "true" : "false"); break; case value_t::INTEGER: - out << *(long *) val.data; + out << val.as_long(); break; case value_t::DATETIME: - out << *(moment_t *) val.data; + out << val.as_datetime(); break; case value_t::AMOUNT: - out << *(amount_t *) val.data; + out << val.as_amount(); break; case value_t::BALANCE: - out << *(balance_t *) val.data; + out << val.as_balance(); break; case value_t::BALANCE_PAIR: - out << *(balance_pair_t *) val.data; + out << val.as_balance_pair(); break; case value_t::STRING: - out << **(string **) val.data; + out << val.as_string(); break; case value_t::XML_NODE: - if ((*(xml::node_t **) val.data)->flags & XML_NODE_IS_PARENT) - out << '<' << (*(xml::node_t **) val.data)->name() << '>'; + if (val.as_xml_node()->has_flags(XML_NODE_IS_PARENT)) + out << '<' << val.as_xml_node()->name() << '>'; else - out << (*(xml::node_t **) val.data)->text(); + out << val.as_xml_node()->text(); break; case value_t::POINTER: @@ -2313,9 +1613,8 @@ std::ostream& operator<<(std::ostream& out, const value_t& val) case value_t::SEQUENCE: { out << '('; bool first = true; - for (value_t::sequence_t::iterator - i = (*(value_t::sequence_t **) val.data)->begin(); - i != (*(value_t::sequence_t **) val.data)->end(); + for (value_t::sequence_t::const_iterator i = val.as_sequence().begin(); + i != val.as_sequence().end(); i++) { if (first) first = false; @@ -2328,7 +1627,7 @@ std::ostream& operator<<(std::ostream& out, const value_t& val) } default: - assert(0); + assert(false); break; } return out; @@ -2378,7 +1677,7 @@ void value_context::describe(std::ostream& out) const throw() ptr->print(out, 20); break; default: - assert(0); + assert(false); break; } out << std::endl; |