libqi-api  2.8.7.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
anyreference.hpp
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_HPP_
8 #define _QI_TYPE_DETAIL_ANYREFERENCE_HPP_
9 
10 #include <vector>
11 #include <map>
12 #include <stdexcept>
13 #include <cmath>
14 #include <qi/atomic.hpp>
15 #include <qi/types.hpp>
16 #include <qi/api.hpp>
17 #include <qi/type/fwd.hpp>
19 #include <ka/scoped.hpp>
20 #include <boost/type_traits/remove_const.hpp>
21 #include <boost/optional.hpp>
22 
23 namespace qi {
24 
25 class AnyReference;
26 using AnyReferenceVector = std::vector<AnyReference>;
27 
28 namespace detail {
29 
30 class UniqueAnyReference;
31 
32 
41 {
42 protected:
45 
48 
52  explicit AnyReferenceBase(TypeInterface* type);
53 
59  AnyReferenceBase(TypeInterface* type, void* value)
60  : _type(type)
61  , _value(value)
62  {}
63 
74  AnyReference _element(const AnyReference& key, bool throwOnFailure, bool autoInsert);
75 
76 public:
79  UniqueAnyReference convert(TypeInterface* targetType) const;
80  UniqueAnyReference convert(ListTypeInterface* targetType) const;
81  UniqueAnyReference convert(StructTypeInterface* targetType) const;
82  UniqueAnyReference convert(MapTypeInterface* targetType) const;
83  UniqueAnyReference convert(IntTypeInterface* targetType) const;
84  UniqueAnyReference convert(FloatTypeInterface* targetType) const;
85  UniqueAnyReference convert(RawTypeInterface* targetType) const;
86  UniqueAnyReference convert(StringTypeInterface* targetType) const;
87  UniqueAnyReference convert(PointerTypeInterface* targetType) const;
88  UniqueAnyReference convert(DynamicTypeInterface* targetType) const;
89  UniqueAnyReference convert(OptionalTypeInterface* targetType) const;
90 
96  template<typename T>
97  T* ptr(bool check = true);
98 
100  bool isValid() const;
101 
103  bool isValue() const;
104 
106  AnyReference convertCopy(TypeInterface* targetType) const;
108 
110 
121  template <typename T>
122  static AnyReference from(const T& ref);
123 
130  template <typename T>
131  static AnyReference fromPtr(const T* ptr);
132 
133  AnyReference clone() const;
135  void destroy();
137 
138 
140 
145  template<typename T>
147  T to() const;
148 
150  template<typename T>
151  T to(const T&) const;
152 
153  int64_t toInt() const;
154  uint64_t toUInt() const;
155  float toFloat() const;
156  double toDouble() const;
157  std::string toString() const;
158 
159  template<typename T>
160  std::vector<T> toList() const;
161 
162  template<typename K, typename V>
163  std::map<K, V> toMap() const;
164 
165  AnyObject toObject() const;
166  template <typename T> boost::optional<T> toOptional() const;
167 
175  AnyValue toTuple(bool homogeneous) const;
177 
178  qi::Signature signature(bool resolveDynamic = false) const;
179  TypeKind kind() const;
180  AnyReference unwrap() const;
181 
183 
199  template<typename T>
200  T& as();
201 
202  int64_t& asInt64() { return as<int64_t>();}
203  uint64_t& asUInt64() { return as<uint64_t>();}
204  int32_t& asInt32() { return as<int32_t>();}
205  uint32_t& asUInt32() { return as<uint32_t>();}
206  int16_t& asInt16() { return as<int16_t>();}
207  uint16_t& asUInt16() { return as<uint16_t>();}
208  int8_t& asInt8() { return as<int8_t>();}
209  uint8_t& asUInt8() { return as<uint8_t>();}
210  double& asDouble() { return as<double>();}
211  float& asFloat() { return as<float>();}
212  std::string& asString() { return as<std::string>();}
213 
215  std::pair<char*, size_t> asRaw() const;
216 
217  boost::optional<AnyReference> asOptional() const;
218 
222  AnyReference content() const;
223 
225 
232  AnyReferenceVector asTupleValuePtr();
233  AnyReferenceVector asListValuePtr();
234  std::map<AnyReference, AnyReference> asMapValuePtr();
236 
239  void update(const AutoAnyReference& b);
240 
242  template<typename T>
243  void set(const T& val);
244 
245  void set(int64_t v) { setInt(v); }
246  void set(int32_t v) { setInt(v); }
247  void set(uint64_t v) { setUInt(v); }
248  void set(uint32_t v) { setUInt(v); }
249  void set(float v) { setFloat(v); }
250  void set(double v) { setDouble(v); }
251  void set(const std::string& v) { setString(v); }
252 
253  void setInt(int64_t v);
254  void setUInt(uint64_t v);
255  void setFloat(float v);
256  void setDouble(double v);
257  void setString(const std::string& v);
258  void setDynamic(const AnyReference &value);
259 
262  void setOptional(const boost::optional<AnyReference>& opt);
263 
264  QI_API_DEPRECATED_MSG(Use `setOptional(boost::optional<AnyReference>)` instead)
265  void setOptional(const AnyReference& opt);
266 
269  void setRaw(const char *buffer, size_t size);
270 
273  void setTuple(const AnyReferenceVector& values);
274 
277  void resetOptional();
278 
281 
293  template<typename K>
294  AnyReference operator[](const K& key);
295  AnyReference operator[](const AnyReference& key);
296 
298  template<typename E, typename K>
299  E& element(const K& key);
300 
307  template<typename K>
308  AnyReference at(const K& key);
309  template<typename K>
310  AnyReference at(const K& key) const;
311  AnyReference at(const AnyReference& key);
312  AnyReference at(const AnyReference& key) const;
313 
314  size_t size() const;
315 
318  bool optionalHasValue() const;
319 
320 
321  //TODO: use AutoAnyReference
322  template<typename T>
323  void append(const T& element);
324  void append(const AnyReference& element);
325 
326  template<typename K, typename V>
327  void insert(const K& key, const V& val);
328  void insert(const AnyReference& key, const AnyReference& val);
329 
330 
334  template<typename K>
335  AnyReference find(const K& key);
336 
338  AnyIterator begin() const; //we lie on const but GV does not honor it yet
340  AnyIterator end() const;
341 
343  AnyReference operator*() const;
345 
347 
348  TypeInterface* type() const { return _type; }
350  std::vector<TypeInterface*> membersType() const;
351  void* rawValue() const { return _value; }
352 
353 protected:
355  void* _value;
356 };
357 
358 } // namespace detail
359 
361 public:
363  : AnyReferenceBase()
364  {}
365 
366  AnyReference(const AnyReferenceBase& rhs)
367  : AnyReferenceBase(rhs)
368  {}
369 
370  explicit AnyReference(TypeInterface* type)
371  : AnyReferenceBase(type)
372  {}
373 
374  AnyReference(TypeInterface* type, void* value)
375  : AnyReferenceBase(type, value)
376  {}
377 
378 private:
379  //block the dangerous automatic cast from AnyValue to AnyRef
380  //use AnyValue::asReference() to take a ref on the content of a value.
381  //use AnyValue::from(value) to take a ref on the value.
382  AnyReference(const AnyValue& val)
383  {
384  throw std::runtime_error("invalid internal operation.");
385  };
386 };
387 
388 using AnyReferenceVector = std::vector<AnyReference>;
389 QI_API bool operator< (const AnyReference& a, const AnyReference& b);
390 QI_API bool operator==(const AnyReference& a, const AnyReference& b);
391 QI_API bool operator!=(const AnyReference& a, const AnyReference& b);
392 
394 QI_API AnyReference makeGenericTuple(const AnyReferenceVector& values);
395 
397 QI_API AnyReference makeGenericTuplePtr(
398  const std::vector<TypeInterface*>& types,
399  const std::vector<void*>& values);
400 
410 {
411 public:
414  : AnyReference()
415  {
416  _value = b._value;
417  _type = b._type;
418  }
419 
421  : AnyReference(self)
422  {}
423 
425  : AnyReference(self)
426  {}
427 
428  template<typename T,
429  // Disable this constructor if T inherits AnyReferenceBase to avoid it being greedy.
430  // It also handles cases where T inherits from either AutoAnyReference or AnyReference
431  // because both of these types inherit AnyReferenceBase.
432  typename = ka::EnableIfNotBaseOf<detail::AnyReferenceBase, T>>
433  AutoAnyReference(const T& ptr)
434  {
435  *static_cast<AnyReference*>(this) = AnyReference::from(ptr);
436  }
437 };
438 
439 namespace detail
440 {
441 
442 struct DeferOwnership {};
443 
445 {
446 public:
447  UniqueAnyReference() = default;
448 
449  KA_GENERATE_FRIEND_REGULAR_OPS_2(UniqueAnyReference, ref, owned)
450 
452  : ref{ ref }
453  , owned{ ref.isValid() }
454  {}
455 
457  : ref{ ref }
458  , owned{ false }
459  {}
460 
462  : ref{ ka::exchange(o.ref, AnyReference{}) }
463  , owned{ ka::exchange(o.owned, false) }
464  {
465  }
466 
468  {
469  ref = ka::exchange(o.ref, AnyReference{});
470  owned = ka::exchange(o.owned, false);
471  return *this;
472  }
473 
475  {
476  destroyRef();
477  }
478 
480  {
481  return ref;
482  }
483 
484  const AnyReference& operator*() const
485  {
486  return ref;
487  }
488 
490  {
491  return &ref;
492  }
493 
494  const AnyReference* operator->() const
495  {
496  return &ref;
497  }
498 
500  {
501  owned = false;
502  return ka::exchange(ref, AnyReference{});
503  }
504 
505  void reset(AnyReference newRef = {})
506  {
507  destroyRef();
508  owned = newRef.isValid();
509  ref = newRef;
510  }
511 
513  {
514  destroyRef();
515  owned = false;
516  ref = newRef;
517  }
518 
519  bool ownsReference() const
520  {
521  return owned;
522  }
523 
525  {
526  owned = true;
527  }
528 
529 private:
530  void destroyRef()
531  {
532  if (owned)
533  ref.destroy();
534  }
535 
536  AnyReference ref;
537  bool owned = false;
538 };
539 
540 } // namespace detail
541 
542 } // namespace qi
543 
545 #include <qi/type/typeinterface.hpp>
546 
547 /* Since AnyReference does not handle its memory, it cannot be used
548  * inside a AnyReference. use AnyValue instead.
549  */
552 
553 #endif
AnyReference(TypeInterface *type)
void destroy()
Stop and flush the logging system.
int64_t int64_t
Definition: types.hpp:61
AutoAnyReference(const AutoAnyReference &b)
#define QI_API
Definition: api.hpp:33
void reset(AnyReference newRef, DeferOwnership)
uint32_t uint32_t
Definition: types.hpp:65
const AnyReference & operator*() const
const AnyReference * operator->() const
void set(const std::string &v)
uint16_t uint16_t
Definition: types.hpp:64
dll import/export and compiler message
UniqueAnyReference(AnyReference ref, DeferOwnership)
UniqueAnyReference(UniqueAnyReference &&o)
AutoAnyReference(const AnyReference &self)
AnyReference makeGenericTuplePtr(const std::vector< TypeInterface * > &types, const std::vector< void * > &values)
AnyReference makeGenericTuple(const AnyReferenceVector &values)
AutoAnyReference(const detail::AnyReferenceBase &self)
std::vector< AnyReference > AnyReferenceVector
UniqueAnyReference & operator=(UniqueAnyReference &&o)
bool operator==(const Signature &lhs, const Signature &rhs)
TypeInterface * type() const
AnyReferenceBase(TypeInterface *type, void *value)
int32_t int32_t
Definition: types.hpp:60
AutoAnyReference(const T &ptr)
void reset(AnyReference newRef={})
uint8_t uint8_t
Definition: types.hpp:63
QI_NO_TYPE(qi::AnyReference)
struct QI_API_DEPRECATED_MSG(Use 'QI_TYPE_ENUM'instead) QI_TYPE_ENUM_REGISTER_
TypeKind
Definition: fwd.hpp:54
AnyReference(const AnyReferenceBase &rhs)
static AnyReference from(const T &ref)
bool operator<(const AnyReference &a, const AnyReference &b)
int8_t int8_t
Definition: types.hpp:58
AnyReference(TypeInterface *type, void *value)
bool operator!=(const Signature &lhs, const Signature &rhs)
Definition: signature.hpp:157
uint64_t uint64_t
Definition: types.hpp:66
int16_t int16_t
Definition: types.hpp:59