Circulator.H
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2012-2015 OpenFOAM Foundation
9  Copyright (C) 2022 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 Class
28  Foam::Circulator
29 
30 Description
31  Walks over a container as if it were circular. The container must have the
32  following members defined:
33  - size_type
34  - difference_type
35  - iterator / const_iterator
36  - reference / const_reference
37 
38  Examples
39 
40  \code
41  face f(identity(5));
42 
43  // Construct Circulator from the face
44  Circulator<face> circ(f);
45 
46  // If it has a size to iterate over,
47  // circulate around the list starting and finishing at the fulcrum.
48  if (!circ.empty())
49  {
50  do
51  {
52  *circ += 1;
53 
54  Info<< "Iterate forwards over face : " << *circ << endl;
55 
56  } while (circ.circulate(CirculatorBase::FORWARD));
57  }
58  \endcode
59 
60 SourceFiles
61  CirculatorI.H
62 
63 \*---------------------------------------------------------------------------*/
64 
65 #ifndef Foam_Circulator_H
66 #define Foam_Circulator_H
67 
68 #include <type_traits> // std::conditional
69 
70 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
71 
72 namespace Foam
73 {
74 
75 /*---------------------------------------------------------------------------*\
76  Class CirculatorBase Declaration
77 \*---------------------------------------------------------------------------*/
78 
79 //- Template-invariant parts for circulators
80 class CirculatorBase
81 {
82 public:
83 
84  // Public Data
85 
86  //- Direction type enumeration
87  enum direction
88  {
92  };
93 
94 
95  // Constructors
96 
97  //- Default construct
98  CirculatorBase() = default;
99 };
100 
101 
102 /*---------------------------------------------------------------------------*\
103  Class CirculatorIters Declaration
104 \*---------------------------------------------------------------------------*/
105 
106 //- A pair of begin/end iterators used for implementing circular iteration
107 template<class Container, bool Const>
108 class CirculatorIters
109 :
110  public CirculatorBase
111 {
112 public:
113 
114  // STL type definitions
115 
116  //- The type that can represent the size of Container
117  using size_type = typename Container::size_type;
118 
119  //- The type that represents difference between iterator objects
120  using difference_type = typename Container::difference_type;
121 
122  //- The container iterator type (const/non-const)
123  using iterator = typename std::conditional
124  <
125  Const,
126  typename Container::const_iterator,
127  typename Container::iterator
128  >::type;
129 
130  //- The reference type (const/non-const)
131  using reference = typename std::conditional
132  <
133  Const,
134  typename Container::const_reference,
135  typename Container::reference
136  >::type;
138 
139 private:
140 
141  // Private Data
142 
143  //- The container beginning
144  iterator begin_;
145 
146  //- The container end
147  iterator end_;
148 
149  //- Random access iterator for traversing Container.
150  iterator iter_;
151 
152  //- Iterator holding location of the fulcrum (start and end) of
153  //- the container.
154  //- Used to decide when iterator should stop circulating the container
155  iterator fulcrum_;
156 
157 
158 protected:
159 
160  // Protected Member Functions
161 
162  //- Compare for equality
163  inline bool equal(const CirculatorIters<Container, Const>& rhs);
164 
165  //- Move iterator forward
166  inline void increment();
167 
168  //- Move iterator backward
169  inline void decrement();
170 
171 
172 public:
173 
174  // Constructors
175 
176  //- Default construct
177  inline CirculatorIters();
178 
179  //- Construct from begin/end iterators
180  inline CirculatorIters(const iterator& begin, const iterator& end);
181 
182  //- Copy construct
184 
185 
186  // Member Functions
187 
188  //- True if begin/end iterators are identical
189  inline bool empty() const;
190 
191  //- Return the range of the iterator pair
192  inline size_type size() const;
193 
194  //- The distance between the iterator and the fulcrum.
195  // This is equivalent to the number of rotations of the circulator
196  inline difference_type nRotations() const;
197 
198  //- Circulate around the list in the given direction
199  //- \return True if iterator has not yet reached the fulcrum
200  inline bool circulate
201  (
203  );
204 
205  //- Set the fulcrum to the current position of the iterator
206  inline void setFulcrumToIterator();
207 
208  //- Set the iterator to the current position of the fulcrum
209  inline void setIteratorToFulcrum();
210 
211  //- Dereference the current iterator
212  inline reference curr() const;
213 
214  //- Dereference the next iterator
215  inline reference next() const;
216 
217  //- Dereference the previous iterator
218  inline reference prev() const;
219 
220 
221  // Member Operators
222 
223  //- Assignment operator for circulators operating
224  //- on the same container type
225  inline void operator=(const CirculatorIters<Container, Const>& rhs);
226 
227  //- Prefix increment the iterator.
228  // Wraps iterator to the begin if it reaches the end
230 
231  //- Postfix increment the iterator.
232  // Wraps iterator to the begin if it reaches the end
234 
235  //- Prefix decrement the iterator.
236  // Wraps iterator to the end if it reaches the beginning
238 
239  //- Postfix decrement the iterator.
240  // Wraps iterator to the end if it reaches the beginning
242 
243  //- Check for equality of this iterator with another iterator that
244  //- operate on the same container type
245  inline bool operator==
246  (
248  ) const;
249 
250  //- Check for inequality of this iterator with another iterator that
251  //- operate on the same container type
252  inline bool operator!=
253  (
255  ) const;
256 
257  //- Dereference the iterator. Same as curr()
258  inline reference operator*() const;
259 
260  //- Dereference the iterator. Same as curr()
261  inline reference operator()() const;
262 
263  //- Return the difference between this iterator and another iterator
264  //- that operate on the same container type
265  inline difference_type operator-
266  (
268  ) const;
269 };
270 
271 
272 /*---------------------------------------------------------------------------*\
273  Class Circulator Declaration
274 \*---------------------------------------------------------------------------*/
275 
276 template<class Container>
277 class Circulator
278 :
279  public CirculatorIters<Container, false>
280 {
281 public:
282 
283  // Constructors
284 
285  //- Default construct
286  Circulator() = default;
287 
288  //- Construct from begin/end of a container
289  explicit Circulator(Container& obj)
290  :
291  CirculatorIters<Container, false>(obj.begin(), obj.end())
292  {}
293 
294  //- Construct from two iterators
295  Circulator
296  (
297  const typename Container::iterator& begin,
298  const typename Container::iterator& end
299  )
300  :
301  CirculatorIters<Container, false>(begin, end)
302  {}
303 
304  //- Copy construct
305  Circulator(const Circulator<Container>& rhs) = default;
306 
307 
308  // Member Operators
309 
310  //- Copy assignment
311  Circulator<Container>& operator=
312  (
313  const Circulator<Container>& rhs
314  ) = default;
315 };
316 
317 
318 /*---------------------------------------------------------------------------*\
319  Class ConstCirculator Declaration
320 \*---------------------------------------------------------------------------*/
321 
322 //- Like Foam::Circulator, but with const-access iterators
323 template<class Container>
324 class ConstCirculator
325 :
326  public CirculatorIters<Container, true>
327 {
328 public:
329 
330  // Constructors
331 
332  //- Default construct
333  ConstCirculator() = default;
334 
335  //- Construct from begin/end of a container
336  explicit ConstCirculator(const Container& obj)
337  :
338  CirculatorIters<Container, true>(obj.begin(), obj.end())
339  {}
340 
341  //- Construct from two iterators
342  inline ConstCirculator
343  (
344  const typename Container::const_iterator& begin,
345  const typename Container::const_iterator& end
346  )
347  :
348  CirculatorIters<Container, true>(begin, end)
349  {}
350 
351  //- Copy construct
352  ConstCirculator(const ConstCirculator<Container>& rhs) = default;
353 
354 
355  // Member Operators
356 
357  //- Copy assignment
358  ConstCirculator<Container>& operator=
359  (
360  const ConstCirculator<Container>& rhs
361  ) = default;
362 };
363 
364 
365 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
366 
367 } // End namespace Foam
368 
369 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
370 
371 #include "CirculatorI.H"
372 
373 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
374 
375 #endif
377 // ************************************************************************* //
reference prev() const
Dereference the previous iterator.
Definition: CirculatorI.H:183
CirculatorIters< Container, Const > & operator--()
Prefix decrement the iterator.
Definition: CirculatorI.H:235
typename Container::difference_type difference_type
The type that represents difference between iterator objects.
Definition: Circulator.H:127
void operator=(const CirculatorIters< Container, Const > &rhs)
Assignment operator for circulators operating on the same container type.
Definition: CirculatorI.H:198
CirculatorBase()=default
Default construct.
direction
Direction type enumeration.
Definition: Circulator.H:86
CirculatorIters()
Default construct.
Definition: CirculatorI.H:66
void setFulcrumToIterator()
Set the fulcrum to the current position of the iterator.
Definition: CirculatorI.H:147
void setIteratorToFulcrum()
Set the iterator to the current position of the fulcrum.
Definition: CirculatorI.H:154
void decrement()
Move iterator backward.
Definition: CirculatorI.H:52
difference_type nRotations() const
The distance between the iterator and the fulcrum.
Definition: CirculatorI.H:121
reference curr() const
Dereference the current iterator.
Definition: CirculatorI.H:162
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: POSIX.C:799
bool equal(const CirculatorIters< Container, Const > &rhs)
Compare for equality.
Definition: CirculatorI.H:26
reference operator()() const
Dereference the iterator. Same as curr()
Definition: CirculatorI.H:282
A pair of begin/end iterators used for implementing circular iteration.
Definition: Circulator.H:111
reference operator*() const
Dereference the iterator. Same as curr()
Definition: CirculatorI.H:274
CirculatorIters< Container, Const > & operator++()
Prefix increment the iterator.
Definition: CirculatorI.H:216
void increment()
Move iterator forward.
Definition: CirculatorI.H:41
size_type size() const
Return the range of the iterator pair.
Definition: CirculatorI.H:113
graph_traits< Graph >::vertices_size_type size_type
Definition: SloanRenumber.C:68
Circulator()=default
Default construct.
typename std::conditional< Const, typename Container::const_iterator, typename Container::iterator >::type iterator
The container iterator type (const/non-const)
Definition: Circulator.H:137
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
Definition: stdFoam.H:201
Walks over a container as if it were circular. The container must have the following members defined:...
Definition: Circulator.H:351
typename Container::size_type size_type
The type that can represent the size of Container.
Definition: Circulator.H:122
Template-invariant parts for circulators.
Definition: Circulator.H:77
ConstCirculator()=default
Default construct.
bool empty() const
True if begin/end iterators are identical.
Definition: CirculatorI.H:105
Like Foam::Circulator, but with const-access iterators.
Definition: Circulator.H:410
typename std::conditional< Const, typename Container::const_reference, typename Container::reference >::type reference
The reference type (const/non-const)
Definition: Circulator.H:147
bool circulate(const CirculatorBase::direction dir=CirculatorBase::NONE)
Circulate around the list in the given direction.
Definition: CirculatorI.H:129
constexpr auto begin(C &c) -> decltype(c.begin())
Return iterator to the beginning of the container c.
Definition: stdFoam.H:168
reference next() const
Dereference the next iterator.
Definition: CirculatorI.H:170
Namespace for OpenFOAM.