diff options
author | John Wiegley <johnw@newartisans.com> | 2010-06-13 03:55:02 -0400 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2010-06-13 03:55:08 -0400 |
commit | 4a44218da15c5d4dfb29fc32dfe5818a5ac27b7a (patch) | |
tree | f263cca3ab24cdad7f76c68e32025feb21b09969 | |
parent | 44a5103e1ce9f968df02ac6e1f86fcf9415a1983 (diff) | |
download | fork-ledger-4a44218da15c5d4dfb29fc32dfe5818a5ac27b7a.tar.gz fork-ledger-4a44218da15c5d4dfb29fc32dfe5818a5ac27b7a.tar.bz2 fork-ledger-4a44218da15c5d4dfb29fc32dfe5818a5ac27b7a.zip |
For value_t, use boost::any to refer to objects
-rw-r--r-- | src/system.hh.in | 1 | ||||
-rw-r--r-- | src/value.cc | 45 | ||||
-rw-r--r-- | src/value.h | 81 |
3 files changed, 75 insertions, 52 deletions
diff --git a/src/system.hh.in b/src/system.hh.in index 34efa424..d9e664e3 100644 --- a/src/system.hh.in +++ b/src/system.hh.in @@ -137,6 +137,7 @@ typedef std::ostream::pos_type ostream_pos_type; #endif #include <boost/algorithm/string.hpp> +#include <boost/any.hpp> #include <boost/bind.hpp> #include <boost/cast.hpp> #include <boost/current_function.hpp> diff --git a/src/value.cc b/src/value.cc index fd49e85c..99837832 100644 --- a/src/value.cc +++ b/src/value.cc @@ -116,8 +116,8 @@ value_t::operator bool() const return false; case SCOPE: return as_scope() != NULL; - case EXPR: - return as_expr(); + case ANY: + return ! as_any().empty(); default: break; } @@ -145,12 +145,6 @@ void value_t::set_type(type_t new_type) } } -void value_t::set_expr(const expr_t& val) -{ - set_type(EXPR); - storage->data = new expr_t(val); -} - bool value_t::to_boolean() const { if (is_boolean()) { @@ -1372,8 +1366,8 @@ bool value_t::is_realzero() const case SCOPE: return as_scope() == NULL; - case EXPR: - return ! as_expr(); + case ANY: + return as_any().empty(); default: add_error_context(_("While applying is_realzero to %1:") << *this); @@ -1404,8 +1398,8 @@ bool value_t::is_zero() const case SCOPE: return as_scope() == NULL; - case EXPR: - return ! as_expr(); + case ANY: + return as_any().empty(); default: add_error_context(_("While applying is_zero to %1:") << *this); @@ -1677,7 +1671,7 @@ value_t value_t::strip_annotations(const keep_details_t& what_to_keep) const case STRING: case MASK: case SCOPE: - case EXPR: + case ANY: return *this; case SEQUENCE: { @@ -1825,13 +1819,14 @@ void value_t::print(std::ostream& out, case SCOPE: out << "<#SCOPE>"; break; - case EXPR: - out << "<#EXPR "; - if (as_expr()) - as_expr().print(out); - else - out << "null"; - out << ">"; + case ANY: + if (as_any().type() == typeid(expr_t::ptr_op_t)) { + out << "<#EXPR "; + as_any<expr_t::ptr_op_t>()->print(out); + out << ">"; + } else { + out << "<#OBJECT>"; + } break; default: @@ -1902,11 +1897,11 @@ void value_t::dump(std::ostream& out, const bool relaxed) const case SCOPE: out << as_scope(); break; - case EXPR: - if (as_expr()) - as_expr().dump(out); + case ANY: + if (as_any().type() == typeid(expr_t::ptr_op_t)) + as_any<expr_t::ptr_op_t>()->dump(out); else - out << "null"; + out << boost::unsafe_any_cast<const void *>(&as_any()); break; case SEQUENCE: { @@ -2020,7 +2015,7 @@ void to_xml(std::ostream& out, const value_t& value) } case value_t::SCOPE: - case value_t::EXPR: + case value_t::ANY: default: assert(false); break; 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<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; @@ -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 <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 +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<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)); } - expr_t& as_expr_lval() const { - VERIFY(is_expr()); - return *boost::get<expr_t *>(storage->data); + 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 expr_t& as_expr() const { - VERIFY(is_expr()); - return *boost::get<expr_t *>(storage->data); + const boost::any& as_any() const { + VERIFY(is_any()); + return boost::get<boost::any>(storage->data); + } + template <typename T> + const T& as_any() const { + return any_cast<const T&>(as_any()); + } + 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 |