MyGUI  3.4.0
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 
64  {
65  public:
66  struct AnyEmpty { };
67  static AnyEmpty Null;
68 
69  Any();
70  Any(const Any::AnyEmpty& value);
71  Any(const Any& other);
72 
73  template<typename ValueType>
74  Any(const ValueType& value) :
75  mContent(new Holder<ValueType>(value))
76  {
77  }
78 
79  ~Any();
80 
81  Any& swap(Any& rhs);
82 
83  template<typename ValueType>
84  Any& operator = (const ValueType& rhs)
85  {
86  Any(rhs).swap(*this);
87  return *this;
88  }
89 
90  Any& operator = (const Any::AnyEmpty& rhs);
91  Any& operator = (const Any& rhs);
92 
93  bool empty() const;
94 
95  const std::type_info& getType() const;
96 
97  template<typename ValueType>
98  ValueType* castType(bool _throw = true) const
99  {
100  if (this->getType() == typeid(ValueType))
101  return &static_cast<Any::Holder<ValueType> *>(this->mContent)->held;
102  MYGUI_ASSERT(!_throw, "Bad cast from type '" << getType().name() << "' to '" << typeid(ValueType).name() << "'");
103  return nullptr;
104  }
105 
106  void* castUnsafe() const;
107 
108  bool compare(const Any& other) const;
109 
110  private:
111  class Placeholder
112  {
113  public:
114  virtual ~Placeholder() = default;
115 
116  public:
117  virtual const std::type_info& getType() const = 0;
118  virtual Placeholder* clone() const = 0;
119  virtual bool compare(Placeholder* other) const = 0;
120  };
121 
122  template<class T>
123  struct HasOperatorEqualImpl
124  {
125  template <typename U>
126  static auto test(U*) -> decltype(std::declval<U>() == std::declval<U>());
127  template <typename>
128  static auto test(...)->std::false_type;
129 
130  using type = typename std::is_same<bool, decltype(test<T>(nullptr))>::type;
131  static constexpr bool value = type::value;
132  };
133 
134  template<class T>
135  struct HasOperatorEqual : HasOperatorEqualImpl<T>::type {};
136  template<typename T1, typename T2>
137  struct HasOperatorEqual<std::pair<T1, T2>>
138  {
139  static constexpr bool value = HasOperatorEqualImpl<T1>::value && HasOperatorEqualImpl<T2>::value;
140  };
141 
142  template<typename ValueType>
143  class Holder :
144  public Placeholder
145  {
146  public:
147  Holder(const ValueType& value) :
148  held(value)
149  {
150  }
151 
152  Holder& operator=(const Holder&) = delete;
153 
154  public:
155  const std::type_info& getType() const override
156  {
157  return typeid(ValueType);
158  }
159 
160  Placeholder* clone() const override
161  {
162  return new Holder(held);
163  }
164 
165  bool compare(Placeholder* other) const override
166  {
167  return compareImpl(other);
168  }
169  private:
170  template<typename T = ValueType>
171  typename std::enable_if<HasOperatorEqual<T>::value == true, bool>::type compareImpl(Placeholder* other) const
172  {
173  return getType() == other->getType() && held == static_cast<Holder*>(other)->held;
174  }
175 
176  template<typename T = ValueType>
177  typename std::enable_if<HasOperatorEqual<T>::value == false, bool>::type compareImpl(Placeholder* other) const
178  {
179  MYGUI_EXCEPT("Type '" << getType().name() << "' is not comparable");
180  }
181 
182  public:
183  ValueType held;
184  };
185 
186  private:
187  Placeholder* mContent;
188  };
189 
190 } // namespace MyGUI
191 
192 #endif // MYGUI_ANY_H_
MyGUI_Diagnostic.h
MyGUI::Any::AnyEmpty
Definition: MyGUI_Any.h:66
MyGUI::Any::swap
Any & swap(Any &rhs)
Definition: MyGUI_Any.cpp:35
MyGUI::Any::castType
ValueType * castType(bool _throw=true) const
Definition: MyGUI_Any.h:98
MyGUI::Any
Definition: MyGUI_Any.h:64
MyGUI_Prerequest.h
MYGUI_EXCEPT
#define MYGUI_EXCEPT(dest)
Definition: MyGUI_Diagnostic.h:26
MYGUI_ASSERT
#define MYGUI_ASSERT(exp, dest)
Definition: MyGUI_Diagnostic.h:34
MYGUI_EXPORT
#define MYGUI_EXPORT
Definition: MyGUI_Platform.h:89
MyGUI::Any::Null
static AnyEmpty Null
Definition: MyGUI_Any.h:67
MyGUI
Definition: MyGUI_ActionController.h:15
MyGUI::Any::Any
Any(const ValueType &value)
Definition: MyGUI_Any.h:74