SHOGUN  6.1.3
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 <stdexcept>
39 #include <string>
40 #include <string.h>
41 #include <typeinfo>
42 #ifdef HAVE_CXA_DEMANGLE
43 #include <cxxabi.h>
44 #endif
45 
46 namespace shogun
47 {
52  template <typename T>
53  std::string demangledType()
54  {
55 #ifdef HAVE_CXA_DEMANGLE
56  size_t length;
57  int status;
58  char* demangled =
59  abi::__cxa_demangle(typeid(T).name(), nullptr, &length, &status);
60  std::string demangled_string(demangled);
61  free(demangled);
62 #else
63  std::string demangled_string(typeid(T).name());
64 #endif
65  return demangled_string;
66  }
67 
68  enum class PolicyType
69  {
70  OWNING,
72  };
73 
81  {
82  public:
87  virtual void set(void** storage, const void* v) const = 0;
88 
92  virtual void clear(void** storage) const = 0;
93 
97  virtual std::string type() const = 0;
98 
102  virtual const std::type_info& type_info() const = 0;
103 
108  virtual bool matches(const std::type_info& ti) const = 0;
109 
115  virtual bool equals(void** storage, void** other_storage) const = 0;
116 
120  virtual std::string policy_name() const = 0;
121 
125  virtual PolicyType policy_type() const = 0;
126  };
127 
131  template <typename T>
133  {
134  public:
139  virtual void set(void** storage, const void* v) const
140  {
141  *(storage) = new T(*reinterpret_cast<T const*>(v));
142  }
143 
147  virtual void clear(void** storage) const
148  {
149  delete reinterpret_cast<T*>(*storage);
150  }
151 
155  virtual std::string type() const
156  {
157  return demangledType<T>();
158  }
159 
163  virtual const std::type_info& type_info() const
164  {
165  return typeid(T);
166  }
167 
172  virtual bool matches(const std::type_info& ti) const
173  {
174  return typeid(T) == ti;
175  }
176 
182  bool equals(void** storage, void** other_storage) const
183  {
184  T typed_storage = *(reinterpret_cast<T*>(*storage));
185  T typed_other_storage = *(reinterpret_cast<T*>(*other_storage));
186  return typed_storage == typed_other_storage;
187  }
188 
189  virtual std::string policy_name() const
190  {
191  return "owning";
192  }
193 
194  virtual PolicyType policy_type() const
195  {
196  return PolicyType::OWNING;
197  }
198  };
199 
200  template <typename T>
202  {
203  public:
208  virtual void set(void** storage, const void* v) const
209  {
210  *(storage) = const_cast<void*>(v);
211  }
212 
216  virtual void clear(void** storage) const
217  {
218  }
219 
223  virtual std::string type() const
224  {
225  return demangledType<T>();
226  }
227 
231  virtual const std::type_info& type_info() const
232  {
233  return typeid(T);
234  }
235 
240  virtual bool matches(const std::type_info& ti) const
241  {
242  return typeid(T) == ti;
243  }
244 
250  bool equals(void** storage, void** other_storage) const
251  {
252  T typed_storage = *(reinterpret_cast<T*>(*storage));
253  T typed_other_storage = *(reinterpret_cast<T*>(*other_storage));
254  return typed_storage == typed_other_storage;
255  }
256 
257  virtual std::string policy_name() const
258  {
259  return "non owning";
260  }
261 
262  virtual PolicyType policy_type() const
263  {
264  return PolicyType::NON_OWNING;
265  }
266  };
267 
268  template <typename T>
270  {
271  typedef PointerValueAnyPolicy<T> Policy;
272  static Policy policy;
273  return &policy;
274  }
275 
276  template <typename T>
278  {
279  typedef NonOwningAnyPolicy<T> Policy;
280  static Policy policy;
281  return &policy;
282  }
283 
290  class Any
291  {
292  public:
294  struct Empty;
295 
297  Any() : Any(owning_policy<Empty>(), nullptr)
298  {
299  }
300 
302  template <typename T>
303  explicit Any(const T& v) : Any(owning_policy<T>(), nullptr)
304  {
305  policy->set(&storage, &v);
306  }
307 
309  Any(BaseAnyPolicy* the_policy, void* the_storage)
310  : policy(the_policy), storage(the_storage)
311  {
312  }
313 
315  Any(const Any& other) : Any(other.policy, nullptr)
316  {
317  assert_same_policy_type(other.policy);
318  policy->set(&storage, other.storage);
319  }
320 
325  Any& operator=(const Any& other)
326  {
327  assert_same_policy_type(other.policy);
328  policy->clear(&storage);
329  policy = other.policy;
330  policy->set(&storage, other.storage);
331  return *(this);
332  }
333 
339  friend inline bool operator==(const Any& lhs, const Any& rhs);
340 
346  friend inline bool operator!=(const Any& lhs, const Any& rhs);
347 
350  {
351  policy->clear(&storage);
352  }
353 
357  template <typename T>
358  T& as() const
359  {
360  if (same_type<T>())
361  {
362  return *(reinterpret_cast<T*>(storage));
363  }
364  else
365  {
366  throw std::logic_error(
367  "Bad cast to " + demangledType<T>() + " but the type is " +
368  policy->type());
369  }
370  }
371 
373  template <typename T>
374  inline bool same_type() const
375  {
376  return (policy == owning_policy<T>()) ||
377  (policy == non_owning_policy<T>()) ||
378  same_type_fallback<T>();
379  }
380 
382  template <typename T>
383  bool same_type_fallback() const
384  {
385  return policy->matches(typeid(T));
386  }
387 
389  bool empty() const
390  {
391  return same_type<Empty>();
392  }
393 
394  const std::type_info& type_info() const
395  {
396  return policy->type_info();
397  }
398 
399  private:
400  void assert_same_policy_type(BaseAnyPolicy* other_policy)
401  {
402  if (policy->policy_type() != other_policy->policy_type())
403  {
404  throw std::logic_error(
405  "The policies are different: " + policy->policy_name() +
406  " and " + other_policy->policy_name());
407  }
408  }
409 
410  private:
411  BaseAnyPolicy* policy;
412  void* storage;
413  };
414 
415  inline bool operator==(const Any& lhs, const Any& rhs)
416  {
417  void* lhs_storage = lhs.storage;
418  void* rhs_storage = rhs.storage;
419  return lhs.policy == rhs.policy &&
420  lhs.policy->equals(&lhs_storage, &rhs_storage);
421  }
422 
423  inline bool operator!=(const Any& lhs, const Any& rhs)
424  {
425  return !(lhs == rhs);
426  }
427 
429  struct Any::Empty
430  {
432  bool operator==(const Empty& other) const
433  {
434  return true;
435  }
436  };
437 
446  template <typename T>
447  inline Any erase_type(const T& v)
448  {
449  return Any(v);
450  }
451 
452  template <typename T>
454  {
455  return Any(non_owning_policy<T>(), v);
456  }
457 
466  template <typename T>
467  inline T recall_type(const Any& any)
468  {
469  return any.as<T>();
470  }
471 }
472 
473 #endif //_ANY_H_
virtual PolicyType policy_type() const
Definition: any.h:194
virtual void clear(void **storage) const
Definition: any.h:147
virtual void clear(void **storage) const
Definition: any.h:216
bool operator==(const Any &lhs, const Any &rhs)
Definition: any.h:415
static BaseAnyPolicy * owning_policy()
Definition: any.h:269
PolicyType
Definition: any.h:68
virtual bool equals(void **storage, void **other_storage) const =0
virtual PolicyType policy_type() const
Definition: any.h:262
virtual std::string policy_name() const
Definition: any.h:257
~Any()
Definition: any.h:349
virtual const std::type_info & type_info() const
Definition: any.h:163
virtual bool matches(const std::type_info &ti) const
Definition: any.h:172
Allows to store objects of arbitrary types by using a BaseAnyPolicy and provides a type agnostic API...
Definition: any.h:290
Any()
Definition: any.h:297
Any erase_type_non_owning(T *v)
Definition: any.h:453
T recall_type(const Any &any)
Definition: any.h:467
bool same_type() const
Definition: any.h:374
virtual const std::type_info & type_info() const
Definition: any.h:231
static BaseAnyPolicy * non_owning_policy()
Definition: any.h:277
Any(const T &v)
Definition: any.h:303
virtual std::string policy_name() const =0
bool same_type_fallback() const
Definition: any.h:383
bool operator!=(const Any &lhs, const Any &rhs)
Definition: any.h:423
virtual PolicyType policy_type() const =0
const std::type_info & type_info() const
Definition: any.h:394
Any(const Any &other)
Definition: any.h:315
virtual std::string type() const
Definition: any.h:155
virtual std::string type() const
Definition: any.h:223
bool operator==(const Empty &other) const
Definition: any.h:432
Any & operator=(const Any &other)
Definition: any.h:325
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:80
all of classes and functions are contained in the shogun namespace
Definition: class_list.h:18
bool equals(void **storage, void **other_storage) const
Definition: any.h:250
virtual bool matches(const std::type_info &ti) const
Definition: any.h:240
std::string demangledType()
Definition: any.h:53
bool equals(void **storage, void **other_storage) const
Definition: any.h:182
T & as() const
Definition: any.h:358
Any(BaseAnyPolicy *the_policy, void *the_storage)
Definition: any.h:309
virtual void set(void **storage, const void *v) const =0
bool empty() const
Definition: any.h:389
Any erase_type(const T &v)
Definition: any.h:447
virtual std::string policy_name() const
Definition: any.h:189
This is one concrete implementation of policy that uses void pointers to store values.
Definition: any.h:132

SHOGUN Machine Learning Toolbox - Documentation