summaryrefslogtreecommitdiff
path: root/value.h
diff options
context:
space:
mode:
Diffstat (limited to 'value.h')
-rw-r--r--value.h444
1 files changed, 0 insertions, 444 deletions
diff --git a/value.h b/value.h
deleted file mode 100644
index fe01786b..00000000
--- a/value.h
+++ /dev/null
@@ -1,444 +0,0 @@
-#ifndef _VALUE_H
-#define _VALUE_H
-
-#include "amount.h"
-#include "balance.h"
-#include "error.h"
-
-#include <exception>
-
-namespace ledger {
-
-// The following type is a polymorphous value type used solely for
-// performance reasons. The alternative is to compute value
-// expressions (valexpr.cc) in terms of the largest data type,
-// balance_t. This was found to be prohibitively expensive, especially
-// when large logic chains were involved, since many temporary
-// allocations would occur for every operator. With value_t, and the
-// fact that logic chains only need boolean values to continue, no
-// memory allocations need to take place at all.
-
-class value_t
-{
- public:
- char data[sizeof(balance_pair_t)];
-
- enum type_t {
- BOOLEAN,
- INTEGER,
- DATETIME,
- AMOUNT,
- BALANCE,
- BALANCE_PAIR
- } type;
-
- value_t() {
- *((long *) data) = 0;
- type = INTEGER;
- }
-
- value_t(const value_t& value) : type(INTEGER) {
- *this = value;
- }
- value_t(const bool value) {
- *((bool *) data) = value;
- type = BOOLEAN;
- }
- value_t(const long value) {
- *((long *) data) = value;
- type = INTEGER;
- }
- value_t(const datetime_t value) {
- *((datetime_t *) data) = value;
- type = DATETIME;
- }
- value_t(const unsigned long value) {
- new((amount_t *) data) amount_t(value);
- type = AMOUNT;
- }
- value_t(const double value) {
- new((amount_t *) data) amount_t(value);
- type = AMOUNT;
- }
- value_t(const std::string& value) {
- new((amount_t *) data) amount_t(value);
- type = AMOUNT;
- }
- value_t(const char * value) {
- new((amount_t *) data) amount_t(value);
- type = AMOUNT;
- }
- value_t(const amount_t& value) {
- new((amount_t *)data) amount_t(value);
- type = AMOUNT;
- }
- value_t(const balance_t& value) : type(INTEGER) {
- *this = value;
- }
- value_t(const balance_pair_t& value) : type(INTEGER) {
- *this = value;
- }
-
- ~value_t() {
- destroy();
- }
-
- void destroy();
- void simplify();
-
- value_t& operator=(const value_t& value);
- value_t& operator=(const bool value) {
- if ((bool *) data != &value) {
- destroy();
- *((bool *) data) = value;
- type = BOOLEAN;
- }
- return *this;
- }
- value_t& operator=(const long value) {
- if ((long *) data != &value) {
- destroy();
- *((long *) data) = value;
- type = INTEGER;
- }
- return *this;
- }
- value_t& operator=(const datetime_t value) {
- if ((datetime_t *) data != &value) {
- destroy();
- *((datetime_t *) data) = value;
- type = DATETIME;
- }
- return *this;
- }
- value_t& operator=(const unsigned long value) {
- return *this = amount_t(value);
- }
- value_t& operator=(const double value) {
- return *this = amount_t(value);
- }
- value_t& operator=(const std::string& value) {
- return *this = amount_t(value);
- }
- value_t& operator=(const char * value) {
- return *this = amount_t(value);
- }
- value_t& operator=(const amount_t& value) {
- if (type == AMOUNT &&
- (amount_t *) data == &value)
- return *this;
-
- if (value.realzero()) {
- return *this = 0L;
- } else {
- destroy();
- new((amount_t *)data) amount_t(value);
- type = AMOUNT;
- }
- return *this;
- }
- value_t& operator=(const balance_t& value) {
- if (type == BALANCE &&
- (balance_t *) data == &value)
- return *this;
-
- if (value.realzero()) {
- return *this = 0L;
- }
- else if (value.amounts.size() == 1) {
- return *this = (*value.amounts.begin()).second;
- }
- else {
- destroy();
- new((balance_t *)data) balance_t(value);
- type = BALANCE;
- return *this;
- }
- }
- value_t& operator=(const balance_pair_t& value) {
- if (type == BALANCE_PAIR &&
- (balance_pair_t *) data == &value)
- return *this;
-
- if (value.realzero()) {
- return *this = 0L;
- }
- else if (! value.cost) {
- return *this = value.quantity;
- }
- else {
- destroy();
- new((balance_pair_t *)data) balance_pair_t(value);
- type = BALANCE_PAIR;
- return *this;
- }
- }
-
- value_t& operator+=(const value_t& value);
- value_t& operator-=(const value_t& value);
- value_t& operator*=(const value_t& value);
- value_t& operator/=(const value_t& value);
-
- template <typename T>
- value_t& operator+=(const T& value) {
- return *this += value_t(value);
- }
- template <typename T>
- value_t& operator-=(const T& value) {
- return *this -= value_t(value);
- }
- template <typename T>
- value_t& operator*=(const T& value) {
- return *this *= value_t(value);
- }
- template <typename T>
- value_t& operator/=(const T& value) {
- return *this /= value_t(value);
- }
-
- value_t operator+(const value_t& value) {
- value_t temp(*this);
- temp += value;
- return temp;
- }
- value_t operator-(const value_t& value) {
- value_t temp(*this);
- temp -= value;
- return temp;
- }
- value_t operator*(const value_t& value) {
- value_t temp(*this);
- temp *= value;
- return temp;
- }
- value_t operator/(const value_t& value) {
- value_t temp(*this);
- temp /= value;
- return temp;
- }
-
- template <typename T>
- value_t operator+(const T& value) {
- return *this + value_t(value);
- }
- template <typename T>
- value_t operator-(const T& value) {
- return *this - value_t(value);
- }
- template <typename T>
- value_t operator*(const T& value) {
- return *this * value_t(value);
- }
- template <typename T>
- value_t operator/(const T& value) {
- return *this / value_t(value);
- }
-
- bool operator<(const value_t& value);
- bool operator<=(const value_t& value);
- bool operator>(const value_t& value);
- bool operator>=(const value_t& value);
- bool operator==(const value_t& value);
- bool operator!=(const value_t& value) {
- return ! (*this == value);
- }
-
- template <typename T>
- bool operator<(const T& value) {
- return *this < value_t(value);
- }
- template <typename T>
- bool operator<=(const T& value) {
- return *this <= value_t(value);
- }
- template <typename T>
- bool operator>(const T& value) {
- return *this > value_t(value);
- }
- template <typename T>
- bool operator>=(const T& value) {
- return *this >= value_t(value);
- }
- template <typename T>
- bool operator==(const T& value) {
- return *this == value_t(value);
- }
- template <typename T>
- bool operator!=(const T& value) {
- return ! (*this == value);
- }
-
- template <typename T>
- operator T() const;
-
- void negate();
- value_t negated() const {
- value_t temp = *this;
- temp.negate();
- return temp;
- }
- value_t operator-() const {
- return negated();
- }
-
- bool realzero() const {
- switch (type) {
- case BOOLEAN:
- return ! *((bool *) data);
- case INTEGER:
- return *((long *) data) == 0;
- case DATETIME:
- return ! *((datetime_t *) data);
- case AMOUNT:
- return ((amount_t *) data)->realzero();
- case BALANCE:
- return ((balance_t *) data)->realzero();
- case BALANCE_PAIR:
- return ((balance_pair_t *) data)->realzero();
-
- default:
- assert(0);
- break;
- }
- assert(0);
- return 0;
- }
-
- void abs();
- void cast(type_t cast_type);
- value_t cost() const;
- value_t price() const;
- value_t date() const;
-
- value_t strip_annotations(const bool keep_price = amount_t::keep_price,
- const bool keep_date = amount_t::keep_date,
- const bool keep_tag = amount_t::keep_tag) const;
-
- value_t& add(const amount_t& amount, const amount_t * cost = NULL);
- value_t value(const datetime_t& moment) const;
- void reduce();
-
- value_t reduced() const {
- value_t temp(*this);
- temp.reduce();
- return temp;
- }
-
- void round();
- value_t unround() const;
-};
-
-#define DEF_VALUE_AUX_OP(OP) \
- inline value_t operator OP(const balance_pair_t& value, \
- const value_t& obj) { \
- return value_t(value) OP obj; \
- } \
- inline value_t operator OP(const balance_t& value, \
- const value_t& obj) { \
- return value_t(value) OP obj; \
- } \
- inline value_t operator OP(const amount_t& value, \
- const value_t& obj) { \
- return value_t(value) OP obj; \
- } \
- template <typename T> \
- inline value_t operator OP(T value, const value_t& obj) { \
- return value_t(value) OP obj; \
- }
-
-DEF_VALUE_AUX_OP(+)
-DEF_VALUE_AUX_OP(-)
-DEF_VALUE_AUX_OP(*)
-DEF_VALUE_AUX_OP(/)
-
-DEF_VALUE_AUX_OP(<)
-DEF_VALUE_AUX_OP(<=)
-DEF_VALUE_AUX_OP(>)
-DEF_VALUE_AUX_OP(>=)
-DEF_VALUE_AUX_OP(==)
-DEF_VALUE_AUX_OP(!=)
-
-template <typename T>
-value_t::operator T() const
-{
- switch (type) {
- case BOOLEAN:
- return *((bool *) data);
- case INTEGER:
- return *((long *) data);
- case DATETIME:
- return *((datetime_t *) data);
- case AMOUNT:
- return *((amount_t *) data);
- case BALANCE:
- return *((balance_t *) data);
- case BALANCE_PAIR:
- return *((balance_pair_t *) data);
-
- default:
- assert(0);
- break;
- }
- assert(0);
- return 0;
-}
-
-template <> value_t::operator long() const;
-template <> value_t::operator datetime_t() const;
-template <> value_t::operator double() const;
-
-inline value_t abs(const value_t& value) {
- value_t temp(value);
- temp.abs();
- return temp;
-}
-
-inline std::ostream& operator<<(std::ostream& out, const value_t& value) {
- switch (value.type) {
- case value_t::BOOLEAN:
- out << (*((bool *) value.data) ? "true" : "false");
- break;
- case value_t::INTEGER:
- out << *((long *) value.data);
- break;
- case value_t::DATETIME:
- out << *((datetime_t *) value.data);
- break;
- case value_t::AMOUNT:
- out << *((amount_t *) value.data);
- break;
- case value_t::BALANCE:
- out << *((balance_t *) value.data);
- break;
- case value_t::BALANCE_PAIR:
- out << *((balance_pair_t *) value.data);
- break;
-
- default:
- assert(0);
- break;
- }
- return out;
-}
-
-class value_context : public error_context
-{
- value_t * bal;
- public:
- value_context(const value_t& _bal,
- const std::string& desc = "") throw();
- virtual ~value_context() throw();
-
- virtual void describe(std::ostream& out) const throw();
-};
-
-class value_error : public error {
- public:
- value_error(const std::string& reason, error_context * ctxt = NULL) throw()
- : error(reason, ctxt) {}
- virtual ~value_error() throw() {}
-};
-
-} // namespace ledger
-
-#endif // _VALUE_H