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)
5  2012, 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 
46 #ifndef LIB_ITER_STACK_H
47 #define LIB_ITER_STACK_H
48 
49 
50 #include "lib/error.hpp"
51 #include "lib/iter-adapter.hpp"
52 #include "lib/nocopy.hpp"
53 #include "lib/util.hpp"
54 
55 #include <deque>
56 #include <utility>
57 
58 
59 namespace lib {
60 
61  using util::unConst;
62 
63  namespace iter {
64 
70  template<class TY>
72  : std::deque<TY>
73  {
74  /* === Iteration control API for IterStateWrapper == */
75 
76  bool
77  checkPoint() const
78  {
79  return not this->empty();
80  }
81 
82  TY &
83  yield() const
84  {
85  REQUIRE (not this->empty());
86  return unConst(this)->back();
87  }
88 
89  void
90  iterNext()
91  {
92  REQUIRE (not this->empty());
93  this->pop_back();
94  }
95  };
96  } // namespace lib::iter
97 
98 
99 
112  template<class TY>
113  struct IterStack
114  : IterStateWrapper<iter::IterDequeStorage<TY>>
115  {
116 
117  // using default create and copy operations
118 
119  IterStack&
120  push (TY const& elm)
121  {
122  this->stateCore().push_back (elm);
123  return *this;
124  }
125 
126  IterStack&
127  push (TY&& elm)
128  {
129  this->stateCore().emplace_back (std::move (elm));
130  return *this;
131  }
132 
133  IterStack&
134  insert (TY const& elm)
135  {
136  return push(elm);
137  }
138 
139 
140  TY
141  pop()
142  {
143  this->__throw_if_empty();
144  TY topElement (std::move (this->stateCore().back()));
145  this->stateCore().pop_back();
146  return topElement;
147  }
148 
149  void
150  clear()
151  {
152  this->stateCore().clear();
153  }
154 
155 
156  /* == diagnostics == */
157 
158  size_t
159  size() const
160  {
161  return unConst(this)->stateCore().size();
162  }
163 
164  bool
165  empty() const
166  {
167  return 0 == size();
168  }
169  };
170 
171 
172 
173 
187  template<class TY>
188  struct IterQueue
189  : IterStateWrapper<iter::IterDequeStorage<TY>>
190  {
191 
192  // using default create and copy operations
193 
194  IterQueue&
195  feed (TY const& elm)
196  {
197  this->stateCore().push_front (elm);
198  return *this;
199  }
200 
201  IterQueue&
202  feed (TY&& elm)
203  {
204  this->stateCore().emplace_front (std::move (elm));
205  return *this;
206  }
207 
208  IterQueue&
209  insert (TY const& elm)
210  {
211  return feed(elm);
212  }
213 
214  TY
215  pop()
216  {
217  this->__throw_if_empty();
218  TY firstElement (std::move (this->stateCore().back()));
219  this->stateCore().pop_back();
220  return firstElement;
221  }
222 
223 
224  /* == diagnostics == */
225 
226  size_t
227  size() const
228  {
229  return unConst(this)->stateCore().size();
230  }
231 
232  bool
233  empty() const
234  {
235  return 0 == size();
236  }
237 
238 
244  struct Builder
246  {
247  Builder(IterQueue& initialElements)
248  : queue_(initialElements)
249  { }
250  // standard copy operations allowed
251 
252  template<typename IT>
253  IterQueue &
254  usingSequence (IT src)
255  {
256  for ( ; src; ++src )
257  queue_.feed (*src);
258  return queue_;
259  }
260 
261  IterQueue &
262  wrapping (TY const& elm)
263  {
264  queue_.feed (elm);
265  return queue_;
266  }
267 
268  private:
269  IterQueue& queue_;
270  };
271 
281  friend IterQueue::Builder
282  build (IterQueue& initial)
283  {
284  return Builder(initial);
285  }
286  };
287 
288 
290  template<typename T>
291  inline IterQueue<T>
292  elements (T const& elm)
293  {
294  return IterQueue<T>().feed(elm);
295  }
296 
297  template<typename T>
298  inline IterQueue<T>
299  elements (T const& e0, T const& e1)
300  {
301  return IterQueue<T>().feed(e0).feed(e1);
302  }
303 
304  template<typename T>
305  inline IterQueue<T>
306  elements (T const& e0, T const& e1, T const& e2)
307  {
308  return IterQueue<T>().feed(e0).feed(e1).feed(e2);
309  }
310 
311  template<typename T>
312  inline IterQueue<T>
313  elements (T const& e0, T const& e1, T const& e2, T const& e3)
314  {
315  return IterQueue<T>().feed(e0).feed(e1).feed(e2).feed(e3);
316  }
317 
318  template<typename T>
319  inline IterQueue<T>
320  elements (T const& e0, T const& e1, T const& e2, T const& e3, T const& e4)
321  {
322  return IterQueue<T>().feed(e0).feed(e1).feed(e2).feed(e3).feed(e4);
323  }
324 
325 
326 
327 } // namespace lib
328 #endif
IterQueue< T > elements(T const &elm)
convenience free function to build an iterable sequence
Definition: iter-stack.hpp:292
A Stack which can be popped by iterating.
Definition: iter-stack.hpp:113
Helper template(s) for creating Lumiera Forward Iterators.
Any copy and copy construction prohibited.
Definition: nocopy.hpp:37
Implementation namespace for support and library code.
A Queue which can be pulled by iterating.
Definition: iter-stack.hpp:188
Mix-Ins to allow or prohibit various degrees of copying and cloning.
Another Lumiera Forward Iterator building block, based on incorporating a state type as »*State Core*...
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
Lumiera error handling (C++ interface).
friend IterQueue::Builder build(IterQueue &initial)
Extension point to be picked up by ADL.
Definition: iter-stack.hpp:282
Wrapper to mark a std::deque instance for use as "state core" within lib::IterStateWrapper.
Definition: iter-stack.hpp:71
Adapter for use as opaque sequence.
Definition: iter-stack.hpp:244