diff options
Diffstat (limited to 'src/value.h')
-rw-r--r-- | src/value.h | 421 |
1 files changed, 166 insertions, 255 deletions
diff --git a/src/value.h b/src/value.h index b1e0459d..a6bb091f 100644 --- a/src/value.h +++ b/src/value.h @@ -65,92 +65,101 @@ class value_t typedef std::vector<value_t> sequence_t; enum type_t { + VOID, BOOLEAN, - INTEGER, DATETIME, + INTEGER, AMOUNT, BALANCE, BALANCE_PAIR, STRING, + SEQUENCE, XML_NODE, - POINTER, - SEQUENCE + POINTER } type; - value_t() { + value_t() : type(VOID) { TRACE_CTOR(value_t, ""); - *((long *) data) = 0; - type = INTEGER; } - value_t(const value_t& val) : type(INTEGER) { + value_t(const value_t& val) : type(VOID) { TRACE_CTOR(value_t, "copy"); *this = val; } value_t(const bool val) { TRACE_CTOR(value_t, "const bool"); - *((bool *) data) = val; type = BOOLEAN; + as_boolean() = val; } value_t(const long val) { TRACE_CTOR(value_t, "const long"); - *((long *) data) = val; type = INTEGER; + as_long() = val; } value_t(const moment_t val) { TRACE_CTOR(value_t, "const moment_t"); - *((moment_t *) data) = val; type = DATETIME; - } - value_t(const unsigned long val) { - TRACE_CTOR(value_t, "const unsigned long"); - new((amount_t *) data) amount_t(val); - type = AMOUNT; + new((moment_t *) data) moment_t(val); } value_t(const double val) { TRACE_CTOR(value_t, "const double"); + type = AMOUNT; new((amount_t *) data) amount_t(val); + } + value_t(const unsigned long val) { + TRACE_CTOR(value_t, "const unsigned long"); type = AMOUNT; + new((amount_t *) data) amount_t(val); } value_t(const string& val, bool literal = false) { TRACE_CTOR(value_t, "const string&, bool"); if (literal) { - type = INTEGER; - set_string(val); + type = STRING; + new((string *) data) string(val); } else { - new((amount_t *) data) amount_t(val); type = AMOUNT; + new((amount_t *) data) amount_t(val); } } - value_t(const char * val) { + value_t(const char * val, bool literal = false) { TRACE_CTOR(value_t, "const char *"); - new((amount_t *) data) amount_t(val); - type = AMOUNT; + if (literal) { + type = STRING; + new((string *) data) string(val); + } else { + type = AMOUNT; + new((amount_t *) data) amount_t(val); + } } value_t(const amount_t& val) { TRACE_CTOR(value_t, "const amount_t&"); - new((amount_t *)data) amount_t(val); type = AMOUNT; + new((amount_t *)data) amount_t(val); } - value_t(const balance_t& val) : type(INTEGER) { + value_t(const balance_t& val) : type(VOID) { TRACE_CTOR(value_t, "const balance_t&"); - *this = val; + type = BALANCE; + new((balance_t *)data) balance_t(val); } - value_t(const balance_pair_t& val) : type(INTEGER) { + value_t(const balance_pair_t& val) : type(VOID) { TRACE_CTOR(value_t, "const balance_pair_t&"); - *this = val; + type = BALANCE_PAIR; + new((balance_pair_t *)data) balance_pair_t(val); + } + value_t(const sequence_t& val) { + TRACE_CTOR(value_t, "const sequence_t&"); + type = SEQUENCE; + new((sequence_t *)data) sequence_t(val); } - value_t(xml::node_t * xml_node) : type(INTEGER) { // gets set in = + value_t(xml::node_t * xml_node) { TRACE_CTOR(value_t, "xml::node_t *"); - *this = xml_node; + type = XML_NODE; + as_xml_node() = xml_node; } - value_t(void * item) : type(INTEGER) { // gets set in = + value_t(void * item) { TRACE_CTOR(value_t, "void *"); - *this = item; - } - value_t(sequence_t * seq) : type(INTEGER) { // gets set in = - TRACE_CTOR(value_t, "sequence_t *"); - *this = seq; + type = POINTER; + as_pointer() = item; } ~value_t() { @@ -159,184 +168,125 @@ class value_t } void destroy(); - void simplify(); + value_t simplify() const { + value_t temp = *this; + temp.in_place_simplify(); + return temp; + } + void in_place_simplify(); value_t& operator=(const value_t& val); -#if 0 - value_t& operator=(const bool val) { - if ((bool *) data != &val) { + + value_t& set_string(const string& str = "") { + if (type != STRING) { destroy(); - *((bool *) data) = val; - type = BOOLEAN; + type = STRING; } + as_string() = str; return *this; } - value_t& operator=(const long val) { - if ((long *) data != &val) { - destroy(); - *((long *) data) = val; - type = INTEGER; - } - return *this; + + bool& as_boolean() { + assert(type == BOOLEAN); + return *(bool *) data; } - value_t& operator=(const moment_t val) { - if ((moment_t *) data != &val) { - destroy(); - *((moment_t *) data) = val; - type = DATETIME; - } - return *this; + const bool& as_boolean() const { + assert(type == BOOLEAN); + return *(bool *) data; } - value_t& operator=(const unsigned long val) { - return *this = amount_t(val); + long& as_long() { + assert(type == INTEGER); + return *(long *) data; } - value_t& operator=(const double val) { - return *this = amount_t(val); + const long& as_long() const { + assert(type == INTEGER); + return *(long *) data; } - value_t& operator=(const string& val) { - return *this = amount_t(val); + moment_t& as_datetime() { + assert(type == DATETIME); + return *(moment_t *) data; } - value_t& operator=(const char * val) { - return *this = amount_t(val); + const moment_t& as_datetime() const { + assert(type == DATETIME); + return *(moment_t *) data; } - value_t& operator=(const amount_t& val) { - if (type == AMOUNT && - (amount_t *) data == &val) - return *this; - - if (val.realzero()) { - return *this = 0L; - } else { - destroy(); - new((amount_t *)data) amount_t(val); - type = AMOUNT; - } - return *this; + amount_t& as_amount() { + assert(type == AMOUNT); + return *(amount_t *) data; } - value_t& operator=(const balance_t& val) { - if (type == BALANCE && - (balance_t *) data == &val) - return *this; - - if (val.realzero()) { - return *this = 0L; - } - else if (val.amounts.size() == 1) { - return *this = (*val.amounts.begin()).second; - } - else { - destroy(); - new((balance_t *)data) balance_t(val); - type = BALANCE; - return *this; - } + const amount_t& as_amount() const { + assert(type == AMOUNT); + return *(amount_t *) data; } - value_t& operator=(const balance_pair_t& val) { - if (type == BALANCE_PAIR && - (balance_pair_t *) data == &val) - return *this; - - if (val.realzero()) { - return *this = 0L; - } - else if (! val.cost) { - return *this = val.quantity; - } - else { - destroy(); - new((balance_pair_t *)data) balance_pair_t(val); - type = BALANCE_PAIR; - return *this; - } + balance_t& as_balance() { + assert(type == BALANCE); + return *(balance_t *) data; } - value_t& operator=(xml::node_t * xml_node) { - assert(xml_node); - if (type == XML_NODE && *(xml::node_t **) data == xml_node) - return *this; - - if (! xml_node) { - type = XML_NODE; - return *this = 0L; - } - else { - destroy(); - *(xml::node_t **)data = xml_node; - type = XML_NODE; - return *this; - } + const balance_t& as_balance() const { + assert(type == BALANCE); + return *(balance_t *) data; } - value_t& operator=(void * item) { - assert(item); - if (type == POINTER && *(void **) data == item) - return *this; - - if (! item) { - type = POINTER; - return *this = 0L; - } - else { - destroy(); - *(void **)data = item; - type = POINTER; - return *this; - } + balance_pair_t& as_balance_pair() { + assert(type == BALANCE_PAIR); + return *(balance_pair_t *) data; } - value_t& operator=(sequence_t * seq) { - assert(seq); - if (type == SEQUENCE && *(sequence_t **) data == seq) - return *this; - - if (! seq) { - type = SEQUENCE; - return *this = 0L; - } - else { - destroy(); - *(sequence_t **)data = seq; - type = SEQUENCE; - return *this; - } + const balance_pair_t& as_balance_pair() const { + assert(type == BALANCE_PAIR); + return *(balance_pair_t *) data; + } + string& as_string() { + assert(type == STRING); + return *(string *) data; + } + const string& as_string() const { + assert(type == STRING); + return *(string *) data; + } + sequence_t& as_sequence() { + assert(type == SEQUENCE); + return *(sequence_t *) data; + } + const sequence_t& as_sequence() const { + assert(type == SEQUENCE); + return *(sequence_t *) data; } -#endif - value_t& set_string(const string& str = "") { - if (type != STRING) { - destroy(); - *(string **) data = new string(str); - type = STRING; - } else { - **(string **) data = str; - } - return *this; + xml::node_t *& as_xml_node() { + assert(type == XML_NODE); + return *(xml::node_t **) data; + } + xml::node_t * as_xml_node() const { + assert(type == XML_NODE); + return *(xml::node_t **) data; + } + void *& as_pointer() { + assert(type == POINTER); + return *(void **) data; + } + void * as_pointer() const { + assert(type == POINTER); + return *(void **) data; } - bool& to_boolean(); - long& to_long(); - moment_t& to_datetime(); - amount_t& to_amount(); - balance_t& to_balance(); - balance_pair_t& to_balance_pair(); - string& to_string(); - xml::node_t *& to_xml_node(); - void *& to_pointer(); - sequence_t *& to_sequence(); + bool to_boolean() const; + long to_long() const; + moment_t to_datetime() const; + amount_t to_amount() const; + balance_t to_balance() const; + balance_pair_t to_balance_pair() const; + string to_string() const; + sequence_t to_sequence() const; value_t& operator[](const int index) { - sequence_t * seq = to_sequence(); - assert(seq); - return (*seq)[index]; + return as_sequence()[index]; } void push_back(const value_t& val) { - sequence_t * seq = to_sequence(); - assert(seq); - return seq->push_back(val); + return as_sequence().push_back(val); } std::size_t size() const { - sequence_t * seq = const_cast<value_t&>(*this).to_sequence(); - assert(seq); - return seq->size(); + return as_sequence().size(); } value_t& operator+=(const value_t& val); @@ -344,42 +294,42 @@ class value_t value_t& operator*=(const value_t& val); value_t& operator/=(const value_t& val); - int compare(const value_t& val) const; - - bool operator==(const value_t& val) const { - return compare(val) == 0; - } -#if 0 - template <typename T> - bool operator==(const T& val) const { - return *this == value_t(val); - } -#endif - - bool operator<(const value_t& val) const { - return compare(val) < 0; - } -#if 0 - template <typename T> - bool operator<(const T& val) const { - return *this < value_t(val); + bool operator==(const value_t& val) const; + bool operator<(const value_t& val) const; + //bool operator>(const value_t& val) const; + + string label(optional<type_t> the_type = optional<type_t>()) const { + switch (the_type ? *the_type : type) { + case VOID: + return "an uninitialized value"; + case BOOLEAN: + return "a boolean"; + case INTEGER: + return "an integer"; + case DATETIME: + return "a date/time"; + case AMOUNT: + return "an amount"; + case BALANCE: + return "a balance"; + case BALANCE_PAIR: + return "a balance pair"; + case STRING: + return "a string"; + case SEQUENCE: + return "a sequence"; + case XML_NODE: + return "an xml node"; + case POINTER: + return "a pointer"; + default: + assert(false); + break; + } } -#endif - + operator bool() const; -#if 0 - operator long() const; - operator unsigned long() const; - operator double() const; - operator moment_t() const; - operator string() const; - operator char *() const; - operator amount_t() const; - operator balance_t() const; - operator balance_pair_t() const; -#endif - value_t operator-() const { return negate(); } @@ -429,45 +379,6 @@ class value_t friend std::ostream& operator<<(std::ostream& out, const value_t& val); }; -#if 0 -template <typename T> -value_t::operator T() const -{ - switch (type) { - case BOOLEAN: - return *(bool *) data; - case INTEGER: - return *(long *) data; - case DATETIME: - return *(moment_t *) data; - case AMOUNT: - return *(amount_t *) data; - case BALANCE: - return *(balance_t *) data; - case STRING: - return **(string **) data; - case XML_NODE: - return *(xml::node_t **) data; - case POINTER: - return *(void **) data; - case SEQUENCE: - return *(sequence_t **) data; - - default: - assert(0); - break; - } - assert(0); - return 0; -} - -template <> value_t::operator bool() const; -template <> value_t::operator long() const; -template <> value_t::operator moment_t() const; -template <> value_t::operator double() const; -template <> value_t::operator string() const; -#endif - std::ostream& operator<<(std::ostream& out, const value_t& val); #if 0 |