Alchemy  1.0
A framework to robustly process network messages and structured data
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
datum.h
Go to the documentation of this file.
1 /// @file datum.h
2 ///
3 /// A type-wrapper that provides transparent access to a
4 /// range of memory in message buffer, as if it were the
5 /// specified type itself.
6 ///
7 /// The MIT License(MIT)
8 /// @copyright 2014 Paul M Watt
9 // ****************************************************************************
10 #ifndef DATUM_H_INCLUDED
11 #define DATUM_H_INCLUDED
12 // Includes *******************************************************************
13 #include <Pb/meta_fwd.h>
14 #include <Pb/type_at.h>
15 #include <Hg/datum/basic_datum.h>
16 
17 namespace Hg
18 {
19 
20 // ****************************************************************************
21 /// A type-wrapper that provides transparent access to a range
22 /// of memory in a message buffer as if it were the specified
23 /// type itself.
24 ///
25 /// The Datum<> is intended to be used as if it were the direct field itself.
26 /// All details of byte-order and memory-alignment are handled
27 /// internally by the buffers the Datum<> instance is mapped to.
28 ///
29 /// @param Idx [size_t] The index of this element in the
30 /// TypeList definition.
31 /// Idx must be < length<T>::value.
32 /// @param format_t [typename] The TypeList that contains this
33 /// elements definition.
34 /// T must be an indexable type container.
35 /// @note Parameterized type **T** is verified by the compiler to be
36 /// A type container.
37 ///
38 template <size_t Idx,
39  typename format_t
40  >
41 class Datum
42  : public detail::DefineFieldType< Idx, format_t>::type
43 {
44  static_assert(type_container<format_t>::value, "format_t must be a type container.");
45 
46 public:
47  // Constants ****************************************************************
48  static const
50  ///< The offset in the buffer where this
51  /// msg field is located.
52 
53  // Typedefs *****************************************************************
54  typedef typename
56  format_t
57  >::type field_type;
58  ///< Type mapping for the message format
59  /// type to the actual value_type.
60 
61  typedef typename
63  ///< The type extracted at the current
64  /// index defined in the parent TypeList.
65  typedef typename
67  ///< The data type managed by this Datum.
68  /// This is the type of data that will
69  /// be written to the attached buffer.
70 
71  typedef format_t format_type;
72  ///< format of the parent TypeList.
73 
74  // **************************************************************************
75  /// Default Constructor
76  ///
78  : field_type()
79  { }
80 
81  // **************************************************************************
82  /// Copy Constructor
83  ///
84  /// Makes a complete copy of an existing Datum object.
85  ///
86  /// @param datum A reference to the Another instance of a Datum.
87  ///
88  Datum(Datum& datum)
89  {
90  set(datum.get());
91  }
92 
93 #ifdef ALCHEMY_RVALUE_REF_SUPPORTED
94 
95  // **************************************************************************
96  /// Move Constructor
97  ///
98  /// Moves the current instance from one datum to another.
99  ///
100  /// @param proxy A rvalue reference to the another instance of a Datum.
101  ///
102  Datum(Datum&& datum)
103  {
104  *this = std::move(datum);
105  }
106 
107  // **************************************************************************
108  /// Move Assignment operator
109  ///
110  /// Moves the current instance from one datum to another.
111  ///
112  /// @param proxy A rvalue reference to the another instance of a Datum.
113  ///
114  Datum& operator=(Datum&& datum)
115  {
116  this->set(datum.get());
117  return *this;
118  }
119 
120 #endif
121 
122  // **************************************************************************
123  /// Assignment Operator
124  ///
125  /// Allows assignment of the Datum value.
126  /// Associated buffers are not changed through assignment.
127  ///
128  /// @param rhs A different instance of a Datum object whose
129  /// value will be copied into this instance.
130  ///
131  Datum& operator=(const Datum& rhs)
132  {
133  set(rhs.get());
134  return *this;
135  }
136 
137  // **************************************************************************
138  /// Assignment Operator (value_type)
139  ///
140  /// Allows assignment to this Datum type from it's parameter type, *value_type*.
141  /// This function is the key to allowing the Datum to behave as if the
142  /// assignment was performed directly on the the managed type.
143  ///
144  /// @param rhs A value of the Datum value_type that will
145  /// be used to directly modify the value of the object.
146  ///
147  Datum&
149  {
150  set(rhs);
151  return *this;
152  }
153 
154  // **************************************************************************
155  /// Operator to value_type
156  ///
157  /// Allows this Datum object to be converted to the value_type
158  /// managed by this object. The value returned comes from the data buffer.
159  ///
160  /// @return The current value of this object is returned.
161  ///
162  operator value_type() const
163  {
164  return get();
165  }
166 
167  // Comparison Operators *****************************************************
168  // **************************************************************************
169  /// Equality Value Comparison (value_type)
170  ///
171  /// @param rhs A value_type value to compare with the value
172  /// of this instance.
173  ///
174  bool operator==(const value_type& rhs) const
175  {
176  return equivalent(rhs);
177  }
178 
179  // **************************************************************************
180  /// Inequality Value Comparison (value_type)
181  ///
182  /// @param rhs A value_type value to compare with the value
183  /// of this instance.
184  ///
185  bool operator!=(const value_type& rhs) const
186  {
187  return !equivalent(rhs);
188  }
189 
190  // **************************************************************************
191  /// less Than Value Comparison (value_type)
192  ///
193  /// @param rhs A value_type value to compare with the value
194  /// of this instance.
195  ///
196  bool operator< (const value_type& rhs) const
197  {
198  return less(rhs);
199  }
200 
201  // **************************************************************************
202  /// less Than or equal Value Comparison (value_type)
203  ///
204  /// @param rhs A value_type value to compare with the value
205  /// of this instance.
206  ///
207  bool operator<=(const value_type& rhs) const
208  {
209  return less(rhs)
210  || equivalent(rhs);
211  }
212 
213  // **************************************************************************
214  /// Greater Than or equal Value Comparison (value_type)
215  ///
216  /// @param rhs A value_type value to compare with the value
217  /// of this instance.
218  ///
219  bool operator>=(const value_type& rhs) const
220  {
221  return !less(rhs);
222  }
223 
224  // **************************************************************************
225  /// Greater Than Value Comparison (value_type)
226  ///
227  /// @param rhs A value_type value to compare with the value
228  /// of this instance.
229  ///
230  bool operator> (const value_type& rhs) const
231  {
232  return !operator<=(rhs);
233  }
234 
235  // Methods ******************************************************************
236  // **************************************************************************
237  /// Zeros the datum.
238  ///
239  void clear ( )
240  {
241  set(value_type());
242  }
243 
244  // **************************************************************************
245  /// Returns the current value of this Datum.
246  ///
247  /// If a buffer is attached to this message field, the value will be read
248  /// from the buffer. Otherwise the data will be returned.
249  /// This const version will not update the data from the buffer.
250  ///
251  /// @return The value of this Datum is returned.
252  /// If a valid buffer is associated with this field, the data
253  /// referenced in the buffer is returned.
254  /// Otherwise the temporary locally cached value is returned.
255  ///
256  const value_type& get( ) const
257  {
258  return get_data();
259  }
260 
261  // **************************************************************************
262  /// Returns a reference to the value managed in this datum.
263  ///
264  value_type& get( )
265  {
266  return get_reference();
267  }
268 
269 
270  // **************************************************************************
271  /// Updates the value of this Datum.
272  ///
273  /// @param value The value to assign to this object.
274  /// The local cached value will be updated.
275  /// If a buffer has been associated with this object, its data
276  /// will be updated with the value as well.
277  ///
278  void set(const value_type& value)
279  {
280  set_data(value);
281  }
282 
283  // **************************************************************************
284  /// Indicates equivalency for a value_type and this Datum's value.
285  ///
286  /// @param rhs A value_type value to compare with the value
287  /// of this instance.
288  ///
289  bool equivalent(const value_type &rhs) const
290  {
291  return get() == rhs;
292  }
293 
294  // **************************************************************************
295  /// Compares a value_type against this Datum's value for less-than relationship.
296  ///
297  /// @param rhs A value_type value to compare with the value
298  /// of this instance.
299  ///
300  bool less(const value_type &rhs) const
301  {
302  return get() < rhs;
303  }
304 
305 protected:
306  // **************************************************************************
307  /// Returns a reference to the internal data storage.
308  ///
309  /// Returns a reference to the internal data storage managed by this
310  /// Datum. The reference to the data can be useful, and necessary for
311  ///
313  {
314  field_type* pThis = static_cast<field_type*>(this);
315  //return pThis->m_data;
316  return pThis->reference();
317  }
318 
319  // **************************************************************************
320  /// Returns the value of the data buffer.
321  ///
322  const value_type& get_data() const
323  {
324  const field_type* pThis = static_cast<const field_type*>(this);
325  return pThis->data();
326  //return pThis->m_data;
327  }
328 
329  // **************************************************************************
330  /// Returns the value of the data buffer.
331  ///
332  void set_data(const value_type &value)
333  {
334  Hg::detail::copy_value_type(get_reference(), value);
335  }
336 };
337 
338 } // namespace Hg
339 
340 #endif