Alchemy  1.0
A framework to robustly process network messages and structured data
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
basic_datum.h
1 /// @file detail/basic_datum.h
2 ///
3 /// The declaration and definition of general functions for a data field.
4 ///
5 /// The MIT License(MIT)
6 /// @copyright 2014 Paul M Watt
7 // ****************************************************************************
8 #ifndef BASIC_DATUM_H_INCLUDED
9 #define BASIC_DATUM_H_INCLUDED
10 // Includes ******************************************************************
11 #include <Pb/meta_fwd.h>
12 #include <Hg/msg_buffer.h>
13 #include <Hg/deduce_type_trait.h>
14 //#include <Pb/bit_field/bit_field_array.h>
15 //#include <Pb/bit_field/bit_field_vector.h>
16 
17 namespace Hg
18 {
19 
20 namespace detail
21 {
22 
23 // ****************************************************************************
24 /// Type definition that indicates the parameterized-type
25 /// located at an index in a type container.
26 ///
27 /// @paramT field_t [typename] This parameterized type declares the
28 /// type at the associated location in the parent
29 /// type container.
30 ///
31 /// @note This type should be specialized for custom fields that
32 /// desire the field_t input to differ from the defined value_type.
33 ///
34 template <typename FieldT>
36 {
37  typedef FieldT value_type; ///< The matching data type for the index.
38  /// The default implementation uses
39  /// the same type as the index type.
40 };
41 
42 // ****************************************************************************
43 /// Generalized copy function for message field value types.
44 ///
45 /// @param to A reference to the variable to copy the into.
46 /// @param from A reference to the data to copy from.
47 ///
48 template< typename T >
49 void copy_value_type(T& to, const T& from)
50 {
51  to = from;
52 }
53 
54 
55 // ****************************************************************************
56 /// (Static-Array Specialization) Type definitions for bit-fields in type-container.
57 ///
58 /// @param SubTypeT [typename] This parameterized type declares the
59 /// sub-type of the array defined at the location
60 /// in the parent type container.
61 /// @param N [size_t] The number of elements in the array.
62 ///
63 //template< typename SubTypeT,
64 // size_t N
65 // >
66 //struct field_data_t < Hg::BitFieldArray<SubTypeT, N> >
67 //{
68 // typedef
69 // SubTypeT sub_type;
70 //
71 // typedef
72 // Hg::BitFieldArray<SubTypeT, N> value_type;
73 //};
74 
75 
76 // ****************************************************************************
77 /// (Fixed-Array Specialization) To copy from one instance to another.
78 ///
79 /// @paramt SubTypeT [typename] This parameterized type declares the
80 /// sub-type of the array defined at the location
81 /// in the parent type container.
82 /// @paramt N [size_t] The number of elements in the array.
83 ///
84 //template< typename SubTypeT,
85 // size_t N
86 // >
87 //void copy_value_type( BitFieldArray<SubTypeT, N>& to,
88 // const BitFieldArray<SubTypeT, N>& from)
89 //{
90 // std::copy(from.begin(), from.end(), to.begin());
91 //}
92 
93 // ****************************************************************************
94 /// (Dynamic-Array Specialization) Type definitions for bit-field in type-container.
95 ///
96 /// @param SubTypeT [typename] This parameterized type declares the
97 /// sub-type of the vector defined at the location
98 /// in the parent type container.
99 /// @param AllocT [typename] The defined allocator of the vector.
100 ///
101 //template< typename SubTypeT,
102 // typename AllocT
103 // >
104 //struct field_data_t < Hg::BitFieldVector<SubTypeT, AllocT> >
105 //{
106 // typedef
107 // SubTypeT sub_type;
108 //
109 // typedef
110 // Hg::BitFieldVector<SubTypeT, AllocT> value_type;
111 //};
112 
113 
114 // ****************************************************************************
115 /// (Dynamic-Array Specialization) To copy from one instance to another.
116 ///
117 /// @param SubTypeT [typename] This parameterized type declares the
118 /// sub-type of the vector defined at the location
119 /// in the parent type container.
120 /// @param AllocT [typename] The defined allocator of the vector.
121 ///
122 //template< class SubTypeT,
123 // class A
124 // >
125 //void copy_value_type( BitFieldVector<SubTypeT, A>& to,
126 // const BitFieldVector<SubTypeT, A>& from)
127 //{
128 // to.clear();
129 // if (from.empty())
130 // {
131 // return;
132 // }
133 //
134 // to.resize(from.size());
135 // std::copy( from.begin(),
136 // from.end(),
137 // to.begin());
138 //}
139 
140 
141 // ****************************************************************************
142 /// (Fixed-Array Specialization) To copy from one instance to another.
143 ///
144 /// @paramt SubTypeT [typename] This parameterized type declares the
145 /// sub-type of the array defined at the location
146 /// in the parent type container.
147 /// @paramt N [size_t] The number of elements in the array.
148 ///
149 template< typename SubTypeT,
150  size_t N
151  >
152 void copy_value_type( std::array<SubTypeT, N>& to,
153  const std::array<SubTypeT, N>& from)
154 {
155  std::copy(from.begin(), from.end(), to.begin());
156 }
157 
158 
159 // ****************************************************************************
160 /// (Dynamic-Array Specialization) Type definitions for field in type-container.
161 ///
162 /// @param SubTypeT [typename] This parameterized type declares the
163 /// sub-type of the vector defined at the location
164 /// in the parent type container.
165 /// @param AllocT [typename] The defined allocator of the vector.
166 ///
167 template< typename SubTypeT,
168  typename AllocT
169  >
170 struct field_data_t < std::vector<SubTypeT, AllocT> >
171 {
172  typedef
173  SubTypeT sub_type;
174 
175  typedef typename
176  field_data_t<sub_type>::value_type value_sub_type;
177 
178 
179  typedef typename
180  std::conditional
181  < nested_value<sub_type>::value,
182  std::vector< value_sub_type, AllocT>,
183  std::vector< sub_type, AllocT>
184  >::type value_type;
185  ///< The proper value_type definition
186  /// deduced from the type-container
187  /// and the specified array sub-type.
188 };
189 
190 
191 // ****************************************************************************
192 /// (Dynamic-Array Specialization) To copy from one instance to another.
193 ///
194 /// @param SubTypeT [typename] This parameterized type declares the
195 /// sub-type of the vector defined at the location
196 /// in the parent type container.
197 /// @param AllocT [typename] The defined allocator of the vector.
198 ///
199 template< typename SubTypeT,
200  typename AllocT
201  >
202 void copy_value_type( std::vector<SubTypeT, AllocT>& to,
203  const std::vector<SubTypeT, AllocT>& from)
204 {
205  // Empty the existing elements before inserting the new data.
206  to.clear();
207  std::copy(from.begin(), from.end(), std::back_inserter(to));
208 }
209 
210 
211 // ****************************************************************************
212 /// Provides the data field type definitions.
213 ///
214 /// This class acts as a discriminator object to choose the proper msg field types.
215 /// This method of field and data definition allows the use of virtual
216 /// interfaces to be avoided for message fields.
217 ///
218 /// In cases such as a uint8_t, this would cause a 400% increase in size for
219 /// no value. This extra hidden complexity of implementation is well worth
220 /// the runtime value of the final structure.
221 ///
222 /// @note The template defaults use *field_t* for both *index_type*
223 /// and *value_type*. These definitions determine the data
224 /// managed within a Datum. This template should be
225 /// specialized if a different *value_type* is desired.
226 ///
227 /// @note The simplest method to specialize the value_type is
228 /// to create a specialization of the *field_data_t* template.
229 ///
230 /// @paramt FieldT This parameterized type declares the
231 /// type at the associated location in the parent
232 /// type container.
233 ///
234 template< class FieldT,
235  class TraitT = typename Hg::detail::DeduceTypeTrait<FieldT>::type >
237 {
238  typedef
239  FieldT index_type; ///< The type at the index of the
240  /// parent type container.
241  typedef typename
243  value_type; ///< The specified value type for
244  /// the current Datum.
245 
246  // **************************************************************************
247  /// Returns a reference to the internal data storage.
248  ///
249  /// Returns a reference to the internal data storage managed by this
250  /// Datum. The reference to the data can be useful, and necessary for
251  ///
253  {
254  return m_data;
255  }
256 
257  // **************************************************************************
258  /// Returns the value of the data buffer.
259  ///
260  const value_type& data() const
261  {
262  return m_data;
263  }
264 
265  // **************************************************************************
266  /// Returns the value of the data buffer.
267  ///
268  void data(const value_type &value)
269  {
270  Hg::detail::copy_value_type(reference(), value);
271  }
272 
273 protected:
274  value_type m_data; ///< This is a local copy of the data
275  /// value to shadow the value held in
276  /// the buffer.
277 };
278 
279 // ****************************************************************************
280 /// Nested Specialization for the index and data field type definitions.
281 ///
282 /// @paramt FieldT This parameterized type declares the
283 /// type at the associated location in the parent
284 /// type container.
285 ///
286 template< typename FieldT >
287 struct FieldTypes <FieldT, nested_trait>
288  : public field_data_t<FieldT>::value_type
289 {
290  typedef
291  FieldT index_type; ///< The type at the index of the
292  /// parent type container.
293  typedef typename
295  value_type; ///< The specified value type for
296  /// the current Datum.
297 
298  // **************************************************************************
299  /// Returns a reference to the internal data storage.
300  ///
301  /// Returns a reference to the internal data storage managed by this
302  /// Datum. The reference to the data can be useful, and necessary for
303  ///
305  {
306  return *static_cast<value_type*>(this);
307  }
308 
309  // **************************************************************************
310  /// Returns the value of the data buffer.
311  ///
312  const value_type& data() const
313  {
314  return *static_cast<const value_type*>(this);
315  }
316 
317  // **************************************************************************
318  /// Returns the value of the data buffer.
319  ///
320  void data(const value_type &value)
321  {
322  reference() = value;
323  }
324 };
325 
326 // ****************************************************************************
327 /// Packed Bits Specialization for the index and data field type definitions.
328 ///
329 /// @paramt FieldT This parameterized type declares the
330 /// type at the associated location in the parent
331 /// type container.
332 ///
333 template< typename FieldT >
334 struct FieldTypes <FieldT, packed_trait>
335  : public FieldT
336 {
337  typedef
338  FieldT index_type; ///< The type at the index of the
339  /// parent type container.
340  typedef typename
342  packed_type; ///< The packed-bit container type.
343  typedef typename
344  packed_type::value_type
345  value_type; ///< The value type used by the packed-bits.
346 
347  // **************************************************************************
348  /// Returns a reference to the internal data storage.
349  ///
350  /// Returns a reference to the internal data storage managed by this
351  /// Datum. The reference to the data can be useful, and necessary for
352  ///
354  {
355  return this->value();
356  }
357 
358  // **************************************************************************
359  /// Returns the value of the data buffer.
360  ///
361  const value_type& data() const
362  {
363  return this->value();
364  }
365 
366  // **************************************************************************
367  /// Assigns a new value to the data buffer.
368  ///
369  void data(const value_type &value)
370  {
371  reference() = value;
372  }
373 
374 };
375 
376 
377 
378 // ****************************************************************************
379 /// A meta-function that simplfies the declaration of a FieldType.
380 /// Publically derive from the type member of this struct.
381 ///
382 /// Specialize this template class to customize the internal type that
383 /// an index_type will resolve to.
384 ///
385 /// @paramt Idx [size_t] The index of this element in the
386 /// TypeList definition.
387 /// Idx must be < length<T>::value.
388 /// @paramt T The TypeList that contains this
389 /// elements definition.
390 /// T must be an indexable type container.
391 ///
392 template< size_t Idx,
393  typename format_t
394  >
396 {
397  // Typedefs *****************************************************************
398  typedef typename
399  Hg::TypeAt<Idx, format_t>::type index_type;
400  ///< The type extracted at the current
401  /// index defined in the parent TypeList.
402 
403  typedef
405  < index_type > type;
406  ///< The field type definition that maps
407  /// a field type with it's value_type.
408 };
409 
410 
411 } // namespace detail
412 
413 } // namespace Hg
414 
415 #endif