From 23f04e33b5eb35f4d44d97f14094d1cc98dd37c8 Mon Sep 17 00:00:00 2001 From: laurence Date: Tue, 11 Dec 2012 16:18:29 +0000 Subject: [PATCH] ENH: circulator added circulator and const_circulator wrap around lists so that they may be iterated over indefinitely. --- applications/test/Circulator/Make/files | 3 + applications/test/Circulator/Make/options | 0 .../test/Circulator/Test-Circulator.C | 268 ++++++++++++++++ .../CirculatorBase/CirculatorBase.H | 77 +++++ .../Circulators/circulator/circulator.H | 227 ++++++++++++++ .../Circulators/circulator/circulatorI.H | 290 +++++++++++++++++ .../const_circulator/const_circulator.H | 247 +++++++++++++++ .../const_circulator/const_circulatorI.H | 293 ++++++++++++++++++ 8 files changed, 1405 insertions(+) create mode 100644 applications/test/Circulator/Make/files create mode 100644 applications/test/Circulator/Make/options create mode 100644 applications/test/Circulator/Test-Circulator.C create mode 100644 src/OpenFOAM/containers/Circulators/CirculatorBase/CirculatorBase.H create mode 100644 src/OpenFOAM/containers/Circulators/circulator/circulator.H create mode 100644 src/OpenFOAM/containers/Circulators/circulator/circulatorI.H create mode 100644 src/OpenFOAM/containers/Circulators/const_circulator/const_circulator.H create mode 100644 src/OpenFOAM/containers/Circulators/const_circulator/const_circulatorI.H diff --git a/applications/test/Circulator/Make/files b/applications/test/Circulator/Make/files new file mode 100644 index 0000000000..b6a4e63dc2 --- /dev/null +++ b/applications/test/Circulator/Make/files @@ -0,0 +1,3 @@ +Test-Circulator.C + +EXE = $(FOAM_USER_APPBIN)/Test-Circulator diff --git a/applications/test/Circulator/Make/options b/applications/test/Circulator/Make/options new file mode 100644 index 0000000000..e69de29bb2 diff --git a/applications/test/Circulator/Test-Circulator.C b/applications/test/Circulator/Test-Circulator.C new file mode 100644 index 0000000000..19a21f6b79 --- /dev/null +++ b/applications/test/Circulator/Test-Circulator.C @@ -0,0 +1,268 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2012 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see . + +Application + Test-circulator + +Description + +\*---------------------------------------------------------------------------*/ + +#include "List.H" +#include "ListOps.H" +#include "face.H" +#include "circulator.H" +#include "const_circulator.H" + + +using namespace Foam; + + +// return +// 0: no match +// +1: identical +// -1: same face, but different orientation +label compare(const face& a, const face& b) +{ + // Basic rule: we assume that the sequence of labels in each list + // will be circular in the same order (but not necessarily in the + // same direction or from the same starting point). + + // Trivial reject: faces are different size + label sizeA = a.size(); + label sizeB = b.size(); + + if (sizeA != sizeB || sizeA == 0) + { + return 0; + } + + const_circulator aCirc(a); + const_circulator bCirc(b); + + // Rotate face b until its element matches the starting element of face a. + do + { + if (aCirc() == bCirc()) + { + // Set bCirc fulcrum to its iterator and increment the iterators + bCirc.setFulcrumToIterator(); + ++aCirc; + ++bCirc; + + break; + } + } while (bCirc.circulate(CirculatorBase::CLOCKWISE)); + + // Look forwards around the faces for a match + do + { + if (aCirc() != bCirc()) + { + break; + } + } + while + ( + aCirc.circulate(CirculatorBase::CLOCKWISE), + bCirc.circulate(CirculatorBase::CLOCKWISE) + ); + + // If the circulator has stopped then faces a and b matched. + if (!aCirc.circulate()) + { + return 1; + } + else + { + // Reset the circulators back to their fulcrum + aCirc.setIteratorToFulcrum(); + bCirc.setIteratorToFulcrum(); + ++aCirc; + --bCirc; + } + + // Look backwards around the faces for a match + do + { + if (aCirc() != bCirc()) + { + break; + } + } + while + ( + aCirc.circulate(CirculatorBase::CLOCKWISE), + bCirc.circulate(CirculatorBase::ANTICLOCKWISE) + ); + + // If the circulator has stopped then faces a and b matched. + if (!aCirc.circulate()) + { + return -1; + } + + return 0; +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// Main program: + +int main(int argc, char *argv[]) +{ + Info<< "Test the implementation of a circular iterator" << nl << endl; + + Info<< "Test const circulator. First go forwards, then backwards." + << nl << endl; + + face f(identity(4)); + + const_circulator cStart(f); + + if (cStart.size()) do + { + Info<< "Iterate forwards over face (prev/curr/next) : " + << cStart.prev() << " / " << cStart() << " / " << cStart.next() + << endl; + + } while (cStart.circulate(CirculatorBase::CLOCKWISE)); + + if (cStart.size()) do + { + Info<< "Iterate backwards over face : " << cStart() << endl; + + } while (cStart.circulate(CirculatorBase::ANTICLOCKWISE)); + + + Info<< nl << nl << "Test non-const circulator" << nl << endl; + + circulator cStart2(f); + + Info<< "Face before : " << f << endl; + + if (cStart2.size()) do + { + Info<< "Iterate forwards over face (prev/curr/next) : " + << cStart2.prev() << " / " << cStart2() << " / " << cStart2.next() + << endl; + + } while (cStart2.circulate(CirculatorBase::CLOCKWISE)); + + if (cStart2.size()) do + { + Info<< "Iterate forwards over face, adding 1 to each element : " + << cStart2(); + + cStart2() += 1; + + Info<< " -> " << cStart2() << endl; + } while (cStart2.circulate(CirculatorBase::CLOCKWISE)); + + Info<< "Face after : " << f << endl; + + + Info<< nl << nl << "Compare two faces: " << endl; + face a(identity(5)); + Info<< "Compare " << a << " and " << a << " Match = " << compare(a, a) + << endl; + + face b(reverseList(a)); + Info<< "Compare " << a << " and " << b << " Match = " << compare(a, b) + << endl; + + face c(a); + c[4] = 3; + Info<< "Compare " << a << " and " << c << " Match = " << compare(a, c) + << endl; + + face d(rotateList(a, 2)); + Info<< "Compare " << a << " and " << d << " Match = " << compare(a, d) + << endl; + + face g(labelList(5, 1)); + face h(g); + Info<< "Compare " << g << " and " << h << " Match = " << compare(g, h) + << endl; + + g[0] = 2; + h[3] = 2; + Info<< "Compare " << g << " and " << h << " Match = " << compare(g, h) + << endl; + + g[4] = 3; + h[4] = 3; + Info<< "Compare " << g << " and " << h << " Match = " << compare(g, h) + << endl; + + face face1(identity(1)); + Info<< "Compare " << face1 << " and " << face1 + << " Match = " << compare(face1, face1) << endl; + + Info<< nl << nl << "Zero face" << nl << endl; + + face fZero; + circulator cZero(fZero); + + if (cZero.size()) do + { + Info<< "Iterate forwards over face : " << cZero() << endl; + + } while (cZero.circulate(CirculatorBase::CLOCKWISE)); + + fZero = face(identity(5)); + + // circulator was invalidated so reset + cZero = circulator(fZero); + + do + { + Info<< "Iterate forwards over face : " << cZero() << endl; + + } while (cZero.circulate(CirculatorBase::CLOCKWISE)); + + + Info<< nl << nl << "Simultaneously go forwards/backwards over face " << f + << nl << endl; + + const_circulator circForward(f); + const_circulator circBackward(f); + + if (circForward.size() && circBackward.size()) do + { + Info<< "Iterate over face forwards : " << circForward() + << ", backwards : " << circBackward() << endl; + } + while + ( + circForward.circulate(CirculatorBase::CLOCKWISE), + circBackward.circulate(CirculatorBase::ANTICLOCKWISE) + ); + + Info<< "\nEnd\n" << endl; + + return 0; +} + + +// ************************************************************************* // diff --git a/src/OpenFOAM/containers/Circulators/CirculatorBase/CirculatorBase.H b/src/OpenFOAM/containers/Circulators/CirculatorBase/CirculatorBase.H new file mode 100644 index 0000000000..d1ab166bab --- /dev/null +++ b/src/OpenFOAM/containers/Circulators/CirculatorBase/CirculatorBase.H @@ -0,0 +1,77 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2012 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see . + +Class + Foam::CirculatorBase + +Description + Base class for circulators + +\*---------------------------------------------------------------------------*/ + +#ifndef CirculatorBase_H +#define CirculatorBase_H + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + + +/*---------------------------------------------------------------------------*\ + Class CirculatorBase Declaration +\*---------------------------------------------------------------------------*/ + +class CirculatorBase +{ +public: + + // Public data + + //- Direction type enumeration + enum direction + { + NONE, + CLOCKWISE, + ANTICLOCKWISE + }; + + + // Constructors + + //- Construct null + CirculatorBase(){}; + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/OpenFOAM/containers/Circulators/circulator/circulator.H b/src/OpenFOAM/containers/Circulators/circulator/circulator.H new file mode 100644 index 0000000000..15188df982 --- /dev/null +++ b/src/OpenFOAM/containers/Circulators/circulator/circulator.H @@ -0,0 +1,227 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2012 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see . + +Class + Foam::circulator + +Description + Walks over a container as if it were circular. The container must have the + following members defined: + - value_type + - size_type + - difference_type + - iterator + - reference + + Examples + + \code + face f(identity(5)); + + // Construct circulator from the face + circulator circ(f); + + // First check that the circulator has a size to iterate over. + // Then circulate around the list starting and finishing at the fulcrum. + if (circ.size()) do + { + circ() += 1; + + Info<< "Iterate forwards over face : " << circ() << endl; + + } while (circ.circulate(CirculatorBase::CLOCKWISE)); + \endcode + +SourceFiles + circulatorI.H + +\*---------------------------------------------------------------------------*/ + +#ifndef circulator_H +#define circulator_H + +#include "CirculatorBase.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + + +/*---------------------------------------------------------------------------*\ + Class circulator Declaration +\*---------------------------------------------------------------------------*/ + +template +class circulator +: + public CirculatorBase +{ + +protected: + + // Protected data + + //- Iterator pointing to the beginning of the container + typename ContainerType::iterator begin_; + + //- Iterator pointing to the end of the container + typename ContainerType::iterator end_; + + //- Random access iterator for traversing ContainerType. + typename ContainerType::iterator iter_; + + //- Iterator holding the location of the fulcrum (start and end) of + // the container. Used to decide when the iterator should stop + // circulating over the container + typename ContainerType::iterator fulcrum_; + + +public: + + // STL type definitions + + //- Type of values ContainerType contains. + typedef typename ContainerType::value_type value_type; + + //- The type that can represent the size of ContainerType + typedef typename ContainerType::size_type size_type; + + //- The type that can represent the difference between any two + // iterator objects. + typedef typename ContainerType::difference_type difference_type; + + //- Random access iterator for traversing ContainerType. + typedef typename ContainerType::iterator iterator; + + //- Type that can be used for storing into + // ContainerType::value_type objects. + typedef typename ContainerType::reference reference; + + + // Constructors + + //- Construct null + inline circulator(); + + //- Construct from a container. + inline explicit circulator(ContainerType& container); + + //- Construct from two iterators + inline circulator(const iterator& begin, const iterator& end); + + //- Construct as copy + inline circulator(const circulator&); + + + //- Destructor + ~circulator(); + + + // Member Functions + + //- Return the range of the iterator + inline size_type size() const; + + //- Circulate around the list in the given direction + inline bool circulate(const CirculatorBase::direction dir = NONE); + + //- Set the fulcrum to the current position of the iterator + inline void setFulcrumToIterator(); + + //- Set the iterator to the current position of the fulcrum + inline void setIteratorToFulcrum(); + + //- Return the distance between the iterator and the fulcrum. This is + // equivalent to the number of rotations of the circulator. + inline difference_type nRotations() const; + + //- Dereference the next iterator and return + inline reference next() const; + + //- Dereference the previous iterator and return + inline reference prev() const; + + + // Member Operators + + //- Assignment operator for circulators that operate on the same + // container type + inline void operator=(const circulator&); + + //- Prefix increment. Increments the iterator. + // Sets the iterator to the beginning of the container if it reaches + // the end + inline circulator& operator++(); + + //- Postfix increment. Increments the iterator. + // Sets the iterator to the beginning of the container if it reaches + // the end + inline circulator operator++(int); + + //- Prefix decrement. Decrements the iterator. + // Sets the iterator to the end of the container if it reaches + // the beginning + inline circulator& operator--(); + + //- Postfix decrement. Decrements the iterator. + // Sets the iterator to the end of the container if it reaches + // the beginning + inline circulator operator--(int); + + //- Check for equality of this iterator with another iterator that + // operate on the same container type + inline bool operator==(const circulator& c) const; + + //- Check for inequality of this iterator with another iterator that + // operate on the same container type + inline bool operator!=(const circulator& c) const; + + //- Dereference the iterator and return + inline reference operator*() const; + + //- Dereference the iterator and return + inline reference operator()() const; + + //- Return the difference between this iterator and another iterator + // that operate on the same container type + inline difference_type operator- + ( + const circulator& c + ) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "circulatorI.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/OpenFOAM/containers/Circulators/circulator/circulatorI.H b/src/OpenFOAM/containers/Circulators/circulator/circulatorI.H new file mode 100644 index 0000000000..e39f1fa27d --- /dev/null +++ b/src/OpenFOAM/containers/Circulators/circulator/circulatorI.H @@ -0,0 +1,290 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2012 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see . + +\*---------------------------------------------------------------------------*/ + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +template +Foam::circulator::circulator() +: + CirculatorBase(), + begin_(0), + end_(0), + iter_(0), + fulcrum_(0) +{} + + +template +Foam::circulator::circulator(ContainerType& container) +: + CirculatorBase(), + begin_(container.begin()), + end_(container.end()), + iter_(begin_), + fulcrum_(begin_) +{} + + +template +Foam::circulator::circulator +( + const iterator& begin, + const iterator& end +) +: + CirculatorBase(), + begin_(begin), + end_(end), + iter_(begin), + fulcrum_(begin) +{} + + +template +Foam::circulator::circulator +( + const circulator& rhs +) +: + CirculatorBase(), + begin_(rhs.begin_), + end_(rhs.end_), + iter_(rhs.iter_), + fulcrum_(rhs.fulcrum_) +{} + + +// * * * * * * * * * * * * * * * * Destructors * * * * * * * * * * * * * * * // + +template +Foam::circulator::~circulator() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template +typename Foam::circulator::size_type +Foam::circulator::size() const +{ + return end_ - begin_; +} + + +template +bool Foam::circulator::circulate +( + const CirculatorBase::direction dir +) +{ + if (dir == CirculatorBase::CLOCKWISE) + { + operator++(); + } + else if (dir == CirculatorBase::ANTICLOCKWISE) + { + operator--(); + } + + return !(iter_ == fulcrum_); +} + + +template +void Foam::circulator::setFulcrumToIterator() +{ + fulcrum_ = iter_; +} + + +template +void Foam::circulator::setIteratorToFulcrum() +{ + iter_ = fulcrum_; +} + + +template +typename Foam::circulator::difference_type +Foam::circulator::nRotations() const +{ + return (iter_ - fulcrum_); +} + + +template +typename Foam::circulator::reference +Foam::circulator::next() const +{ + if (iter_ == end_ - 1) + { + return *begin_; + } + + return *(iter_ + 1); +} + + +template +typename Foam::circulator::reference +Foam::circulator::prev() const +{ + if (iter_ == begin_) + { + return *(end_ - 1); + } + + return *(iter_ - 1); +} + + +// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // + +template +void Foam::circulator::operator= +( + const circulator& rhs +) +{ + // Check for assignment to self + if (this == &rhs) + { + FatalErrorIn + ( + "Foam::circulator::operator=" + "(const Foam::circulator&)" + ) << "Attempted assignment to self" + << abort(FatalError); + } + + begin_ = rhs.begin_; + end_ = rhs.end_; + iter_ = rhs.iter_; + fulcrum_ = rhs.fulcrum_; +} + + +template +Foam::circulator& +Foam::circulator::operator++() +{ + ++iter_; + if (iter_ == end_) + { + iter_ = begin_; + } + + return *this; +} + + +template +Foam::circulator +Foam::circulator::operator++(int) +{ + circulator tmp = *this; + ++(*this); + return tmp; +} + + +template +Foam::circulator& +Foam::circulator::operator--() +{ + if (iter_ == begin_) + { + iter_ = end_; + } + --iter_; + + return *this; +} + + +template +Foam::circulator +Foam::circulator::operator--(int) +{ + circulator tmp = *this; + --(*this); + return tmp; +} + + +template +bool Foam::circulator::operator== +( + const circulator& c +) const +{ + return + ( + begin_ == c.begin_ + && end_ == c.end_ + && iter_ == c.iter_ + && fulcrum_ == c.fulcrum_ + ); +} + + +template +bool Foam::circulator::operator!= +( + const circulator& c +) const +{ + return !(*this == c); +} + + +template +typename Foam::circulator::reference +Foam::circulator::operator*() const +{ + return *iter_; +} + + +template +typename Foam::circulator::reference +Foam::circulator::operator()() const +{ + return operator*(); +} + + +template +typename Foam::circulator::difference_type +Foam::circulator::operator- +( + const circulator& c +) const +{ + return iter_ - c.iter_; +} + + +// ************************************************************************* // diff --git a/src/OpenFOAM/containers/Circulators/const_circulator/const_circulator.H b/src/OpenFOAM/containers/Circulators/const_circulator/const_circulator.H new file mode 100644 index 0000000000..fc8ba633aa --- /dev/null +++ b/src/OpenFOAM/containers/Circulators/const_circulator/const_circulator.H @@ -0,0 +1,247 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2012 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see . + +Class + Foam::const_circulator + +Description + Walks over a container as if it were circular. The container must have the + following members defined: + - value_type + - size_type + - difference_type + - const_iterator + - const_reference + + Examples: + + \code + face f(identity(5)); + + // Construct circulator from the face + const_circulator circ(f); + + // First check that the circulator has a size to iterate over. + // Then circulate around the list starting and finishing at the fulcrum. + if (circ.size()) do + { + Info<< "Iterate forwards over face : " << circ() << endl; + + } while (circ.circulate(CirculatorBase::CLOCKWISE)); + \endcode + + \code + face f(identity(5)); + + const_circulator circClockwise(f); + const_circulator circAnticlockwise(f); + + if (circClockwise.size() && circAnticlockwise.size()) do + { + Info<< "Iterate forward over face :" << circClockwise() << endl; + Info<< "Iterate backward over face:" << circAnticlockwise() << endl; + } + while + ( + circClockwise.circulate(CirculatorBase::CLOCKWISE), + circAnticlockwise.circulate(CirculatorBase::ANTICLOCKWISE) + ); + \endcode + +SourceFiles + const_circulatorI.H + +\*---------------------------------------------------------------------------*/ + +#ifndef const_circulator_H +#define const_circulator_H + +#include "CirculatorBase.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + + +/*---------------------------------------------------------------------------*\ + Class const_circulator Declaration +\*---------------------------------------------------------------------------*/ + +template +class const_circulator +: + public CirculatorBase +{ + +protected: + + // Protected data + + //- Iterator pointing to the beginning of the container + typename ContainerType::const_iterator begin_; + + //- Iterator pointing to the end of the container + typename ContainerType::const_iterator end_; + + //- Iterator + typename ContainerType::const_iterator iter_; + + //- Iterator holding the location of the fulcrum (start and end) of + // the container. Used to decide when the iterator should stop + // circulating over the container + typename ContainerType::const_iterator fulcrum_; + + +public: + + // STL type definitions + + //- Type of values ContainerType contains. + typedef typename ContainerType::value_type value_type; + + //- The type that can represent the size of ContainerType + typedef typename ContainerType::size_type size_type; + + //- The type that can represent the difference between any two + // iterator objects. + typedef typename ContainerType::difference_type difference_type; + + //- Random access iterator for traversing ContainerType. + typedef typename ContainerType::const_iterator const_iterator; + + //- Type that can be used for storing into + // const ContainerType::value_type objects. + typedef typename ContainerType::const_reference const_reference; + + + // Constructors + + //- Construct null + inline const_circulator(); + + //- Construct from a container. + inline explicit const_circulator(const ContainerType& container); + + //- Construct from two iterators + inline const_circulator + ( + const const_iterator& begin, + const const_iterator& end + ); + + //- Construct as copy + inline const_circulator(const const_circulator&); + + + //- Destructor + ~const_circulator(); + + + // Member Functions + + //- Return the range of the iterator + inline size_type size() const; + + //- Circulate around the list in the given direction + inline bool circulate(const CirculatorBase::direction dir = NONE); + + //- Set the fulcrum to the current position of the iterator + inline void setFulcrumToIterator(); + + //- Set the iterator to the current position of the fulcrum + inline void setIteratorToFulcrum(); + + //- Return the distance between the iterator and the fulcrum. This is + // equivalent to the number of rotations of the circulator. + inline difference_type nRotations() const; + + //- Dereference the next iterator and return + inline const_reference next() const; + + //- Dereference the previous iterator and return + inline const_reference prev() const; + + + // Member Operators + + //- Assignment operator for circulators that operate on the same + // container type + inline void operator=(const const_circulator&); + + //- Prefix increment. Increments the iterator. + // Sets the iterator to the beginning of the container if it reaches + // the end + inline const_circulator& operator++(); + + //- Postfix increment. Increments the iterator. + // Sets the iterator to the beginning of the container if it reaches + // the end + inline const_circulator operator++(int); + + //- Prefix decrement. Decrements the iterator. + // Sets the iterator to the end of the container if it reaches + // the beginning + inline const_circulator& operator--(); + + //- Postfix decrement. Decrements the iterator. + // Sets the iterator to the end of the container if it reaches + // the beginning + inline const_circulator operator--(int); + + //- Check for equality of this iterator with another iterator that + // operate on the same container type + inline bool operator==(const const_circulator& c) const; + + //- Check for inequality of this iterator with another iterator that + // operate on the same container type + inline bool operator!=(const const_circulator& c) const; + + //- Dereference the iterator and return + inline const_reference operator*() const; + + //- Dereference the iterator and return + inline const_reference operator()() const; + + //- Return the difference between this iterator and another iterator + // that operate on the same container type + inline difference_type operator- + ( + const const_circulator& c + ) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "const_circulatorI.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/OpenFOAM/containers/Circulators/const_circulator/const_circulatorI.H b/src/OpenFOAM/containers/Circulators/const_circulator/const_circulatorI.H new file mode 100644 index 0000000000..47cdb69f06 --- /dev/null +++ b/src/OpenFOAM/containers/Circulators/const_circulator/const_circulatorI.H @@ -0,0 +1,293 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2012 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see . + +\*---------------------------------------------------------------------------*/ + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +template +Foam::const_circulator::const_circulator() +: + CirculatorBase(), + begin_(0), + end_(0), + iter_(0), + fulcrum_(0) +{} + + +template +Foam::const_circulator::const_circulator +( + const ContainerType& container +) +: + CirculatorBase(), + begin_(container.begin()), + end_(container.end()), + iter_(begin_), + fulcrum_(begin_) +{} + + +template +Foam::const_circulator::const_circulator +( + const const_iterator& begin, + const const_iterator& end +) +: + CirculatorBase(), + begin_(begin), + end_(end), + iter_(begin), + fulcrum_(begin) +{} + + +template +Foam::const_circulator::const_circulator +( + const const_circulator& rhs +) +: + CirculatorBase(), + begin_(rhs.begin_), + end_(rhs.end_), + iter_(rhs.iter_), + fulcrum_(rhs.fulcrum_) +{} + + +// * * * * * * * * * * * * * * * * Destructors * * * * * * * * * * * * * * * // + +template +Foam::const_circulator::~const_circulator() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template +typename Foam::const_circulator::size_type +Foam::const_circulator::size() const +{ + return end_ - begin_; +} + + +template +bool Foam::const_circulator::circulate +( + const CirculatorBase::direction dir +) +{ + if (dir == CirculatorBase::CLOCKWISE) + { + operator++(); + } + else if (dir == CirculatorBase::ANTICLOCKWISE) + { + operator--(); + } + + return !(iter_ == fulcrum_); +} + + +template +void Foam::const_circulator::setFulcrumToIterator() +{ + fulcrum_ = iter_; +} + + +template +void Foam::const_circulator::setIteratorToFulcrum() +{ + iter_ = fulcrum_; +} + + +template +typename Foam::const_circulator::difference_type +Foam::const_circulator::nRotations() const +{ + return (iter_ - fulcrum_); +} + + +template +typename Foam::const_circulator::const_reference +Foam::const_circulator::next() const +{ + if (iter_ == end_ - 1) + { + return *begin_; + } + + return *(iter_ + 1); +} + + +template +typename Foam::const_circulator::const_reference +Foam::const_circulator::prev() const +{ + if (iter_ == begin_) + { + return *(end_ - 1); + } + + return *(iter_ - 1); +} + + +// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // + +template +void Foam::const_circulator::operator= +( + const const_circulator& rhs +) +{ + // Check for assignment to self + if (this == &rhs) + { + FatalErrorIn + ( + "Foam::const_circulator::operator=" + "(const Foam::const_circulator&)" + ) << "Attempted assignment to self" + << abort(FatalError); + } + + begin_ = rhs.begin_; + end_ = rhs.end_; + iter_ = rhs.iter_; + fulcrum_ = rhs.fulcrum_; +} + + +template +Foam::const_circulator& +Foam::const_circulator::operator++() +{ + ++iter_; + if (iter_ == end_) + { + iter_ = begin_; + } + + return *this; +} + + +template +Foam::const_circulator +Foam::const_circulator::operator++(int) +{ + const_circulator tmp = *this; + ++(*this); + return tmp; +} + + +template +Foam::const_circulator& +Foam::const_circulator::operator--() +{ + if (iter_ == begin_) + { + iter_ = end_; + } + --iter_; + + return *this; +} + + +template +Foam::const_circulator +Foam::const_circulator::operator--(int) +{ + const_circulator tmp = *this; + --(*this); + return tmp; +} + + +template +bool Foam::const_circulator::operator== +( + const const_circulator& c +) const +{ + return + ( + begin_ == c.begin_ + && end_ == c.end_ + && iter_ == c.iter_ + && fulcrum_ == c.fulcrum_ + ); +} + + +template +bool Foam::const_circulator::operator!= +( + const const_circulator& c +) const +{ + return !(*this == c); +} + + +template +typename Foam::const_circulator::const_reference +Foam::const_circulator::operator*() const +{ + return *iter_; +} + + +template +typename Foam::const_circulator::const_reference +Foam::const_circulator::operator()() const +{ + return operator*(); +} + + +template +typename Foam::const_circulator::difference_type +Foam::const_circulator::operator- +( + const const_circulator& c +) const +{ + return iter_ - c.iter_; +} + + +// ************************************************************************* //