diff --git a/src/OpenFOAM/containers/Lists/ListOps/ListOps.C b/src/OpenFOAM/containers/Lists/ListOps/ListOps.C
index 5524ba27e9de2020cccd867b25a91fefb3d6f948..58f95736bb920db080df4f5c2504cbfb43793881 100644
--- a/src/OpenFOAM/containers/Lists/ListOps/ListOps.C
+++ b/src/OpenFOAM/containers/Lists/ListOps/ListOps.C
@@ -82,7 +82,7 @@ Foam::labelListList Foam::invertOneToMany
 
     labelListList inverse(len);
 
-    for (label i=0; i<len; ++i)
+    for (label i=0; i < len; ++i)
     {
         inverse[i].resize(sizes[i]);
         sizes[i] = 0; // reset size counter
diff --git a/src/OpenFOAM/containers/Lists/ListOps/ListOps.H b/src/OpenFOAM/containers/Lists/ListOps/ListOps.H
index c4058fd94b19ba2d42ed85afa7babd39f6808428..737941993805c9bc6b88a348af0389b55d0d2a4a 100644
--- a/src/OpenFOAM/containers/Lists/ListOps/ListOps.H
+++ b/src/OpenFOAM/containers/Lists/ListOps/ListOps.H
@@ -59,10 +59,10 @@ namespace Foam
 //  Compare to List::null() which returns null pointer cast as list reference.
 //
 //  \deprecated This cast is disallowed with many modern compilers (JUL-2018)
-template<class Type>
-static const List<Type>& emptyList()
+template<class T>
+static const List<T>& emptyList()
 {
-    return *reinterpret_cast<const List<Type>*>(&emptyLabelList);
+    return *reinterpret_cast<const List<T>*>(&emptyLabelList);
 }
 
 
@@ -245,35 +245,51 @@ void inplaceUniqueSort
 );
 
 
-//- Extract elements of the input List when select is true.
+//- Extract elements of the input list when select is true.
 //
-//  \param select the bool-list selector, for which the operator[]
+//  \param[in] select the bool-list selector, for which the operator[]
 //      returns true or false.  A labelHashSet can also be used since
 //      it satisfies these requirements
-//  \param input the list input values. Cannot be a FixedList since
-//      it doesn't resize.
-//  \param invert set as true to invert the selection logic
+//  \param[in] input the list input values.
+//  \param[in] invert set as true to invert the selection logic
 //
 //  Eg, to extract all selected elements:
 //  \code
 //    subset<boolList, labelList>(selectedElems, list);
 //  \endcode
-template<class BoolListType, class ListType>
-ListType subset
+//
+//  \return The subsetted list
+template<class BoolListType, class T>
+List<T> subset
 (
     const BoolListType& select,
-    const ListType& input,
+    const UList<T>& input,
     const bool invert=false
 );
 
-//- Inplace extract elements of the input List when select is true.
+//- Extract elements of the input list when select is true.
+//
+//  \param[in] select the selection as a bitSet.
+//  \param[in] input the list input values.
+//  \param[in] invert set as true to invert the selection logic
 //
-//  \param select the bool-list selector, for which the operator[]
+//  \return The subsetted list
+template<class T>
+List<T> subset
+(
+    const bitSet& select,
+    const UList<T>& input,
+    const bool invert=false
+);
+
+//- Inplace extract elements of the input list when select is true.
+//
+//  \param[in] select the bool-list selector, for which the operator[]
 //      returns true or false.  A labelHashSet can also be used since
 //      it satisfies these requirements
-//  \param input the list input values. Cannot be a FixedList since
-//      it doesn't resize.
-//  \param invert set as true to invert the selection logic
+//  \param[in,out] input the list input values.
+//      Cannot be a FixedList since it doesn't resize.
+//  \param[in] invert set as true to invert the selection logic
 template<class BoolListType, class ListType>
 void inplaceSubset
 (
@@ -282,19 +298,42 @@ void inplaceSubset
     const bool invert=false
 );
 
+//- Inplace extract elements of the input list when select is true.
+//
+//  \param[in] select the selection as a bitSet.
+//  \param[in,out] input the list input values.
+//      Cannot be a FixedList since it doesn't resize.
+//  \param[in] invert set as true to invert the selection logic
+//
+//  \note Includes optimized handling of bitSet when invert=false.
+template<class ListType>
+void inplaceSubset
+(
+    const bitSet& select,
+    ListType& input,
+    const bool invert=false
+);
 
 //- Copy a subset of the input list when predicate is true.
-//  Do not use FixedList for the input list, since it doesn't resize.
-template<class ListType, class UnaryPredicate>
-ListType subsetList
+//
+//  \param[in,out] input the list input values.
+//  \param[in] pred the selection predicate
+//  \param[in] invert set as true to invert the selection logic
+template<class T, class UnaryPredicate>
+List<T> subsetList
 (
-    const ListType& input,
+    const UList<T>& input,
     const UnaryPredicate& pred,
     const bool invert=false
 );
 
