summaryrefslogtreecommitdiff
path: root/value.h
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2008-04-13 03:35:00 -0400
committerJohn Wiegley <johnw@newartisans.com>2008-04-13 03:35:00 -0400
commit42f43b7686038e4cbca16d8d2118b139544e6de3 (patch)
tree52c5473401c57282242d66b8dd75f4c07bf41d07 /value.h
parentc7b4370ff9c8ab5c96f15b1e712e6db6bdab6324 (diff)
downloadfork-ledger-42f43b7686038e4cbca16d8d2118b139544e6de3.tar.gz
fork-ledger-42f43b7686038e4cbca16d8d2118b139544e6de3.tar.bz2
fork-ledger-42f43b7686038e4cbca16d8d2118b139544e6de3.zip
Check in all changes made so far toward 3.0.
Diffstat (limited to 'value.h')
-rw-r--r--value.h206
1 files changed, 163 insertions, 43 deletions
diff --git a/value.h b/value.h
index fe01786b..10d669be 100644
--- a/value.h
+++ b/value.h
@@ -5,10 +5,15 @@
#include "balance.h"
#include "error.h"
+#include <deque>
#include <exception>
namespace ledger {
+namespace xml {
+ class node_t;
+}
+
// 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,
@@ -21,6 +26,8 @@ namespace ledger {
class value_t
{
public:
+ typedef std::deque<value_t> sequence_t;
+
char data[sizeof(balance_pair_t)];
enum type_t {
@@ -29,57 +36,91 @@ class value_t
DATETIME,
AMOUNT,
BALANCE,
- BALANCE_PAIR
+ BALANCE_PAIR,
+ STRING,
+ XML_NODE,
+ POINTER,
+ SEQUENCE
} type;
value_t() {
+ TRACE_CTOR("value_t()");
*((long *) data) = 0;
type = INTEGER;
}
value_t(const value_t& value) : type(INTEGER) {
+ TRACE_CTOR("value_t(copy)");
*this = value;
}
value_t(const bool value) {
+ TRACE_CTOR("value_t(const bool)");
*((bool *) data) = value;
type = BOOLEAN;
}
value_t(const long value) {
+ TRACE_CTOR("value_t(const long)");
*((long *) data) = value;
type = INTEGER;
}
value_t(const datetime_t value) {
+ TRACE_CTOR("value_t(const datetime_t)");
*((datetime_t *) data) = value;
type = DATETIME;
}
value_t(const unsigned long value) {
+ TRACE_CTOR("value_t(const unsigned long)");
new((amount_t *) data) amount_t(value);
type = AMOUNT;
}
value_t(const double value) {
+ TRACE_CTOR("value_t(const double)");
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 std::string& value, bool literal = false) {
+ TRACE_CTOR("value_t(const std::string&, bool)");
+ if (literal) {
+ type = INTEGER;
+ set_string(value);
+ } else {
+ new((amount_t *) data) amount_t(value);
+ type = AMOUNT;
+ }
}
value_t(const char * value) {
+ TRACE_CTOR("value_t(const char *)");
new((amount_t *) data) amount_t(value);
type = AMOUNT;
}
value_t(const amount_t& value) {
+ TRACE_CTOR("value_t(const amount_t&)");
new((amount_t *)data) amount_t(value);
type = AMOUNT;
}
value_t(const balance_t& value) : type(INTEGER) {
+ TRACE_CTOR("value_t(const balance_t&)");
*this = value;
}
value_t(const balance_pair_t& value) : type(INTEGER) {
+ TRACE_CTOR("value_t(const balance_pair_t&)");
*this = value;
}
+ value_t(xml::node_t * xml_node) : type(INTEGER) { // gets set in =
+ TRACE_CTOR("value_t(xml::node_t *)");
+ *this = xml_node;
+ }
+ value_t(void * item) : type(INTEGER) { // gets set in =
+ 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;
+ }
~value_t() {
+ TRACE_DTOR("value_t");
destroy();
}
@@ -127,7 +168,7 @@ class value_t
if (type == AMOUNT &&
(amount_t *) data == &value)
return *this;
-
+
if (value.realzero()) {
return *this = 0L;
} else {
@@ -141,7 +182,7 @@ class value_t
if (type == BALANCE &&
(balance_t *) data == &value)
return *this;
-
+
if (value.realzero()) {
return *this = 0L;
}
@@ -159,7 +200,7 @@ class value_t
if (type == BALANCE_PAIR &&
(balance_pair_t *) data == &value)
return *this;
-
+
if (value.realzero()) {
return *this = 0L;
}
@@ -173,6 +214,94 @@ class value_t
return *this;
}
}
+ 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;
+ }
+ }
+ 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;
+ }
+ }
+ 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;
+ }
+ }
+
+ value_t& set_string(const std::string& str = "") {
+ if (type != STRING) {
+ destroy();
+ *(std::string **) data = new std::string(str);
+ type = STRING;
+ } else {
+ **(std::string **) data = str;
+ }
+ return *this;
+ }
+
+ bool to_boolean() const;
+ long to_integer() const;
+ datetime_t to_datetime() const;
+ amount_t to_amount() const;
+ balance_t to_balance() const;
+ balance_pair_t to_balance_pair() const;
+ std::string to_string() const;
+ xml::node_t * to_xml_node() const;
+ void * to_pointer() const;
+ sequence_t * to_sequence() const;
+
+ value_t& operator[](const int index) {
+ sequence_t * seq = to_sequence();
+ assert(seq);
+ return (*seq)[index];
+ }
+
+ void push_back(const value_t& value) {
+ sequence_t * seq = to_sequence();
+ assert(seq);
+ return seq->push_back(value);
+ }
+
+ std::size_t size() const {
+ sequence_t * seq = to_sequence();
+ assert(seq);
+ return seq->size();
+ }
value_t& operator+=(const value_t& value);
value_t& operator-=(const value_t& value);
@@ -295,6 +424,12 @@ class value_t
return ((balance_t *) data)->realzero();
case BALANCE_PAIR:
return ((balance_pair_t *) data)->realzero();
+ case STRING:
+ return ((std::string *) data)->empty();
+ case XML_NODE:
+ case POINTER:
+ case SEQUENCE:
+ return *(void **) data == NULL;
default:
assert(0);
@@ -324,8 +459,11 @@ class value_t
return temp;
}
- void round();
- value_t unround() const;
+ void round();
+ value_t unround() const;
+
+ void write(std::ostream& out, const int first_width,
+ const int latter_width = -1) const;
};
#define DEF_VALUE_AUX_OP(OP) \
@@ -363,17 +501,23 @@ value_t::operator T() const
{
switch (type) {
case BOOLEAN:
- return *((bool *) data);
+ return *(bool *) data;
case INTEGER:
- return *((long *) data);
+ return *(long *) data;
case DATETIME:
- return *((datetime_t *) data);
+ return *(datetime_t *) data;
case AMOUNT:
- return *((amount_t *) data);
+ return *(amount_t *) data;
case BALANCE:
- return *((balance_t *) data);
- case BALANCE_PAIR:
- return *((balance_pair_t *) data);
+ return *(balance_t *) data;
+ case STRING:
+ return **(std::string **) data;
+ case XML_NODE:
+ return *(xml::node_t **) data;
+ case POINTER:
+ return *(void **) data;
+ case SEQUENCE:
+ return *(sequence_t **) data;
default:
assert(0);
@@ -383,9 +527,11 @@ value_t::operator T() const
return 0;
}
+template <> value_t::operator bool() const;
template <> value_t::operator long() const;
template <> value_t::operator datetime_t() const;
template <> value_t::operator double() const;
+template <> value_t::operator std::string() const;
inline value_t abs(const value_t& value) {
value_t temp(value);
@@ -393,33 +539,7 @@ inline value_t abs(const value_t& value) {
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;
-}
+std::ostream& operator<<(std::ostream& out, const value_t& value);
class value_context : public error_context
{