7 #ifndef _QITYPE_DETAIL_TYPETUPLE_HXX_
8 #define _QITYPE_DETAIL_TYPETUPLE_HXX_
11 #include <boost/type_traits.hpp>
12 #include <boost/utility/enable_if.hpp>
24 std::map<std::string, ::qi::AnyValue>& fields,
25 const std::vector<std::tuple<std::string, TypeInterface*>>& missing,
26 const char** which=0,
int whichLength=0);
32 std::map<std::string, qi::AnyValue>& fields,
33 const std::vector<std::tuple<std::string, TypeInterface*>>& missing)
35 return missing.empty();
37 static bool convertTo(
const std::map<std::string, qi::AnyReference>& dropFields)
39 return dropFields.empty();
46 std::map<std::string, ::qi::AnyValue>& fields,
47 const std::vector<std::tuple<std::string, TypeInterface*>>& missing)
49 return missing.empty();
51 static bool convertFrom(
const std::map<std::string, qi::AnyReference>& dropFields)
53 return dropFields.empty();
61 std::map<std::string, qi::AnyValue>& fields,
62 const std::vector<std::tuple<std::string, TypeInterface*>>& missing,
63 const std::map<std::string, qi::AnyReference>& dropfields)
69 std::map<std::string, ::qi::AnyValue>& fields,
70 const std::vector<std::tuple<std::string, TypeInterface*>>& missing,
71 const std::map<std::string, ::qi::AnyReference>& dropfields)
81 #define QI_TYPE_STRUCT_EXTENSION_ADDED_FIELDS(name, ...) \
87 struct StructVersioningDelegateAddFields<name> \
89 static bool convertFrom(StructTypeInterface* type, \
90 std::map<std::string, ::qi::AnyValue>& fields, \
91 const std::vector<std::tuple<std::string, TypeInterface*>>& missing) \
93 static const char* which[] = {__VA_ARGS__}; \
94 const int count = sizeof(which) / sizeof(char*); \
95 return fillMissingFieldsWithDefaultValues(fields, missing, which, count); \
97 static bool convertTo(const std::map<std::string, ::qi::AnyReference>& todrop) \
99 static const char* which[] = {__VA_ARGS__}; \
100 const int count = sizeof(which) / sizeof(char*); \
101 for (const auto& field : todrop) \
102 if (std::find(which, which + count, field.first) == which + count) \
112 #define QI_TYPE_STRUCT_EXTENSION_DROPPED_FIELDS(name, ...) \
118 struct StructVersioningDelegateDropFields<name> \
120 static bool convertTo(StructTypeInterface* type, \
121 std::map<std::string, ::qi::AnyValue>& fields, \
122 const std::vector<std::tuple<std::string, TypeInterface*>>& missing) \
124 static const char* which[] = {__VA_ARGS__}; \
125 const int count = sizeof(which) / sizeof(char*); \
126 return fillMissingFieldsWithDefaultValues(fields, missing, which, count); \
128 static bool convertFrom(const std::map<std::string, ::qi::AnyReference>& todrop) \
130 static const char* which[] = {__VA_ARGS__}; \
131 const int count = sizeof(which) / sizeof(char*); \
132 for (const auto& field : todrop) \
133 if (std::find(which, which + count, field.first) == which + count) \
155 #define QI_TYPE_STRUCT_EXTENSION_CONVERT_HANDLERS(name, fromHandler, toHandler) \
161 struct StructVersioningDelegate<name> \
163 static bool convertFrom(StructTypeInterface* type, \
164 std::map<std::string, ::qi::AnyValue>& fields, \
165 const std::vector<std::tuple<std::string, TypeInterface*>>& missing, \
166 const std::map<std::string, ::qi::AnyReference>& dropfields) \
168 return fromHandler(fields, missing, dropfields); \
170 static bool convertTo(StructTypeInterface* type, \
171 std::map<std::string, ::qi::AnyValue>& fields, \
172 const std::vector<std::tuple<std::string, TypeInterface*>>& missing, \
173 const std::map<std::string, ::qi::AnyReference>& dropfields) \
175 return toHandler(fields, missing, dropfields); \
186 ref = *(T*)typeOf<T>()->ptrFromStorage(&storage);
198 template<
typename C,
typename A>
void*
fieldStorage(C* inst, A accessor)
201 (
void*)&detail::Accessor<A>::access(inst, accessor));
204 template<
typename C,
typename A>
205 typename detail::Accessor<A>::value_type&
208 using T =
typename detail::Accessor<A>::value_type;
214 #define __QI_TYPE_STRUCT_DECLARE(name, extra) \
218 struct TypeImpl<name> : public ::qi::StructTypeInterface \
221 using ClassType = name; \
223 std::vector<::qi::TypeInterface*> memberTypes() override; \
224 std::vector<std::string> elementsName() override; \
225 std::string className() override; \
226 void* get(void* storage, unsigned int index) override; \
227 void set(void** storage, unsigned int index, void* valStorage) override; \
228 virtual bool convertFrom(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 virtual bool convertTo(std::map<std::string, ::qi::AnyValue>& fields, \
232 const std::vector<std::tuple<std::string, TypeInterface*>>& missing, \
233 const std::map<std::string, ::qi::AnyReference>& dropfields) override; \
234 extra using Impl = ::qi::DefaultTypeImplMethods<name, ::qi::TypeByPointerPOD<name>>; \
235 _QI_BOUNCE_TYPE_METHODS(Impl); \
239 #define __QI_TUPLE_TYPE(_, what, field) res.push_back(::qi::typeOf(ptr->field));
240 #define __QI_TUPLE_GET(_, what, field) if (i == index) return ::qi::typeOf(ptr->field)->initializeStorage(&ptr->field); i++;
241 #define __QI_TUPLE_SET(_, what, field) if (i == index) ::qi::detail::setFromStorage(ptr->field, valueStorage); i++;
242 #define __QI_TUPLE_FIELD_NAME(_, what, field) res.push_back(BOOST_PP_STRINGIZE(QI_DELAY(field)));
243 #define __QI_TYPE_STRUCT_IMPLEMENT(name, inl, onSet, ...) \
246 inl TypeImpl<name>::TypeImpl() \
248 ::qi::registerStruct(this); \
250 inl std::vector<::qi::TypeInterface*> TypeImpl<name>::memberTypes() \
253 std::vector<::qi::TypeInterface*> res; \
254 QI_VAARGS_APPLY(__QI_TUPLE_TYPE, _, __VA_ARGS__); \
257 inl void* TypeImpl<name>::get(void* storage, unsigned int index) \
259 unsigned int i = 0; \
260 name* ptr = (name*)ptrFromStorage(&storage); \
261 QI_VAARGS_APPLY(__QI_TUPLE_GET, _, __VA_ARGS__); \
264 inl void TypeImpl<name>::set(void** storage, unsigned int index, void* valueStorage) \
266 unsigned int i = 0; \
267 name* ptr = (name*)ptrFromStorage(storage); \
268 QI_VAARGS_APPLY(__QI_TUPLE_SET, _, __VA_ARGS__); \
271 inl std::vector<std::string> TypeImpl<name>::elementsName() \
273 std::vector<std::string> res; \
274 QI_VAARGS_APPLY(__QI_TUPLE_FIELD_NAME, _, __VA_ARGS__); \
277 inl std::string TypeImpl<name>::className() \
279 return ::qi::detail::normalizeClassName(BOOST_PP_STRINGIZE(name)); \
281 inl bool TypeImpl<name>::convertFrom(std::map<std::string, ::qi::AnyValue>& fields, \
282 const std::vector<std::tuple<std::string, TypeInterface*>>& missing, \
283 const std::map<std::string, ::qi::AnyReference>& dropfields) \
285 return ::qi::detail::StructVersioningDelegate<name>::convertFrom(this, fields, missing, dropfields); \
287 inl bool TypeImpl<name>::convertTo(std::map<std::string, ::qi::AnyValue>& fields, \
288 const std::vector<std::tuple<std::string, TypeInterface*>>& missing, \
289 const std::map<std::string, ::qi::AnyReference>& dropfields) \
291 return ::qi::detail::StructVersioningDelegate<name>::convertTo(this, fields, missing, dropfields); \
296 #define QI_STRUCT_HELPER(name, func) (name, func, FUNC)
297 #define QI_STRUCT_FIELD(name, field) (name, field, FIELD)
301 #define __QI_STRUCT_ACCESS_FUNC(fname, field) &field
303 #define __QI_STRUCT_ACCESS_FIELD(fname, field) &ClassType::field
306 #define __QI_STRUCT_ACCESS_BOUNCE2(name, accessor, type) \
307 QI_CAT(__QI_STRUCT_ACCESS_, type)(name, accessor)
310 #define __QI_STRUCT_ACCESS_BOUNCE1(x, y) \
311 __QI_STRUCT_ACCESS_BOUNCE2(x, y, FIELD)
314 #define __QI_STRUCT_ACCESS_BOUNCE(...) \
315 QI_CAT(__QI_STRUCT_ACCESS_BOUNCE, QI_LIST_VASIZE((__VA_ARGS__)))(__VA_ARGS__)
318 #define __QI_STRUCT_ACCESS(tuple) QI_DELAY(__QI_STRUCT_ACCESS_BOUNCE)tuple
321 #define __QI_ATUPLE_TYPE(_, what, field) res.push_back(::qi::detail::fieldType(__QI_STRUCT_ACCESS(field)));
322 #define __QI_ATUPLE_GET(_, what, field) if (i == index) return ::qi::detail::fieldStorage(ptr, __QI_STRUCT_ACCESS(field)); i++;
323 #define __QI_ATUPLE_FIELD_NAME(_, what, field) res.push_back(QI_PAIR_FIRST(field));
324 #define __QI_ATUPLE_FROMDATA(idx, what, field) ::qi::detail::fieldValue(ptr, __QI_STRUCT_ACCESS(field), const_cast<void**>(&data[idx]))
325 #define __QI_TYPE_STRUCT_AGREGATE_CONSTRUCTOR_IMPLEMENT(name, inl, onSet, ...) \
328 inl TypeImpl<name>::TypeImpl() \
330 ::qi::registerStruct(this); \
332 inl std::vector<::qi::TypeInterface*> TypeImpl<name>::memberTypes() \
334 std::vector<::qi::TypeInterface*> res; \
335 QI_VAARGS_APPLY(__QI_ATUPLE_TYPE, name, __VA_ARGS__); \
339 inl void* TypeImpl<name>::get(void* storage, unsigned int index) \
341 unsigned int i = 0; \
342 name* ptr = (name*)ptrFromStorage(&storage); \
343 QI_VAARGS_APPLY(__QI_ATUPLE_GET, name, __VA_ARGS__); \
347 inl void TypeImpl<name>::set(void** storage, unsigned int index, void* valueStorage) \
349 throw std::runtime_error("single-field set not implemented"); \
352 inl void TypeImpl<name>::set(void** storage, const std::vector<void*>& data) \
354 name* ptr = (name*)ptrFromStorage(storage); \
355 *ptr = name(QI_VAARGS_MAP(__QI_ATUPLE_FROMDATA, name, __VA_ARGS__)); \
358 inl std::vector<std::string> TypeImpl<name>::elementsName() \
360 std::vector<std::string> res; \
361 QI_VAARGS_APPLY(__QI_ATUPLE_FIELD_NAME, _, __VA_ARGS__); \
364 inl std::string TypeImpl<name>::className() \
367 return ::qi::detail::normalizeClassName(BOOST_PP_STRINGIZE(name)); \
369 inl bool TypeImpl<name>::convertFrom(std::map<std::string, ::qi::AnyValue>& fields, \
370 const std::vector<std::tuple<std::string, TypeInterface*>>& missing, \
371 const std::map<std::string, ::qi::AnyReference>& dropfields) \
375 inl bool TypeImpl<name>::convertTo(std::map<std::string, ::qi::AnyValue>& fields, \
376 const std::vector<std::tuple<std::string, TypeInterface*>>& missing, \
377 const std::map<std::string, ::qi::AnyReference>& dropfields) \
384 #define QI_TYPE_STRUCT_PRIVATE_ACCESS(name) \
385 friend class qi::TypeImpl<name>;
396 #define QI_TYPE_STRUCT(name, ...) \
397 QI_TYPE_STRUCT_DECLARE(name) \
398 __QI_TYPE_STRUCT_IMPLEMENT(name, inline, , __VA_ARGS__)
403 #define QI_TYPE_STRUCT_EX(name, onSet, ...) \
404 QI_TYPE_STRUCT_DECLARE(name) \
405 __QI_TYPE_STRUCT_IMPLEMENT(name, inline, onSet, __VA_ARGS__)
407 #define QI_TYPE_STRUCT_IMPLEMENT(name, ...) \
408 __QI_TYPE_STRUCT_IMPLEMENT(name, , , __VA_ARGS__)
432 #define QI_TYPE_STRUCT_AGREGATE_CONSTRUCTOR(name, ...) \
433 __QI_TYPE_STRUCT_DECLARE(name, \
434 void set(void** storage, const std::vector<void*>&) override;) \
435 __QI_TYPE_STRUCT_AGREGATE_CONSTRUCTOR_IMPLEMENT(name, inline, , __VA_ARGS__)
443 #define QI_TYPE_STRUCT_REGISTER(name, ...) \
445 QI_TYPE_STRUCT(name, __VA_ARGS__) \
447 QI_TYPE_REGISTER_CUSTOM(name, _qi_::qi::TypeImpl<name>)
454 #define QI_TYPE_STRUCT_AGREGATE_CONSTRUCTOR_REGISTER(name, ...) \
456 QI_TYPE_STRUCT_AGREGATE_CONSTRUCTOR(name, __VA_ARGS__); \
458 QI_TYPE_REGISTER_CUSTOM(name, _qi_::qi::TypeImpl<name>)
467 #define QI_TYPE_STRUCT_BOUNCE(name, bounceTo, conversion) \
469 template<> class TypeImpl<name>: public ::qi::StructTypeInterfaceBouncer<name, bounceTo> \
472 void adaptStorage(void** storage, void** adapted) \
474 name* ptr = (name*)ptrFromStorage(storage); \
475 bounceTo * tptr = conversion(ptr); \
476 *adapted = bounceType()->initializeStorage(tptr); \
478 std::string className() \
480 return ::qi::detail::normalizeClassName(BOOST_PP_STRINGIZE(name)); \
487 #define QI_TYPE_STRUCT_BOUNCE_REGISTER(name, bounceTo, conversion) \
489 QI_TYPE_STRUCT_BOUNCE(name, bounceTo, conversion); \
491 QI_TYPE_REGISTER_CUSTOM(name, _qi_::qi::TypeImpl<name>)
496 template<
typename T,
typename TO>
504 result = typeOf<TO>();
508 virtual void adaptStorage(
void** storage,
void** adapted) = 0;
516 void*
get(
void* storage,
unsigned int index)
override
523 std::vector<void*>
get(
void* storage)
override
530 void set(
void** storage,
const std::vector<void*>& vals)
override
537 void set(
void** storage,
unsigned int index,
void* valStorage)
override
549 virtual bool convertFrom(std::map<std::string, qi::AnyValue>& fields,
550 const std::vector<std::tuple<std::string, TypeInterface*>>& missing,
551 const std::map<std::string, qi::AnyReference>& dropfields)
override
556 virtual bool convertTo(std::map<std::string, qi::AnyValue>& fields,
557 const std::vector<std::tuple<std::string, TypeInterface*>>& missing,
558 const std::map<std::string, qi::AnyReference>& dropfields)
override
566 template<
typename F,
typename S>
574 _memberTypes.push_back(typeOf<F>());
575 _memberTypes.push_back(typeOf<S>());
579 std::vector<TypeInterface*>
memberTypes()
override {
return _memberTypes;}
580 void*
get(
void* storage,
unsigned int index)
override
589 void set(
void** storage,
unsigned int index,
void* valStorage)
override
592 const std::vector<TypeInterface*>& types = _memberTypes;
606 #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)
dll import/export and compiler message
virtual void * initializeStorage(void *ptr=nullptr)=0
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
static bool convertTo(const std::map< std::string, qi::AnyReference > &dropFields)