Alchemy  1.0
A framework to robustly process network messages and structured data
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
msg_view_iterator.h
Go to the documentation of this file.
1 /// @file Hg/msg_view_iterator.h
2 ///
3 /// The msg_view iterator type for working with opaque types.
4 ///
5 /// The MIT License(MIT)
6 /// @copyright 2014 Paul M Watt
7 // ****************************************************************************
8 #ifndef msg_view_ITERATOR_H_INCLUDED
9 #define msg_view_ITERATOR_H_INCLUDED
10 // Includes ******************************************************************
11 #include <Hg/static_msg_buffer.h>
12 
13 namespace Hg
14 {
15 
16 template< typename MsgT,
17  typename StorageT
18  >
19 class basic_msg;
20 
21 // **************************************************************************
22 /// Iterator for nonmutable msg_view.
23 ///
24 template< typename T >
26 {
27 public:
29  typedef std::random_access_iterator_tag iterator_category;
30 
31  typedef basic_msg< T,
33  typedef ptrdiff_t difference_type;
34  typedef const value_type* pointer;
35  typedef const value_type& reference;
36  typedef value_type* Tptr;
37 
38  // **************************************************************************
39  /// Default constructor with a pointer to a NULL msg_view.
40  ///
42  : m_pBuffer()
43  , m_ptr()
44  { }
45 
46  // **************************************************************************
47  /// Initialized constructor with a pointer to a msg_view.
48  ///
50  : m_pBuffer(pArg)
51  , m_ptr()
52  { }
53 
54  // **************************************************************************
55  /// Return designated object.
56  ///
58  {
59  return (*Realize());
60  }
61 
62  // **************************************************************************
63  /// Return pointer to class object.
64  ///
66  {
67  return Realize();
68  }
69 
70  // **************************************************************************
71  /// Preincrement.
72  ///
74  {
75  m_ptr = 0;
76  m_pBuffer += k_size;
77  return (*this);
78  }
79 
80  // **************************************************************************
81  /// Postincrement.
82  ///
84  {
85  iter_t tmp = *this;
86 
87  m_ptr = 0;
88  m_pBuffer += k_size;
89 
90  return (tmp);
91  }
92 
93  // **************************************************************************
94  /// Predecrement.
95  ///
97  {
98  m_ptr = 0;
99  m_pBuffer -= k_size;
100  return (*this);
101  }
102 
103  // **************************************************************************
104  /// Postdecrement.
105  ///
107  {
108  iter_t tmp = *this;
109 
110  m_ptr = 0;
111  m_pBuffer -= k_size;
112 
113  return (tmp);
114  }
115 
116  // **************************************************************************
117  /// Increment by integer.
118  ///
119  iter_t& operator+=(difference_type offset)
120  {
121  m_ptr = 0;
122  m_pBuffer += k_size * offset;
123  return (*this);
124  }
125 
126  // **************************************************************************
127  /// Return this + integer.
128  ///
129  iter_t operator+(difference_type offset) const
130  {
131  iter_t tmp = *this;
132  return (tmp += offset);
133  }
134 
135  // **************************************************************************
136  /// Decrement by integer.
137  ///
138  iter_t& operator-=(difference_type offset)
139  {
140  m_ptr = 0;
141  m_pBuffer -= k_size * offset;
142  return (*this);
143  }
144 
145  // **************************************************************************
146  /// Return this - integer.
147  ///
148  iter_t operator-(difference_type offset) const
149  {
150  iter_t tmp = *this;
151  return (tmp -= offset);
152  }
153 
154  // **************************************************************************
155  /// Return difference of iterators.
156  ///
157  difference_type operator-(const iter_t& rhs) const
158  {
159  return (this->m_pBuffer - rhs.m_pBuffer) / k_size;
160  }
161 
162  // **************************************************************************
163  /// Subscript.
164  ///
165  reference operator[](difference_type offset) const
166  {
167  return (*(*this + offset));
168  }
169 
170  // **************************************************************************
171  /// Test for iterator equality.
172  ///
173  bool operator==(const iter_t& rhs) const
174  {
175  return (this->m_pBuffer == rhs.m_pBuffer);
176  }
177 
178  // **************************************************************************
179  /// Test for iterator inequality.
180  ///
181  bool operator!=(const iter_t& rhs) const
182  {
183  return (!(*this == rhs));
184  }
185 
186  // **************************************************************************
187  /// Test if this < rhs.
188  ///
189  bool operator<(const iter_t& rhs) const
190  {
191  return (this->m_pBuffer < rhs.m_pBuffer);
192  }
193 
194  // **************************************************************************
195  /// Test if this > rhs.
196  ///
197  bool operator>(const iter_t& rhs) const
198  {
199  return (rhs < *this);
200  }
201 
202  // **************************************************************************
203  /// Test if this <= rhs.
204  ///
205  bool operator<=(const iter_t& rhs) const
206  {
207  return (!(rhs < *this));
208  }
209 
210  // **************************************************************************
211  /// Test if this >= rhs.
212  ///
213  bool operator>=(const iter_t& rhs) const
214  {
215  return (!(*this < rhs));
216  }
217 
218 protected:
219  // Member Data **************************************************************
220  static const
222 
223 
224  byte_t *m_pBuffer; ///< pointer to the raw data buffer.
225 
226  mutable
227  value_type m_msg; ///< Instance of message to realize the
228  /// msg_view for each piece of data.
229  /// The message is realized each time the
230  /// iterator is dereferenced.
231 
232  mutable
233  Tptr m_ptr; ///< pointer to element in the msg_view
234 
235  // Member functions *********************************************************
236  // ************************************************************************
237  /// Indicates if this position has been dereferenced.
238  ///
240  {
241  return m_ptr != 0;
242  }
243 
244  // ************************************************************************
245  /// Reads the current data into the message context for interaction.
246  ///
247  Tptr Realize() const
248  {
249  if (m_ptr)
250  return m_ptr;
251 
252  m_msg.assign(m_pBuffer, k_size);
253  m_ptr = &m_msg;
254 
255  return m_ptr;
256  }
257 
258 };
259 
260 
261 // ****************************************************************************
262 /// Iterator for a mutable msg_view.
263 ///
264 template< typename T >
266  : public msg_view_const_iterator<T>
267 {
268 public:
271  typedef std::random_access_iterator_tag iterator_category;
272 
273  typedef basic_msg< T,
275  typedef ptrdiff_t difference_type;
276  typedef value_type* pointer;
277  typedef value_type& reference;
278 
279  // **************************************************************************
280  /// Default constructor for an iterator with a NULL msg_view pointer.
281  ///
283  { }
284 
285  // **************************************************************************
286  /// Constructor for an initialized iterator with a valid msg_view pointer.
287  ///
289  : base_t(pArg)
290  { }
291 
292  // **************************************************************************
293  /// Destructor
294  ///
296  {
297  Store();
298  }
299 
300  // **************************************************************************
301  /// Return designated object.
302  ///
304  {
305  return ((reference)**(base_t *)this);
306  }
307 
308  // **************************************************************************
309  /// Return pointer to class object.
310  ///
312  {
313  // TODO: Make sure a pointer_to implementation is always available.
314  //return (std::pointer_traits<pointer>::pointer_to(**this));
315  return ((pointer)*(base_t *)this);
316  }
317 
318  // **************************************************************************
319  /// Preincrement.
320  ///
322  {
323  Store();
324  ++*(base_t *)this;
325  return *this;
326  }
327 
328  // **************************************************************************
329  /// Postincrement.
330  ///
332  {
333  iter_t tmp = *this;
334  ++*this;
335  return tmp;
336  }
337 
338  // **************************************************************************
339  /// Predecrement.
340  ///
342  {
343  Store();
344  --*(base_t *)this;
345  return *this;
346  }
347 
348  // **************************************************************************
349  /// Postdecrement.
350  ///
352  {
353  iter_t tmp = *this;
354  --*this;
355  return tmp;
356  }
357 
358  // **************************************************************************
359  /// Increment by integer.
360  ///
361  iter_t& operator+=(difference_type offset)
362  {
363  Store();
364  *(base_t *)this += offset;
365  return *this;
366  }
367 
368  // **************************************************************************
369  /// Return this + integer.
370  ///
371  iter_t operator+(difference_type offset) const
372  {
373  iter_t tmp = *this;
374  return tmp += offset;
375  }
376 
377  // **************************************************************************
378  /// Decrement by integer.
379  ///
380  iter_t& operator-=(difference_type offset)
381  {
382  return *this += -offset;
383  }
384 
385  // **************************************************************************
386  /// Return this - integer.
387  ///
388  iter_t operator-(difference_type offset) const
389  {
390  iter_t tmp = *this;
391  return tmp -= offset;
392  }
393 
394  // **************************************************************************
395  /// Return difference of iterators.
396  ///
397  difference_type operator-(const base_t& rhs) const
398  {
399  return (*(base_t *)this - rhs);
400  }
401 
402  // **************************************************************************
403  /// Subscript
404  ///
405  reference operator[](difference_type offset) const
406  {
407  return (*(*this + offset));
408  }
409 
410 private:
411  // Member Functions *******************************************************
412  // ************************************************************************
413  /// Stores the current message context back into the data buffer.
414  ///
415  void Store()
416  {
417  if (base_t::is_referenced())
418  {
420  base_t::k_size);
421  }
422  }
423 };
424 
425 
426 } // namespace Hg
427 
428 #endif