libqi-api  2.8.7.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
listtypeinterface.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 _QITYPE_DETAIL_TYPELIST_HXX_
8 #define _QITYPE_DETAIL_TYPELIST_HXX_
9 
10 #include <qi/atomic.hpp>
11 
14 #include <qi/anyfunction.hpp>
15 
16 namespace qi
17 {
18  // List container
19 template<typename T, typename H = ListTypeInterface>
20 class ListTypeInterfaceImpl: public H
21 {
22 public:
25  size_t size(void* storage) override;
26  TypeInterface* elementType() override;
27  AnyIterator begin(void* storage) override;
28  AnyIterator end(void* storage) override;
29  void pushBack(void** storage, void* valueStorage) override;
32 };
33 
34 // Type impl for any class that behaves as a forward iterator (++, *, ==)
35 template<typename T>
37 {
38 public:
39  using Storage = T;
40  AnyReference dereference(void* storage) override
41  {
42  T* ptr = (T*)ptrFromStorage(&storage);
43  return AnyReference::from(*(*ptr));
44  }
45  void next(void** storage) override
46  {
47  T* ptr = (T*)ptrFromStorage(storage);
48  ++(*ptr);
49  }
50  bool equals(void* s1, void* s2) override
51  {
52  T* p1 = (T*)ptrFromStorage(&s1);
53  T* p2 = (T*)ptrFromStorage(&s2);
54  return *p1 == *p2;
55  }
58  static AnyIterator make(const T& val)
59  {
60  static TypeSimpleIteratorImpl<T>* type = 0;
61  QI_THREADSAFE_NEW(type);
62  return AnyValue(AnyReference(type, type->initializeStorage(const_cast<void*>((const void*)&val))));
63  }
64 };
65 
66 
67 template<typename T, typename H>
69 {
70  _elementType = typeOf<typename T::value_type>();
71 }
72 
73 template<typename T, typename H> TypeInterface*
75 {
76  return _elementType;
77 }
78 
79 template<typename T, typename H>
81 {
82  T* ptr = (T*)ptrFromStorage(&storage);
84 }
85 
86 template<typename T, typename H>
88 {
89  T* ptr = (T*)ptrFromStorage(&storage);
91 }
92 namespace detail
93 {
94  template<typename T, typename E>
95  void pushBack(T& container, E* element)
96  {
97  container.push_back(*element);
98  }
99  template<typename CE, typename E>
100  void pushBack(std::set<CE>& container, E* element)
101  {
102  container.insert(*element);
103  }
104 }
105 template<typename T, typename H>
106 void ListTypeInterfaceImpl<T, H>::pushBack(void **storage, void* valueStorage)
107 {
108  T* ptr = (T*) ptrFromStorage(storage);
109  detail::pushBack(*ptr, (typename T::value_type*)_elementType->ptrFromStorage(&valueStorage));
110 }
111 
112 template<typename T, typename H>
114 {
115  T* ptr = (T*) ptrFromStorage(&storage);
116  return ptr->size();
117 }
118 
119 // There is no way to register a template container type :(
120 template<typename T> struct TypeImpl<std::vector<T> >: public ListTypeInterfaceImpl<std::vector<T> >
121 {
122  static_assert(!boost::is_same<T,bool>::value, "std::vector<bool> is not supported by AnyValue.");
123 };
124 template<typename T> struct TypeImpl<std::list<T> >: public ListTypeInterfaceImpl<std::list<T> > {};
125 template<typename T> struct TypeImpl<std::set<T> >: public ListTypeInterfaceImpl<std::set<T> > {};
126 
127 
128 // varargs container
129 template<typename T>
130 class VarArgsTypeInterfaceImpl: public ListTypeInterfaceImpl<typename T::VectorType, VarArgsTypeInterface>
131 {
132 public:
134 
137 
139 
140  void* adaptStorage(void** storage) {
141  T* ptr = (T*) ptrFromStorage(storage);
142  //return ptr
143  typename T::VectorType& v = ptr->args();
144  return &v;
145  }
146 
147  size_t size(void* storage) override {
148  return BaseClass::size(adaptStorage(&storage));
149  }
150  AnyIterator begin(void* storage) override {
151  return BaseClass::begin(adaptStorage(&storage));
152  }
153  AnyIterator end(void* storage) override {
154  return BaseClass::end(adaptStorage(&storage));
155  }
156  void pushBack(void** storage, void* valueStorage) override {
157  void* vstor = adaptStorage(storage);
158  BaseClass::pushBack(&vstor, valueStorage);
159  }
160 
161  //ListTypeInterface* _list;
162 };
163 
164 
165 template<typename T> struct TypeImpl<qi::VarArguments<T> >: public VarArgsTypeInterfaceImpl<qi::VarArguments<T> > {};
166 }
167 
168 #endif // _QITYPE_DETAIL_TYPELIST_HXX_
virtual void * ptrFromStorage(void **)=0
static AnyIterator make(const T &val)
_QI_BOUNCE_TYPE_METHODS(MethodsImpl)
void pushBack(T &container, E *element)
AnyIterator begin(void *storage) override
#define QI_THREADSAFE_NEW(...)
Safe static initialization of variables.
Definition: atomic.hpp:374
virtual void * initializeStorage(void *ptr=nullptr)=0
_QI_BOUNCE_TYPE_METHODS(MethodsImpl)
AnyIterator end(void *storage) override
void next(void **storage) override
Increment the iterator.
void * adaptStorage(void **storage)
bool equals(void *s1, void *s2) override
Check for iterator equality.
AnyIterator end(void *storage) override
AnyReference dereference(void *storage) override
TypeInterface * elementType() override
size_t size(void *storage) override
Return the number of elements in the list.
void pushBack(void **storage, void *valueStorage) override
void pushBack(void **storage, void *valueStorage) override
Append an element to the end of the list.
DefaultTypeImplMethods< T, TypeByPointerPOD< T >> MethodsImpl
size_t size(void *storage) override
static AnyReference from(const T &ref)
AnyIterator begin(void *storage) override
Return an iterator pointing to the first element of the list.