diff --git a/applications/test/Tuple2/Test-Tuple2.C b/applications/test/Tuple2/Test-Tuple2.C index 27b0fbf6d0b117d19e2a74f6c84c7dbfe28d6415..4f02359f032684c0c611a793c962e31d5c3daf78 100644 --- a/applications/test/Tuple2/Test-Tuple2.C +++ b/applications/test/Tuple2/Test-Tuple2.C @@ -39,6 +39,7 @@ Description #include "List.H" #include "ListOps.H" #include "ops.H" +#include "PstreamCombineReduceOps.H" #include <functional> using namespace Foam; @@ -121,6 +122,43 @@ int main() Info<< "Unsorted tuples:" << nl << list1 << nl; + // Test minFirst, maxFirst functors + { + indexedScalar minIndexed(labelMax, Zero); + indexedScalar maxIndexed(labelMin, Zero); + + for (const auto& item : list1) + { + minFirstEqOp<label>()(minIndexed, item); + maxFirstEqOp<label>()(maxIndexed, item); + } + + Foam::combineReduce(minIndexed, minFirstEqOp<label>()); + Foam::combineReduce(maxIndexed, maxFirstEqOp<label>()); + + Info<< "Min indexed: " << minIndexed << nl + << "Max indexed: " << maxIndexed << nl; + } + + // Test minFirst, maxFirst functors + { + indexedScalar minIndexed(labelMax, Zero); + indexedScalar maxIndexed(labelMin, Zero); + + for (const auto& item : list1) + { + minIndexed = minFirstOp<label>()(minIndexed, item); + maxIndexed = maxFirstOp<label>()(maxIndexed, item); + } + + Foam::combineReduce(minIndexed, minFirstEqOp<label>()); + Foam::combineReduce(maxIndexed, maxFirstEqOp<label>()); + + Info<< "Min indexed: " << minIndexed << nl + << "Max indexed: " << maxIndexed << nl; + } + + Foam::sort(list1, std::less<indexedScalar>()); Info<< "sorted tuples:" << nl << list1 << nl; diff --git a/src/OpenFOAM/primitives/Tuple2/Tuple2.H b/src/OpenFOAM/primitives/Tuple2/Tuple2.H index c8e4342af7fc757956c30e785a2787505585fd70..35875938080f86a5f66a3fdb524afc7cbb7a3722 100644 --- a/src/OpenFOAM/primitives/Tuple2/Tuple2.H +++ b/src/OpenFOAM/primitives/Tuple2/Tuple2.H @@ -42,6 +42,7 @@ See also #include "Istream.H" #include "Ostream.H" +#include "Pair.H" #include <utility> // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -140,6 +141,8 @@ public: }; +// * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * * // + //- Return reverse of a Tuple2 template<class T1, class T2> inline Tuple2<T2, T1> reverse(const Tuple2<T1,T2>& t) @@ -148,6 +151,8 @@ inline Tuple2<T2, T1> reverse(const Tuple2<T1,T2>& t) } +// * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * * // + template<class T1, class T2> inline bool operator==(const Tuple2<T1,T2>& a, const Tuple2<T1,T2>& b) { @@ -173,7 +178,6 @@ inline bool operator<(const Tuple2<T1,T2>& a, const Tuple2<T1,T2>& b) } - template<class T1, class T2> inline bool operator<=(const Tuple2<T1,T2>& a, const Tuple2<T1,T2>& b) { @@ -195,7 +199,83 @@ inline bool operator>=(const Tuple2<T1,T2>& a, const Tuple2<T1,T2>& b) } -// IOstream Operators +// * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * * // + +// Comparing first only + +//- Compare tuple-like containers +// \return reference to the container with the smaller value of first +template<class T1> +struct minFirstOp +{ + const Pair<T1>& operator()(const Pair<T1>& a, const Pair<T1>& b) const + { + return (b.first() < a.first()) ? b : a; + } + + template<class T2> + const Tuple2<T1,T2>& + operator()(const Tuple2<T1,T2>& a, const Tuple2<T1,T2>& b) const + { + return (b.first() < a.first()) ? b : a; + } +}; + + +//- Assign tuple-like container to use the one with the smaller value of first +template<class T1> +struct minFirstEqOp +{ + void operator()(Pair<T1>& x, const Pair<T1>& y) const + { + if (y.first() < x.first()) x = y; + } + + template<class T2> + void operator()(Tuple2<T1,T2>& x, const Tuple2<T1,T2>& y) const + { + if (y.first() < x.first()) x = y; + } +}; + + +//- Compare tuple-like containers +// \return reference to the container with the larger value of first +template<class T1> +struct maxFirstOp +{ + const Pair<T1>& operator()(const Pair<T1>& a, const Pair<T1>& b) const + { + return (a.first() < b.first()) ? b : a; + } + + template<class T2> + const Tuple2<T1,T2>& + operator()(const Tuple2<T1,T2>& a, const Tuple2<T1,T2>& b) const + { + return (a.first() < b.first()) ? b : a; + } +}; + + +//- Assign tuple-like container to use the one with the larger value of first +template<class T1> +struct maxFirstEqOp +{ + void operator()(Pair<T1>& x, const Pair<T1>& y) const + { + if (x.first() < y.first()) x = y; + } + + template<class T2> + void operator()(Tuple2<T1,T2>& x, const Tuple2<T1,T2>& y) const + { + if (x.first() < y.first()) x = y; + } +}; + + +// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * // //- Read Tuple2 from Istream, discarding contents of existing Tuple2. template<class T1, class T2>