RefleX
Build DDS Applications in Modern C++ without IDL
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Macros Pages
memberwise.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 
11 #ifndef RTIREFLEX_MEMBERWISE_H
12 #define RTIREFLEX_MEMBERWISE_H
13 
14 #include <vector>
15 #include <type_traits>
16 
17 #include "ndds/ndds_cpp.h"
18 #include "reflex/dd_extra.h"
19 #include "reflex/enable_if.h"
20 
21 namespace reflex {
22 
23  namespace meta {
24 
25  template <int... I> struct indices;
26 
27  struct Too_Many_Indices;
28 
29  template <class T, class Indices>
31  {
32  typedef Too_Many_Indices type;
33  };
34 
35  template <class... Args, int Head, int... Tail>
36  struct get_nested_type<std::tuple<Args...>, indices<Head, Tail...>>
37  {
38  typedef typename std::tuple_element<Head, std::tuple<Args...>>::type TE;
39  typedef typename get_nested_type<TE, indices<Tail...>>::type type;
40  };
41 
42  template <class... Args, int Head>
43  struct get_nested_type<std::tuple<Args...>, indices<Head>>
44  {
45  typedef typename std::tuple_element<Head, std::tuple<Args...>>::type type;
46  };
47 
48  template <class TagType, class... Args, int Head, int... Tail>
49  struct get_nested_type<match::Union<TagType, Args...>, indices<Head, Tail...>>
50  {
51  typedef typename match::Union<TagType, Args...>::case_tuple_type CaseTuple;
52  typedef typename std::tuple_element<Head, CaseTuple>::type Case;
53  typedef typename get_nested_type<typename Case::type, indices<Tail...>>::type type;
54  };
55 
56  template <class TagType, class... Args, int Head>
57  struct get_nested_type<match::Union<TagType, Args...>, indices<Head>>
58  {
59  typedef typename match::Union<TagType, Args...>::case_tuple_type CaseTuple;
60  typedef typename std::tuple_element<Head, CaseTuple>::type Case;
61  typedef typename Case::type type;
62  };
63 
64  template <class... Args, int Head, int... Tail>
65  struct get_nested_type<match::Sparse<Args...>, indices<Head, Tail...>>
66  {
67  typedef typename match::Sparse<Args...>::raw_tuple_type RawTuple;
68  typedef typename std::tuple_element<Head, RawTuple>::type Raw;
69  typedef typename get_nested_type<Raw, indices<Tail...>>::type type;
70  };
71 
72  template <class... Args, int Head>
73  struct get_nested_type<match::Sparse<Args...>, indices<Head>>
74  {
75  typedef typename match::Sparse<Args...>::raw_tuple_type RawTuple;
76  typedef typename std::tuple_element<Head, RawTuple>::type type;
77  };
78 
79  template <class T, int Head, int... Tail>
80  struct get_nested_type<std::vector<T>, indices<Head, Tail...>>
81  {
82  typedef typename get_nested_type<T, indices<Tail...>>::type type;
83  };
84 
85  template <class T, int Head>
86  struct get_nested_type<std::vector<T>, indices<Head>>
87  {
88  typedef T type;
89  };
90 
91  } // namespace meta
92 
93  namespace detail {
94 
95  struct NameHelper;
96 
97 
98  template <class T>
99  void set_member_by_index(DDS_DynamicData &instance,
100  unsigned index,
101  const T & val)
102  {
103  // set_member_value<NameHelper, 0>(instance, MemberAccess::BY_ID(index + 1), val);
104  }
105 
106  template <class T>
107  void set_member_by_name(DDS_DynamicData &instance,
108  const char * name,
109  const T & val)
110  {
111  // set_member_value<NameHelper, 0>(instance, MemberAccess::BY_NAME(name), val);
112  }
113 
114  template <class T>
115  void recurse_and_set(DDS_DynamicData &outer,
116  const std::vector<int> & bind_points,
117  unsigned i,
118  const T & val)
119  {
120  if (i < bind_points.size() - 1)
121  {
122  DDS_DynamicData inner(NULL, DDS_DYNAMIC_DATA_PROPERTY_DEFAULT);
123  SafeBinder binder(outer, inner, MemberAccess::BY_ID(bind_points[i] + 1));
124  recurse_and_set(inner, bind_points, i + 1, val);
125  }
126  else
127  set_member_by_index(outer, bind_points[i], val);
128  }
129 
130  template <class T>
131  void recurse_and_set(DDS_DynamicData &outer,
132  const std::vector<const char *> & bind_points,
133  unsigned i,
134  const T & val)
135  {
136  if (i < bind_points.size() - 1)
137  {
138  DDS_DynamicData inner(NULL, DDS_DYNAMIC_DATA_PROPERTY_DEFAULT);
139  SafeBinder binder(outer, inner, MemberAccess::BY_NAME(bind_points[i]));
140  recurse_and_set(inner, bind_points, i + 1, val);
141  }
142  else
143  set_member_by_name(outer, bind_points[i], val);
144  }
145 
146  template <class T>
147  void set_member_by_indices(DDS_DynamicData &instance,
148  std::vector<int> indices,
149  const T & val)
150  {
151  recurse_and_set(instance, indices, 0, val);
152  }
153 
154  template <class T>
155  void set_member_by_names(DDS_DynamicData &instance,
156  std::vector<const char *> names,
157  const T & val)
158  {
159  recurse_and_set(instance, names, 0, val);
160  }
161 
162  template <class T>
163  void set_member(DDS_DynamicData &instance,
164  const char *expr,
165  const T & val)
166  {
167  // FIXME
168  }
169 
170  template <class T, class Tuple, class Indices>
171  struct TraverseTupleByIndices;
172 
173  template <class T, class Tuple, int Head, int... Tail>
174  struct TraverseTupleByIndices<T, Tuple, meta::indices<Head, Tail...>>
175  {
176  static void exec(DDS_DynamicData & outer, const T & val)
177  {
178  std::cerr << "binding " << Head << "\n";
179  DDS_DynamicData inner(NULL, DDS_DYNAMIC_DATA_PROPERTY_DEFAULT);
180  SafeBinder binder(outer, inner, MemberAccess::BY_ID(Head + 1));
181  TraverseTupleByIndices<T, Tuple, meta::indices<Tail...>>::exec(inner, val);
182  std::cerr << "unbinding\n";
183  }
184  };
185 
186  template <class T, class Tuple, int Last>
187  struct TraverseTupleByIndices<T, Tuple, meta::indices<Last>>
188  {
189  static void exec(DDS_DynamicData & outer, const T & val)
190  {
191  std::cerr << "set_member_by_index Last = " << Last;
192  set_member_by_index(outer, Last, val);
193  std::cerr << "set_member_by_index Last = " << Last;
194  }
195  };
196 
197  template <class T, class Tuple, int Head, int... I>
198  void set_member_by_indices(DDS_DynamicData &instance,
199  const T & val)
200  {
201  // This functionality is buggy in case of unions. especially default cases.
202  typedef typename meta::get_nested_type<Tuple, meta::indices<Head, I...>>::type Nested;
203  static_assert(std::is_same<Nested, T>::value, "The types don't match");
204  TraverseTupleByIndices<T, Tuple, meta::indices<Head, I...>>::exec(instance, val);
205  }
206 
207  } // namespace detail
208 
209 } // namespace reflex
210 
211 #endif // RTIREFLEX_MEMBERWISE_H
212 
213 
Definition: disc_union.h:139
std::tuple_element< Head, CaseTuple >::type Case
Definition: memberwise.h:60
get_nested_type< Raw, indices< Tail...> >::type type
Definition: memberwise.h:69
Definition: disc_union.h:27
std::tuple_element< Head, std::tuple< Args...> >::type TE
Definition: memberwise.h:38
std::tuple_element< Head, CaseTuple >::type Case
Definition: memberwise.h:52
std::tuple_element< Head, std::tuple< Args...> >::type type
Definition: memberwise.h:45
get_nested_type< TE, indices< Tail...> >::type type
Definition: memberwise.h:39
match::Sparse< Args...>::raw_tuple_type RawTuple
Definition: memberwise.h:67
match::Sparse< Args...>::raw_tuple_type RawTuple
Definition: memberwise.h:75
Too_Many_Indices type
Definition: memberwise.h:32
get_nested_type< typename Case::type, indices< Tail...> >::type type
Definition: memberwise.h:53
match::Union< TagType, Args...>::case_tuple_type CaseTuple
Definition: memberwise.h:59
std::tuple_element< Head, RawTuple >::type Raw
Definition: memberwise.h:68
Definition: memberwise.h:25
get_nested_type< T, indices< Tail...> >::type type
Definition: memberwise.h:82
Definition: memberwise.h:30
std::tuple_element< Head, RawTuple >::type type
Definition: memberwise.h:76
match::Union< TagType, Args...>::case_tuple_type CaseTuple
Definition: memberwise.h:51