7 #ifndef _QITYPE_DETAILS_TYPETUPLE_HXX_
8 #define _QITYPE_DETAILS_TYPETUPLE_HXX_
10 #include <boost/type_traits.hpp>
11 #include <boost/utility/enable_if.hpp>
22 static bool canDropFields(
void*,
const std::vector<std::string>&) {
return false;}
29 std::map<std::string, ::qi::AnyValue>& fields,
30 const std::vector<std::string>& missing,
31 const char** which=0,
int whichLength=0);
38 #define QI_TYPE_STRUCT_EXTENSION_FILL_FIELDS(name, ...) \
39 namespace qi { namespace detail { template<> struct StructVersioningDelegateFill<name> { \
40 static bool fillMissingFields(StructTypeInterface* type, std::map<std::string, ::qi::AnyValue>& fields, const std::vector<std::string>& missing) \
42 const char* which[] = {__VA_ARGS__ }; \
43 int count = sizeof(which) / sizeof(char*); \
44 return fillMissingFieldsWithDefaultValues(type, fields, missing, which, count); \
47 #define QI_TYPE_STRUCT_EXTENSION_FILL_ALL(name, ...) \
49 namespace qi { namespace detail { template<> struct StructVersioningDelegateFill<name> { \
50 static bool fillMissingFields(StructTypeInterface* type, std::map<std::string, ::qi::AnyValue>& fields, const std::vector<std::string>& missing) \
52 return fillMissingFieldsWithDefaultValues(type, fields, missing); \
55 #define QI_TYPE_STRUCT_EXTENSION_DROP_ALL(name) \
57 namespace qi { namespace detail { template<> struct StructVersioningDelegateDrop<name> { \
58 static bool canDropFields(void*, const std::vector<std::string>&) { return true;} \
62 #define QI_TYPE_STRUCT_EXTENSION_DROP_FIELDS(name, ...) \
63 namespace qi { namespace detail { template<> struct StructVersioningDelegateDrop<name> { \
64 static bool canDropFields(void*, const std::vector<std::string>& fields) { \
65 const char* okFields[] = {__VA_ARGS__ }; \
66 int count = sizeof(okFields) / sizeof(char*); \
67 for (unsigned i=0; i<fields.size(); ++i) \
68 if (std::find(okFields, okFields+count, fields[i]) == okFields+count) return false; \
77 #define QI_TYPE_STRUCT_EXTENSION_DROP_HANDLER(name, f) \
78 namespace qi { namespace detail { template<> struct StructVersioningDelegateDrop<name> { \
79 static bool canDropFields(void* store, const std::vector<std::string>& fields) { \
80 return f((name*)store, fields);} \
89 #define QI_TYPE_STRUCT_EXTENSION_FILL_HANDLER(name, f) \
90 namespace qi { namespace detail { template<> struct StructVersioningDelegateFill<name> { \
91 static bool fillMissingFields(StructTypeInterface* type, std::map<std::string, ::qi::AnyValue>& fields, const std::vector<std::string>& missing) \
93 return f(fields, missing) ; \
102 #define QI_TYPE_STRUCT_EXTENSION_ALL(name) \
103 QI_TYPE_STRUCT_EXTENSION_DROP_ALL(name); \
104 QI_TYPE_STRUCT_EXTENSION_FILL_ALL(name)
107 #define QI_TYPE_STRUCT_EXTENSION_FIELDS(name, ...) \
108 QI_TYPE_STRUCT_EXTENSION_DROP_FIELDS(name, __VA_ARGS__); \
109 QI_TYPE_STRUCT_EXTENSION_FILL_FIELDS(name, __VA_ARGS__)
116 ref = *(T*)typeOf<T>()->ptrFromStorage(&storage);
128 template<
typename C,
typename A>
void*
fieldStorage(C* inst, A accessor)
131 (
void*)&detail::Accessor<A>::access(inst, accessor));
134 template<
typename C,
typename A>
135 typename detail::Accessor<A>::value_type&
138 typedef typename detail::Accessor<A>::value_type T;
145 #define __QI_TYPE_STRUCT_DECLARE(name, extra) \
147 template<> struct TypeImpl<name>: public ::qi::StructTypeInterface \
150 typedef name ClassType; \
152 virtual std::vector< ::qi::TypeInterface*> memberTypes(); \
153 virtual std::vector<std::string> elementsName(); \
154 virtual std::string className(); \
155 virtual void* get(void* storage, unsigned int index); \
156 virtual void set(void** storage, unsigned int index, void* valStorage); \
157 virtual bool canDropFields(void* storage, const std::vector<std::string>& fieldNames); \
158 virtual bool fillMissingFields(std::map<std::string, ::qi::AnyValue>& fields, const std::vector<std::string>& missing); \
160 typedef ::qi::DefaultTypeImplMethods<name, ::qi::TypeByPointerPOD<name> > Impl; \
161 _QI_BOUNCE_TYPE_METHODS(Impl); \
165 #define __QI_TUPLE_TYPE(_, what, field) res.push_back(::qi::typeOf(ptr->field));
166 #define __QI_TUPLE_GET(_, what, field) if (i == index) return ::qi::typeOf(ptr->field)->initializeStorage(&ptr->field); i++;
167 #define __QI_TUPLE_SET(_, what, field) if (i == index) ::qi::detail::setFromStorage(ptr->field, valueStorage); i++;
168 #define __QI_TUPLE_FIELD_NAME(_, what, field) res.push_back(BOOST_PP_STRINGIZE(QI_DELAY(field)));
169 #define __QI_TYPE_STRUCT_IMPLEMENT(name, inl, onSet, ...) \
171 inl TypeImpl<name>::TypeImpl() { \
172 ::qi::registerStruct(this); \
174 inl std::vector< ::qi::TypeInterface*> TypeImpl<name>::memberTypes() \
177 std::vector< ::qi::TypeInterface*> res; \
178 QI_VAARGS_APPLY(__QI_TUPLE_TYPE, _, __VA_ARGS__); \
181 inl void* TypeImpl<name>::get(void* storage, unsigned int index) \
183 unsigned int i = 0; \
184 name* ptr = (name*)ptrFromStorage(&storage); \
185 QI_VAARGS_APPLY(__QI_TUPLE_GET, _, __VA_ARGS__); \
188 inl void TypeImpl<name>::set(void** storage, unsigned int index, void* valueStorage)\
191 name* ptr = (name*)ptrFromStorage(storage); \
192 QI_VAARGS_APPLY(__QI_TUPLE_SET, _, __VA_ARGS__); \
195 inl std::vector<std::string> TypeImpl<name>::elementsName() \
197 std::vector<std::string> res; \
198 QI_VAARGS_APPLY(__QI_TUPLE_FIELD_NAME, _, __VA_ARGS__); \
201 inl std::string TypeImpl<name>::className() \
203 return ::qi::detail::normalizeClassName(BOOST_PP_STRINGIZE(name));\
205 inl bool TypeImpl<name>::canDropFields(void* storage, const std::vector<std::string>& fieldNames) {return ::qi::detail::StructVersioningDelegateDrop<name>::canDropFields(storage, fieldNames);} \
206 inl bool TypeImpl<name>::fillMissingFields(std::map<std::string, ::qi::AnyValue>& fields, const std::vector<std::string>& missing) {return ::qi::detail::StructVersioningDelegateFill<name>::fillMissingFields(this, fields, missing);} \
212 #define QI_STRUCT_HELPER(name, func) (name, func, FUNC)
213 #define QI_STRUCT_FIELD(name, field) (name, field, FIELD)
217 #define __QI_STRUCT_ACCESS_FUNC(fname, field) &field
219 #define __QI_STRUCT_ACCESS_FIELD(fname, field) &ClassType::field
222 #define __QI_STRUCT_ACCESS_BOUNCE2(name, accessor, type) \
223 QI_CAT(__QI_STRUCT_ACCESS_, type)(name, accessor)
226 #define __QI_STRUCT_ACCESS_BOUNCE1(x, y) \
227 __QI_STRUCT_ACCESS_BOUNCE2(x, y, FIELD)
230 #define __QI_STRUCT_ACCESS_BOUNCE(...) \
231 QI_CAT(__QI_STRUCT_ACCESS_BOUNCE, QI_LIST_VASIZE((__VA_ARGS__)))(__VA_ARGS__)
234 #define __QI_STRUCT_ACCESS(tuple) QI_DELAY(__QI_STRUCT_ACCESS_BOUNCE)tuple
237 #define __QI_ATUPLE_TYPE(_, what, field) res.push_back(::qi::detail::fieldType(__QI_STRUCT_ACCESS(field)));
238 #define __QI_ATUPLE_GET(_, what, field) if (i == index) return ::qi::detail::fieldStorage(ptr, __QI_STRUCT_ACCESS(field)); i++;
239 #define __QI_ATUPLE_FIELD_NAME(_, what, field) res.push_back(QI_PAIR_FIRST(field));
240 #define __QI_ATUPLE_FROMDATA(idx, what, field) ::qi::detail::fieldValue(ptr, __QI_STRUCT_ACCESS(field), const_cast<void**>(&data[idx]))
241 #define __QI_TYPE_STRUCT_AGREGATE_CONSTRUCTOR_IMPLEMENT(name, inl, onSet, ...)\
243 inl TypeImpl<name>::TypeImpl() { \
244 ::qi::registerStruct(this); \
246 inl std::vector< ::qi::TypeInterface*> TypeImpl<name>::memberTypes() \
248 std::vector< ::qi::TypeInterface*> res; \
249 QI_VAARGS_APPLY(__QI_ATUPLE_TYPE, name, __VA_ARGS__); \
253 inl void* TypeImpl<name>::get(void* storage, unsigned int index) \
255 unsigned int i = 0; \
256 name* ptr = (name*)ptrFromStorage(&storage); \
257 QI_VAARGS_APPLY(__QI_ATUPLE_GET, name, __VA_ARGS__); \
261 inl void TypeImpl<name>::set(void** storage, unsigned int index, void* valueStorage)\
263 throw std::runtime_error("single-field set not implemented");\
266 inl void TypeImpl<name>::set(void** storage, const std::vector<void*>& data) \
268 name* ptr = (name*)ptrFromStorage(storage); \
269 *ptr = name(QI_VAARGS_MAP(__QI_ATUPLE_FROMDATA, name, __VA_ARGS__)); \
272 inl std::vector<std::string> TypeImpl<name>::elementsName() \
274 std::vector<std::string> res; \
275 QI_VAARGS_APPLY(__QI_ATUPLE_FIELD_NAME, _, __VA_ARGS__); \
278 inl std::string TypeImpl<name>::className() \
281 return ::qi::detail::normalizeClassName(BOOST_PP_STRINGIZE(name));\
283 inl bool TypeImpl<name>::canDropFields(void* storage, const std::vector<std::string>& fieldNames) {return ::qi::detail::StructVersioningDelegateDrop<name>::canDropFields(storage, fieldNames);} \
284 inl bool TypeImpl<name>::fillMissingFields(std::map<std::string, ::qi::AnyValue>& fields, const std::vector<std::string>& missing) {return ::qi::detail::StructVersioningDelegateFill<name>::fillMissingFields(this, fields, missing);} \
289 #define QI_TYPE_STRUCT_PRIVATE_ACCESS(name) \
290 friend class qi::TypeImpl<name>;
301 #define QI_TYPE_STRUCT(name, ...) \
302 QI_TYPE_STRUCT_DECLARE(name) \
303 __QI_TYPE_STRUCT_IMPLEMENT(name, inline, , __VA_ARGS__)
308 #define QI_TYPE_STRUCT_EX(name, onSet, ...) \
309 QI_TYPE_STRUCT_DECLARE(name) \
310 __QI_TYPE_STRUCT_IMPLEMENT(name, inline, onSet, __VA_ARGS__)
312 #define QI_TYPE_STRUCT_IMPLEMENT(name, ...) \
313 __QI_TYPE_STRUCT_IMPLEMENT(name, , , __VA_ARGS__)
337 #define QI_TYPE_STRUCT_AGREGATE_CONSTRUCTOR(name, ...) \
338 __QI_TYPE_STRUCT_DECLARE(name, \
339 virtual void set(void** storage, const std::vector<void*>&);) \
340 __QI_TYPE_STRUCT_AGREGATE_CONSTRUCTOR_IMPLEMENT(name, inline, , __VA_ARGS__)
348 #define QI_TYPE_STRUCT_REGISTER(name, ...) \
350 QI_TYPE_STRUCT(name, __VA_ARGS__) \
352 QI_TYPE_REGISTER_CUSTOM(name, _qi_::qi::TypeImpl<name>)
359 #define QI_TYPE_STRUCT_AGREGATE_CONSTRUCTOR_REGISTER(name, ...) \
361 QI_TYPE_STRUCT_AGREGATE_CONSTRUCTOR(name, __VA_ARGS__); \
363 QI_TYPE_REGISTER_CUSTOM(name, _qi_::qi::TypeImpl<name>)
372 #define QI_TYPE_STRUCT_BOUNCE(name, bounceTo, conversion) \
374 template<> class TypeImpl<name>: public ::qi::StructTypeInterfaceBouncer<name, bounceTo> \
377 void adaptStorage(void** storage, void** adapted) \
379 name* ptr = (name*)ptrFromStorage(storage); \
380 bounceTo * tptr = conversion(ptr); \
381 *adapted = bounceType()->initializeStorage(tptr); \
383 std::string className() \
385 return ::qi::detail::normalizeClassName(BOOST_PP_STRINGIZE(name)); \
392 #define QI_TYPE_STRUCT_BOUNCE_REGISTER(name, bounceTo, conversion) \
394 QI_TYPE_STRUCT_BOUNCE(name, bounceTo, conversion); \
396 QI_TYPE_REGISTER_CUSTOM(name, _qi_::qi::TypeImpl<name>)
401 template<
typename T,
typename TO>
409 result = typeOf<TO>();
413 virtual void adaptStorage(
void** storage,
void** adapted) = 0;
421 virtual void*
get(
void* storage,
unsigned int index)
428 virtual std::vector<void*>
get(
void* storage)
435 virtual void set(
void** storage,
const std::vector<void*>& vals)
442 virtual void set(
void** storage,
unsigned int index,
void* valStorage)
454 virtual bool fillMissingFields(std::map<std::string, ::qi::AnyValue>& fields,
const std::vector<std::string>& missing) {
461 template<
typename F,
typename S>
469 _memberTypes.push_back(typeOf<F>());
470 _memberTypes.push_back(typeOf<S>());
475 void*
get(
void* storage,
unsigned int index)
484 void set(
void** storage,
unsigned int index,
void* valStorage)
487 const std::vector<TypeInterface*>& types = _memberTypes;
501 #endif // _QITYPE_DETAILS_TYPETUPLE_HXX_
virtual void * ptrFromStorage(void **)=0
void setFromStorage(T &ref, void *storage)
std::vector< TypeInterface * > memberTypes()
bool fillMissingFieldsWithDefaultValues(StructTypeInterface *type, std::map< std::string,::qi::AnyValue > &fields, const std::vector< std::string > &missing, const char **which=0, int whichLength=0)
DefaultTypeImplMethods< std::pair< F, S >, TypeByPointerPOD< std::pair< F, S > > > Methods
virtual std::vector< TypeInterface * > memberTypes()=0
_QI_BOUNCE_TYPE_METHODS(Methods)
detail::Accessor< A >::value_type & fieldValue(C *instance, A accessor, void **data)
virtual std::vector< TypeInterface * > memberTypes()
#define _QI_BOUNCE_TYPE_METHODS(Bounce)
Implement all methods of Type as bouncers to Bouncer.
virtual bool fillMissingFields(std::map< std::string, AnyValue > &fields, const std::vector< std::string > &missing)
Fill missing fields caused by conversion from a different struct. Return whether fill succeeded...
std::vector< TypeInterface * > _memberTypes
static bool fillMissingFields(StructTypeInterface *type, std::map< std::string,::qi::AnyValue > &fields, const std::vector< std::string > &missing)
#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.
static bool canDropFields(void *, const std::vector< std::string > &)
virtual void adaptStorage(void **storage, void **adapted)=0
virtual std::vector< std::string > elementsName()
Get the names of the fields of the struct.
virtual void set(void **storage, unsigned int index, void *valStorage)
Set the fields of the struct at index (copies the value given)
StructTypeInterface * bounceType()
void * fieldStorage(C *inst, A accessor)
TypeInterface * fieldType(A)
std::pair< F, S > BackendType
virtual void * initializeStorage(void *ptr=0)
virtual void set(void **storage, const std::vector< void * > &)
Set all the fields of the struct (copies the values given in the vector)
virtual void set(void **storage, const std::vector< void * > &vals)
Set all the fields of the struct (copies the values given in the vector)
virtual bool fillMissingFields(std::map< std::string,::qi::AnyValue > &fields, const std::vector< std::string > &missing)
std::string normalizeClassName(const std::string &name)
void set(void **storage, unsigned int index, void *valStorage)
Set the fields of the struct at index (copies the value given)
virtual void * ptrFromStorage(void **s)
DefaultTypeImplMethods< T, TypeByPointerPOD< T > > Methods
virtual void * initializeStorage(void *ptr=0)=0