libqi-api  release-2.5.3-2016-11-18
 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 
10 namespace qi
11 {
12 
13 namespace detail
14 {
15 
17 {
18  AnyReference res;
19  res._type = _type;
20  res._value = _type ? res._type->clone(_value) : 0;
21  return res;
22 }
23 
24 inline qi::Signature AnyReferenceBase::signature(bool resolveDynamic) const
25 {
26  if (!_type)
27  return qi::Signature();
28  else
29  return _type->signature(_value, resolveDynamic);
30 }
31 
33 {
34  if (_type)
36  _value = _type = 0;
37 }
38 
40  : _type(0)
41  , _value(0)
42 {
43 }
44 
46  : _type(type)
47  , _value(type->initializeStorage())
48 {
49 }
50 
51 template<typename T>
53 {
54  static TypeInterface* t = 0;
55  if (!t)
56  t = typeOf<typename boost::remove_const<T>::type>();
57  void *value = t->initializeStorage(const_cast<void*>((const void*)ptr));
58  return AnyReference(t, value);
59 }
60 
61 template<typename T>
63 {
64  AnyReference ref;
65  static TypeInterface* t = 0;
66  QI_ONCE( t = typeOf<typename boost::remove_const<T>::type>());
67  return AnyReference(t, t->initializeStorage(const_cast<void*>((const void*)&ptr)));
68 }
69 
71 {
72  if (!_type)
73  throw std::runtime_error("Can't take the kind of an invalid value");
74  else
75  return _type->kind();
76 }
77 
79 {
80  AnyReference res = *this;
81  while (res.kind() == TypeKind_Dynamic)
82  {
83  res = res.content();
84  }
85  return res;
86 }
87 
88 template<TypeKind T> struct TypeOfKind {};
89 
90 #define TYPE_OF_KIND(k, t) template<> struct TypeOfKind<k> { using type = t;}
91 // Kind -> handler Type (IntTypeInterface, ListTypeInterface...) accessor
95 #undef TYPE_OF_KIND
96 
97 // Optimized AnyReferenceBase::as<T> for direct access to a subType getter
98 template<typename T, TypeKind k>
99 inline T valueAs(const AnyReferenceBase& v)
100 {
101  if (v.kind() == k)
102  return static_cast<T>(
103  static_cast<typename TypeOfKind<k>::type*>(v.type())
104  ->get(v.rawValue()));
105  // Fallback to default which will attempt a full conversion.
106  return v.to<T>();
107 }
108 
109 template<typename T>
110 inline T* AnyReferenceBase::ptr(bool check)
111 {
112  if (!_type || (check && typeOf<T>()->info() != _type->info()))
113  return 0;
114  else
115  return (T*)_type->ptrFromStorage(&_value);
116 }
117 
118 template<typename T>
120 {
121  T* p = ptr<T>(true);
122  if (!p)
123  throw std::runtime_error("Type mismatch");
124  return *p;
125 }
126 
127 template<typename T>
128 inline T AnyReferenceBase::to(const T&) const
129 {
130  return to<T>();
131 }
132 
134  TypeInterface* from, TypeInterface* to, const std::string& additionalMsg);
135 
136 template<typename T>
137 inline T AnyReferenceBase::to() const
138 {
139  TypeInterface* targetType = typeOf<T>();
140  std::pair<AnyReference, bool> conv = convert(targetType);
141  if (!conv.first._type)
142  {
143  throwConversionFailure(_type, targetType, ""); // no additional message
144  }
145  T result = *conv.first.ptr<T>(false);
146  if (conv.second)
147  conv.first.destroy();
148  return result;
149 }
150 
151 template<>
152 inline void AnyReferenceBase::to<void>() const
153 {
154  return;
155 }
156 
157 inline bool AnyReferenceBase::isValid() const
158 {
159  return _type != 0;
160 }
161 
162 inline bool AnyReferenceBase::isValue() const
163 {
164  return _type != 0 && _type->info() != typeOf<void>()->info();
165 }
166 
168 {
169  return detail::valueAs<int64_t, TypeKind_Int>(*this);
170 }
171 
173 {
174  return detail::valueAs<uint64_t, TypeKind_Int>(*this);
175 }
176 
177 inline float AnyReferenceBase::toFloat() const
178 {
179  return detail::valueAs<float, TypeKind_Float>(*this);
180 }
181 
182 inline double AnyReferenceBase::toDouble() const
183 {
184  return detail::valueAs<double, TypeKind_Float>(*this);
185 }
186 
187 inline std::string AnyReferenceBase::toString() const
188 {
189  return to<std::string>();
190 }
191 
192 template<typename T>
193 inline std::vector<T> AnyReferenceBase::toList() const
194 {
195  return to<std::vector<T> >();
196 }
197 
198 template<typename K, typename V>
199 inline std::map<K, V> AnyReferenceBase::toMap() const
200 {
201  return to<std::map<K, V> >();
202 }
203 
205 {
206  return asTupleValuePtr();
207 }
208 
209 template<typename T>
210 void AnyReferenceBase::set(const T& v)
211 {
213  }
214 
215 inline void AnyReferenceBase::setFloat(float v)
216 {
217  setDouble(static_cast<double>(v));
218 }
219 
220 template<typename E, typename K>
222 {
223  return (*this)[key].template as<E>();
224 }
225 
226 template<typename K>
228 {
229  return operator[](AnyReferenceBase::from(key));
230 }
231 
233 {
234  return _element(key, true, true);
235 }
236 
237 template<typename K>
239 {
240  // note that this implementation is currently not very useful
241  // (it does the same thing as the const version) and could be removed.
242  // In the future, AnyReferenceConst should be implemented to
243  // make the distinction between the two, and in this case
244  // this version of the function will have a real meaning.
245  return at(AnyReferenceBase::from(key));
246 }
247 
248 template<typename K>
250 {
251  return at(AnyReferenceBase::from(key));
252 }
253 
255 {
256  return _element(key, false, false);
257 }
258 
260 {
261  return const_cast<AnyReferenceBase*>(this)->at(key);
262 }
263 
264 template<typename T>
265 void AnyReferenceBase::append(const T& element)
266 {
267  append(AnyReference::from(element));
268 }
269 
270 template<typename K, typename V>
271 void AnyReferenceBase::insert(const K& key, const V& val)
272 {
274 }
275 
276 template<typename K>
278 {
279  return _element(AnyReference::from(key), false, false);
280 }
281 
282 } // namespace detail
283 
284 inline bool operator != (const AnyReference& a, const AnyReference& b)
285 {
286  return !(a==b);
287 }
288 
289 } // namespace qi
290 
291 #endif
virtual void * ptrFromStorage(void **)=0
std::pair< AnyReference, bool > convert(TypeInterface *targetType) const
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:66
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
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:317
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:53
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:154
AnyReference operator[](const K &key)
uint64_t uint64_t
Definition: types.hpp:66
void append(const T &element)
virtual void * initializeStorage(void *ptr=0)=0
AnyReference unwrap() const
qi::Signature signature(void *storage=0, bool resolveDynamic=false)