7 #ifndef _QITYPE_DETAIL_TYPETUPLE_HXX_
8 #define _QITYPE_DETAIL_TYPETUPLE_HXX_
10 #include <boost/type_traits.hpp>
11 #include <boost/utility/enable_if.hpp>
21 std::map<std::string, ::qi::AnyValue>& fields,
22 const std::vector<std::tuple<std::string, TypeInterface*>>& missing,
23 const char** which=0,
int whichLength=0);
29 std::map<std::string, qi::AnyValue>& fields,
30 const std::vector<std::tuple<std::string, TypeInterface*>>& missing)
32 return missing.empty();
34 static bool convertTo(
const std::map<std::string, qi::AnyReference>& dropFields)
36 return dropFields.empty();
43 std::map<std::string, ::qi::AnyValue>& fields,
44 const std::vector<std::tuple<std::string, TypeInterface*>>& missing)
46 return missing.empty();
48 static bool convertFrom(
const std::map<std::string, qi::AnyReference>& dropFields)
50 return dropFields.empty();
58 std::map<std::string, qi::AnyValue>& fields,
59 const std::vector<std::tuple<std::string, TypeInterface*>>& missing,
60 const std::map<std::string, qi::AnyReference>& dropfields)
66 std::map<std::string, ::qi::AnyValue>& fields,
67 const std::vector<std::tuple<std::string, TypeInterface*>>& missing,
68 const std::map<std::string, ::qi::AnyReference>& dropfields)
78 #define QI_TYPE_STRUCT_EXTENSION_ADDED_FIELDS(name, ...) \
84 struct StructVersioningDelegateAddFields<name> \
86 static bool convertFrom(StructTypeInterface* type, \
87 std::map<std::string, ::qi::AnyValue>& fields, \
88 const std::vector<std::tuple<std::string, TypeInterface*>>& missing) \
90 static const char* which[] = {__VA_ARGS__}; \
91 const int count = sizeof(which) / sizeof(char*); \
92 return fillMissingFieldsWithDefaultValues(fields, missing, which, count); \
94 static bool convertTo(const std::map<std::string, ::qi::AnyReference>& todrop) \
96 static const char* which[] = {__VA_ARGS__}; \
97 const int count = sizeof(which) / sizeof(char*); \
98 for (const auto& field : todrop) \
99 if (std::find(which, which + count, field.first) == which + count) \
109 #define QI_TYPE_STRUCT_EXTENSION_DROPPED_FIELDS(name, ...) \
115 struct StructVersioningDelegateDropFields<name> \
117 static bool convertTo(StructTypeInterface* type, \
118 std::map<std::string, ::qi::AnyValue>& fields, \
119 const std::vector<std::tuple<std::string, TypeInterface*>>& missing) \
121 static const char* which[] = {__VA_ARGS__}; \
122 const int count = sizeof(which) / sizeof(char*); \
123 return fillMissingFieldsWithDefaultValues(fields, missing, which, count); \
125 static bool convertFrom(const std::map<std::string, ::qi::AnyReference>& todrop) \
127 static const char* which[] = {__VA_ARGS__}; \
128 const int count = sizeof(which) / sizeof(char*); \
129 for (const auto& field : todrop) \
130 if (std::find(which, which + count, field.first) == which + count) \
152 #define QI_TYPE_STRUCT_EXTENSION_CONVERT_HANDLERS(name, fromHandler, toHandler) \
158 struct StructVersioningDelegate<name> \
160 static bool convertFrom(StructTypeInterface* type, \
161 std::map<std::string, ::qi::AnyValue>& fields, \
162 const std::vector<std::tuple<std::string, TypeInterface*>>& missing, \
163 const std::map<std::string, ::qi::AnyReference>& dropfields) \
165 return fromHandler(fields, missing, dropfields); \
167 static bool convertTo(StructTypeInterface* type, \
168 std::map<std::string, ::qi::AnyValue>& fields, \
169 const std::vector<std::tuple<std::string, TypeInterface*>>& missing, \
170 const std::map<std::string, ::qi::AnyReference>& dropfields) \
172 return toHandler(fields, missing, dropfields); \
183 ref = *(T*)typeOf<T>()->ptrFromStorage(&storage);
195 template<
typename C,
typename A>
void*
fieldStorage(C* inst, A accessor)
198 (
void*)&detail::Accessor<A>::access(inst, accessor));
201 template<
typename C,
typename A>
202 typename detail::Accessor<A>::value_type&
205 using T =
typename detail::Accessor<A>::value_type;
211 #define __QI_TYPE_STRUCT_DECLARE(name, extra) \
215 struct TypeImpl<name> : public ::qi::StructTypeInterface \
218 using ClassType = name; \
220 std::vector<::qi::TypeInterface*> memberTypes() override; \
221 std::vector<std::string> elementsName() override; \
222 std::string className() override; \
223 void* get(void* storage, unsigned int index) override; \
224 void set(void** storage, unsigned int index, void* valStorage) override; \
225 virtual bool convertFrom(std::map<std::string, ::qi::AnyValue>& fields, \
226 const std::vector<std::tuple<std::string, TypeInterface*>>& missing, \
227 const std::map<std::string, ::qi::AnyReference>& dropfields) override; \
228 virtual bool convertTo(std::map<std::string, ::qi::AnyValue>& fields, \
229 const std::vector<std::tuple<std::string, TypeInterface*>>& missing, \
230 const std::map<std::string, ::qi::AnyReference>& dropfields) override; \
231 extra using Impl = ::qi::DefaultTypeImplMethods<name, ::qi::TypeByPointerPOD<name>>; \
232 _QI_BOUNCE_TYPE_METHODS(Impl); \
236 #define __QI_TUPLE_TYPE(_, what, field) res.push_back(::qi::typeOf(ptr->field));
237 #define __QI_TUPLE_GET(_, what, field) if (i == index) return ::qi::typeOf(ptr->field)->initializeStorage(&ptr->field); i++;
238 #define __QI_TUPLE_SET(_, what, field) if (i == index) ::qi::detail::setFromStorage(ptr->field, valueStorage); i++;
239 #define __QI_TUPLE_FIELD_NAME(_, what, field) res.push_back(BOOST_PP_STRINGIZE(QI_DELAY(field)));
240 #define __QI_TYPE_STRUCT_IMPLEMENT(name, inl, onSet, ...) \
243 inl TypeImpl<name>::TypeImpl() \
245 ::qi::registerStruct(this); \
247 inl std::vector<::qi::TypeInterface*> TypeImpl<name>::memberTypes() \
250 std::vector<::qi::TypeInterface*> res; \
251 QI_VAARGS_APPLY(__QI_TUPLE_TYPE, _, __VA_ARGS__); \
254 inl void* TypeImpl<name>::get(void* storage, unsigned int index) \
256 unsigned int i = 0; \
257 name* ptr = (name*)ptrFromStorage(&storage); \
258 QI_VAARGS_APPLY(__QI_TUPLE_GET, _, __VA_ARGS__); \
261 inl void TypeImpl<name>::set(void** storage, unsigned int index, void* valueStorage) \
263 unsigned int i = 0; \
264 name* ptr = (name*)ptrFromStorage(storage); \
265 QI_VAARGS_APPLY(__QI_TUPLE_SET, _, __VA_ARGS__); \
268 inl std::vector<std::string> TypeImpl<name>::elementsName() \
270 std::vector<std::string> res; \
271 QI_VAARGS_APPLY(__QI_TUPLE_FIELD_NAME, _, __VA_ARGS__); \
274 inl std::string TypeImpl<name>::className() \
276 return ::qi::detail::normalizeClassName(BOOST_PP_STRINGIZE(name)); \
278 inl bool TypeImpl<name>::convertFrom(std::map<std::string, ::qi::AnyValue>& fields, \
279 const std::vector<std::tuple<std::string, TypeInterface*>>& missing, \
280 const std::map<std::string, ::qi::AnyReference>& dropfields) \
282 return ::qi::detail::StructVersioningDelegate<name>::convertFrom(this, fields, missing, dropfields); \
284 inl bool TypeImpl<name>::convertTo(std::map<std::string, ::qi::AnyValue>& fields, \
285 const std::vector<std::tuple<std::string, TypeInterface*>>& missing, \
286 const std::map<std::string, ::qi::AnyReference>& dropfields) \
288 return ::qi::detail::StructVersioningDelegate<name>::convertTo(this, fields, missing, dropfields); \
293 #define QI_STRUCT_HELPER(name, func) (name, func, FUNC)
294 #define QI_STRUCT_FIELD(name, field) (name, field, FIELD)
298 #define __QI_STRUCT_ACCESS_FUNC(fname, field) &field
300 #define __QI_STRUCT_ACCESS_FIELD(fname, field) &ClassType::field
303 #define __QI_STRUCT_ACCESS_BOUNCE2(name, accessor, type) \
304 QI_CAT(__QI_STRUCT_ACCESS_, type)(name, accessor)
307 #define __QI_STRUCT_ACCESS_BOUNCE1(x, y) \
308 __QI_STRUCT_ACCESS_BOUNCE2(x, y, FIELD)
311 #define __QI_STRUCT_ACCESS_BOUNCE(...) \
312 QI_CAT(__QI_STRUCT_ACCESS_BOUNCE, QI_LIST_VASIZE((__VA_ARGS__)))(__VA_ARGS__)
315 #define __QI_STRUCT_ACCESS(tuple) QI_DELAY(__QI_STRUCT_ACCESS_BOUNCE)tuple
318 #define __QI_ATUPLE_TYPE(_, what, field) res.push_back(::qi::detail::fieldType(__QI_STRUCT_ACCESS(field)));
319 #define __QI_ATUPLE_GET(_, what, field) if (i == index) return ::qi::detail::fieldStorage(ptr, __QI_STRUCT_ACCESS(field)); i++;
320 #define __QI_ATUPLE_FIELD_NAME(_, what, field) res.push_back(QI_PAIR_FIRST(field));
321 #define __QI_ATUPLE_FROMDATA(idx, what, field) ::qi::detail::fieldValue(ptr, __QI_STRUCT_ACCESS(field), const_cast<void**>(&data[idx]))
322 #define __QI_TYPE_STRUCT_AGREGATE_CONSTRUCTOR_IMPLEMENT(name, inl, onSet, ...) \
325 inl TypeImpl<name>::TypeImpl() \
327 ::qi::registerStruct(this); \
329 inl std::vector<::qi::TypeInterface*> TypeImpl<name>::memberTypes() \
331 std::vector<::qi::TypeInterface*> res; \
332 QI_VAARGS_APPLY(__QI_ATUPLE_TYPE, name, __VA_ARGS__); \
336 inl void* TypeImpl<name>::get(void* storage, unsigned int index) \
338 unsigned int i = 0; \
339 name* ptr = (name*)ptrFromStorage(&storage); \
340 QI_VAARGS_APPLY(__QI_ATUPLE_GET, name, __VA_ARGS__); \
344 inl void TypeImpl<name>::set(void** storage, unsigned int index, void* valueStorage) \
346 throw std::runtime_error("single-field set not implemented"); \
349 inl void TypeImpl<name>::set(void** storage, const std::vector<void*>& data) \
351 name* ptr = (name*)ptrFromStorage(storage); \
352 *ptr = name(QI_VAARGS_MAP(__QI_ATUPLE_FROMDATA, name, __VA_ARGS__)); \
355 inl std::vector<std::string> TypeImpl<name>::elementsName() \
357 std::vector<std::string> res; \
358 QI_VAARGS_APPLY(__QI_ATUPLE_FIELD_NAME, _, __VA_ARGS__); \
361 inl std::string TypeImpl<name>::className() \
364 return ::qi::detail::normalizeClassName(BOOST_PP_STRINGIZE(name)); \
366 inl bool TypeImpl<name>::convertFrom(std::map<std::string, ::qi::AnyValue>& fields, \
367 const std::vector<std::tuple<std::string, TypeInterface*>>& missing, \
368 const std::map<std::string, ::qi::AnyReference>& dropfields) \
372 inl bool TypeImpl<name>::convertTo(std::map<std::string, ::qi::AnyValue>& fields, \
373 const std::vector<std::tuple<std::string, TypeInterface*>>& missing, \
374 const std::map<std::string, ::qi::AnyReference>& dropfields) \
381 #define QI_TYPE_STRUCT_PRIVATE_ACCESS(name) \
382 friend class qi::TypeImpl<name>;
393 #define QI_TYPE_STRUCT(name, ...) \
394 QI_TYPE_STRUCT_DECLARE(name) \
395 __QI_TYPE_STRUCT_IMPLEMENT(name, inline, , __VA_ARGS__)
400 #define QI_TYPE_STRUCT_EX(name, onSet, ...) \
401 QI_TYPE_STRUCT_DECLARE(name) \
402 __QI_TYPE_STRUCT_IMPLEMENT(name, inline, onSet, __VA_ARGS__)
404 #define QI_TYPE_STRUCT_IMPLEMENT(name, ...) \
405 __QI_TYPE_STRUCT_IMPLEMENT(name, , , __VA_ARGS__)
429 #define QI_TYPE_STRUCT_AGREGATE_CONSTRUCTOR(name, ...) \
430 __QI_TYPE_STRUCT_DECLARE(name, \
431 void set(void** storage, const std::vector<void*>&) override;) \
432 __QI_TYPE_STRUCT_AGREGATE_CONSTRUCTOR_IMPLEMENT(name, inline, , __VA_ARGS__)
440 #define QI_TYPE_STRUCT_REGISTER(name, ...) \
442 QI_TYPE_STRUCT(name, __VA_ARGS__) \
444 QI_TYPE_REGISTER_CUSTOM(name, _qi_::qi::TypeImpl<name>)
451 #define QI_TYPE_STRUCT_AGREGATE_CONSTRUCTOR_REGISTER(name, ...) \
453 QI_TYPE_STRUCT_AGREGATE_CONSTRUCTOR(name, __VA_ARGS__); \
455 QI_TYPE_REGISTER_CUSTOM(name, _qi_::qi::TypeImpl<name>)
464 #define QI_TYPE_STRUCT_BOUNCE(name, bounceTo, conversion) \
466 template<> class TypeImpl<name>: public ::qi::StructTypeInterfaceBouncer<name, bounceTo> \
469 void adaptStorage(void** storage, void** adapted) \
471 name* ptr = (name*)ptrFromStorage(storage); \
472 bounceTo * tptr = conversion(ptr); \
473 *adapted = bounceType()->initializeStorage(tptr); \
475 std::string className() \
477 return ::qi::detail::normalizeClassName(BOOST_PP_STRINGIZE(name)); \
484 #define QI_TYPE_STRUCT_BOUNCE_REGISTER(name, bounceTo, conversion) \
486 QI_TYPE_STRUCT_BOUNCE(name, bounceTo, conversion); \
488 QI_TYPE_REGISTER_CUSTOM(name, _qi_::qi::TypeImpl<name>)
493 template<
typename T,
typename TO>
501 result = typeOf<TO>();
505 virtual void adaptStorage(
void** storage,
void** adapted) = 0;
513 void*
get(
void* storage,
unsigned int index)
override
520 std::vector<void*>
get(
void* storage)
override
527 void set(
void** storage,
const std::vector<void*>& vals)
override
534 void set(
void** storage,
unsigned int index,
void* valStorage)
override
546 virtual bool convertFrom(std::map<std::string, qi::AnyValue>& fields,
547 const std::vector<std::tuple<std::string, TypeInterface*>>& missing,
548 const std::map<std::string, qi::AnyReference>& dropfields)
override
553 virtual bool convertTo(std::map<std::string, qi::AnyValue>& fields,
554 const std::vector<std::tuple<std::string, TypeInterface*>>& missing,
555 const std::map<std::string, qi::AnyReference>& dropfields)
override
563 template<
typename F,
typename S>
571 _memberTypes.push_back(typeOf<F>());
572 _memberTypes.push_back(typeOf<S>());
576 std::vector<TypeInterface*>
memberTypes()
override {
return _memberTypes;}
577 void*
get(
void* storage,
unsigned int index)
override
586 void set(
void** storage,
unsigned int index,
void* valStorage)
override
589 const std::vector<TypeInterface*>& types = _memberTypes;
603 #endif // _QITYPE_DETAIL_TYPETUPLE_HXX_
virtual void * ptrFromStorage(void **)=0
void set(void **storage, const std::vector< void * > &vals) override
Set all the fields of the struct (copies the values given in the vector)
void setFromStorage(T &ref, void *storage)
std::vector< TypeInterface * > memberTypes() override
DefaultTypeImplMethods< T, TypeByPointerPOD< T >> Methods
static bool convertFrom(StructTypeInterface *type, std::map< std::string, qi::AnyValue > &fields, const std::vector< std::tuple< std::string, TypeInterface * >> &missing, const std::map< std::string, qi::AnyReference > &dropfields)
static bool convertFrom(const std::map< std::string, qi::AnyReference > &dropFields)
virtual bool convertTo(std::map< std::string, qi::AnyValue > &fields, const std::vector< std::tuple< std::string, TypeInterface * >> &missing, const std::map< std::string, qi::AnyReference > &dropfields) override
virtual bool convertFrom(std::map< std::string,::qi::AnyValue > &fields, const std::vector< std::tuple< std::string, TypeInterface * >> &missing, const std::map< std::string,::qi::AnyReference > &dropfields)
Fill missing fields caused by conversion from a different struct. Return whether fill succeeded...
bool fillMissingFieldsWithDefaultValues(std::map< std::string,::qi::AnyValue > &fields, const std::vector< std::tuple< std::string, TypeInterface * >> &missing, const char **which=0, int whichLength=0)
virtual std::vector< TypeInterface * > memberTypes()=0
_QI_BOUNCE_TYPE_METHODS(Methods)
detail::Accessor< A >::value_type & fieldValue(C *instance, A accessor, void **data)
std::vector< TypeInterface * > memberTypes() override
#define _QI_BOUNCE_TYPE_METHODS(Bounce)
Implement all methods of Type as bouncers to Bouncer.
std::vector< TypeInterface * > _memberTypes
void * ptrFromStorage(void **s) override
static bool convertTo(StructTypeInterface *type, std::map< std::string,::qi::AnyValue > &fields, const std::vector< std::tuple< std::string, TypeInterface * >> &missing, const std::map< std::string,::qi::AnyReference > &dropfields)
#define QI_ONCE(code)
Execute code once, parallel calls are blocked until code finishes.
virtual std::vector< void * > get(void *storage)
Get all the fields storages of the struct (not a copy)
virtual std::vector< std::string > elementsName()
Get the names of the fields of the struct.
void set(void **storage, unsigned int index, void *valStorage) override
Set the fields of the struct at index (copies the value given)
void * initializeStorage(void *ptr=0) override
virtual void adaptStorage(void **storage, void **adapted)=0
StructTypeInterface * bounceType()
void * fieldStorage(C *inst, A accessor)
TypeInterface * fieldType(A)
virtual void set(void **storage, const std::vector< void * > &)
Set all the fields of the struct (copies the values given in the vector)
void set(void **storage, unsigned int index, void *valStorage) override
Set the fields of the struct at index (copies the value given)
virtual bool convertTo(std::map< std::string,::qi::AnyValue > &fields, const std::vector< std::tuple< std::string, TypeInterface * >> &missing, const std::map< std::string,::qi::AnyReference > &dropfields)
Fill missing fields caused by conversion to a different struct. Return whether fill succeeded...
static bool convertTo(StructTypeInterface *type, std::map< std::string,::qi::AnyValue > &fields, const std::vector< std::tuple< std::string, TypeInterface * >> &missing)
static bool convertFrom(StructTypeInterface *type, std::map< std::string, qi::AnyValue > &fields, const std::vector< std::tuple< std::string, TypeInterface * >> &missing)
std::string normalizeClassName(const std::string &name)
typename std::pair< F, S > BackendType
std::vector< std::string > elementsName() override
Get the names of the fields of the struct.
virtual bool convertFrom(std::map< std::string, qi::AnyValue > &fields, const std::vector< std::tuple< std::string, TypeInterface * >> &missing, const std::map< std::string, qi::AnyReference > &dropfields) override
virtual void * initializeStorage(void *ptr=0)=0
static bool convertTo(const std::map< std::string, qi::AnyReference > &dropFields)