From 4a44218da15c5d4dfb29fc32dfe5818a5ac27b7a Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 13 Jun 2010 03:55:02 -0400 Subject: For value_t, use boost::any to refer to objects --- src/value.h | 81 ++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 54 insertions(+), 27 deletions(-) (limited to 'src/value.h') diff --git a/src/value.h b/src/value.h index 7bd09c9a..361282c4 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 data; type_t type; @@ -354,10 +353,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 + 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 +532,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 +731,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, 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 + bool is_any() const { + return (is_type(ANY) && + boost::get(storage->data).type() == typeid(T)); } - expr_t& as_expr_lval() const { - VERIFY(is_expr()); - return *boost::get(storage->data); + boost::any& as_any_lval() { + VERIFY(is_any()); + _dup(); + return boost::get(storage->data); + } + template + T& as_any_lval() { + return any_cast(as_any_lval()); } - const expr_t& as_expr() const { - VERIFY(is_expr()); - return *boost::get(storage->data); + const boost::any& as_any() const { + VERIFY(is_any()); + return boost::get(storage->data); + } + template + const T& as_any() const { + return any_cast(as_any()); + } + void set_any(const boost::any& val) { + set_type(ANY); + storage->data = val; + } + template + 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 -- cgit v1.2.3