SHOGUN  6.0.0
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 #ifdef HAVE_CXA_DEMANGLE
42 #include <cxxabi.h>
43 #endif
44 
45 namespace shogun
46 {
51  template <typename T>
52  std::string demangledType()
53  {
54 #ifdef HAVE_CXA_DEMANGLE
55  size_t length;
56  int status;
57  char* demangled = abi::__cxa_demangle(typeid(T).name(), nullptr, &length, &status);
58  std::string demangled_string(demangled);
59  free(demangled);
60 #else
61  std::string demangled_string(typeid(T).name());
62 #endif
63  return demangled_string;
64  }
65 
66  enum class PolicyType {
67  OWNING,
69  };
70 
78  {
79  public:
84  virtual void set(void** storage, const void* v) const = 0;
85 
89  virtual void clear(void** storage) const = 0;
90 
94  virtual std::string type() const = 0;
95 
100  virtual bool matches(const std::type_info& ti) const = 0;
101 
107  virtual bool equals(void** storage, void** other_storage) const = 0;
108 
112  virtual std::string policy_name() const = 0;
113 
117  virtual PolicyType policy_type() const = 0;
118  };
119 
123  template <typename T>
125  {
126  public:
131  virtual void set(void** storage, const void* v) const
132  {
133  *(storage) = new T(*reinterpret_cast<T const*>(v));
134  }
135 
139  virtual void clear(void** storage) const
140  {
141  delete reinterpret_cast<T*>(*storage);
142  }
143 
147  virtual std::string type() const
148  {
149  return demangledType<T>();
150  }
151 
156  virtual bool matches(const std::type_info& ti) const
157  {
158  return typeid(T) == ti;
159  }
160 
166  bool equals(void** storage, void** other_storage) const
167  {
168  T typed_storage = *(reinterpret_cast<T*>(*storage));
169  T typed_other_storage = *(reinterpret_cast<T*>(*other_storage));
170  return typed_storage == typed_other_storage;
171  }
172 
173  virtual std::string policy_name() const {
174  return "owning";
175  }
176 
177  virtual PolicyType policy_type() const {
178  return PolicyType::OWNING;
179  }
180  };
181 
182  template <typename T>
184  {
185  public:
190  virtual void set(void** storage, const void* v) const
191  {
192  *(storage) = const_cast<void*>(v);
193  }
194 
198  virtual void clear(void** storage) const
199  {
200  }
201 
205  virtual std::string type() const
206  {
207  return demangledType<T>();
208  }
209 
214  virtual bool matches(const std::type_info& ti) const
215  {
216  return typeid(T) == ti;
217  }
218 
224  bool equals(void** storage, void** other_storage) const
225  {
226  T typed_storage = *(reinterpret_cast<T*>(*storage));
227  T typed_other_storage = *(reinterpret_cast<T*>(*other_storage));
228  return typed_storage == typed_other_storage;
229  }
230 
231  virtual std::string policy_name() const {
232  return "non owning";
233  }
234 
235  virtual PolicyType policy_type() const {
236  return PolicyType::NON_OWNING;
237  }
238  };
239 
240  template <typename T>
242  {
243  typedef PointerValueAnyPolicy<T> Policy;
244  static Policy policy;
245  return &policy;
246  }
247 
248  template <typename T>
250  {
251  typedef NonOwningAnyPolicy<T> Policy;
252  static Policy policy;
253  return &policy;
254  }
255 
262  class Any
263  {
264  public:
266  struct Empty;
267 
269  Any() : Any(owning_policy<Empty>(), nullptr)
270  {
271  }
272 
274  template <typename T>
275  explicit Any(const T& v) : Any(owning_policy<T>(), nullptr)
276  {
277  policy->set(&storage, &v);
278  }
279 
281  Any(BaseAnyPolicy* the_policy, void* the_storage) : policy(the_policy), storage(the_storage)
282  {
283  }
284 
286  Any(const Any& other) : Any(other.policy, nullptr)
287  {
288  assert_same_policy_type(other.policy);
289  policy->set(&storage, other.storage);
290  }
291 
296  Any& operator=(const Any& other)
297  {
298  assert_same_policy_type(other.policy);
299  policy->clear(&storage);
300  policy = other.policy;
301  policy->set(&storage, other.storage);
302  return *(this);
303  }
304 
310  friend inline bool operator==(const Any& lhs, const Any& rhs);
311 
317  friend inline bool operator!=(const Any& lhs, const Any& rhs);
318 
321  {
322  policy->clear(&storage);
323  }
324 
328  template <typename T>
329  T& as() const
330  {
331  if (same_type<T>())
332  {
333  return *(reinterpret_cast<T*>(storage));
334  }
335  else
336  {
337  throw std::logic_error("Bad cast to " + demangledType<T>() +
338  " but the type is " + policy->type());
339  }
340  }
341 
343  template <typename T>
344  inline bool same_type() const
345  {
346  return (policy == owning_policy<T>()) || (policy == non_owning_policy<T>()) || same_type_fallback<T>();
347  }
348 
350  template <typename T>
351  bool same_type_fallback() const
352  {
353  return policy->matches(typeid(T));
354  }
355 
357  bool empty() const
358  {
359  return same_type<Empty>();
360  }
361 
362  private:
363 
364  void assert_same_policy_type(BaseAnyPolicy* other_policy) {
365  if (policy->policy_type() != other_policy->policy_type()) {
366  throw std::logic_error("The policies are different: " +
367  policy->policy_name() + " and " +
368  other_policy->policy_name());
369  }
370  }
371 
372  private:
373  BaseAnyPolicy* policy;
374  void* storage;
375  };
376 
377  inline bool operator==(const Any& lhs, const Any& rhs)
378  {
379  void* lhs_storage = lhs.storage;
380  void* rhs_storage = rhs.storage;
381  return lhs.policy == rhs.policy &&
382  lhs.policy->equals(&lhs_storage, &rhs_storage);
383  }
384 
385  inline bool operator!=(const Any& lhs, const Any& rhs)
386  {
387  return !(lhs == rhs);
388  }
389 
391  struct Any::Empty
392  {
394  bool operator==(const Empty& other) const
395  {
396  return true;
397  }
398  };
399 
408  template <typename T>
409  inline Any erase_type(const T& v)
410  {
411  return Any(v);
412  }
413 
414  template <typename T>
416  {
417  return Any(non_owning_policy<T>(), v);
418  }
419 
428  template <typename T>
429  inline T recall_type(const Any& any)
430  {
431  return any.as<T>();
432  }
433 
434 }
435 
436 #endif //_ANY_H_
virtual PolicyType policy_type() const
Definition: any.h:177
bool same_type_fallback() const
Definition: any.h:351
bool equals(void **storage, void **other_storage) const
Definition: any.h:224
bool operator==(const Any &lhs, const Any &rhs)
Definition: any.h:377
static BaseAnyPolicy * owning_policy()
Definition: any.h:241
PolicyType
Definition: any.h:66
virtual bool equals(void **storage, void **other_storage) const =0
T & as() const
Definition: any.h:329
~Any()
Definition: any.h:320
virtual bool matches(const std::type_info &ti) const
Definition: any.h:214
virtual bool matches(const std::type_info &ti) const
Definition: any.h:156
Allows to store objects of arbitrary types by using a BaseAnyPolicy and provides a type agnostic API...
Definition: any.h:262
Any()
Definition: any.h:269
virtual void clear(void **storage) const
Definition: any.h:198
virtual std::string policy_name() const
Definition: any.h:231
Any erase_type_non_owning(T *v)
Definition: any.h:415
bool operator==(const Empty &other) const
Definition: any.h:394
virtual std::string type() const
Definition: any.h:147
T recall_type(const Any &any)
Definition: any.h:429
bool same_type() const
Definition: any.h:344
bool empty() const
Definition: any.h:357
bool equals(void **storage, void **other_storage) const
Definition: any.h:166
static BaseAnyPolicy * non_owning_policy()
Definition: any.h:249
Any(const T &v)
Definition: any.h:275
virtual std::string policy_name() const =0
bool operator!=(const Any &lhs, const Any &rhs)
Definition: any.h:385
virtual void clear(void **storage) const
Definition: any.h:139
virtual PolicyType policy_type() const =0
Any(const Any &other)
Definition: any.h:286
virtual PolicyType policy_type() const
Definition: any.h:235
virtual std::string policy_name() const
Definition: any.h:173
Any & operator=(const Any &other)
Definition: any.h:296
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:77
all of classes and functions are contained in the shogun namespace
Definition: class_list.h:18
std::string demangledType()
Definition: any.h:52
virtual std::string type() const
Definition: any.h:205
Any(BaseAnyPolicy *the_policy, void *the_storage)
Definition: any.h:281
virtual void set(void **storage, const void *v) const =0
Any erase_type(const T &v)
Definition: any.h:409
This is one concrete implementation of policy that uses void pointers to store values.
Definition: any.h:124

SHOGUN Machine Learning Toolbox - Documentation