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