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

View File

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

View File

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

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020-2022 OpenCFD Ltd.
Copyright (C) 2020-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -71,9 +71,9 @@ inline Ostream& info(const UList<bool>& bools)
Info<< "size=" << bools.size()
<< " count=" << BitOps::count(bools)
<< " !count=" << BitOps::count(bools, false)
<< " all:" << BitOps::all(bools)
<< " any:" << BitOps::any(bools)
<< " none:" << BitOps::none(bools) << nl;
<< " all:" << bools.all()
<< " any:" << bools.any()
<< " none:" << bools.none() << nl;
return Info;
}

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018-2023 OpenCFD Ltd.
Copyright (C) 2018-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -33,6 +33,12 @@ License
// * * * * * * * * * * * * * * * * * BitOps * * * * * * * * * * * * * * * * //
unsigned int Foam::BitOps::count(const bitSet& bitset, const bool on)
{
return bitset.count(on);
}
// See bitSet::setMany for original implementation
void Foam::BitOps::set(List<bool>& bools, const labelUList& locations)
{

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018-2023 OpenCFD Ltd.
Copyright (C) 2018-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
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);
}
//- 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()
inline bool all(const UList<bool>& bools)
{
return std::all_of(bools.begin(), bools.end(), identityOp());
}
inline bool all(const UList<bool>& bools) { return bools.all(); }
//- True if any entries are 'true'.
// For compatibility with bitSet::any()
inline bool any(const UList<bool>& bools)
{
return std::any_of(bools.begin(), bools.end(), identityOp());
}
inline bool any(const UList<bool>& bools) { return bools.any(); }
//- True if no entries are 'true'.
// For compatibility with bitSet::none()
inline bool none(const UList<bool>& bools)
{
return std::none_of(bools.begin(), bools.end(), identityOp());
}
inline bool none(const UList<bool>& bools) { return bools.none(); }
//- Set the listed locations (assign 'true').
@ -150,6 +141,10 @@ List<bool> select(const label n, const labelUList& locations);
// \return a List of bools
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.
// Similar to bitSet::toc()
//
@ -292,13 +287,13 @@ struct bitInfo
constexpr bitInfo() noexcept : value(0) {}
//- Value construct
explicit bitInfo(UIntType val) : value(val) {}
explicit bitInfo(UIntType val) noexcept : value(val) {}
//- Conversion to base type
operator UIntType () const { return value; }
operator UIntType () const noexcept { return value; }
//- Conversion to base type
operator UIntType& () { return value; }
operator UIntType& () noexcept { return value; }
};
} // End namespace BitOps

View File

@ -565,11 +565,38 @@ public:
// 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,
//- always false for out-of-range access.
// \note Method name compatibility with bitSet, HashSet
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
{
return (i >= 0 && i < size_ && v_[i]);
@ -579,7 +606,7 @@ public:
//- always false for out-of-range access.
// \note Method name compatibility with bitSet
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
{
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>
inline T& Foam::UList<T>::operator[](const label i)
{
#ifdef FULLDEBUG
checkIndex(i);
#endif
if constexpr (std::is_same_v<bool, std::remove_cv_t<T>>)
{
// 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];
}
@ -378,9 +374,20 @@ inline T& Foam::UList<T>::operator[](const label i)
template<class T>
inline const T& Foam::UList<T>::operator[](const label i) const
{
#ifdef FULLDEBUG
checkIndex(i);
#endif
if constexpr (std::is_same_v<bool, std::remove_cv_t<T>>)
{
// 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];
}

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.
// When start is specified, any occurrences before start are ignored.
// 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>
Foam::label Foam::ListOps::count_if
(

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2018-2021 OpenCFD Ltd.
Copyright (C) 2018-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
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>::one = true;
bool Foam::pTraits<bool>::dummy = false;
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
const bool& Foam::pTraits<bool>::null() noexcept
{
dummy = false;
return dummy;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //

View File

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

View File

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