+
 //- Inplace subset of the list when predicate is true.
-//  Do not use FixedList for the input list, since it doesn't resize.
+//
+//  \param[in,out] input the list input/output values.
+//       Cannot be a FixedList since it doesn't resize.
+//  \param[in] pred the selection predicate
+//  \param[in] invert set as true to invert the selection logic
 template<class ListType, class UnaryPredicate>
 void inplaceSubsetList
 (
diff --git a/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C b/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C
index 2fad7cccc8b15306c8f1667093a2b0817d719771..f6236a031ad8e04a3065785618f790a4f985b466 100644
--- a/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C
+++ b/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C
@@ -470,22 +470,22 @@ void Foam::inplaceUniqueSort
 }
 
 
-template<class BoolListType, class ListType>
-ListType Foam::subset
+template<class BoolListType, class T>
+Foam::List<T> Foam::subset
 (
     const BoolListType& select,
-    const ListType& input,
+    const UList<T>& input,
     const bool invert
 )
 {
-    const label len = input.size();
+    // Note: select can have a different size (eg, labelHashSet)
 
-    // select can have a different size (eg, bitSet, labelHashSet)
+    const label len = input.size();
 
-    ListType output(len);
-    output.resize(len);   // Consistent sizing (eg, DynamicList)
+    List<T> output(len);
 
     label count = 0;
+
     for (label i=0; i < len; ++i)
     {
         if (select[i] ? !invert : invert)
@@ -494,6 +494,55 @@ ListType Foam::subset
             ++count;
         }
     }
+
+    output.resize(count);
+
+    return output;
+}
+
+
+template<class T>
+Foam::List<T> Foam::subset
+(
+    const bitSet& select,
+    const UList<T>& input,
+    const bool invert
+)
+{
+    const label len = input.size();
+
+    List<T> output;
+
+    label count = 0;
+
+    if (!invert)
+    {
+        output.resize(select.count());
+
+        for (const label i : select)
+        {
+            if (i >= len) break; // Avoid out of bounds (when select is longer)
+
+            output[count] = input[i];
+            ++count;
+        }
+    }
+    else
+    {
+        const label outlen = (select.size() - select.count());
+        output.resize(outlen);
+
+        for (label i=0; i < len; ++i)
+        {
+            if (!select[i])
+            {
+                output[count] = input[i];
+                ++count;
+                if (count >= outlen) break;  // terminate early
+            }
+        }
+    }
+
     output.resize(count);
 
     return output;
@@ -508,11 +557,12 @@ void Foam::inplaceSubset
     const bool invert
 )
 {
-    const label len = input.size();
+    // Note: select can have a different size (eg, labelHashSet)
 
-    // select can have a different size (eg, bitSet, labelHashSet)
+    const label len = input.size();
 
     label count = 0;
+
     for (label i=0; i < len; ++i)
     {
         if (select[i] ? !invert : invert)
@@ -524,22 +574,75 @@ void Foam::inplaceSubset
             ++count;
         }
     }
+
+    input.resize(count);
+}
+
+
+template<class ListType>
+void Foam::inplaceSubset
+(
+    const bitSet& select,
+    ListType& input,
+    const bool invert
+)
+{
+    label count = 0;
+
+    if (!invert)
+    {
+        // Normal selection
+
+        const label len = input.size();
+
+        for (const label i : select)
+        {
+            if (i >= len) break;
+
+            if (count != i)
+            {
+                input[count] = std::move(input[i]);
+            }
+            ++count;
+        }
+    }
+    else
+    {
+        // Inverted selection
+
+        const label outlen = (select.size() - select.count());
+
+        const label len = min(input.size(), select.size());
+
+        for (label i=0; i < len; ++i)
+        {
+            if (!select[i])
+            {
+                if (count != i)
+                {
+                    input[count] = std::move(input[i]);
+                }
+                ++count;
+                if (count >= outlen) break;  // terminate early
+            }
+        }
+    }
+
     input.resize(count);
 }
 
 
-template<class ListType, class UnaryPredicate>
-ListType Foam::subsetList
+template<class T, class UnaryPredicate>
+Foam::List<T> Foam::subsetList
 (
-    const ListType& input,
+    const UList<T>& input,
     const UnaryPredicate& pred,
     const bool invert
 )
 {
     const label len = input.size();
 
-    ListType output(len);
-    output.resize(len);  // Consistent sizing (eg, DynamicList)
+    List<T> output(len);
 
     label count = 0;
     for (label i=0; i < len; ++i)
@@ -550,6 +653,7 @@ ListType Foam::subsetList
             ++count;
         }
     }
+
     output.resize(count);
 
     return output;
@@ -593,10 +697,8 @@ void Foam::invertManyToMany
     // The output list sizes
     labelList sizes(len, 0);
 
-    forAll(input, listi)
+    for (const InputIntListType& sublist : input)
     {
-        const InputIntListType& sublist = input[listi];
-
         forAll(sublist, idx)
         {
             sizes[sublist[idx]]++;