1 // file : cutl/container/any.hxx 2 // copyright : Copyright (c) 2009-2017 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::unique_ptr/auto_ptr 9 #include <typeinfo> // std::type_info 10 11 #include <cutl/exception.hxx> 12 13 namespace cutl 14 { 15 namespace container 16 { 17 class any 18 { 19 public: 20 struct typing: exception {}; 21 22 public: any()23 any () 24 { 25 } 26 27 template <typename X> any(X const & x)28 any (X const& x) 29 : holder_ (new holder_impl<X> (x)) 30 { 31 } 32 any(any const & x)33 any (any const& x) 34 : holder_ (x.holder_->clone ()) 35 { 36 } 37 38 template <typename X> 39 any& operator =(X const & x)40 operator= (X const& x) 41 { 42 holder_.reset (new holder_impl<X> (x)); 43 return *this; 44 } 45 46 any& operator =(any const & x)47 operator= (any const& x) 48 { 49 holder_.reset (x.holder_->clone ()); 50 return *this; 51 } 52 53 public: 54 template <typename X> 55 X& value()56 value () 57 { 58 if (holder_impl<X>* p = dynamic_cast<holder_impl<X>*> (holder_.get ())) 59 return p->value (); 60 else 61 throw typing (); 62 } 63 64 template <typename X> 65 X const& value() const66 value () const 67 { 68 if (holder_impl<X>* p = dynamic_cast<holder_impl<X>*> (holder_.get ())) 69 return p->value (); 70 else 71 throw typing (); 72 } 73 74 std::type_info const& type_info() const75 type_info () const 76 { 77 return holder_->type_info (); 78 } 79 80 public: 81 bool empty() const82 empty () const 83 { 84 return holder_.get () == 0; 85 } 86 87 void reset()88 reset () 89 { 90 return holder_.reset (); 91 } 92 93 private: 94 class LIBCUTL_EXPORT holder 95 { 96 public: 97 virtual ~holder()98 ~holder () {} 99 100 virtual holder* 101 clone () const = 0; 102 103 virtual std::type_info const& 104 type_info () const = 0; 105 }; 106 107 template <typename X> 108 class holder_impl: public holder 109 { 110 public: holder_impl(X const & x)111 holder_impl (X const& x) 112 : x_ (x) 113 { 114 } 115 116 virtual holder_impl* clone() const117 clone () const 118 { 119 return new holder_impl (x_); 120 } 121 122 virtual std::type_info const& type_info() const123 type_info () const 124 { 125 return typeid (x_); 126 } 127 128 X const& value() const129 value () const 130 { 131 return x_; 132 } 133 134 X& value()135 value () 136 { 137 return x_; 138 } 139 140 private: 141 X x_; 142 }; 143 144 private: 145 #ifdef LIBCUTL_CXX11 146 std::unique_ptr<holder> holder_; 147 #else 148 std::auto_ptr<holder> holder_; 149 #endif 150 }; 151 } 152 } 153 154 #endif // CUTL_CONTAINER_ANY_HXX 155