TGUI  0.8-dev
Any.hpp
1 //
3 // TGUI - Texus' Graphical User Interface
4 // Copyright (C) 2012-2017 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 <type_traits>
31 #include <utility>
32 #include <typeinfo>
33 
34 namespace tgui
35 {
36  struct Any
37  {
38  template<class T>
39  using StorageType = typename std::decay<T>::type;
40 
41  bool is_null() const
42  {
43  return ptr == nullptr;
44  }
45 
46  bool not_null() const
47  {
48  return ptr != nullptr;
49  }
50 
51  template<typename U>
52  Any(U&& value)
53  : ptr{new Derived<StorageType<U>>(std::forward<U>(value))}
54  {
55  }
56 
57  template<class U>
58  bool is() const
59  {
60  typedef StorageType<U> T;
61  return dynamic_cast<Derived<T>*>(ptr);
62  }
63 
64  template<class U>
65  StorageType<U>& as() const
66  {
67  typedef StorageType<U> T;
68  auto derived = dynamic_cast<Derived<T>*>(ptr);
69  if (!derived)
70  throw std::bad_cast();
71 
72  return derived->value;
73  }
74 
75  template<class U>
76  operator U()
77  {
78  return as<StorageType<U>>();
79  }
80 
81  Any()
82  : ptr(nullptr)
83  {
84  }
85 
86  Any(const Any& that)
87  : ptr(that.clone())
88  {
89  }
90 
91  Any(Any&& that)
92  : ptr(that.ptr)
93  {
94  that.ptr = nullptr;
95  }
96 
97  Any& operator=(const Any& a)
98  {
99  if (ptr == a.ptr)
100  return *this;
101 
102  auto old_ptr = ptr;
103 
104  ptr = a.clone();
105 
106  if (old_ptr)
107  delete old_ptr;
108 
109  return *this;
110  }
111 
112  Any& operator=(Any&& a)
113  {
114  if (ptr == a.ptr)
115  return *this;
116 
117  std::swap(ptr, a.ptr);
118 
119  return *this;
120  }
121 
122  ~Any()
123  {
124  delete ptr;
125  }
126 
127  private:
128  struct Base
129  {
130  virtual ~Base() {}
131  virtual Base* clone() const = 0;
132  };
133 
134  template<typename T>
135  struct Derived : Base
136  {
137  template<typename U>
138  Derived(U&& val) :
139  value(std::forward<U>(val))
140  {
141  }
142 
143  Base* clone() const
144  {
145  return new Derived<T>(value);
146  }
147 
148  T value;
149  };
150 
151  Base* clone() const
152  {
153  if (ptr)
154  return ptr->clone();
155  else
156  return nullptr;
157  }
158 
159  Base* ptr;
160  };
161 }
162 
163 #endif // TGUI_ANY_HPP
Namespace that contains all TGUI functions and classes.
Definition: AbsoluteOrRelativeValue.hpp:36
Definition: Any.hpp:36