Alchemy  1.0
A framework to robustly process network messages and structured data
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
array_proxy.h
1 /// @file detail/array_proxy.h
2 ///
3 /// A parameterized type that abstracts the details of accessing Array entries
4 /// with a fixed-size field length.
5 ///
6 /// The MIT License(MIT)
7 /// @copyright 2014 Paul M Watt
8 // ****************************************************************************
9 #ifndef ARRAY_PROXY_H_INCLUDED
10 #define ARRAY_PROXY_H_INCLUDED
11 // Includes ******************************************************************
12 
13 #include <Pb/meta_fwd.h>
14 #include <Pb/type_list.h>
15 #include <Pb/type_at.h>
16 #include <Hg/datum/datum.h>
17 #include <Hg/storage_policy.h>
18 #include <array>
19 
20 namespace Hg
21 {
22 
23 namespace detail
24 {
25 
26 // Forward Declarations (No Default Implementation) ***************************
27 template< class ArrayT >
28 struct array_size;
29 
30 
31 // ****************************************************************************
32 /// Extracts the array extent from a std::array definition.
33 ///
34 template< class T, size_t N>
35 struct array_size< std::array<T, N> >
36  : std::integral_constant<size_t, N>
37 { };
38 
39 // ****************************************************************************
40 /// Extracts the array extent from a std::array definition.
41 ///
42 template< class T, size_t N>
43 struct array_size< Hg::BitFieldArray<T, N> >
44  : std::integral_constant<size_t, N>
45 { };
46 
47 
48 // ****************************************************************************
49 /// A template to provide access to sequences of data fields.
50 ///
51 /// @paramt IdxT The index of the array field represented by this proxy.
52 /// @paramt FormatType The type list format that contains the array field.
53 ///
54 template< size_t IdxT,
55  typename FormatT
56  >
57 struct DataProxy <array_trait, IdxT, FormatT>
58  : public Hg::Datum<IdxT, FormatT>
59 {
60  // Typedefs *****************************************************************
61  typedef FormatT format_type;
62 
63  typedef
64  Hg::Datum < IdxT,
65  format_type
66  > datum_type;
67 
68  typedef typename
70  format_type
71  >::type field_type;
72  ///< Type mapping for the message format
73  /// type to the actual value_type.
74 
75  typedef typename
77  ///< The type extracted at the current
78  /// index defined in the parent TypeList.
79 
80  typedef typename
81  index_type::value_type data_type;
82  ///< The value type of the element extracted
83  /// at the current index defined in the
84  /// parent TypeList.
85 
86  // Constants ****************************************************************
87  static
88  const size_t k_extent = array_size<index_type>::value;
89  ///< The number of elements in the array.
90 
91  // Typedefs *****************************************************************
92  typedef typename
93  std::conditional< std::is_base_of<array_trait, index_type>::value,
94  index_type,
95  typename field_type::value_type
96  >::type
97  value_type;
98 
99  ///< The data type managed by this Array.
100  /// This is the type of data that will
101  /// be written to the attached buffer.
102  ///
103  /// The index_type is redefined here
104  /// in order to capture and convert array
105  /// definitions like this: "(&T) [N]"
106  /// To the form: std::array<T,N>
107 
108 
109 
110  typedef typename /// Reference to an element in the array.
111  value_type::reference reference;
112 
113  typedef typename /// Const Reference to an element in the array.
114  value_type::const_reference const_reference;
115 
116  typedef typename /// An iterator to a value_type index.
117  value_type::iterator iterator;
118 
119  typedef typename /// A const iterator to a value_type index.
120  value_type::const_iterator const_iterator;
121 
122  typedef typename /// A reverse iterator to a value_type index.
123  value_type::reverse_iterator reverse_iterator;
124 
125  typedef typename /// A const reverse iterator to a value_type index.
126  value_type::const_reverse_iterator const_reverse_iterator;
127 
128  // **************************************************************************
129  /// Default Constructor
130  ///
132  { }
133 
134  // **************************************************************************
135  /// Copy Constructor
136  ///
137  /// Makes a complete copy of an existing Proxy object.
138  ///
139  /// @param proxy A reference to the Another instance of a DataProxy.
140  ///
141  DataProxy(const DataProxy& proxy)
142  {
143  set(proxy.get());
144  }
145 
146  // **************************************************************************
147  /// Value Constructor: Construct a proxy directly from a datum instance.
148  ///
149  /// @param datum A reference to a datum object used to initilize this.
150  ///
151  DataProxy(const datum_type& datum)
152  : datum_type(datum)
153  { }
154 
155  // **************************************************************************
156  /// Value Constructor: Construct a proxy directly from a datum instance.
157  ///
158  /// @param datum A reference to a datum object used to initilize this.
159  ///
160  DataProxy(const value_type& value)
161  {
162  set(value);
163  }
164 
165  // **************************************************************************
166  /// Value assignment
167  ///
169  {
170  *static_cast<datum_type*>(this) = value;
171  return *this;
172  }
173 
174  // **************************************************************************
175  /// Value assignment
176  ///
178  {
179  set(value);
180  return *this;
181  }
182 
183  // **************************************************************************
184  /// Returns the number of valid objects managed by this array structure.
185  ///
186  size_t size() const { return this->get().size(); }
187 
188  // **************************************************************************
189  /// Returns the number of bytes that are required to hold this array in a buffer.
190  ///
191  size_t size_of() const { return sizeof(this->get()); }
192 
193 
194  // **************************************************************************
195  /// Updates the value of this ArrayProxy with a std::array type.
196  ///
197  /// @param value The array which will initialize this object.
198  ///
199  void set(const value_type& value)
200  {
201  std::copy( value.begin(),
202  value.end(),
203  begin());
204  }
205 
206  // **************************************************************************
207  /// Updates the value of this Array with a native array type.
208  ///
209  /// @param value The array which will initialize this object.
210  ///
211  void set(const data_type (&value)[k_extent])
212  {
213  std::copy( &value[0],
214  (&value[0]) + k_extent,
215  begin());
216  }
217 
218  // **************************************************************************
219  /// Conversion operator to a base Datum Type.
220  ///
221  /// @note The converted Datum base provides access to the Attach and
222  /// Flush functions of the Datum.
223  ///
224  operator reference()
225  {
226  return *static_cast<datum_type*>(this);
227  }
228 
229  // **************************************************************************
230  /// Value Conversion Operator (value_type)
231  ///
232  /// Allows the entire BitSet to be extracted and assigned as a value to
233  /// the host value type.
234  ///
235  operator value_type() const
236  {
237  return static_cast<const datum_type*>(this)->operator value_type();
238  }
239 
240  // **************************************************************************
241  /// Accesses the value at the specified index in the array data..
242  ///
243  const_reference at(size_t idx) const { return this->get().at(idx); }
244 
245  // **************************************************************************
246  /// Accesses the value at the specified index in the array data..
247  ///
248  reference at(size_t idx) { return this->get().at(idx); }
249 
250  // **************************************************************************
251  /// Accesses the value at the specified index in the array data..
252  ///
253  const_reference operator[](size_t idx) const { return this->get()[idx]; }
254 
255  // **************************************************************************
256  /// Accesses the value at the specified index in the array data..
257  ///
258  reference operator[](size_t idx) { return this->get()[idx]; }
259 
260  // **************************************************************************
261  /// Accesses the value at the specified index in the array data..
262  ///
263  const_reference front() const { return this->get().front(); }
264 
265  // **************************************************************************
266  /// Accesses the value at the specified index in the array data..
267  ///
268  reference front() { return this->get().front(); }
269 
270  // **************************************************************************
271  /// Accesses the value at the specified index in the array data..
272  ///
273  const_reference back() const { return this->get().back(); }
274 
275  // **************************************************************************
276  /// Accesses the value at the specified index in the array data..
277  ///
278  reference back() { return this->get().back(); }
279 
280  // Iterator Functions *******************************************************
281  // **************************************************************************
282  /// Returns an iterator to the first item in the array.
283  ///
284  iterator begin() { return this->get().begin(); }
285  const_iterator begin() const { return this->get().begin(); }
286  const_iterator cbegin() const { return this->get().cbegin(); }
287 
288  // **************************************************************************
289  /// Returns an iterator to the item one passed the end of the array.
290  ///
291  iterator end() { return this->get().end(); }
292  const_iterator end() const { return this->get().end(); }
293  const_iterator cend() const { return this->get().cend(); }
294 
295  // **************************************************************************
296  /// Returns an iterator to the last item of the array moving in reverse.
297  ///
298  reverse_iterator rbegin() { return this->get().rbegin(); }
299  const_reverse_iterator rbegin() const { return this->get().rbegin(); }
300  const_reverse_iterator crbegin() const { return this->get().crbegin();}
301 
302  // **************************************************************************
303  /// Returns an iterator to the item one passed the beginning of the array,
304  /// moving in reverse.
305  ///
306  reverse_iterator rend() { return this->get().rend(); }
307  const_reverse_iterator rend() const { return this->get().rend(); }
308  const_reverse_iterator crend() const { return this->get().crend(); }
309 };
310 
311 
312 } // namespace detail
313 
314 } // namespace Hg
315 
316 #endif