Commit c65e2e58 authored by Mark OLESEN's avatar Mark OLESEN
Browse files

ENH: add some standard templates and macros into stdFoam.H

- some functionality similar to what the standary library <iterator>
  provides.

  * stdFoam::begin() and stdFoam::end() do type deduction,
    which means that many cases it is possible to manage these types
    of changes.

    For example, when managing a number of indices:
       Map<labelHashSet> lookup;

    1) Longhand:

        for
        (
            Map<labelHashSet>::const_iterator iter = lookup.begin();
            iter != lookup.end();
            ++iter
        )
        { .... }

    1b) The same, but wrapped via a macro:

        forAllConstIter(Map<labelHashSet>, lookup, iter)
        { .... }

    2) Using stdFoam begin/end templates directly

        for
        (
            auto iter = stdFoam::begin(lookup);
            iter != stdFoam::end(lookup);
            ++iter
        )
        { .... }

    2b) The same, but wrapped via a macro:

        forAllConstIters(lookup, iter)
        { .... }

Note that in many cases it is possible to simply use a range-based for.
Eg,
     labelList myList;

     for (auto val : myList)
     { ... }

     for (const auto& val : myList)
     { ... }

These however will not work with any of the OpenFOAM hash-tables,
since the standard C++ concept of an iterator would return a key,value
pair when deferencing the *iter.

