summaryrefslogtreecommitdiff
path: root/value.cc
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2006-03-04 17:13:45 +0000
committerJohn Wiegley <johnw@newartisans.com>2008-04-13 02:41:29 -0400
commit7acc1306d985fb532ee429121fac0e1692285503 (patch)
tree6ff877c57daf4fdeb048147dad6f17811cdeca41 /value.cc
parent11498f48070a9e96826afb316c684fed8c59397b (diff)
downloadfork-ledger-7acc1306d985fb532ee429121fac0e1692285503.tar.gz
fork-ledger-7acc1306d985fb532ee429121fac0e1692285503.tar.bz2
fork-ledger-7acc1306d985fb532ee429121fac0e1692285503.zip
*** empty log message ***
Diffstat (limited to 'value.cc')
-rw-r--r--value.cc777
1 files changed, 535 insertions, 242 deletions
diff --git a/value.cc b/value.cc
index 377a9631..6bd66b6d 100644
--- a/value.cc
+++ b/value.cc
@@ -1,4 +1,5 @@
#include "value.h"
+#include "debug.h"
namespace ledger {
@@ -19,6 +20,34 @@ void value_t::destroy()
}
}
+void value_t::simplify()
+{
+ if (realzero()) {
+ DEBUG_PRINT("amounts.values.simplify", "Zeroing type " << type);
+ *this = 0L;
+ return;
+ }
+
+ if (type == BALANCE_PAIR &&
+ (! ((balance_pair_t *) data)->cost ||
+ ((balance_pair_t *) data)->cost->realzero())) {
+ DEBUG_PRINT("amounts.values.simplify", "Reducing balance pair to balance");
+ cast(BALANCE);
+ }
+
+ if (type == BALANCE &&
+ ((balance_t *) data)->amounts.size() == 1) {
+ DEBUG_PRINT("amounts.values.simplify", "Reducing balance to amount");
+ cast(AMOUNT);
+ }
+
+ if (type == AMOUNT &&
+ ! ((amount_t *) data)->commodity()) {
+ DEBUG_PRINT("amounts.values.simplify", "Reducing amount to integer");
+ cast(INTEGER);
+ }
+}
+
value_t& value_t::operator=(const value_t& value)
{
if (this == &value)
@@ -57,253 +86,493 @@ value_t& value_t::operator=(const value_t& value)
return *this;
}
-#define DEF_VALUE_ADDSUB_OP(OP) \
-value_t& value_t::operator OP(const value_t& value) \
-{ \
- switch (type) { \
- case BOOLEAN: \
- case INTEGER: \
- cast(INTEGER); \
- switch (value.type) { \
- case BOOLEAN: \
- *((long *) data) OP (*((bool *) value.data) ? 1L : 0L); \
- break; \
- case INTEGER: \
- *((long *) data) OP *((long *) value.data); \
- break; \
- case AMOUNT: \
- cast(AMOUNT); \
- *((amount_t *) data) OP *((amount_t *) value.data); \
- break; \
- case BALANCE: \
- cast(BALANCE); \
- *((balance_t *) data) OP *((balance_t *) value.data); \
- break; \
- case BALANCE_PAIR: \
- cast(BALANCE_PAIR); \
- *((balance_pair_t *) data) OP *((balance_pair_t *) value.data); \
- break; \
- default: \
- assert(0); \
- break; \
- } \
- break; \
- \
- case AMOUNT: \
- switch (value.type) { \
- case BOOLEAN: \
- if (*((bool *) value.data) && \
- ((amount_t *) data)->commodity()) { \
- cast(BALANCE); \
- return *this OP value; \
- } \
- *((amount_t *) data) OP (*((bool *) value.data) ? 1L : 0L); \
- break; \
- \
- case INTEGER: \
- if (*((long *) value.data) && \
- ((amount_t *) data)->commodity()) { \
- cast(BALANCE); \
- return *this OP value; \
- } \
- *((amount_t *) data) OP *((long *) value.data); \
- break; \
- \
- case AMOUNT: \
- if (((amount_t *) data)->commodity() != \
- ((amount_t *) value.data)->commodity()) { \
- cast(BALANCE); \
- return *this OP value; \
- } \
- *((amount_t *) data) OP *((amount_t *) value.data); \
- break; \
- \
- case BALANCE: \
- cast(BALANCE); \
- *((balance_t *) data) OP *((balance_t *) value.data); \
- break; \
- \
- case BALANCE_PAIR: \
- cast(BALANCE_PAIR); \
- *((balance_pair_t *) data) OP *((balance_pair_t *) value.data); \
- break; \
- \
- default: \
- assert(0); \
- break; \
- } \
- break; \
- \
- case BALANCE: \
- switch (value.type) { \
- case BOOLEAN: \
- *((balance_t *) data) OP (*((bool *) value.data) ? 1L : 0L); \
- break; \
- case INTEGER: \
- *((balance_t *) data) OP *((long *) value.data); \
- break; \
- case AMOUNT: \
- *((balance_t *) data) OP *((amount_t *) value.data); \
- break; \
- case BALANCE: \
- *((balance_t *) data) OP *((balance_t *) value.data); \
- break; \
- case BALANCE_PAIR: \
- cast(BALANCE_PAIR); \
- *((balance_pair_t *) data) OP *((balance_pair_t *) value.data); \
- break; \
- default: \
- assert(0); \
- break; \
- } \
- break; \
- \
- case BALANCE_PAIR: \
- switch (value.type) { \
- case BOOLEAN: \
- *((balance_pair_t *) data) OP (*((bool *) value.data) ? 1L : 0L); \
- break; \
- case INTEGER: \
- *((balance_pair_t *) data) OP *((long *) value.data); \
- break; \
- case AMOUNT: \
- *((balance_pair_t *) data) OP *((amount_t *) value.data); \
- break; \
- case BALANCE: \
- *((balance_pair_t *) data) OP *((balance_t *) value.data); \
- break; \
- case BALANCE_PAIR: \
- *((balance_pair_t *) data) OP *((balance_pair_t *) value.data); \
- break; \
- default: \
- assert(0); \
- break; \
- } \
- break; \
- \
- default: \
- assert(0); \
- break; \
- } \
- return *this; \
+value_t& value_t::operator+=(const value_t& value)
+{
+ switch (type) {
+ case BOOLEAN:
+ case INTEGER:
+ cast(INTEGER);
+ switch (value.type) {
+ case BOOLEAN:
+ *((long *) data) += (*((bool *) value.data) ? 1L : 0L);
+ break;
+ case INTEGER:
+ *((long *) data) += *((long *) value.data);
+ break;
+ case AMOUNT:
+ cast(AMOUNT);
+ *((amount_t *) data) += *((amount_t *) value.data);
+ break;
+ case BALANCE:
+ cast(BALANCE);
+ *((balance_t *) data) += *((balance_t *) value.data);
+ break;
+ case BALANCE_PAIR:
+ cast(BALANCE_PAIR);
+ *((balance_pair_t *) data) += *((balance_pair_t *) value.data);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ break;
+
+ case AMOUNT:
+ switch (value.type) {
+ case BOOLEAN:
+ if (*((bool *) value.data) &&
+ ((amount_t *) data)->commodity()) {
+ cast(BALANCE);
+ return *this += value;
+ }
+ *((amount_t *) data) += (*((bool *) value.data) ? 1L : 0L);
+ break;
+
+ case INTEGER:
+ if (*((long *) value.data) &&
+ ((amount_t *) data)->commodity()) {
+ cast(BALANCE);
+ return *this += value;
+ }
+ *((amount_t *) data) += *((long *) value.data);
+ break;
+
+ case AMOUNT:
+ if (((amount_t *) data)->commodity() !=
+ ((amount_t *) value.data)->commodity()) {
+ cast(BALANCE);
+ return *this += value;
+ }
+ *((amount_t *) data) += *((amount_t *) value.data);
+ break;
+
+ case BALANCE:
+ cast(BALANCE);
+ *((balance_t *) data) += *((balance_t *) value.data);
+ break;
+
+ case BALANCE_PAIR:
+ cast(BALANCE_PAIR);
+ *((balance_pair_t *) data) += *((balance_pair_t *) value.data);
+ break;
+
+ default:
+ assert(0);
+ break;
+ }
+ break;
+
+ case BALANCE:
+ switch (value.type) {
+ case BOOLEAN:
+ *((balance_t *) data) += (*((bool *) value.data) ? 1L : 0L);
+ break;
+ case INTEGER:
+ *((balance_t *) data) += *((long *) value.data);
+ break;
+ case AMOUNT:
+ *((balance_t *) data) += *((amount_t *) value.data);
+ break;
+ case BALANCE:
+ *((balance_t *) data) += *((balance_t *) value.data);
+ break;
+ case BALANCE_PAIR:
+ cast(BALANCE_PAIR);
+ *((balance_pair_t *) data) += *((balance_pair_t *) value.data);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ break;
+
+ case BALANCE_PAIR:
+ switch (value.type) {
+ case BOOLEAN:
+ *((balance_pair_t *) data) += (*((bool *) value.data) ? 1L : 0L);
+ break;
+ case INTEGER:
+ *((balance_pair_t *) data) += *((long *) value.data);
+ break;
+ case AMOUNT:
+ *((balance_pair_t *) data) += *((amount_t *) value.data);
+ break;
+ case BALANCE:
+ *((balance_pair_t *) data) += *((balance_t *) value.data);
+ break;
+ case BALANCE_PAIR:
+ *((balance_pair_t *) data) += *((balance_pair_t *) value.data);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ break;
+
+ default:
+ assert(0);
+ break;
+ }
+ return *this;
}
-DEF_VALUE_ADDSUB_OP(+=)
-DEF_VALUE_ADDSUB_OP(-=)
+value_t& value_t::operator-=(const value_t& value)
+{
+ switch (type) {
+ case BOOLEAN:
+ case INTEGER:
+ cast(INTEGER);
+ switch (value.type) {
+ case BOOLEAN:
+ *((long *) data) -= (*((bool *) value.data) ? 1L : 0L);
+ break;
+ case INTEGER:
+ *((long *) data) -= *((long *) value.data);
+ break;
+ case AMOUNT:
+ cast(AMOUNT);
+ *((amount_t *) data) -= *((amount_t *) value.data);
+ break;
+ case BALANCE:
+ cast(BALANCE);
+ *((balance_t *) data) -= *((balance_t *) value.data);
+ break;
+ case BALANCE_PAIR:
+ cast(BALANCE_PAIR);
+ *((balance_pair_t *) data) -= *((balance_pair_t *) value.data);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ break;
-#define DEF_VALUE_MULDIV_OP(OP) \
-value_t& value_t::operator OP(const value_t& value) \
-{ \
- switch (type) { \
- case BOOLEAN: \
- case INTEGER: \
- cast(INTEGER); \
- switch (value.type) { \
- case BOOLEAN: \
- *((long *) data) OP (*((bool *) value.data) ? 1L : 0L); \
- break; \
- case INTEGER: \
- *((long *) data) OP *((long *) value.data); \
- break; \
- case AMOUNT: \
- cast(AMOUNT); \
- *((amount_t *) data) OP *((amount_t *) value.data); \
- break; \
- case BALANCE: \
- cast(BALANCE); \
- *((balance_t *) data) OP *((balance_t *) value.data); \
- break; \
- case BALANCE_PAIR: \
- cast(BALANCE_PAIR); \
- *((balance_pair_t *) data) OP *((balance_pair_t *) value.data); \
- break; \
- default: \
- assert(0); \
- break; \
- } \
- break; \
- \
- case AMOUNT: \
- switch (value.type) { \
- case BOOLEAN: \
- *((amount_t *) data) OP (*((bool *) value.data) ? 1L : 0L); \
- break; \
- case INTEGER: \
- *((amount_t *) data) OP *((long *) value.data); \
- break; \
- case AMOUNT: \
- *((amount_t *) data) OP *((amount_t *) value.data); \
- break; \
- case BALANCE: \
- cast(BALANCE); \
- *((balance_t *) data) OP *((balance_t *) value.data); \
- break; \
- case BALANCE_PAIR: \
- cast(BALANCE_PAIR); \
- *((balance_pair_t *) data) OP *((balance_pair_t *) value.data); \
- break; \
- default: \
- assert(0); \
- break; \
- } \
- break; \
- \
- case BALANCE: \
- switch (value.type) { \
- case BOOLEAN: \
- *((balance_t *) data) OP (*((bool *) value.data) ? 1L : 0L); \
- break; \
- case INTEGER: \
- *((balance_t *) data) OP *((long *) value.data); \
- break; \
- case AMOUNT: \
- *((balance_t *) data) OP *((amount_t *) value.data); \
- break; \
- case BALANCE: \
- *((balance_t *) data) OP *((balance_t *) value.data); \
- break; \
- case BALANCE_PAIR: \
- cast(BALANCE_PAIR); \
- *((balance_pair_t *) data) OP *((balance_pair_t *) value.data); \
- break; \
- default: \
- assert(0); \
- break; \
- } \
- break; \
- \
- case BALANCE_PAIR: \
- switch (value.type) { \
- case BOOLEAN: \
- *((balance_pair_t *) data) OP (*((bool *) value.data) ? 1L : 0L); \
- break; \
- case INTEGER: \
- *((balance_pair_t *) data) OP *((long *) value.data); \
- break; \
- case AMOUNT: \
- *((balance_pair_t *) data) OP *((amount_t *) value.data); \
- break; \
- case BALANCE: \
- *((balance_pair_t *) data) OP *((balance_t *) value.data); \
- break; \
- case BALANCE_PAIR: \
- *((balance_pair_t *) data) OP *((balance_pair_t *) value.data); \
- break; \
- default: \
- assert(0); \
- break; \
- } \
- break; \
- \
- default: \
- assert(0); \
- break; \
- } \
- return *this; \
+ case AMOUNT:
+ switch (value.type) {
+ case BOOLEAN:
+ if (*((bool *) value.data) &&
+ ((amount_t *) data)->commodity()) {
+ cast(BALANCE);
+ return *this -= value;
+ }
+ *((amount_t *) data) -= (*((bool *) value.data) ? 1L : 0L);
+ break;
+
+ case INTEGER:
+ if (*((long *) value.data) &&
+ ((amount_t *) data)->commodity()) {
+ cast(BALANCE);
+ return *this -= value;
+ }
+ *((amount_t *) data) -= *((long *) value.data);
+ break;
+
+ case AMOUNT:
+ if (((amount_t *) data)->commodity() !=
+ ((amount_t *) value.data)->commodity()) {
+ cast(BALANCE);
+ return *this -= value;
+ }
+ *((amount_t *) data) -= *((amount_t *) value.data);
+ break;
+
+ case BALANCE:
+ cast(BALANCE);
+ *((balance_t *) data) -= *((balance_t *) value.data);
+ break;
+
+ case BALANCE_PAIR:
+ cast(BALANCE_PAIR);
+ *((balance_pair_t *) data) -= *((balance_pair_t *) value.data);
+ break;
+
+ default:
+ assert(0);
+ break;
+ }
+ break;
+
+ case BALANCE:
+ switch (value.type) {
+ case BOOLEAN:
+ *((balance_t *) data) -= (*((bool *) value.data) ? 1L : 0L);
+ break;
+ case INTEGER:
+ *((balance_t *) data) -= *((long *) value.data);
+ break;
+ case AMOUNT:
+ *((balance_t *) data) -= *((amount_t *) value.data);
+ break;
+ case BALANCE:
+ *((balance_t *) data) -= *((balance_t *) value.data);
+ break;
+ case BALANCE_PAIR:
+ cast(BALANCE_PAIR);
+ *((balance_pair_t *) data) -= *((balance_pair_t *) value.data);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ break;
+
+ case BALANCE_PAIR:
+ switch (value.type) {
+ case BOOLEAN:
+ *((balance_pair_t *) data) -= (*((bool *) value.data) ? 1L : 0L);
+ break;
+ case INTEGER:
+ *((balance_pair_t *) data) -= *((long *) value.data);
+ break;
+ case AMOUNT:
+ *((balance_pair_t *) data) -= *((amount_t *) value.data);
+ break;
+ case BALANCE:
+ *((balance_pair_t *) data) -= *((balance_t *) value.data);
+ break;
+ case BALANCE_PAIR:
+ *((balance_pair_t *) data) -= *((balance_pair_t *) value.data);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ break;
+
+ default:
+ assert(0);
+ break;
+ }
+
+ simplify();
+
+ return *this;
}
-DEF_VALUE_MULDIV_OP(*=)
-DEF_VALUE_MULDIV_OP(/=)
+value_t& value_t::operator*=(const value_t& value)
+{
+ if (value.realzero()) {
+ *this = 0L;
+ return *this;
+ }
+
+ switch (type) {
+ case BOOLEAN:
+ case INTEGER:
+ cast(INTEGER);
+ switch (value.type) {
+ case BOOLEAN:
+ *((long *) data) *= (*((bool *) value.data) ? 1L : 0L);
+ break;
+ case INTEGER:
+ *((long *) data) *= *((long *) value.data);
+ break;
+ case AMOUNT:
+ cast(AMOUNT);
+ *((amount_t *) data) *= *((amount_t *) value.data);
+ break;
+ case BALANCE:
+ cast(BALANCE);
+ *((balance_t *) data) *= *((balance_t *) value.data);
+ break;
+ case BALANCE_PAIR:
+ cast(BALANCE_PAIR);
+ *((balance_pair_t *) data) *= *((balance_pair_t *) value.data);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ break;
+
+ case AMOUNT:
+ switch (value.type) {
+ case BOOLEAN:
+ *((amount_t *) data) *= (*((bool *) value.data) ? 1L : 0L);
+ break;
+ case INTEGER:
+ *((amount_t *) data) *= *((long *) value.data);
+ break;
+ case AMOUNT:
+ *((amount_t *) data) *= *((amount_t *) value.data);
+ break;
+ case BALANCE:
+ cast(BALANCE);
+ *((balance_t *) data) *= *((balance_t *) value.data);
+ break;
+ case BALANCE_PAIR:
+ cast(BALANCE_PAIR);
+ *((balance_pair_t *) data) *= *((balance_pair_t *) value.data);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ break;
+
+ case BALANCE:
+ switch (value.type) {
+ case BOOLEAN:
+ *((balance_t *) data) *= (*((bool *) value.data) ? 1L : 0L);
+ break;
+ case INTEGER:
+ *((balance_t *) data) *= *((long *) value.data);
+ break;
+ case AMOUNT:
+ *((balance_t *) data) *= *((amount_t *) value.data);
+ break;
+ case BALANCE:
+ *((balance_t *) data) *= *((balance_t *) value.data);
+ break;
+ case BALANCE_PAIR:
+ cast(BALANCE_PAIR);
+ *((balance_pair_t *) data) *= *((balance_pair_t *) value.data);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ break;
+
+ case BALANCE_PAIR:
+ switch (value.type) {
+ case BOOLEAN:
+ *((balance_pair_t *) data) *= (*((bool *) value.data) ? 1L : 0L);
+ break;
+ case INTEGER:
+ *((balance_pair_t *) data) *= *((long *) value.data);
+ break;
+ case AMOUNT:
+ *((balance_pair_t *) data) *= *((amount_t *) value.data);
+ break;
+ case BALANCE:
+ *((balance_pair_t *) data) *= *((balance_t *) value.data);
+ break;
+ case BALANCE_PAIR:
+ *((balance_pair_t *) data) *= *((balance_pair_t *) value.data);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ break;
+
+ default:
+ assert(0);
+ break;
+ }
+ return *this;
+}
+
+value_t& value_t::operator/=(const value_t& value)
+{
+ switch (type) {
+ case BOOLEAN:
+ case INTEGER:
+ cast(INTEGER);
+ switch (value.type) {
+ case BOOLEAN:
+ *((long *) data) /= (*((bool *) value.data) ? 1L : 0L);
+ break;
+ case INTEGER:
+ *((long *) data) /= *((long *) value.data);
+ break;
+ case AMOUNT:
+ cast(AMOUNT);
+ *((amount_t *) data) /= *((amount_t *) value.data);
+ break;
+ case BALANCE:
+ cast(BALANCE);
+ *((balance_t *) data) /= *((balance_t *) value.data);
+ break;
+ case BALANCE_PAIR:
+ cast(BALANCE_PAIR);
+ *((balance_pair_t *) data) /= *((balance_pair_t *) value.data);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ break;
+
+ case AMOUNT:
+ switch (value.type) {
+ case BOOLEAN:
+ *((amount_t *) data) /= (*((bool *) value.data) ? 1L : 0L);
+ break;
+ case INTEGER:
+ *((amount_t *) data) /= *((long *) value.data);
+ break;
+ case AMOUNT:
+ *((amount_t *) data) /= *((amount_t *) value.data);
+ break;
+ case BALANCE:
+ cast(BALANCE);
+ *((balance_t *) data) /= *((balance_t *) value.data);
+ break;
+ case BALANCE_PAIR:
+ cast(BALANCE_PAIR);
+ *((balance_pair_t *) data) /= *((balance_pair_t *) value.data);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ break;
+
+ case BALANCE:
+ switch (value.type) {
+ case BOOLEAN:
+ *((balance_t *) data) /= (*((bool *) value.data) ? 1L : 0L);
+ break;
+ case INTEGER:
+ *((balance_t *) data) /= *((long *) value.data);
+ break;
+ case AMOUNT:
+ *((balance_t *) data) /= *((amount_t *) value.data);
+ break;
+ case BALANCE:
+ *((balance_t *) data) /= *((balance_t *) value.data);
+ break;
+ case BALANCE_PAIR:
+ cast(BALANCE_PAIR);
+ *((balance_pair_t *) data) /= *((balance_pair_t *) value.data);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ break;
+
+ case BALANCE_PAIR:
+ switch (value.type) {
+ case BOOLEAN:
+ *((balance_pair_t *) data) /= (*((bool *) value.data) ? 1L : 0L);
+ break;
+ case INTEGER:
+ *((balance_pair_t *) data) /= *((long *) value.data);
+ break;
+ case AMOUNT:
+ *((balance_pair_t *) data) /= *((amount_t *) value.data);
+ break;
+ case BALANCE:
+ *((balance_pair_t *) data) /= *((balance_t *) value.data);
+ break;
+ case BALANCE_PAIR:
+ *((balance_pair_t *) data) /= *((balance_pair_t *) value.data);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ break;
+
+ default:
+ assert(0);
+ break;
+ }
+ return *this;
+}
#define DEF_VALUE_CMP_OP(OP) \
bool value_t::operator OP(const value_t& value) \
@@ -747,6 +1016,30 @@ value_t value_t::price() const
return value_t();
}
+value_t value_t::date() const
+{
+ switch (type) {
+ case BOOLEAN:
+ case INTEGER:
+ return *this;
+
+ case AMOUNT:
+ return ((amount_t *) data)->date();
+
+ case BALANCE:
+ return (long)((balance_t *) data)->date();
+
+ case BALANCE_PAIR:
+ return (long)((balance_pair_t *) data)->quantity.date();
+
+ default:
+ assert(0);
+ break;
+ }
+ assert(0);
+ return value_t();
+}
+
value_t value_t::reduce(const bool keep_price, const bool keep_date,
const bool keep_tag) const
{