ENH: extend UList<bool> specializations to include any(), all(), none()

- simplifies code with boolList vs. bitSet
This commit is contained in:
Mark Olesen
2025-08-26 12:32:14 +02:00
parent 2446f3f0c7
commit 3ad17ddf5e
14 changed files with 151 additions and 60 deletions

View File

@ -1,3 +1,3 @@
Test-bitSet1.C Test-bitSet1.cxx
EXE = $(FOAM_USER_APPBIN)/Test-bitSet1 EXE = $(FOAM_USER_APPBIN)/Test-bitSet1

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
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.
@ -75,9 +75,9 @@ inline Ostream& info(const UList<bool>& bools)
Info<< "size=" << bools.size() Info<< "size=" << bools.size()
<< " count=" << BitOps::count(bools) << " count=" << BitOps::count(bools)
<< " !count=" << BitOps::count(bools, false) << " !count=" << BitOps::count(bools, false)
<< " all:" << BitOps::all(bools) << " all:" << bools.all()
<< " any:" << BitOps::any(bools) << " any:" << bools.any()
<< " none:" << BitOps::none(bools) << nl; << " none:" << bools.none() << nl;
return Info; return Info;
} }
@ -194,8 +194,10 @@ int main(int argc, char *argv[])
{ {
boolList bools = list1.values(); boolList bools = list1.values();
Info<<"===============" << nl; Info<< "===============" << nl;
Info<<"bools: " << flatOutput(bools) << nl; Info<< "bools: " << flatOutput(bools) << nl;
Info<< " ";
info(bools);
for (int i : { -10, 0, 8, 15, 32}) for (int i : { -10, 0, 8, 15, 32})
{ {
@ -238,17 +240,18 @@ int main(int argc, char *argv[])
} }
#ifdef TEST_SFINAE #ifdef TEST_SFINAE
// This should fail to compile:
{ {
labelList labels = list1.toc(); labelList labels = list1.toc();
if (labels.test(0)) if (labels.test(0))
{ {
Info<<"no" << endl; Info<< "no" << endl;
} }
List<double*> ptrs(10, nullptr); List<double*> ptrs(10, nullptr);
if (ptrs.get(0)) if (ptrs.get(0))
{ {
Info<<"no" << endl; Info<< "no" << endl;
} }
} }
#endif #endif

View File

@ -1,3 +1,3 @@
Test-boolList.C Test-boolList.cxx
EXE = $(FOAM_USER_APPBIN)/Test-boolList EXE = $(FOAM_USER_APPBIN)/Test-boolList

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.
@ -71,9 +71,9 @@ inline Ostream& info(const UList<bool>& bools)
Info<< "size=" << bools.size() Info<< "size=" << bools.size()
<< " count=" << BitOps::count(bools) << " count=" << BitOps::count(bools)
<< " !count=" << BitOps::count(bools, false) << " !count=" << BitOps::count(bools, false)
<< " all:" << BitOps::all(bools) << " all:" << bools.all()
<< " any:" << BitOps::any(bools) << " any:" << bools.any()
<< " none:" << BitOps::none(bools) << nl; << " none:" << bools.none() << nl;
return Info; return Info;
} }

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.
@ -33,6 +33,12 @@ License
// * * * * * * * * * * * * * * * * * BitOps * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * BitOps * * * * * * * * * * * * * * * * //
unsigned int Foam::BitOps::count(const bitSet& bitset, const bool on)
{
return bitset.count(on);
}
// See bitSet::setMany for original implementation // See bitSet::setMany for original implementation
void Foam::BitOps::set(List<bool>& bools, const labelUList& locations) void Foam::BitOps::set(List<bool>& bools, const labelUList& locations)
{ {

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.
@ -77,26 +77,17 @@ inline unsigned int count(const UList<bool>& bools, const bool val=true)
return std::count(bools.begin(), bools.end(), val); return std::count(bools.begin(), bools.end(), val);
} }
//- True if all entries are 'true' or if the set is empty. //- True if all entries are 'true' or if the list is empty.
// For compatibility with bitSet::all() // For compatibility with bitSet::all()
inline bool all(const UList<bool>& bools) inline bool all(const UList<bool>& bools) { return bools.all(); }
{
return std::all_of(bools.begin(), bools.end(), identityOp());
}
//- True if any entries are 'true'. //- True if any entries are 'true'.
// For compatibility with bitSet::any() // For compatibility with bitSet::any()
inline bool any(const UList<bool>& bools) inline bool any(const UList<bool>& bools) { return bools.any(); }
{
return std::any_of(bools.begin(), bools.end(), identityOp());
}
//- True if no entries are 'true'. //- True if no entries are 'true'.
// For compatibility with bitSet::none() // For compatibility with bitSet::none()
inline bool none(const UList<bool>& bools) inline bool none(const UList<bool>& bools) { return bools.none(); }
{
return std::none_of(bools.begin(), bools.end(), identityOp());
}
//- Set the listed locations (assign 'true'). //- Set the listed locations (assign 'true').
@ -150,6 +141,10 @@ List<bool> select(const label n, const labelUList& locations);
// \return a List of bools // \return a List of bools
List<bool> select(const labelUList& locations); List<bool> select(const labelUList& locations);
//- Forward to bitSet::count()
unsigned int count(const bitSet& bitset, const bool on=true);
//- Return the (sorted) values corresponding to 'true' entries. //- Return the (sorted) values corresponding to 'true' entries.
// Similar to bitSet::toc() // Similar to bitSet::toc()
// //
@ -292,13 +287,13 @@ struct bitInfo
constexpr bitInfo() noexcept : value(0) {} constexpr bitInfo() noexcept : value(0) {}
//- Value construct //- Value construct
explicit bitInfo(UIntType val) : value(val) {} explicit bitInfo(UIntType val) noexcept : value(val) {}
//- Conversion to base type //- Conversion to base type
operator UIntType () const { return value; } operator UIntType () const noexcept { return value; }
//- Conversion to base type //- Conversion to base type
operator UIntType& () { return value; } operator UIntType& () noexcept { return value; }
}; };
} // End namespace BitOps } // End namespace BitOps

