Alchemy  1.0
A framework to robustly process network messages and structured data
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
make_Hg_type_list.h
1 /// @file Hg/detail/make_Hg_type_list.h
2 ///
3 /// Processes a basic typelist to be compatible with types required for Hg.
4 ///
5 /// The MIT License(MIT)
6 /// @copyright 2014 Paul M Watt
7 // ****************************************************************************
8 #ifndef MAKE_HG_TYPE_LIST_H_INCLUDED
9 #define MAKE_HG_TYPE_LIST_H_INCLUDED
10 // Includes ******************************************************************
11 #include <Pb/type_list.h>
12 #include <Pb/type_at.h>
13 #include <Hg/proxy/deduce_proxy_type.h>
14 //#include <Pb/bit_field/bit_field_array.h>
15 //#include <Pb/bit_field/bit_field_vector.h>
16 #include <Pb/dynamic.h>
17 
18 namespace Hg
19 {
20 
21 // Forward Declarations *******************************************************
22 // ****************************************************************************
23 /// Creates a type list suitable for processing within Hg messages.
24 ///
25 /// Some field types, such as arrays and vectors, may be defined with raw
26 /// types. This prevents Hg from properly interfacing with the parameters
27 /// to accurately serialize the data.
28 ///
29 template< class T>
31 
32 namespace detail
33 {
34 
35 // Overview *******************************************************************
36 //
37 // Generally only the array and vector require type replacements for their
38 // proper functioning. In some cases it is more efficient to create
39 // a specialized version of the array/vector, such as with the BitFieldArray.
40 //
41 // The table below indicates the combination types that have replacements
42 // defined for them.
43 //
44 // Type<T>: Sub-type<S>: Substitution Required:
45 // ----------- ----------- ----------------------------
46 // Fundamental n/a none
47 // BitField n/a none
48 // Nested n/a make_Hg_type_list<T>::type
49 //
50 // Array Fundamental none
51 // Array BitField BitFieldArray
52 // Array Nested make_Hg_type_list<S>::type
53 // Array Array yes / Sub-type also processed
54 // Array Vector vector / Sub-type also processed
55 //
56 // Vector Fundamental none
57 // Vector BitField BitFieldVector
58 // Vector Nested make_Hg_type_list<S>::type
59 // Vector Array yes / Sub-type also processed
60 // Vector Vector yes / Sub-type also processed
61 //
62 //
63 
64 
65 // ****************************************************************************
66 // Creates a type list with exactly one type entry.
67 //
68 template < class T >
69 struct StartTypeList
70 {
71  typedef typename
72  Hg::push_front< Hg::TypeList< Hg::MT >,
73  T
74  >::type type;
75 };
76 
77 // ****************************************************************************
78 // Creates the proper type declaration for a sequence container type.
79 //
80 // @paramt T The type container used for the declaration.
81 /// @paramT ValueTraitT The trait type of the value_type of the container.
82 //
83 template< class T,
84  class ValueTraitT
85  >
87 {
88  typedef T type;
89 };
90 
91 // ****************************************************************************
92 // Processes a child nested-type for Hg compatibility.
93 //
94 // @paramt T The type container used for the type declaration.
95 //
96 template< class T >
98 {
99  typedef typename
100  make_Hg_type_list<T>::type type;
101 };
102 
103 // ****************************************************************************
104 // Declares a BitFieldArray in place of the array<bit_field> definition.
105 //
106 // @paramt ArrayT The array definition type.
107 // @paramt T The value type in the container.
108 // @param N The number of elements in the container.
109 //
110 //template< class T,
111 // size_t N,
112 // template <class, size_t> class ArrayT
113 // >
114 //struct DeclareTypeSequence < ArrayT<T,N>, packed_trait >
115 //{
116 // typedef
117 // Hg::BitFieldArray<T, N> type;
118 //};
119 
120 // ****************************************************************************
121 // Redeclares the array of nested types, as an array of nested Hg types.
122 //
123 // @paramt ArrayT The array definition type.
124 // @paramt T The value type in the container.
125 // @param N The number of elements in the container.
126 //
127 template< class T,
128  size_t N,
129  template <class, size_t> class ArrayT
130  >
131 struct DeclareTypeSequence < ArrayT<T,N>, nested_trait >
132 {
133  // Define a typedef that represents the actual data-type
134  // that reprsents the type-list T passed into this array.
135  typedef typename
136  FieldTypes <T>::value_type value_type;
137 
138  typedef
139  std::array< value_type, N> type;
140 };
141 
142 // ****************************************************************************
143 // Declares a BitFieldVector in place of the vector<bit_field> definition.
144 //
145 // @paramt VectorT The vector definition type.
146 // @paramt T The value type in the container.
147 // @param A The allocator used for memory management.
148 //
149 //template< class T,
150 // class A,
151 // template <class, class> class VectorT
152 // >
153 //struct DeclareTypeSequence < VectorT<T,A>, packed_trait >
154 //{
155 // typedef
156 // Hg::BitFieldVector<T, A> type;
157 //};
158 
159 // ****************************************************************************
160 // Processes a nested field recursively to correct any vector definitions.
161 //
162 // @paramt VectorT The vector definition type.
163 // @paramt T The value type in the container.
164 // @param A The allocator used for memory management.
165 //
166 template< class T,
167  class A,
168  template <class, class> class VectorT
169  >
170 struct DeclareTypeSequence < VectorT<T,A>, nested_trait >
171 {
172  // Define a typedef that represents the actual data-type
173  // that reprsents the type-list T passed into this array.
174  typedef typename
175  FieldTypes <T>::value_type value_type;
176 
177  typedef
178  std::vector< value_type, A> type;
179 };
180 
181 
182 
183 // ****************************************************************************
184 // The default implementation is a no-op and returns the same type.
185 //
186 template< class T,
187  class TraitT>
188 struct ReplaceType
189 {
190  typedef T type;
191 };
192 
193 // ****************************************************************************
194 // The array type requires the specific definitions for internal types.
195 //
196 template< class ArrayT >
197 struct ReplaceType< ArrayT, array_trait>
198 {
199  // Extract the type and extent from the array declaration.
200  typedef typename
201  ArrayT::value_type value_type;
202 
203  // Deduce the type trait of value_type
204  // for declaration of the type sequence.
205  typedef typename
206  DeduceTypeTrait<value_type>::type type_trait;
207 
208  // If the value type has a dynamic size, then the array will be converted
209  // to a vector, with a pre-allocated size.
210  // This greatly simplifies serialization.
211  // It also allows pure fixed-size constructs to be optimized as such.
212  typedef typename
213  DeclareTypeSequence < ArrayT,
214  type_trait
215  >::type array_type;
216 
217  typedef typename
218  DeclareTypeSequence < std::vector<value_type>,
219  type_trait
220  >::type vector_type;
221 
222 
223  // TODO: Need to find a solution for redefined symbols when the array is converted to a vector.
224  typedef array_type type;
225  //typedef typename
226  // std::conditional< has_dynamic<value_type>::value,
227  // vector_type,
228  // array_type
229  // >::type type;
230 };
231 
232 // ****************************************************************************
233 // The vector type requires the specific definitions for internal types.
234 //
235 template< class VectorT >
236 struct ReplaceType< VectorT, vector_trait>
237 {
238  // Extract the value type declaration from inside the vector declaration.
239  typedef typename
240  VectorT::value_type value_type;
241 
242  // Deduce the type trait of value_type
243  // for declaration of the type sequence.
244  typedef typename
245  DeduceTypeTrait<value_type>::type type_trait;
246 
247  typedef typename
248  DeclareTypeSequence < VectorT,
249  type_trait
250  >::type type;
251 };
252 
253 
254 // ****************************************************************************
255 // Inspects the input type, and applies adjustments for compatibility with Hg.
256 //
257 template< class T >
258 struct AdjustType
259 {
260  typedef typename
261  ReplaceType < T,
262  typename DeduceTypeTrait<T>::type
263  >::type type;
264 };
265 
266 // ****************************************************************************
267 // Inspect each item and add the proper format to the final type_list.
268 //
269 template< class T,
270  class TailT,
271  class HgT
272  >
273 struct make_Hg_worker
274 {
275  // The result of inspecting a type and
276  typedef typename // potentially adjusting the type.
277  AdjustType<T>::type adjusted_type;
278 
279 
280 
281  typedef typename // The next item on the list to process.
282  Hg::front<TailT>::type next_type;
283 
284 
285  typedef typename // The remainder of the unprocessed types.
286  Hg::pop_front<TailT>::type list_tail;
287 
288 
289  typedef typename
290  make_Hg_worker< next_type, // A recursively built list of processed
291  list_tail, // types that have been adjusted to be
292  HgT // compatible for Hg message types.
293  >::type hg_list;
294 
295  typedef typename
296  Hg::push_front< hg_list,
297  adjusted_type // The list of types converted for Hg.
298  >::type type;
299 };
300 
301 // ****************************************************************************
302 // Terminating case where the next element reported by the input list is empty.
303 //
304 template< class LList,
305  class PList
306  >
307 struct make_Hg_worker < Hg::MT,
308  LList,
309  PList>
310 {
311  typedef PList type;
312 };
313 
314 } // namespace detail
315 
316 
317 
318 
319 // ****************************************************************************
320 // @Note: Type T must be a typelist.
321 //
322 template< class T>
323 struct make_Hg_type_list
324 {
325 protected:
326  typedef typename // The next item on the list to process.
327  Hg::front<T>::type next_type;
328 
329 
330  typedef typename // The remainder of the unprocessed types.
331  Hg::pop_front<T>::type list_tail;
332 
333 
334 public:
335  typedef typename // Make the Hg compatible list.
336  detail::make_Hg_worker< next_type,
337  list_tail,
339  >::type type;
340 };
341 
342 
343 } // namespace Hg
344 
345 
346 #endif
347