MyGUI  3.0.1
MyGUI_Any.h
Go to the documentation of this file.
1 
7 /*
8  This file is part of MyGUI.
9 
10  MyGUI is free software: you can redistribute it and/or modify
11  it under the terms of the GNU Lesser General Public License as published by
12  the Free Software Foundation, either version 3 of the License, or
13  (at your option) any later version.
14 
15  MyGUI is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  GNU Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public License
21  along with MyGUI. If not, see <http://www.gnu.org/licenses/>.
22 */
23 
24 // -- Based on boost::any, original copyright information follows --
25 // Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
26 //
27 // Distributed under the Boost Software License, Version 1.0.
28 // (See at http://www.boost.org/LICENSE_1_0.txt)
29 // -- End original copyright --
30 
31 #ifndef __MYGUI_ANY_H__
32 #define __MYGUI_ANY_H__
33 
34 #include "MyGUI_Prerequest.h"
35 #include "MyGUI_Diagnostic.h"
36 #include <algorithm>
37 #include <typeinfo>
38 
39 namespace MyGUI
40 {
41 
81  {
82 
83  private:
84  struct AnyEmpty { };
85 
86  public:
87  static AnyEmpty Null;
88 
89  public:
90  Any() :
91  mContent(nullptr)
92  {
93  }
94 
95  template<typename ValueType> Any(const ValueType& value) :
96  mContent(new Holder<ValueType>(value))
97  {
98  }
99 
100  Any(const Any::AnyEmpty& value) :
101  mContent(nullptr)
102  {
103  }
104 
105  Any(const Any& other) :
106  mContent(other.mContent ? other.mContent->clone() : nullptr)
107  {
108  }
109 
110  ~Any()
111  {
112  delete mContent;
113  }
114 
115  Any& swap(Any& rhs)
116  {
117  std::swap(mContent, rhs.mContent);
118  return *this;
119  }
120 
121  template<typename ValueType> Any& operator = (const ValueType& rhs)
122  {
123  Any(rhs).swap(*this);
124  return *this;
125  }
126 
127  Any& operator = (const Any::AnyEmpty& rhs)
128  {
129  delete mContent;
130  mContent = nullptr;
131  return *this;
132  }
133 
134  Any& operator = (const Any& rhs)
135  {
136  Any(rhs).swap(*this);
137  return *this;
138  }
139 
140  bool empty() const
141  {
142  return !mContent;
143  }
144 
145  const std::type_info& getType() const
146  {
147  return mContent ? mContent->getType() : typeid(void);
148  }
149 
150  template<typename ValueType>
151  ValueType * castType(bool _throw = true) const
152  {
153  if (this->getType() == typeid(ValueType))
154  {
155  return &static_cast<Any::Holder<ValueType> *>(this->mContent)->held;
156  }
157  MYGUI_ASSERT(!_throw, "Bad cast from type '" << getType().name() << "' to '" << typeid(ValueType).name() << "'");
158  return nullptr;
159  }
160 
161  void * castUnsafe() const
162  {
163  return mContent ? static_cast<Any::Holder<void *> *>(this->mContent)->held : nullptr;
164  }
165 
166  private:
167  class Placeholder
168  {
169  public:
170  virtual ~Placeholder() { }
171 
172  public:
173  virtual const std::type_info& getType() const = 0;
174  virtual Placeholder * clone() const = 0;
175 
176  };
177 
178  template<typename ValueType> class Holder : public Placeholder
179  {
180  public:
181  Holder(const ValueType& value) :
182  held(value)
183  {
184  }
185 
186  public:
187  virtual const std::type_info& getType() const
188  {
189  return typeid(ValueType);
190  }
191 
192  virtual Placeholder * clone() const
193  {
194  return new Holder(held);
195  }
196 
197  public:
198  ValueType held;
199 
200  private:
201  Holder& operator=(const Holder &);
202 
203  };
204 
205 
206  private: // representation
207  Placeholder * mContent;
208 
209  };
210 
211 } // namespace MyGUI
212 
213 #endif // __MYGUI_ANY_H__