Lumiera  0.pre.03
»edit your freedom«
iter-stack.hpp
Go to the documentation of this file.
1 /*
2  ITER-STACK.hpp - a stack which can be popped by iterating
3 
4  Copyright (C) Lumiera.org
5  2012, 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 
55 #ifndef LIB_ITER_STACK_H
56 #define LIB_ITER_STACK_H
57 
58 
59 #include "lib/error.hpp"
60 #include "lib/iter-adapter.hpp"
61 #include "lib/nocopy.hpp"
62 #include "lib/util.hpp"
63 
64 #include <deque>
65 #include <utility>
66 
67 
68 namespace lib {
69 
70  using util::unConst;
71 
72  namespace iter {
73 
79  template<class TY>
81  : std::deque<TY>
82  {
83  /* === Iteration control API for IterStateWrapper == */
84 
85  bool
86  checkPoint() const
87  {
88  return not this->empty();
89  }
90 
91  TY &
92  yield() const
93  {
94  REQUIRE (not this->empty());
95  return unConst(this)->back();
96  }
97 
98  void
99  iterNext()
100  {
101  REQUIRE (not this->empty());
102  this->pop_back();
103  }
104  };
105  } // namespace lib::iter
106 
107 
108 
121  template<class TY>
122  struct IterStack
123  : IterStateWrapper<TY, iter::IterDequeStorage<TY>>
124  {
125 
126  // using default create and copy operations
127 
128  IterStack&
129  push (TY const& elm)
130  {
131  this->stateCore().push_back (elm);
132  return *this;
133  }
134 
135  IterStack&
136  push (TY&& elm)
137  {
138  this->stateCore().emplace_back (std::move (elm));
139  return *this;
140  }
141 
142  IterStack&
143  insert (TY const& elm)
144  {
145  return push(elm);
146  }
147 
148 
149  TY
150  pop()
151  {
152  this->__throw_if_empty();
153  TY topElement (std::move (this->stateCore().back()));
154  this->stateCore().pop_back();
155  return topElement;
156  }
157 
158  void
159  clear()
160  {
161  this->stateCore().clear();
162  }
163 
164 
165  /* == diagnostics == */
166 
167  size_t
168  size() const
169  {
170  return unConst(this)->stateCore().size();
171  }
172 
173  bool
174  empty() const
175  {
176  return 0 == size();
177  }
178  };
179 
180 
181 
182 
196  template<class TY>
197  struct IterQueue
198  : IterStateWrapper<TY, iter::IterDequeStorage<TY>>
199  {
200 
201  // using default create and copy operations
202 
203  IterQueue&
204  feed (TY const& elm)
205  {
206  this->stateCore().push_front (elm);
207  return *this;
208  }
209 
210  IterQueue&
211  feed (TY&& elm)
212  {
213  this->stateCore().emplace_front (std::move (elm));
214  return *this;
215  }
216 
217  IterQueue&
218  insert (TY const& elm)
219  {
220  return feed(elm);
221  }
222 
223  TY
224  pop()
225  {
226  this->__throw_if_empty();
227  TY firstElement (std::move (this->stateCore().back()));
228  this->stateCore().pop_back();
229  return firstElement;
230  }
231 
232 
233  /* == diagnostics == */
234 
235  size_t
236  size() const
237  {
238  return unConst(this)->stateCore().size();
239  }
240 
241  bool
242  empty() const
243  {
244  return 0 == size();
245  }
246 
247 
253  struct Builder
255  {
256  Builder(IterQueue& initialElements)
257  : queue_(initialElements)
258  { }
259  // standard copy operations allowed
260 
261  template<typename IT>
262  IterQueue &
263  usingSequence (IT src)
264  {
265  for ( ; src; ++src )
266  queue_.feed (*src);
267  return queue_;
268  }
269 
270  IterQueue &
271  wrapping (TY const& elm)
272  {
273  queue_.feed (elm);
274  return queue_;
275  }
276 
277  private:
278  IterQueue& queue_;
279  };
280 
290  friend IterQueue::Builder
291  build (IterQueue& initial)
292  {
293  return Builder(initial);
294  }
295  };
296 
297 
299  template<typename T>
300  inline IterQueue<T>
301  elements (T const& elm)
302  {
303  return IterQueue<T>().feed(elm);
304  }
305 
306  template<typename T>
307  inline IterQueue<T>
308  elements (T const& e0, T const& e1)
309  {
310  return IterQueue<T>().feed(e0).feed(e1);
311  }
312 
313  template<typename T>
314  inline IterQueue<T>
315  elements (T const& e0, T const& e1, T const& e2)
316  {
317  return IterQueue<T>().feed(e0).feed(e1).feed(e2);
318  }
319 
320  template<typename T>
321  inline IterQueue<T>
322  elements (T const& e0, T const& e1, T const& e2, T const& e3)
323  {
324  return IterQueue<T>().feed(e0).feed(e1).feed(e2).feed(e3);
325  }
326 
327  template<typename T>
328  inline IterQueue<T>
329  elements (T const& e0, T const& e1, T const& e2, T const& e3, T const& e4)
330  {
331  return IterQueue<T>().feed(e0).feed(e1).feed(e2).feed(e3).feed(e4);
332  }
333 
334 
335 
336 } // namespace lib
337 #endif
IterQueue< T > elements(T const &elm)
convenience free function to build an iterable sequence
Definition: iter-stack.hpp:301
A Stack which can be popped by iterating.
Definition: iter-stack.hpp:122
Helper template(s) for creating Lumiera Forward Iterators.
Implementation namespace for support and library code.
A Queue which can be pulled by iterating.
Definition: iter-stack.hpp:197
Mix-Ins to allow or prohibit various degrees of copying and cloning.
Another Lumiera Forward Iterator building block, based on incorporating a state type right into the i...
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
Types marked with this mix-in may be created by copy-construction (or move construction), but may be not reassigned thereafter.
Definition: nocopy.hpp:91
Lumiera error handling (C++ interface).
friend IterQueue::Builder build(IterQueue &initial)
Extension point to be picked up by ADL.
Definition: iter-stack.hpp:291
Wrapper to mark a std::deque instance for use as "state core" within lib::IterStateWrapper.
Definition: iter-stack.hpp:80
Adapter for use as opaque sequence.
Definition: iter-stack.hpp:253