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_vector.h
Go to the documentation of this file.
1 /// @file bit_field_vector.h
2 ///
3 /// Defines the BitFieldVector 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 vector 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_VECTOR_H_INCLUDED
18 #define BIT_FIELD_VECTOR_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 <vector>
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 vector.
41 ///
42 /// Each field allocated in the vector 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  typename A = std::allocator<T>
48  >
50  : vector_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 vector.
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 vector.
70  /// This is the type of data that will
71  /// be written to the attached buffer.
72  typedef A allocator_type;
73  ///< The allocator used by this vector.
74 
75 
76  typedef std::vector<value_type, A> vector_type;
77 
78  typedef /// Reference to an element in the vector.
80 
81  typedef /// Const Reference to an element in the vector.
83 
84 
85  // TODO: Bit-field access through the iterator is not yet supported,
86  // the user is actually receiving an iterator to an integer.
87 
88  typedef typename /// An iterator to a value_type index.
89  vector_type::iterator iterator;
90 
91  typedef typename /// A const iterator to a value_type index.
92  vector_type::const_iterator const_iterator;
93 
94  typedef typename /// A reverse iterator to a value_type index.
95  vector_type::reverse_iterator reverse_iterator;
96 
97  typedef typename /// A const reverse iterator to a value_type index.
98  vector_type::const_reverse_iterator const_reverse_iterator;
99 
100 
101  // Construction *************************************************************
102  // **************************************************************************
103  /// Default Constructor
104  ///
106  {
107 // static_assert(false, "Support for Bitfield Vectors is not complete. This type is not supported.");
108  // TODO: Considering a compilation flag to not initialize buffers for performance conscieous users.
109  std::fill(m_data.begin(), m_data.end(), value_type());
110  }
111 
112 
113  // **************************************************************************
114  /// Copy Constructor.
115  ///
117  {
118  if (rhs.empty())
119  {
120  return;
121  }
122 
123  resize(rhs.size());
124  std::copy( rhs.begin(),
125  rhs.end(),
126  begin());
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  /// Returns a pointer to the raw data buffer for the container for reference.
148  ///
149  const value_type* data() const
150  {
151  return &m_data[0];
152  }
153 
154  // **************************************************************************
155  /// Returns a pointer to the raw data buffer for the container for assignment.
156  ///
158  {
159  return &m_data[0];
160  }
161 
162  // **************************************************************************
163  /// Erases every element in the vector.
164  ///
165  void clear()
166  {
167  m_data.clear();
168  }
169 
170  // **************************************************************************
171  /// Indicates if this container contains 0 elements.
172  ///
173  bool empty() const
174  {
175  return size() == 0;
176  }
177 
178  // **************************************************************************
179  /// Returns the number of elements within the vector.
180  ///
181  size_t size() const
182  {
183  return m_data.size();
184  }
185 
186  // **************************************************************************
187  /// Returns the number of bytes required to hold the entire vector of data.
188  ///
189  size_t data_size() const
190  {
191  return size() * sizeof(value_type);
192  }
193 
194  // **************************************************************************
195  /// Changes the number of elements stored.
196  ///
197  /// @param n The number of elements the container should now hold.
198  ///
199  void resize(size_t count) { resize(count, value_type()); }
200 
201  // **************************************************************************
202  /// Changes the number of elements stored.
203  ///
204  /// @param n The number of elements the container should now hold.
205  /// @param value Default value to initialize elements if the resize
206  /// causes new elements to be added to the container.
207  ///
208  void resize(size_t count,
209  value_type value) { m_data.resize(count, value); }
210 
211  // **************************************************************************
212  /// Conversion operator to the value_type reference.
213  ///
214  /// @note The converted vector interface provides direct access values.
215  ///
216  operator reference()
217  {
218  //return *static_cast<datum_type*>(this);
219  return reference();
220  }
221 
222  // **************************************************************************
223  /// Value Conversion Operator (value_type)
224  ///
225  /// Allows the entire BitSet to be extracted and assigned as a value to
226  /// the host value type.
227  ///
228  operator value_type() const
229  {
230 // return static_cast<const datum_type*>(this)->operator value_type();
231  return value_type();
232  }
233 
234  // **************************************************************************
235  /// Accesses the value at the specified index in the vector data..
236  ///
237  const_reference at(size_t idx) const
238  {
239  // Remove constness to allow the non-const calls
240  // from the bit-field implementation to be called.
241  // A const instance of the object will be returned.
242  this_type *pThis = const_cast<this_type*>(this);
243 
244  return const_reference(pThis->m_data.at(idx));
245  }
246 
247  // **************************************************************************
248  /// Accesses the value at the specified index in the vector data..
249  ///
250  reference at(size_t idx)
251  {
252  return reference(m_data.at(idx));
253  }
254 
255  // **************************************************************************
256  /// Accesses the value at the specified index in the vector data..
257  ///
258  const_reference operator[](size_t idx) const
259  {
260  // Remove constness to allow the non-const calls
261  // from the bit-field implementation to be called.
262  // A const instance of the object will be returned.
263  this_type *pThis = const_cast<this_type*>(this);
264 
265  return const_reference(pThis->m_data[idx]);
266  }
267 
268  // **************************************************************************
269  /// Accesses the value at the specified index in the vector data..
270  ///
271  reference operator[](size_t idx)
272  {
273  return reference(m_data[idx]);
274  }
275 
276  // **************************************************************************
277  /// Accesses the first value in the vector data..
278  ///
280  {
281  // Remove constness to allow the non-const calls
282  // from the bit-field implementation to be called.
283  // A const instance of the object will be returned.
284  this_type *pThis = const_cast<this_type*>(this);
285 
286  return const_reference(pThis->m_data.front());
287  }
288 
289  // **************************************************************************
290  /// Accesses the first value in the vector data..
291  ///
293  {
294  return reference(m_data.front());
295  }
296 
297  // **************************************************************************
298  /// Accesses the last valid value in the vector data..
299  ///
301  {
302  // Remove constness to allow the non-const calls
303  // from the bit-field implementation to be called.
304  // A const instance of the object will be returned.
305  this_type *pThis = const_cast<this_type*>(this);
306 
307  return const_reference(pThis->m_data.back());
308  }
309 
310  // **************************************************************************
311  /// Accesses the last valid value in the vector data..
312  ///
314  {
315  return reference(m_data.back());
316  }
317 
318  // Iterator Functions *******************************************************
319  // **************************************************************************
320  /// Returns an iterator to the first item in the vector.
321  ///
322  iterator begin() { return m_data.begin(); }
323  const_iterator begin() const { return m_data.begin(); }
324  const_iterator cbegin() const { return m_data.cbegin(); }
325 
326  // **************************************************************************
327  /// Returns an iterator to the item one passed the end of the vector.
328  ///
329  iterator end() { return m_data.end(); }
330  const_iterator end() const { return m_data.end(); }
331  const_iterator cend() const { return m_data.cend(); }
332 
333  // **************************************************************************
334  /// Returns an iterator to the last item of the vector moving in reverse.
335  ///
336  reverse_iterator rbegin() { return m_data.rbegin(); }
337  const_reverse_iterator rbegin() const { return m_data.rbegin(); }
338  const_reverse_iterator crbegin() const { return m_data.crbegin();}
339 
340  // **************************************************************************
341  /// Returns an iterator to the item one passed the beginning of the vector,
342  /// moving in reverse.
343  ///
344  reverse_iterator rend() { return m_data.rend(); }
345  const_reverse_iterator rend() const { return m_data.rend(); }
346  const_reverse_iterator crend() const { return m_data.crend(); }
347 
348  // Modifiers ****************************************************************
349  // **************************************************************************
350  /// Removes the specified element from this container.
351  ///
352  /// @param pos Iterator that points to the element to be removed.
353  ///
354  /// @return The iterator that follows the last item removed is returned.
355  ///
356  /// @note All iterators at or after this point of erasure will be
357  /// invalidated.
358  ///
359  iterator erase(iterator pos) { return m_data.erase(pos); }
360 
361  // **************************************************************************
362  /// Removes the range of specified elements from this container.
363  ///
364  /// @param first Iterator that points to the first element to be removed.
365  /// @param last Iterator that points to the last element to be removed.
366  ///
367  /// @return The iterator that follows the last item removed is returned.
368  ///
369  /// @note All iterators at or after this point of erasure will be
370  /// invalidated.
371  ///
372  iterator erase(iterator first, iterator last) { return m_data.erase(first, last);}
373 
374  // **************************************************************************
375  /// Removes the specified element from this container.
376  ///
377  /// @param pos Iterator that points to the element to be removed.
378  ///
379  /// @return The iterator that follows the last item removed is returned.
380  ///
381  /// @note All iterators at or after this point of erasure will be
382  /// invalidated.
383  ///
384  void push_back(const vector_type& value) { m_data.push_back(value); }
385 
386  // **************************************************************************
387  /// Removes the last element in the container.
388  ///
389  /// @note: Iterators that point to the last element and end will be
390  /// invalidated after this call.
391  ///
392  void pop_back() { if (!m_data.empty()) {
393  m_data.pop_back();
394  }
395  }
396 
397  // **************************************************************************
398  /// Exchanges the contents of this BitFieldVector container with those of other.
399  /// This version does not invoke any move, copy, or swap operations on
400  /// the individual elements.
401  ///
402  /// Iterators and references will remain valid, with the exception to the
403  /// end iterators.
404  ///
405  /// @param other The other vector to swap elements.
406  ///
407  void swap(BitFieldVector& other) { m_data.swap(other.m_data); }
408 
409  // **************************************************************************
410  /// Exchanges the contents of the container with those of other.
411  /// This version does not invoke any move, copy, or swap operations on
412  /// the individual elements.
413  ///
414  /// Iterators and references will remain valid, with the exception to the
415  /// end iterators.
416  ///
417  /// @param other The other vector to swap elements.
418  ///
419  void swap(value_type& other) { m_data.swap(other); }
420 
421 private:
422  // Data Members *************************************************************
423  vector_type m_data; ///< The data buffers that hold the
424  /// raw values for the collection of
425  /// bit-fields.
426 };
427 
428 
429 } // namespace Hg
430 
431 
432 #endif