Lumiera  0.pre.03
»edit your freedom«
iter-cursor.hpp
Go to the documentation of this file.
1 /*
2  ITER-CURSOR.hpp - wrap bidirectional STL container iterators
3 
4  Copyright (C)
5  2015, Hermann Vosseler <Ichthyostega@web.de>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 */
13 
14 
30 #ifndef SRC_LIB_ITER_CURSOR_H
31 #define SRC_LIB_ITER_CURSOR_H
32 
33 
34 #include "lib/error.hpp"
35 #include "lib/iter-adapter.hpp"
36 
37 #include <type_traits>
38 #include <utility>
39 
40 
41 namespace lib {
42  namespace iter {
43 
48  template<class IT>
49  class CursorGear
50  {
51  bool backwards_{false};
52  const IT start_;
53  const IT end_;
54 
55  IT pos_;
56 
57 
58  public:
59  using pointer = typename meta::ValueTypeBinding<IT>::pointer;
60  using reference = typename meta::ValueTypeBinding<IT>::reference;
61  using value_type = typename std::remove_reference<reference>::type;
62 
63 
64  CursorGear()
65  : start_()
66  , end_()
67  , pos_()
68  { }
69 
70  CursorGear (IT&& begin, IT&& end)
71  : start_(std::forward<IT>(begin))
72  , end_(std::forward<IT>(end))
73  , pos_(start_)
74  { }
75 
76  // using default copy/assignment
77 
78 
79  void
80  reverse(bool backwards)
81  {
82  if (backwards != backwards_) reverse();
83  }
84 
85  void
86  reverse()
87  {
88  if (start_ == end_) return;
89  if (backwards_)
90  {
91  if (pos_ != start_) --pos_;
92  backwards_ = false;
93  }
94  else
95  {
96  if (pos_ != end_) ++pos_;
97  backwards_ = true;
98  }
99  }
100 
101  /* === Iteration control API for IterStateWrapper == */
102 
103  bool
104  checkPoint() const
105  {
106  return backwards_? pos_ != start_
107  : pos_ != end_;
108  }
109 
110  reference
111  yield() const
112  {
113  return backwards_? *(pos_-1)
114  : *(pos_);
115  }
116 
117  void
118  iterNext()
119  {
120  if (backwards_)
121  --pos_;
122  else
123  ++pos_;
124  }
125 
126 
127  friend bool
128  operator== (CursorGear const& g1, CursorGear const& g2)
129  {
130  return (not g1.checkPoint() and not g2.checkPoint()) // note: all exhausted iters are equal
131  or ( g1.pos_ == g2.pos_
132  and g1.backwards_ == g2.backwards_
133  and g1.start_ == g2.start_
134  and g1.end_ == g2.end_
135  );
136  }
137  };
138 
139 
140  } // namespace iter
141 
142 
143 
144 
156  template<class IT>
158  : public IterStateWrapper<iter::CursorGear<IT>>
159  {
160  using _Core = iter::CursorGear<IT>;
162 
163  public:
164  IterCursor() =default;
165  IterCursor (IterCursor&&) =default;
166  IterCursor (IterCursor const&) =default;
167  IterCursor& operator= (IterCursor&&) =default;
168  IterCursor& operator= (IterCursor const&) =default;
169 
170 
171  template<class CON>
172  explicit
173  IterCursor (CON& container)
174  : _Parent(_Core(container.begin(), container.end()))
175  { }
176 
177  IterCursor (IT&& begin, IT&& end)
178  : _Parent(_Core(std::forward<IT>(begin), std::forward<IT>(end)))
179  { }
180 
181 
189  IterCursor&
191  {
192  this->stateCore().reverse();
193  return *this;
194  }
195 
196  IterCursor&
197  switchForwards()
198  {
199  this->stateCore().reverse(false);
200  return *this;
201  }
202 
203  IterCursor&
204  switchBackwards()
205  {
206  this->stateCore().reverse(true);
207  return *this;
208  }
209  };
210 
211 
212 } // namespace lib
213 #endif /*SRC_LIB_ITER_CURSOR_H*/
Helper template(s) for creating Lumiera Forward Iterators.
IterCursor & switchDir()
change the orientation of iteration.
Implementation namespace for support and library code.
Another Lumiera Forward Iterator building block, based on incorporating a state type as »*State Core*...
A cursor-like iterator with the ability to switch iteration direction.
typename std::remove_reference< reference >::type value_type
Definition: iter-cursor.hpp:61
Lumiera error handling (C++ interface).