SHOGUN  4.2.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
any.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016, Shogun-Toolbox e.V. <shogun-team@shogun-toolbox.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  *
31  * Written (W) 2016 Sergey Lisitsyn
32  * Written (W) 2016 Sanuj Sharma
33  */
34 
35 #ifndef _ANY_H_
36 #define _ANY_H_
37 
38 #include <string.h>
39 #include <stdexcept>
40 #include <typeinfo>
41 #include <cxxabi.h>
42 
43 namespace shogun
44 {
49  template <typename T>
50  std::string demangledType()
51  {
52  size_t length;
53  int status;
54  char* demangled = abi::__cxa_demangle(typeid(T).name(), nullptr, &length, &status);
55  std::string demangled_string(demangled);
56  free(demangled);
57  return demangled_string;
58  }
59 
67  {
68  public:
73  virtual void set(void** storage, const void* v) const = 0;
74 
78  virtual void clear(void** storage) const = 0;
79 
83  virtual std::string type() const = 0;
84 
89  virtual bool matches(const std::type_info& ti) const = 0;
90 
96  virtual bool equals(void** storage, void** other_storage) const = 0;
97  };
98 
102  template <typename T>
104  {
105  public:
110  virtual void set(void** storage, const void* v) const
111  {
112  *(storage) = new T(*reinterpret_cast<T const*>(v));
113  }
114 
118  virtual void clear(void** storage) const
119  {
120  delete reinterpret_cast<T*>(*storage);
121  }
122 
126  virtual std::string type() const
127  {
128  return demangledType<T>();
129  }
130 
135  virtual bool matches(const std::type_info& ti) const
136  {
137  return typeid(T) == ti;
138  }
139 
145  bool equals(void** storage, void** other_storage) const
146  {
147  T typed_storage = *(reinterpret_cast<T*>(*storage));
148  T typed_other_storage = *(reinterpret_cast<T*>(*other_storage));
149  return typed_storage == typed_other_storage;
150  }
151  };
152 
159  class Any
160  {
161  public:
163  struct Empty;
164 
166  Any() : policy(select_policy<Empty>()), storage(nullptr)
167  {
168  }
169 
171  template <typename T>
172  explicit Any(const T& v) : policy(select_policy<T>()), storage(nullptr)
173  {
174  policy->set(&storage, &v);
175  }
176 
178  Any(const Any& other) : policy(other.policy), storage(nullptr)
179  {
180  policy->set(&storage, other.storage);
181  }
182 
187  Any& operator=(const Any& other)
188  {
189  policy->clear(&storage);
190  policy = other.policy;
191  policy->set(&storage, other.storage);
192  return *(this);
193  }
194 
200  friend inline bool operator==(const Any& lhs, const Any& rhs);
201 
207  friend inline bool operator!=(const Any& lhs, const Any& rhs);
208 
211  {
212  policy->clear(&storage);
213  }
214 
218  template <typename T>
219  T& as() const
220  {
221  if (same_type<T>())
222  {
223  return *(reinterpret_cast<T*>(storage));
224  }
225  else
226  {
227  throw std::logic_error("Bad cast to " + demangledType<T>() +
228  " but the type is " + policy->type());
229  }
230  }
231 
233  template <typename T>
234  inline bool same_type() const
235  {
236  return (policy == select_policy<T>()) || same_type_fallback<T>();
237  }
238 
240  template <typename T>
241  bool same_type_fallback() const
242  {
243  return policy->matches(typeid(T));
244  }
245 
247  bool empty() const
248  {
249  return same_type<Empty>();
250  }
251  private:
252  template <typename T>
253  static BaseAnyPolicy* select_policy()
254  {
255  typedef PointerValueAnyPolicy<T> Policy;
256  static Policy policy;
257  return &policy;
258  }
259 
260  BaseAnyPolicy* policy;
261  void* storage;
262  };
263 
264  inline bool operator==(const Any& lhs, const Any& rhs)
265  {
266  void* lhs_storage = lhs.storage;
267  void* rhs_storage = rhs.storage;
268  return lhs.policy == rhs.policy and
269  lhs.policy->equals(&lhs_storage, &rhs_storage);
270  }
271 
272  inline bool operator!=(const Any& lhs, const Any& rhs)
273  {
274  return !(lhs == rhs);
275  }
276 
278  struct Any::Empty
279  {
281  bool operator==(const Empty& other) const
282  {
283  return true;
284  }
285  };
286 
295  template <typename T>
296  inline Any erase_type(const T& v)
297  {
298  return Any(v);
299  }
300 
309  template <typename T>
310  inline T recall_type(const Any& any)
311  {
312  return any.as<T>();
313  }
314 
315 }
316 
317 #endif //_ANY_H_
virtual void clear(void **storage) const
Definition: any.h:118
friend bool operator!=(const Any &lhs, const Any &rhs)
Definition: any.h:272
bool operator==(const Any &lhs, const Any &rhs)
Definition: any.h:264
virtual bool equals(void **storage, void **other_storage) const =0
~Any()
Definition: any.h:210
virtual bool matches(const std::type_info &ti) const
Definition: any.h:135
Allows to store objects of arbitrary types by using a BaseAnyPolicy and provides a type agnostic API...
Definition: any.h:159
Any()
Definition: any.h:166
T recall_type(const Any &any)
Definition: any.h:310
bool same_type() const
Definition: any.h:234
Any(const T &v)
Definition: any.h:172
bool same_type_fallback() const
Definition: any.h:241
virtual bool matches(const std::type_info &ti) const =0
bool operator!=(const Any &lhs, const Any &rhs)
Definition: any.h:272
Any(const Any &other)
Definition: any.h:178
virtual std::string type() const
Definition: any.h:126
bool operator==(const Empty &other) const
Definition: any.h:281
virtual void set(void **storage, const void *v) const
Definition: any.h:110
Any & operator=(const Any &other)
Definition: any.h:187
An interface for a policy to store a value. Value can be any data like primitive data-types, shogun objects, etc. Policy defines how to handle this data. It works with a provided memory region and is able to set value, clear it and return the type-name as string.
Definition: any.h:66
virtual void clear(void **storage) const =0
all of classes and functions are contained in the shogun namespace
Definition: class_list.h:18
virtual std::string type() const =0
std::string demangledType()
Definition: any.h:50
bool equals(void **storage, void **other_storage) const
Definition: any.h:145
friend bool operator==(const Any &lhs, const Any &rhs)
Definition: any.h:264
T & as() const
Definition: any.h:219
virtual void set(void **storage, const void *v) const =0
bool empty() const
Definition: any.h:247
Any erase_type(const T &v)
Definition: any.h:296
This is one concrete implementation of policy that uses void pointers to store values.
Definition: any.h:103

SHOGUN Machine Learning Toolbox - Documentation