ENH: update MinMax to accept multiple values for add()
- now also provide its own member data (previously inherited from Tuple2) to provide better isolation from future changes
This commit is contained in:
parent
14b2302b38
commit
0aecb25024
@ -170,8 +170,19 @@ int main(int argc, char *argv[])
|
||||
|
||||
values1 *= (Pstream::myProcNo()+1);
|
||||
|
||||
Pout<<"min-max of " << flatOutput(values1) << " = "
|
||||
<< minMax(values1) << endl;
|
||||
{
|
||||
auto limits = minMax(values1);
|
||||
|
||||
Pout<<"min-max of " << flatOutput(values1) << " = "
|
||||
<< limits << endl;
|
||||
|
||||
// add in some more values
|
||||
limits.add(-100, 10, 1000, 500, 800);
|
||||
|
||||
limits.add(-120, 1200);
|
||||
|
||||
Pout<<"with more values: " << limits << endl;
|
||||
}
|
||||
|
||||
// Construct from values
|
||||
MinMax<scalar> minmax1(values1);
|
||||
|
@ -1,3 +1,3 @@
|
||||
Test-minMax2.C
|
||||
Test-minMax2.cxx
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-minMax2
|
||||
|
@ -110,9 +110,15 @@ typedef MinMax<scalar> scalarMinMax; //!< A scalar min/max range
|
||||
|
||||
template<class T>
|
||||
class MinMax
|
||||
:
|
||||
public Tuple2<T,T>
|
||||
{
|
||||
// Private Data
|
||||
|
||||
//- Min value
|
||||
T min_;
|
||||
|
||||
//- Max value
|
||||
T max_;
|
||||
|
||||
public:
|
||||
|
||||
// Typedefs
|
||||
@ -126,23 +132,26 @@ public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct inverted range
|
||||
//- Default construct: an inverted range
|
||||
inline MinMax();
|
||||
|
||||
//- Copy construct from components
|
||||
//- Construct from min/max limits
|
||||
inline MinMax(const T& minVal, const T& maxVal);
|
||||
|
||||
//- Copy construct from components
|
||||
//- Implicit construct from min/max limits
|
||||
inline MinMax(const std::pair<T,T>& range);
|
||||
|
||||
//- Copy construct from components
|
||||
//- Implicit construct from min/max limits
|
||||
inline MinMax(const Pair<T>& range);
|
||||
|
||||
//- Implicit construct from min/max limits
|
||||
inline MinMax(const Tuple2<T,T>& range);
|
||||
|
||||
//- Construct with a single zero value
|
||||
inline explicit MinMax(const Foam::zero);
|
||||
inline explicit MinMax(Foam::zero);
|
||||
|
||||
//- Implicit construct from zero_one as 0-1 range (pTraits zero, one)
|
||||
inline MinMax(const Foam::zero_one);
|
||||
inline MinMax(Foam::zero_one);
|
||||
|
||||
//- Construct with a single initial value
|
||||
inline explicit MinMax(const T& val);
|
||||
@ -167,25 +176,25 @@ public:
|
||||
|
||||
// Access
|
||||
|
||||
//- The min value (first)
|
||||
inline const T& min() const noexcept;
|
||||
//- The min value
|
||||
const T& min() const noexcept { return min_; }
|
||||
|
||||
//- The min value (first)
|
||||
inline T& min() noexcept;
|
||||
//- The min value
|
||||
T& min() noexcept { return min_; }
|
||||
|
||||
//- The max value (second)
|
||||
inline const T& max() const noexcept;
|
||||
//- The max value
|
||||
const T& max() const noexcept { return max_; }
|
||||
|
||||
//- The max value (second)
|
||||
inline T& max() noexcept;
|
||||
//- The max value
|
||||
T& max() noexcept { return max_; }
|
||||
|
||||
//- The min/max average value
|
||||
inline T centre() const;
|
||||
|
||||
//- The min to max span. Zero if the range is invalid.
|
||||
//- The min to max span. Zero for invalid range.
|
||||
inline T span() const;
|
||||
|
||||
//- The magnitude of the min to max span. Zero if the range is invalid.
|
||||
//- The magnitude of the min to max span. Zero for invalid range.
|
||||
inline scalar mag() const;
|
||||
|
||||
//- Range is empty if it is inverted
|
||||
@ -194,9 +203,6 @@ public:
|
||||
//- Range is non-inverted
|
||||
inline bool good() const;
|
||||
|
||||
//- Range is non-inverted
|
||||
bool valid() const { return good(); }
|
||||
|
||||
//- Reset to an inverted (invalid) range
|
||||
inline void reset();
|
||||
|
||||
@ -244,6 +250,11 @@ public:
|
||||
//- Include the values into the range
|
||||
inline MinMax<T>& add(const UList<T>& vals);
|
||||
|
||||
//- Include two or more values into the range.
|
||||
// All values must be similar types
|
||||
template<class... Args>
|
||||
inline MinMax<T>& add(const T& val0, const T& val1, Args&&... values);
|
||||
|
||||
|
||||
// Member Operators
|
||||
|
||||
@ -264,19 +275,19 @@ public:
|
||||
inline MinMax<T>& operator+=(const UList<T>& vals);
|
||||
|
||||
//- Multiply range by scalar factor
|
||||
inline MinMax<T>& operator*=(const scalar& s);
|
||||
inline MinMax<T>& operator*=(scalar s);
|
||||
|
||||
//- Divide range by scalar factor
|
||||
inline MinMax<T>& operator/=(const scalar& s);
|
||||
inline MinMax<T>& operator/=(scalar s);
|
||||
|
||||
|
||||
// Housekeeping
|
||||
|
||||
//- Range is non-inverted. Same as good (2022-10)
|
||||
bool valid() const { return good(); }
|
||||
|
||||
//- Old method name. Same as clamp (2023-01)
|
||||
T clip(const T& val) const { return this->clamp(val); }
|
||||
|
||||
//- Old method (2023-01)
|
||||
void inplaceClip(T& val) const { val = this->clamp(val); }
|
||||
};
|
||||
|
||||
|
||||
@ -299,6 +310,30 @@ word name(const MinMax<T>& range)
|
||||
return '(' + Foam::name(range.min()) + ',' + Foam::name(range.max()) + ')';
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
|
||||
|
||||
//- Read min/max range as (min max) tuple from Istream
|
||||
template<class T>
|
||||
inline Istream& operator>>(Istream& is, MinMax<T>& range)
|
||||
{
|
||||
is.readBegin("min.max");
|
||||
is >> range.min() >> range.max();
|
||||
is.readEnd("min.max");
|
||||
|
||||
is.check(FUNCTION_NAME);
|
||||
return is;
|
||||
}
|
||||
|
||||
//- Write min/max range as (min max) tuple to Ostream
|
||||
template<class T>
|
||||
inline Ostream& operator<<(Ostream& os, const MinMax<T>& range)
|
||||
{
|
||||
os << token::BEGIN_LIST
|
||||
<< range.min() << token::SPACE << range.max()
|
||||
<< token::END_LIST;
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2019-2023 OpenCFD Ltd.
|
||||
Copyright (C) 2019-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -53,49 +53,65 @@ inline Foam::MinMax<T> Foam::MinMax<T>::zero_one()
|
||||
template<class T>
|
||||
inline Foam::MinMax<T>::MinMax()
|
||||
:
|
||||
Tuple2<T,T>(pTraits<T>::max, pTraits<T>::min)
|
||||
// An inverted range
|
||||
min_(pTraits<T>::max),
|
||||
max_(pTraits<T>::min)
|
||||
{}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline Foam::MinMax<T>::MinMax(const T& minVal, const T& maxVal)
|
||||
:
|
||||
Tuple2<T,T>(minVal, maxVal)
|
||||
min_(minVal),
|
||||
max_(maxVal)
|
||||
{}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline Foam::MinMax<T>::MinMax(const std::pair<T,T>& range)
|
||||
:
|
||||
Tuple2<T,T>(range.first, range.second)
|
||||
min_(range.first),
|
||||
max_(range.second)
|
||||
{}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline Foam::MinMax<T>::MinMax(const Pair<T>& range)
|
||||
:
|
||||
Tuple2<T,T>(range.first(), range.second())
|
||||
min_(range.first()),
|
||||
max_(range.second())
|
||||
{}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline Foam::MinMax<T>::MinMax(const Foam::zero)
|
||||
inline Foam::MinMax<T>::MinMax(const Tuple2<T,T>& range)
|
||||
:
|
||||
Tuple2<T,T>(pTraits<T>::zero, pTraits<T>::zero)
|
||||
min_(range.first()),
|
||||
max_(range.second())
|
||||
{}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline Foam::MinMax<T>::MinMax(const Foam::zero_one)
|
||||
inline Foam::MinMax<T>::MinMax(Foam::zero)
|
||||
:
|
||||
Tuple2<T,T>(pTraits<T>::zero, pTraits<T>::one)
|
||||
min_(pTraits<T>::zero),
|
||||
max_(pTraits<T>::zero)
|
||||
{}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline Foam::MinMax<T>::MinMax(Foam::zero_one)
|
||||
:
|
||||
min_(pTraits<T>::zero),
|
||||
max_(pTraits<T>::one)
|
||||
{}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline Foam::MinMax<T>::MinMax(const T& val)
|
||||
:
|
||||
Tuple2<T,T>(val, val)
|
||||
min_(val),
|
||||
max_(val)
|
||||
{}
|
||||
|
||||
|
||||
@ -110,34 +126,6 @@ inline Foam::MinMax<T>::MinMax(const UList<T>& vals)
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class T>
|
||||
inline const T& Foam::MinMax<T>::min() const noexcept
|
||||
{
|
||||
return this->first();
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline T& Foam::MinMax<T>::min() noexcept
|
||||
{
|
||||
return this->first();
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline const T& Foam::MinMax<T>::max() const noexcept
|
||||
{
|
||||
return this->second();
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline T& Foam::MinMax<T>::max() noexcept
|
||||
{
|
||||
return this->second();
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline T Foam::MinMax<T>::centre() const
|
||||
{
|
||||
@ -156,7 +144,7 @@ inline T Foam::MinMax<T>::span() const
|
||||
template<class T>
|
||||
inline Foam::scalar Foam::MinMax<T>::mag() const
|
||||
{
|
||||
return ::Foam::mag(span());
|
||||
return (empty() ? scalar(0) : ::Foam::mag(max() - min()));
|
||||
}
|
||||
|
||||
|
||||
@ -171,31 +159,32 @@ inline bool Foam::MinMax<T>::empty() const
|
||||
template<class T>
|
||||
inline bool Foam::MinMax<T>::good() const
|
||||
{
|
||||
return !empty();
|
||||
return !(max() < min());
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline void Foam::MinMax<T>::reset()
|
||||
{
|
||||
min() = pTraits<T>::max;
|
||||
max() = pTraits<T>::min;
|
||||
// An inverted range
|
||||
min_ = pTraits<T>::max;
|
||||
max_ = pTraits<T>::min;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline void Foam::MinMax<T>::reset(const T& val)
|
||||
{
|
||||
min() = val;
|
||||
max() = val;
|
||||
min_ = val;
|
||||
max_ = val;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline void Foam::MinMax<T>::reset(const T& minVal, const T& maxVal)
|
||||
{
|
||||
min() = minVal;
|
||||
max() = maxVal;
|
||||
min_ = minVal;
|
||||
max_ = maxVal;
|
||||
}
|
||||
|
||||
|
||||
@ -246,6 +235,7 @@ inline T Foam::MinMax<T>::clamp(const T& val) const
|
||||
{
|
||||
if (good())
|
||||
{
|
||||
// Uses Foam::min/Foam::max for component-wise handling
|
||||
return Foam::min(Foam::max(val, min()), max());
|
||||
}
|
||||
|
||||
@ -256,6 +246,7 @@ inline T Foam::MinMax<T>::clamp(const T& val) const
|
||||
template<class T>
|
||||
inline Foam::MinMax<T>& Foam::MinMax<T>::add(const MinMax& other)
|
||||
{
|
||||
// Uses Foam::min/Foam::max for component-wise handling
|
||||
min() = Foam::min(min(), other.min());
|
||||
max() = Foam::max(max(), other.max());
|
||||
return *this;
|
||||
@ -265,6 +256,7 @@ inline Foam::MinMax<T>& Foam::MinMax<T>::add(const MinMax& other)
|
||||
template<class T>
|
||||
inline Foam::MinMax<T>& Foam::MinMax<T>::add(const T& val)
|
||||
{
|
||||
// Uses Foam::min/Foam::max for component-wise handling
|
||||
min() = Foam::min(min(), val);
|
||||
max() = Foam::max(max(), val);
|
||||
return *this;
|
||||
@ -282,6 +274,25 @@ inline Foam::MinMax<T>& Foam::MinMax<T>::add(const UList<T>& vals)
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
template<class... Args>
|
||||
inline Foam::MinMax<T>& Foam::MinMax<T>::add
|
||||
(
|
||||
const T& val0,
|
||||
const T& val1,
|
||||
Args&&... values
|
||||
)
|
||||
{
|
||||
add(val0);
|
||||
add(val1);
|
||||
|
||||
// Add multiple values via fold expression
|
||||
((*this += std::forward<Args>(values)), ...);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||
|
||||
template<class T>
|
||||
@ -325,6 +336,7 @@ inline bool Foam::MinMax<T>::operator()(const T& val) const
|
||||
template<class T>
|
||||
inline Foam::MinMax<T>& Foam::MinMax<T>::operator&=(const MinMax<T>& b)
|
||||
{
|
||||
// Uses Foam::min/Foam::max for component-wise handling
|
||||
min() = ::Foam::max(min(), b.min());
|
||||
max() = ::Foam::min(max(), b.max());
|
||||
|
||||
@ -354,7 +366,7 @@ inline Foam::MinMax<T>& Foam::MinMax<T>::operator+=(const UList<T>& vals)
|
||||
|
||||
|
||||
template<class T>
|
||||
inline Foam::MinMax<T>& Foam::MinMax<T>::operator*=(const scalar& s)
|
||||
inline Foam::MinMax<T>& Foam::MinMax<T>::operator*=(scalar s)
|
||||
{
|
||||
min() *= s;
|
||||
max() *= s;
|
||||
@ -363,7 +375,7 @@ inline Foam::MinMax<T>& Foam::MinMax<T>::operator*=(const scalar& s)
|
||||
|
||||
|
||||
template<class T>
|
||||
inline Foam::MinMax<T>& Foam::MinMax<T>::operator/=(const scalar& s)
|
||||
inline Foam::MinMax<T>& Foam::MinMax<T>::operator/=(scalar s)
|
||||
{
|
||||
min() /= s;
|
||||
max() /= s;
|
||||
|
@ -44,7 +44,7 @@ Description
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Global Functions
|
||||
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
|
||||
|
||||
//- The mag() function for min/max range
|
||||
template<class T>
|
||||
@ -156,7 +156,7 @@ inline scalarMinMax minMaxMag(const UList<T>& vals)
|
||||
scalarMinMax result;
|
||||
for (const T& val : vals)
|
||||
{
|
||||
result += Foam::mag(val);
|
||||
result.add(Foam::mag(val));
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -174,38 +174,20 @@ inline scalarMinMax minMaxMag(const MinMax<T>& range)
|
||||
}
|
||||
|
||||
|
||||
//- Combine the magitude of two values to create a min/max range.
|
||||
//- Order is unimportant.
|
||||
template<class T>
|
||||
inline scalarMinMax minMaxMag(const T& x, const T& y)
|
||||
//- Combine the magitude of two values (similar or dissimilar types)
|
||||
//- to create a min/max range. Order is unimportant.
|
||||
template<class T1, class T2>
|
||||
inline scalarMinMax minMaxMag(const T1& x, const T2& y)
|
||||
{
|
||||
return minMaxMag(x).add(Foam::mag(y));
|
||||
}
|
||||
|
||||
|
||||
//- Scalar combine two MinMax ranges of same type
|
||||
template<class T>
|
||||
inline scalarMinMax minMaxMag(const MinMax<T>& x, const MinMax<T>& y)
|
||||
{
|
||||
return
|
||||
(
|
||||
minMaxMag(x)
|
||||
.add(Foam::mag(y.min()))
|
||||
.add(Foam::mag(y.max()))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//- Scalar combine two MinMax ranges of dissimilar types
|
||||
//- Scalar combine two MinMax ranges (same or dissimilar types)
|
||||
template<class T1, class T2>
|
||||
inline scalarMinMax minMaxMag(const MinMax<T1>& x, const MinMax<T2>& y)
|
||||
{
|
||||
return
|
||||
(
|
||||
minMaxMag(x)
|
||||
.add(Foam::mag(y.min()))
|
||||
.add(Foam::mag(y.max()))
|
||||
);
|
||||
return minMaxMag(x).add(Foam::mag(y.min()), Foam::mag(y.max()));
|
||||
}
|
||||
|
||||
|
||||
@ -309,7 +291,7 @@ inline MinMax<T> operator+(const MinMax<T>& x, const MinMax<T>& y)
|
||||
|
||||
//- Multiply range by scalar factor
|
||||
template<class T>
|
||||
inline MinMax<T> operator*(const MinMax<T>& x, const scalar& s)
|
||||
inline MinMax<T> operator*(const MinMax<T>& x, scalar s)
|
||||
{
|
||||
return MinMax<T>(x.min()*s, x.max()*s);
|
||||
}
|
||||
@ -317,7 +299,7 @@ inline MinMax<T> operator*(const MinMax<T>& x, const scalar& s)
|
||||
|
||||
//- Divide range by scalar factor
|
||||
template<class T>
|
||||
inline MinMax<T> operator/(const MinMax<T>& x, const scalar& s)
|
||||
inline MinMax<T> operator/(const MinMax<T>& x, scalar s)
|
||||
{
|
||||
return MinMax<T>(x.min()/s, x.max()/s);
|
||||
}
|
||||
|
@ -58,9 +58,7 @@ void Foam::binModels::uniformBin::initialise()
|
||||
);
|
||||
|
||||
MinMax<vector> limits(pts);
|
||||
|
||||
geomLimits.add(limits.min());
|
||||
geomLimits.add(limits.max());
|
||||
geomLimits.add(limits.min(), limits.max());
|
||||
}
|
||||
|
||||
for (const label zonei : cellZoneIDs_)
|
||||
@ -72,9 +70,7 @@ void Foam::binModels::uniformBin::initialise()
|
||||
);
|
||||
|
||||
MinMax<vector> limits(pts);
|
||||
|
||||
geomLimits.add(limits.min());
|
||||
geomLimits.add(limits.max());
|
||||
geomLimits.add(limits.min(), limits.max());
|
||||
}
|
||||
|
||||
// Globally consistent
|
||||
|
Loading…
Reference in New Issue
Block a user