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) Lumiera.org
5  2015, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 */
22 
23 
39 #ifndef SRC_LIB_ITER_CURSOR_H
40 #define SRC_LIB_ITER_CURSOR_H
41 
42 
43 #include "lib/error.hpp"
44 #include "lib/iter-adapter.hpp"
45 
46 #include <type_traits>
47 #include <utility>
48 
49 
50 namespace lib {
51  namespace iter {
52 
57  template<class IT>
58  class CursorGear
59  {
60  bool backwards_{false};
61  const IT start_;
62  const IT end_;
63 
64  IT pos_;
65 
66 
67  public:
68  using pointer = typename meta::ValueTypeBinding<IT>::pointer;
69  using reference = typename meta::ValueTypeBinding<IT>::reference;
70  using value_type = typename std::remove_reference<reference>::type;
71 
72 
73  CursorGear()
74  : start_()
75  , end_()
76  , pos_()
77  { }
78 
79  CursorGear (IT&& begin, IT&& end)
80  : start_(std::forward<IT>(begin))
81  , end_(std::forward<IT>(end))
82  , pos_(start_)
83  { }
84 
85  // using default copy/assignment
86 
87 
88  void
89  reverse(bool backwards)
90  {
91  if (backwards != backwards_) reverse();
92  }
93 
94  void
95  reverse()
96  {
97  if (start_ == end_) return;
98  if (backwards_)
99  {
100  if (pos_ != start_) --pos_;
101  backwards_ = false;
102  }
103  else
104  {
105  if (pos_ != end_) ++pos_;
106  backwards_ = true;
107  }
108  }
109 
110  /* === Iteration control API for IterStateWrapper == */
111 
112  bool
113  checkPoint() const
114  {
115  return backwards_? pos_ != start_
116  : pos_ != end_;
117  }
118 
119  reference
120  yield() const
121  {
122  return backwards_? *(pos_-1)
123  : *(pos_);
124  }
125 
126  void
127  iterNext()
128  {
129  if (backwards_)
130  --pos_;
131  else
132  ++pos_;
133  }
134 
135 
136  friend bool
137  operator== (CursorGear const& g1, CursorGear const& g2)
138  {
139  return (not g1.checkPoint() and not g2.checkPoint()) // note: all exhausted iters are equal
140  or ( g1.pos_ == g2.pos_
141  and g1.backwards_ == g2.backwards_
142  and g1.start_ == g2.start_
143  and g1.end_ == g2.end_
144  );
145  }
146  };
147 
148 
149  } // namespace iter
150 
151 
152 
153 
165  template<class IT>
167  : public IterStateWrapper<typename iter::CursorGear<IT>::value_type, iter::CursorGear<IT>>
168  {
169  using _Core = iter::CursorGear<IT>;
171 
172  public:
173  IterCursor() =default;
174  IterCursor (IterCursor&&) =default;
175  IterCursor (IterCursor const&) =default;
176  IterCursor& operator= (IterCursor&&) =default;
177  IterCursor& operator= (IterCursor const&) =default;
178 
179 
180  template<class CON>
181  explicit
182  IterCursor (CON& container)
183  : _Parent(_Core(container.begin(), container.end()))
184  { }
185 
186  IterCursor (IT&& begin, IT&& end)
187  : _Parent(_Core(std::forward<IT>(begin), std::forward<IT>(end)))
188  { }
189 
190 
198  IterCursor&
200  {
201  this->stateCore().reverse();
202  return *this;
203  }
204 
205  IterCursor&
206  switchForwards()
207  {
208  this->stateCore().reverse(false);
209  return *this;
210  }
211 
212  IterCursor&
213  switchBackwards()
214  {
215  this->stateCore().reverse(true);
216  return *this;
217  }
218  };
219 
220 
221 } // namespace lib
222 #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 right into the i...
A cursor-like iterator with the ability to switch iteration direction.
typename std::remove_reference< reference >::type value_type
Definition: iter-cursor.hpp:70
Lumiera error handling (C++ interface).