TGUI  1.3-dev
Loading...
Searching...
No Matches
Any.hpp
1
2//
3// TGUI - Texus' Graphical User Interface
4// Copyright (C) 2012-2024 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
32#if !TGUI_EXPERIMENTAL_USE_STD_MODULE
33 #include <type_traits>
34 #include <utility>
35 #include <typeinfo>
36
37 #if TGUI_COMPILED_WITH_CPP_VER >= 17
38 #include <any>
39 #endif
40#endif
41
42TGUI_MODULE_EXPORT namespace tgui
43{
44#if TGUI_COMPILED_WITH_CPP_VER >= 17
45 using Any = std::any;
46
47 template<typename T>
48 T AnyCast(const Any& obj)
49 {
50 return std::any_cast<T>(obj);
51 }
52#else
53 struct Any
54 {
55 template<class T>
56 using StorageType = std::decay_t<T>;
57
58 TGUI_NODISCARD bool is_null() const
59 {
60 return ptr == nullptr;
61 }
62
63 TGUI_NODISCARD bool not_null() const
64 {
65 return ptr != nullptr;
66 }
67
68 template<typename U>
69 Any(U&& value) // NOLINT(bugprone-forwarding-reference-overload)
70 : ptr{new Derived<StorageType<U>>(std::forward<U>(value))}
71 {
72 }
73
74 TGUI_NODISCARD bool has_value() const noexcept
75 {
76 return ptr != nullptr;
77 }
78
79 template<class U>
80 TGUI_NODISCARD bool is() const
81 {
82 using T = StorageType<U>;
83 return (dynamic_cast<Derived<T>*>(ptr) != nullptr);
84 }
85
86 template<class U>
87 StorageType<U>& as() const
88 {
89 using T = StorageType<U>;
90 auto derived = dynamic_cast<Derived<T>*>(ptr);
91 if (!derived)
92 throw std::bad_cast();
93
94 return derived->value;
95 }
96
97 template<class U>
98 operator U()
99 {
100 return as<StorageType<U>>();
101 }
102
103 Any()
104 : ptr(nullptr)
105 {
106 }
107
108 Any(const Any& that)
109 : ptr(that.clone())
110 {
111 }
112
113 Any(Any&& that) noexcept
114 : ptr(that.ptr)
115 {
116 that.ptr = nullptr;
117 }
118
119 Any& operator=(const Any& a)
120 {
121 if ((this == &a) || (ptr == a.ptr))
122 return *this;
123
124 auto old_ptr = ptr;
125
126 ptr = a.clone();
127
128 if (old_ptr)
129 delete old_ptr;
130
131 return *this;
132 }
133
134 Any& operator=(Any&& a) noexcept
135 {
136 if ((this == &a) || (ptr == a.ptr))
137 return *this;
138
139 std::swap(ptr, a.ptr);
140
141 return *this;
142 }
143
144 ~Any()
145 {
146 delete ptr;
147 }
148
149 private:
150 struct Base
151 {
152 virtual ~Base() = default;
153 TGUI_NODISCARD virtual Base* clone() const = 0;
154 };
155
156 template<typename T>
157 struct Derived : Base
158 {
159 template<typename U>
160 Derived(U&& val) : // NOLINT(bugprone-forwarding-reference-overload)
161 value(std::forward<U>(val))
162 {
163 }
164
165 Base* clone() const override
166 {
167 return new Derived<T>(value);
168 }
169
170 T value;
171 };
172
173 TGUI_NODISCARD Base* clone() const
174 {
175 if (ptr)
176 return ptr->clone();
177 else
178 return nullptr;
179 }
180
181 Base* ptr;
182 };
183
184 template<typename T>
185 TGUI_NODISCARD T AnyCast(const Any& obj)
186 {
187 return obj.as<T>();
188 }
189#endif
190}
191
192#endif // TGUI_ANY_HPP
Namespace that contains all TGUI functions and classes.
Definition AbsoluteOrRelativeValue.hpp:39