safe_any.hpp
Go to the documentation of this file.
1 #ifndef SAFE_ANY_VARNUMBER_H
2 #define SAFE_ANY_VARNUMBER_H
3 
4 #include <exception>
5 #include <algorithm>
6 #include <iostream>
7 #include <chrono>
8 #include <string>
9 #include <cstring>
10 #include <type_traits>
11 #include "any.hpp"
12 #include "demangle_util.h"
13 #include "convert_impl.hpp"
14 
15 namespace SafeAny
16 {
17 // Rational: since type erased numbers will always use at least 8 bytes
18 // it is faster to cast everything to either double, uint64_t or int64_t.
19 class Any
20 {
21  template <typename T>
22  using EnableIntegral =
23  typename std::enable_if<std::is_integral<T>::value || std::is_enum<T>::value>::type*;
24 
25  template <typename T>
26  using EnableNonIntegral =
27  typename std::enable_if<!std::is_integral<T>::value && !std::is_enum<T>::value>::type*;
28 
29  template <typename T>
30  using EnableString = typename std::enable_if<std::is_same<T, std::string>::value>::type*;
31 
32  template <typename T>
33  using EnableArithmetic = typename std::enable_if<std::is_arithmetic<T>::value>::type*;
34 
35  template <typename T>
36  using EnableEnum = typename std::enable_if<std::is_enum<T>::value>::type*;
37 
38  template <typename T>
39  using EnableUnknownType =
40  typename std::enable_if<!std::is_arithmetic<T>::value && !std::is_enum<T>::value &&
41  !std::is_same<T, std::string>::value>::type*;
42 
43  public:
44  Any()
45  {
46  }
47 
48  ~Any() = default;
49 
50  Any(const double& value) : _any(value)
51  {
52  }
53 
54  Any(const uint64_t& value) : _any(value)
55  {
56  }
57 
58  Any(const float& value) : _any(double(value))
59  {
60  }
61 
62  Any(const std::string& str) : _any(SimpleString(str))
63  {
64  }
65 
66  // all the other integrals are casted to int64_t
67  template <typename T>
68  explicit Any(const T& value, EnableIntegral<T> = 0) : _any(int64_t(value))
69  {
70  }
71 
72  // default for other custom types
73  template <typename T>
74  explicit Any(const T& value, EnableNonIntegral<T> = 0) : _any(value)
75  {
76  }
77 
78  // this is different from any_cast, because if allows safe
79  // conversions between arithmetic values.
80  template <typename T>
81  T cast() const
82  {
83  if (_any.type() == typeid(T))
84  {
85  return linb::any_cast<T>(_any);
86  }
87  else
88  {
89  return convert<T>();
90  }
91  }
92 
93  const std::type_info& type() const noexcept
94  {
95  return _any.type();
96  }
97 
98  private:
100 
101  //----------------------------
102 
103  template <typename DST>
104  DST convert(EnableString<DST> = 0) const
105  {
106  const auto& type = _any.type();
107 
108  if (type == typeid(SimpleString))
109  {
110  return linb::any_cast<SimpleString>(_any).toStdString();
111  }
112  else if (type == typeid(int64_t))
113  {
114  return std::to_string(linb::any_cast<int64_t>(_any));
115  }
116  else if (type == typeid(uint64_t))
117  {
118  return std::to_string(linb::any_cast<uint64_t>(_any));
119  }
120  else if (type == typeid(double))
121  {
122  return std::to_string(linb::any_cast<double>(_any));
123  }
124 
125  throw errorMsg<DST>();
126  }
127 
128  template <typename DST>
130  {
131  using details::convertNumber;
132  DST out;
133 
134  const auto& type = _any.type();
135 
136  if (type == typeid(int64_t))
137  {
138  convertNumber<int64_t, DST>(linb::any_cast<int64_t>(_any), out);
139  }
140  else if (type == typeid(uint64_t))
141  {
142  convertNumber<uint64_t, DST>(linb::any_cast<uint64_t>(_any), out);
143  }
144  else if (type == typeid(double))
145  {
146  convertNumber<double, DST>(linb::any_cast<double>(_any), out);
147  }
148  else
149  {
150  throw errorMsg<DST>();
151  }
152  return out;
153  }
154 
155  template <typename DST>
156  DST convert(EnableEnum<DST> = 0) const
157  {
158  using details::convertNumber;
159 
160  const auto& type = _any.type();
161 
162  if (type == typeid(int64_t))
163  {
164  uint64_t out = linb::any_cast<int64_t>(_any);
165  return static_cast<DST>(out);
166  }
167  else if (type == typeid(uint64_t))
168  {
169  uint64_t out = linb::any_cast<uint64_t>(_any);
170  return static_cast<DST>(out);
171  }
172 
173  throw errorMsg<DST>();
174  }
175 
176  template <typename DST>
178  {
179  throw errorMsg<DST>();
180  }
181 
182  template <typename T>
183  std::runtime_error errorMsg() const
184  {
185  char buffer[1024];
186  sprintf(buffer, "[Any::convert]: no known safe conversion between %s and %s",
187  BT::demangle( _any.type().name() ).c_str(),
188  BT::demangle( typeid(T).name() ).c_str() );
189  return std::runtime_error(buffer);
190  }
191 };
192 
193 } // end namespace VarNumber
194 
195 #endif // VARNUMBER_H
typename std::enable_if< std::is_integral< T >::value||std::is_enum< T >::value >::type * EnableIntegral
Definition: safe_any.hpp:23
std::runtime_error errorMsg() const
Definition: safe_any.hpp:183
Any(const float &value)
Definition: safe_any.hpp:58
static raw_event_t * buffer
Definition: minitrace.cpp:54
~Any()=default
Any(const T &value, EnableIntegral< T >=0)
Definition: safe_any.hpp:68
ValueType any_cast(const any &operand)
Performs *any_cast<add_const_t<remove_reference_t<ValueType>>>(&operand), or throws bad_any_cast on f...
Definition: any.hpp:386
Any(const std::string &str)
Definition: safe_any.hpp:62
typename std::enable_if< std::is_arithmetic< T >::value >::type * EnableArithmetic
Definition: safe_any.hpp:33
const std::type_info & type() const noexcept
Definition: safe_any.hpp:93
Any(const T &value, EnableNonIntegral< T >=0)
Definition: safe_any.hpp:74
DST convert(EnableEnum< DST >=0) const
Definition: safe_any.hpp:156
std::string demangle(char const *name)
Definition: demangle_util.h:92
typename std::enable_if<!std::is_arithmetic< T >::value &&!std::is_enum< T >::value &&!std::is_same< T, std::string >::value >::type * EnableUnknownType
Definition: safe_any.hpp:41
Any(const double &value)
Definition: safe_any.hpp:50
linb::any _any
Definition: safe_any.hpp:99
Any(const uint64_t &value)
Definition: safe_any.hpp:54
DST convert(EnableString< DST >=0) const
Definition: safe_any.hpp:104
const std::type_info & type() const noexcept
If *this has a contained object of type T, typeid(T); otherwise typeid(void).
Definition: any.hpp:129
DST convert(EnableUnknownType< DST >=0) const
Definition: safe_any.hpp:177
T cast() const
Definition: safe_any.hpp:81
typename std::enable_if<!std::is_integral< T >::value &&!std::is_enum< T >::value >::type * EnableNonIntegral
Definition: safe_any.hpp:27
typename std::enable_if< std::is_enum< T >::value >::type * EnableEnum
Definition: safe_any.hpp:36
DST convert(EnableArithmetic< DST >=0) const
Definition: safe_any.hpp:129
std::basic_string< CharT, Traits > to_string(basic_string_view< CharT, Traits > v)
typename std::enable_if< std::is_same< T, std::string >::value >::type * EnableString
Definition: safe_any.hpp:30


behaviortree_cpp
Author(s): Michele Colledanchise, Davide Faconti
autogenerated on Sun Feb 3 2019 03:14:32