diff options
author | John Wiegley <johnw@newartisans.com> | 2010-06-13 15:04:53 -0400 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2010-06-13 15:04:53 -0400 |
commit | 0c699e4d57fe91fa04c4c2f23f9c2f2a6a5da582 (patch) | |
tree | 985c50c080c077fa931ed9bf01c3895cbb851eda /src/value.h | |
parent | 40f553228f5a28034c6635fdcb4c86af28a385ed (diff) | |
parent | cf0147fcd04fc7ec4b3849350430e47169581e64 (diff) | |
download | fork-ledger-0c699e4d57fe91fa04c4c2f23f9c2f2a6a5da582.tar.gz fork-ledger-0c699e4d57fe91fa04c4c2f23f9c2f2a6a5da582.tar.bz2 fork-ledger-0c699e4d57fe91fa04c4c2f23f9c2f2a6a5da582.zip |
Merge branch 'next'
Diffstat (limited to 'src/value.h')
-rw-r--r-- | src/value.h | 122 |
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()) |