diff --git a/applications/test/bitSet1/Make/files b/applications/test/bitSet1/Make/files index c87b831b38..7104798002 100644 --- a/applications/test/bitSet1/Make/files +++ b/applications/test/bitSet1/Make/files @@ -1,3 +1,3 @@ -Test-bitSet1.C +Test-bitSet1.cxx EXE = $(FOAM_USER_APPBIN)/Test-bitSet1 diff --git a/applications/test/bitSet1/Test-bitSet1.C b/applications/test/bitSet1/Test-bitSet1.cxx similarity index 100% rename from applications/test/bitSet1/Test-bitSet1.C rename to applications/test/bitSet1/Test-bitSet1.cxx diff --git a/applications/test/bitSet2/Test-bitSet2.cxx b/applications/test/bitSet2/Test-bitSet2.cxx index 8f9f5d487e..6b0675b836 100644 --- a/applications/test/bitSet2/Test-bitSet2.cxx +++ b/applications/test/bitSet2/Test-bitSet2.cxx @@ -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& 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 ptrs(10, nullptr); if (ptrs.get(0)) { - Info<<"no" << endl; + Info<< "no" << endl; } } #endif diff --git a/applications/test/boolList/Make/files b/applications/test/boolList/Make/files index 9cbdcc0808..cde3a1614a 100644 --- a/applications/test/boolList/Make/files +++ b/applications/test/boolList/Make/files @@ -1,3 +1,3 @@ -Test-boolList.C +Test-boolList.cxx EXE = $(FOAM_USER_APPBIN)/Test-boolList diff --git a/applications/test/boolList/Test-boolList.C b/applications/test/boolList/Test-boolList.cxx similarity index 96% rename from applications/test/boolList/Test-boolList.C rename to applications/test/boolList/Test-boolList.cxx index a55fe67a9b..36b96440a8 100644 --- a/applications/test/boolList/Test-boolList.C +++ b/applications/test/boolList/Test-boolList.cxx @@ -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& 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; } diff --git a/src/OpenFOAM/containers/Bits/BitOps/BitOps.C b/src/OpenFOAM/containers/Bits/BitOps/BitOps.C index 83f052543c..1e0fbaf938 100644 --- a/src/OpenFOAM/containers/Bits/BitOps/BitOps.C +++ b/src/OpenFOAM/containers/Bits/BitOps/BitOps.C @@ -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& bools, const labelUList& locations) { diff --git a/src/OpenFOAM/containers/Bits/BitOps/BitOps.H b/src/OpenFOAM/containers/Bits/BitOps/BitOps.H index fb0e1688fb..aa3b8edea2 100644 --- a/src/OpenFOAM/containers/Bits/BitOps/BitOps.H +++ b/src/OpenFOAM/containers/Bits/BitOps/BitOps.H @@ -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& 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& bools) -{ - return std::all_of(bools.begin(), bools.end(), identityOp()); -} +inline bool all(const UList& bools) { return bools.all(); } //- True if any entries are 'true'. // For compatibility with bitSet::any() -inline bool any(const UList& bools) -{ - return std::any_of(bools.begin(), bools.end(), identityOp()); -} +inline bool any(const UList& bools) { return bools.any(); } //- True if no entries are 'true'. // For compatibility with bitSet::none() -inline bool none(const UList& bools) -{ - return std::none_of(bools.begin(), bools.end(), identityOp()); -} +inline bool none(const UList& bools) { return bools.none(); } //- Set the listed locations (assign 'true'). @@ -150,6 +141,10 @@ List select(const label n, const labelUList& locations); // \return a List of bools List 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 diff --git a/src/OpenFOAM/containers/Lists/List/UList.H b/src/OpenFOAM/containers/Lists/List/UList.H index a446eca351..15418892d2 100644 --- a/src/OpenFOAM/containers/Lists/List/UList.H +++ b/src/OpenFOAM/containers/Lists/List/UList.H @@ -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 + std::enable_if_t>, bool> + inline all() const + { + return !contains(false); + } + + //- True if any entries are 'true'. + // \note Method name compatibility with bitSet + template + std::enable_if_t>, bool> + inline any() const + { + return contains(true); + } + + //- True if no entries are 'true'. + // \note Method name compatibility with bitSet + template + std::enable_if_t>, 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 - std::enable_if_t, bool> + std::enable_if_t>, 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 - std::enable_if_t, bool> + std::enable_if_t>, bool> inline get(const label i) const { return (i >= 0 && i < size_ && v_[i]); diff --git a/src/OpenFOAM/containers/Lists/List/UListI.H b/src/OpenFOAM/containers/Lists/List/UListI.H index 9e544cbfcf..d90e72e74e 100644 --- a/src/OpenFOAM/containers/Lists/List/UListI.H +++ b/src/OpenFOAM/containers/Lists/List/UListI.H @@ -348,29 +348,25 @@ inline void Foam::UList::operator=(const T& val) } -namespace Foam -{ - // Template specialization for bool - template<> - inline const bool& Foam::UList::operator[](const label i) const - { - // Lazy evaluation - return false for out-of-range - if (i >= 0 && i < size_) - { - return v_[i]; - } - - return Foam::pTraits::zero; - } -} // End namespace Foam - - template inline T& Foam::UList::operator[](const label i) { - #ifdef FULLDEBUG - checkIndex(i); - #endif + if constexpr (std::is_same_v>) + { + // 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(Foam::pTraits::null()); + } + } + else + { + #ifdef FULLDEBUG + checkIndex(i); + #endif + } return v_[i]; } @@ -378,9 +374,20 @@ inline T& Foam::UList::operator[](const label i) template inline const T& Foam::UList::operator[](const label i) const { - #ifdef FULLDEBUG - checkIndex(i); - #endif + if constexpr (std::is_same_v>) + { + // Lazy evaluation - return false for out-of-range + if (i < 0 || i >= size_) + { + return Foam::pTraits::null(); + } + } + else + { + #ifdef FULLDEBUG + checkIndex(i); + #endif + } return v_[i]; } diff --git a/src/OpenFOAM/containers/Lists/ListOps/ListOps.H b/src/OpenFOAM/containers/Lists/ListOps/ListOps.H index 73b941d3a9..5343eb6384 100644 --- a/src/OpenFOAM/containers/Lists/ListOps/ListOps.H +++ b/src/OpenFOAM/containers/Lists/ListOps/ListOps.H @@ -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 +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. diff --git a/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C b/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C index a58efd291e..f743feaf0e 100644 --- a/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C +++ b/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C @@ -1154,6 +1154,33 @@ bool Foam::ListOps::equal } +template +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 Foam::label Foam::ListOps::count_if ( diff --git a/src/OpenFOAM/primitives/bools/bool/bool.C b/src/OpenFOAM/primitives/bools/bool/bool.C index cb796a5371..09770db906 100644 --- a/src/OpenFOAM/primitives/bools/bool/bool.C +++ b/src/OpenFOAM/primitives/bools/bool/bool.C @@ -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::componentNames[] = { "" }; const bool Foam::pTraits::zero = false; const bool Foam::pTraits::one = true; +bool Foam::pTraits::dummy = false; + + +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // + +const bool& Foam::pTraits::null() noexcept +{ + dummy = false; + return dummy; +} // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // diff --git a/src/OpenFOAM/primitives/bools/bool/bool.H b/src/OpenFOAM/primitives/bools/bool/bool.H index 090fae4137..b766903d63 100644 --- a/src/OpenFOAM/primitives/bools/bool/bool.H +++ b/src/OpenFOAM/primitives/bools/bool/bool.H @@ -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 diff --git a/src/parallel/decompose/decompositionMethods/decompositionMethod/decompositionMethod.C b/src/parallel/decompose/decompositionMethods/decompositionMethod/decompositionMethod.C index ba67ac8902..75a30f2f29 100644 --- a/src/parallel/decompose/decompositionMethods/decompositionMethod/decompositionMethod.C +++ b/src/parallel/decompose/decompositionMethods/decompositionMethod/decompositionMethod.C @@ -512,7 +512,7 @@ Foam::labelList Foam::decompositionMethod::decompose const bool hasUnblocked = returnReduceOr ( - !blockedFace.empty() && !BitOps::all(blockedFace) + !blockedFace.empty() && !blockedFace.all() );