The deduction methods also exhibits some slightly odd behaviour with
some PtrLists (needs some more investigation).
parent 6a5ea9a2
......@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -41,6 +41,8 @@ int main(int argc, char *argv[])
{
DLList<scalar> myList;
Info<< "DLList<scalar>" << nl;
for (int i = 0; i<10; i++)
{
myList.append(1.3*i);
......@@ -49,9 +51,7 @@ int main(int argc, char *argv[])
myList.append(100.3);
myList.append(500.3);
Info<< nl << "And again using STL iterator: " << nl << endl;
forAllIter(DLList<scalar>, myList, iter)
forAllConstIters(myList, iter)
{
Info<< "element:" << *iter << endl;
}
......@@ -59,7 +59,7 @@ int main(int argc, char *argv[])
Info<< nl << "And again using the same STL iterator: " << nl << endl;
forAllIter(DLList<scalar>, myList, iter)
forAllIters(myList, iter)
{
Info<< "Removing " << myList.remove(iter) << endl;
}
......@@ -68,13 +68,10 @@ int main(int argc, char *argv[])
myList.append(200.3);
myList.append(100.3);
Info<< nl << "And again using STL const_iterator: " << nl << endl;
forAllConstIter(DLList<scalar>, myList, iter)
Info<< nl << "Using range-based for: " << nl << endl;
for (auto val : myList)
{
Info<< "element:" << *iter << endl;
Info<< "element:" << val << endl;
}
Info<< nl << "Testing swapUp and swapDown: " << endl;
......@@ -84,9 +81,9 @@ int main(int argc, char *argv[])
myList.swapUp(myList.DLListBase::first());
myList.swapUp(myList.DLListBase::last());
forAllIter(DLList<scalar>, myList, iter)
for (auto val : myList)
{
Info<< "element:" << *iter << endl;
Info<< "element:" << val << endl;
}
Info<< nl << "swapDown" << endl;
......@@ -94,12 +91,11 @@ int main(int argc, char *argv[])
myList.swapDown(myList.DLListBase::first());
myList.swapDown(myList.DLListBase::last());
forAllIter(DLList<scalar>, myList, iter)
for (auto val : myList)
{
Info<< "element:" << *iter << endl;
Info<< "element:" << val << endl;
}
Info<< nl << "Testing transfer: " << nl << nl
<< "original: " << myList << endl;
......
......@@ -168,9 +168,24 @@ int main(int argc, char *argv[])
Info<< nl << "scalarDict2: " << endl;
forAllConstIter(PtrDictionary<Scalar>, scalarDict2, iter)
{
std::cout<< "iter: " << typeid(*iter).name() << '\n';
Info<< "elem = " << *iter << endl;
}
// FIXME: the deduction seems to be different here.
// - returns pointer (as perhaps actually expected) not the
// underlying value.
forAllConstIters(scalarDict2, iter)
{
std::cout<< "iter: " << typeid(*iter).name() << '\n';
Info<< "elem = " << *(*iter) << endl;
}
std::cout<< "iter type: "
<< typeid(stdFoam::begin(scalarDict2)).name() << '\n';
scalarDict.transfer(scalarDict2);
......
......@@ -62,7 +62,7 @@ int main()
Info<< "\ntable1 sortedToc: " << table1.sortedToc() << endl;
table1.printInfo(Info)
<< "table1 [" << table1.size() << "] " << endl;
forAllConstIter(HashTable<scalar>, table1, iter)
forAllConstIters(table1, iter)
{
Info<< iter.key() << " => " << iter() << nl;
}
......@@ -106,7 +106,7 @@ int main()
<< "\ntable3" << table3 << nl;
Info<< "\nerase table2 by iterator" << nl;
forAllIter(HashTable<scalar>, table2, iter)
forAllIters(table2, iter)
{
Info<< "erasing " << iter.key() << " => " << iter.object() << " ... ";
table2.erase(iter);
......
......@@ -78,7 +78,7 @@ int main(int argc, char *argv[])
Info<< nl << "And again using STL iterator: " << nl << endl;
forAllIter(SLList<scalar>, myList, iter)
forAllIters(myList, iter)
{
Info<< "element:" << *iter << endl;
}
......@@ -87,7 +87,7 @@ int main(int argc, char *argv[])
const ISLList<Scalar>& const_myList = myList;
forAllConstIter(SLList<scalar>, const_myList, iter)
forAllConstIters(const_myList, iter)
{
Info<< "element:" << *iter << endl;
}
......
......@@ -77,24 +77,12 @@ int main(int argc, char *argv[])
<< "] = '" << namedEnumTest::namedEnum[opt] << "'" << nl;
}
#if __cplusplus > 201100L
// C++11
Info<< "loop over enums (C++11 for range):" << nl;
for (auto const& opt : options)
for (const auto& opt : options)
{
Info<< "option[" << opt
<< "] = '" << namedEnumTest::namedEnum[opt] << "'" << nl;
}
#else
Info<< "loop over enums (via iterator):" << nl;
forAllConstIter(List<namedEnumTest::option>, options, iter)
{
const namedEnumTest::option& opt = *iter;
Info<< "option[" << opt
<< "] = '" << namedEnumTest::namedEnum[opt] << "'" << nl;
}
#endif
Info<< nl
<< namedEnumTest::namedEnum["a"] << nl
......
......@@ -52,29 +52,29 @@ int main(int argc, char *argv[])
Info<< nl << "And again using STL iterator: " << nl << endl;
forAllIter(SLList<scalar>, myList, iter)
for (auto const& val : myList)
{
Info<< "element:" << *iter << endl;
Info<< "element:" << val << endl;
}
Info<< nl << "And again using STL const_iterator: " << nl << endl;
const SLList<scalar>& const_myList = myList;
forAllConstIter(SLList<scalar>, const_myList, iter)
forAllConstIters(const_myList, iter)
{
Info<< "element:" << *iter << endl;
}
forAllIter(SLList<scalar>, myList, iter)
forAllIters(myList, iter)
{
Info<< "Removing element:" << *iter << endl;
myList.remove(iter);
}
forAllConstIter(SLList<scalar>, const_myList, iter)
for (auto const& val : const_myList)
{
Info<< "element:" << *iter << endl;
Info<< "element:" << val << endl;
}
......
......@@ -28,10 +28,6 @@ Description
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "IOobject.H"
#include "IOstreams.H"
#include "IFstream.H"
#include "IStringStream.H"
#include "labelRanges.H"
using namespace Foam;
......@@ -42,6 +38,7 @@ using namespace Foam;
int main(int argc, char *argv[])
{
argList::noParallel();
argList::noFunctionObjects();
argList::validArgs.insert("start size .. startN sizeN");
argList::addOption("verbose");
argList::addNote
......@@ -76,12 +73,9 @@ int main(int argc, char *argv[])
}
{
label start = 0;
label size = 0;
IStringStream(args[argI])() >> start;
label start = args.argRead<label>(argI);
label size = args.argRead<label>(argI+1);
++argI;
IStringStream(args[argI])() >> size;
range.reset(start, size);
}
......@@ -90,9 +84,9 @@ int main(int argc, char *argv[])
if (removeMode)
{
Info<< "del " << range << " :";
forAllConstIter(labelRange, range, iter)
for (auto i : range)
{
Info<< " " << iter();
Info<< " " << i;
}
Info<< nl;
......@@ -101,9 +95,9 @@ int main(int argc, char *argv[])
else
{
Info<< "add " << range << " :";
forAllConstIter(labelRange, range, iter)
for (auto i : range)
{
Info<< " " << iter();
Info<< " " << i;
}
Info<< nl;
......
......@@ -47,6 +47,7 @@ SourceFiles
#include "uLabel.H"
#include "nullObject.H"
#include "zero.H"
#include "stdFoam.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......@@ -427,69 +428,6 @@ inline void reverse(UList<T>& ul);
#include "UListI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Loop across all elements in \a list
// \par Usage
// \code
// forAll(anyList, i)
// {
// statements;
// }
// \endcode
// \sa forAllReverse
#define forAll(list, i) \
for (Foam::label i=0; i<(list).size(); ++i)
//- Reverse loop across all elements in \a list
// \par Usage
// \code
// forAllReverse(anyList, i)
// {
// statements;
// }
// \endcode
// \sa forAll
#define forAllReverse(list, i) \
for (Foam::label i=(list).size()-1; i>=0; --i)
//- Iterate across all elements in the \a container object of type
// \a Container.
// \par Usage
// \code
// forAll(ContainerType, container, iter)
// {
// statements;
// }
// \endcode
// \sa forAllConstIter
#define forAllIter(Container,container,iter) \
for \
( \
Container::iterator iter = (container).begin(); \
iter != (container).end(); \
++iter \
)
//- Iterate across all elements in the \a container object of type
// \a Container with const access.
// \par Usage
// \code
// forAllConstIter(ContainerType, container, iter)
// {
// statements;
// }
// \endcode
// \sa forAllIter
#define forAllConstIter(Container,container,iter) \
for \
( \
Container::const_iterator iter = (container).cbegin(); \
iter != (container).cend(); \
++iter \
)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
......
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
\\/ 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 <http://www.gnu.org/licenses/>.
Namespace
stdFoam
Description
Includes some global templates and macros used by OpenFOAM.
Some of the templates are defined here correspond to useful
std templates that are part of future C++ standards, or that
are in a state of change. Defining them here provides some additional
control over which definition are used within the OpenFOAM code-base.
SeeAlso
- http://en.cppreference.com/w/cpp/iterator/end
- http://en.cppreference.com/w/cpp/iterator/begin
\*---------------------------------------------------------------------------*/
#ifndef StdFoam_H
#define StdFoam_H
#include <initializer_list>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace stdFoam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Return iterator to the beginning of the container \a c or array.
// Definition as per std::begin C++17
template<class C>
constexpr auto begin(C& c) -> decltype(c.begin())
{
return c.begin();
}
//- Return const_iterator to the beginning of the container \a c or array.
// Definition as per std::begin C++17
template<class C>
constexpr auto begin(const C& c) -> decltype(c.begin())
{
return c.begin();
}
//- Return const_iterator to the beginning of the container \a c or array.
// Definition as per std::cbegin C++17
template<class C>
constexpr auto cbegin(const C& c) -> decltype(c.begin())
{
return c.begin();
}
//- Return iterator to the end of the container \a c or array.
// Definition as per std::end C++17
template<class C>
constexpr auto end(C& c) -> decltype(c.end())
{
return c.end();
}
//- Return const_iterator to the end of the container \a c or array.
// Definition as per std::end C++17
template<class C>
constexpr auto end(const C& c) -> decltype(c.end())
{
return c.end();
}
//- Return const_iterator to the end of the container \a c or array.
// Definition as per std::cend C++17
template<class C>
constexpr auto cend(const C& c) -> decltype(c.end())
{
return c.end();
}
} // End namespace stdFoam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Iterate across all elements in the \a container object of type
// \a Container.
// \par Usage
// \code
// forAllIters(container, iter)
// {
// statements;
// }
// \endcode
// \sa forAllConstIters, forAllIter, forAllConstIters
#define forAllIters(container,it) \
for \
( \
auto it = stdFoam::begin(container); \
it != stdFoam::end(container); \
++it \
)
//- Iterate across all elements of the \a container object with const access.
// \par Usage
// \code
// forAllConstIters(container, iter)
// {
// statements;
// }
// \endcode
// \sa forAllIters, forAllIter, forAllConstIter
#define forAllConstIters(container,cit) \
for \
( \
auto cit = stdFoam::cbegin(container); \
cit != stdFoam::cend(container); \
++cit \
)
//- Loop across all elements in \a list
// \par Usage
// \code
// forAll(anyList, i)
// {
// statements;
// }
// \endcode
// \sa forAllReverse
#define forAll(list, i) \
for (Foam::label i=0; i<(list).size(); ++i)
//- Reverse loop across all elements in \a list
// \par Usage
// \code
// forAllReverse(anyList, i)
// {
// statements;
// }
// \endcode
// \sa forAll
#define forAllReverse(list, i) \
for (Foam::label i=(list).size()-1; i>=0; --i)
//- Iterate across all elements in the \a container object
// of type \a Container.
// \par Usage
// \code
// forAllIter(ContainerType, container, iter)
// {
// statements;
// }
// \endcode
// \sa forAllConstIter
#define forAllIter(Container,container,iter) \
for \
( \
Container::iterator iter = (container).begin(); \
iter != (container).end(); \
++iter \
)
//- Iterate across all elements in the \a container object
// of type \a Container with const access.
// \par Usage
// \code
// forAllConstIter(ContainerType, container, iter)
// {
// statements;
// }
// \endcode
// \sa forAllIter
#define forAllConstIter(Container,container,iter) \
for \
( \
Container::const_iterator iter = (container).cbegin(); \
iter != (container).cend(); \
++iter \
)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment