TGUI  0.9-dev
Any.hpp
1 //
3 // TGUI - Texus' Graphical User Interface
4 // Copyright (C) 2012-2020 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 
39 namespace 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);
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:35