libqi-api  2.4.3.28
 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 
78 template<TypeKind T> struct TypeOfKind {};
79 
80 #define TYPE_OF_KIND(k, t) template<> struct TypeOfKind<k> { typedef t type;}
81 // Kind -> handler Type (IntTypeInterface, ListTypeInterface...) accessor
85 #undef TYPE_OF_KIND
86 
87 // Optimized AnyReferenceBase::as<T> for direct access to a subType getter
88 template<typename T, TypeKind k>
89 inline T valueAs(const AnyReferenceBase& v)
90 {
91  if (v.kind() == k)
92  return static_cast<T>(
93  static_cast<typename TypeOfKind<k>::type*>(v.type())
94  ->get(v.rawValue()));
95  // Fallback to default which will attempt a full conversion.
96  return v.to<T>();
97 }
98 
99 template<typename T>
100 inline T* AnyReferenceBase::ptr(bool check)
101 {
102  if (!_type || (check && typeOf<T>()->info() != _type->info()))
103  return 0;
104  else
105  return (T*)_type->ptrFromStorage(&_value);
106 }
107 
108 template<typename T>
110 {
111  T* p = ptr<T>(true);
112  if (!p)
113  throw std::runtime_error("Type mismatch");
114  return *p;
115 }
116 
117 template<typename T>
118 inline T AnyReferenceBase::to(const T&) const
119 {
120  return to<T>();
121 }
122 
124  TypeInterface* from, TypeInterface* to);
125 
126 template<typename T>
127 inline T AnyReferenceBase::to() const
128 {
129  TypeInterface* targetType = typeOf<T>();
130  std::pair<AnyReference, bool> conv = convert(targetType);
131  if (!conv.first._type)
132  {
133  throwConversionFailure(_type, targetType);
134  }
135  T result = *conv.first.ptr<T>(false);
136  if (conv.second)
137  conv.first.destroy();
138  return result;
139 }
140 
141 template<>
142 inline void AnyReferenceBase::to<void>() const
143 {
144  return;
145 }
146 
147 inline bool AnyReferenceBase::isValid() const
148 {
149  return _type != 0;
150 }
151 
152 inline bool AnyReferenceBase::isValue() const
153 {
154  return _type != 0 && _type->info() != typeOf<void>()->info();
155 }
156 
158 {
159  return detail::valueAs<int64_t, TypeKind_Int>(*this);
160 }
161 
163 {
164  return detail::valueAs<uint64_t, TypeKind_Int>(*this);
165 }
166 
167 inline float AnyReferenceBase::toFloat() const
168 {
169  return detail::valueAs<float, TypeKind_Float>(*this);
170 }
171 
172 inline double AnyReferenceBase::toDouble() const
173 {
174  return detail::valueAs<double, TypeKind_Float>(*this);
175 }
176 
177 inline std::string AnyReferenceBase::toString() const
178 {
179  return to<std::string>();
180 }
181 
182 template<typename T>
183 inline std::vector<T> AnyReferenceBase::toList() const
184 {
185  return to<std::vector<T> >();
186 }
187 
188 template<typename K, typename V>
189 inline std::map<K, V> AnyReferenceBase::toMap() const
190 {
191  return to<std::map<K, V> >();
192 }
193 
195 {
196  return asTupleValuePtr();
197 }
198 
199 template<typename T>
200 void AnyReferenceBase::set(const T& v)
201 {
203  }
204 
205 inline void AnyReferenceBase::setFloat(float v)
206 {
207  setDouble(static_cast<double>(v));
208 }
209 
210 template<typename E, typename K>
212 {
213  return (*this)[key].template as<E>();
214 }
215 
216 template<typename K>
218 {
219  return _element(AnyReferenceBase::from(key), true);
220 }
221 
222 template<typename T>
223 void AnyReferenceBase::append(const T& element)
224 {
225  _append(AnyReference::from(element));
226 }
227 
228 template<typename K, typename V>
229 void AnyReferenceBase::insert(const K& key, const V& val)
230 {
232 }
233 
234 template<typename K>
236 {
237  return _element(AnyReference::from(key), false);
238 }
239 
240 } // namespace detail
241 
242 inline bool operator != (const AnyReference& a, const AnyReference& b)
243 {
244  return !(a==b);
245 }
246 
247 } // namespace qi
248 
249 #endif
virtual void * ptrFromStorage(void **)=0
std::pair< AnyReference, bool > convert(TypeInterface *targetType) const
void _append(const AnyReference &element)
void update(const AutoAnyReference &b)
#define QI_API
Definition: api.hpp:34
T * ptr(bool check=true)
#define QI_NORETURN
Portable noreturn attribute, used to declare that a function does not return.
Definition: macro.hpp:53
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:96
void insert(const K &key, const V &val)
T valueAs(const AnyReferenceBase &v)
void destroy()
Deletes storage.
T to() const
Convert to anything or throw trying.
qi::Signature signature(bool resolveDynamic=false) const
AnyReference _element(const AnyReference &key, bool throwOnFailure)
QI_NORETURN void throwConversionFailure(TypeInterface *from, TypeInterface *to)
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:298
virtual const TypeInfo & info()=0
Get the TypeInfo corresponding to this type.
uint64_t uint64_t
Cross-platform unsigned integer of length 64 bits (8 bytes).
Definition: types.hpp:81
TypeInterface * typeOf()
Definition: type.hxx:91
AnyReference clone() const
void set(const T &val)
Update the value to val, which will be converted if required.
void _insert(const AnyReference &key, const AnyReference &val)
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)
int64_t int64_t
Cross-platform signed integer of length 64 bits (8 bytes).
Definition: types.hpp:76
void append(const T &element)
virtual void * initializeStorage(void *ptr=0)=0
qi::Signature signature(void *storage=0, bool resolveDynamic=false)