- Aldebaran documentation |
- C++ Libraries |
- index

libqi-api 2.8.7.4

- Main Page
- Related Pages
- Namespaces
- Classes
- Files
- Examples

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
typeimpl.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_TYPEIMPL_HXX_
8 #define _QITYPE_DETAIL_TYPEIMPL_HXX_
9
10 #include <set>
11 #include <qi/type/detail/hasless.hxx>
12
13
14 /* This file contains class to help implementing the Type interface.
15 */
16 namespace qi
17 {
18 namespace detail {
20 void QI_API typeFail(const char* typeName, const char* operation);
21
22 /* Handle creation (create, createInPlace), copy (copy, clone, cloneInPlace), and
23 * destruction(destroy) of a given type.
24 * There is currently no portable way to detect if a given class has
25 * accesible constructor, destructor and/or copy operators.
26 * So we provide a reasonable default behavior (through our class/struct
27 * registration macros) and rely on the user to call the appropriate
28 * QI_TYPE_NOT_* macro to override.
29 */
30 template<typename T, bool b>
31 struct TypeTraitCreate
32 {
33 static void* create() { return new T();}
34 static void createInPlace(void* ptr) { new(ptr)T();}
35 };
36
37 template<typename T>
38 struct TypeTraitCreate<T, false>
39 {
40 static void* create() { typeFail(qi::typeId<T>().name(), "default constructor"); return 0;}
41 static void createInPlace(void* ptr) {typeFail(qi::typeId<T>().name(), "default constructor");}
42 };
43
44 template<typename T, bool b>
45 struct TypeTraitCopy
46 {
47 static void copy(void* dst, const void* src) { *(T*)dst = *(const T*)src;}
48 static void* clone(void* src) { return new T(*(T*)src);}
49 static void cloneInPlace(void* ptr, void* src) { new (ptr)T(*(T*)src);}
50 };
51
52 template<typename T>
53 struct TypeTraitCopy<T, false>
54 {
55 template<typename T1, typename T2>
56 static void copy(const T1& d, const T2&s) {typeFail(qi::typeId<T>().name(), "copy operator");}
57 static void* clone(void* src) { typeFail(qi::typeId<T>().name(), "clone"); return 0;}
58 static void cloneInPlace(void* ptr, void* src) { typeFail(qi::typeId<T>().name(), "clone");}
59 };
60
61 template<typename T, bool b>
62 struct TypeTraitDestroy
63 {
64 static void destroy(void* ptr) { delete (T*)ptr;}
65 };
66
67 template<typename T>
68 struct TypeTraitDestroy<T, false>
69 {
70 template<typename U>
71 static void destroy(const U& ptr) {typeFail(qi::typeId<T>().name(), "destructor");}
72 };
73
74 /* Use a two-stage override mechanism.
75 * That way if a user uses our macro that specializes
76 * TypeManager on one of the versions below, she can still
77 * specializes the appropriate TypeManagerDefault{Struct,Class}.
78 */
79 template<typename T>
80 struct TypeManagerDefaultStruct
81 : public TypeTraitCreate<T, true>
82 , public TypeTraitCopy<T, true>
83 , public TypeTraitDestroy<T, true>
84 {};
85
86 template<typename T>
87 struct TypeManagerDefaultInterface
88 : public TypeTraitCreate<T, false>
89 , public TypeTraitCopy<T, false>
90 , public TypeTraitDestroy<T, true>
91 {};
92
93 template<typename T>
94 struct TypeManagerNull
95 : public TypeTraitCreate<T, false>
96 , public TypeTraitCopy<T, false>
97 , public TypeTraitDestroy<T, false>
98 {};
99
100 template<typename T>
101 struct TypeManagerNotConstructible // not constructible but copyable
102 : public TypeTraitCreate<T, false>
103 , public TypeTraitCopy<T, true>
104 , public TypeTraitDestroy<T, true>
105 {};
106
107
108 // TypeManager is accessed by this interface.
109 // Only things for which we are sure are marked constructible and clonable
110 template<typename T>
111 struct TypeManager
112 : public boost::mpl::if_c<
113 boost::is_function<T>::value,
114 TypeManagerNull<T>,
115 typename boost::mpl::if_c< boost::is_pod<T>::value,
116 TypeManagerDefaultStruct<T>,
117 TypeManagerDefaultInterface<T> >
118 ::type>::type {};
119
120 // Except for boost::function which matches is_function and is copyable
121 template<typename T>
122 struct TypeManager<boost::function<T> >: public TypeManagerDefaultStruct<boost::function<T> >
123 {};
124 template<typename T>
125 struct TypeManager<const T>: public TypeManager<T>{};
126
127 }
128
129 /* To avoid the diamond inheritance problem (interface inheritance between
130 * for instance Type and IntTypeInterface, and we want to reuse implementations),
131 * Provide methods in a class that does not inherit from Type, and a macro
132 * to generate the virtual bouncers.
133 */
135 template <typename T, typename Manager=detail::TypeManager<T> >
136 class TypeByPointer
137 {
138 public:
139 using type = T;
140
141 static void* ptrFromStorage(void** storage)
142 {
143 return *storage;
144 }
145
146 static void* initializeStorage(void* ptr=0)
147 {
148 if (ptr)
149 return ptr;
150 //Warning:
151 // If T is not clonable (no copy constructor or operator=)
152 // add QI_TYPE_NOT_CLONABLE(T) next to the declaration of T
153 // in your code.
154 void* res = Manager::create();
155 if (!res)
156 qiLogError("qitype.bypointer") << "initializeStorage error on " << qi::typeId<T>().name();
157 return res;
158 }
159
160 static void* clone(void* src)
161 {
162 return Manager::clone(src);
163 }
164
165 static void destroy(void* src)
166 {
167 T* ptr = (T*)ptrFromStorage(&src);
168 Manager::destroy(ptr);
169 }
170 };
171
172 // const ward
173 template <typename T>
174 class TypeByPointer<const T>: public TypeByPointer<T>
175 {};
176 // Helper to mark POD-like
177 template <typename T>
178 class TypeByPointerPOD: public TypeByPointer<T, detail::TypeManagerDefaultStruct<T> >{};
180 /* No longuer used since we have an in-place modification
181 * of AnyReference, as by-value storage would break reference semantic
182 */
183 template <typename T>
184 class TypeByValue
185 {
186 public:
187 using type = T;
188 static void* ptrFromStorage(void** storage)
189 {
190 return storage;
191 }
192 static void* initializeStorage(void* ptr=0)
193 {
194 void* result = 0;
195 T* tresult=(T*)(void*)&result;
196 detail::TypeManager<T>::createInPlace(tresult);
197
198 if (ptr)
199 detail::TypeManager<T>::copy(tresult, (T*)ptr);
200
201 return result;
202 }
203 static void* clone(void* src)
204 {
205 void* res;
206 detail::TypeManager<T>::cloneInPlace(&res, (T*)&src);
207 return res;
208 }
209
210 static void destroy(void* storage)
211 {
212 T* ptr = (T*)ptrFromStorage(&storage);
213 ptr->~T();
214 }
215 };
216
217 // const ward
218 template <typename T>
219 class TypeByValue<const T>: public TypeByValue<T>
220 {};
221
222
223 /* implementation of Type methods that bounces to the various aspect
224 * subclasses.
225 *
226 */
227 template < typename T, typename _Access = TypeByPointer<T> >
228 class DefaultTypeImplMethods
229 {
230 public:
231 using Access = _Access;
232
233 static void* initializeStorage(void* ptr=0)
234 {
235 return Access::initializeStorage(ptr);
236 }
237
238 static void* ptrFromStorage(void** storage)
239 {
240 return Access::ptrFromStorage(storage);
241 }
242
243 static const TypeInfo& info()
244 {
245 static const TypeInfo result(qi::typeId<T>());
246 return result;
247 }
248
249 static void* clone(void* src)
250 {
251 return Access::clone(src);
252 }
253
254 static void destroy(void* ptr)
255 {
256 Access::destroy(ptr);
257 }
258
259 static bool less(void* a, void* b)
260 {
261 return ::qi::detail::Less<T>()((T*)ptrFromStorage(&a), (T*)ptrFromStorage(&b));
262 }
263 };
264
266 #define _QI_BOUNCE_TYPE_METHODS_NOCLONE(Bounce) \
267 const ::qi::TypeInfo& info() override { return Bounce::info();} \
268 void* initializeStorage(void* ptr=0) override { return Bounce::initializeStorage(ptr);} \
269 void* ptrFromStorage(void**s) override { return Bounce::ptrFromStorage(s);} \
270 bool less(void* a, void* b) override { return Bounce::less(a, b);}
271
273 #define _QI_BOUNCE_TYPE_METHODS(Bounce) \
274 _QI_BOUNCE_TYPE_METHODS_NOCLONE(Bounce) \
275 void* clone(void* ptr) override { return Bounce::clone(ptr);} \
276 void destroy(void* ptr) override { Bounce::destroy(ptr);}
277
279 #define _QI_BOUNCE_TYPE_METHODS_NOINFO(Bounce) \
280 void* initializeStorage(void* ptr=0) override { return Bounce::initializeStorage(ptr);} \
281 void* ptrFromStorage(void**s) override { return Bounce::ptrFromStorage(s);} \
282 void* clone(void* ptr) override { return Bounce::clone(ptr);} \
283 void destroy(void* ptr) override { Bounce::destroy(ptr);} \
284 bool less(void* a, void* b) override { return Bounce::less(a, b);}
285
286 template < typename T, typename _Access = TypeByPointer<T> >
287 class DefaultTypeImpl
288 : public TypeInterface
289 {
290 public:
291 using MethodsImpl = DefaultTypeImplMethods<T, _Access>;
292 _QI_BOUNCE_TYPE_METHODS(MethodsImpl);
293 };
294
299 template<typename T>
300 class TypeImpl: public DefaultTypeImpl<T>
301 {};
302
303 // void
304 template<>
305 class TypeImpl<void>: public TypeInterface
306 {
307 public:
308 const TypeInfo& info() override
309 {
310 static TypeInfo result = TypeInfo(qi::typeId<void>());
311 return result;
312 }
313 // do not return 0 everywhere and provide a correct impl
314 // this may be used as void*, that's why we need to keep storage
315 void* initializeStorage(void* ptr) override { return ptr; }
316 void* ptrFromStorage(void** storage) override { return (void*)storage; }
317 void* clone(void* storage) override { return storage; }
318 void destroy(void* ptr) override {}
319 TypeKind kind() override { return TypeKind_Void; }
320 bool less(void* a, void* b) override { return false; }
321 };
322
323 //reference
324 template<typename T>
325 class TypeImpl<T&>: public TypeImpl<T>
326 {};
327
328
329
330 }
331
332 namespace _qi_
333 {
334 namespace qi
335 {
336 // Support for QI_TYPE_STRUCT_REGISTER and QI_TYPE_STRUCT_BOUNCE_REGISTER
337 template<typename T>
338 class TypeImpl
339 {};
340 }
341 }
342
343 #endif // _QITYPE_DETAIL_TYPEIMPL_HXX_
qi::TypeByValue::destroy
static void destroy(void *storage)
Definition: typeimpl.hxx:210
qi::TypeImpl< void >::info
const TypeInfo & info() override
Get the TypeInfo corresponding to this type.
Definition: typeimpl.hxx:308
qi::TypeImpl
Definition: typeimpl.hxx:300
qi::TypeByPointer::clone
static void * clone(void *src)
Definition: typeimpl.hxx:160
qi::detail::TypeTraitCreate< T, false >::create
static void * create()
Definition: typeimpl.hxx:40
qi::log::destroy
void destroy()
Stop and flush the logging system.
qi::detail::TypeManagerNull
Definition: typeimpl.hxx:94
qi::detail::TypeTraitCopy::cloneInPlace
static void cloneInPlace(void *ptr, void *src)
Definition: typeimpl.hxx:49
qi::detail::TypeManagerNotConstructible
Definition: typeimpl.hxx:101
QI_API
#define QI_API
Definition: api.hpp:33
qi::detail::TypeTraitCopy
Definition: typeimpl.hxx:45
qi::detail::TypeTraitCreate::create
static void * create()
Definition: typeimpl.hxx:33
qi::detail::TypeManager
Definition: typeimpl.hxx:111
qi::DefaultTypeImplMethods::info
static const TypeInfo & info()
Definition: typeimpl.hxx:243
qi::DefaultTypeImplMethods::initializeStorage
static void * initializeStorage(void *ptr=0)
Definition: typeimpl.hxx:233
qi::TypeByValue::type
T type
Definition: typeimpl.hxx:187
qi::TypeByPointer::destroy
static void destroy(void *src)
Definition: typeimpl.hxx:165
qi::TypeImpl< void >::less
bool less(void *a, void *b) override
Definition: typeimpl.hxx:320
qi::TypeKind_Void
Definition: fwd.hpp:57
qi::detail::TypeTraitCopy::copy
static void copy(void *dst, const void *src)
Definition: typeimpl.hxx:47
qi::TypeByPointer::ptrFromStorage
static void * ptrFromStorage(void **storage)
Definition: typeimpl.hxx:141
qi::detail::TypeTraitCopy< T, false >::cloneInPlace
static void cloneInPlace(void *ptr, void *src)
Definition: typeimpl.hxx:58
qi::detail::TypeManagerDefaultStruct
Definition: typeimpl.hxx:80
qi::DefaultTypeImplMethods::Access
_Access Access
Definition: typeimpl.hxx:231
qi::TypeInfo
Definition: typeinterface.hpp:45
qi::detail::TypeTraitCreate::createInPlace
static void createInPlace(void *ptr)
Definition: typeimpl.hxx:34
qi::detail::TypeTraitCreate< T, false >::createInPlace
static void createInPlace(void *ptr)
Definition: typeimpl.hxx:41
qi::DefaultTypeImplMethods::less
static bool less(void *a, void *b)
Definition: typeimpl.hxx:259
qi::TypeInterface
Definition: typeinterface.hpp:129
qi::TypeByPointer::initializeStorage
static void * initializeStorage(void *ptr=0)
Definition: typeimpl.hxx:146
qi::TypeImpl< void >::destroy
void destroy(void *ptr) override
Free all resources of a storage.
Definition: typeimpl.hxx:318
qiLogError
#define qiLogError(...)
Log in error mode.
Definition: log.hpp:120
qi::TypeByValue::clone
static void * clone(void *src)
Definition: typeimpl.hxx:203
qi::TypeImpl< void >::ptrFromStorage
void * ptrFromStorage(void **storage) override
Definition: typeimpl.hxx:316
_QI_BOUNCE_TYPE_METHODS
#define _QI_BOUNCE_TYPE_METHODS(Bounce)
Implement all methods of Type as bouncers to Bouncer.
Definition: typeimpl.hxx:273
qi::TypeByPointer
Access API that stores a T* in storage.
Definition: typeimpl.hxx:136
qi::detail::TypeTraitDestroy::destroy
static void destroy(void *ptr)
Definition: typeimpl.hxx:64
qi::detail::TypeTraitDestroy< T, false >::destroy
static void destroy(const U &ptr)
Definition: typeimpl.hxx:71
qi::DefaultTypeImplMethods
Definition: typeimpl.hxx:228
qi::DefaultTypeImplMethods::destroy
static void destroy(void *ptr)
Definition: typeimpl.hxx:254
qi::detail::typeFail
void typeFail(const char *typeName, const char *operation)
Report a type operation failure.
qi::detail::TypeManagerDefaultInterface
Definition: typeimpl.hxx:87
qi::detail::TypeTraitCopy::clone
static void * clone(void *src)
Definition: typeimpl.hxx:48
qi::DefaultTypeImplMethods::clone
static void * clone(void *src)
Definition: typeimpl.hxx:249
qi::detail::TypeTraitCopy< T, false >::copy
static void copy(const T1 &d, const T2 &s)
Definition: typeimpl.hxx:56
hasless.hxx
qi::TypeByPointerPOD
Definition: typeimpl.hxx:178
qi::detail::TypeTraitCopy< T, false >::clone
static void * clone(void *src)
Definition: typeimpl.hxx:57
_qi_::qi::TypeImpl
Definition: typeimpl.hxx:338
qi::src
T src(const std::atomic< T > &x)
Definition: atomic.hpp:318
qi::detail::TypeTraitDestroy
Definition: typeimpl.hxx:62
qi::log::env::QI_DEFAULT_LOGHANDLER::name
char const *const name
qi::TypeByValue::initializeStorage
static void * initializeStorage(void *ptr=0)
Definition: typeimpl.hxx:192
qi::TypeKind
TypeKind
Definition: fwd.hpp:54
qi::detail::TypeTraitCreate
Definition: typeimpl.hxx:31
qi::DefaultTypeImplMethods::ptrFromStorage
static void * ptrFromStorage(void **storage)
Definition: typeimpl.hxx:238
qi::TypeByValue::ptrFromStorage
static void * ptrFromStorage(void **storage)
Definition: typeimpl.hxx:188
qi::TypeByValue
Access api that stores a T in storage.
Definition: typeimpl.hxx:184
qi::TypeImpl< void >::initializeStorage
void * initializeStorage(void *ptr) override
Definition: typeimpl.hxx:315
qi::DefaultTypeImpl
Definition: typeimpl.hxx:287
qi::TypeImpl< void >::kind
TypeKind kind() override
Definition: typeimpl.hxx:319
qi::TypeImpl< void >::clone
void * clone(void *storage) override
Allocate a storage and copy the value given as an argument.
Definition: typeimpl.hxx:317
qi::TypeByPointer< T >::type
T type
Definition: typeimpl.hxx:139