// file : cult/containers/any.hxx // author : Boris Kolpackov // copyright : Copyright (c) 2005-2010 Boris Kolpackov // license : GNU GPL v2 + exceptions; see accompanying LICENSE file #ifndef CULT_CONTAINERS_ANY_HXX #define CULT_CONTAINERS_ANY_HXX #include #include namespace Cult { namespace Containers { //@@ eager clonning: do I need it? // // class Any { public: struct Typing {}; public: template Any (X const& x) : holder_ (new HolderTemplate (x)) { } Any (Any const& any) : holder_ (any.holder_->clone ()) { } public: template Any& operator= (X const& x) { holder_ = Evptr (new HolderTemplate (x)); return *this; } Any& operator= (Any const& any) { holder_ = any.holder_->clone (); return *this; } public: /* template operator X& () { return value (); } template operator X const& () const { return value (); } */ public: template X& value () { //@@ too strict // if (holder_->type_id () == typeid (X)) { return dynamic_cast*>(holder_.get ())->value (); } else { throw Typing (); } } template X const& value () const { if (holder_->type_id () == typeid (X)) { return dynamic_cast*>(holder_.get ())->value (); } else { throw Typing (); } } public: RTTI::TypeId type_id () const { return holder_->type_id (); } public: /* template friend x operator+ (any const& a, x const& b) { return a.value () + b; } template friend x operator+ (x const& a, any const& b) { return a + b.value (); } */ private: class Holder { public: virtual ~Holder () { } Evptr clone () const { return clone_ (); } virtual RTTI::TypeId type_id () const = 0; protected: virtual Evptr clone_ () const = 0; }; template class HolderTemplate : public Holder { public: HolderTemplate (X const& value) : value_ (value) { } virtual RTTI::TypeId type_id () const { return RTTI::TypeId (typeid (value_)); } X const& value () const { return value_; } X& value () { return value_; } protected: virtual Evptr clone_ () const { return new HolderTemplate (value_); } private: X value_; }; private: Evptr holder_; }; } } #include #endif // CULT_CONTAINERS_ANY_HXX