11 #ifndef RTIREFLEX_TYPECODE_MANIP_H
12 #define RTIREFLEX_TYPECODE_MANIP_H
18 #include <ndds/ndds_cpp.h>
28 #define GET_PRIMITIVE_TC_DEF(BASIC_TYPE, TYPECODE) \
29 static const DDS_TypeCode * \
30 get_primitive_tc(DDS_TypeCodeFactory * factory, \
31 const BASIC_TYPE *) { \
32 return factory->get_primitive_tc(TYPECODE); \
41 const DDS_TypeCode * tc,
42 DDS_UnsignedLong indent);
44 template <
size_t I,
class DimList>
47 template <
size_t I,
size_t Head,
size_t... Tail>
48 struct CopyDims <I, reflex::meta::dim_list<Head, Tail...>>
50 static void exec(DDS_UnsignedLongSeq & seq)
57 template <
size_t I,
size_t Last>
58 struct CopyDims<I, reflex::meta::dim_list<Last>>
60 static void exec(DDS_UnsignedLongSeq & seq)
66 template <
class Tuple,
size_t I,
size_t MAX_INDEX,
class Case>
67 struct MatchDefaultCase;
69 template <
class Tuple,
size_t I,
size_t MAX_INDEX,
class T,
int Tag,
int... Tags>
70 struct MatchDefaultCase<Tuple, I, MAX_INDEX, match::Case<T, Tag, Tags...>>
74 detail::MatchDefaultCase<Tuple,
77 typename std::tuple_element<I + 1, Tuple>::type
82 template <
class Tuple,
size_t MAX_INDEX,
class T,
int Tag,
int... Tags>
83 struct MatchDefaultCase<Tuple, MAX_INDEX, MAX_INDEX, match::Case<T, Tag, Tags...>>
88 template <
class Tuple,
size_t I,
size_t MAX_INDEX,
class T>
89 struct MatchDefaultCase<Tuple, I, MAX_INDEX, match::Case<T>>
94 template <
class Tuple,
size_t MAX_INDEX,
class T>
95 struct MatchDefaultCase<Tuple, MAX_INDEX, MAX_INDEX, match::Case<T>>
97 enum { value = MAX_INDEX };
100 template <
class TagType,
class... Cases>
101 struct DefaultCaseIndex;
103 template <
class TagType,
class... Cases>
104 struct DefaultCaseIndex<match::Union<TagType, Cases...>>
106 typedef typename match::Union<TagType, Cases...>::case_tuple_type CaseTuple;
109 MatchDefaultCase<CaseTuple,
112 typename std::tuple_element<1, CaseTuple>::type>::value
116 struct Primitive_TC_Helper
143 struct Enum_TC_Helper
145 template <
size_t I,
size_t MAX>
146 struct SetEnumMembers
148 static void exec(DDS_EnumMemberSeq & enum_seq,
149 std::vector<reflex::codegen::MemberInfo> & info_seq)
151 using namespace detail;
154 info_seq[I] = EnumDef<T>::template EnumMember<I>::info();
155 enum_seq[I].name =
const_cast<char *
>(info_seq[I].name.c_str());
156 enum_seq[I].ordinal = info_seq[I].value;
157 SetEnumMembers<I + 1, MAX>::exec(enum_seq, info_seq);
161 template <
size_t MAX>
162 struct SetEnumMembers<MAX, MAX>
164 static void exec(DDS_EnumMemberSeq & enum_seq,
165 std::vector<reflex::codegen::MemberInfo> & info_seq)
167 using namespace detail;
170 info_seq[MAX] = EnumDef<T>::template EnumMember<MAX>::info();
171 enum_seq[MAX].name =
const_cast<char *
>(info_seq[MAX].name.c_str());
172 enum_seq[MAX].ordinal = info_seq[MAX].value;
178 struct Struct_TC_Helper
181 static SafeTypeCode<T> get_typecode_struct(
185 DDS_TypeCodeFactory * factory =
186 DDS_TypeCodeFactory::get_instance();
188 std::string struct_name =
191 const char * type_name =
192 name ? name : struct_name.c_str();
195 DDS_ExceptionCode_t ex;
196 DDS_TypeCode *structTc =
197 factory->create_struct_tc(type_name,
198 DDS_StructMemberSeq(), ex);
200 SafeTypeCode<T> safetc(factory, structTc);
202 check_exception_code(
203 "get_typecode_struct: Unable to create struct typecode, error = ",
206 detail::TypelistIterator<
210 factory, safetc.get());
216 static SafeTypeCode<T> get_typecode_struct(
220 DDS_TypeCodeFactory * factory =
221 DDS_TypeCodeFactory::get_instance();
223 std::string struct_name =
226 const char * type_name =
227 name ? name : struct_name.c_str();
231 SafeTypeCode<BaseType> baseTc =
232 get_typecode_struct<BaseType>(
236 DDS_ExceptionCode_t ex;
237 DDS_TypeCode *valueTc =
238 factory->create_value_tc(
240 DDS_EXTENSIBLE_EXTENSIBILITY,
243 DDS_ValueMemberSeq(),
246 SafeTypeCode<T> aggregateTc(factory, valueTc);
248 check_exception_code(
249 "get_typecode_struct: Unable to create valuetype typecode, error = ",
252 detail::TypelistIterator<
256 ::add(factory, aggregateTc.get());
278 static SafeTypeCode<Str>
280 DDS_TypeCodeFactory * factory,
284 DDS_ExceptionCode_t ex;
286 SafeTypeCode<Str> stringTc(
291 check_exception_code(
292 "InnerTypeCodeBase::create_string_tc: Unable to create string typecode, error = ",
302 static SafeTypeCode<T> get_typecode(
303 DDS_TypeCodeFactory * factory,
312 return Struct_TC_Helper::get_typecode_struct<T>(
319 static SafeTypeCode<T> get_typecode(
320 DDS_TypeCodeFactory * factory,
324 return SafeTypeCode<T>(factory,
325 Primitive_TC_Helper::get_primitive_tc(factory, primitive));
330 static SafeTypeCode<T> get_typecode(
331 DDS_TypeCodeFactory * factory,
339 DDS_ExceptionCode_t ex;
340 DDS_EnumMemberSeq enum_seq;
341 std::vector<reflex::codegen::MemberInfo> info_seq(EnumDef<T>::size);
342 enum_seq.ensure_length(EnumDef<T>::size, EnumDef<T>::size);
343 Enum_TC_Helper<T>::template SetEnumMembers<0, EnumDef<T>::size - 1>::exec(enum_seq, info_seq);
345 SafeTypeCode<T> enumTc(
347 factory->create_enum_tc(EnumDef<T>::name(), enum_seq, ex));
349 check_exception_code(
350 "get_typecode: Unable to create enum typecode, error = ",
356 template <
class C,
size_t Bound>
357 static SafeTypeCode<reflex::match::Bounded<C, Bound>> get_typecode(
358 DDS_TypeCodeFactory * factory,
362 SafeTypeCode<typename C::value_type> innerTc
363 = TC_Helper::get_typecode(
365 static_cast<typename C::value_type *>(0));
367 DDS_ExceptionCode_t ex;
368 SafeTypeCode<reflex::match::Bounded<C, Bound>> seqTc
370 factory->create_sequence_tc(Bound, innerTc.get(), ex));
372 check_exception_code(
373 "get_typecode: Unable to create sequence typecode, error = ",
380 static SafeTypeCode<C> get_typecode(
381 DDS_TypeCodeFactory * factory,
385 SafeTypeCode<typename reflex::type_traits::container_traits<C>::value_type> innerTc
386 = TC_Helper::get_typecode(
390 DDS_ExceptionCode_t ex;
391 SafeTypeCode<C> seqTc(
397 check_exception_code(
398 "get_typecode: Unable to create sequence typecode, error = ",
404 template <
class T,
size_t N>
405 static SafeTypeCode<std::array<T, N>> get_typecode(
406 DDS_TypeCodeFactory * factory,
407 const std::array<T, N> *)
410 SafeTypeCode<BasicType> basicTc
411 = TC_Helper::get_typecode(
413 static_cast<BasicType *>(0));
415 DDS_UnsignedLongSeq dims;
418 dims.ensure_length(DimList::size, DimList::size);
419 detail::CopyDims<0, DimList>::exec(dims);
421 DDS_ExceptionCode_t ex;
422 SafeTypeCode<std::array<T, N>> arrayTc(
424 factory->create_array_tc(dims, basicTc.get(), ex));
426 check_exception_code(
427 "InnerTypeCodeBase::create_array_tc: Unable to create array typecode, error = ",
433 template <
size_t Bound>
434 static SafeTypeCode<reflex::match::Bounded<std::string, Bound>>
436 DDS_TypeCodeFactory * factory,
439 DDS_ExceptionCode_t ex;
441 SafeTypeCode<match::Bounded<std::string, Bound>>
442 stringTc(factory, factory->create_string_tc(Bound, ex));
444 check_exception_code(
445 "get_typecode::create_string_tc: Unable to create string typecode, error = ",
452 static SafeTypeCode<match::Range<T>> get_typecode(
453 DDS_TypeCodeFactory * factory,
456 SafeTypeCode<typename reflex::meta::remove_reference<T>::type> innerTc
457 = TC_Helper::get_typecode(
461 DDS_ExceptionCode_t ex;
462 SafeTypeCode<match::Range<T>> seqTc(
464 factory->create_sequence_tc(
469 check_exception_code(
470 "get_typecode: Unable to create sequence typecode, error = ",
509 static SafeTypeCode<Opt> get_typecode(
510 DDS_TypeCodeFactory * factory,
522 SafeTypeCode<OptValuetype> innerTc =
523 TC_Helper::get_typecode(
525 static_cast<OptValuetype *>(0));
527 DDS_ExceptionCode_t ex = DDS_NO_EXCEPTION_CODE;
528 SafeTypeCode<Opt> optionalTc(
530 factory->clone_tc(innerTc.get(), ex));
532 check_exception_code(
533 "get_typecode<optional>: Unable to clone typecode, error = ",
539 template <
class T,
size_t Bound>
540 static SafeTypeCode<match::BoundedRange<T, Bound>> get_typecode(
541 DDS_TypeCodeFactory * factory,
544 SafeTypeCode<typename reflex::meta::remove_reference<T>::type> innerTc
545 = TC_Helper::get_typecode(
549 DDS_ExceptionCode_t ex = DDS_NO_EXCEPTION_CODE;
550 SafeTypeCode<match::BoundedRange<T, Bound>> seqTc(
552 factory->create_sequence_tc(Bound, innerTc.get(), ex));
554 check_exception_code(
555 "get_typecode<BoundedRange>: Unable to create sequence typecode, error = ",
561 template <
class... Args>
563 DDS_TypeCodeFactory * factory,
566 DDS_ExceptionCode_t ex = DDS_NO_EXCEPTION_CODE;
574 check_exception_code(
575 "get_typecode<Sparse>: Unable to create sparse typecode, error = ",
579 ::reflex::match::Sparse<Args...>::raw_tuple_type RawTuple;
581 TypelistIterator<RawTuple,
584 factory, sparseTc.get());
589 template <
class TagType,
class... Cases>
592 DDS_TypeCodeFactory * factory,
595 SafeTypeCode<TagType> discTc =
596 TC_Helper::get_typecode(
598 static_cast<TagType *>(0));
603 DDS_UnionMemberSeq umember_seq;
605 umember_seq.ensure_length(ncases, ncases);
607 TC_Helper::add_union_members(
612 DDS_ExceptionCode_t ex = DDS_NO_EXCEPTION_CODE;
617 detail::DefaultCaseIndex<match::Union<TagType, Cases...>>::value,
621 check_exception_code(
622 "get_typecode<Union>: Unable to create union typecode, error = ",
625 TypelistIterator<CaseTuple,
633 static SafeTypeCode<T> get_typecode(
634 DDS_TypeCodeFactory * factory,
640 SafeTypeCode<InnerType> innerTc =
641 TC_Helper::get_typecode(
643 static_cast<InnerType *>(0));
647 DDS_UnsignedLongSeq dims;
648 dims.ensure_length(DimList::size, DimList::size);
649 detail::CopyDims<0, DimList>::exec(dims);
651 DDS_ExceptionCode_t ex = DDS_NO_EXCEPTION_CODE;
652 SafeTypeCode<T> arrayTc(
654 factory->create_array_tc(dims, innerTc.get(), ex));
656 check_exception_code(
657 "add_member_impl<BuiltInArray>: Unable to create array typecode, error = ",
665 template <
class TagType,
class... Cases>
666 static void add_union_members(
667 DDS_TypeCodeFactory * factory,
668 DDS_UnionMemberSeq & seq,
673 TypelistIterator<CaseTuple,
681 void add_member_impl(
682 DDS_TypeCodeFactory * factory,
683 DDS_TypeCode * outerTc,
684 const char * member_name,
690 DDS_ExceptionCode_t ex;
691 SafeTypeCode<T> innerTc =
692 TC_Helper::get_typecode(
694 static_cast<T *>(0));
697 (outerTc->kind(ex) == DDS_TK_SPARSE) ?
id : DDS_TYPECODE_MEMBER_ID_INVALID;
699 outerTc->add_member(member_name,
705 detail::check_exception_code(
706 "add_member_impl<T>: Unable to add inner typecode, error = ",
759 void add_member_forward(
760 DDS_TypeCodeFactory * factory,
761 DDS_TypeCode * outerTc,
762 const char * member_name,
769 if (flags == DDS_TYPECODE_KEY_MEMBER)
771 std::stringstream stream;
772 stream <<
"add_member_forward: optinal member "
774 <<
" can't be a key.";
775 throw std::runtime_error(stream.str());
778 flags = DDS_TYPECODE_NONKEY_MEMBER;
787 const_cast<T *>(tptr));
790 template <
size_t I,
class Case>
793 template <
size_t I,
class T,
int Head,
int... Tail>
794 struct LabelAdder<I, match::Case<T, Head, Tail...>>
796 enum { count = 1 +
sizeof...(Tail) };
798 static void exec(DDS_LongSeq & seq)
801 LabelAdder<I + 1, match::Case<T, Tail...>>::exec(seq);
805 template <
size_t I,
class T,
int Last>
806 struct LabelAdder<I, match::Case<T, Last>>
810 static void exec(DDS_LongSeq & seq)
816 template <
size_t I,
class T>
817 struct LabelAdder<I, match::Case<T>>
821 static void exec(DDS_LongSeq & seq)
828 template <
class Case>
830 DDS_TypeCodeFactory * factory,
831 const char * member_name,
832 DDS_UnionMember & umember)
837 DDS_LongSeq label_seq;
838 label_seq.ensure_length(
839 LabelAdder<0, Case>::count,
840 LabelAdder<0, Case>::count);
841 LabelAdder<0, Case>::exec(label_seq);
843 umember.name =
const_cast<char *
>(member_name);
850 TC_Helper::get_typecode(
852 static_cast<CaseTypeNoRef *>(0)).release();
854 umember.labels = label_seq;
894 template <
class Case>
895 void case_add_forward(
896 DDS_TypeCodeFactory * factory,
897 const char * member_name,
898 DDS_UnionMember & umember)
900 case_add_impl<Case>(factory, member_name, umember);
905 DDS_TypeCodeFactory * factory,
914 DDS_TypeCodeFactory * factory,
918 DDS_ExceptionCode_t ex;
919 factory->delete_tc(tc, ex);
921 if (ex != DDS_NO_EXCEPTION_CODE)
923 std::cerr <<
"deleteTc: Unable to delete typecode, error = "
924 << detail::get_readable_ex_code(ex)
931 void deleteTc_forward(
932 DDS_TypeCodeFactory * factory,
935 deleteTc_impl<TC>(factory, tc);
942 #ifndef REFLEX_NO_HEADER_ONLY
943 #include "reflex/../../src/typecode_manip.cxx"
946 #endif // RTIREFLEX_TYPECODE_MANIP_H
Definition: enable_if.h:413
Definition: disc_union.h:139
Definition: disc_union.h:27
Definition: enable_if.h:329
#define REFLEX_DECLSPEC
Definition: dllexport.h:36
boost::any_range< T, boost::forward_traversal_tag, T, std::ptrdiff_t > Range
Definition: enable_if.h:95
Definition: enable_if.h:132
#define GET_PRIMITIVE_TC_DEF(BASIC_TYPE, TYPECODE)
Definition: typecode_manip.h:28
Definition: enable_if.h:344
#define REFLEX_DLL_EXPORT
Definition: dllexport.h:35
Definition: enable_if.h:284
Definition: member_names.h:99
Definition: enable_if.h:251
Definition: enable_if.h:215
Definition: enable_if.h:353
Definition: enable_if.h:466
unsigned char octet_t
Definition: dd_extra.h:48
reflex::meta::false_type has_base
Definition: enable_if.h:467
container_traits_impl< C, is_container< C >::value >::value_type value_type
Definition: enable_if.h:447
Definition: enable_if.h:473
Definition: enable_if.h:479
Definition: enable_if.h:302