Alchemy  1.0
A framework to robustly process network messages and structured data
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
vector_proxy.h
1 /// @file detail/vector_proxy.h
2 ///
3 /// The declaration and definition of the Vector DataProxy.
4 ///
5 /// A parameterized type that abstracts the details of accessing Datum entries
6 /// with variable length fields.
7 ///
8 /// The MIT License(MIT)
9 /// @copyright 2014 Paul M Watt
10 // ****************************************************************************
11 #ifndef VECTOR_PROXY_H_INCLUDED
12 #define VECTOR_PROXY_H_INCLUDED
13 // Includes ******************************************************************
14 
15 #include <Pb/meta_fwd.h>
16 #include <Pb/type_list.h>
17 #include <Pb/type_at.h>
18 #include <Hg/datum/datum.h>
19 #include <Hg/storage_policy.h>
20 #include <Hg/msg_view.h>
21 
22 #include <vector>
23 
24 namespace Hg
25 {
26 
27 namespace detail
28 {
29 
30 // ****************************************************************************
31 /// A template to provide access to sequences of data fields.
32 ///
33 /// @paramt IdxT
34 /// @paramt FormatType
35 ///
36 template< size_t IdxT,
37  typename FormatT
38  >
39 struct DataProxy <vector_trait, IdxT, FormatT>
40  : public Hg::Datum<IdxT, FormatT>
41 {
42  // Typedefs *****************************************************************
43  typedef FormatT format_type;
44 
45  typedef
46  Hg::Datum < IdxT,
47  format_type
48  > datum_type;
49 
50  typedef typename
52  format_type
53  >::type field_type;
54  ///< Type mapping for the message format
55  /// type to the actual value_type.
56 
57  typedef typename
59  ///< The raw type extracted at the current
60  /// index defined in the parent TypeList.
61 
62  typedef typename
63  index_type::value_type data_type;
64  ///< The value type of the element extracted
65  /// at the current index defined in the
66  /// parent TypeList.
67 
68  // Typedefs *****************************************************************
69  typedef typename
70  std::conditional< std::is_base_of<vector_trait, index_type>::value,
71  index_type,
72  typename field_type::value_type
73  >::type
74  value_type;
75 
76  typedef typename /// Reference to an element in the vector.
77  value_type::reference reference;
78 
79  typedef typename /// Const Reference to an element in the vector.
80  value_type::const_reference const_reference;
81 
82  typedef typename /// An iterator to a value_type index.
83  value_type::iterator iterator;
84 
85  typedef typename /// A const iterator to a value_type index.
86  value_type::const_iterator const_iterator;
87 
88  typedef typename /// A reverse iterator to a value_type index.
89  value_type::reverse_iterator reverse_iterator;
90 
91  typedef typename /// A const reverse iterator to a value_type index.
92  value_type::const_reverse_iterator const_reverse_iterator;
93 
94  // **************************************************************************
95  /// Default Constructor
96  ///
98  { }
99 
100  // **************************************************************************
101  /// Copy Constructor
102  ///
103  /// Makes a complete copy of an existing Proxy object.
104  ///
105  /// @param proxy A reference to the Another instance of a DataProxy.
106  ///
107  DataProxy(const DataProxy& proxy)
108  {
109  set(proxy.get());
110  }
111 
112  // **************************************************************************
113  /// Value Constructor: Construct a proxy directly from a datum instance.
114  ///
115  /// @param datum A reference to a datum object used to initilize this.
116  ///
117  DataProxy(const datum_type& datum)
118  : datum_type(datum)
119  { }
120 
121  // **************************************************************************
122  /// Value Constructor: Construct a proxy directly from a datum instance.
123  ///
124  /// @param datum A reference to a datum object used to initilize this.
125  ///
126  DataProxy(const value_type& value)
127  {
128  set(value);
129  }
130 
131  // **************************************************************************
132  /// Value assignment
133  ///
135  {
136  *static_cast<datum_type*>(this) = value;
137  return *this;
138  }
139 
140  // **************************************************************************
141  /// Value assignment
142  ///
144  {
145  set(value);
146  return *this;
147  }
148 
149  // **************************************************************************
150  /// Releases all allocated memory dedicated for storing entry data.
151  ///
152  void clear() { return this->get().clear(); }
153 
154  // **************************************************************************
155  /// Indicates if the vector does not have any space allocated for data.
156  ///
157  bool empty() { return this->get().empty(); }
158 
159  // **************************************************************************
160  /// Insures that space is reserved to hold at least new_cap elements.
161  ///
162  void reserve(size_t new_cap) { this->get().reserve(new_cap); }
163 
164  // **************************************************************************
165  /// Returns the number of elements that this vector can hold based on the
166  /// current allocated space.
167  ///
168  size_t capacity() const { return this->get().capacity(); }
169 
170  // **************************************************************************
171  /// Returns the number of valid objects managed by this vector structure.
172  ///
173  size_t size() const { return this->get().size(); }
174 
175  // **************************************************************************
176  /// Changes the number of elements stored.
177  ///
178  /// @param n The number of elements the container should now hold.
179  ///
180  void resize(size_t count) { resize(count, data_type()); }
181 
182  // **************************************************************************
183  /// Changes the number of elements stored.
184  ///
185  /// @param n The number of elements the container should now hold.
186  /// @param value Default value to initialize elements if the resize
187  /// causes new elements to be added to the container.
188  ///
189  void resize(size_t count,
190  data_type value) { this->get().resize(count, value); }
191 
192  // **************************************************************************
193  /// Updates the value of this VectorProxy with a std::vector type.
194  ///
195  /// @param value The vector which will initialize this object.
196  ///
197  void set(const value_type& value)
198  {
199  resize(value.size());
200  std::copy( value.begin(),
201  value.end(),
202  begin());
203  }
204 
205  // **************************************************************************
206  /// Updates the value of this Vector with a native array type.
207  ///
208  /// @param value The array which will initialize this object.
209  ///
210  template <size_t ExtentT>
211  void set(const data_type (&value)[ExtentT])
212  {
213  std::copy( &value[0],
214  (&value[0]) + ExtentT,
215  std::back_inserter(this->get()));
216  }
217 
218  // **************************************************************************
219  /// Replaces the contents of the container.
220  ///
221  void assign(size_t count, const data_type& value) { return this->get().assign(count, value); }
222 
223  // **************************************************************************
224  /// Replaces the contents of the container.
225  ///
226  template< typename InputIt >
227  void assign(InputIt first, InputIt last) { return this->get().assign(first, last); }
228 
229  // **************************************************************************
230  /// Conversion operator to a base Datum Type.
231  ///
232  /// @note The converted Datum base provides access to the Attach and
233  /// Flush functions of the Datum.
234  ///
235  operator reference()
236  {
237  return *static_cast<datum_type*>(this);
238  }
239 
240  // **************************************************************************
241  /// Value Conversion Operator (value_type)
242  ///
243  /// Allows the entire vector to be extracted and assigned as a value to
244  /// the host value type.
245  ///
246  operator value_type() const
247  {
248  return static_cast<const datum_type*>(this)->operator value_type();
249  }
250 
251  // **************************************************************************
252  /// Accesses the value at the specified index in the vector data..
253  ///
254  const_reference at(size_t idx) const { return this->get().at(idx); }
255 
256  // **************************************************************************
257  /// Accesses the value at the specified index in the vector data..
258  ///
259  reference at(size_t idx) { return this->get().at(idx); }
260 
261  // **************************************************************************
262  /// Accesses the value at the specified index in the vector data..
263  ///
264  const_reference operator[](size_t idx) const { return this->get()[idx]; }
265 
266  // **************************************************************************
267  /// Accesses the value at the specified index in the vector data..
268  ///
269  reference operator[](size_t idx) { return this->get()[idx]; }
270 
271  // **************************************************************************
272  /// Accesses the value at the specified index in the vector data..
273  ///
274  const_reference front() const { return this->get().front(); }
275 
276  // **************************************************************************
277  /// Accesses the value at the specified index in the vector data..
278  ///
279  reference front() { return this->get().front(); }
280 
281  // **************************************************************************
282  /// Accesses the value at the specified index in the vector data..
283  ///
284  const_reference back() const { return this->get().back(); }
285 
286  // **************************************************************************
287  /// Accesses the value at the specified index in the vector data..
288  ///
289  reference back() { return this->get().back(); }
290 
291  // Iterator Functions *******************************************************
292  // **************************************************************************
293  /// Returns an iterator to the first item in the vector.
294  ///
295  iterator begin() { return this->get().begin(); }
296  const_iterator begin() const { return this->get().begin(); }
297  const_iterator cbegin() const { return this->get().cbegin(); }
298 
299  // **************************************************************************
300  /// Returns an iterator to the item one passed the end of the vector.
301  ///
302  iterator end() { return this->get().end(); }
303  const_iterator end() const { return this->get().end(); }
304  const_iterator cend() const { return this->get().cend(); }
305 
306  // **************************************************************************
307  /// Returns an iterator to the last item of the vector moving in reverse.
308  ///
309  reverse_iterator rbegin() { return this->get().rbegin(); }
310  const_reverse_iterator rbegin() const { return this->get().rbegin(); }
311  const_reverse_iterator crbegin() const { return this->get().crbegin();}
312 
313  // **************************************************************************
314  /// Returns an iterator to the item one passed the beginning of the vector,
315  /// moving in reverse.
316  ///
317  reverse_iterator rend() { return this->get().rend(); }
318  const_reverse_iterator rend() const { return this->get().rend(); }
319  const_reverse_iterator crend() const { return this->get().crend(); }
320 
321  // Modifiers ****************************************************************
322  // **************************************************************************
323  /// Removes the specified element from this container.
324  ///
325  /// @param pos Iterator that points to the element to be removed.
326  ///
327  /// @return The iterator that follows the last item removed is returned.
328  ///
329  /// @note All iterators at or after this point of erasure will be
330  /// invalidated.
331  ///
332  iterator erase(iterator pos) { return this->get().erase(pos); }
333 
334  // **************************************************************************
335  /// Removes the range of specified elements from this container.
336  ///
337  /// @param first Iterator that points to the first element to be removed.
338  /// @param last Iterator that points to the last element to be removed.
339  ///
340  /// @return The iterator that follows the last item removed is returned.
341  ///
342  /// @note All iterators at or after this point of erasure will be
343  /// invalidated.
344  ///
345  iterator erase(iterator first, iterator last) { return this->get().erase(first, last);}
346 
347  // **************************************************************************
348  /// Removes the specified element from this container.
349  ///
350  /// @param pos Iterator that points to the element to be removed.
351  ///
352  /// @return The iterator that follows the last item removed is returned.
353  ///
354  /// @note All iterators at or after this point of erasure will be
355  /// invalidated.
356  ///
357  void push_back(const_reference value) { this->get().push_back(value); }
358 
359  // **************************************************************************
360  /// Removes the last element in the container.
361  ///
362  /// @note: Iterators that point to the last element and end will be
363  /// invalidated after this call.
364  ///
365  void pop_back() { if (!this->get().empty()) {
366  this->get().pop_back();
367  }
368  }
369 
370  // **************************************************************************
371  /// Exchanges the contents of this DataProxy container with those of other.
372  /// This version does not invoke any move, copy, or swap operations on
373  /// the individual elements.
374  ///
375  /// Iterators and references will remain valid, with the exception to the
376  /// end iterators.
377  ///
378  /// @param other The other vector to swap elements.
379  ///
380  void swap(DataProxy& other) { this->get().swap(other.get()); }
381 
382  // **************************************************************************
383  /// Exchanges the contents of the container with those of other.
384  /// This version does not invoke any move, copy, or swap operations on
385  /// the individual elements.
386  ///
387  /// Iterators and references will remain valid, with the exception to the
388  /// end iterators.
389  ///
390  /// @param other The other vector to swap elements.
391  ///
392  void swap(value_type& other) { this->get().swap(other); }
393 
394 };
395 
396 } // namespace detail
397 } // namespace Hg
398 
399 #endif