summaryrefslogtreecommitdiff
path: root/src/value.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/value.h')
-rw-r--r--src/value.h122
1 files changed, 60 insertions, 62 deletions
diff --git a/src/value.h b/src/value.h
index 4dfd591c..6fe24da6 100644
--- a/src/value.h
+++ b/src/value.h
@@ -57,7 +57,6 @@ namespace ledger {
DECLARE_EXCEPTION(value_error, std::runtime_error);
class scope_t;
-class expr_t;
/**
* @class value_t
@@ -110,7 +109,7 @@ public:
MASK, // a regular expression mask
SEQUENCE, // a vector of value_t objects
SCOPE, // a pointer to a scope
- EXPR // a pointer to a value expression
+ ANY // a pointer to an arbitrary object
};
private:
@@ -128,17 +127,17 @@ private:
* The `type' member holds the value_t::type_t value representing
* the type of the object stored.
*/
- variant<bool, // BOOLEAN
- datetime_t, // DATETIME
- date_t, // DATE
- long, // INTEGER
- amount_t, // AMOUNT
- balance_t *, // BALANCE
- string, // STRING
- mask_t, // MASK
- sequence_t *, // SEQUENCE
- scope_t *, // SCOPE
- expr_t * // EXPR
+ variant<bool, // BOOLEAN
+ datetime_t, // DATETIME
+ date_t, // DATE
+ long, // INTEGER
+ amount_t, // AMOUNT
+ balance_t *, // BALANCE
+ string, // STRING
+ mask_t, // MASK
+ sequence_t *, // SEQUENCE
+ scope_t *, // SCOPE
+ boost::any // ANY
> data;
type_t type;
@@ -256,8 +255,7 @@ private:
* subsequently be modified.
*/
void _dup() {
- VERIFY(storage);
- if (storage->refc > 1)
+ if (storage && storage->refc > 1)
storage = new storage_t(*storage.get());
}
@@ -354,10 +352,13 @@ public:
TRACE_CTOR(value_t, "scope_t *");
set_scope(item);
}
- explicit value_t(const expr_t& item) {
- TRACE_CTOR(value_t, "const expr_t&");
- set_expr(item);
+#if 0
+ template <typename T>
+ explicit value_t(T& item) {
+ TRACE_CTOR(value_t, "T&");
+ set_any(item);
}
+#endif
/**
* Destructor. This does not do anything, because the intrusive_ptr
@@ -530,7 +531,7 @@ public:
* is_string()
* is_mask()
* is_sequence()
- * is_pointer()
+ * is_any()
*
* There are corresponding as_*() methods that represent a value as a
* reference to its underlying type. For example, as_long() returns a
@@ -729,20 +730,45 @@ public:
}
/**
- * Dealing with expr pointers.
+ * Dealing with any type at all is bit involved because we actually
+ * deal with typed object. For example, if you call as_any it returns
+ * a boost::any object, but if you use as_any<type_t>, then it returns
+ * a type_t by value.
*/
- bool is_expr() const {
- return is_type(EXPR);
+ bool is_any() const {
+ return is_type(ANY);
+ }
+ template <typename T>
+ bool is_any() const {
+ return (is_type(ANY) &&
+ boost::get<boost::any>(storage->data).type() == typeid(T));
+ }
+ boost::any& as_any_lval() {
+ VERIFY(is_any());
+ _dup();
+ return boost::get<boost::any>(storage->data);
+ }
+ template <typename T>
+ T& as_any_lval() {
+ return any_cast<T&>(as_any_lval());
+ }
+ const boost::any& as_any() const {
+ VERIFY(is_any());
+ return boost::get<boost::any>(storage->data);
}
- expr_t& as_expr_lval() const {
- VERIFY(is_expr());
- return *boost::get<expr_t *>(storage->data);
+ template <typename T>
+ const T& as_any() const {
+ return any_cast<const T&>(as_any());
}
- const expr_t& as_expr() const {
- VERIFY(is_expr());
- return *boost::get<expr_t *>(storage->data);
+ void set_any(const boost::any& val) {
+ set_type(ANY);
+ storage->data = val;
+ }
+ template <typename T>
+ void set_any(T& val) {
+ set_type(ANY);
+ storage->data = boost::any(val);
}
- void set_expr(const expr_t& val);
/**
* Data conversion methods. These methods convert a value object to
@@ -904,39 +930,7 @@ public:
/**
* Informational methods.
*/
- string label(optional<type_t> the_type = none) const {
- switch (the_type ? *the_type : type()) {
- case VOID:
- return _("an uninitialized value");
- case BOOLEAN:
- return _("a boolean");
- case DATETIME:
- return _("a date/time");
- case DATE:
- return _("a date");
- case INTEGER:
- return _("an integer");
- case AMOUNT:
- return _("an amount");
- case BALANCE:
- return _("a balance");
- case STRING:
- return _("a string");
- case MASK:
- return _("a regexp");
- case SEQUENCE:
- return _("a sequence");
- case SCOPE:
- return _("a scope");
- case EXPR:
- return _("a expr");
- default:
- assert(false);
- break;
- }
- assert(false);
- return _("<invalid>");
- }
+ string label(optional<type_t> the_type = none) const;
/**
* Printing methods.
@@ -993,6 +987,10 @@ inline string value_context(const value_t& val) {
return buf.str();
}
+inline value_t scope_value(scope_t * val) {
+ return value_t(val);
+}
+
template <typename T>
inline value_t& add_or_set_value(value_t& lhs, const T& rhs) {
if (lhs.is_null())