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
23namespace 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
Any(const ValueType &value)
Definition: MyGUI_Any.h:66
ValueType * castType(bool _throw=true) const
Definition: MyGUI_Any.h:90