MyGUI  3.4.1
MyGUI_Any.h
Go to the documentation of this file.
1 /*
2  * This source file is part of MyGUI. For the latest info, see http://mygui.info/
3  * Distributed under the MIT License
4  * (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT)
5  */
6 
7 // -- Based on boost::any, original copyright information follows --
8 // Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
9 //
10 // Distributed under the Boost Software License, Version 1.0.
11 // (See at http://www.boost.org/LICENSE_1_0.txt)
12 // -- End original copyright --
13 
14 #ifndef MYGUI_ANY_H_
15 #define MYGUI_ANY_H_
16 
17 #include "MyGUI_Prerequest.h"
18 #include "MyGUI_Diagnostic.h"
19 #include <algorithm>
20 
21 #include <typeinfo>
22 
23 namespace MyGUI
24 {
25 
56  {
57  public:
58  struct AnyEmpty { };
59  static AnyEmpty Null;
60 
61  Any();
62  Any(const Any::AnyEmpty& value);
63  Any(const Any& other);
64 
65  template<typename ValueType>
66  Any(const ValueType& value) :
67  mContent(new Holder<ValueType>(value))
68  {
69  }
70 
71  ~Any();
72 
73  Any& swap(Any& rhs);
74 
75  template<typename ValueType>
76  Any& operator = (const ValueType& rhs)
77  {
78  Any(rhs).swap(*this);
79  return *this;
80  }
81 
82  Any& operator = (const Any::AnyEmpty& rhs);
83  Any& operator = (const Any& rhs);
84 
85  bool empty() const;
86 
87  const std::type_info& getType() const;
88 
89  template<typename ValueType>
90  ValueType* castType(bool _throw = true) const
91  {
92  if (this->getType() == typeid(ValueType))
93  return &static_cast<Any::Holder<ValueType> *>(this->mContent)->held;
94  MYGUI_ASSERT(!_throw, "Bad cast from type '" << getType().name() << "' to '" << typeid(ValueType).name() << "'");
95  return nullptr;
96  }
97 
98  void* castUnsafe() const;
99 
100  bool compare(const Any& other) const;
101 
102  private:
103  class Placeholder
104  {
105  public:
106  virtual ~Placeholder() = default;
107 
108  public:
109  virtual const std::type_info& getType() const = 0;
110  virtual Placeholder* clone() const = 0;
111  virtual bool compare(Placeholder* other) const = 0;
112  };
113 
114  template<class T>
115  struct HasOperatorEqualImpl
116  {
117  template <typename U>
118  static auto test(U*) -> decltype(std::declval<U>() == std::declval<U>());
119  template <typename>
120  static auto test(...)->std::false_type;
121 
122  using type = typename std::is_same<bool, decltype(test<T>(nullptr))>::type;
123  static constexpr bool value = type::value;
124  };
125 
126  template<class T>
127  struct HasOperatorEqual : HasOperatorEqualImpl<T>::type {};
128  template<typename T1, typename T2>
129  struct HasOperatorEqual<std::pair<T1, T2>>
130  {
131  static constexpr bool value = HasOperatorEqualImpl<T1>::value && HasOperatorEqualImpl<T2>::value;
132  };
133 
134  template<typename ValueType>
135  class Holder :
136  public Placeholder
137  {
138  public:
139  Holder(const ValueType& value) :
140  held(value)
141  {
142  }
143 
144  Holder& operator=(const Holder&) = delete;
145 
146  public:
147  const std::type_info& getType() const override
148  {
149  return typeid(ValueType);
150  }
151 
152  Placeholder* clone() const override
153  {
154  return new Holder(held);
155  }
156 
157  bool compare(Placeholder* other) const override
158  {
159  return compareImpl(other);
160  }
161  private:
162  template<typename T = ValueType>
163  typename std::enable_if<HasOperatorEqual<T>::value == true, bool>::type compareImpl(Placeholder* other) const
164  {
165  return getType() == other->getType() && held == static_cast<Holder*>(other)->held;
166  }
167 
168  template<typename T = ValueType>
169  typename std::enable_if<HasOperatorEqual<T>::value == false, bool>::type compareImpl(Placeholder* other) const
170  {
171  MYGUI_EXCEPT("Type '" << getType().name() << "' is not comparable");
172  }
173 
174  public:
175  ValueType held;
176  };
177 
178  private:
179  Placeholder* mContent;
180  };
181 
182 } // namespace MyGUI
183 
184 #endif // MYGUI_ANY_H_
#define MYGUI_ASSERT(exp, dest)
#define MYGUI_EXCEPT(dest)
#define MYGUI_EXPORT
Any & swap(Any &rhs)
Definition: MyGUI_Any.cpp:35
static AnyEmpty Null
Definition: MyGUI_Any.h:59
ValueType * castType(bool _throw=true) const
Definition: MyGUI_Any.h:90
Any(const ValueType &value)
Definition: MyGUI_Any.h:66