// file : cutl/container/any.hxx // author : Boris Kolpackov // copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC // license : MIT; see accompanying LICENSE file #ifndef CUTL_CONTAINER_ANY_HXX #define CUTL_CONTAINER_ANY_HXX #include // std::auto_ptr #include // std::type_info #include #include namespace cutl { namespace container { class LIBCUTL_EXPORT any { public: struct LIBCUTL_EXPORT typing: exception {}; public: template any (X const& x) : holder_ (new holder_impl (x)) { } any (any const& x) : holder_ (x.holder_->clone ()) { } template any& operator= (X const& x) { holder_.reset (new holder_impl (x)); return *this; } any& operator= (any const& x) { holder_.reset (x.holder_->clone ()); return *this; } public: template X& value () { if (holder_impl* p = dynamic_cast*> (holder_.get ())) return p->value (); else throw typing (); } template X const& value () const { if (holder_impl* p = dynamic_cast*> (holder_.get ())) return p->value (); else throw typing (); } public: std::type_info const& type_info () const { return holder_->type_info (); } private: class LIBCUTL_EXPORT holder { public: virtual ~holder () {} virtual holder* clone () const = 0; virtual std::type_info const& type_info () const = 0; }; template class holder_impl: public holder { public: holder_impl (X const& x) : x_ (x) { } virtual holder_impl* clone () const { return new holder_impl (x_); } virtual std::type_info const& type_info () const { return typeid (x_); } X const& value () const { return x_; } X& value () { return x_; } private: X x_; }; private: std::auto_ptr holder_; }; } } #endif // CUTL_CONTAINER_ANY_HXX