11 #ifndef RTIREFLEX_DD_MANIP_H
12 #define RTIREFLEX_DD_MANIP_H
21 #include "ndds/ndds_cpp.h"
29 #include <boost/fusion/support/is_sequence.hpp>
30 #include <boost/fusion/include/is_sequence.hpp>
32 #define SET_MEMBER_VALUE_DECL(TYPE) \
33 REFLEX_DLL_EXPORT static void set_member_value( \
34 DDS_DynamicData & instance, \
35 const MemberAccess &ma, \
39 #define GET_MEMBER_VALUE_DECL(TYPE) \
40 REFLEX_DLL_EXPORT static void get_member_value( \
41 const DDS_DynamicData & instance, \
42 const MemberAccess &ma, \
61 static const unsigned int size = 128;
73 T * primitive_ptr_cast(T * t,
76 !std::is_same<signed char, T>::value>::type * = 0)
84 bool do_serialize(T &)
90 uint32_t array_length(
const T &)
95 struct set_member_overload_resolution_helper
120 static void set_member_value(
121 DDS_DynamicData & instance,
122 const MemberAccess &ma,
127 if (ma.access_by_id()) {
128 rc = instance.set_string(NULL, ma.get_id(), val.c_str());
131 rc = instance.set_string(ma.get_name(),
132 DDS_DYNAMIC_DATA_MEMBER_ID_UNSPECIFIED,
135 detail::check_retcode(
"DDS_DynamicData::set_string error = ", rc);
139 static void set_member_value(
140 DDS_DynamicData & instance,
141 const MemberAccess &ma,
147 if (ma.access_by_id())
148 rc = instance.set_long(NULL, ma.get_id(), val);
150 rc = instance.set_long(
152 DDS_DYNAMIC_DATA_MEMBER_ID_UNSPECIFIED,
155 detail::check_retcode(
"set_member_value: set_long (for enums) error = ", rc);
162 template <
class Typelist>
163 static void set_member_value(
164 DDS_DynamicData & instance,
165 const MemberAccess & ma,
166 const Typelist & val,
173 DDS_DynamicData inner(NULL, DDS_DYNAMIC_DATA_PROPERTY_DEFAULT);
174 SafeBinder binder(instance, inner, ma);
182 static void set_member_value(
183 DDS_DynamicData & instance,
184 const MemberAccess &ma,
194 if (do_serialize(val))
196 typename DynamicDataSeqTraits<typename reflex::type_traits::container_traits<C>::value_type>::type seq;
197 seq.ensure_length(val.size(), val.size());
200 for (
auto const &elem : val) {
205 DDS_ReturnCode_t rc = set_sequence(instance, ma, seq);
206 detail::check_retcode(
"set_member_value: Error setting (bool/enum) seq, error = ", rc);
212 static void set_member_value(
213 DDS_DynamicData & instance,
214 const MemberAccess &ma,
223 if (do_serialize(val))
225 DDS_DynamicData seq_member(NULL, DDS_DYNAMIC_DATA_PROPERTY_DEFAULT);
226 SafeBinder binder(instance, seq_member, ma);
240 for (
auto const &elem : val)
242 set_member_value(seq_member, MemberAccess::BY_ID(i + 1), elem);
249 DDS_DynamicData & instance,
250 const MemberAccess &ma,
251 const std::vector<long double> & val,
255 static void set_member_value(
256 DDS_DynamicData & instance,
257 const MemberAccess &ma,
258 const std::vector<T> & val,
267 typename DynamicDataSeqTraits<T>::type seq;
268 std::vector<T> & nc_val =
const_cast<std::vector<T> &
>(val);
269 if (seq.loan_contiguous(primitive_ptr_cast(&nc_val[0]), val.size(), val.capacity()) !=
true)
271 throw std::runtime_error(
"set_member_value: sequence loaning failed");
274 DDS_ReturnCode_t rc = set_sequence(instance, ma, seq);
276 detail::check_retcode(
"set_member_value: Error setting sequence, error = ", rc);
282 static void set_member_value_range(
283 DDS_DynamicData & instance,
284 const MemberAccess &ma,
288 typename DynamicDataSeqTraits<T>::type seq;
290 size_t size = boost::distance(range);
291 seq.ensure_length(size, size);
294 for (
auto const &elem : range)
300 DDS_ReturnCode_t rc = set_sequence(instance, ma, seq);
301 detail::check_retcode(
"set_member_value: Error setting sequence, error = ", rc);
305 static void set_member_value_range(
306 DDS_DynamicData & instance,
307 const MemberAccess &ma,
311 DDS_DynamicData seq_member(NULL, DDS_DYNAMIC_DATA_PROPERTY_DEFAULT);
312 SafeBinder binder(instance, seq_member, ma);
314 size_t size = boost::distance(range);
325 for (
typename match::Range<T>::const_iterator iter = boost::begin(range);
326 iter != boost::end(range);
330 (seq_member, MemberAccess::BY_ID(i + 1), *iter);
337 static void set_member_value(
338 DDS_DynamicData & instance,
339 const MemberAccess &ma,
342 set_member_value_range(instance, ma, range);
345 template <
class T,
size_t Bound>
346 static void set_member_value(
347 DDS_DynamicData & instance,
348 const MemberAccess &ma,
351 set_member_value_range(instance, ma, range);
354 template <
class... Args>
355 static void set_member_value(
356 DDS_DynamicData & instance,
357 const MemberAccess & ma,
360 DDS_DynamicData inner(NULL, DDS_DYNAMIC_DATA_PROPERTY_DEFAULT);
361 SafeBinder binder(instance, inner, ma);
366 template <
class TagType,
class... Cases>
367 static void set_member_value(
368 DDS_DynamicData & instance,
369 const MemberAccess & ma,
372 DDS_DynamicData inner(NULL, DDS_DYNAMIC_DATA_PROPERTY_DEFAULT);
373 SafeBinder binder(instance, inner, ma);
376 match::Union<TagType, Cases...>::case_tuple_type CaseTuple;
378 typedef TypelistIterator<
387 MemberAccess::BY_ID(-999),
392 template <
class T,
size_t Dim>
393 static void set_member_value(
394 DDS_DynamicData & instance,
395 const MemberAccess & ma,
402 DDS_DynamicData arr_member(NULL, DDS_DYNAMIC_DATA_PROPERTY_DEFAULT);
403 SafeBinder binder(instance, arr_member, ma);
408 DDS_UnsignedLong length = array_length(val);
409 for (DDS_UnsignedLong i = 0; i < length; ++i)
411 set_member_value(arr_member, MemberAccess::BY_ID(i + 1), arr[i]);
415 template <
class T,
size_t Dim>
416 static void set_member_value(
417 DDS_DynamicData & instance,
418 const MemberAccess &ma,
428 DDS_ReturnCode_t rc =
429 detail::set_array(instance, ma, array_length(val), arr);
431 detail::check_retcode(
"set_member_value: Error setting array, error = ", rc);
434 template <
class T,
size_t Dim>
435 static void set_member_value(
436 DDS_DynamicData & instance,
437 const MemberAccess & ma,
438 const std::array<T, Dim> & val,
444 DDS_DynamicData arr_member(NULL, DDS_DYNAMIC_DATA_PROPERTY_DEFAULT);
445 SafeBinder binder(instance, arr_member, ma);
450 DDS_UnsignedLong length = array_length(val);
451 for (DDS_UnsignedLong i = 0; i < length; ++i)
453 set_member_value(arr_member, MemberAccess::BY_ID(i + 1), arr[i]);
457 template <
class T,
size_t Dim>
458 static void set_member_value(
459 DDS_DynamicData & instance,
460 const MemberAccess &ma,
461 const std::array<T, Dim> & val,
470 DDS_ReturnCode_t rc =
471 detail::set_array(instance, ma, array_length(val), arr);
473 detail::check_retcode(
"set_member_value: Error setting array, error = ", rc);
496 template <
typename Opt>
497 static void set_member_value(
498 DDS_DynamicData & instance,
499 const MemberAccess &ma,
505 set_member_value(instance, ma, *opt);
509 template <
class T,
size_t Bound>
510 static void set_member_value(
511 DDS_DynamicData & instance,
512 const MemberAccess &ma,
515 set_member_value(instance, ma, static_cast<const T &>(val));
520 void set_member_forward(
521 DDS_DynamicData & instance,
522 const MemberAccess &ma,
525 set_member_overload_resolution_helper::
526 set_member_value(instance, ma, val);
532 struct get_member_overload_resolution_helper
557 static void get_member_value(
558 const DDS_DynamicData & instance,
559 const MemberAccess &ma,
564 char * buf = raw.buf;
565 DDS_UnsignedLong size = RawStorage::size;
567 const char * member_name =
568 ma.access_by_id() ? NULL : ma.get_name();
569 int id = ma.access_by_id() ?
570 ma.get_id() : DDS_DYNAMIC_DATA_MEMBER_ID_UNSPECIFIED;
573 DDS_ReturnCode_t rc =
574 instance.get_string(buf, &size, member_name,
id);
576 if (rc == DDS_RETCODE_OK)
580 else if (rc == DDS_RETCODE_OUT_OF_RESOURCES)
585 rc = instance.get_string(buf, &size, member_name,
id);
586 detail::check_retcode(
"DDS_DynamicData::get_string failed. error = ", rc);
588 DDS_String_free(buf);
591 detail::check_retcode(
"DDS_DynamicData::get_string failed. error = ", rc);
597 static void get_member_value(
598 const DDS_DynamicData & instance,
599 const MemberAccess &ma,
606 const char * member_name =
607 ma.access_by_id() ? NULL : ma.get_name();
609 int id = ma.access_by_id() ?
610 ma.get_id() : DDS_DYNAMIC_DATA_MEMBER_ID_UNSPECIFIED;
612 rc = instance.get_long(out, member_name,
id);
613 detail::check_retcode(
"get_member_value: get_long (for enums) failed, error = ", rc);
619 using namespace reflex::codegen;
623 template <
class Typelist>
629 static void get_member_value(
630 const DDS_DynamicData & instance,
631 const MemberAccess &ma,
639 DDS_DynamicData inner(NULL, DDS_DYNAMIC_DATA_PROPERTY_DEFAULT);
640 SafeBinder binder(instance, inner, ma);
647 static void right_size(C &c,
size_t size)
653 template <
class T,
class Alloc>
654 static void right_size(std::vector<T, Alloc> & v,
size_t size)
659 template <
class T,
class Alloc>
660 static void right_size(std::list<T, Alloc> & l,
size_t size)
665 template <
class T,
class Comp,
class Alloc>
666 static void right_size(std::set<T, Comp, Alloc> & s,
size_t)
673 template <
class Key,
class T,
class Comp,
class Alloc>
674 static void right_size(std::map<Key, T, Comp, Alloc> & m,
size_t)
681 template <
class Iter,
class U>
682 static void primitive_assign(Iter dest, U src)
684 *dest =
static_cast<typename std::iterator_traits<Iter>::value_type
>(src);
688 static void primitive_assign(std::vector<bool>::iterator dest,
691 *dest = src ?
true :
false;
701 template <
class Seq,
class C>
702 static void copy_primitive_seq(
709 for (
size_t i = 0; i < count; ++i, ++iter)
714 primitive_assign(iter, seq[i]);
718 template <
class Seq,
class T,
class Key,
class Alloc>
719 static void copy_primitive_seq(
722 std::set<T, Key, Alloc> & s)
724 for (
size_t i = 0; i < count; ++i)
729 s.insert(
static_cast<
730 typename std::set<T, Key, Alloc>::value_type
>(seq[i]));
738 static void get_member_value(
739 const DDS_DynamicData & instance,
740 const MemberAccess &ma,
750 DDS_DynamicDataMemberInfo seq_info;
752 const char * member_name =
753 ma.access_by_id() ? NULL : ma.get_name();
754 int id = ma.access_by_id() ?
755 ma.get_id() : DDS_DYNAMIC_DATA_MEMBER_ID_UNSPECIFIED;
757 instance.get_member_info(seq_info, member_name,
id);
758 right_size(val, seq_info.element_count);
760 if (seq_info.element_count > 0)
762 typename DynamicDataSeqTraits<typename reflex::type_traits::container_traits<C>::value_type>::type seq;
763 seq.ensure_length(seq_info.element_count,
764 seq_info.element_count);
766 DDS_ReturnCode_t rc = detail::get_sequence(instance, seq, ma);
767 detail::check_retcode(
"get_member_value: get_sequence error = ", rc);
768 copy_primitive_seq(seq, seq_info.element_count, val);
773 template <
class Seq,
class C>
775 static void copy_complex_seq(
786 assert(c.size() == count);
791 get_member_value(seq, MemberAccess::BY_ID(i + 1), elem);
797 template <
class Seq,
class Key,
class T,
class Comp,
class Alloc>
799 static void copy_complex_seq(
802 std::map<Key, T, Comp, Alloc> & map)
806 for (
size_t i = 0; i < count; ++i)
808 typedef typename std::map<Key, T, Comp, Alloc>::value_type PairType;
809 std::pair<typename reflex::meta::remove_const<typename PairType::first_type>::type,
810 typename PairType::second_type> temp;
811 get_member_value(seq, MemberAccess::BY_ID(i + 1), temp);
812 map.insert(std::move(temp));
817 template <
class Seq,
class T,
class Key,
class Alloc>
819 static void copy_complex_seq(
822 std::set<T, Key, Alloc> & s)
826 for (
size_t i = 0; i < count; ++i)
832 get_member_value(seq, MemberAccess::BY_ID(i + 1), temp);
833 s.insert(std::move(temp));
841 static void get_member_value(
842 const DDS_DynamicData & instance,
843 const MemberAccess &ma,
851 DDS_DynamicData seq_member(NULL, DDS_DYNAMIC_DATA_PROPERTY_DEFAULT);
852 SafeBinder binder(instance, seq_member, ma);
854 DDS_DynamicDataInfo seq_info;
855 seq_member.get_info(seq_info);
857 right_size(val, seq_info.member_count);
858 copy_complex_seq(seq_member, seq_info.member_count, val);
863 const DDS_DynamicData & instance,
864 const MemberAccess &ma,
865 std::vector<long double> & val,
869 static void get_member_value(
870 const DDS_DynamicData & instance,
871 const MemberAccess &ma,
872 std::vector<T> & val,
879 DDS_DynamicDataMemberInfo seq_info;
881 const char * member_name =
882 ma.access_by_id() ? NULL : ma.get_name();
883 int id = ma.access_by_id() ?
884 ma.get_id() : DDS_DYNAMIC_DATA_MEMBER_ID_UNSPECIFIED;
886 instance.get_member_info(seq_info, member_name,
id);
887 right_size(val, seq_info.element_count);
889 if (seq_info.element_count > 0)
891 typename DynamicDataSeqTraits<T>::type seq;
892 if (seq.loan_contiguous(primitive_ptr_cast(&val[0]), val.size(), val.capacity()) !=
true)
894 throw std::runtime_error(
"get_member_value: sequence loaning failed");
897 DDS_ReturnCode_t rc = detail::get_sequence(instance, seq, ma);
899 detail::check_retcode(
"get_member_value: get_sequence error = ", rc);
903 template <
class T,
size_t Bound>
904 static void get_member_value(
905 const DDS_DynamicData & instance,
906 const MemberAccess &ma,
909 get_member_value(instance, ma, static_cast<T &>(val));
917 static void get_member_value_range(
918 const DDS_DynamicData & instance,
919 const MemberAccess &ma,
925 typename DynamicDataSeqTraits<T>::type seq;
926 DDS_DynamicDataMemberInfo seq_info;
928 const char * member_name =
929 ma.access_by_id() ? NULL : ma.get_name();
930 int id = ma.access_by_id() ?
931 ma.get_id() : DDS_DYNAMIC_DATA_MEMBER_ID_UNSPECIFIED;
933 instance.get_member_info(seq_info, member_name,
id);
934 seq.ensure_length(seq_info.element_count,
935 seq_info.element_count);
937 if (seq_info.element_count > 0)
939 DDS_ReturnCode_t rc = detail::get_sequence(instance, seq, ma);
940 detail::check_retcode(
"get_member_value: get_sequence error = ", rc);
942 if (boost::distance(range) < seq_info.element_count) {
943 throw std::runtime_error(
"get_member_value: Insufficient range");
946 typename match::Range<T>::iterator iter = boost::begin(range);
947 for (
size_t i = 0; i < seq_info.element_count; ++i, ++iter)
950 *iter =
static_cast<T
>(seq[i]);
956 static void get_member_value_range(
957 const DDS_DynamicData & instance,
958 const MemberAccess &ma,
964 DDS_DynamicData seq_member(NULL, DDS_DYNAMIC_DATA_PROPERTY_DEFAULT);
965 SafeBinder binder(instance, seq_member, ma);
967 DDS_DynamicDataInfo seq_info;
968 seq_member.get_info(seq_info);
970 if (boost::distance(range) < seq_info.member_count) {
971 throw std::runtime_error(
"get_member_value: Insufficient range");
974 typename match::Range<T>::iterator iter = boost::begin(range);
975 for (
int i = 0; i < seq_info.member_count; ++i, ++iter)
977 get_member_value(seq_member, MemberAccess::BY_ID(i + 1), *iter);
983 static void get_member_value(
984 const DDS_DynamicData & instance,
985 const MemberAccess &ma,
988 get_member_value_range(instance, ma, range);
991 template <
class T,
size_t Bound>
992 static void get_member_value(
993 const DDS_DynamicData & instance,
994 const MemberAccess &ma,
997 get_member_value_range(instance, ma, range);
1000 template <
class... Args>
1001 static void get_member_value(
1002 const DDS_DynamicData & instance,
1003 const MemberAccess &ma,
1006 DDS_DynamicData inner(NULL, DDS_DYNAMIC_DATA_PROPERTY_DEFAULT);
1007 SafeBinder binder(instance, inner, ma);
1012 template <
class T,
size_t Dim>
1013 static void get_member_value(
1014 const DDS_DynamicData & instance,
1015 const MemberAccess & ma,
1023 DDS_DynamicData arr_member(NULL, DDS_DYNAMIC_DATA_PROPERTY_DEFAULT);
1024 SafeBinder binder(instance, arr_member, ma);
1026 DDS_UnsignedLong length = array_length(val);
1031 for (DDS_UnsignedLong i = 0; i < length; ++i)
1033 get_member_value(arr_member, MemberAccess::BY_ID(i + 1), arr[i]);
1037 template <
class T,
size_t Dim>
1038 static void get_member_value(
1039 const DDS_DynamicData & instance,
1040 const MemberAccess & ma,
1048 DDS_UnsignedLong length = array_length(val);
1053 DDS_ReturnCode_t rc = detail::get_array(instance, arr, &length, ma);
1054 detail::check_retcode(
"get_member_value: get_array error = ", rc);
1057 template <
class T,
size_t Dim>
1058 static void get_member_value(
1059 const DDS_DynamicData & instance,
1060 const MemberAccess & ma,
1061 std::array<T, Dim> &val,
1068 DDS_DynamicData arr_member(NULL, DDS_DYNAMIC_DATA_PROPERTY_DEFAULT);
1069 SafeBinder binder(instance, arr_member, ma);
1071 DDS_UnsignedLong length = array_length(val);
1076 for (DDS_UnsignedLong i = 0; i < length; ++i)
1080 MemberAccess::BY_ID(i + 1),
1085 template <
class T,
size_t Dim>
1086 static void get_member_value(
1087 const DDS_DynamicData & instance,
1088 const MemberAccess & ma,
1089 std::array<T, Dim> & val,
1096 DDS_UnsignedLong length = array_length(val);
1101 DDS_ReturnCode_t rc = detail::get_array(instance, arr, &length, ma);
1102 detail::check_retcode(
"get_member_value: get_array error = ", rc);
1105 template <
class TagType,
class... Cases>
1106 static void get_member_value(
1107 const DDS_DynamicData & instance,
1108 const MemberAccess & ma,
1111 DDS_DynamicData inner(NULL, DDS_DYNAMIC_DATA_PROPERTY_DEFAULT);
1112 SafeBinder binder(instance, inner, ma);
1114 typedef typename match::Union<TagType, Cases...>::case_tuple_type CaseTuple;
1115 typedef TypelistIterator<
1120 DDS_DynamicDataMemberInfo member_info;
1121 inner.get_member_info_by_index(member_info, 0 );
1128 int discriminator_value =
static_cast<TagType
>(member_info.member_id);
1132 MemberAccess::BY_ID(discriminator_value),
1133 discriminator_value,
1138 template <
class Opt>
1139 static void initialize_optional(Opt & opt)
1146 template <
class... T>
1147 static void initialize_optional(boost::optional<T...> & opt)
1149 opt = boost::in_place<T...>();
1153 static void initialize_optional(boost::optional<T> & opt)
1155 opt = boost::in_place<T>();
1160 template <
typename Opt>
1161 static void get_member_value(
1162 const DDS_DynamicData & instance,
1163 const MemberAccess &ma,
1167 const char * member_name
1168 = ma.access_by_id() ? NULL : ma.get_name();
1170 int id = ma.access_by_id() ?
1171 ma.get_id() : DDS_DYNAMIC_DATA_MEMBER_ID_UNSPECIFIED;
1173 if (instance.member_exists(member_name,
id))
1176 initialize_optional(opt);
1180 get_member_value(instance, ma, *opt);
1186 void get_member_forward(
1187 const DDS_DynamicData & instance,
1188 const MemberAccess &ma,
1191 get_member_overload_resolution_helper::
1192 get_member_value(instance, ma, val);
1205 template <
class Iter>
1209 return boost::make_iterator_range(begin, end);
1212 template <
size_t Bound,
class Iter>
1217 return boost::make_iterator_range(
1218 match::make_bounded_view_iterator<Bound>(begin),
1219 match::make_bounded_view_iterator<Bound>(end));
1222 template <
size_t Bound,
class T>
1225 return make_bounded_range<Bound>(t.begin(), t.end());
1231 #ifndef REFLEX_NO_HEADER_ONLY
1232 #include "reflex/../../src/dd_manip.cxx"
1235 #endif // RTIREFLEX_DD_MANIP_H
Definition: enable_if.h:413
Definition: disc_union.h:139
void write_dynamicdata(DDS_DynamicData &dest, const T &src)
Copies source data into the destination DDS_DynamicData instance.
Definition: reflex.h:157
Definition: disc_union.h:27
match::Range< typename Iter::reference > make_range(Iter begin, Iter end)
Definition: dd_manip.h:1206
boost::any_range< T, boost::forward_traversal_tag, T, std::ptrdiff_t > Range
Definition: enable_if.h:95
Definition: enable_if.h:263
void enum_cast(T &dst, DDS_Long src)
Casts integers to user-defined enumeration types.
Definition: enable_if.h:155
Definition: enable_if.h:275
const tuple_type & get_opt_tuple() const
Definition: disc_union.h:32
Definition: enable_if.h:311
#define REFLEX_DLL_EXPORT
Definition: dllexport.h:35
match::BoundedRange< typename T::reference, Bound > make_bounded_range(T &t)
Definition: dd_manip.h:1223
void read_dynamicdata(T &dest, const DDS_DynamicData &src)
Extracts data out from the source DDS_DynamicData instance and copies into the destination object of ...
Definition: reflex.h:186
#define SET_MEMBER_VALUE_DECL(TYPE)
Definition: dd_manip.h:32
#define GET_MEMBER_VALUE_DECL(TYPE)
Definition: dd_manip.h:39
Definition: enable_if.h:284
Definition: enable_if.h:269
Definition: enable_if.h:251
Definition: enable_if.h:215
bool empty() const
Definition: disc_union.h:256
Definition: enable_if.h:353
Definition: enable_if.h:257
Definition: enable_if.h:457
unsigned char octet_t
Definition: dd_extra.h:48
container_traits_impl< C, is_container< C >::value >::iterator iterator
Definition: enable_if.h:453
container_traits_impl< C, is_container< C >::value >::value_type value_type
Definition: enable_if.h:447
Definition: enable_if.h:320