TGUI  0.10-dev
Any.hpp
1
2//
3// TGUI - Texus' Graphical User Interface
4// Copyright (C) 2012-2021 Bruno Van de Velde (vdv_b@tgui.eu)
5//
6// This software is provided 'as-is', without any express or implied warranty.
7// In no event will the authors be held liable for any damages arising from the use of this software.
8//
9// Permission is granted to anyone to use this software for any purpose,
10// including commercial applications, and to alter it and redistribute it freely,
11// subject to the following restrictions:
12//
13// 1. The origin of this software must not be misrepresented;
14// you must not claim that you wrote the original software.
15// If you use this software in a product, an acknowledgment
16// in the product documentation would be appreciated but is not required.
17//
18// 2. Altered source versions must be plainly marked as such,
19// and must not be misrepresented as being the original software.
20//
21// 3. This notice may not be removed or altered from any source distribution.
22//
24
25// Code based on http://codereview.stackexchange.com/questions/20058/c11-any-class
26
27#ifndef TGUI_ANY_HPP
28#define TGUI_ANY_HPP
29
30#include <TGUI/Config.hpp>
31#include <type_traits>
32#include <utility>
33#include <typeinfo>
34
35#if TGUI_COMPILED_WITH_CPP_VER >= 17
36 #include <any>
37#endif
38
39namespace tgui
40{
41#if TGUI_COMPILED_WITH_CPP_VER >= 17
42 using Any = std::any;
43
44 template<typename T>
45 T AnyCast(const Any& obj)
46 {
47 return std::any_cast<T>(obj);
48 }
49#else
50 struct Any
51 {
52 template<class T>
53 using StorageType = typename std::decay<T>::type;
54
55 bool is_null() const
56 {
57 return ptr == nullptr;
58 }
59
60 bool not_null() const
61 {
62 return ptr != nullptr;
63 }
64
65 template<typename U>
66 Any(U&& value)
67 : ptr{new Derived<StorageType<U>>(std::forward<U>(value))}
68 {
69 }
70
71 template<class U>
72 bool is() const
73 {
74 typedef StorageType<U> T;
75 return (dynamic_cast<Derived<T>*>(ptr) != nullptr);
76 }
77
78 template<class U>
79 StorageType<U>& as() const
80 {
81 typedef StorageType<U> T;
82 auto derived = dynamic_cast<Derived<T>*>(ptr);
83 if (!derived)
84 throw std::bad_cast();
85
86 return derived->value;
87 }
88
89 template<class U>
90 operator U()
91 {
92 return as<StorageType<U>>();
93 }
94
95 Any()
96 : ptr(nullptr)
97 {
98 }
99
100 Any(const Any& that)
101 : ptr(that.clone())
102 {
103 }
104
105 Any(Any&& that) noexcept
106 : ptr(that.ptr)
107 {
108 that.ptr = nullptr;
109 }
110
111 Any& operator=(const Any& a)
112 {
113 if (ptr == a.ptr)
114 return *this;
115
116 auto old_ptr = ptr;
117
118 ptr = a.clone();
119
120 if (old_ptr)
121 delete old_ptr;
122
123 return *this;
124 }
125
126 Any& operator=(Any&& a) noexcept
127 {
128 if (ptr == a.ptr)
129 return *this;
130
131 std::swap(ptr, a.ptr);
132
133 return *this;
134 }
135
136 ~Any()
137 {
138 delete ptr;
139 }
140
141 private:
142 struct Base
143 {
144 virtual ~Base() {}
145 virtual Base* clone() const = 0;
146 };
147
148 template<typename T>
149 struct Derived : Base
150 {
151 template<typename U>
152 Derived(U&& val) :
153 value(std::forward<U>(val))
154 {
155 }
156
157 Base* clone() const override
158 {
159 return new Derived<T>(value);
160 }
161
162 T value;
163 };
164
165 Base* clone() const
166 {
167 if (ptr)
168 return ptr->clone();
169 else
170 return nullptr;
171 }
172
173 Base* ptr;
174 };
175
176 template<typename T>
177 T AnyCast(const Any& obj)
178 {
179 return obj.as<T>();
180 }
181#endif
182}
183
184#endif // TGUI_ANY_HPP
Namespace that contains all TGUI functions and classes.
Definition: AbsoluteOrRelativeValue.hpp:36