ENH: upgrade to use some C++17 constructs

- 'if constexpr (...)'
   * instead of std::enable_if
   * terminate template recursion
   * compile-time elimination of code

- use C++14 '_t', '_v' versions,
  eg, std::is_integral_v<T> instead of std::is_integral<T>::value

- std::begin, std::end, std::void_t instead of prev stdFoam versions

- provide is_contiguous_v<..> as short form of is_contiguous<..>::value
  with the additional benefit of removing any cv qualifiers.

ENH: include is_rotational_vectorspace trait

- tests for vector-space and nComponents > 1 (ie, not sphericalTensor)

ENH: improve robustness of pTraits_.. tests by removing cv qualifiers
This commit is contained in:
Mark Olesen
2025-01-27 14:53:36 +01:00
parent b9f05bdc01
commit cf2b305b4f
133 changed files with 1548 additions and 1942 deletions

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2020-2022 OpenCFD Ltd. Copyright (C) 2020-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -38,12 +38,11 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "complex.H"
#include "Tensor.H" #include "Tensor.H"
#include "SymmTensor.H" #include "SymmTensor.H"
#include "SphericalTensor.H" #include "SphericalTensor.H"
#include "DiagTensor.H" #include "DiagTensor.H"
#include "scalar.H"
#include "complex.H"
using namespace Foam; using namespace Foam;
@ -57,45 +56,11 @@ unsigned nTest_ = 0;
unsigned nFail_ = 0; unsigned nFail_ = 0;
// Compare two floating point types, and print output.
// Do ++nFail_ if values of two objects are not equal within a given tolerance.
// The function is converted from PEP-485.
template<class Type>
typename std::enable_if<pTraits<Type>::rank == 0, void>::type
cmp
(
const word& msg,
const Type& x,
const Type& y,
const scalar relTol = 1e-8, //<! are values the same within 8 decimals
const scalar absTol = 0 //<! useful for cmps near zero
)
{
Info<< msg << x << endl;
unsigned nFail = 0;
if (max(absTol, relTol*max(mag(x), mag(y))) < mag(x - y))
{
++nFail;
}
if (nFail)
{
Info<< nl
<< " #### Fail in " << nFail << " comps ####" << nl << endl;
++nFail_;
}
++nTest_;
}
// Compare two containers elementwise, and print output. // Compare two containers elementwise, and print output.
// Do ++nFail_ if two components are not equal within a given tolerance. // Do ++nFail_ if two components are not equal within a given tolerance.
// The function is converted from PEP-485 // The function is converted from PEP-485
template<class Type> template<class Type>
typename std::enable_if<pTraits<Type>::rank != 0, void>::type void cmp
cmp
( (
const word& msg, const word& msg,
const Type& x, const Type& x,
@ -104,18 +69,37 @@ cmp
const scalar absTol = 0 const scalar absTol = 0
) )
{ {
Info<< msg << x << endl; const auto notEqual = [=](const auto& a, const auto& b) -> bool
{
return
(
Foam::max(absTol, relTol*Foam::max(Foam::mag(a), Foam::mag(b)))
< Foam::mag(a - b)
);
};
unsigned nFail = 0; unsigned nFail = 0;
for (direction i = 0; i < pTraits<Type>::nComponents; ++i) if constexpr (is_vectorspace_v<Type>)
{ {
if (max(absTol, relTol*max(mag(x[i]), mag(y[i]))) < mag(x[i] - y[i])) for (direction i = 0; i < pTraits<Type>::nComponents; ++i)
{
if (notEqual(x[i], y[i]))
{
++nFail;
}
}
}
else
{
if (notEqual(x, y))
{ {
++nFail; ++nFail;
} }
} }
Info<< msg << x << endl;
if (nFail) if (nFail)
{ {
Info<< nl Info<< nl
@ -368,27 +352,26 @@ void test_global_opers(Type)
// Do compile-time recursion over the given types // Do compile-time recursion over the given types
template<std::size_t I = 0, typename... Tp> template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I == sizeof...(Tp), void>::type void run_tests(const std::tuple<Tp...>& types, const List<word>& names)
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID){}
template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I < sizeof...(Tp), void>::type
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID)
{ {
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl; if constexpr (I < sizeof...(Tp))
test_constructors(std::get<I>(types)); {
const auto& name = names[I];
Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl; Info<< nl << " ## Test constructors: " << name << " ##" << nl;
test_member_funcs(std::get<I>(types)); test_constructors(std::get<I>(types));
Info<< nl << " ## Test global functions: "<< typeID[I] << " ##" << nl; Info<< nl << " ## Test member functions: " << name << " ##" << nl;
test_global_funcs(std::get<I>(types)); test_member_funcs(std::get<I>(types));
Info<< nl << " ## Test global operators: "<< typeID[I] <<" ##" << nl; Info<< nl << " ## Test global functions: " << name << " ##" << nl;
test_global_opers(std::get<I>(types)); test_global_funcs(std::get<I>(types));
run_tests<I + 1, Tp...>(types, typeID); Info<< nl << " ## Test global operators: " << name << " ##" << nl;
test_global_opers(std::get<I>(types));
run_tests<I + 1, Tp...>(types, names);
}
} }
@ -403,8 +386,8 @@ int main()
const List<word> typeID const List<word> typeID
({ ({
"DiagTensor<floatScalar>", "DiagTensor<float>",
"DiagTensor<doubleScalar>", "DiagTensor<double>",
"DiagTensor<complex>" "DiagTensor<complex>"
}); });

View File

@ -185,7 +185,7 @@ int main(int argc, char *argv[])
} }
std::cout<< "iter type: " std::cout<< "iter type: "
<< typeid(stdFoam::begin(scalarDict2)).name() << '\n'; << typeid(std::begin(scalarDict2)).name() << '\n';
scalarDict.transfer(scalarDict2); scalarDict.transfer(scalarDict2);

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2019-2023 OpenCFD Ltd. Copyright (C) 2019-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -85,8 +85,7 @@ void compileInfo()
template<class FixedListType> template<class FixedListType>
typename std::enable_if std::enable_if_t<(FixedListType::max_size() == 2), bool>
<(FixedListType::max_size() == 2), bool>::type
is_pair() is_pair()
{ {
return true; return true;
@ -94,7 +93,7 @@ is_pair()
template<class FixedListType> template<class FixedListType>
typename std::enable_if<(FixedListType::max_size() != 2), std::string>::type std::enable_if_t<(FixedListType::max_size() != 2), std::string>
is_pair() is_pair()
{ {
return "not really at all"; return "not really at all";

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2021 OpenCFD Ltd. Copyright (C) 2021-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -42,9 +42,11 @@ Note
#include "Hash.H" #include "Hash.H"
#ifdef FULLDEBUG #ifdef FULLDEBUG
#define HashTypeInfo(Args) void info() { std::cerr<< "" Args << "\n"; } #define HashTypeInfo(Name) \
static constexpr const char* name() noexcept { return Name; } \
void info() const { std::cerr<< name() << " hashing\n"; }
#else #else
#define HashTypeInfo(Args) void info() {} #define HashTypeInfo(Name) void info() const {}
#endif #endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -53,20 +55,36 @@ namespace Foam
{ {
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class Hash Declaration Class HashFunc Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
template<class T, class SFINAEType=bool> template<class T>
struct HashFun struct HashFun
{ {
#ifdef FULLDEBUG void info() const
static constexpr const char* name() noexcept { return "default"; } {
#endif #ifdef FULLDEBUG
HashTypeInfo("plain hash") if constexpr (std::is_base_of_v<std::string, T>)
{
std::cerr<< "std::string hashing\n";
}
else
{
std::cerr<< "default hashing\n";
}
#endif
}
unsigned operator()(const T& obj, unsigned seed=0) const unsigned operator()(const T& obj, unsigned seed=0) const
{ {
return Foam::Hasher(&obj, sizeof(obj), seed); if constexpr (std::is_base_of_v<std::string, T>)
{
return Foam::Hasher(obj.data(), obj.size(), seed);
}
else
{
return Foam::Hasher(&obj, sizeof(obj), seed);
}
} }
}; };
@ -76,45 +94,17 @@ struct HashFun
//- Hashing for label //- Hashing for label
template<> struct HashFun<Foam::label> : Hash<label> template<> struct HashFun<Foam::label> : Hash<label>
{ {
#ifdef FULLDEBUG HashTypeInfo("label")
static constexpr const char* name() noexcept { return "label"; }
#endif
HashTypeInfo("hash label")
}; };
//- Hashing for pointers, interpret pointer as a integer type //- Hashing for pointers, interpret pointer as a integer type
template<> struct HashFun<void*> : Hash<void *> template<> struct HashFun<void*> : Hash<void *>
{ {
#ifdef FULLDEBUG HashTypeInfo("pointer")
static constexpr const char* name() noexcept { return "pointer"; }
#endif
HashTypeInfo("hash ptr")
}; };
//- Hashing for string types
template<class StringType>
struct HashFun
<
StringType,
typename std::enable_if
<
std::is_base_of<std::string, StringType>::value, bool
>::type
>
{
#ifdef FULLDEBUG
static constexpr const char* name() noexcept { return "string"; }
#endif
HashTypeInfo("hash string")
unsigned operator()(const std::string& obj, unsigned seed=0) const
{
return Foam::Hasher(obj.data(), obj.size(), seed);
}
};
} // End namespace Foam } // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -133,83 +123,56 @@ namespace Foam
template<> struct HashFun<edge> : Hash<edge> template<> struct HashFun<edge> : Hash<edge>
{ {
#ifdef FULLDEBUG HashTypeInfo("edge")
static constexpr const char* name() noexcept { return "edge"; }
#endif
HashTypeInfo("hash edge")
}; };
template<> struct HashFun<face> : Hash<face> template<> struct HashFun<face> : Hash<face>
{ {
#ifdef FULLDEBUG HashTypeInfo("face")
static constexpr const char* name() noexcept { return "face"; }
#endif
HashTypeInfo("hash face")
}; };
template<> struct HashFun<triFace> : Hash<triFace> template<> struct HashFun<triFace> : Hash<triFace>
{ {
#ifdef FULLDEBUG HashTypeInfo("triFace")
static constexpr const char* name() noexcept { return "triFace"; }
#endif
HashTypeInfo("hash triFace")
}; };
template<class T> template<class T>
struct HashFun<Pair<T>> : Hash<Pair<T>> struct HashFun<Pair<T>> : Hash<Pair<T>>
{ {
#ifdef FULLDEBUG HashTypeInfo("Pair")
static constexpr const char* name() noexcept { return "Pair"; }
#endif
HashTypeInfo("hash Pair")
}; };
template<class T1, class T2> template<class T1, class T2>
struct HashFun<Tuple2<T1, T2>> : Hash<Tuple2<T1, T2>> struct HashFun<Tuple2<T1, T2>> : Hash<Tuple2<T1, T2>>
{ {
#ifdef FULLDEBUG HashTypeInfo("Tuple2")
static constexpr const char* name() noexcept { return "Tuple2"; }
#endif
HashTypeInfo("hash Tuple2")
}; };
template<class T> template<class T>
struct HashFun<List<T>> : Hash<List<T>> struct HashFun<List<T>> : Hash<List<T>>
{ {
#ifdef FULLDEBUG HashTypeInfo("List")
static constexpr const char* name() noexcept { return "List"; }
#endif
HashTypeInfo("hash List")
}; };
template<class T> struct HashFun<UList<T>> : Hash<UList<T>> template<class T> struct HashFun<UList<T>> : Hash<UList<T>>
{ {
#ifdef FULLDEBUG HashTypeInfo("UList")
static constexpr const char* name() noexcept { return "UList"; }
#endif
HashTypeInfo("hash UList")
}; };
template<class T, int SizeMin> template<class T, int SizeMin>
struct HashFun<DynamicList<T, SizeMin>> : Hash<DynamicList<T, SizeMin>> struct HashFun<DynamicList<T, SizeMin>> : Hash<DynamicList<T, SizeMin>>
{ {
#ifdef FULLDEBUG HashTypeInfo("DynamicList")
static constexpr const char* name() noexcept { return "DynamicList"; }
#endif
HashTypeInfo("hash DynamicList")
}; };
template<class T, unsigned N> template<class T, unsigned N>
struct HashFun<FixedList<T, N>> : Hash<FixedList<T, N>> struct HashFun<FixedList<T, N>> : Hash<FixedList<T, N>>
{ {
#ifdef FULLDEBUG HashTypeInfo("FixedList")
static constexpr const char* name() noexcept { return "FixedList"; }
#endif
HashTypeInfo("hash FixedList")
}; };

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2018-2021 OpenCFD Ltd. Copyright (C) 2018-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -81,7 +81,7 @@ void infoHashString
void reportHashList(const UList<string>& list) void reportHashList(const UList<string>& list)
{ {
Info<< "contiguous = " << is_contiguous<string>::value << nl << nl; Info<< "contiguous = " << is_contiguous_v<string> << nl << nl;
for (const string& val : list) for (const string& val : list)
{ {
@ -94,7 +94,7 @@ void reportHashList(const UList<string>& list)
void reportHashList(const UList<label>& list) void reportHashList(const UList<label>& list)
{ {
Info<<"contiguous = " << is_contiguous<label>::value << nl << nl; Info<<"contiguous = " << is_contiguous_v<label> << nl << nl;
for (const label val : list) for (const label val : list)
{ {
@ -113,7 +113,7 @@ void reportHashList(const UList<label>& list)
void reportHashList(const UList<face>& list) void reportHashList(const UList<face>& list)
{ {
Info<<"contiguous = " << is_contiguous<label>::value << nl << nl; Info<<"contiguous = " << is_contiguous_v<label> << nl << nl;
for (const face& f : list) for (const face& f : list)
{ {
@ -154,7 +154,7 @@ void reportHashList(const UList<labelList>& list)
void reportHashList(const UList<wordPair>& list) void reportHashList(const UList<wordPair>& list)
{ {
Info<<"contiguous = " << is_contiguous<wordPair>::value << nl << nl; Info<<"contiguous = " << is_contiguous_v<wordPair> << nl << nl;
for (const wordPair& pr : list) for (const wordPair& pr : list)
{ {
@ -179,7 +179,7 @@ void reportHashList(const UList<wordPair>& list)
void reportHashList(const UList<labelPair>& list) void reportHashList(const UList<labelPair>& list)
{ {
Info<<"contiguous = " << is_contiguous<labelPair>::value << nl << nl; Info<<"contiguous = " << is_contiguous_v<labelPair> << nl << nl;
for (const labelPair& pr : list) for (const labelPair& pr : list)
{ {
@ -200,7 +200,7 @@ void reportHashList(const UList<labelPair>& list)
void reportHashList(const UList<labelPairPair>& list) void reportHashList(const UList<labelPairPair>& list)
{ {
Info<<"contiguous = " << is_contiguous<labelPairPair>::value << nl << nl; Info<<"contiguous = " << is_contiguous_v<labelPairPair> << nl << nl;
for (const labelPairPair& pr : list) for (const labelPairPair& pr : list)
{ {
@ -221,7 +221,7 @@ void reportHashList(const UList<labelPairPair>& list)
void reportHashList(const UList<edge>& list) void reportHashList(const UList<edge>& list)
{ {
Info<<"contiguous = " << is_contiguous<edge>::value << nl << nl; Info<<"contiguous = " << is_contiguous_v<edge> << nl << nl;
for (const edge& e : list) for (const edge& e : list)
{ {
@ -242,7 +242,7 @@ void reportHashList(const UList<edge>& list)
void reportHashList(const UList<triFace>& list) void reportHashList(const UList<triFace>& list)
{ {
Info<<"contiguous = " << is_contiguous<triFace>::value << nl << nl; Info<<"contiguous = " << is_contiguous_v<triFace> << nl << nl;
for (const triFace& f : list) for (const triFace& f : list)
{ {

View File

@ -213,11 +213,10 @@ int main(int argc, char *argv[])
mesh mesh
); );
Info<< "points path: " << io.typeFilePath<labelIOList>() << nl; Info<< "points path: " << io.typeFilePath<pointIOField>() << nl;
Info<< "points path: " << io.typeFilePath<void>() << nl;
io.resetHeader("bad-points"); io.resetHeader("bad-points");
Info<< "bad path: " << io.typeFilePath<void>() << nl; Info<< "bad path: " << io.typeFilePath<labelIOList>() << nl;
} }
IOobject io IOobject io

View File

@ -45,7 +45,7 @@ using namespace Foam;
template<class Type> template<class Type>
word report() word report()
{ {
if (is_globalIOobject<Type>::value) if constexpr (is_globalIOobject<Type>::value)
{ {
return "global"; return "global";
} }

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2023 OpenCFD Ltd. Copyright (C) 2017-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -118,7 +118,7 @@ Ostream& printListOutputType(const char* what)
{ {
Info<< what Info<< what
<< " (contiguous=" << " (contiguous="
<< is_contiguous<T>::value << " no_linebreak=" << is_contiguous_v<T> << " no_linebreak="
<< Detail::ListPolicy::no_linebreak<T>::value << Detail::ListPolicy::no_linebreak<T>::value
<< " short_length=" << " short_length="
<< Detail::ListPolicy::short_length<T>::value << ')'; << Detail::ListPolicy::short_length<T>::value << ')';

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2021 OpenCFD Ltd. Copyright (C) 2021-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -128,18 +128,17 @@ void test_member_funcs(Type)
// Do compile-time recursion over the given types // Do compile-time recursion over the given types
template<std::size_t I = 0, typename... Tp> template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I == sizeof...(Tp), void>::type void run_tests(const std::tuple<Tp...>& types, const List<word>& names)
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID){}
template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I < sizeof...(Tp), void>::type
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID)
{ {
Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl; if constexpr (I < sizeof...(Tp))
test_member_funcs(std::get<I>(types)); {
const auto& name = names[I];
run_tests<I + 1, Tp...>(types, typeID); Info<< nl << " ## Test member functions: " << name << " ##" << nl;
test_member_funcs(std::get<I>(types));
run_tests<I + 1, Tp...>(types, names);
}
} }

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2020-2022 OpenCFD Ltd. Copyright (C) 2020-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -38,12 +38,11 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "complex.H"
#include "Tensor.H" #include "Tensor.H"
#include "SymmTensor.H" #include "SymmTensor.H"
#include "SphericalTensor.H" #include "SphericalTensor.H"
#include "DiagTensor.H" #include "DiagTensor.H"
#include "scalar.H"
#include "complex.H"
using namespace Foam; using namespace Foam;
@ -57,65 +56,50 @@ unsigned nTest_ = 0;
unsigned nFail_ = 0; unsigned nFail_ = 0;
// Compare two floating point types, and print output. // Compare two containers elementwise, and print output.
// Do ++nFail_ if values of two objects are not equal within a given tolerance. // Do ++nFail_ if values of two objects are not equal within a given tolerance.
// The function is converted from PEP-485. // The function is converted from PEP-485.
template<class Type> template<class Type, class Type2 = Type>
typename std::enable_if<pTraits<Type>::rank == 0, void>::type void cmp
cmp
( (
const word& msg, const word& msg,
const Type& x, const Type& x,
const Type& y, const Type2& y,
const scalar relTol = 1e-8, //<! are values the same within 8 decimals const scalar relTol = 1e-8, //<! are values the same within 8 decimals
const scalar absTol = 0 //<! useful for cmps near zero const scalar absTol = 0 //<! useful for cmps near zero
) )
{ {
Info<< msg << x << endl; const auto notEqual = [=](const auto& a, const auto& b) -> bool
{
return
(
Foam::max(absTol, relTol*Foam::max(Foam::mag(a), Foam::mag(b)))
< Foam::mag(a - b)
);
};
unsigned nFail = 0; unsigned nFail = 0;
if (max(absTol, relTol*max(mag(x), mag(y))) < mag(x - y)) if constexpr (is_vectorspace_v<Type>)
{ {
++nFail; for (direction i = 0; i < pTraits<Type>::nComponents; ++i)
{
if (notEqual(x[i], y[i]))
{
++nFail;
}
}
} }
else
if (nFail)
{ {
Info<< nl if (notEqual(x, y))
<< " #### Fail in " << nFail << " comps ####" << nl << endl;
++nFail_;
}
++nTest_;
}
// Compare two containers elementwise, and print output.
// Do ++nFail_ if two components are not equal within a given tolerance.
// The function is converted from PEP-485
template<class Type>
typename std::enable_if<pTraits<Type>::rank != 0, void>::type
cmp
(
const word& msg,
const Type& x,
const Type& y,
const scalar relTol = 1e-8,
const scalar absTol = 0
)
{
Info<< msg << x << endl;
unsigned nFail = 0;
for (direction i = 0; i < pTraits<Type>::nComponents; ++i)
{
if (max(absTol, relTol*max(mag(x[i]), mag(y[i]))) < mag(x[i] - y[i]))
{ {
++nFail; ++nFail;
} }
} }
Info<< msg << x << endl;
if (nFail) if (nFail)
{ {
Info<< nl Info<< nl
@ -277,27 +261,26 @@ void test_global_opers(Type)
// Do compile-time recursion over the given types // Do compile-time recursion over the given types
template<std::size_t I = 0, typename... Tp> template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I == sizeof...(Tp), void>::type void run_tests(const std::tuple<Tp...>& types, const List<word>& names)
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID){}
template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I < sizeof...(Tp), void>::type
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID)
{ {
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl; if constexpr (I < sizeof...(Tp))
test_constructors(std::get<I>(types)); {
const auto& name = names[I];
Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl; Info<< nl << " ## Test constructors: " << name << " ##" << nl;
test_member_funcs(std::get<I>(types)); test_constructors(std::get<I>(types));
Info<< nl << " ## Test global functions: "<< typeID[I] << " ##" << nl; Info<< nl << " ## Test member functions: " << name << " ##" << nl;
test_global_funcs(std::get<I>(types)); test_member_funcs(std::get<I>(types));
Info<< nl << " ## Test global operators: "<< typeID[I] <<" ##" << nl; Info<< nl << " ## Test global functions: " << name << " ##" << nl;
test_global_opers(std::get<I>(types)); test_global_funcs(std::get<I>(types));
run_tests<I + 1, Tp...>(types, typeID); Info<< nl << " ## Test global operators: " << name << " ##" << nl;
test_global_opers(std::get<I>(types));
run_tests<I + 1, Tp...>(types, names);
}
} }
@ -312,8 +295,8 @@ int main()
const List<word> typeID const List<word> typeID
({ ({
"SphericalTensor<floatScalar>", "SphericalTensor<float>",
"SphericalTensor<doubleScalar>", "SphericalTensor<double>",
"SphericalTensor<complex>" "SphericalTensor<complex>"
}); });

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2020-2022 OpenCFD Ltd. Copyright (C) 2020-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -38,11 +38,10 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "complex.H"
#include "Tensor2D.H" #include "Tensor2D.H"
#include "SymmTensor2D.H" #include "SymmTensor2D.H"
#include "SphericalTensor2D.H" #include "SphericalTensor2D.H"
#include "scalar.H"
#include "complex.H"
using namespace Foam; using namespace Foam;
@ -56,12 +55,11 @@ unsigned nTest_ = 0;
unsigned nFail_ = 0; unsigned nFail_ = 0;
// Compare two floating point types, and print output. // Compare two containers elementwise, and print output.
// Do ++nFail_ if values of two objects are not equal within a given tolerance. // Do ++nFail_ if values of two objects are not equal within a given tolerance.
// The function is converted from PEP-485. // The function is converted from PEP-485.
template<class Type> template<class Type>
typename std::enable_if<pTraits<Type>::rank == 0, void>::type void cmp
cmp
( (
const word& msg, const word& msg,
const Type& x, const Type& x,
@ -70,51 +68,37 @@ cmp
const scalar absTol = 0 //<! useful for cmps near zero const scalar absTol = 0 //<! useful for cmps near zero
) )
{ {
Info<< msg << x << endl; const auto notEqual = [=](const auto& a, const auto& b) -> bool
{
return
(
Foam::max(absTol, relTol*Foam::max(Foam::mag(a), Foam::mag(b)))
< Foam::mag(a - b)
);
};
unsigned nFail = 0; unsigned nFail = 0;
if (max(absTol, relTol*max(mag(x), mag(y))) < mag(x - y)) if constexpr (is_vectorspace_v<Type>)
{ {
++nFail; for (direction i = 0; i < pTraits<Type>::nComponents; ++i)
{
if (notEqual(x[i], y[i]))
{
++nFail;
}
}
} }
else
if (nFail)
{ {
Info<< nl if (notEqual(x, y))
<< " #### Fail in " << nFail << " comps ####" << nl << endl;
++nFail_;
}
++nTest_;
}
// Compare two containers elementwise, and print output.
// Do ++nFail_ if two components are not equal within a given tolerance.
// The function is converted from PEP-485
template<class Type>
typename std::enable_if<pTraits<Type>::rank != 0, void>::type
cmp
(
const word& msg,
const Type& x,
const Type& y,
const scalar relTol = 1e-8,
const scalar absTol = 0
)
{
Info<< msg << x << endl;
unsigned nFail = 0;
for (direction i = 0; i < pTraits<Type>::nComponents; ++i)
{
if (max(absTol, relTol*max(mag(x[i]), mag(y[i]))) < mag(x[i] - y[i]))
{ {
++nFail; ++nFail;
} }
} }
Info<< msg << x << endl;
if (nFail) if (nFail)
{ {
Info<< nl Info<< nl
@ -260,27 +244,26 @@ void test_global_opers(Type)
// Do compile-time recursion over the given types // Do compile-time recursion over the given types
template<std::size_t I = 0, typename... Tp> template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I == sizeof...(Tp), void>::type void run_tests(const std::tuple<Tp...>& types, const List<word>& names)
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID){}
template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I < sizeof...(Tp), void>::type
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID)
{ {
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl; if constexpr (I < sizeof...(Tp))
test_constructors(std::get<I>(types)); {
const auto& name = names[I];
Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl; Info<< nl << " ## Test constructors: " << name << " ##" << nl;
test_member_funcs(std::get<I>(types)); test_constructors(std::get<I>(types));
Info<< nl << " ## Test global functions: "<< typeID[I] << " ##" << nl; Info<< nl << " ## Test member functions: " << name << " ##" << nl;
test_global_funcs(std::get<I>(types)); test_member_funcs(std::get<I>(types));
Info<< nl << " ## Test global operators: "<< typeID[I] <<" ##" << nl; Info<< nl << " ## Test global functions: " << name << " ##" << nl;
test_global_opers(std::get<I>(types)); test_global_funcs(std::get<I>(types));
run_tests<I + 1, Tp...>(types, typeID); Info<< nl << " ## Test global operators: " << name << " ##" << nl;
test_global_opers(std::get<I>(types));
run_tests<I + 1, Tp...>(types, names);
}
} }
@ -295,8 +278,8 @@ int main()
const List<word> typeID const List<word> typeID
({ ({
"SphericalTensor2D<floatScalar>", "SphericalTensor2D<float>",
"SphericalTensor2D<doubleScalar>", "SphericalTensor2D<double>",
"SphericalTensor2D<complex>" "SphericalTensor2D<complex>"
}); });

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2020-2022 OpenCFD Ltd. Copyright (C) 2020-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -40,11 +40,10 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "complex.H"
#include "symmTensor.H" #include "symmTensor.H"
#include "transform.H" #include "transform.H"
#include "Random.H" #include "Random.H"
#include "scalar.H"
#include "complex.H"
using namespace Foam; using namespace Foam;
@ -69,12 +68,12 @@ symmTensor makeRandomContainer(Random& rnd)
// Create a symmTensor based on a given value // Create a symmTensor based on a given value
template<class Type> template<class Type>
typename std::enable_if std::enable_if_t
< <
std::is_same<floatScalar, Type>::value || std::is_floating_point_v<Type> || std::is_same_v<complex, Type>,
std::is_same<doubleScalar, Type>::value,
symmTensor symmTensor
>::type makeContainer(const Type val) >
makeContainer(const Type val)
{ {
symmTensor T(Zero); symmTensor T(Zero);
std::fill(T.begin(), T.end(), val); std::fill(T.begin(), T.end(), val);
@ -82,12 +81,11 @@ typename std::enable_if
} }
// Compare two floating point types, and print output. // Compare two containers elementwise, and print output.
// Do ++nFail_ if values of two objects are not equal within a given tolerance. // Do ++nFail_ if values of two objects are not equal within a given tolerance.
// The function is converted from PEP-485. // The function is converted from PEP-485.
template<class Type> template<class Type>
typename std::enable_if<pTraits<Type>::rank == 0, void>::type void cmp
cmp
( (
const word& msg, const word& msg,
const Type& x, const Type& x,
@ -96,51 +94,37 @@ cmp
const scalar relTol = 1e-8 //<! are values the same within 8 decimals const scalar relTol = 1e-8 //<! are values the same within 8 decimals
) )
{ {
Info<< msg << x << "?=" << y << endl; const auto notEqual = [=](const auto& a, const auto& b) -> bool
{
return
(
Foam::max(absTol, relTol*Foam::max(Foam::mag(a), Foam::mag(b)))
< Foam::mag(a - b)
);
};
unsigned nFail = 0; unsigned nFail = 0;
if (max(absTol, relTol*max(mag(x), mag(y))) < mag(x - y)) if constexpr (is_vectorspace_v<Type>)
{ {
++nFail; for (direction i = 0; i < pTraits<Type>::nComponents; ++i)
{
if (notEqual(x[i], y[i]))
{
++nFail;
}
}
} }
else
if (nFail)
{ {
Info<< nl if (notEqual(x, y))
<< " #### Fail in " << nFail << " comps ####" << nl << endl;
++nFail_;
}
++nTest_;
}
// Compare two containers elementwise, and print output.
// Do ++nFail_ if two components are not equal within a given tolerance.
// The function is converted from PEP-485
template<class Type>
typename std::enable_if<pTraits<Type>::rank != 0, void>::type
cmp
(
const word& msg,
const Type& x,
const Type& y,
const scalar absTol = 0,
const scalar relTol = 1e-8
)
{
Info<< msg << x << "?=" << y << endl;
unsigned nFail = 0;
for (direction i = 0; i < pTraits<Type>::nComponents; ++i)
{
if (max(absTol, relTol*max(mag(x[i]), mag(y[i]))) < mag(x[i] - y[i]))
{ {
++nFail; ++nFail;
} }
} }
Info<< msg << x << "?=" << y << endl;
if (nFail) if (nFail)
{ {
Info<< nl Info<< nl
@ -588,27 +572,26 @@ void test_eigen_funcs(const symmTensor& T)
// Do compile-time recursion over the given types // Do compile-time recursion over the given types
template<std::size_t I = 0, typename... Tp> template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I == sizeof...(Tp), void>::type void run_tests(const std::tuple<Tp...>& types, const List<word>& names)
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID){}
template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I < sizeof...(Tp), void>::type
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID)
{ {
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl; if constexpr (I < sizeof...(Tp))
test_constructors(std::get<I>(types)); {
const auto& name = names[I];
Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl; Info<< nl << " ## Test constructors: " << name << " ##" << nl;
test_member_funcs(std::get<I>(types)); test_constructors(std::get<I>(types));
Info<< nl << " ## Test global functions: "<< typeID[I] << " ##" << nl; Info<< nl << " ## Test member functions: " << name << " ##" << nl;
test_global_funcs(std::get<I>(types)); test_member_funcs(std::get<I>(types));
Info<< nl << " ## Test global operators: "<< typeID[I] <<" ##" << nl; Info<< nl << " ## Test global functions: " << name << " ##" << nl;
test_global_opers(std::get<I>(types)); test_global_funcs(std::get<I>(types));
run_tests<I + 1, Tp...>(types, typeID); Info<< nl << " ## Test global operators: " << name << " ##" << nl;
test_global_opers(std::get<I>(types));
run_tests<I + 1, Tp...>(types, names);
}
} }
@ -623,8 +606,8 @@ int main()
const List<word> typeID const List<word> typeID
({ ({
"SymmTensor<floatScalar>", "SymmTensor<float>",
"SymmTensor<doubleScalar>", "SymmTensor<double>",
"SymmTensor<complex>" "SymmTensor<complex>"
}); });

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2019-2022 OpenCFD Ltd. Copyright (C) 2019-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -40,11 +40,10 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "complex.H"
#include "symmTensor2D.H" #include "symmTensor2D.H"
#include "transform.H" #include "transform.H"
#include "Random.H" #include "Random.H"
#include "scalar.H"
#include "complex.H"
using namespace Foam; using namespace Foam;
@ -67,45 +66,11 @@ symmTensor2D makeRandomContainer(Random& rnd)
} }
// Compare two floating point types, and print output.
// Do ++nFail_ if values of two objects are not equal within a given tolerance.
// The function is converted from PEP-485.
template<class Type>
typename std::enable_if<pTraits<Type>::rank == 0, void>::type
cmp
(
const word& msg,
const Type& x,
const Type& y,
const scalar absTol = 0, //<! useful for cmps near zero
const scalar relTol = 1e-8 //<! are values the same within 8 decimals
)
{
Info<< msg << x << "?=" << y << endl;
unsigned nFail = 0;
if (max(absTol, relTol*max(mag(x), mag(y))) < mag(x - y))
{
++nFail;
}
if (nFail)
{
Info<< nl
<< " #### Fail in " << nFail << " comps ####" << nl << endl;
++nFail_;
}
++nTest_;
}
// Compare two containers elementwise, and print output. // Compare two containers elementwise, and print output.
// Do ++nFail_ if two components are not equal within a given tolerance. // Do ++nFail_ if two components are not equal within a given tolerance.
// The function is converted from PEP-485 // The function is converted from PEP-485
template<class Type> template<class Type>
typename std::enable_if<pTraits<Type>::rank != 0, void>::type void cmp
cmp
( (
const word& msg, const word& msg,
const Type& x, const Type& x,
@ -114,18 +79,37 @@ cmp
const scalar relTol = 1e-8 const scalar relTol = 1e-8
) )
{ {
Info<< msg << x << "?=" << y << endl; const auto notEqual = [=](const auto& a, const auto& b) -> bool
{
return
(
Foam::max(absTol, relTol*Foam::max(Foam::mag(a), Foam::mag(b)))
< Foam::mag(a - b)
);
};
unsigned nFail = 0; unsigned nFail = 0;
for (direction i = 0; i < pTraits<Type>::nComponents; ++i) if constexpr (is_vectorspace_v<Type>)
{ {
if (max(absTol, relTol*max(mag(x[i]), mag(y[i]))) < mag(x[i] - y[i])) for (direction i = 0; i < pTraits<Type>::nComponents; ++i)
{
if (notEqual(x[i], y[i]))
{
++nFail;
}
}
}
else
{
if (notEqual(x, y))
{ {
++nFail; ++nFail;
} }
} }
Info<< msg << x << "?=" << y << endl;
if (nFail) if (nFail)
{ {
Info<< nl Info<< nl
@ -538,27 +522,26 @@ void test_eigen_funcs(const symmTensor2D& T)
// Do compile-time recursion over the given types // Do compile-time recursion over the given types
template<std::size_t I = 0, typename... Tp> template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I == sizeof...(Tp), void>::type void run_tests(const std::tuple<Tp...>& types, const List<word>& names)
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID){}
template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I < sizeof...(Tp), void>::type
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID)
{ {
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl; if constexpr (I < sizeof...(Tp))
test_constructors(std::get<I>(types)); {
const auto& name = names[I];
Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl; Info<< nl << " ## Test constructors: " << name << " ##" << nl;
test_member_funcs(std::get<I>(types)); test_constructors(std::get<I>(types));
Info<< nl << " ## Test global functions: "<< typeID[I] << " ##" << nl; Info<< nl << " ## Test member functions: " << name << " ##" << nl;
test_global_funcs(std::get<I>(types)); test_member_funcs(std::get<I>(types));
Info<< nl << " ## Test global operators: "<< typeID[I] <<" ##" << nl; Info<< nl << " ## Test global functions: " << name << " ##" << nl;
test_global_opers(std::get<I>(types)); test_global_funcs(std::get<I>(types));
run_tests<I + 1, Tp...>(types, typeID); Info<< nl << " ## Test global operators: " << name << " ##" << nl;
test_global_opers(std::get<I>(types));
run_tests<I + 1, Tp...>(types, names);
}
} }
@ -573,8 +556,8 @@ int main(int argc, char *argv[])
const List<word> typeID const List<word> typeID
({ ({
"SymmTensor2D<floatScalar>", "SymmTensor2D<float>",
"SymmTensor2D<doubleScalar>", "SymmTensor2D<double>",
"SymmTensor2D<complex>" "SymmTensor2D<complex>"
}); });

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2018 OpenFOAM Foundation Copyright (C) 2018 OpenFOAM Foundation
Copyright (C) 2019-2020 OpenCFD Ltd. Copyright (C) 2019-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -41,11 +41,10 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "complex.H"
#include "tensor.H" #include "tensor.H"
#include "transform.H" #include "transform.H"
#include "Random.H" #include "Random.H"
#include "scalar.H"
#include "complex.H"
using namespace Foam; using namespace Foam;
@ -68,45 +67,11 @@ tensor makeRandomContainer(Random& rnd)
} }
// Compare two floating point types, and print output.
// Do ++nFail_ if values of two objects are not equal within a given tolerance.
// The function is converted from PEP-485.
template<class Type>
typename std::enable_if<pTraits<Type>::rank == 0, void>::type
cmp
(
const word& msg,
const Type& x,
const Type& y,
const scalar absTol = 0, //<! useful for cmps near zero
const scalar relTol = 1e-8 //<! are values the same within 8 decimals
)
{
Info<< msg << x << "?=" << y << endl;
unsigned nFail = 0;
if (max(absTol, relTol*max(mag(x), mag(y))) < mag(x - y))
{
++nFail;
}
if (nFail)
{
Info<< nl
<< " #### Fail in " << nFail << " comps ####" << nl << endl;
++nFail_;
}
++nTest_;
}
// Compare two containers elementwise, and print output. // Compare two containers elementwise, and print output.
// Do ++nFail_ if two components are not equal within a given tolerance. // Do ++nFail_ if two components are not equal within a given tolerance.
// The function is converted from PEP-485 // The function is converted from PEP-485
template<class Type> template<class Type>
typename std::enable_if<pTraits<Type>::rank != 0, void>::type void cmp
cmp
( (
const word& msg, const word& msg,
const Type& x, const Type& x,
@ -115,18 +80,37 @@ cmp
const scalar relTol = 1e-8 const scalar relTol = 1e-8
) )
{ {
Info<< msg << x << "?=" << y << endl; const auto notEqual = [=](const auto& a, const auto& b) -> bool
{
return
(
Foam::max(absTol, relTol*Foam::max(Foam::mag(a), Foam::mag(b)))
< Foam::mag(a - b)
);
};
unsigned nFail = 0; unsigned nFail = 0;
for (direction i = 0; i < pTraits<Type>::nComponents; ++i) if constexpr (is_vectorspace_v<Type>)
{ {
if (max(absTol, relTol*max(mag(x[i]), mag(y[i]))) < mag(x[i] - y[i])) for (direction i = 0; i < pTraits<Type>::nComponents; ++i)
{
if (notEqual(x[i], y[i]))
{
++nFail;
}
}
}
else
{
if (notEqual(x, y))
{ {
++nFail; ++nFail;
} }
} }
Info<< msg << x << "?=" << y << endl;
if (nFail) if (nFail)
{ {
Info<< nl Info<< nl
@ -987,27 +971,26 @@ void test_eigen_funcs(const tensor& T, const bool prod = true)
// Do compile-time recursion over the given types // Do compile-time recursion over the given types
template<std::size_t I = 0, typename... Tp> template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I == sizeof...(Tp), void>::type void run_tests(const std::tuple<Tp...>& types, const List<word>& names)
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID){}
template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I < sizeof...(Tp), void>::type
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID)
{ {
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl; if constexpr (I < sizeof...(Tp))
test_constructors(std::get<I>(types)); {
const auto& name = names;
Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl; Info<< nl << " ## Test constructors: " << name << " ##" << nl;
test_member_funcs(std::get<I>(types)); test_constructors(std::get<I>(types));
Info<< nl << " ## Test global functions: "<< typeID[I] << " ##" << nl; Info<< nl << " ## Test member functions: " << name << " ##" << nl;
test_global_funcs(std::get<I>(types)); test_member_funcs(std::get<I>(types));
Info<< nl << " ## Test global operators: "<< typeID[I] <<" ##" << nl; Info<< nl << " ## Test global functions: " << name <<" ##" << nl;
test_global_opers(std::get<I>(types)); test_global_funcs(std::get<I>(types));
run_tests<I + 1, Tp...>(types, typeID); Info<< nl << " ## Test global operators: " << name <<" ##" << nl;
test_global_opers(std::get<I>(types));
run_tests<I + 1, Tp...>(types, names);
}
} }
@ -1022,8 +1005,8 @@ int main()
const List<word> typeID const List<word> typeID
({ ({
"Tensor<floatScalar>", "Tensor<float>",
"Tensor<doubleScalar>", "Tensor<double>",
"Tensor<complex>" "Tensor<complex>"
}); });

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2014 OpenFOAM Foundation Copyright (C) 2014 OpenFOAM Foundation
Copyright (C) 2019-2022 OpenCFD Ltd. Copyright (C) 2019-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -41,13 +41,13 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "scalar.H"
#include "complex.H"
#include "vector2DField.H" #include "vector2DField.H"
#include "tensor2D.H" #include "tensor2D.H"
#include "symmTensor2D.H" #include "symmTensor2D.H"
#include "transform.H" #include "transform.H"
#include "Random.H" #include "Random.H"
#include "scalar.H"
#include "complex.H"
using namespace Foam; using namespace Foam;
@ -70,12 +70,11 @@ tensor2D makeRandomContainer(Random& rnd)
} }
// Compare two floating point types, and print output. // Compare two containers elementwise, and print output.
// Do ++nFail_ if values of two objects are not equal within a given tolerance. // Do ++nFail_ if two components are not equal within a given tolerance.
// The function is converted from PEP-485. // The function is converted from PEP-485
template<class Type> template<class Type>
typename std::enable_if<pTraits<Type>::rank == 0, void>::type void cmp
cmp
( (
const word& msg, const word& msg,
const Type& x, const Type& x,
@ -84,51 +83,37 @@ cmp
const scalar relTol = 1e-8 //<! are values the same within 8 decimals const scalar relTol = 1e-8 //<! are values the same within 8 decimals
) )
{ {
Info<< msg << x << "?=" << y << endl; const auto notEqual = [=](const auto& a, const auto& b) -> bool
{
return
(
Foam::max(absTol, relTol*Foam::max(Foam::mag(a), Foam::mag(b)))
< Foam::mag(a - b)
);
};
unsigned nFail = 0; unsigned nFail = 0;
if (max(absTol, relTol*max(mag(x), mag(y))) < mag(x - y)) if constexpr (is_vectorspace_v<Type>)
{ {
++nFail; for (direction i = 0; i < pTraits<Type>::nComponents; ++i)
{
if (notEqual(x[i], y[i]))
{
++nFail;
}
}
} }
else
if (nFail)
{ {
Info<< nl if (notEqual(x, y))
<< " #### Fail in " << nFail << " comps ####" << nl << endl;
++nFail_;
}
++nTest_;
}
// Compare two containers elementwise, and print output.
// Do ++nFail_ if two components are not equal within a given tolerance.
// The function is converted from PEP-485
template<class Type>
typename std::enable_if<pTraits<Type>::rank != 0, void>::type
cmp
(
const word& msg,
const Type& x,
const Type& y,
const scalar absTol = 0,
const scalar relTol = 1e-8
)
{
Info<< msg << x << "?=" << y << endl;
unsigned nFail = 0;
for (direction i = 0; i < pTraits<Type>::nComponents; ++i)
{
if (max(absTol, relTol*max(mag(x[i]), mag(y[i]))) < mag(x[i] - y[i]))
{ {
++nFail; ++nFail;
} }
} }
Info<< msg << x << "?=" << y << endl;
if (nFail) if (nFail)
{ {
Info<< nl Info<< nl
@ -795,27 +780,26 @@ void test_eigen_funcs(const tensor2D& T)
// Do compile-time recursion over the given types // Do compile-time recursion over the given types
template<std::size_t I = 0, typename... Tp> template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I == sizeof...(Tp), void>::type void run_tests(const std::tuple<Tp...>& types, const List<word>& names)
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID){}
template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I < sizeof...(Tp), void>::type
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID)
{ {
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl; if constexpr (I < sizeof...(Tp))
test_constructors(std::get<I>(types)); {
const auto& name = names[I];
Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl; Info<< nl << " ## Test constructors: " << name << " ##" << nl;
test_member_funcs(std::get<I>(types)); test_constructors(std::get<I>(types));
Info<< nl << " ## Test global functions: "<< typeID[I] << " ##" << nl; Info<< nl << " ## Test member functions: " << name << " ##" << nl;
test_global_funcs(std::get<I>(types)); test_member_funcs(std::get<I>(types));
Info<< nl << " ## Test global operators: "<< typeID[I] <<" ##" << nl; Info<< nl << " ## Test global functions: " << name << " ##" << nl;
test_global_opers(std::get<I>(types)); test_global_funcs(std::get<I>(types));
run_tests<I + 1, Tp...>(types, typeID); Info<< nl << " ## Test global operators: " << name << " ##" << nl;
test_global_opers(std::get<I>(types));
run_tests<I + 1, Tp...>(types, names);
}
} }
@ -831,8 +815,8 @@ int main(int argc, char *argv[])
const List<word> typeID const List<word> typeID
({ ({
"Tensor2D<floatScalar>", "Tensor2D<float>",
"Tensor2D<doubleScalar>", "Tensor2D<double>",
"Tensor2D<complex>" "Tensor2D<complex>"
}); });

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2020-2022 OpenCFD Ltd. Copyright (C) 2020-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -67,13 +67,9 @@ doubleScalar getTol(complex)
} }
// Create a non-complex random Matrix. // Create a random Matrix (real or complex)
template<class MatrixType> template<class MatrixType>
typename std::enable_if MatrixType makeRandomMatrix
<
!std::is_same<complex, typename MatrixType::cmptType>:: value,
MatrixType
>::type makeRandomMatrix
( (
const labelPair& dims, const labelPair& dims,
Random& rndGen Random& rndGen
@ -81,34 +77,22 @@ typename std::enable_if
{ {
MatrixType mat(dims); MatrixType mat(dims);
std::generate if constexpr (std::is_same_v<complex, typename MatrixType::cmptType>)
(
mat.begin(),
mat.end(),
[&]{return rndGen.GaussNormal<scalar>();}
);
return mat;
}
// Create a complex random Matrix.
template<class MatrixType>
typename std::enable_if
<
std::is_same<complex, typename MatrixType::cmptType>:: value,
MatrixType
>::type makeRandomMatrix
(
const labelPair& dims,
Random& rndGen
)
{
MatrixType mat(dims);
for (auto& x : mat)
{ {
x = complex(rndGen.GaussNormal<scalar>(), rndGen.GaussNormal<scalar>()); for (auto& x : mat)
{
x.real(rndGen.GaussNormal<scalar>());
x.imag(rndGen.GaussNormal<scalar>());
}
}
else
{
std::generate
(
mat.begin(),
mat.end(),
[&]{ return rndGen.GaussNormal<scalar>(); }
);
} }
return mat; return mat;
@ -179,128 +163,57 @@ List<Type> flt
} }
// Compare two floating point types, and print output. // Compare two values or two containers (elementwise), and print output.
// Do ++nFail_ if values of two objects are not equal within a given tolerance. // Do ++nFail_ if values of two objects are not equal within a given tolerance.
// The function is converted from PEP-485. // The function is converted from PEP-485.
template<class Type> template<class Type1, class Type2 = Type1>
typename std::enable_if void cmp
<
std::is_same<floatScalar, Type>::value ||
std::is_same<doubleScalar, Type>::value ||
std::is_same<complex, Type>::value,
void
>::type cmp
( (
const word& msg, const word& msg,
const Type& x, const Type1& x,
const Type& y, const Type2& y,
const scalar absTol = 0, //<! useful for cmps near zero const scalar absTol = 0, //<! useful for cmps near zero
const scalar relTol = 1e-8, //<! are values the same within 8 decimals const scalar relTol = 1e-8, //<! are values the same within 8 decimals
const bool verbose = false const bool verbose = false
) )
{ {
if (verbose) const auto notEqual = [=](const auto& a, const auto& b) -> bool
{ {
Info<< msg << x << "?=" << y << endl; return
} (
Foam::max(absTol, relTol*Foam::max(Foam::mag(a), Foam::mag(b)))
< Foam::mag(a - b)
);
};
unsigned nFail = 0; unsigned nFail = 0;
if (max(absTol, relTol*max(mag(x), mag(y))) < mag(x - y)) if constexpr
(
std::is_floating_point_v<Type1> || std::is_same_v<complex, Type1>
)
{ {
++nFail; if (notEqual(x, y))
}
if (nFail)
{
Info<< nl
<< " #### Fail in " << nFail << " comps ####" << nl << endl;
++nFail_;
}
++nTest_;
}
// Compare two containers elementwise, and print output.
// Do ++nFail_ if two components are not equal within a given tolerance.
// The function is converted from PEP-485
template<class Type>
typename std::enable_if
<
!std::is_same<floatScalar, Type>::value &&
!std::is_same<doubleScalar, Type>::value &&
!std::is_same<complex, Type>::value,
void
>::type cmp
(
const word& msg,
const Type& x,
const Type& y,
const scalar absTol = 0,
const scalar relTol = 1e-8,
const bool verbose = false
)
{
if (verbose)
{
Info<< msg << x << "?=" << y << endl;
}
unsigned nFail = 0;
for (label i = 0; i < x.size(); ++i)
{
if (max(absTol, relTol*max(mag(x[i]), mag(y[i]))) < mag(x[i] - y[i]))
{ {
++nFail; ++nFail;
} }
} }
else
if (nFail)
{ {
Info<< nl for (label i = 0; i < x.size(); ++i)
<< " #### Fail in " << nFail << " comps ####" << nl << endl; {
++nFail_; if (notEqual(x[i], y[i]))
{
++nFail;
}
}
} }
++nTest_;
}
// Compare two containers elementwise, and print output.
// Do ++nFail_ if two components are not equal within a given tolerance.
// The function is converted from PEP-485
template<class Type1, class Type2>
typename std::enable_if
<
!std::is_same<floatScalar, Type1>::value &&
!std::is_same<doubleScalar, Type1>::value &&
!std::is_same<complex, Type1>::value,
void
>::type cmp
(
const word& msg,
const Type1& x,
const Type2& y,
const scalar absTol = 0,
const scalar relTol = 1e-8,
const bool verbose = false
)
{
if (verbose) if (verbose)
{ {
Info<< msg << x << "?=" << y << endl; Info<< msg << x << "?=" << y << endl;
} }
unsigned nFail = 0;
for (label i = 0; i < x.size(); ++i)
{
if (max(absTol, relTol*max(mag(x[i]), mag(y[i]))) < mag(x[i] - y[i]))
{
++nFail;
}
}
if (nFail) if (nFail)
{ {
Info<< nl Info<< nl
@ -321,11 +234,6 @@ void cmp
const bool verbose = false const bool verbose = false
) )
{ {
if (verbose)
{
Info<< msg << x << "?=" << y << endl;
}
unsigned nFail = 0; unsigned nFail = 0;
if (x != y) if (x != y)
@ -333,6 +241,11 @@ void cmp
++nFail; ++nFail;
} }
if (verbose)
{
Info<< msg << x << "?=" << y << endl;
}
if (nFail) if (nFail)
{ {
Info<< nl Info<< nl

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2020-2022 OpenCFD Ltd. Copyright (C) 2020-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -54,7 +54,7 @@ int main(int argc, char *argv[])
{ {
Info<< "boolVector" << nl Info<< "boolVector" << nl
<< " size = " << boolVector::size() << nl << " size = " << boolVector::size() << nl
<< " contiguous = " << is_contiguous<boolVector>::value << nl << " contiguous = " << is_contiguous_v<boolVector> << nl
<< nl; << nl;
{ {

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2018-2019 OpenCFD Ltd. Copyright (C) 2018-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -72,13 +72,14 @@ void printInfo(const char* const name = nullptr)
Info<< name; Info<< name;
} }
Info<< " contiguous=" << Switch(is_contiguous<T>::value); Info<< " contiguous=" << Switch(is_contiguous<T>::value)
<< " / " << Switch(is_contiguous_v<T>);
if (is_contiguous_label<T>::value) if constexpr (is_contiguous_label<T>::value)
{ {
Info<< " label"; Info<< " label";
} }
if (is_contiguous_scalar<T>::value) if constexpr (is_contiguous_scalar<T>::value)
{ {
Info<< " scalar"; Info<< " scalar";
} }
@ -96,10 +97,11 @@ int main(int argc, char *argv[])
argList::noParallel(); argList::noParallel();
argList::noFunctionObjects(); argList::noFunctionObjects();
printInfo<label>();
printInfo<label>(); printInfo<label>();
printInfo<double>(); printInfo<double>();
printInfo<FixedList<double, 4>>(); printInfo<FixedList<double, 4>>();
printInfo<Pair<long>>(); printInfo<const Pair<long>>();
printInfo<FixedList<word, 2>>(); printInfo<FixedList<word, 2>>();
printInfo<Pair<word>>(); printInfo<Pair<word>>();

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2021-2024 OpenCFD Ltd. Copyright (C) 2021-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM, distributed under GPL-3.0-or-later. This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
@ -122,7 +122,7 @@ int main(int argc, char *argv[])
// Regular broadcast doesn't work // Regular broadcast doesn't work
Info<< "exprValue" Info<< "exprValue"
<< " sizeof:" << sizeof(expressions::exprValue) << " sizeof:" << sizeof(expressions::exprValue)
<< " contiguous:" << is_contiguous<expressions::exprValue>::value << " contiguous:" << is_contiguous_v<expressions::exprValue>
<< nl << nl; << nl << nl;
{ {

View File

@ -3,4 +3,5 @@ EXE_INC = \
-I$(LIB_SRC)/meshTools/lnInclude -I$(LIB_SRC)/meshTools/lnInclude
EXE_LIBS = \ EXE_LIBS = \
-lfiniteVolume -lfiniteVolume \
-lmeshTools

View File

@ -3,4 +3,5 @@ EXE_INC = \
-I$(LIB_SRC)/meshTools/lnInclude -I$(LIB_SRC)/meshTools/lnInclude
EXE_LIBS = \ EXE_LIBS = \
-lfiniteVolume -lfiniteVolume \
-lmeshTools

View File

@ -48,7 +48,7 @@ word toString(const fileOperation::procRangeType& group)
{ {
return word::null; return word::null;
} }
return Foam::name(group.first()) + "-" + Foam::name(group.last()); return Foam::name(group.min()) + "-" + Foam::name(group.max());
} }

View File

@ -31,13 +31,12 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "complex.H"
#include "tensor.H" #include "tensor.H"
#include "symmTensor.H" #include "symmTensor.H"
#include "transform.H" #include "transform.H"
#include "unitConversion.H" #include "unitConversion.H"
#include "Random.H" #include "Random.H"
#include "scalar.H"
#include "complex.H"
#include "sigFpe.H" #include "sigFpe.H"
using namespace Foam; using namespace Foam;

View File

@ -3,4 +3,5 @@ EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude -I$(LIB_SRC)/finiteVolume/lnInclude
EXE_LIBS = \ EXE_LIBS = \
-lfiniteVolume -lfiniteVolume \
-lmeshTools

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd. Copyright (C) 2020-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -36,10 +36,9 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "complex.H"
#include "DiagonalMatrix.H" #include "DiagonalMatrix.H"
#include "RectangularMatrix.H" #include "RectangularMatrix.H"
#include "scalar.H"
#include "complex.H"
#include "TestTools.H" #include "TestTools.H"
using namespace Foam; using namespace Foam;
@ -173,24 +172,23 @@ void test_global_funcs(Type)
// Do compile-time recursion over the given types // Do compile-time recursion over the given types
template<std::size_t I = 0, typename... Tp> template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I == sizeof...(Tp), void>::type void run_tests(const std::tuple<Tp...>& types, const List<word>& names)
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID){}
template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I < sizeof...(Tp), void>::type
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID)
{ {
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl; if constexpr (I < sizeof...(Tp))
test_constructors(std::get<I>(types)); {
const auto& name = names[I];
Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl; Info<< nl << " ## Test constructors: " << name << " ##" << nl;
test_member_funcs(std::get<I>(types)); test_constructors(std::get<I>(types));
Info<< nl << " ## Test global functions: "<< typeID[I] << " ##" << nl; Info<< nl << " ## Test member functions: " << name << " ##" << nl;
test_global_funcs(std::get<I>(types)); test_member_funcs(std::get<I>(types));
run_tests<I + 1, Tp...>(types, typeID); Info<< nl << " ## Test global functions: " << name << " ##" << nl;
test_global_funcs(std::get<I>(types));
run_tests<I + 1, Tp...>(types, names);
}
} }
@ -205,8 +203,8 @@ int main()
const List<word> typeID const List<word> typeID
({ ({
"DiagonalMatrix<floatScalar>", "DiagonalMatrix<float>",
"DiagonalMatrix<doubleScalar>", "DiagonalMatrix<double>",
"DiagonalMatrix<complex>" "DiagonalMatrix<complex>"
}); });

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2020-2022 OpenCFD Ltd. Copyright (C) 2020-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is derivative work of OpenFOAM. This file is derivative work of OpenFOAM.
@ -36,10 +36,10 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "complex.H"
#include "scalarMatrices.H" #include "scalarMatrices.H"
#include "RectangularMatrix.H" #include "RectangularMatrix.H"
#include "SquareMatrix.H" #include "SquareMatrix.H"
#include "complex.H"
#include "IOmanip.H" #include "IOmanip.H"
#include "EigenMatrix.H" #include "EigenMatrix.H"
#include "TestTools.H" #include "TestTools.H"
@ -335,27 +335,26 @@ void test_eigenvectors(Type)
// Do compile-time recursion over the given types // Do compile-time recursion over the given types
template<std::size_t I = 0, typename... Tp> template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I == sizeof...(Tp), void>::type void run_tests(const std::tuple<Tp...>& types, const List<word>& names)
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID){}
template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I < sizeof...(Tp), void>::type
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID)
{ {
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl; if constexpr (I < sizeof...(Tp))
test_constructors(std::get<I>(types)); {
const auto& name = names[I];
Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl; Info<< nl << " ## Test constructors: " << name << " ##" << nl;
test_member_funcs(std::get<I>(types)); test_constructors(std::get<I>(types));
Info<< nl << " ## Test eigenvalues: "<< typeID[I] <<" ##" << nl; Info<< nl << " ## Test member functions: " << name << " ##" << nl;
test_eigenvalues(std::get<I>(types)); test_member_funcs(std::get<I>(types));
Info<< nl << " ## Test eigenvectors: "<< typeID[I] <<" ##" << nl; Info<< nl << " ## Test eigenvalues: " << name << " ##" << nl;
test_eigenvectors(std::get<I>(types)); test_eigenvalues(std::get<I>(types));
run_tests<I + 1, Tp...>(types, typeID); Info<< nl << " ## Test eigenvectors: " << name << " ##" << nl;
test_eigenvectors(std::get<I>(types));
run_tests<I + 1, Tp...>(types, names);
}
} }
@ -372,8 +371,8 @@ int main()
const List<word> typeID const List<word> typeID
({ ({
"SquareMatrix<floatScalar>", "SquareMatrix<float>",
"SquareMatrix<doubleScalar>" "SquareMatrix<double>"
}); });
run_tests(types, typeID); run_tests(types, typeID);
@ -539,3 +538,6 @@ int main()
Info<< nl << " #### Passed all " << nTest_ <<" tests ####\n" << endl; Info<< nl << " #### Passed all " << nTest_ <<" tests ####\n" << endl;
return 0; return 0;
} }
// ************************************************************************* //

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2020-2022 OpenCFD Ltd. Copyright (C) 2020-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -32,9 +32,9 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "complex.H"
#include "MatrixTools.H" #include "MatrixTools.H"
#include "QRMatrix.H" #include "QRMatrix.H"
#include "complex.H"
#include "IOmanip.H" #include "IOmanip.H"
#include "TestTools.H" #include "TestTools.H"
@ -533,21 +533,20 @@ void test_decomposition(MatrixType)
// Do compile-time recursion over the given types // Do compile-time recursion over the given types
template<std::size_t I = 0, typename... Tp> template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I == sizeof...(Tp), void>::type void run_tests(const std::tuple<Tp...>& types, const List<word>& names)
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID){}
template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I < sizeof...(Tp), void>::type
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID)
{ {
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl; if constexpr (I < sizeof...(Tp))
test_constructors(std::get<I>(types)); {
const auto& name = names[I];
Info<< nl << " ## Test decomposition: "<< typeID[I] <<" ##" << nl; Info<< nl << " ## Test constructors: " << name << " ##" << nl;
test_decomposition(std::get<I>(types)); test_constructors(std::get<I>(types));
run_tests<I + 1, Tp...>(types, typeID); Info<< nl << " ## Test decomposition: " << name << " ##" << nl;
test_decomposition(std::get<I>(types));
run_tests<I + 1, Tp...>(types, names);
}
} }
@ -570,9 +569,9 @@ int main()
const List<word> typeID const List<word> typeID
({ ({
"RectangularMatrix<doubleScalar>", "RectangularMatrix<double>",
"RectangularMatrix<complex>", "RectangularMatrix<complex>",
"SquareMatrix<doubleScalar>", "SquareMatrix<double>",
"SquareMatrix<complex>" "SquareMatrix<complex>"
}); });

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd. Copyright (C) 2020-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -42,10 +42,9 @@ Note
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "complex.H"
#include "RectangularMatrix.H" #include "RectangularMatrix.H"
#include "SquareMatrix.H" #include "SquareMatrix.H"
#include "scalar.H"
#include "complex.H"
#include "IOmanip.H" #include "IOmanip.H"
#include "TestTools.H" #include "TestTools.H"
@ -809,36 +808,34 @@ void test_global_opers(Type)
// Do compile-time recursion over the given types // Do compile-time recursion over the given types
template<std::size_t I = 0, typename... Tp> template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I == sizeof...(Tp), void>::type void run_tests(const std::tuple<Tp...>& types, const List<word>& names)
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID){}
template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I < sizeof...(Tp), void>::type
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID)
{ {
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl; if constexpr (I < sizeof...(Tp))
test_constructors(std::get<I>(types)); {
const auto& name = names[I];
Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl; Info<< nl << " ## Test constructors: " << name << " ##" << nl;
test_member_funcs(std::get<I>(types)); test_constructors(std::get<I>(types));
Info<< nl << " ## Test member opers: "<< typeID[I] <<" ##" << nl; Info<< nl << " ## Test member functions: " << name << " ##" << nl;
test_member_opers(std::get<I>(types)); test_member_funcs(std::get<I>(types));
Info<< nl << " ## Test global functions: "<< typeID[I] << " ##" << nl; Info<< nl << " ## Test member opers: " << name << " ##" << nl;
test_global_funcs(std::get<I>(types)); test_member_opers(std::get<I>(types));
Info<< nl << " ## Test global operators: "<< typeID[I] << " ##" << nl; Info<< nl << " ## Test global functions: " << name << " ##" << nl;
test_global_opers(std::get<I>(types)); test_global_funcs(std::get<I>(types));
Info<< nl << " ## Test friend funcs: "<< typeID[I] <<" ##" << nl; Info<< nl << " ## Test global operators: " << name << " ##" << nl;
test_friend_funcs(std::get<I>(types)); test_global_opers(std::get<I>(types));
run_tests<I + 1, Tp...>(types, typeID); Info<< nl << " ## Test friend funcs: " << name << " ##" << nl;
test_friend_funcs(std::get<I>(types));
run_tests<I + 1, Tp...>(types, names);
}
} }
// * * * * * * * * * * * * * * * Main Program * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Main Program * * * * * * * * * * * * * * * //
int main() int main()
@ -852,8 +849,8 @@ int main()
const List<word> typeID const List<word> typeID
({ ({
"RectangularMatrix<floatScalar>", "RectangularMatrix<float>",
"RectangularMatrix<doubleScalar>", "RectangularMatrix<double>",
"RectangularMatrix<complex>" "RectangularMatrix<complex>"
}); });

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd. Copyright (C) 2020-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -42,11 +42,10 @@ Note
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "complex.H"
#include "scalarMatrices.H" #include "scalarMatrices.H"
#include "RectangularMatrix.H" #include "RectangularMatrix.H"
#include "SquareMatrix.H" #include "SquareMatrix.H"
#include "scalar.H"
#include "complex.H"
#include "IOmanip.H" #include "IOmanip.H"
#include "TestTools.H" #include "TestTools.H"
@ -932,33 +931,32 @@ void test_global_opers(Type)
// Do compile-time recursion over the given types // Do compile-time recursion over the given types
template<std::size_t I = 0, typename... Tp> template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I == sizeof...(Tp), void>::type void run_tests(const std::tuple<Tp...>& types, const List<word>& names)
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID){}
template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I < sizeof...(Tp), void>::type
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID)
{ {
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl; if constexpr (I < sizeof...(Tp))
test_constructors(std::get<I>(types)); {
const auto& name = names[I];
Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl; Info<< nl << " ## Test constructors: " << name << " ##" << nl;
test_member_funcs(std::get<I>(types)); test_constructors(std::get<I>(types));
Info<< nl << " ## Test member opers: "<< typeID[I] <<" ##" << nl; Info<< nl << " ## Test member functions: " << name << " ##" << nl;
test_member_opers(std::get<I>(types)); test_member_funcs(std::get<I>(types));
Info<< nl << " ## Test global functions: "<< typeID[I] << " ##" << nl; Info<< nl << " ## Test member opers: " << name << " ##" << nl;
test_global_funcs(std::get<I>(types)); test_member_opers(std::get<I>(types));
Info<< nl << " ## Test global operators: "<< typeID[I] << " ##" << nl; Info<< nl << " ## Test global functions: " << name << " ##" << nl;
test_global_opers(std::get<I>(types)); test_global_funcs(std::get<I>(types));
Info<< nl << " ## Test friend funcs: "<< typeID[I] <<" ##" << nl; Info<< nl << " ## Test global operators: " << name << " ##" << nl;
test_friend_funcs(std::get<I>(types)); test_global_opers(std::get<I>(types));
run_tests<I + 1, Tp...>(types, typeID); Info<< nl << " ## Test friend funcs: " << name << " ##" << nl;
test_friend_funcs(std::get<I>(types));
run_tests<I + 1, Tp...>(types, names);
}
} }
@ -975,8 +973,8 @@ int main()
const List<word> typeID const List<word> typeID
({ ({
"SquareMatrix<floatScalar>", "SquareMatrix<float>",
"SquareMatrix<doubleScalar>", "SquareMatrix<double>",
"SquareMatrix<complex>" "SquareMatrix<complex>"
}); });

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd. Copyright (C) 2020-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -42,12 +42,11 @@ Note
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "complex.H"
#include "scalarMatrices.H" #include "scalarMatrices.H"
#include "RectangularMatrix.H" #include "RectangularMatrix.H"
#include "SquareMatrix.H" #include "SquareMatrix.H"
#include "SymmetricSquareMatrix.H" #include "SymmetricSquareMatrix.H"
#include "scalar.H"
#include "complex.H"
#include "IOmanip.H" #include "IOmanip.H"
#include "Random.H" #include "Random.H"
#include "TestTools.H" #include "TestTools.H"
@ -138,33 +137,32 @@ void test_global_opers(Type)
// Do compile-time recursion over the given types // Do compile-time recursion over the given types
template<std::size_t I = 0, typename... Tp> template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I == sizeof...(Tp), void>::type void run_tests(const std::tuple<Tp...>& types, const List<word>& names)
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID){}
template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I < sizeof...(Tp), void>::type
run_tests(const std::tuple<Tp...>& types, const List<word>& typeID)
{ {
Info<< nl << " ## Test constructors: "<< typeID[I] <<" ##" << nl; if constexpr (I < sizeof...(Tp))
test_constructors(std::get<I>(types)); {
const auto& name = names[I];
Info<< nl << " ## Test member functions: "<< typeID[I] <<" ##" << nl; Info<< nl << " ## Test constructors: " << name << " ##" << nl;
test_member_funcs(std::get<I>(types)); test_constructors(std::get<I>(types));
Info<< nl << " ## Test member opers: "<< typeID[I] <<" ##" << nl; Info<< nl << " ## Test member functions: " << name << " ##" << nl;
test_member_opers(std::get<I>(types)); test_member_funcs(std::get<I>(types));
Info<< nl << " ## Test global functions: "<< typeID[I] << " ##" << nl; Info<< nl << " ## Test member opers: " << name << " ##" << nl;
test_global_funcs(std::get<I>(types)); test_member_opers(std::get<I>(types));
Info<< nl << " ## Test global operators: "<< typeID[I] << " ##" << nl; Info<< nl << " ## Test global functions: " << name << " ##" << nl;
test_global_opers(std::get<I>(types)); test_global_funcs(std::get<I>(types));
Info<< nl << " ## Test friend funcs: "<< typeID[I] <<" ##" << nl; Info<< nl << " ## Test global operators: " << name << " ##" << nl;
test_friend_funcs(std::get<I>(types)); test_global_opers(std::get<I>(types));
run_tests<I + 1, Tp...>(types, typeID); Info<< nl << " ## Test friend funcs: " << name << " ##" << nl;
test_friend_funcs(std::get<I>(types));
run_tests<I + 1, Tp...>(types, names);
}
} }
@ -181,8 +179,8 @@ int main()
const List<word> typeID const List<word> typeID
({ ({
"SymmetricSquareMatrix<floatScalar>", "SymmetricSquareMatrix<float>",
"SymmetricSquareMatrix<doubleScalar>", "SymmetricSquareMatrix<double>",
"SymmetricSquareMatrix<complex>" "SymmetricSquareMatrix<complex>"
}); });

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2023 OpenCFD Ltd. Copyright (C) 2023-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -32,9 +32,11 @@ Description
#include "pTraits.H" #include "pTraits.H"
#include "contiguous.H" #include "contiguous.H"
#include "boolVector.H" // A FixedList pretending to be a vector #include "boolVector.H" // A FixedList pretending to be a vector
#include "complex.H"
#include "vector.H" #include "vector.H"
#include "tensor.H" #include "tensor.H"
#include "complex.H" #include "sphericalTensor.H"
#include "symmTensor.H"
#include "uLabel.H" #include "uLabel.H"
#include "Switch.H" #include "Switch.H"
@ -50,26 +52,37 @@ template<class T, class = void>
struct has_typeName : std::false_type {}; struct has_typeName : std::false_type {};
//- Test if Type has typeName member //- Test if Type has typeName member
template<class T> template<class T>
struct has_typeName<T, stdFoam::void_t<decltype(pTraits<T>::typeName)>> struct has_typeName
<
T,
std::void_t<decltype(pTraits<std::remove_cv_t<T>>::typeName)>
>
: :
std::true_type std::true_type
{}; {};
template<class T> template<class T>
typename std::enable_if<has_typeName<T>::value, void>::type void printTypeName()
printTypeName()
{ {
Info<< pTraits<T>::typeName; // Both float and double have pTraits typeName = "scalar"!
} if constexpr (std::is_same_v<float, std::remove_cv_t<T>>)
{
template<class T> Info<< "<float>";
typename std::enable_if<!has_typeName<T>::value, void>::type }
printTypeName() else if constexpr (std::is_same_v<double, std::remove_cv_t<T>>)
{ {
Info<< typeid(T).name(); Info<< "<double>";
}
else if constexpr (has_typeName<T>::value)
{
Info<< pTraits<std::remove_cv_t<T>>::typeName;
}
else
{
Info<< typeid(T).name();
}
} }
@ -80,23 +93,24 @@ template<class T>
struct has_zero_one struct has_zero_one
< <
T, T,
stdFoam::void_t<decltype(pTraits<T>::zero), decltype(pTraits<T>::one)> std::void_t
<
decltype(pTraits<std::remove_cv_t<T>>::zero),
decltype(pTraits<std::remove_cv_t<T>>::one)
>
> : std::true_type {}; > : std::true_type {};
template<class T> template<class T>
typename std::enable_if<has_zero_one<T>::value, void>::type void printMinMaxRange()
printMinMaxRange()
{ {
Info<< " zero=" << pTraits<T>::zero if constexpr (has_zero_one<T>::value)
<< " one=" << pTraits<T>::one; {
Info<< " zero=" << pTraits<std::remove_cv_t<T>>::zero
<< " one=" << pTraits<std::remove_cv_t<T>>::one;
}
} }
template<class T>
typename std::enable_if<!has_zero_one<T>::value, void>::type
printMinMaxRange()
{}
template<class T> template<class T>
void printTraits() void printTraits()
@ -104,11 +118,12 @@ void printTraits()
printTypeName<T>(); printTypeName<T>();
printMinMaxRange<T>(); printMinMaxRange<T>();
Info<< " integral=" << std::is_integral<T>::value Info<< " integral=" << std::is_integral_v<T>
<< " floating=" << std::is_floating_point<T>::value << " floating=" << std::is_floating_point_v<T>
<< " rank=" << pTraits_rank<T>::value << " rank=" << pTraits_rank<T>::value
<< " nComponents=" << pTraits_nComponents<T>::value << " nComponents=" << pTraits_nComponents<T>::value
<< " vector-space=" << Switch::name(is_vectorspace<T>::value) << " vector-space=" << Switch::name(is_vectorspace_v<T>)
<< " rotate=" << Switch::name(is_rotational_vectorspace_v<T>)
<< " is_label=" << Switch::name(is_contiguous_label<T>::value) << " is_label=" << Switch::name(is_contiguous_label<T>::value)
<< " is_scalar=" << Switch::name(is_contiguous_scalar<T>::value) << " is_scalar=" << Switch::name(is_contiguous_scalar<T>::value)
<< " cmptType=" << typeid(typename pTraits_cmptType<T>::type).name() << " cmptType=" << typeid(typename pTraits_cmptType<T>::type).name()
@ -137,9 +152,11 @@ int main()
printTraits<bool>(); printTraits<bool>();
printTraits<label>(); printTraits<label>();
printTraits<scalar>(); printTraits<scalar>();
printTraits<complex>(); // Uses specialized pTraits_... printTraits<const complex>(); // Uses specialized pTraits_...
printTraits<floatVector>(); printTraits<floatVector>();
printTraits<doubleVector>(); printTraits<doubleVector>();
printTraits<sphericalTensor>();
printTraits<symmTensor>();
printTraits<tensor>(); printTraits<tensor>();
printTraits<boolVector>(); // Uses specialized pTraits_... printTraits<boolVector>(); // Uses specialized pTraits_...
printTraits<word>(); printTraits<word>();

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2022 OpenCFD Ltd. Copyright (C) 2022-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -46,7 +46,7 @@ using namespace Foam;
template<class T> template<class T>
void printPre(const T& value) void printPre(const T& value)
{ {
Info<< nl << "is_contiguous:" << is_contiguous<T>::value << endl; Info<< nl << "is_contiguous:" << is_contiguous_v<T> << endl;
Pout<< "pre-broadcast: " << value << endl; Pout<< "pre-broadcast: " << value << endl;
} }
@ -68,7 +68,7 @@ void testBroadcast(T& value)
template<class T> template<class T>
void testBroadcast(List<T>& values) void testBroadcast(List<T>& values)
{ {
Info<< nl << "is_contiguous:" << is_contiguous<T>::value << endl; Info<< nl << "is_contiguous:" << is_contiguous_v<T> << endl;
Pout<< "pre-broadcast: " << flatOutput(values) << endl; Pout<< "pre-broadcast: " << flatOutput(values) << endl;
Pstream::broadcast(values); Pstream::broadcast(values);
Pout<< "post-broadcast: " << flatOutput(values) << endl; Pout<< "post-broadcast: " << flatOutput(values) << endl;

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2022-2024 OpenCFD Ltd. Copyright (C) 2022-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -44,55 +44,17 @@ Description
using namespace Foam; using namespace Foam;
//- Number of elements corresponding to max byte transfer.
// Normal upper limit is INT_MAX since MPI sizes are limited to <int>.
template<class Type>
inline std::size_t maxTransferCount
(
const std::size_t max_bytes = std::size_t(0)
) noexcept
{
return
(
(max_bytes == 0) // ie, unlimited
? (std::size_t(0)) //
: (max_bytes > std::size_t(INT_MAX)) // MPI limit is <int>
? (std::size_t(INT_MAX) / sizeof(Type)) //
: (max_bytes > sizeof(Type)) // require an integral number
? (max_bytes / sizeof(Type)) //
: (std::size_t(1)) // min of one element
);
}
//- Upper limit on number of transfer bytes.
// Max bytes is normally INT_MAX since MPI sizes are limited to <int>.
// Negative values indicate a subtraction from INT_MAX.
inline std::size_t PstreamDetail_maxTransferBytes
(
const int64_t max_bytes
) noexcept
{
return
(
(max_bytes < 0) // (numBytes fewer than INT_MAX)
? std::size_t(INT_MAX + max_bytes)
: std::size_t(max_bytes)
);
}
template<class Container, class Type> template<class Container, class Type>
void broadcast_chunks void broadcast_chunks
( (
Container& sendData, Container& sendData,
const int tag = UPstream::msgType(), const int tag = UPstream::msgType(),
const label comm = UPstream::worldComm const label comm = UPstream::worldComm,
const int64_t maxComms_bytes = UPstream::maxCommsSize const int64_t maxComms_bytes = UPstream::maxCommsSize
) )
{ {
// OR static_assert(is_contiguous<T>::value, "Contiguous data only!") // OR static_assert(is_contiguous_v<Type>, "Contiguous data only!")
if (!is_contiguous<Type>::value) if constexpr (!is_contiguous_v<Type>)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Contiguous data only." << sizeof(Type) << "Contiguous data only." << sizeof(Type)
@ -119,9 +81,9 @@ void broadcast_chunks
// Is zero for non-chunked exchanges. // Is zero for non-chunked exchanges.
const std::size_t chunkSize const std::size_t chunkSize
( (
PstreamDetail_maxTransferCount<Type> PstreamDetail::maxTransferCount<Type>
( (
PstreamDetail_maxTransferBytes(maxComms_bytes) PstreamDetail::maxTransferBytes(maxComms_bytes)
) )
); );

View File

@ -7,6 +7,7 @@ EXE_INC = \
EXE_LIBS = \ EXE_LIBS = \
-lfiniteVolume \ -lfiniteVolume \
-lmeshTools \
-ldynamicFvMesh \ -ldynamicFvMesh \
-lsampling \ -lsampling \
-loverset -loverset

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2020-2023 OpenCFD Ltd. Copyright (C) 2020-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM, distributed under GPL-3.0-or-later. This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
@ -36,13 +36,13 @@ template<class T>
void constructInfo() void constructInfo()
{ {
Info<< " move-constructible:" Info<< " move-constructible:"
<< std::is_move_constructible<T>::value << std::is_move_constructible_v<T>
<< " move-assignable:" << " move-assignable:"
<< std::is_move_assignable<T>::value << std::is_move_assignable_v<T>
<< " nothrow:" << " nothrow:"
<< std::is_nothrow_move_assignable<T>::value << std::is_nothrow_move_assignable_v<T>
<< " trivially:" << " trivially:"
<< std::is_trivially_move_assignable<T>::value << std::is_trivially_move_assignable_v<T>
<< nl; << nl;
} }

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2017-2021 OpenCFD Ltd. Copyright (C) 2017-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -322,12 +322,12 @@ int main(int argc, char *argv[])
Info<< "_GLIBCXX_RELEASE = " << (_GLIBCXX_RELEASE) << nl; Info<< "_GLIBCXX_RELEASE = " << (_GLIBCXX_RELEASE) << nl;
#endif #endif
if (std::is_same<regExp, regExpCxx>::value) if constexpr (std::is_same_v<regExp, regExpCxx>)
{ {
Info<< "Foam::regExp uses C++11 regex" << nl; Info<< "Foam::regExp uses C++11 regex" << nl;
} }
#ifndef _WIN32 #ifndef _WIN32
if (std::is_same<regExp, regExpPosix>::value) if constexpr (std::is_same_v<regExp, regExpPosix>)
{ {
Info<< "Foam::regExp uses POSIX regex" << nl; Info<< "Foam::regExp uses POSIX regex" << nl;
} }

View File

@ -53,6 +53,27 @@ namespace Foam
{} {}
}; };
// Test compilation with static_assert workaround
// (workaround before CWG2518)
template<class T>
inline unsigned sizeof_float()
{
if constexpr (std::is_floating_point_v<T>)
{
return sizeof(T);
}
else
{
// static_assert(false, "only use for floats");
static_assert
(
stdFoam::dependent_false_v<T>,
"only use for floats"
);
return 0u;
}
}
} }

View File

@ -2,4 +2,4 @@ EXE_INC = \
-I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/mesh/blockMesh/lnInclude -I$(LIB_SRC)/mesh/blockMesh/lnInclude
EXE_LIBS = -lblockMesh EXE_LIBS = -lblockMesh -lmeshTools

View File

@ -3,4 +3,5 @@ EXE_INC = \
-I$(LIB_SRC)/surfMesh/lnInclude -I$(LIB_SRC)/surfMesh/lnInclude
EXE_LIBS = \ EXE_LIBS = \
-lfileFormats \
-lsurfMesh -lsurfMesh

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2018-2023 OpenCFD Ltd. Copyright (C) 2018-2024 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM, distributed under GPL-3.0-or-later. This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
@ -45,13 +45,13 @@ void printInfo(const tmp<T>& item, const bool verbose = false)
} }
Info<< " move-constructible:" Info<< " move-constructible:"
<< std::is_move_constructible<tmp<T>>::value << std::is_move_constructible_v<tmp<T>>
<< " move-assignable:" << " move-assignable:"
<< std::is_move_assignable<tmp<T>>::value << std::is_move_assignable_v<tmp<T>>
<< " nothrow:" << " nothrow:"
<< std::is_nothrow_move_assignable<tmp<T>>::value << std::is_nothrow_move_assignable_v<tmp<T>>
<< " trivially:" << " trivially:"
<< std::is_trivially_move_assignable<tmp<T>>::value << std::is_trivially_move_assignable_v<tmp<T>>
<< nl; << nl;
if (verbose && item) if (verbose && item)

View File

@ -231,7 +231,7 @@ int main(int argc, char *argv[])
Info<< nl Info<< nl
<< "solverPerformanceDict: " << "solverPerformanceDict: "
<< mesh.solverPerformanceDict() << endl; << mesh.data().solverPerformanceDict() << endl;
if (args.found("zip")) if (args.found("zip"))

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2023 OpenCFD Ltd. Copyright (C) 2016-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -232,7 +232,7 @@ vtk::outputOptions getOutputOptions(const argList& args)
if (!args.found("ascii")) if (!args.found("ascii"))
{ {
if (sizeof(float) != 4 || sizeof(label) != 4) if constexpr (sizeof(float) != 4 || sizeof(label) != 4)
{ {
opts.ascii(true); opts.ascii(true);

View File

@ -137,15 +137,11 @@ cd $WM_THIRD_PARTY_DIR
Subequent compilation with Allwmake will now run largely without any Subequent compilation with Allwmake will now run largely without any
problems, except that the components linking against CGAL problems, except that the components linking against CGAL
(foamyMesh and surfaceBooleanFeatures) will also try to link against (foamyMesh and surfaceBooleanFeatures) will also try to link against
a nonexistent mpfr library. As a workaround, the link-dependency can a nonexistent mpfr library. As a workaround, the link-dependency will
be removed in wmake/rules/General/CGAL : be removed in wmake/rules/General/cgal by specifying the `CGAL_FLAVOUR`
when compiling:
``` ```
CGAL_LIBS = \ no-cgal | cgal-header | cgal-header-no-mpfr | cgal-no-mpfr | cgal-mpfr
-L$(BOOST_ARCH_PATH)/lib \
-L$(BOOST_ARCH_PATH)/lib$(WM_COMPILER_LIB_ARCH) \
-L$(CGAL_ARCH_PATH)/lib \
-L$(CGAL_ARCH_PATH)/lib$(WM_COMPILER_LIB_ARCH) \
-lCGAL
``` ```
A robuster solution is still being sought. A robuster solution is still being sought.

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2018-2023 OpenCFD Ltd. Copyright (C) 2018-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -188,12 +188,12 @@ Foam::PackedList<Width>::unpack() const
{ {
static_assert static_assert
( (
std::is_integral<IntType>::value, std::is_integral_v<IntType>,
"Integral required for output." "Integral required for output."
); );
static_assert static_assert
( (
std::numeric_limits<IntType>::digits >= Width, Width < std::numeric_limits<IntType>::digits,
"Width of IntType is too small to hold result" "Width of IntType is too small to hold result"
); );
@ -244,12 +244,12 @@ Foam::PackedList<Width>::unpack(const labelRange& range) const
{ {
static_assert static_assert
( (
std::is_integral<IntType>::value, std::is_integral_v<IntType>,
"Integral required for unpack output." "Integral required for unpack output."
); );
static_assert static_assert
( (
std::numeric_limits<IntType>::digits >= Width, Width < std::numeric_limits<IntType>::digits,
"Width of IntType is too small to hold unpack output." "Width of IntType is too small to hold unpack output."
); );
@ -278,12 +278,12 @@ Foam::PackedList<Width>::unpack(const labelUList& locations) const
{ {
static_assert static_assert
( (
std::is_integral<IntType>::value, std::is_integral_v<IntType>,
"Integral required for unpack output." "Integral required for unpack output."
); );
static_assert static_assert
( (
std::numeric_limits<IntType>::digits >= Width, Width < std::numeric_limits<IntType>::digits,
"Width of IntType is too small to hold unpack output." "Width of IntType is too small to hold unpack output."
); );

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2023 OpenCFD Ltd. Copyright (C) 2017-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -648,7 +648,7 @@ inline std::streamsize Foam::PackedList<Width>::size_data() const noexcept
template<unsigned Width> template<unsigned Width>
inline std::streamsize Foam::PackedList<Width>::size_bytes() const noexcept inline std::streamsize Foam::PackedList<Width>::size_bytes() const noexcept
{ {
return num_blocks(size()) * sizeof(block_type); return size_data() * sizeof(block_type);
} }

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2022-2023 OpenCFD Ltd. Copyright (C) 2022-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -103,7 +103,7 @@ Foam::Ostream& Foam::CircularBuffer<T>::writeList
} }
#endif #endif
if (os.format() == IOstreamOption::BINARY && is_contiguous<T>::value) if (os.format() == IOstreamOption::BINARY && is_contiguous_v<T>)
{ {
// Binary and contiguous // Binary and contiguous
@ -136,11 +136,7 @@ Foam::Ostream& Foam::CircularBuffer<T>::writeList
|| ||
( (
(len <= shortLen) (len <= shortLen)
&& && (is_contiguous_v<T> || Detail::ListPolicy::no_linebreak<T>::value)
(
is_contiguous<T>::value
|| Detail::ListPolicy::no_linebreak<T>::value
)
) )
) )
{ {

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2012-2015 OpenFOAM Foundation Copyright (C) 2012-2015 OpenFOAM Foundation
Copyright (C) 2022 OpenCFD Ltd. Copyright (C) 2022-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -120,20 +120,20 @@ public:
using difference_type = typename Container::difference_type; using difference_type = typename Container::difference_type;
//- The container iterator type (const/non-const) //- The container iterator type (const/non-const)
using iterator = typename std::conditional using iterator = std::conditional_t
< <
Const, Const,
typename Container::const_iterator, typename Container::const_iterator,
typename Container::iterator typename Container::iterator
>::type; >;
//- The reference type (const/non-const) //- The reference type (const/non-const)
using reference = typename std::conditional using reference = std::conditional_t
< <
Const, Const,
typename Container::const_reference, typename Container::const_reference,
typename Container::reference typename Container::reference
>::type; >;
private: private:

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019-2023 OpenCFD Ltd. Copyright (C) 2019-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -254,11 +254,11 @@ Foam::label Foam::CompactListList<T>::maxNonLocalSize(const label rowi) const
template<class T> template<class T>
std::streamsize Foam::CompactListList<T>::byteSize() const std::streamsize Foam::CompactListList<T>::byteSize() const
{ {
if (!is_contiguous<T>::value) if constexpr (!is_contiguous_v<T>)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Invalid for non-contiguous data types" << "Invalid for non-contiguous data types"
<< abort(FatalError); << Foam::abort(FatalError);
} }
return this->size_bytes(); return this->size_bytes();
} }

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2024 OpenCFD Ltd. Copyright (C) 2017-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -136,12 +136,12 @@ public:
//- A table entry (node) that encapsulates the key/val tuple //- A table entry (node) that encapsulates the key/val tuple
//- with an additional linked-list entry for hash collisions //- with an additional linked-list entry for hash collisions
typedef typename std::conditional using node_type = std::conditional_t
< <
std::is_same<Foam::zero, typename std::remove_cv<T>::type>::value, std::is_same_v<Foam::zero, std::remove_cv_t<T>>,
Detail::HashTableSingle<Key>, Detail::HashTableSingle<Key>,
Detail::HashTablePair<Key, T> Detail::HashTablePair<Key, T>
>::type node_type; >;
// STL type definitions // STL type definitions
@ -652,31 +652,31 @@ protected:
using difference_type = this_type::difference_type; using difference_type = this_type::difference_type;
//- The HashTable container type //- The HashTable container type
using table_type = typename std::conditional using table_type = std::conditional_t
< <
Const, Const,
const this_type, const this_type,
this_type this_type
>::type; >;
//- The node-type being addressed //- The node-type being addressed
using node_type = typename std::conditional using node_type = std::conditional_t
< <
Const, Const,
const this_type::node_type, const this_type::node_type,
this_type::node_type this_type::node_type
>::type; >;
//- The key type //- The key type
using key_type = this_type::key_type; using key_type = this_type::key_type;
//- The object type being addressed //- The object type being addressed
using mapped_type = typename std::conditional using mapped_type = std::conditional_t
< <
Const, Const,
const this_type::mapped_type, const this_type::mapped_type,
this_type::mapped_type this_type::mapped_type
>::type; >;
protected: protected:

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2019-2023 OpenCFD Ltd. Copyright (C) 2019-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -165,39 +165,28 @@ struct HashTablePair
return key_ < rhs.key_; return key_ < rhs.key_;
} }
//- Write (key, val) pair - for pointer types //- Write (key, val) pair
template<class TypeT = V> void print(Ostream& os) const
typename std::enable_if
<
(
std::is_pointer<TypeT>::value
|| Detail::isPointerLike<TypeT>::value
),
void
>::type
print(Ostream& os) const
{ {
os << key_; os << key_;
if (val_) if constexpr
{
os << ' ' << *val_;
}
}
//- Write (key, val) pair - for non-pointer types
template<class TypeT = V>
typename std::enable_if
<
( (
!std::is_pointer<TypeT>::value std::is_pointer_v<V>
&& !Detail::isPointerLike<TypeT>::value || Detail::isPointerLike<V>::value
), )
void {
>::type // Pointer or pointer-like types
print(Ostream& os) const if (val_)
{ {
os << key_ << ' ' << val_; os << ' ' << *val_;
}
}
else
{
// Non-pointer types
os << ' ' << val_;
}
} }
}; };

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2014 OpenFOAM Foundation Copyright (C) 2011-2014 OpenFOAM Foundation
Copyright (C) 2016-2022 OpenCFD Ltd. Copyright (C) 2016-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -44,7 +44,7 @@ Foam::Ostream& Foam::IndirectListBase<T, Addr>::writeList
const label len = list.size(); const label len = list.size();
if (os.format() == IOstreamOption::BINARY && is_contiguous<T>::value) if (os.format() == IOstreamOption::BINARY && is_contiguous_v<T>)
{ {
// Binary and contiguous // Binary and contiguous
os << nl << len << nl; os << nl << len << nl;
@ -69,7 +69,7 @@ Foam::Ostream& Foam::IndirectListBase<T, Addr>::writeList
os.endRawWrite(); os.endRawWrite();
} }
} }
else if (is_contiguous<T>::value && len > 1 && list.uniform()) else if (is_contiguous_v<T> && len > 1 && list.uniform())
{ {
// Two or more entries, and all entries have identical values. // Two or more entries, and all entries have identical values.
os << len << token::BEGIN_BLOCK << list[0] << token::END_BLOCK; os << len << token::BEGIN_BLOCK << list[0] << token::END_BLOCK;
@ -80,11 +80,7 @@ Foam::Ostream& Foam::IndirectListBase<T, Addr>::writeList
|| ||
( (
(len <= shortLen) (len <= shortLen)
&& && (is_contiguous_v<T> || Detail::ListPolicy::no_linebreak<T>::value)
(
is_contiguous<T>::value
|| Detail::ListPolicy::no_linebreak<T>::value
)
) )
) )
{ {

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2021-2023 OpenCFD Ltd. Copyright (C) 2021-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -202,7 +202,7 @@ Foam::Istream& Foam::DynamicList<T, SizeMin>::readList(Istream& is)
// Resize to length required // Resize to length required
list.resize_nocopy(len); list.resize_nocopy(len);
if (is.format() == IOstreamOption::BINARY && is_contiguous<T>::value) if (is.format() == IOstreamOption::BINARY && is_contiguous_v<T>)
{ {
// Binary and contiguous // Binary and contiguous
@ -222,7 +222,7 @@ Foam::Istream& Foam::DynamicList<T, SizeMin>::readList(Istream& is)
); );
} }
} }
else if (std::is_same<char, typename std::remove_cv<T>::type>::value) else if constexpr (std::is_same_v<char, std::remove_cv_t<T>>)
{ {
// Special treatment for char data (binary I/O only) // Special treatment for char data (binary I/O only)
const auto oldFmt = is.format(IOstreamOption::BINARY); const auto oldFmt = is.format(IOstreamOption::BINARY);

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2017-2023 OpenCFD Ltd. Copyright (C) 2017-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -33,11 +33,11 @@ License
template<class T, unsigned N> template<class T, unsigned N>
std::streamsize Foam::FixedList<T, N>::byteSize() std::streamsize Foam::FixedList<T, N>::byteSize()
{ {
if (!is_contiguous<T>::value) if constexpr (!is_contiguous_v<T>)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Invalid for non-contiguous data types" << "Invalid for non-contiguous data types"
<< abort(FatalError); << Foam::abort(FatalError);
} }
return FixedList<T, N>::size_bytes(); return FixedList<T, N>::size_bytes();
} }

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2023 OpenCFD Ltd. Copyright (C) 2017-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -497,17 +497,19 @@ public:
unsigned seed=0 unsigned seed=0
) const ) const
{ {
if (is_contiguous<T>::value) if constexpr (is_contiguous_v<T>)
{ {
return Foam::Hasher(obj.cdata(), obj.size_bytes(), seed); return Foam::Hasher(obj.cdata(), obj.size_bytes(), seed);
} }
else
Foam::Hash<T> op;
for (const T& val : obj)
{ {
seed = op(val, seed); Foam::Hash<T> op;
for (const T& val : obj)
{
seed = op(val, seed);
}
return seed;
} }
return seed;
} }
}; };

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2022 OpenCFD Ltd. Copyright (C) 2017-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -40,10 +40,13 @@ void Foam::FixedList<T, N>::writeEntry(Ostream& os) const
if (token::compound::isCompound(tag)) if (token::compound::isCompound(tag))
{ {
os << tag << token::SPACE; os << tag << token::SPACE;
if (os.format() == IOstreamOption::BINARY && is_contiguous<T>::value) if constexpr (is_contiguous_v<T>)
{ {
// Need the size too so that List<Type>::readList parses correctly if (os.format() == IOstreamOption::BINARY)
os << static_cast<label>(N); {
// Need size too so that List<Type>::readList parses correctly
os << static_cast<label>(N);
}
} }
} }
os << *this; os << *this;
@ -90,7 +93,7 @@ Foam::Ostream& Foam::FixedList<T, N>::writeList
// small and we prefer a consistent appearance. // small and we prefer a consistent appearance.
// Eg, FixedList<T,2> or Pair<T> as "(-1 -1)", never as "2{-1}" // Eg, FixedList<T,2> or Pair<T> as "(-1 -1)", never as "2{-1}"
if (os.format() == IOstreamOption::BINARY && is_contiguous<T>::value) if (os.format() == IOstreamOption::BINARY && is_contiguous_v<T>)
{ {
// Binary and contiguous. Size is always non-zero // Binary and contiguous. Size is always non-zero
@ -103,11 +106,7 @@ Foam::Ostream& Foam::FixedList<T, N>::writeList
|| ||
( (
(N <= unsigned(shortLen)) (N <= unsigned(shortLen))
&& && (is_contiguous_v<T> || Detail::ListPolicy::no_linebreak<T>::value)
(
is_contiguous<T>::value
|| Detail::ListPolicy::no_linebreak<T>::value
)
) )
) )
{ {
@ -158,7 +157,7 @@ Foam::Istream& Foam::FixedList<T, N>::readList
is.fatalCheck(FUNCTION_NAME); is.fatalCheck(FUNCTION_NAME);
if (is.format() == IOstreamOption::BINARY && is_contiguous<T>::value) if (is.format() == IOstreamOption::BINARY && is_contiguous_v<T>)
{ {
// Binary and contiguous. Length is non-zero // Binary and contiguous. Length is non-zero

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2023 OpenCFD Ltd. Copyright (C) 2017-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -356,7 +356,7 @@ public:
// //
// \return True if value changed. // \return True if value changed.
template<class TypeT = T> template<class TypeT = T>
typename std::enable_if<std::is_same<bool, TypeT>::value, bool>::type std::enable_if_t<std::is_same_v<bool, TypeT>, bool>
inline set(const label i, bool val = true) inline set(const label i, bool val = true)
{ {
if (i < 0) if (i < 0)

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2018-2023 OpenCFD Ltd. Copyright (C) 2018-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -202,7 +202,7 @@ Foam::Istream& Foam::List<T>::readList(Istream& is)
// Resize to length required // Resize to length required
list.resize_nocopy(len); list.resize_nocopy(len);
if (is.format() == IOstreamOption::BINARY && is_contiguous<T>::value) if (is.format() == IOstreamOption::BINARY && is_contiguous_v<T>)
{ {
// Binary and contiguous // Binary and contiguous
@ -222,7 +222,7 @@ Foam::Istream& Foam::List<T>::readList(Istream& is)
); );
} }
} }
else if (std::is_same<char, typename std::remove_cv<T>::type>::value) else if constexpr (std::is_same_v<char, std::remove_cv_t<T>>)
{ {
// Special treatment for char data (binary I/O only) // Special treatment for char data (binary I/O only)
const auto oldFmt = is.format(IOstreamOption::BINARY); const auto oldFmt = is.format(IOstreamOption::BINARY);

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2023 OpenCFD Ltd. Copyright (C) 2017-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -166,11 +166,11 @@ void Foam::UList<T>::operator=(const Foam::zero)
template<class T> template<class T>
std::streamsize Foam::UList<T>::byteSize() const std::streamsize Foam::UList<T>::byteSize() const
{ {
if (!is_contiguous<T>::value) if constexpr (!is_contiguous_v<T>)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Invalid for non-contiguous data types" << "Invalid for non-contiguous data types"
<< abort(FatalError); << Foam::abort(FatalError);
} }
return this->size_bytes(); return this->size_bytes();
} }

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2023 OpenCFD Ltd. Copyright (C) 2017-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -555,7 +555,7 @@ public:
//- always false for out-of-range access. //- always false for out-of-range access.
// \note Method name compatibility with bitSet, HashSet // \note Method name compatibility with bitSet, HashSet
template<class TypeT = T> template<class TypeT = T>
typename std::enable_if<std::is_same<bool, TypeT>::value, bool>::type std::enable_if_t<std::is_same_v<bool, TypeT>, bool>
inline test(const label i) const inline test(const label i) const
{ {
return (i >= 0 && i < size_ && v_[i]); return (i >= 0 && i < size_ && v_[i]);
@ -565,7 +565,7 @@ public:
//- always false for out-of-range access. //- always false for out-of-range access.
// \note Method name compatibility with bitSet // \note Method name compatibility with bitSet
template<class TypeT = T> template<class TypeT = T>
typename std::enable_if<std::is_same<bool, TypeT>::value, bool>::type std::enable_if_t<std::is_same_v<bool, TypeT>, bool>
inline get(const label i) const inline get(const label i) const
{ {
return (i >= 0 && i < size_ && v_[i]); return (i >= 0 && i < size_ && v_[i]);
@ -576,7 +576,7 @@ public:
// \return True if value changed and was not out-of-range // \return True if value changed and was not out-of-range
// \note Method name compatibility with bitSet // \note Method name compatibility with bitSet
template<class TypeT = T> template<class TypeT = T>
typename std::enable_if<std::is_same<bool, TypeT>::value, bool>::type std::enable_if_t<std::is_same_v<bool, TypeT>, bool>
inline unset(const label i) inline unset(const label i)
{ {
if (i >= 0 && i < size_ && v_[i]) if (i >= 0 && i < size_ && v_[i])
@ -599,17 +599,19 @@ public:
unsigned seed=0 unsigned seed=0
) const ) const
{ {
if (is_contiguous<T>::value) if constexpr (is_contiguous_v<T>)
{ {
return Foam::Hasher(obj.cdata(), obj.size_bytes(), seed); return Foam::Hasher(obj.cdata(), obj.size_bytes(), seed);
} }
else
Foam::Hash<T> op;
for (const T& val : obj)
{ {
seed = op(val, seed); Foam::Hash<T> op;
for (const T& val : obj)
{
seed = op(val, seed);
}
return seed;
} }
return seed;
} }
}; };

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2015-2023 OpenCFD Ltd. Copyright (C) 2015-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -69,7 +69,7 @@ inline void Foam::UList<T>::fill_uniform(const Foam::zero)
// issues. // issues.
// May also have special triggers when assigning non-contiguous from zero... // May also have special triggers when assigning non-contiguous from zero...
if (is_contiguous<T>::value) if constexpr (is_contiguous_v<T>)
{ {
// Can dispatch with // Can dispatch with
// - std::execution::parallel_unsequenced_policy // - std::execution::parallel_unsequenced_policy

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2023 OpenCFD Ltd. Copyright (C) 2016-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -49,7 +49,7 @@ void Foam::UList<T>::writeEntry(Ostream& os) const
else if else if
( (
os.format() == IOstreamOption::BINARY os.format() == IOstreamOption::BINARY
|| std::is_same<char, typename std::remove_cv<T>::type>::value || std::is_same_v<char, std::remove_cv_t<T>>
) )
{ {
// Zero-sized binary - Write size only // Zero-sized binary - Write size only
@ -89,7 +89,7 @@ Foam::Ostream& Foam::UList<T>::writeList
const label len = list.size(); const label len = list.size();
if (os.format() == IOstreamOption::BINARY && is_contiguous<T>::value) if (os.format() == IOstreamOption::BINARY && is_contiguous_v<T>)
{ {
// Binary and contiguous // Binary and contiguous
@ -101,7 +101,7 @@ Foam::Ostream& Foam::UList<T>::writeList
os.write(list.cdata_bytes(), list.size_bytes()); os.write(list.cdata_bytes(), list.size_bytes());
} }
} }
else if (std::is_same<char, typename std::remove_cv<T>::type>::value) else if constexpr (std::is_same_v<char, std::remove_cv_t<T>>)
{ {
// Special treatment for char data (binary I/O only) // Special treatment for char data (binary I/O only)
@ -116,7 +116,7 @@ Foam::Ostream& Foam::UList<T>::writeList
os.format(oldFmt); os.format(oldFmt);
} }
else if (is_contiguous<T>::value && len > 1 && list.uniform()) else if (is_contiguous_v<T> && len > 1 && list.uniform())
{ {
// Two or more entries, and all entries have identical values. // Two or more entries, and all entries have identical values.
os << len << token::BEGIN_BLOCK << list[0] << token::END_BLOCK; os << len << token::BEGIN_BLOCK << list[0] << token::END_BLOCK;
@ -127,11 +127,7 @@ Foam::Ostream& Foam::UList<T>::writeList
|| ||
( (
(len <= shortLen) (len <= shortLen)
&& && (is_contiguous_v<T> || Detail::ListPolicy::no_linebreak<T>::value)
(
is_contiguous<T>::value
|| Detail::ListPolicy::no_linebreak<T>::value
)
) )
) )
{ {
@ -234,7 +230,7 @@ Foam::Istream& Foam::UList<T>::readList(Istream& is)
<< exit(FatalIOError); << exit(FatalIOError);
} }
if (is.format() == IOstreamOption::BINARY && is_contiguous<T>::value) if (is.format() == IOstreamOption::BINARY && is_contiguous_v<T>)
{ {
// Binary and contiguous // Binary and contiguous
@ -254,7 +250,7 @@ Foam::Istream& Foam::UList<T>::readList(Istream& is)
); );
} }
} }
else if (std::is_same<char, typename std::remove_cv<T>::type>::value) else if constexpr (std::is_same_v<char, std::remove_cv_t<T>>)
{ {
// Special treatment for char data (binary I/O only) // Special treatment for char data (binary I/O only)
const auto oldFmt = is.format(IOstreamOption::BINARY); const auto oldFmt = is.format(IOstreamOption::BINARY);

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2019-2023 OpenCFD Ltd. Copyright (C) 2019-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -72,7 +72,7 @@ struct short_length : std::integral_constant<int,10> {};
// Default definition: (integral | floating-point) are contiguous and thus // Default definition: (integral | floating-point) are contiguous and thus
// never need any line breaks // never need any line breaks
template<class T> template<class T>
struct no_linebreak : std::is_arithmetic<T> {}; struct no_linebreak : std::is_arithmetic<std::remove_cv_t<T>> {};
// Specialization for word-like classes // Specialization for word-like classes
// These elements are normally fairly short, so ok to output a few (eg, 10) // These elements are normally fairly short, so ok to output a few (eg, 10)

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2018-2024 OpenCFD Ltd. Copyright (C) 2018-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -413,12 +413,8 @@ protected:
// Typedefs // Typedefs
//- The list container type //- The list container type
using list_type = typename std::conditional using list_type =
< std::conditional_t<Const, const UPtrList<T>, UPtrList<T>>;
Const,
const UPtrList<T>,
UPtrList<T>
>::type;
protected: protected:

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2015-2017 OpenFOAM Foundation Copyright (C) 2015-2017 OpenFOAM Foundation
Copyright (C) 2016-2023 OpenCFD Ltd. Copyright (C) 2016-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -56,12 +56,14 @@ bool Foam::IOobject::typeHeaderOk
template<class Type> template<class Type>
Foam::fileName Foam::IOobject::typeFilePath(const bool search) const Foam::fileName Foam::IOobject::typeFilePath(const bool search) const
{ {
return if constexpr (is_globalIOobject<Type>::value)
( {
is_globalIOobject<Type>::value return this->globalFilePath(Type::typeName, search);
? this->globalFilePath(Type::typeName, search) }
: this->localFilePath(Type::typeName, search) else
); {
return this->localFilePath(Type::typeName, search);
}
} }

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2018-2024 OpenCFD Ltd. Copyright (C) 2018-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -300,7 +300,7 @@ public:
//- Check if the label byte-size associated with the stream //- Check if the label byte-size associated with the stream
//- is the same as the given type //- is the same as the given type
template<class T = label> template<class T = label>
typename std::enable_if<std::is_integral<T>::value, bool>::type std::enable_if_t<std::is_integral_v<T>, bool>
checkLabelSize() const noexcept checkLabelSize() const noexcept
{ {
return sizeofLabel_ == sizeof(T); return sizeofLabel_ == sizeof(T);
@ -309,7 +309,7 @@ public:
//- Check if the scalar byte-size associated with the stream //- Check if the scalar byte-size associated with the stream
//- is the same as the given type //- is the same as the given type
template<class T = scalar> template<class T = scalar>
typename std::enable_if<std::is_floating_point<T>::value, bool>::type std::enable_if_t<std::is_floating_point_v<T>, bool>
checkScalarSize() const noexcept checkScalarSize() const noexcept
{ {
return sizeofScalar_ == sizeof(T); return sizeofScalar_ == sizeof(T);
@ -515,26 +515,26 @@ protected:
namespace Detail namespace Detail
{ {
//- Termination for input looping (no-op)
template<class IS> inline void inputLoop(IS&) {}
//- Termination for output looping (no-op)
template<class OS> inline void outputLoop(OS&) {}
//- Input looping. Read into first parameter and recurse. //- Input looping. Read into first parameter and recurse.
template<class IS, class Type, class... Args> template<class IS, class Type, class... Args>
inline void inputLoop(IS& is, Type& arg1, Args&&... args) void inputLoop(IS& is, Type& arg1, Args&&... args)
{ {
is >> arg1; is >> arg1;
Detail::inputLoop(is, std::forward<Args>(args)...); if constexpr (sizeof...(args))
{
Detail::inputLoop(is, std::forward<Args>(args)...);
}
} }
//- Output looping. Write first parameter and recurse. //- Output looping. Write first parameter and recurse.
template<class OS, class Type, class... Args> template<class OS, class Type, class... Args>
inline void outputLoop(OS& os, const Type& arg1, Args&&... args) void outputLoop(OS& os, const Type& arg1, Args&&... args)
{ {
os << arg1; os << arg1;
Detail::outputLoop(os, std::forward<Args>(args)...); if constexpr (sizeof...(args))
{
Detail::outputLoop(os, std::forward<Args>(args)...);
}
} }
} // End namespace Detail } // End namespace Detail

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2023 OpenCFD Ltd. Copyright (C) 2017-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -237,7 +237,7 @@ namespace Detail
{ {
is.beginRawRead(); is.beginRawRead();
if (is_contiguous_label<T>::value) if constexpr (is_contiguous_label<T>::value)
{ {
readRawLabel readRawLabel
( (
@ -246,7 +246,7 @@ namespace Detail
byteCount/sizeof(label) byteCount/sizeof(label)
); );
} }
else if (is_contiguous_scalar<T>::value) else if constexpr (is_contiguous_scalar<T>::value)
{ {
readRawScalar readRawScalar
( (

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2022-2024 OpenCFD Ltd. Copyright (C) 2022-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -34,7 +34,7 @@ License
template<class Type> template<class Type>
void Foam::Pstream::broadcast(Type& value, const label comm) void Foam::Pstream::broadcast(Type& value, const label comm)
{ {
if (is_contiguous<Type>::value) if constexpr (is_contiguous_v<Type>)
{ {
// Note: contains parallel guard internally // Note: contains parallel guard internally
UPstream::broadcast UPstream::broadcast
@ -82,7 +82,7 @@ void Foam::Pstream::broadcasts(const label comm, Type& arg1, Args&&... args)
template<class ListType> template<class ListType>
void Foam::Pstream::broadcastList(ListType& list, const label comm) void Foam::Pstream::broadcastList(ListType& list, const label comm)
{ {
if (is_contiguous<typename ListType::value_type>::value) if constexpr (is_contiguous_v<typename ListType::value_type>)
{ {
// List data are contiguous // List data are contiguous
// 1. broadcast the size // 1. broadcast the size

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2019-2024 OpenCFD Ltd. Copyright (C) 2019-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -62,7 +62,7 @@ void Foam::Pstream::combineGather
// Receive from my downstairs neighbours // Receive from my downstairs neighbours
for (const label belowID : myComm.below()) for (const label belowID : myComm.below())
{ {
if (is_contiguous<T>::value) if constexpr (is_contiguous_v<T>)
{ {
T received; T received;
@ -115,7 +115,7 @@ void Foam::Pstream::combineGather
<< " data:" << value << endl; << " data:" << value << endl;
} }
if (is_contiguous<T>::value) if constexpr (is_contiguous_v<T>)
{ {
UOPstream::write UOPstream::write
( (
@ -174,7 +174,7 @@ void Foam::Pstream::listCombineGather
// Receive from my downstairs neighbours // Receive from my downstairs neighbours
for (const label belowID : myComm.below()) for (const label belowID : myComm.below())
{ {
if (is_contiguous<T>::value) if constexpr (is_contiguous_v<T>)
{ {
List<T> received(values.size()); List<T> received(values.size());
@ -233,7 +233,7 @@ void Foam::Pstream::listCombineGather
<< " data:" << values << endl; << " data:" << values << endl;
} }
if (is_contiguous<T>::value) if constexpr (is_contiguous_v<T>)
{ {
UOPstream::write UOPstream::write
( (

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2024 OpenCFD Ltd. Copyright (C) 2016-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -631,7 +631,7 @@ void Foam::Pstream::exchange
const bool wait const bool wait
) )
{ {
static_assert(is_contiguous<Type>::value, "Contiguous data only!"); static_assert(is_contiguous_v<Type>, "Contiguous data only!");
if (!UPstream::is_rank(comm)) if (!UPstream::is_rank(comm))
{ {
@ -695,7 +695,7 @@ void Foam::Pstream::exchange
const bool wait const bool wait
) )
{ {
static_assert(is_contiguous<Type>::value, "Contiguous data only!"); static_assert(is_contiguous_v<Type>, "Contiguous data only!");
const int myProci = UPstream::myProcNo(comm); const int myProci = UPstream::myProcNo(comm);

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2023-2024 OpenCFD Ltd. Copyright (C) 2023-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -70,7 +70,7 @@ void exchangeConsensus
const label comm const label comm
) )
{ {
static_assert(is_contiguous<Type>::value, "Contiguous data only!"); static_assert(is_contiguous_v<Type>, "Contiguous data only!");
const bool initialBarrier = (UPstream::tuning_NBX_ > 0); const bool initialBarrier = (UPstream::tuning_NBX_ > 0);
@ -252,7 +252,7 @@ void exchangeConsensus
const label comm const label comm
) )
{ {
static_assert(is_contiguous<Type>::value, "Contiguous data only!"); static_assert(is_contiguous_v<Type>, "Contiguous data only!");
const bool initialBarrier = (UPstream::tuning_NBX_ > 0); const bool initialBarrier = (UPstream::tuning_NBX_ > 0);
@ -419,7 +419,7 @@ void Foam::Pstream::exchangeConsensus
const bool /* wait (ignored) */ const bool /* wait (ignored) */
) )
{ {
static_assert(is_contiguous<Type>::value, "Contiguous data only!"); static_assert(is_contiguous_v<Type>, "Contiguous data only!");
if (sendBufs.size() != UPstream::nProcs(comm)) if (sendBufs.size() != UPstream::nProcs(comm))
{ {
@ -454,7 +454,7 @@ void Foam::Pstream::exchangeConsensus
const bool /* wait (ignored) */ const bool /* wait (ignored) */
) )
{ {
static_assert(is_contiguous<Type>::value, "Contiguous data only!"); static_assert(is_contiguous_v<Type>, "Contiguous data only!");
PstreamDetail::exchangeConsensus<Container, Type> PstreamDetail::exchangeConsensus<Container, Type>
( (
@ -478,7 +478,7 @@ Foam::Pstream::exchangeConsensus
{ {
Map<Container> recvBufs; Map<Container> recvBufs;
static_assert(is_contiguous<Type>::value, "Contiguous data only!"); static_assert(is_contiguous_v<Type>, "Contiguous data only!");
PstreamDetail::exchangeConsensus<Container, Type> PstreamDetail::exchangeConsensus<Container, Type>
( (

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2019-2024 OpenCFD Ltd. Copyright (C) 2019-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -59,7 +59,7 @@ void Foam::Pstream::gather
{ {
T received; T received;
if (is_contiguous<T>::value) if constexpr (is_contiguous_v<T>)
{ {
UIPstream::read UIPstream::read
( (
@ -82,7 +82,7 @@ void Foam::Pstream::gather
// Send up value // Send up value
if (myComm.above() >= 0) if (myComm.above() >= 0)
{ {
if (is_contiguous<T>::value) if constexpr (is_contiguous_v<T>)
{ {
UOPstream::write UOPstream::write
( (
@ -108,43 +108,29 @@ Foam::List<T> Foam::Pstream::listGatherValues
( (
const T& localValue, const T& localValue,
const label comm, const label comm,
const int tag [[maybe_unused]] const int tag
) )
{ {
// OR if constexpr (is_contiguous_v<T>)
// if (is_contiguous<T>::value)
// {
// return UPstream::listGatherValues(localValue, comm);
// }
List<T> allValues;
if (UPstream::is_parallel(comm))
{ {
const label numProc = UPstream::nProcs(comm); // UPstream version is contiguous only
return UPstream::listGatherValues(localValue, comm);
}
else
{
List<T> allValues;
if (UPstream::master(comm)) if (UPstream::is_parallel(comm))
{ {
allValues.resize(numProc); const label numProc = UPstream::nProcs(comm);
}
if (is_contiguous<T>::value)
{
UPstream::mpiGather
(
reinterpret_cast<const char*>(&localValue),
allValues.data_bytes(),
sizeof(T), // The send/recv size per rank
comm
);
}
else
{
if (UPstream::master(comm)) if (UPstream::master(comm))
{ {
allValues.resize(numProc);
// Non-trivial to manage non-blocking gather without a // Non-trivial to manage non-blocking gather without a
// PEX/NBX approach (eg, PstreamBuffers) but leave with // PEX/NBX approach (eg, PstreamBuffers).
// with simple exchange for now // Leave with simple exchange for now
allValues[0] = localValue; allValues[0] = localValue;
@ -158,16 +144,16 @@ Foam::List<T> Foam::Pstream::listGatherValues
OPstream::send(localValue, UPstream::masterNo(), tag, comm); OPstream::send(localValue, UPstream::masterNo(), tag, comm);
} }
} }
} else
else {
{ // non-parallel: return own value
// non-parallel: return own value // TBD: only when UPstream::is_rank(comm) as well?
// TBD: only when UPstream::is_rank(comm) as well? allValues.resize(1);
allValues.resize(1); allValues[0] = localValue;
allValues[0] = localValue; }
}
return allValues; return allValues;
}
} }
@ -176,85 +162,73 @@ T Foam::Pstream::listScatterValues
( (
const UList<T>& allValues, const UList<T>& allValues,
const label comm, const label comm,
const int tag [[maybe_unused]] const int tag
) )
{ {
// OR if constexpr (is_contiguous_v<T>)
// if (is_contiguous<T>::value)
// {
// return UPstream::listScatterValues(allValues, comm);
// }
T localValue{};
if (UPstream::is_parallel(comm))
{ {
const label numProc = UPstream::nProcs(comm); // UPstream version is contiguous only
return UPstream::listScatterValues(allValues, comm);
if (UPstream::master(comm) && allValues.size() < numProc)
{
FatalErrorInFunction
<< "Attempting to send " << allValues.size()
<< " values to " << numProc << " processors" << endl
<< Foam::abort(FatalError);
}
if (is_contiguous<T>::value)
{
UPstream::mpiScatter
(
allValues.cdata_bytes(),
reinterpret_cast<char*>(&localValue),
sizeof(T), // The send/recv size per rank
comm
);
}
else
{
if (UPstream::master(comm))
{
const label startOfRequests = UPstream::nRequests();
List<DynamicList<char>> sendBuffers(numProc);
for (int proci = 1; proci < numProc; ++proci)
{
UOPstream toProc
(
UPstream::commsTypes::nonBlocking,
proci,
sendBuffers[proci],
tag,
comm
);
toProc << allValues[proci];
}
// Wait for outstanding requests
UPstream::waitRequests(startOfRequests);
return allValues[0];
}
else if (UPstream::is_rank(comm))
{
IPstream::recv(localValue, UPstream::masterNo(), tag, comm);
}
}
} }
else else
{ {
// non-parallel: return first value T localValue{};
// TBD: only when UPstream::is_rank(comm) as well?
if (!allValues.empty()) if (UPstream::is_parallel(comm))
{ {
return allValues[0]; const label numProc = UPstream::nProcs(comm);
}
if (UPstream::master(comm) && allValues.size() < numProc)
{
FatalErrorInFunction
<< "Attempting to send " << allValues.size()
<< " values to " << numProc << " processors" << endl
<< Foam::abort(FatalError);
}
if (UPstream::master(comm))
{
const label startOfRequests = UPstream::nRequests();
List<DynamicList<char>> sendBuffers(numProc);
for (int proci = 1; proci < numProc; ++proci)
{
UOPstream toProc
(
UPstream::commsTypes::nonBlocking,
proci,
sendBuffers[proci],
tag,
comm
);
toProc << allValues[proci];
}
// Wait for outstanding requests
UPstream::waitRequests(startOfRequests);
return allValues[0];
}
else if (UPstream::is_rank(comm))
{
IPstream::recv(localValue, UPstream::masterNo(), tag, comm);
}
}
else
{
// non-parallel: return first value
// TBD: only when UPstream::is_rank(comm) as well?
if (!allValues.empty())
{
return allValues[0];
}
}
return localValue;
} }
return localValue;
} }
// ************************************************************************* // // ************************************************************************* //

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2015-2024 OpenCFD Ltd. Copyright (C) 2015-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -72,7 +72,7 @@ void Foam::Pstream::gatherList
{ {
const labelList& belowLeaves = comms[belowID].allBelow(); const labelList& belowLeaves = comms[belowID].allBelow();
if (is_contiguous<T>::value) if constexpr (is_contiguous_v<T>)
{ {
List<T> received(belowLeaves.size() + 1); List<T> received(belowLeaves.size() + 1);
@ -141,7 +141,7 @@ void Foam::Pstream::gatherList
<< " data:" << values[myProci] << endl; << " data:" << values[myProci] << endl;
} }
if (is_contiguous<T>::value) if constexpr (is_contiguous_v<T>)
{ {
List<T> sending(belowLeaves.size() + 1); List<T> sending(belowLeaves.size() + 1);
sending[0] = values[myProci]; sending[0] = values[myProci];
@ -223,7 +223,7 @@ void Foam::Pstream::scatterList
{ {
const labelList& notBelowLeaves = myComm.allNotBelow(); const labelList& notBelowLeaves = myComm.allNotBelow();
if (is_contiguous<T>::value) if constexpr (is_contiguous_v<T>)
{ {
List<T> received(notBelowLeaves.size()); List<T> received(notBelowLeaves.size());
@ -273,7 +273,7 @@ void Foam::Pstream::scatterList
const label belowID = myComm.below()[belowI]; const label belowID = myComm.below()[belowI];
const labelList& notBelowLeaves = comms[belowID].allNotBelow(); const labelList& notBelowLeaves = comms[belowID].allNotBelow();
if (is_contiguous<T>::value) if constexpr (is_contiguous_v<T>)
{ {
List<T> sending(notBelowLeaves.size()); List<T> sending(notBelowLeaves.size());
@ -362,13 +362,13 @@ template<class T>
void Foam::Pstream::allGatherList void Foam::Pstream::allGatherList
( (
UList<T>& values, UList<T>& values,
const int tag, [[maybe_unused]] const int tag,
const label comm const label comm
) )
{ {
if (UPstream::is_parallel(comm)) if (UPstream::is_parallel(comm))
{ {
if (is_contiguous<T>::value) if constexpr (is_contiguous_v<T>)
{ {
if (values.size() < UPstream::nProcs(comm)) if (values.size() < UPstream::nProcs(comm))
{ {
@ -379,13 +379,14 @@ void Foam::Pstream::allGatherList
} }
UPstream::mpiAllGather(values.data_bytes(), sizeof(T), comm); UPstream::mpiAllGather(values.data_bytes(), sizeof(T), comm);
return;
} }
else
{
const auto& comms = UPstream::whichCommunication(comm);
const auto& comms = UPstream::whichCommunication(comm); Pstream::gatherList(comms, values, tag, comm);
Pstream::scatterList(comms, values, tag, comm);
Pstream::gatherList(comms, values, tag, comm); }
Pstream::scatterList(comms, values, tag, comm);
} }
} }

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2021-2023 OpenCFD Ltd. Copyright (C) 2021-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -34,6 +34,14 @@ Foam::List<T> Foam::UPstream::allGatherValues
const label comm const label comm
) )
{ {
if constexpr (!is_contiguous_v<T>)
{
FatalErrorInFunction
<< "Cannot all-gather values for non-contiguous types"
" - consider Pstream variant instead" << endl
<< Foam::abort(FatalError);
}
List<T> allValues; List<T> allValues;
if (UPstream::is_parallel(comm)) if (UPstream::is_parallel(comm))
@ -41,17 +49,7 @@ Foam::List<T> Foam::UPstream::allGatherValues
allValues.resize(UPstream::nProcs(comm)); allValues.resize(UPstream::nProcs(comm));
allValues[UPstream::myProcNo(comm)] = localValue; allValues[UPstream::myProcNo(comm)] = localValue;
if (is_contiguous<T>::value) UPstream::mpiAllGather(allValues.data_bytes(), sizeof(T), comm);
{
UPstream::mpiAllGather(allValues.data_bytes(), sizeof(T), comm);
}
else
{
FatalErrorInFunction
<< "Cannot all-gather values for non-contiguous types"
" - consider Pstream variant instead" << endl
<< Foam::abort(FatalError);
}
} }
else else
{ {
@ -72,6 +70,14 @@ Foam::List<T> Foam::UPstream::listGatherValues
const label comm const label comm
) )
{ {
if constexpr (!is_contiguous_v<T>)
{
FatalErrorInFunction
<< "Cannot gather values for non-contiguous types"
" - consider Pstream variant instead" << endl
<< Foam::abort(FatalError);
}
List<T> allValues; List<T> allValues;
if (UPstream::is_parallel(comm)) if (UPstream::is_parallel(comm))
@ -81,23 +87,13 @@ Foam::List<T> Foam::UPstream::listGatherValues
allValues.resize(UPstream::nProcs(comm)); allValues.resize(UPstream::nProcs(comm));
} }
if (is_contiguous<T>::value) UPstream::mpiGather
{ (
UPstream::mpiGather reinterpret_cast<const char*>(&localValue),
( allValues.data_bytes(),
reinterpret_cast<const char*>(&localValue), sizeof(T), // The send/recv size per rank
allValues.data_bytes(), comm
sizeof(T), // The send/recv size per rank );
comm
);
}
else
{
FatalErrorInFunction
<< "Cannot gather values for non-contiguous types"
" - consider Pstream variant instead" << endl
<< Foam::abort(FatalError);
}
} }
else else
{ {
@ -118,6 +114,14 @@ T Foam::UPstream::listScatterValues
const label comm const label comm
) )
{ {
if constexpr (!is_contiguous_v<T>)
{
FatalErrorInFunction
<< "Cannot scatter values for non-contiguous types"
" - consider Pstream variant instead" << endl
<< Foam::abort(FatalError);
}
T localValue{}; T localValue{};
if (UPstream::is_parallel(comm)) if (UPstream::is_parallel(comm))
@ -132,23 +136,13 @@ T Foam::UPstream::listScatterValues
<< Foam::abort(FatalError); << Foam::abort(FatalError);
} }
if (is_contiguous<T>::value) UPstream::mpiScatter
{ (
UPstream::mpiScatter allValues.cdata_bytes(),
( reinterpret_cast<char*>(&localValue),
allValues.cdata_bytes(), sizeof(T), // The send/recv size per rank
reinterpret_cast<char*>(&localValue), comm
sizeof(T), // The send/recv size per rank );
comm
);
}
else
{
FatalErrorInFunction
<< "Cannot scatter values for non-contiguous types"
" - consider Pstream variant instead" << endl
<< Foam::abort(FatalError);
}
} }
else else
{ {

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2024 OpenCFD Ltd. Copyright (C) 2017-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -312,20 +312,20 @@ public:
{ {
// Private Member Functions // Private Member Functions
//- Fill with zero (contiguous types) //- Fill with zero (contiguous types) or with default value
template<class ValT = typename T::value_type> //- initialized (non-contiguous types)
typename std::enable_if<pTraits_has_zero<ValT>::value, void>::type void _m_fill_zero()
_m_fill_zero()
{ {
T::operator=(pTraits<ValT>::zero); typedef typename T::value_type valueType;
}
//- Fill with default value initialized (non-contiguous types) if constexpr (pTraits_has_zero<valueType>::value)
template<class ValT = typename T::value_type> {
typename std::enable_if<!pTraits_has_zero<ValT>::value, void>::type T::operator=(pTraits<valueType>::zero);
_m_fill_zero() }
{ else
T::operator=(ValT()); {
T::operator=(valueType());
}
} }
public: public:

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2024 OpenCFD Ltd. Copyright (C) 2017-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -920,12 +920,12 @@ Foam::token::tokenType Foam::token::Compound<T>::typeCode() const
typedef typename T::value_type valueType; typedef typename T::value_type valueType;
if (std::is_same<valueType, bool>::value) if constexpr (std::is_same_v<bool, valueType>)
{ {
// List<bool> // List<bool>
return token::tokenType::BOOL; return token::tokenType::BOOL;
} }
else if (is_contiguous_label<valueType>::value) else if constexpr (is_contiguous_label<valueType>::value)
{ {
// List<label>, List<labelVector> etc // List<label>, List<labelVector> etc
return token::tokenType::LABEL; return token::tokenType::LABEL;
@ -939,7 +939,7 @@ Foam::token::tokenType Foam::token::Compound<T>::typeCode() const
// ); // );
} }
else if (is_contiguous_scalar<valueType>::value) else if constexpr (is_contiguous_scalar<valueType>::value)
{ {
// List<scalar>, List<vector>, List<tensor> etc // List<scalar>, List<vector>, List<tensor> etc
return return
@ -949,7 +949,7 @@ Foam::token::tokenType Foam::token::Compound<T>::typeCode() const
: token::tokenType::DOUBLE : token::tokenType::DOUBLE
); );
} }
else if (std::is_same<valueType, char>::value) else if constexpr (std::is_same_v<char, valueType>)
{ {
// List<char> // List<char>
return token::tokenType::PUNCTUATION; return token::tokenType::PUNCTUATION;

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2016-2024 OpenCFD Ltd. Copyright (C) 2016-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -154,24 +154,24 @@ public:
friend dictionary; friend dictionary;
//- The const/non-const type for the context and sub-dictionaries //- The const/non-const type for the context and sub-dictionaries
typedef typename std::conditional using dict_type =
<Const, const dictionary, dictionary>::type dict_type; std::conditional_t<Const, const dictionary, dictionary>;
//- The const/non-const type for entries //- The const/non-const type for entries
typedef typename std::conditional using value_type =
<Const, const entry, entry>::type value_type; std::conditional_t<Const, const entry, entry>;
//- A pointer to a const/non-const dictionary //- A pointer to a const/non-const dictionary
typedef dict_type* dict_pointer; using dict_pointer = dict_type*;
//- A reference to a const/non-const dictionary //- A reference to a const/non-const dictionary
typedef dict_type& dict_reference; using dict_reference = dict_type&;
//- A pointer to a const/non-const entry //- A pointer to a const/non-const entry
typedef value_type* pointer; using pointer = value_type*;
//- A reference to a const/non-const entry //- A reference to a const/non-const entry
typedef value_type& reference; using reference = value_type&;
protected: protected:

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2019 OpenFOAM Foundation Copyright (C) 2011-2019 OpenFOAM Foundation
Copyright (C) 2016-2023 OpenCFD Ltd. Copyright (C) 2016-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -99,7 +99,7 @@ Foam::label Foam::objectRegistry::countTypeImpl
if if
( (
(std::is_void<Type>::value || Foam::isA<Type>(*obj)) (std::is_void_v<Type> || Foam::isA<Type>(*obj))
&& matchName(obj->name()) && matchName(obj->name())
) )
{ {
@ -164,7 +164,7 @@ Foam::wordList Foam::objectRegistry::namesTypeImpl
if if
( (
(std::is_void<Type>::value || Foam::isA<Type>(*obj)) (std::is_void_v<Type> || Foam::isA<Type>(*obj))
&& matchName(obj->name()) && matchName(obj->name())
) )
{ {
@ -195,7 +195,7 @@ Foam::objectRegistry::objectsTypeImpl
const bool doSort const bool doSort
) )
{ {
typedef typename std::remove_cv<Type>::type BaseType; using BaseType = std::remove_cv_t<Type>;
UPtrList<Type> result(list.size()); UPtrList<Type> result(list.size());
@ -237,7 +237,7 @@ Foam::objectRegistry::lookupClassTypeImpl
const objectRegistry& list const objectRegistry& list
) )
{ {
typedef typename std::remove_cv<Type>::type BaseType; using BaseType = std::remove_cv_t<Type>;
HashTable<Type*> result(list.capacity()); HashTable<Type*> result(list.capacity());
@ -318,7 +318,7 @@ Foam::label Foam::objectRegistry::count
if if
( (
std::is_void<Type>::value std::is_void_v<Type>
|| ||
( (
strict strict

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2010-2018 Bernhard Gschaider Copyright (C) 2010-2018 Bernhard Gschaider
Copyright (C) 2019-2022 OpenCFD Ltd. Copyright (C) 2019-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -137,7 +137,7 @@ bool Foam::expressions::exprDriver::isFunction(const word& name) const
// Currently only scalar, vector // Currently only scalar, vector
#undef doLocalCode #undef doLocalCode
#define doLocalCode(WhichType, MapperMember) \ #define doLocalCode(WhichType, MapperMember) \
if (std::is_same<Type, WhichType>::value) \ if constexpr (std::is_same_v<Type, WhichType>) \
{ \ { \
return bool \ return bool \
( \ ( \
@ -172,7 +172,7 @@ Type Foam::expressions::exprDriver::getFunctionValue
// Currently only scalar, vector // Currently only scalar, vector
#undef doLocalCode #undef doLocalCode
#define doLocalCode(WhichType, MapperMember) \ #define doLocalCode(WhichType, MapperMember) \
if (std::is_same<Type, WhichType>::value) \ if constexpr (std::is_same_v<Type, WhichType>) \
{ \ { \
const Function1<WhichType>* ptr = \ const Function1<WhichType>* ptr = \
this->template getFunction1Ptr<WhichType> \ this->template getFunction1Ptr<WhichType> \
@ -230,7 +230,7 @@ void Foam::expressions::exprDriver::fillFunctionValues
// Currently only scalar, vector // Currently only scalar, vector
#undef doLocalCode #undef doLocalCode
#define doLocalCode(WhichType, MapperMember) \ #define doLocalCode(WhichType, MapperMember) \
if (std::is_same<Type, WhichType>::value) \ if constexpr (std::is_same_v<Type, WhichType>) \
{ \ { \
const Function1<WhichType>* ptr = \ const Function1<WhichType>* ptr = \
this->template getFunction1Ptr<WhichType> \ this->template getFunction1Ptr<WhichType> \

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2012-2018 Bernhard Gschaider Copyright (C) 2012-2018 Bernhard Gschaider
Copyright (C) 2019-2023 OpenCFD Ltd. Copyright (C) 2019-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -512,7 +512,7 @@ bool Foam::expressions::exprResult::writeEntryChecked
if (this->size() <= 0) if (this->size() <= 0)
{ {
if (value_.good() && is_contiguous<Type>::value) if (value_.good() && is_contiguous_v<Type>)
{ {
const Type& val = value_.get<Type>(); const Type& val = value_.get<Type>();
@ -534,7 +534,7 @@ bool Foam::expressions::exprResult::writeEntryChecked
{ {
const Field<Type>& fld = *static_cast<const Field<Type>*>(fieldPtr_); const Field<Type>& fld = *static_cast<const Field<Type>*>(fieldPtr_);
if (value_.good() && is_contiguous<Type>::value) if (value_.good() && is_contiguous_v<Type>)
{ {
if (keyword.size()) if (keyword.size())
{ {

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2015-2023 OpenCFD Ltd. Copyright (C) 2015-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -734,7 +734,7 @@ void Foam::Field<Type>::writeEntry(const word& keyword, Ostream& os) const
// The contents are 'uniform' if the list is non-empty // The contents are 'uniform' if the list is non-empty
// and all entries have identical values. // and all entries have identical values.
if (is_contiguous<Type>::value && List<Type>::uniform()) if (is_contiguous_v<Type> && List<Type>::uniform())
{ {
os << word("uniform") << token::SPACE << List<Type>::front(); os << word("uniform") << token::SPACE << List<Type>::front();
} }

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2017-2019 OpenCFD Ltd. Copyright (C) 2017-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -32,8 +32,8 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef unitConversion_H #ifndef Foam_unitConversion_H
#define unitConversion_H #define Foam_unitConversion_H
#include "mathematicalConstants.H" #include "mathematicalConstants.H"
@ -121,13 +121,13 @@ inline constexpr scalar paToBar(const scalar pa) noexcept
//- User literal for degrees to radians conversion (integers) //- User literal for degrees to radians conversion (integers)
inline constexpr scalar operator "" _deg(unsigned long long int deg) noexcept inline constexpr scalar operator ""_deg(unsigned long long int deg) noexcept
{ {
return (deg*M_PI/180.0); return (deg*M_PI/180.0);
} }
//- User literal for degrees to radians conversion (floats) //- User literal for degrees to radians conversion (floats)
inline constexpr scalar operator "" _deg(long double deg) noexcept inline constexpr scalar operator ""_deg(long double deg) noexcept
{ {
return (deg*M_PI/180.0); return (deg*M_PI/180.0);
} }

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2022-2024 OpenCFD Ltd. Copyright (C) 2022-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -53,36 +53,32 @@ namespace PstreamUtils
// Casting helpers // Casting helpers
struct Cast struct Cast
{ {
// Cast UPstream::Communicator to MPI_Comm (pointer) //- Cast UPstream::Communicator to MPI_Comm
template<typename Type = MPI_Comm> template<typename Type = MPI_Comm>
static typename std::enable_if<std::is_pointer<Type>::value, Type>::type static Type to_mpi(UPstream::Communicator arg) noexcept
to_mpi(const UPstream::Communicator& arg) noexcept
{ {
return reinterpret_cast<Type>(arg.value()); if constexpr (std::is_pointer_v<Type>)
{
return reinterpret_cast<Type>(arg.value());
}
else // std::is_integral_v<Type>
{
return static_cast<Type>(arg.value());
}
} }
// Cast UPstream::Communicator to MPI_Comm (integer) //- Cast UPstream::Request to MPI_Request
template<typename Type = MPI_Comm>
static typename std::enable_if<std::is_integral<Type>::value, Type>::type
to_mpi(const UPstream::Communicator& arg) noexcept
{
return static_cast<Type>(arg.value());
}
// Cast UPstream::Request to MPI_Request (pointer)
template<typename Type = MPI_Request> template<typename Type = MPI_Request>
static typename std::enable_if<std::is_pointer<Type>::value, Type>::type static Type to_mpi(UPstream::Request arg) noexcept
to_mpi(const UPstream::Request& arg) noexcept
{ {
return reinterpret_cast<Type>(arg.value()); if constexpr (std::is_pointer_v<Type>)
} {
return reinterpret_cast<Type>(arg.value());
// Cast UPstream::Request to MPI_Request (integer) }
template<typename Type = MPI_Request> else // std::is_integral_v<Type>
static typename std::enable_if<std::is_integral<Type>::value, Type>::type {
to_mpi(const UPstream::Request& arg) noexcept return static_cast<Type>(arg.value());
{ }
return static_cast<Type>(arg.value());
} }
}; };

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2017-2023 OpenCFD Ltd. Copyright (C) 2017-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -34,39 +34,27 @@ Description
#include <algorithm> #include <algorithm>
#include <initializer_list> #include <initializer_list>
#include <iterator> // for std::begin, std::end, ...
#include <memory> #include <memory>
#include <utility>
#include <type_traits> #include <type_traits>
#include <utility>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Compile-time warning for use of deprecated methods (compiler-dependent). // Compile-time warning for use of deprecated methods (compiler-dependent).
// Use within the class declaration. // Use within the class declaration.
#if (__cplusplus >= 201402L) #define FOAM_DEPRECATED(since) [[deprecated("Since " #since)]]
# define FOAM_DEPRECATED(since) [[deprecated("Since " #since)]] #define FOAM_DEPRECATED_FOR(since, replacement) [[deprecated("Since " #since "; use " #replacement)]]
# define FOAM_DEPRECATED_FOR(since, replacement) [[deprecated("Since " #since "; use " #replacement)]] #define FOAM_DEPRECATED_STRICT(since, replacement) [[deprecated("Since " #since "; use " #replacement)]]
# define FOAM_DEPRECATED_STRICT(since, replacement) [[deprecated("Since " #since "; use " #replacement)]]
#elif defined(__GNUC__)
# define FOAM_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
# define FOAM_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
# define FOAM_DEPRECATED_STRICT(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
#else
# define FOAM_DEPRECATED(since)
# define FOAM_DEPRECATED_FOR(since, replacement)
# define FOAM_DEPRECATED_STRICT(since, replacement)
#endif
#ifndef FOAM_COMPILE_STRICT
# undef FOAM_DEPRECATED_STRICT
# define FOAM_DEPRECATED_STRICT(since, replacement)
#endif
// Compile-time warning about unused result // Branch prediction helpers. With C++20 can use [[likely]], [[unlikely]]
// FUTURE: check __has_cpp_attribute(nodiscard) and define with [[nodiscard]] #if defined(__GNUC__) || defined(__clang__)
#if defined(__GNUC__) # define FOAM_UNLIKELY(cond) __builtin_expect(!!(cond),0)
# define FOAM_NODISCARD __attribute__((warn_unused_result)) # define FOAM_LIKELY(cond) __builtin_expect(!!(cond),1)
#else #else
# define FOAM_NODISCARD # define FOAM_UNLIKELY(cond) (cond)
# define FOAM_LIKELY(cond) (cond)
#endif #endif
@ -104,6 +92,8 @@ struct identityOp
}; };
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Swap non-array types as per std::swap, but in Foam namespace. //- Swap non-array types as per std::swap, but in Foam namespace.
// \sa http://www.cplusplus.com/reference/utility/swap/ // \sa http://www.cplusplus.com/reference/utility/swap/
// //
@ -141,127 +131,13 @@ void Swap(T (&a)[N], T (&b)[N])
// - https://en.cppreference.com/w/cpp/iterator/rbegin // - https://en.cppreference.com/w/cpp/iterator/rbegin
// - https://en.cppreference.com/w/cpp/iterator/rend // - https://en.cppreference.com/w/cpp/iterator/rend
namespace stdFoam namespace stdFoam
{ {
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // //- Map any dependent type to false (workaround before CWG2518)
template<typename...>
// Forward iteration inline constexpr bool dependent_false_v = false;
//- Return iterator to the beginning of the container \a c.
// 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.
// 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.
// 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.
// 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.
// 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.
// Definition as per std::cend C++17
template<class C>
constexpr auto cend(const C& c) -> decltype(c.end())
{
return c.end();
}
// Reverse iteration
//- Return reverse_iterator to the reverse-begin of container \a c.
// Definition as per std::rbegin C++17
template<class C>
constexpr auto rbegin(C& c) -> decltype(c.rbegin())
{
return c.rbegin();
}
//- Return const_reverse_iterator to the reverse-begin of container \a c.
// Definition as per std::rbegin C++17
template<class C>
constexpr auto rbegin(const C& c) -> decltype(c.rbegin())
{
return c.rbegin();
}
//- Return const_reverse_iterator to the reverse-begin of container \a c.
// Definition as per std::crbegin C++17
template<class C>
constexpr auto crbegin(const C& c) -> decltype(c.rbegin())
{
return c.rbegin();
}
//- Return reverse_iterator to reverse-end of container \a c.
// Definition as per std::rend C++17
template<class C>
constexpr auto rend(C& c) -> decltype(c.rend())
{
return c.rend();
}
//- Return const_reverse_iterator to reverse-end of container \a c.
// Definition as per std::rend C++17
template<class C>
constexpr auto rend(const C& c) -> decltype(c.rend())
{
return c.rend();
}
//- Return const_reverse_iterator to reverse-end of container \a c.
// Definition as per std::crend C++17
template<class C>
constexpr auto crend(const C& c) -> decltype(c.rend())
{
return c.rend();
}
//- Return the lesser of the parameters.
// Definition as per std::min C++14
template<class T>
constexpr inline const T& min(const T& a, const T& b)
{
return (b < a) ? b : a;
}
//- Return the greater of the parameters.
// Definition as per std::max C++14
template<class T>
constexpr inline const T& max(const T& a, const T& b)
{
return (a < b) ? b : a;
}
} // End namespace stdFoam } // End namespace stdFoam
@ -280,8 +156,8 @@ constexpr inline const T& max(const T& a, const T& b)
#define forAllIters(container,iter) \ #define forAllIters(container,iter) \
for \ for \
( \ ( \
auto iter = stdFoam::begin(container); \ auto iter = std::begin(container); \
iter != stdFoam::end(container); \ iter != std::end(container); \
++iter \ ++iter \
) )
@ -298,8 +174,8 @@ constexpr inline const T& max(const T& a, const T& b)
#define forAllConstIters(container,iter) \ #define forAllConstIters(container,iter) \
for \ for \
( \ ( \
auto iter = stdFoam::cbegin(container); \ auto iter = std::cbegin(container); \
iter != stdFoam::cend(container); \ iter != std::cend(container); \
++iter \ ++iter \
) )
@ -317,8 +193,8 @@ constexpr inline const T& max(const T& a, const T& b)
#define forAllReverseIters(container,iter) \ #define forAllReverseIters(container,iter) \
for \ for \
( \ ( \
auto iter = stdFoam::rbegin(container); \ auto iter = std::rbegin(container); \
iter != stdFoam::rend(container); \ iter != std::rend(container); \
++iter \ ++iter \
) )
@ -335,8 +211,8 @@ constexpr inline const T& max(const T& a, const T& b)
#define forAllConstReverseIters(container,iter) \ #define forAllConstReverseIters(container,iter) \
for \ for \
( \ ( \
auto iter = stdFoam::crbegin(container); \ auto iter = std::crbegin(container); \
iter != stdFoam::crend(container); \ iter != std::crend(container); \
++iter \ ++iter \
) )
@ -434,13 +310,13 @@ public:
// STL type definitions // STL type definitions
using element_type = Type; using element_type = Type;
using value_type = std::remove_cv<Type>; using value_type = std::remove_cv_t<Type>;
using size_type = std::size_t; using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
using pointer = Type*; using pointer = Type*;
using const_pointer = const Type*; using const_pointer = const Type*;
using reference = Type&; using reference = element_type&;
using const_reference = const Type&; using const_reference = const element_type&;
using difference_type = std::ptrdiff_t;
using iterator = Type*; using iterator = Type*;
@ -565,7 +441,7 @@ public:
//- A writable view as byte content (if the pointer type is non-const). //- A writable view as byte content (if the pointer type is non-const).
//- Like data(), the const access itself is const. //- Like data(), the const access itself is const.
template<class TypeT = Type> template<class TypeT = Type>
typename std::enable_if<!std::is_const<TypeT>::value, char*>::type std::enable_if_t<!std::is_const_v<TypeT>, char*>
data_bytes() const noexcept data_bytes() const noexcept
{ {
return reinterpret_cast<char*>(data_); return reinterpret_cast<char*>(data_);

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2020-2023 OpenCFD Ltd. Copyright (C) 2020-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -74,7 +74,7 @@ Type Foam::csvTableReader<Type>::readValue
{ {
Type result; Type result;
if (std::is_integral<Type>::value) if constexpr (std::is_integral_v<Type>)
{ {
// nComponents == 1 // nComponents == 1
setComponent(result, 0) = readLabel(strings[componentColumns_[0]]); setComponent(result, 0) = readLabel(strings[componentColumns_[0]]);

View File

@ -159,7 +159,7 @@ class EigenMatrix
{ {
static_assert static_assert
( (
std::is_floating_point<cmptType>::value, std::is_floating_point_v<cmptType>,
"EigenMatrix operates only with scalar base type." "EigenMatrix operates only with scalar base type."
); );

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2019-2024 OpenCFD Ltd. Copyright (C) 2019-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -72,7 +72,7 @@ void Foam::LUscalarMatrix::solve
{ {
// Nothing to do // Nothing to do
} }
else if (is_contiguous<Type>::value) else if constexpr (is_contiguous_v<Type>)
{ {
UIPstream::read UIPstream::read
( (
@ -96,7 +96,7 @@ void Foam::LUscalarMatrix::solve
{ {
// Nothing to do // Nothing to do
} }
else if (is_contiguous<Type>::value) else if constexpr (is_contiguous_v<Type>)
{ {
UOPstream::write UOPstream::write
( (
@ -136,7 +136,7 @@ void Foam::LUscalarMatrix::solve
{ {
// Nothing to do // Nothing to do
} }
else if (is_contiguous<Type>::value) else if constexpr (is_contiguous_v<Type>)
{ {
UOPstream::write UOPstream::write
( (
@ -160,7 +160,7 @@ void Foam::LUscalarMatrix::solve
{ {
// Nothing to do // Nothing to do
} }
else if (is_contiguous<Type>::value) else if constexpr (is_contiguous_v<Type>)
{ {
UIPstream::read UIPstream::read
( (

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2019-2022 OpenCFD Ltd. Copyright (C) 2019-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -508,11 +508,11 @@ Foam::scalar Foam::Matrix<Form, Type>::norm(const bool noSqrt) const
template<class Form, class Type> template<class Form, class Type>
std::streamsize Foam::Matrix<Form, Type>::byteSize() const std::streamsize Foam::Matrix<Form, Type>::byteSize() const
{ {
if (!is_contiguous<Type>::value) if constexpr (!is_contiguous_v<Type>)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Invalid for non-contiguous data types" << "Invalid for non-contiguous data types"
<< abort(FatalError); << Foam::abort(FatalError);
} }
return this->size_bytes(); return this->size_bytes();
} }

View File

@ -210,7 +210,7 @@ public:
inline bool empty() const noexcept; inline bool empty() const noexcept;
//- The number of elements in Matrix (m*n) //- The number of elements in Matrix (m*n)
inline label size() const; inline label size() const noexcept;
//- Return row/column sizes //- Return row/column sizes
inline labelPair sizes() const; inline labelPair sizes() const;

View File

@ -86,7 +86,7 @@ Foam::Matrix<Form, Type>::clone() const
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Form, class Type> template<class Form, class Type>
inline Foam::label Foam::Matrix<Form, Type>::size() const inline Foam::label Foam::Matrix<Form, Type>::size() const noexcept
{ {
return mRows_ * nCols_; return mRows_ * nCols_;
} }
@ -209,7 +209,7 @@ inline char* Foam::Matrix<Form, Type>::data_bytes() noexcept
template<class Form, class Type> template<class Form, class Type>
inline std::streamsize Foam::Matrix<Form, Type>::size_bytes() const noexcept inline std::streamsize Foam::Matrix<Form, Type>::size_bytes() const noexcept
{ {
return mRows_*nCols_*sizeof(Type); return std::streamsize(mRows_*nCols_)*sizeof(Type);
} }

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019-2023 OpenCFD Ltd. Copyright (C) 2019-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -69,7 +69,7 @@ bool Foam::Matrix<Form, Type>::readMatrix(Istream& is)
// The total size // The total size
const label len = size(); const label len = size();
if (is.format() == IOstreamOption::BINARY && is_contiguous<Type>::value) if (is.format() == IOstreamOption::BINARY && is_contiguous_v<Type>)
{ {
// Binary and contiguous // Binary and contiguous
@ -152,7 +152,7 @@ Foam::Ostream& Foam::Matrix<Form, Type>::writeMatrix
// Rows, columns size // Rows, columns size
os << mat.nRows() << token::SPACE << mat.nCols(); os << mat.nRows() << token::SPACE << mat.nCols();
if (os.format() == IOstreamOption::BINARY && is_contiguous<Type>::value) if (os.format() == IOstreamOption::BINARY && is_contiguous_v<Type>)
{ {
// Binary and contiguous // Binary and contiguous
@ -162,7 +162,7 @@ Foam::Ostream& Foam::Matrix<Form, Type>::writeMatrix
os.write(mat.cdata_bytes(), mat.size_bytes()); os.write(mat.cdata_bytes(), mat.size_bytes());
} }
} }
else if (is_contiguous<Type>::value && len > 1 && mat.uniform()) else if (is_contiguous_v<Type> && len > 1 && mat.uniform())
{ {
// Two or more entries, and all entries have identical values. // Two or more entries, and all entries have identical values.
os << token::BEGIN_BLOCK << *iter << token::END_BLOCK; os << token::BEGIN_BLOCK << *iter << token::END_BLOCK;
@ -170,7 +170,7 @@ Foam::Ostream& Foam::Matrix<Form, Type>::writeMatrix
else if else if
( (
(len <= 1 || !shortLen) (len <= 1 || !shortLen)
|| (len <= shortLen && is_contiguous<Type>::value) || (len <= shortLen && is_contiguous_v<Type>)
) )
{ {
// Single-line output (entire matrix) // Single-line output (entire matrix)
@ -201,7 +201,7 @@ Foam::Ostream& Foam::Matrix<Form, Type>::writeMatrix
else if else if
( (
(mat.nCols() <= 1 || !shortLen) (mat.nCols() <= 1 || !shortLen)
|| (mat.nCols() <= shortLen && is_contiguous<Type>::value) || (mat.nCols() <= shortLen && is_contiguous_v<Type>)
) )
{ {
// Multi-line matrix, single-line rows // Multi-line matrix, single-line rows

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2019-2023 OpenCFD Ltd. Copyright (C) 2019-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -36,10 +36,15 @@ template<class Type>
void Foam::processorLduInterface::send void Foam::processorLduInterface::send
( (
const UPstream::commsTypes commsType, const UPstream::commsTypes commsType,
const UList<Type>& f const UList<Type>& fld
) const ) const
{ {
const label nBytes = f.byteSize(); if constexpr (!is_contiguous_v<Type>)
{
FatalErrorInFunction
<< "Invalid for non-contiguous data types"
<< Foam::abort(FatalError);
}
if if
( (
@ -51,28 +56,30 @@ void Foam::processorLduInterface::send
( (
commsType, commsType,
neighbProcNo(), neighbProcNo(),
f.cdata_bytes(), fld.cdata_bytes(),
nBytes, fld.size_bytes(),
tag(), tag(),
comm() comm()
); );
} }
else if (commsType == UPstream::commsTypes::nonBlocking) else if (commsType == UPstream::commsTypes::nonBlocking)
{ {
resizeBuf(byteSendBuf_, nBytes); if (fld.empty())
std::memcpy
(
static_cast<void*>(byteSendBuf_.data()), f.cdata(), nBytes
);
resizeBuf(byteRecvBuf_, nBytes);
if (!nBytes)
{ {
// Can skip empty messages // Can skip empty messages
return; return;
} }
const label nBytes = fld.size_bytes();
resizeBuf(byteSendBuf_, nBytes);
resizeBuf(byteRecvBuf_, nBytes);
std::memcpy
(
static_cast<void*>(byteSendBuf_.data()), fld.cdata(), nBytes
);
UIPstream::read UIPstream::read
( (
commsType, commsType,
@ -106,10 +113,15 @@ template<class Type>
void Foam::processorLduInterface::receive void Foam::processorLduInterface::receive
( (
const UPstream::commsTypes commsType, const UPstream::commsTypes commsType,
UList<Type>& f UList<Type>& fld
) const ) const
{ {
const label nBytes = f.byteSize(); if constexpr (!is_contiguous_v<Type>)
{
FatalErrorInFunction
<< "Invalid for non-contiguous data types"
<< Foam::abort(FatalError);
}
if if
( (
@ -121,17 +133,19 @@ void Foam::processorLduInterface::receive
( (
commsType, commsType,
neighbProcNo(), neighbProcNo(),
f.data_bytes(), fld.data_bytes(),
nBytes, fld.size_bytes(),
tag(), tag(),
comm() comm()
); );
} }
else if (commsType == UPstream::commsTypes::nonBlocking) else if (commsType == UPstream::commsTypes::nonBlocking)
{ {
const label nBytes = fld.size_bytes();
std::memcpy std::memcpy
( (
static_cast<void*>(f.data()), byteRecvBuf_.cdata(), nBytes static_cast<void*>(fld.data()), byteRecvBuf_.cdata(), nBytes
); );
} }
else else
@ -163,20 +177,23 @@ void Foam::processorLduInterface::compressedSend
const UList<Type>& f const UList<Type>& f
) const ) const
{ {
if if constexpr
( (
f.size() std::is_integral_v<Type>
&& UPstream::floatTransfer || (sizeof(float) == sizeof(scalar))
&& (!std::is_integral<Type>::value && sizeof(scalar) != sizeof(float))
) )
{ {
static const label nCmpts = // No compression if integral or scalar is float
( this->send(commsType, f);
// Placeholder value for unusable template instantiation }
std::is_integral<Type>::value else if (f.empty() || !UPstream::floatTransfer)
? 1 {
: sizeof(Type)/sizeof(scalar) // No compression
); this->send(commsType, f);
}
else // (!f.empty() && UPstream::floatTransfer)
{
static const label nCmpts = (sizeof(Type)/sizeof(scalar));
const label nm1 = (f.size() - 1)*nCmpts; const label nm1 = (f.size() - 1)*nCmpts;
const label nBytes = f.size()*nCmpts*sizeof(float); const label nBytes = f.size()*nCmpts*sizeof(float);
@ -239,10 +256,6 @@ void Foam::processorLduInterface::compressedSend
<< exit(FatalError); << exit(FatalError);
} }
} }
else
{
this->send(commsType, f);
}
} }
@ -253,20 +266,23 @@ void Foam::processorLduInterface::compressedReceive
UList<Type>& f UList<Type>& f
) const ) const
{ {
if if constexpr
( (
f.size() std::is_integral_v<Type>
&& UPstream::floatTransfer || (sizeof(float) == sizeof(scalar))
&& (!std::is_integral<Type>::value && sizeof(scalar) != sizeof(float))
) )
{ {
static const label nCmpts = // No compression if integral or scalar is float
( this->receive<Type>(commsType, f);
// Placeholder value for unusable template instantiation }
std::is_integral<Type>::value else if (f.empty() || !UPstream::floatTransfer)
? 1 {
: sizeof(Type)/sizeof(scalar) // Nothing to compress
); this->receive<Type>(commsType, f);
}
else // (!f.empty() && UPstream::floatTransfer)
{
static const label nCmpts = (sizeof(Type)/sizeof(scalar));
const label nm1 = (f.size() - 1)*nCmpts; const label nm1 = (f.size() - 1)*nCmpts;
const label nBytes = f.size()*nCmpts*sizeof(float); const label nBytes = f.size()*nCmpts*sizeof(float);
@ -306,10 +322,6 @@ void Foam::processorLduInterface::compressedReceive
sArray[i] = fArray[i] + slast[i%nCmpts]; sArray[i] = fArray[i] + slast[i%nCmpts];
} }
} }
else
{
this->receive<Type>(commsType, f);
}
} }

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2019-2021 OpenCFD Ltd. Copyright (C) 2019-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -64,7 +64,7 @@ class ConstPrecisionAdaptor
//- Set adaptor for different input, copying as required //- Set adaptor for different input, copying as required
void setInput(const Container<InputType>& src) void setInput(const Container<InputType>& src)
{ {
if (std::is_same<Type, InputType>::value) if constexpr (std::is_same_v<Type, InputType>)
{ {
// Use reference directly // Use reference directly
this->cref(reinterpret_cast<const Container<Type>&>(src)); this->cref(reinterpret_cast<const Container<Type>&>(src));
@ -80,7 +80,7 @@ class ConstPrecisionAdaptor
//- Set from tmp, steal pointer if possible //- Set from tmp, steal pointer if possible
void tmpInput(tmp<Container<InputType>>& tsrc) void tmpInput(tmp<Container<InputType>>& tsrc)
{ {
if (std::is_same<Type, InputType>::value && tsrc.is_pointer()) if (std::is_same_v<Type, InputType> && tsrc.is_pointer())
{ {
// Acquire control of the managed pointer // Acquire control of the managed pointer
this->reset(reinterpret_cast<Container<Type>*>(tsrc.ptr())); this->reset(reinterpret_cast<Container<Type>*>(tsrc.ptr()));
@ -161,10 +161,10 @@ public:
static const Container<Type>& select static const Container<Type>& select
( (
const Container<InputType>& input, const Container<InputType>& input,
Container<Type>& other [[maybe_unused]] Container<Type>& other
) )
{ {
if (std::is_same<Type, InputType>::value) if constexpr (std::is_same_v<Type, InputType>)
{ {
return reinterpret_cast<const Container<Type>&>(input); return reinterpret_cast<const Container<Type>&>(input);
} }
@ -197,10 +197,14 @@ class PrecisionAdaptor
// Private Member Functions // Private Member Functions
//- Set adaptor for different input, copying as required //- Set adaptor for different input, copying as required
void setInput(Container<InputType>& src, const bool doCopy) void setInput
(
Container<InputType>& src,
[[maybe_unused]] const bool doCopy
)
{ {
orig_.ref(src); orig_.ref(src);
if (std::is_same<Type, InputType>::value) if constexpr (std::is_same_v<Type, InputType>)
{ {
// Use reference directly // Use reference directly
this->ref(reinterpret_cast<Container<Type>&>(src)); this->ref(reinterpret_cast<Container<Type>&>(src));

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2015-2017 OpenFOAM Foundation Copyright (C) 2015-2017 OpenFOAM Foundation
Copyright (C) 2015-2024 OpenCFD Ltd. Copyright (C) 2015-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -162,11 +162,11 @@ void Foam::mapDistributeBase::send
const label comm const label comm
) )
{ {
if (!is_contiguous<T>::value) if constexpr (!is_contiguous_v<T>)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Only contiguous is currently supported" << "Only contiguous is currently supported"
<< exit(FatalError); << Foam::abort(FatalError);
} }
const auto myRank = UPstream::myProcNo(comm); const auto myRank = UPstream::myProcNo(comm);
@ -318,14 +318,15 @@ void Foam::mapDistributeBase::receive
const label comm const label comm
) )
{ {
if (!is_contiguous<T>::value) if constexpr (!is_contiguous_v<T>)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Only contiguous is currently supported" << "Only contiguous is currently supported"
<< exit(FatalError); << Foam::abort(FatalError);
} }
const auto myRank = UPstream::myProcNo(comm); const auto myRank = UPstream::myProcNo(comm);
[[maybe_unused]]
const auto nProcs = UPstream::nProcs(comm); const auto nProcs = UPstream::nProcs(comm);
@ -463,6 +464,7 @@ void Foam::mapDistributeBase::distribute
) )
{ {
const auto myRank = UPstream::myProcNo(comm); const auto myRank = UPstream::myProcNo(comm);
[[maybe_unused]]
const auto nProcs = UPstream::nProcs(comm); const auto nProcs = UPstream::nProcs(comm);
if (!UPstream::parRun()) if (!UPstream::parRun())
@ -679,7 +681,7 @@ void Foam::mapDistributeBase::distribute
{ {
const label startOfRequests = UPstream::nRequests(); const label startOfRequests = UPstream::nRequests();
if (!is_contiguous<T>::value) if constexpr (!is_contiguous_v<T>)
{ {
PstreamBuffers pBufs(comm, tag); PstreamBuffers pBufs(comm, tag);
@ -909,6 +911,7 @@ void Foam::mapDistributeBase::distribute
) )
{ {
const auto myRank = UPstream::myProcNo(comm); const auto myRank = UPstream::myProcNo(comm);
[[maybe_unused]]
const auto nProcs = UPstream::nProcs(comm); const auto nProcs = UPstream::nProcs(comm);
if (!UPstream::parRun()) if (!UPstream::parRun())
@ -1119,7 +1122,7 @@ void Foam::mapDistributeBase::distribute
{ {
const label startOfRequests = UPstream::nRequests(); const label startOfRequests = UPstream::nRequests();
if (!is_contiguous<T>::value) if constexpr (!is_contiguous_v<T>)
{ {
PstreamBuffers pBufs(comm, tag); PstreamBuffers pBufs(comm, tag);

View File

@ -555,7 +555,7 @@ public:
//- Return neighbour cell values for all boundary faces //- Return neighbour cell values for all boundary faces
//- by swapping via boundary faces //- by swapping via boundary faces
template<class T> template<class T>
FOAM_NODISCARD static List<T> swapBoundaryCellList [[nodiscard]] static List<T> swapBoundaryCellList
( (
const polyMesh& mesh, const polyMesh& mesh,
const UList<T>& cellData, const UList<T>& cellData,
@ -570,7 +570,7 @@ public:
//- Return neighbour cell positions for all boundary faces //- Return neighbour cell positions for all boundary faces
//- by swapping via boundary faces //- by swapping via boundary faces
FOAM_NODISCARD static List<point> swapBoundaryCellPositions [[nodiscard]] static List<point> swapBoundaryCellPositions
( (
const polyMesh& mesh, const polyMesh& mesh,
const UList<point>& cellData, const UList<point>& cellData,

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2015-2024 OpenCFD Ltd. Copyright (C) 2015-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -1057,7 +1057,7 @@ void Foam::syncTools::syncBoundaryFaceList
if if
( (
is_contiguous<T>::value is_contiguous_v<T>
&& UPstream::defaultCommsType == UPstream::commsTypes::nonBlocking && UPstream::defaultCommsType == UPstream::commsTypes::nonBlocking
) )
{ {

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2013-2017 OpenFOAM Foundation Copyright (C) 2013-2017 OpenFOAM Foundation
Copyright (C) 2019-2024 OpenCFD Ltd. Copyright (C) 2019-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -40,7 +40,7 @@ License
// return // return
// ( // (
// ( // (
// !is_contiguous<Type>::value // !is_contiguous_v<Type>
// && UPstream::commsTypes::nonBlocking == preferred // && UPstream::commsTypes::nonBlocking == preferred
// ) // )
// ? UPstream::commsTypes::scheduled // ? UPstream::commsTypes::scheduled
@ -138,7 +138,7 @@ void Foam::globalIndex::gatherValues
const UPstream::commsTypes commsType = const UPstream::commsTypes commsType =
( (
( (
!is_contiguous<Type>::value !is_contiguous_v<Type>
&& UPstream::commsTypes::nonBlocking == preferredCommsType && UPstream::commsTypes::nonBlocking == preferredCommsType
) )
? UPstream::commsTypes::scheduled ? UPstream::commsTypes::scheduled
@ -156,7 +156,7 @@ void Foam::globalIndex::gatherValues
for (label i = 1; i < procIDs.size(); ++i) for (label i = 1; i < procIDs.size(); ++i)
{ {
if (is_contiguous<Type>::value) if constexpr (is_contiguous_v<Type>)
{ {
UIPstream::read UIPstream::read
( (
@ -178,7 +178,7 @@ void Foam::globalIndex::gatherValues
{ {
allValues.clear(); // safety: zero-size on non-master allValues.clear(); // safety: zero-size on non-master
if (is_contiguous<Type>::value) if constexpr (is_contiguous_v<Type>)
{ {
UOPstream::write UOPstream::write
( (
@ -222,7 +222,7 @@ void Foam::globalIndex::gather
const UPstream::commsTypes commsType = const UPstream::commsTypes commsType =
( (
( (
!is_contiguous<Type>::value !is_contiguous_v<Type>
&& UPstream::commsTypes::nonBlocking == preferredCommsType && UPstream::commsTypes::nonBlocking == preferredCommsType
) )
? UPstream::commsTypes::scheduled ? UPstream::commsTypes::scheduled
@ -253,7 +253,7 @@ void Foam::globalIndex::gather
{ {
// Nothing to do // Nothing to do
} }
else if (is_contiguous<Type>::value) else if constexpr (is_contiguous_v<Type>)
{ {
UIPstream::read UIPstream::read
( (
@ -277,7 +277,7 @@ void Foam::globalIndex::gather
{ {
// Nothing to do // Nothing to do
} }
else if (is_contiguous<Type>::value) else if constexpr (is_contiguous_v<Type>)
{ {
UOPstream::write UOPstream::write
( (
@ -317,7 +317,7 @@ void Foam::globalIndex::gather
{ {
// low-level: no parRun guard // low-level: no parRun guard
if (is_contiguous<Type>::value) if constexpr (is_contiguous_v<Type>)
{ {
// Flatten list (locally) so that we can benefit from using direct // Flatten list (locally) so that we can benefit from using direct
// read/write of contiguous data // read/write of contiguous data
@ -339,7 +339,7 @@ void Foam::globalIndex::gather
const UPstream::commsTypes commsType = const UPstream::commsTypes commsType =
( (
( (
!is_contiguous<Type>::value !is_contiguous_v<Type>
&& UPstream::commsTypes::nonBlocking == preferredCommsType && UPstream::commsTypes::nonBlocking == preferredCommsType
) )
? UPstream::commsTypes::scheduled ? UPstream::commsTypes::scheduled
@ -567,14 +567,14 @@ void Foam::globalIndex::mpiGather
char dataMode(0); char dataMode(0);
int nCmpts(0); int nCmpts(0);
if (is_contiguous<Type>::value) if constexpr (is_contiguous_v<Type>)
{ {
if (is_contiguous_scalar<Type>::value) if constexpr (is_contiguous_scalar<Type>::value)
{ {
dataMode = 'f'; dataMode = 'f';
nCmpts = static_cast<int>(sizeof(Type)/sizeof(scalar)); nCmpts = static_cast<int>(sizeof(Type)/sizeof(scalar));
} }
else if (is_contiguous_label<Type>::value) else if constexpr (is_contiguous_label<Type>::value)
{ {
dataMode = 'i'; dataMode = 'i';
nCmpts = static_cast<int>(sizeof(Type)/sizeof(label)); nCmpts = static_cast<int>(sizeof(Type)/sizeof(label));
@ -921,7 +921,7 @@ void Foam::globalIndex::scatter
const UPstream::commsTypes commsType = const UPstream::commsTypes commsType =
( (
( (
!is_contiguous<Type>::value !is_contiguous_v<Type>
&& UPstream::commsTypes::nonBlocking == preferredCommsType && UPstream::commsTypes::nonBlocking == preferredCommsType
) )
? UPstream::commsTypes::scheduled ? UPstream::commsTypes::scheduled
@ -942,7 +942,7 @@ void Foam::globalIndex::scatter
{ {
// Nothing to do // Nothing to do
} }
else if (is_contiguous<Type>::value) else if constexpr (is_contiguous_v<Type>)
{ {
UOPstream::write UOPstream::write
( (
@ -978,7 +978,7 @@ void Foam::globalIndex::scatter
{ {
// Nothing to do // Nothing to do
} }
else if (is_contiguous<Type>::value) else if constexpr (is_contiguous_v<Type>)
{ {
UIPstream::read UIPstream::read
( (

View File

@ -6,6 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -31,8 +32,8 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef VectorSpaceOps_H #ifndef Foam_VectorSpaceOps_H
#define VectorSpaceOps_H #define Foam_VectorSpaceOps_H
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -41,56 +42,76 @@ namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- General looping form. Executing at index \<I\> with termination at \<N\> //- Recursive execution. Terminating at \<N\>, starting at index \<I\>
template<direction N, direction I> template<direction N, direction I>
struct VectorSpaceOps struct VectorSpaceOps
{ {
template<class V, class S, class EqOp> template<class V, class S, class EqOp>
static inline void eqOpS(V& vs, const S& s, EqOp eo) static inline void eqOpS(V& vs, const S& s, EqOp eo)
{ {
eo(vs.v_[I], s); // if constexpr (I < N)
VectorSpaceOps<N, I+1>::eqOpS(vs, s, eo); {
eo(vs.v_[I], s);
VectorSpaceOps<N, I+1>::eqOpS(vs, s, eo);
}
} }
template<class S, class V, class EqOp> template<class S, class V, class EqOp>
static inline void SeqOp(S& s, const V& vs, EqOp eo) static inline void SeqOp(S& s, const V& vs, EqOp eo)
{ {
eo(s, vs.v_[I]); // if constexpr (I < N)
VectorSpaceOps<N, I+1>::SeqOp(s, vs, eo); {
eo(s, vs.v_[I]);
VectorSpaceOps<N, I+1>::SeqOp(s, vs, eo);
}
} }
template<class V1, class V2, class EqOp> template<class V1, class V2, class EqOp>
static inline void eqOp(V1& vs1, const V2& vs2, EqOp eo) static inline void eqOp(V1& vs1, const V2& vs2, EqOp eo)
{ {
eo(vs1.v_[I], vs2.v_[I]); // if constexpr (I < N)
VectorSpaceOps<N, I+1>::eqOp(vs1, vs2, eo); {
eo(vs1.v_[I], vs2.v_[I]);
VectorSpaceOps<N, I+1>::eqOp(vs1, vs2, eo);
}
} }
template<class V, class V1, class S, class Op> template<class V, class V1, class S, class Op>
static inline void opVS(V& vs, const V1& vs1, const S& s, Op o) static inline void opVS(V& vs, const V1& vs1, const S& s, Op o)
{ {
vs.v_[I] = o(vs1.v_[I], s); // if constexpr (I < N)
VectorSpaceOps<N, I+1>::opVS(vs, vs1, s, o); {
vs.v_[I] = o(vs1.v_[I], s);
VectorSpaceOps<N, I+1>::opVS(vs, vs1, s, o);
}
} }
template<class V, class S, class V1, class Op> template<class V, class S, class V1, class Op>
static inline void opSV(V& vs, const S& s, const V1& vs1, Op o) static inline void opSV(V& vs, const S& s, const V1& vs1, Op o)
{ {
vs.v_[I] = o(s, vs1.v_[I]); // if constexpr (I < N)
VectorSpaceOps<N, I+1>::opSV(vs, s, vs1, o); {
vs.v_[I] = o(s, vs1.v_[I]);
VectorSpaceOps<N, I+1>::opSV(vs, s, vs1, o);
}
} }
template<class V, class V1, class Op> template<class V, class V1, class Op>
static inline void op(V& vs, const V1& vs1, const V1& vs2, Op o) static inline void op(V& vs, const V1& vs1, const V1& vs2, Op o)
{ {
vs.v_[I] = o(vs1.v_[I], vs2.v_[I]); // if constexpr (I < N)
VectorSpaceOps<N, I+1>::op(vs, vs1, vs2, o); {
vs.v_[I] = o(vs1.v_[I], vs2.v_[I]);
VectorSpaceOps<N, I+1>::op(vs, vs1, vs2, o);
}
} }
}; };
//- Loop termination form, when index and loop count \<N\> are identical //- Loop termination form, when index and loop count \<N\> are identical
// Not really needed with c++17 'if constexpr' except that gcc-7, gcc-8
// produce spurious warnings about unused parameters
template<direction N> template<direction N>
struct VectorSpaceOps<N, N> struct VectorSpaceOps<N, N>
{ {

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2014 OpenFOAM Foundation Copyright (C) 2011-2014 OpenFOAM Foundation
Copyright (C) 2019-2023 OpenCFD Ltd. Copyright (C) 2019-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -320,22 +320,16 @@ namespace Detail
//- The 'conjugate' of non-complex returns itself (pass-through) //- The 'conjugate' of non-complex returns itself (pass-through)
//- it does not return a complex! //- it does not return a complex!
template<class T> template<class T>
typename std::enable_if std::enable_if_t<!std::is_same_v<complex, T>, const T&>
< conj(const T& val)
!std::is_same<complex, T>::value,
const T&
>::type conj(const T& val)
{ {
return val; return val;
} }
//- The conjugate of a complex number //- The conjugate of a complex number
template<class T> template<class T>
typename std::enable_if std::enable_if_t<std::is_same_v<complex, T>, complex>
< conj(const T& val)
std::is_same<complex, T>::value,
complex
>::type conj(const T& val)
{ {
return val.conjugate(); return val.conjugate();
} }

View File

@ -72,7 +72,7 @@ class Enum
// Allow enums and integrals (should fit within an int) // Allow enums and integrals (should fit within an int)
static_assert static_assert
( (
std::is_enum<EnumType>::value || std::is_integral<EnumType>::value, std::is_enum_v<EnumType> || std::is_integral_v<EnumType>,
"Enum must be enum or an integral type" "Enum must be enum or an integral type"
); );

View File

@ -72,7 +72,7 @@ Type Foam::Function1Types::CSV<Type>::readValue
{ {
Type result; Type result;
if (std::is_integral<Type>::value) if constexpr (std::is_integral_v<Type>)
{ {
// nComponents == 1 // nComponents == 1
setComponent(result, 0) = readLabel(strings[componentColumns_[0]]); setComponent(result, 0) = readLabel(strings[componentColumns_[0]]);

Some files were not shown because too many files have changed in this diff Show More