Skip to content
Snippets Groups Projects
Commit e0255cff authored by Mark OLESEN's avatar Mark OLESEN
Browse files

ENH: add compareOp for three-way comparison

- similar to the \c <=> operator in C++20.
  Primarily for use when defining cascaded sort function objects.
parent 8b569b16
No related branches found
No related tags found
No related merge requests found
......@@ -32,9 +32,39 @@ Description
#include "label.H"
#include "scalar.H"
#include "List.H"
#include "ops.H"
#include <functional>
using namespace Foam;
// Test for special comparison operation using compareOp
// Normal sort on label, reverse sort on scalar
struct special1
{
typedef Tuple2<label, scalar> type;
bool operator()(const type& a, const type& b) const
{
int val = compareOp<label>()(a.first(), b.first());
return (val == 0) ? (b.second() < a.second()) : (val < 0);
}
};
// Test for special comparison operation using compareOp
// Normal sort on scalar, reverse sort on label
struct special2
{
typedef Tuple2<label, scalar> type;
bool operator()(const type& a, const type& b) const
{
scalar val = compareOp<scalar>()(a.second(), b.second());
return (val == 0) ? (b.first() < a.first()) : (val < 0);
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
......@@ -46,19 +76,39 @@ int main()
Info<< "tuple: "
<< t2 << " "
<< t2.first() << " " << t2.second() << endl;
<< t2.first() << " " << t2.second() << nl;
List<indexedScalar> list1(10);
forAll(list1, i)
// As list. Generated so that we have duplicate indices
List<indexedScalar> list1(3*4);
for (label i = 0; i < 4; ++i)
{
list1[i] = indexedScalar(-i, i*i);
const label j = (i+1);
const label idx = ((i % 2) ? -1 : 1) * (j);
list1[i] = indexedScalar(idx, (j*j));
list1[i+4] = indexedScalar(idx, 2*j); // duplicate index
list1[i+8] = indexedScalar(idx+12, 2*j); // duplicate value
}
sort(list1);
Info<< "Unsorted tuples:" << nl << list1 << nl;
Foam::sort(list1, std::less<indexedScalar>());
Info<< "sorted tuples:" << nl << list1 << nl;
Foam::sort(list1, std::greater<indexedScalar>());
Info<< "reverse sorted tuples:" << nl << list1 << nl;
Foam::sort(list1, special1());
Info<< "special sorted tuples - sort on index, reverse on value:"
<< nl << list1 << nl;
Foam::sort(list1, special2());
Info<< "tuples:" << nl
<< list1
<< endl;
Info<< "special sorted tuples - sort on value, reverse on index:"
<< nl << list1 << nl;
Info<< "End\n" << endl;
......
......@@ -405,6 +405,28 @@ inline Scalar stabilise(const Scalar s, const Scalar tol)
// Specializations
// Default definition in ops.H
template<class T> struct compareOp;
//- Compare scalar values
template<>
struct compareOp<Scalar>
{
const Scalar tolerance;
//- Construct with specified tolerance (non-negative value)
compareOp(Scalar tol = ScalarVSMALL)
:
tolerance(tol)
{}
Scalar operator()(const Scalar& a, const Scalar& b) const
{
return (mag(a - b) <= tolerance) ? 0 : (a - b);
}
};
// Default definition in ops.H
template<class T> struct equalOp;
......
......@@ -216,6 +216,21 @@ WeightedOp(multiply, (weight*y))
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Three-way comparison operation of two parameters,
// similar to the \c <=> operator in C++20.
//
// \return a negative value for less, a positive value for greater,
// and zero for equal value.
template<class T>
struct compareOp
{
int operator()(const T& a, const T& b) const WARNRETURN
{
return (a < b) ? -1 : (b < a) ? 1 : 0;
}
};
//- General get operation to extract the 'name' from an object as a word.
// The default implementation uses the 'name()' method commonly used within
// OpenFOAM.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment