libqi-api  2.8.7.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
anyreference.hxx
Go to the documentation of this file.
1 #pragma once
2 /*
3 ** Copyright (C) 2013 Aldebaran Robotics
4 ** See COPYING for the license
5 */
6 
7 #ifndef _QI_TYPE_DETAIL_ANYREFERENCE_HXX_
8 #define _QI_TYPE_DETAIL_ANYREFERENCE_HXX_
9 
11 
12 namespace qi
13 {
14 
15 namespace detail
16 {
17 
19 {
20  AnyReference res;
21  res._type = _type;
22  res._value = _type ? res._type->clone(_value) : 0;
23  return res;
24 }
25 
26 inline qi::Signature AnyReferenceBase::signature(bool resolveDynamic) const
27 {
28  if (!_type)
29  return qi::Signature();
30  else
31  return _type->signature(_value, resolveDynamic);
32 }
33 
35 {
36  if (_type)
38  _value = _type = 0;
39 }
40 
42  : _type(0)
43  , _value(0)
44 {
45 }
46 
48  : _type(type)
49  , _value(type->initializeStorage())
50 {
51 }
52 
53 template<typename T>
55 {
56  static TypeInterface* t = 0;
57  if (!t)
58  t = typeOf<typename boost::remove_const<T>::type>();
59  void *value = t->initializeStorage(const_cast<void*>((const void*)ptr));
60  return AnyReference(t, value);
61 }
62 
63 template<typename T>
65 {
66  static TypeInterface* t = 0;
67  QI_ONCE( t = typeOf<typename boost::remove_const<T>::type>());
68  return AnyReference(t, t->initializeStorage(const_cast<void*>((const void*)&value)));
69 }
70 
72 {
73  if (!_type)
74  throw std::runtime_error("Can't take the kind of an invalid value");
75  else
76  return _type->kind();
77 }
78 
80 {
81  AnyReference res = *this;
82  while (res.isValid() && res.kind() == TypeKind_Dynamic)
83  {
84  res = res.content();
85  }
86  return res;
87 }
88 
89 template<TypeKind T> struct TypeOfKind {};
90 
91 #define TYPE_OF_KIND(k, t) template<> struct TypeOfKind<k> { using type = t;}
92 // Kind -> handler Type (IntTypeInterface, ListTypeInterface...) accessor
96 #undef TYPE_OF_KIND
97 
98 // Optimized AnyReferenceBase::as<T> for direct access to a subType getter
99 template<typename T, TypeKind k>
100 inline T valueAs(const AnyReferenceBase& v)
101 {
102  if (v.kind() == k)
103  return static_cast<T>(
104  static_cast<typename TypeOfKind<k>::type*>(v.type())
105  ->get(v.rawValue()));
106  // Fallback to default which will attempt a full conversion.
107  return v.to<T>();
108 }
109 
110 template<typename T>
111 inline T* AnyReferenceBase::ptr(bool check)
112 {
113  if (!_type || (check && typeOf<T>()->info() != _type->info()))
114  return 0;
115  else
116  return (T*)_type->ptrFromStorage(&_value);
117 }
118 
119 template<typename T>
121 {
122  T* p = ptr<T>(true);
123  if (!p)
124  throw std::runtime_error("Type mismatch");
125  return *p;
126 }
127 
128 template<typename T>
129 inline T AnyReferenceBase::to(const T&) const
130 {
131  return to<T>();
132 }
133 
135  TypeInterface* from, TypeInterface* to, const std::string& additionalMsg);
136 
137 template<typename T>
138 inline T AnyReferenceBase::to() const
139 {
140  TypeInterface* targetType = typeOf<T>();
141  auto conv = convert(targetType);
142  if (!conv->_type)
143  {
144  throwConversionFailure(_type, targetType, ""); // no additional message
145  }
146  T result = *conv->ptr<T>(false);
147  return result;
148 }
149 
150 template<>
151 inline void AnyReferenceBase::to<void>() const
152 {
153  return;
154 }
155 
156 inline bool AnyReferenceBase::isValid() const
157 {
158  return _type != 0;
159 }
160 
161 inline bool AnyReferenceBase::isValue() const
162 {
163  return _type != 0 && _type->info() != typeOf<void>()->info();
164 }
165 
167 {
168  return detail::valueAs<int64_t, TypeKind_Int>(*this);
169 }
170 
172 {
173  return detail::valueAs<uint64_t, TypeKind_Int>(*this);
174 }
175 
176 inline float AnyReferenceBase::toFloat() const
177 {
178  return detail::valueAs<float, TypeKind_Float>(*this);
179 }
180 
181 inline double AnyReferenceBase::toDouble() const
182 {
183  return detail::valueAs<double, TypeKind_Float>(*this);
184 }
185 
186 inline std::string AnyReferenceBase::toString() const
187 {
188  return to<std::string>();
189 }
190 
191 template<typename T>
192 inline std::vector<T> AnyReferenceBase::toList() const
193 {
194  return to<std::vector<T> >();
195 }
196 
197 template<typename K, typename V>
198 inline std::map<K, V> AnyReferenceBase::toMap() const
199 {
200  return to<std::map<K, V> >();
201 }
202 
203 template <typename T>
204 inline boost::optional<T> AnyReferenceBase::toOptional() const
205 {
206  return to<boost::optional<T>>();
207 }
208 
210 {
211  return asTupleValuePtr();
212 }
213 
214 template<typename T>
215 void AnyReferenceBase::set(const T& v)
216 {
218 }
219 
220 inline void AnyReferenceBase::setFloat(float v)
221 {
222  setDouble(static_cast<double>(v));
223 }
224 
225 template<typename E, typename K>
227 {
228  return (*this)[key].template as<E>();
229 }
230 
231 template<typename K>
233 {
234  return operator[](AnyReferenceBase::from(key));
235 }
236 
238 {
239  return _element(key, true, true);
240 }
241 
242 template<typename K>
244 {
245  // note that this implementation is currently not very useful
246  // (it does the same thing as the const version) and could be removed.
247  // In the future, AnyReferenceConst should be implemented to
248  // make the distinction between the two, and in this case
249  // this version of the function will have a real meaning.
250  return at(AnyReferenceBase::from(key));
251 }
252 
253 template<typename K>
255 {
256  return at(AnyReferenceBase::from(key));
257 }
258 
260 {
261  return _element(key, false, false);
262 }
263 
265 {
266  return const_cast<AnyReferenceBase*>(this)->at(key);
267 }
268 
269 template<typename T>
270 void AnyReferenceBase::append(const T& element)
271 {
272  append(AnyReference::from(element));
273 }
274 
275 template<typename K, typename V>
276 void AnyReferenceBase::insert(const K& key, const V& val)
277 {
279 }
280 
281 template<typename K>
283 {
284  return _element(AnyReference::from(key), false, false);
285 }
286 
287 } // namespace detail
288 
289 inline bool operator != (const AnyReference& a, const AnyReference& b)
290 {
291  return !(a==b);
292 }
293 
294 } // namespace qi
295 
296 #endif
virtual void * ptrFromStorage(void **)=0
int64_t int64_t
Definition: types.hpp:61
void update(const AutoAnyReference &b)
#define QI_API
Definition: api.hpp:33
T * ptr(bool check=true)
#define QI_NORETURN
Portable noreturn attribute, used to declare that a function does not return.
Definition: macro.hpp:68
UniqueAnyReference convert(TypeInterface *targetType) const
QI_NORETURN void throwConversionFailure(TypeInterface *from, TypeInterface *to, const std::string &additionalMsg)
E & element(const K &key)
Call operator[](key).as<E>, element type must match E.
AnyReferenceVector asTupleValuePtr()
AnyReference find(const K &key)
virtual TypeKind kind()
Definition: type.hxx:99
AnyReferenceBase()
Constructs an invalid reference, pointing to nothing.
qi::Signature signature(void *storage=nullptr, bool resolveDynamic=false)
virtual void * initializeStorage(void *ptr=nullptr)=0
AnyReference _element(const AnyReference &key, bool throwOnFailure, bool autoInsert)
void insert(const K &key, const V &val)
T valueAs(const AnyReferenceBase &v)
AnyReference at(const K &key)
void destroy()
Deletes storage.
T to() const
Convert to anything or throw trying.
qi::Signature signature(bool resolveDynamic=false) const
std::vector< AnyReference > AnyReferenceVector
std::string toString() const
TypeInterface * type() const
AnyReferenceVector asListValuePtr()
std::map< K, V > toMap() const
virtual void destroy(void *)=0
Free all resources of a storage.
#define QI_ONCE(code)
Execute code once, parallel calls are blocked until code finishes.
Definition: atomic.hpp:420
virtual const TypeInfo & info()=0
Get the TypeInfo corresponding to this type.
AnyReference content() const
TypeInterface * typeOf()
Definition: type.hxx:94
AnyReference clone() const
void set(const T &val)
Update the value to val, which will be converted if required.
TypeKind
Definition: fwd.hpp:54
std::vector< T > toList() const
#define TYPE_OF_KIND(k, t)
static AnyReference from(const T &ref)
static AnyReference fromPtr(const T *ptr)
virtual void * clone(void *)=0
Allocate a storage and copy the value given as an argument.
bool operator!=(const Signature &lhs, const Signature &rhs)
Definition: signature.hpp:157
AnyReference operator[](const K &key)
boost::optional< T > toOptional() const
uint64_t uint64_t
Definition: types.hpp:66
void append(const T &element)
AnyReference unwrap() const