RefleX
Build DDS Applications in Modern C++ without IDL
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Macros Pages
adapt_macros.h
Go to the documentation of this file.
1 /*********************************************************************************************
2 (c) 2005-2014 Copyright, Real-Time Innovations, Inc. All rights reserved.
3 RTI grants Licensee a license to use, modify, compile, and create derivative works
4 of the Software. Licensee has the right to distribute object form only for use with RTI
5 products. The Software is provided "as is", with no warranty of any type, including
6 any warranty for fitness for any purpose. RTI is under no obligation to maintain or
7 support the Software. RTI shall not be liable for any incidental or consequential
8 damages arising out of the use or inability to use the software.
9 **********************************************************************************************/
10 
18 #ifdef REFLEX_DOXYGEN
19 
23 #define REFLEX_STATIC_STRING_BOUND
24 
28 #define REFLEX_STATIC_CONTAINER_BOUND
29 
30 #endif // REFLEX_DOXYGEN
31 
69 #define REFLEX_ENUM_DEF_CUSTOM(EnumType, Name, Size) \
70 namespace reflex { namespace codegen { \
71  template <> \
72  struct EnumDef<EnumType> \
73  { \
74  static const char *name() { \
75  return Name; \
76  } \
77  \
78  enum { is_enum = true }; \
79  static const unsigned int size = Size; \
80  \
81  template <unsigned Index> \
82  struct EnumMember { \
83  static MemberInfo info(); \
84  }; \
85  }; \
86 } } // namespace reflex::detail
87 
99 #define REFLEX_ENUM_MEMBER_DEF_CUSTOM(EnumType, Index, Name, Ordinal) \
100 namespace reflex { namespace codegen { \
101  template<> \
102  inline MemberInfo \
103  EnumDef<EnumType>::EnumMember<Index>::info() \
104  { \
105  return MemberInfo(Name, Ordinal); \
106  } \
107 } } // namespace reflex::detail
108 
168 #define REFLEX_STRUCT_NAME_DEF_CUSTOM(FullyQualifiedType, Name) \
169 namespace reflex { namespace codegen { \
170  template <> \
171  struct StructName<FullyQualifiedType> \
172  { \
173  static std::string get() { \
174  return Name; \
175  } \
176  }; \
177 } } // namespace reflex::detail
178 
190 #define REFLEX_STRUCT_MEMBER_DEF_CUSTOM(FullyQualifiedType, Index, Name, Flags) \
191 namespace reflex { namespace codegen { \
192  template <> \
193  struct MemberTraits<FullyQualifiedType, Index> \
194  { \
195  static MemberInfo member_info() \
196  { \
197  return MemberInfo(Name, Flags); \
198  } \
199  }; \
200 } } // namespace reflex::detail
201 
230 #define REFLEX_ADAPT_ENUM(EnumType, Attributes) \
231 namespace reflex { namespace codegen { \
232  template <> \
233  struct EnumDef<EnumType> \
234  { \
235  static const char *name() { \
236  return \
237  detail::NameHelper::basename \
238  (#EnumType); \
239  } \
240  \
241  enum { is_enum = true }; \
242  \
243  static const unsigned int size = \
244  BOOST_PP_SEQ_SIZE(RTI_PARENTHESIZE(Attributes)); \
245  \
246  template <unsigned Index> \
247  struct EnumMember { \
248  static MemberInfo info(); \
249  }; \
250  }; \
251 } } /* namespace reflex::detail */ \
252 BOOST_PP_SEQ_FOR_EACH_I(RTI_ENUM_MEMBER_INFO_INTERNAL, \
253  EnumType, \
254  RTI_PARENTHESIZE(Attributes))
255 
302 #define REFLEX_ADAPT_STRUCT(Type,Attributes) \
303  RTI_STRUCT_NAME_DEF_INTERNAL(Type) \
304  RTI_MEMBER_TRAITS(Type, Attributes) \
305  BOOST_FUSION_ADAPT_STRUCT(Type, RTI_TRANSFORM_TRIPLETS_TO_PAIRS(Attributes))
306 
317 #define REFLEX_ADAPT_VALUETYPE(Type, Base, Attributes) \
318  RTI_INHERITANCE_TRAITS(Type, Base) \
319  REFLEX_ADAPT_STRUCT(Type, Attributes)
320 
321 // The parenthesis below are essential for the RTI_DUMMY macro.
323 #define REFLEX_OPTIONAL (DDS_TYPECODE_NONKEY_MEMBER)
324 
326 #define REFLEX_KEY (DDS_TYPECODE_KEY_MEMBER)
327 
329 #define REFLEX_REQUIRED (DDS_TYPECODE_NONKEY_REQUIRED_MEMBER)
330 
332 #define REFLEX_EXTENDS(X) X
333 
334 #ifndef REFLEX_DOXYGEN
335 
336 #define RTI_STRUCT_NAME_DEF_INTERNAL(FullyQualifiedType) \
337  namespace reflex { namespace codegen { \
338  template <> \
339  struct StructName<FullyQualifiedType> \
340  { \
341  static std::string get() \
342  { \
343  return detail::NameHelper::basename(#FullyQualifiedType); \
344  } \
345  }; \
346 } } // namespace reflex::detail
347 
348 #define RTI_INHERITANCE_TRAITS(Derived, Base) \
349 namespace reflex { namespace type_traits { \
350  template <> \
351  struct inheritance_traits<Derived> { \
352  typedef true_type has_base; \
353  typedef Base basetype; \
354  }; \
355 } } // namespace reflex::detail
356 
357 #ifdef RTI_WIN32
358 #define RTI_DUMMY(X) X
359 #define RTI_DUMMY_VAR DDS_Octet RTI_DUMMY=REFLEX_REQUIRED
360 
361 #define RTI_GET_NAME_FLAGS(Type, Name, ...) \
362  #Name, RTI_DUMMY ## __VA_ARGS__
363 #else
364 // Not needed outside Visual Studio
365 #define RTI_DUMMY_VAR
366 
367 #define RTI_WITH_FLAG(Time, Name, Flag) #Name, Flag
368 #define RTI_WITHOUT_FLAG(Time, Name) #Name, REFLEX_REQUIRED
369 
370 #define RTI_PUSH_4TH_ARG(arg1, arg2, arg3, arg4, ...) arg4
371 
372 // A pair will push out RTI_WITHOUT_FLAGS
373 // A triplet will push out RTI_WITH_FLAGS
374 #define RTI_FLAGS_CHOOSER(...) RTI_PUSH_4TH_ARG(__VA_ARGS__, RTI_WITH_FLAG, RTI_WITHOUT_FLAG)
375 
376 // __VA_ARGS__ is either a pair or a triplet.
377 #define RTI_GET_NAME_FLAGS(...) \
378  RTI_FLAGS_CHOOSER(__VA_ARGS__)(__VA_ARGS__)
379 #endif
380 
381 #define RTI_GET_NAME_ORDINAL(Name, Ordinal) #Name, Ordinal
382 
383 // Note that Attr is already has parenthesis.
384 // Attr is either a pair or a triplet
385 // RTI_GET_NAME_FLAGS macro eats the parenthesis around Attr.
386 // RTI_DUMMY_VAR is used on for Win32 only
387 #define RTI_MEMBER_INFO_INTERNAL(R,Data,I,Attr) \
388 namespace reflex { namespace codegen { \
389  template<> \
390  MemberInfo MemberTraits<Data, I>::member_info() \
391  { \
392  RTI_DUMMY_VAR; \
393  return MemberInfo( \
394  RTI_GET_NAME_FLAGS Attr); \
395  } \
396 } } // namespace reflex::detail
397 
398 #define RTI_FILLER_0(...) ((__VA_ARGS__)) RTI_FILLER_1
399 #define RTI_FILLER_1(...) ((__VA_ARGS__)) RTI_FILLER_0
400 #define RTI_FILLER_0_END
401 #define RTI_FILLER_1_END
402 
403 // Convert (a,1,A)(b,2,B)(c,3,C) into ((a,1,A))((b,2,B))((c,3,C))
404 // Otherwise preprocessor will get confused due to commas.
405 // The PARENTHESIZE macro expands as follows:
406 //
407 // RTI_FILLER_0 Attr ---->
408 // RTI_FILLER_0 (a,1,A)(b,2,B)(c,3,C) ---->
409 // ((a,1,A)) RTI_FILLER_1 (b,2,B)(c,3,C) ---->
410 // ((a,1,A)) ((b,2,B)) RTI_FILLER_0 (c,3,C) ---->
411 // ((a,1,A)) ((b,2,B)) ((c,3,C)) RTI_FILLER_1 ---->
412 // BOOST_PP_CAT(((a,1,A)) ((b,2,B)) ((c,3,C)) RTI_FILLER_1, _END) ---->
413 // ((a,1,A)) ((b,2,B)) ((c,3,C)) RTI_FILLER_1_END ---->
414 // ((a,1,A)) ((b,2,B)) ((c,3,C)) ---->
415 // voila!!!
416 
417 #define RTI_PARENTHESIZE(Attr) BOOST_PP_CAT(RTI_FILLER_0 Attr,_END)
418 
419 #define RTI_MEMBER_TRAITS(Name,Attributes) \
420  BOOST_PP_SEQ_FOR_EACH_I(RTI_MEMBER_INFO_INTERNAL,Name,RTI_PARENTHESIZE(Attributes))
421 
422 #define RTI_SKIP_LAST_0(X, Y, ...) (X, Y) RTI_SKIP_LAST_1
423 #define RTI_SKIP_LAST_1(X, Y, ...) (X, Y) RTI_SKIP_LAST_0
424 #define RTI_SKIP_LAST_0_END
425 #define RTI_SKIP_LAST_1_END
426 
427 
428 // Convert (a,1,A)(b,2,B)(c,3,C) into (a,1)(b,2)(c,3)
429 // Otherwise BOOST_FUSION_ADAPT_STRUCT macro will be confused.
430 // The TRANSFORM macro expands as follows:
431 //
432 // RTI_SKIP_LAST_0 Attr ---->
433 // RTI_SKIP_LAST_0 (a,1,A)(b,2,B)(c,3,C) ---->
434 // (a,1) RTI_SKIP_LAST_1 (b,2,B)(c,3,C) ---->
435 // (a,1) (b,2) RTI_SKIP_LAST_0 (c,3,C) ---->
436 // (a,1) (b,2) (c,3) RTI_SKIP_LAST_1 ---->
437 // BOOST_PP_CAT((a,1) (b,2) (c,3) RTI_SKIP_LAST_1, _END) ---->
438 // (a,1) (b,2) (c,3) RTI_SKIP_LAST_1_END ---->
439 // (a,1) (b,2) (c,3) ---->
440 // voila!!!
441 
442 #define RTI_TRANSFORM_TRIPLETS_TO_PAIRS(Attributes) \
443  BOOST_PP_CAT(RTI_SKIP_LAST_0 Attributes, _END)
444 
445 
446 #define RTI_ENUM_MEMBER_INFO_INTERNAL(R,EnumType,Index,Attr) \
447 namespace reflex { namespace codegen { \
448  template<> \
449  MemberInfo EnumDef<EnumType>::EnumMember<Index>::info() \
450  { \
451  return MemberInfo(RTI_GET_NAME_ORDINAL Attr); \
452  } \
453 } } // namespace reflex::detail
454 
455 #endif // REFLEX_DOXYGEN
456