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