View File

@ -565,11 +565,38 @@ public:
// Special Methods // Special Methods
//- True if all entries are 'true' or if the list is empty.
// \note Method name compatibility with bitSet
template<class TypeT = T>
std::enable_if_t<std::is_same_v<bool, std::remove_cv_t<TypeT>>, bool>
inline all() const
{
return !contains(false);
}
//- True if any entries are 'true'.
// \note Method name compatibility with bitSet
template<class TypeT = T>
std::enable_if_t<std::is_same_v<bool, std::remove_cv_t<TypeT>>, bool>
inline any() const
{
return contains(true);
}
//- True if no entries are 'true'.
// \note Method name compatibility with bitSet
template<class TypeT = T>
std::enable_if_t<std::is_same_v<bool, std::remove_cv_t<TypeT>>, bool>
inline none() const
{
return !contains(true);
}
//- Test \c bool value at specified position, //- Test \c bool value at specified position,
//- 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>
std::enable_if_t<std::is_same_v<bool, TypeT>, bool> std::enable_if_t<std::is_same_v<bool, std::remove_cv_t<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]);
@ -579,7 +606,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>
std::enable_if_t<std::is_same_v<bool, TypeT>, bool> std::enable_if_t<std::is_same_v<bool, std::remove_cv_t<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]);

View File

@ -348,29 +348,25 @@ inline void Foam::UList<T>::operator=(const T& val)
} }
namespace Foam
{
// Template specialization for bool
template<>
inline const bool& Foam::UList<bool>::operator[](const label i) const
{
// Lazy evaluation - return false for out-of-range
if (i >= 0 && i < size_)
{
return v_[i];
}
return Foam::pTraits<bool>::zero;
}
} // End namespace Foam
template<class T> template<class T>
inline T& Foam::UList<T>::operator[](const label i) inline T& Foam::UList<T>::operator[](const label i)
{ {
#ifdef FULLDEBUG if constexpr (std::is_same_v<bool, std::remove_cv_t<T>>)
checkIndex(i); {
#endif // Lazy evaluation - return false for out-of-range
// Note: strictly speaking should not be modifiable but we cannot
// alway control which signature (const or non-const) is called
if (i < 0 || i >= size_)
{
return const_cast<bool&>(Foam::pTraits<bool>::null());
}
}
else
{
#ifdef FULLDEBUG
checkIndex(i);
#endif
}
return v_[i]; return v_[i];
} }
@ -378,9 +374,20 @@ inline T& Foam::UList<T>::operator[](const label i)
template<class T> template<class T>
inline const T& Foam::UList<T>::operator[](const label i) const inline const T& Foam::UList<T>::operator[](const label i) const
{ {
#ifdef FULLDEBUG if constexpr (std::is_same_v<bool, std::remove_cv_t<T>>)
checkIndex(i); {
#endif // Lazy evaluation - return false for out-of-range
if (i < 0 || i >= size_)
{
return Foam::pTraits<bool>::null();
}
}
else
{
#ifdef FULLDEBUG
checkIndex(i);
#endif
}
return v_[i]; return v_[i];
} }

View File

@ -658,6 +658,18 @@ inline void identity(labelUList& map, label start = 0)
} }
//- Count the occurrences of the given element.
// When start is specified, any occurrences before start are ignored.
// Like std::count but works with list indexing
template<class ListType>
label count
(
const ListType& input,
typename ListType::const_reference val,
const label start=0
);
//- Count the number of matching entries. //- Count the number of matching entries.
// When start is specified, any occurrences before start are ignored. // When start is specified, any occurrences before start are ignored.
// Linear search. // Linear search.

View File

@ -1154,6 +1154,33 @@ bool Foam::ListOps::equal
} }
template<class ListType>
Foam::label Foam::ListOps::count
(
const ListType& input,
typename ListType::const_reference val,
const label start
)
{
label num = 0;
const label len = input.size();
if (start >= 0)
{
for (label i = start; i < len; ++i)
{
if (val == input[i])
{
++num;
}
}
}
return num;
}
template<class ListType, class UnaryPredicate> template<class ListType, class UnaryPredicate>
Foam::label Foam::ListOps::count_if Foam::label Foam::ListOps::count_if
( (

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.
@ -38,6 +38,16 @@ const char* const Foam::pTraits<bool>::componentNames[] = { "" };
const bool Foam::pTraits<bool>::zero = false; const bool Foam::pTraits<bool>::zero = false;
const bool Foam::pTraits<bool>::one = true; const bool Foam::pTraits<bool>::one = true;
bool Foam::pTraits<bool>::dummy = false;
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
const bool& Foam::pTraits<bool>::null() noexcept
{
dummy = false;
return dummy;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //

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-2021 OpenCFD Ltd. Copyright (C) 2019-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -97,6 +97,10 @@ public:
static const char* const componentNames[]; static const char* const componentNames[];
static const bool zero; static const bool zero;
static const bool one; static const bool one;
static bool dummy; //!< Dummy for return reference
//- Return reference to a (false) dummy value
static const bool& null() noexcept;
// Constructors // Constructors

View File

@ -512,7 +512,7 @@ Foam::labelList Foam::decompositionMethod::decompose
const bool hasUnblocked = const bool hasUnblocked =
returnReduceOr returnReduceOr
( (
!blockedFace.empty() && !BitOps::all(blockedFace) !blockedFace.empty() && !blockedFace.all()
); );