1 // file : cutl/container/any.hxx 2 // copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC 3 // license : MIT; see accompanying LICENSE file 4 5 #ifndef CUTL_CONTAINER_ANY_HXX 6 #define CUTL_CONTAINER_ANY_HXX 7 8 #include <memory> // std::auto_ptr 9 #include <typeinfo> // std::type_info 10 11 #include <cutl/exception.hxx> 12 13 #include <cutl/details/export.hxx> 14 15 namespace cutl 16 { 17 namespace container 18 { 19 class LIBCUTL_EXPORT any 20 { 21 public: 22 struct LIBCUTL_EXPORT typing: exception {}; 23 24 public: any()25 any () 26 { 27 } 28 29 template <typename X> any(X const & x)30 any (X const& x) 31 : holder_ (new holder_impl<X> (x)) 32 { 33 } 34 any(any const & x)35 any (any const& x) 36 : holder_ (x.holder_->clone ()) 37 { 38 } 39 40 template <typename X> 41 any& operator =(X const & x)42 operator= (X const& x) 43 { 44 holder_.reset (new holder_impl<X> (x)); 45 return *this; 46 } 47 48 any& operator =(any const & x)49 operator= (any const& x) 50 { 51 holder_.reset (x.holder_->clone ()); 52 return *this; 53 } 54 55 public: 56 template <typename X> 57 X& value()58 value () 59 { 60 if (holder_impl<X>* p = dynamic_cast<holder_impl<X>*> (holder_.get ())) 61 return p->value (); 62 else 63 throw typing (); 64 } 65 66 template <typename X> 67 X const& value() const68 value () const 69 { 70 if (holder_impl<X>* p = dynamic_cast<holder_impl<X>*> (holder_.get ())) 71 return p->value (); 72 else 73 throw typing (); 74 } 75 76 std::type_info const& type_info() const77 type_info () const 78 { 79 return holder_->type_info (); 80 } 81 82 public: 83 bool empty() const84 empty () const 85 { 86 return holder_.get () == 0; 87 } 88 89 void reset()90 reset () 91 { 92 return holder_.reset (); 93 } 94 95 private: 96 class LIBCUTL_EXPORT holder 97 { 98 public: 99 virtual ~holder()100 ~holder () {} 101 102 virtual holder* 103 clone () const = 0; 104 105 virtual std::type_info const& 106 type_info () const = 0; 107 }; 108 109 template <typename X> 110 class holder_impl: public holder 111 { 112 public: holder_impl(X const & x)113 holder_impl (X const& x) 114 : x_ (x) 115 { 116 } 117 118 virtual holder_impl* clone() const119 clone () const 120 { 121 return new holder_impl (x_); 122 } 123 124 virtual std::type_info const& type_info() const125 type_info () const 126 { 127 return typeid (x_); 128 } 129 130 X const& value() const131 value () const 132 { 133 return x_; 134 } 135 136 X& value()137 value () 138 { 139 return x_; 140 } 141 142 private: 143 X x_; 144 }; 145 146 private: 147 std::auto_ptr<holder> holder_; 148 }; 149 } 150 } 151 152 #endif // CUTL_CONTAINER_ANY_HXX 153