MyGUI 3.4.3
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 static const Any Null;
59 Any();
60 Any(const Any& other);
61 Any(Any&& other) noexcept;
63
64 template<typename ValueType>
65 Any(const ValueType& value) :
66 mContent(std::make_unique<Holder<ValueType>>(value))
67 {
68 }
69
70 template<typename ValueType>
71 Any& operator=(const ValueType& rhs)
72 {
73 mContent = std::make_unique<Holder>(rhs);
74 return *this;
75 }
76
77 Any& operator=(const Any& rhs);
78 Any& operator=(Any&& rhs) noexcept;
79
80 bool empty() const;
81
82 const std::type_info& getType() const;
83
84 template<typename ValueType>
85 ValueType* castType(bool _throw = true) const
86 {
87 if (this->getType() == typeid(ValueType))
88 return &static_cast<Any::Holder<ValueType>*>(this->mContent.get())->held;
90 !_throw,
91 "Bad cast from type '" << getType().name() << "' to '" << typeid(ValueType).name() << "'");
92 return nullptr;
93 }
94
95 bool compare(const Any& other) const;
96
97 private:
98 class Placeholder
99 {
100 public:
101 virtual ~Placeholder() = default;
102
103 public:
104 virtual const std::type_info& getType() const = 0;
105 virtual std::unique_ptr<Placeholder> clone() const = 0;
106 virtual bool compare(const std::unique_ptr<Placeholder>& other) const = 0;
107 };
108
109 template<class T>
110 struct HasOperatorEqualImpl
111 {
112 template<typename U>
113 static auto test(U*) -> decltype(std::declval<U>() == std::declval<U>());
114 template<typename>
115 static auto test(...) -> std::false_type;
116
117 using type = typename std::is_same<bool, decltype(test<T>(nullptr))>::type;
118 static constexpr bool value = type::value;
119 };
120
121 template<class T>
122 struct HasOperatorEqual : HasOperatorEqualImpl<T>::type
123 {
124 };
125 template<typename T1, typename T2>
126 struct HasOperatorEqual<std::pair<T1, T2>>
127 {
128 static constexpr bool value = HasOperatorEqualImpl<T1>::value && HasOperatorEqualImpl<T2>::value;
129 };
130
131 template<typename ValueType>
132 class Holder : public Placeholder
133 {
134 friend class Any;
135
136 public:
137 Holder(const ValueType& value) :
138 held(value)
139 {
140 }
141
142 public:
143 const std::type_info& getType() const override
144 {
145 return typeid(ValueType);
146 }
147
148 std::unique_ptr<Placeholder> clone() const override
149 {
150 return std::make_unique<Holder>(held);
151 }
152
153 bool compare(const std::unique_ptr<Placeholder>& other) const override
154 {
155 if constexpr (HasOperatorEqual<ValueType>::value)
156 return getType() == other->getType() && held == static_cast<Holder*>(other.get())->held;
157 else
158 MYGUI_EXCEPT("Type '" << getType().name() << "' is not comparable");
159 }
160
161 private:
162 ValueType held;
163 };
164
165 private:
166 std::unique_ptr<Placeholder> mContent;
167 };
168
169} // namespace MyGUI
170
171#endif // MYGUI_ANY_H_
#define MYGUI_ASSERT(exp, dest)
#define MYGUI_EXCEPT(dest)
#define MYGUI_EXPORT
Any & operator=(const ValueType &rhs)
Definition MyGUI_Any.h:71
Any & operator=(Any &&rhs) noexcept
Any(Any &&other) noexcept
static const Any Null
Definition MyGUI_Any.h:58
Any(const ValueType &value)
Definition MyGUI_Any.h:65
ValueType * castType(bool _throw=true) const
Definition MyGUI_Any.h:85