Alchemy  1.0
A framework to robustly process network messages and structured data
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
bit_field_array.h
Go to the documentation of this file.
1 /// @file bit_field_array.h
2 ///
3 /// Defines the BitFieldArray construct for Alchemy Message Fields.
4 /// This is a specialized meta object the keeps track of a series of bit-field
5 /// definitions for a message structure.
6 ///
7 /// Note: Currently the array of bit-fields is inefficient due to the number
8 /// of temporary objects that are constructed. This sub-type will be
9 /// optimized after the first mile-stone release.
10 /// The optimization will require an alternative bit-field list implementation
11 /// that allows the internal storage to be reassigned at run time.
12 ///
13 ///
14 /// The MIT License(MIT)
15 /// @copyright 2014 Paul M Watt
16 // ****************************************************************************
17 #ifndef BIT_FIELD_ARRAY_H_INCLUDED
18 #define BIT_FIELD_ARRAY_H_INCLUDED
19 // Includes ******************************************************************
20 #include <Pb/compiler.h>
21 #include <Pb/meta_util.h>
22 
23 #include <Pb/meta_fwd.h>
24 #include <Pb/bit_field/packed_bits.h>
25 #include <Pb/bit_field/bit_field.h>
26 #include <Pb/integer_sequence.h>
27 
28 #include <array>
29 
30 
31 namespace Hg
32 {
33 
34 // ****************************************************************************
35 /// Represents a set of fields that provide homogeneous bit-field access to each
36 /// of the data values.
37 ///
38 /// This object requires a Hg bit-field definition for the type definition of
39 /// this object. The base integer type that is defined for the bit-field
40 /// will be used to define the type for allocation of memory for the array.
41 ///
42 /// Each field allocated in the array will accessible either by the base
43 /// integer type or with the bit-field interface provided supplied to the
44 /// definition.
45 ///
46 template< typename T,
47  size_t N
48  >
50  : array_trait
51 {
52 public:
53  // Typedefs *****************************************************************
55  ///< An alias for this classes definition.
56 
57  typedef T user_bit_field_type;
58  ///< The type of bit-field interface
59  /// defined by the user to access
60  /// individual value entries in the array.
61 
63  ///< The Hg type required to properly
64  /// initialized nested structures to
65  /// provide the natural bit-field syntax.
66 
67  typedef typename
68  T::value_type value_type;
69  ///< The data type managed by this Array.
70  /// This is the type of data that will
71  /// be written to the attached buffer.
72 
73  typedef std::array<value_type, N> array_type;
74 
75  typedef /// Reference to an element in the array.
77 
78  typedef /// Const Reference to an element in the array.
80 
81 
82  // TODO: Bit-field access through the iterator is not yet supported,
83  // the user is actually receiving an iterator to an integer.
84 
85  typedef typename /// An iterator to a value_type index.
86  array_type::iterator iterator;
87 
88  typedef typename /// A const iterator to a value_type index.
89  array_type::const_iterator const_iterator;
90 
91  typedef typename /// A reverse iterator to a value_type index.
92  array_type::reverse_iterator reverse_iterator;
93 
94  typedef typename /// A const reverse iterator to a value_type index.
95  array_type::const_reverse_iterator const_reverse_iterator;
96 
97 
98  // Construction *************************************************************
99  // **************************************************************************
100  /// Default Constructor
101  ///
103  {
104 // static_assert(false, "Support for Bitfield Arrays is not complete. This type is not supported.");
105 
106  // TODO: Considering a compilation flag to not initialize buffers for performance conscious users.
107  std::fill(m_data.begin(), m_data.end(), value_type());
108  }
109 
110 
111  // **************************************************************************
112  /// Copy Constructor.
113  ///
115  {
116  std::copy( rhs.begin(),
117  rhs.end(),
118  begin());
119  }
120 
121  // **************************************************************************
122  /// Value constructor based on an array of raw integer type data.
123  ///
124  BitFieldArray(const value_type (&rhs)[N])
125  {
126  ::memcpy(&m_data[0], &rhs[0], sizeof(value_type) * N);
127  }
128 
129  // **************************************************************************
130  /// Destructor
131  ///
133  { }
134 
135  // **************************************************************************
136  /// Assignment operator.
137  ///
139  {
140  std::copy( rhs.begin(),
141  rhs.end(),
142  begin());
143  return *this;
144  }
145 
146  // **************************************************************************
147  /// Value Assignment operator (Assigns a raw array of the correct size.)
148  ///
150  {
151  ::memcpy(&m_data[0], &rhs[0], sizeof(value_type) * N);
152 
153  return *this;
154  }
155 
156  // **************************************************************************
157  /// Returns a pointer to the raw data buffer for the container for reference.
158  ///
159  const value_type* data() const
160  {
161  return &m_data[0];
162  }
163 
164  // **************************************************************************
165  /// Returns a pointer to the raw data buffer for the container for assignment.
166  ///
168  {
169  return &m_data[0];
170  }
171 
172  // **************************************************************************
173  /// Indicates if this container contains 0 elements.
174  ///
175  bool empty() const
176  {
177  return size() == 0;
178  }
179 
180  // **************************************************************************
181  /// Returns the number of elements within the array.
182  ///
183  size_t size() const
184  {
185  return m_data.size();
186  }
187 
188  // **************************************************************************
189  /// Returns the number of bytes required to hold the entire array of data.
190  ///
191  size_t data_size() const
192  {
193  return size() * sizeof(value_type);
194  }
195 
196  // **************************************************************************
197  /// Conversion operator to the value_type reference.
198  ///
199  /// @note The converted array interface provides direct access values.
200  ///
201  operator reference()
202  {
203 // TODO: Investigate if this is necessary, and add the correct implementation.
204  //return *static_cast<datum_type*>(this);
205  return reference();
206  }
207 
208  // **************************************************************************
209  /// Value Conversion Operator (value_type)
210  ///
211  /// Allows the entire BitSet to be extracted and assigned as a value to
212  /// the host value type.
213  ///
214  operator value_type() const
215  {
216 // return static_cast<const datum_type*>(this)->operator value_type();
217  return value_type();
218  }
219 
220  // **************************************************************************
221  /// Accesses the value at the specified index in the array data..
222  ///
223  const_reference at(size_t idx) const
224  {
225  // Remove constness to allow the non-const calls
226  // from the bit-field implementation to be called.
227  // A const instance of the object will be returned.
228  this_type *pThis = const_cast<this_type*>(this);
229 
230  return const_reference(pThis->m_data.at(idx));
231  }
232 
233  // **************************************************************************
234  /// Accesses the value at the specified index in the array data..
235  ///
236  reference at(size_t idx)
237  {
238  return reference(m_data.at(idx));
239  }
240 
241  // **************************************************************************
242  /// Accesses the value at the specified index in the array data..
243  ///
244  const_reference operator[](size_t idx) const
245  {
246  // Remove constness to allow the non-const calls
247  // from the bit-field implementation to be called.
248  // A const instance of the object will be returned.
249  this_type *pThis = const_cast<this_type*>(this);
250 
251  return const_reference(pThis->m_data[idx]);
252  }
253 
254  // **************************************************************************
255  /// Accesses the value at the specified index in the array data..
256  ///
257  reference operator[](size_t idx)
258  {
259  return reference(m_data[idx]);
260  }
261 
262  // **************************************************************************
263  /// Accesses the first value in the array data..
264  ///
266  {
267  // Remove constness to allow the non-const calls
268  // from the bit-field implementation to be called.
269  // A const instance of the object will be returned.
270  this_type *pThis = const_cast<this_type*>(this);
271 
272  return const_reference(pThis->m_data.front());
273  }
274 
275  // **************************************************************************
276  /// Accesses the first value in the array data..
277  ///
279  {
280  return reference(m_data.front());
281  }
282 
283  // **************************************************************************
284  /// Accesses the last valid value in the array data..
285  ///
287  {
288  // Remove constness to allow the non-const calls
289  // from the bit-field implementation to be called.
290  // A const instance of the object will be returned.
291  this_type *pThis = const_cast<this_type*>(this);
292 
293  return const_reference(pThis->m_data.back());
294  }
295 
296  // **************************************************************************
297  /// Accesses the last valid value in the array data..
298  ///
300  {
301  return reference(m_data.back());
302  }
303 
304  // Iterator Functions *******************************************************
305  // **************************************************************************
306  /// Returns an iterator to the first item in the array.
307  ///
308  iterator begin() { return m_data.begin(); }
309  const_iterator begin() const { return m_data.begin(); }
310  const_iterator cbegin() const { return m_data.cbegin(); }
311 
312  // **************************************************************************
313  /// Returns an iterator to the item one passed the end of the array.
314  ///
315  iterator end() { return m_data.end(); }
316  const_iterator end() const { return m_data.end(); }
317  const_iterator cend() const { return m_data.cend(); }
318 
319  // **************************************************************************
320  /// Returns an iterator to the last item of the array moving in reverse.
321  ///
322  reverse_iterator rbegin() { return m_data.rbegin(); }
323  const_reverse_iterator rbegin() const { return m_data.rbegin(); }
324  const_reverse_iterator crbegin() const { return m_data.crbegin();}
325 
326  // **************************************************************************
327  /// Returns an iterator to the item one passed the beginning of the array,
328  /// moving in reverse.
329  ///
330  reverse_iterator rend() { return m_data.rend(); }
331  const_reverse_iterator rend() const { return m_data.rend(); }
332  const_reverse_iterator crend() const { return m_data.crend(); }
333 
334 
335 private:
336  // Data Members *************************************************************
337  array_type m_data; ///< The data buffers that hold the
338  /// raw values for the collection of
339  /// bit-fields.
340 };
341 
342 
343 } // namespace Hg
344 
345 
346 #endif