Commit 61b50c01 authored by Mark Olesen's avatar Mark Olesen
Browse files

ENH: add subset() method to PackedBoolList

- support &= for UList<label>, UIndirectList<label>
- support set/unset for PackedList<1>
parent ba896b69
......@@ -89,52 +89,32 @@ bool Foam::PackedBoolList::bitorPrepare
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::PackedBoolList::PackedBoolList(Istream& is)
:
PackedList<1>()
{
is >> *this;
}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
Foam::Xfer<Foam::labelList> Foam::PackedBoolList::used() const
template<class LabelListType>
Foam::label Foam::PackedBoolList::setIndices(const LabelListType& indices)
{
labelList lst(this->count());
// no better information, just guess something about the size
reserve(indices.size());
if (lst.size())
label cnt = 0;
forAll(indices, elemI)
{
label nElem = 0;
forAll(*this, elemI)
if (set(indices[elemI]))
{
if (get(elemI))
{
lst[nElem++] = elemI;
}
++cnt;
}
lst.setSize(nElem);
}
return lst.xfer();
return cnt;
}
template<class LabelListType>
Foam::label Foam::PackedBoolList::setIndices(const LabelListType& indices)
Foam::label Foam::PackedBoolList::unsetIndices(const LabelListType& indices)
{
// no better information, just guess something about the size
reserve(indices.size());
label cnt = 0;
forAll(indices, elemI)
{
if (set(indices[elemI]))
if (unset(indices[elemI]))
{
++cnt;
}
......@@ -145,83 +125,110 @@ Foam::label Foam::PackedBoolList::setIndices(const LabelListType& indices)
template<class LabelListType>
Foam::label Foam::PackedBoolList::unsetIndices(const LabelListType& indices)
Foam::label Foam::PackedBoolList::subsetIndices(const LabelListType& indices)
{
// handle trivial case
if (empty() || indices.empty())
{
clear();
return 0;
}
// normal case
PackedBoolList anded;
anded.reserve(size());
label cnt = 0;
forAll(indices, elemI)
{
if (unset(indices[elemI]))
const label& index = indices[elemI];
if (operator[](index))
{
anded.set(index);
++cnt;
}
}
transfer(anded);
return cnt;
}
Foam::label Foam::PackedBoolList::set(const UList<label>& indices)
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::PackedBoolList::PackedBoolList(Istream& is)
:
PackedList<1>()
{
return setIndices(indices);
is >> *this;
}
Foam::label Foam::PackedBoolList::set(const UIndirectList<label>& indices)
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
void Foam::PackedBoolList::set(const PackedList<1>& lst)
{
return setIndices(indices);
// extend addressable area if needed, return maximum size possible
label len = 0;
const bool needTrim = bitorPrepare(lst, len);
// operate directly with the underlying storage
StorageList& lhs = this->storage();
const StorageList& rhs = lst.storage();
for (label i=0; i < len; ++i)
{
lhs[i] |= rhs[i];
}
if (needTrim)
{
trim();
}
}
Foam::label Foam::PackedBoolList::unset(const UList<label>& indices)
Foam::label Foam::PackedBoolList::set(const UList<label>& indices)
{
return unsetIndices(indices);
return setIndices(indices);
}
Foam::label Foam::PackedBoolList::unset(const UIndirectList<label>& indices)
Foam::label Foam::PackedBoolList::set(const UIndirectList<label>& indices)
{
return unsetIndices(indices);
return setIndices(indices);
}
// * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
Foam::PackedBoolList&
Foam::PackedBoolList::operator=(const UList<bool>& lst)
void Foam::PackedBoolList::unset(const PackedList<1>& lst)
{
this->setSize(lst.size());
// operate directly with the underlying storage
StorageList& lhs = this->storage();
const StorageList& rhs = lst.storage();
forAll(*this, elemI)
// overlapping storage size
const label len = min(this->packedLength(), lst.packedLength());
for (label i=0; i < len; ++i)
{
set(elemI, lst[elemI]);
lhs[i] &= ~rhs[i];
}
return *this;
}
Foam::PackedBoolList&
Foam::PackedBoolList::operator=(const UList<label>& indices)
Foam::label Foam::PackedBoolList::unset(const UList<label>& indices)
{
clear();
set(indices);
return *this;
return unsetIndices(indices);
}
Foam::PackedBoolList&
Foam::PackedBoolList::operator=(const UIndirectList<label>& indices)
Foam::label Foam::PackedBoolList::unset(const UIndirectList<label>& indices)
{
clear();
set(indices);
return *this;
return unsetIndices(indices);
}
Foam::PackedBoolList&
Foam::PackedBoolList::operator&=(const PackedList<1>& lst)
void Foam::PackedBoolList::subset(const PackedList<1>& lst)
{
// shrink addressable area if needed
if (this->size() > lst.size())
......@@ -239,30 +246,55 @@ Foam::PackedBoolList::operator&=(const PackedList<1>& lst)
{
lhs[i] &= rhs[i];
}
}
return *this;
Foam::label Foam::PackedBoolList::subset(const UList<label>& indices)
{
return subsetIndices(indices);
}
Foam::PackedBoolList&
Foam::PackedBoolList::operator^=(const PackedList<1>& lst)
Foam::label Foam::PackedBoolList::subset(const UIndirectList<label>& indices)
{
// extend addressable area if needed, return maximum size possible
label len = 0;
const bool needTrim = bitorPrepare(lst, len);
return subsetIndices(indices);
}
// operate directly with the underlying storage
StorageList& lhs = this->storage();
const StorageList& rhs = lst.storage();
for (label i=0; i < len; ++i)
Foam::Xfer<Foam::labelList> Foam::PackedBoolList::used() const
{
labelList lst(this->count());
if (lst.size())
{
lhs[i] ^= rhs[i];
label nElem = 0;
forAll(*this, elemI)
{
if (get(elemI))
{
lst[nElem++] = elemI;
}
}
lst.setSize(nElem);
}
if (needTrim)
return lst.xfer();
}
// * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
Foam::PackedBoolList&
Foam::PackedBoolList::operator=(const UList<bool>& lst)
{
this->setSize(lst.size());
// overwrite with new true/false values
forAll(*this, elemI)
{
trim();
set(elemI, lst[elemI]);
}
return *this;
......@@ -270,7 +302,7 @@ Foam::PackedBoolList::operator^=(const PackedList<1>& lst)
Foam::PackedBoolList&
Foam::PackedBoolList::operator|=(const PackedList<1>& lst)
Foam::PackedBoolList::operator^=(const PackedList<1>& lst)
{
// extend addressable area if needed, return maximum size possible
label len = 0;
......@@ -282,7 +314,7 @@ Foam::PackedBoolList::operator|=(const PackedList<1>& lst)
for (label i=0; i < len; ++i)
{
lhs[i] |= rhs[i];
lhs[i] ^= rhs[i];
}
if (needTrim)
......@@ -294,25 +326,6 @@ Foam::PackedBoolList::operator|=(const PackedList<1>& lst)
}
Foam::PackedBoolList&
Foam::PackedBoolList::operator-=(const PackedList<1>& lst)
{
// operate directly with the underlying storage
StorageList& lhs = this->storage();
const StorageList& rhs = lst.storage();
// overlapping storage size
const label len = min(this->packedLength(), lst.packedLength());
for (label i=0; i < len; ++i)
{
lhs[i] &= ~rhs[i];
}
return *this;
}
// * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * * //
Foam::PackedBoolList Foam::operator&
......
......@@ -75,6 +75,10 @@ class PackedBoolList
template<class LabelListType>
label unsetIndices(const LabelListType& indices);
//- Subset with the listed indices. Return number of elements subsetted.
template<class LabelListType>
label subsetIndices(const LabelListType& indices);
public:
// Constructors
......@@ -122,12 +126,12 @@ public:
// Access
//- Return indices of the used (true) elements as a list of labels
Xfer<labelList> used() const;
using PackedList<1>::set;
using PackedList<1>::unset;
//- Set specified bits.
void set(const PackedList<1>&);
//- Set the listed indices. Return number of elements changed.
// Does auto-vivify for non-existent entries.
label set(const UList<label>& indices);
......@@ -136,6 +140,9 @@ public:
// Does auto-vivify for non-existent entries.
label set(const UIndirectList<label>& indices);
//- Unset specified bits.
void unset(const PackedList<1>&);
//- Unset the listed indices. Return number of elements changed.
// Never auto-vivify entries.
label unset(const UList<label>& indices);
......@@ -144,6 +151,21 @@ public:
// Never auto-vivify entries.
label unset(const UIndirectList<label>& indices);
//- Subset with the specified list.
void subset(const PackedList<1>&);
//- Subset with the listed indices.
// Return number of elements subsetted.
label subset(const UList<label>& indices);
//- Subset with the listed indices.
// Return number of elements subsetted.
label subset(const UIndirectList<label>& indices);
//- Return indices of the used (true) elements as a list of labels
Xfer<labelList> used() const;
// Edit
......@@ -175,24 +197,32 @@ public:
//- Assignment operator,
// using the labels as indices to indicate which bits are set
PackedBoolList& operator=(const UList<label>& indices);
inline PackedBoolList& operator=(const UList<label>& indices);
//- Assignment operator,
// using the labels as indices to indicate which bits are set
PackedBoolList& operator=(const UIndirectList<label>& indices);
inline PackedBoolList& operator=(const UIndirectList<label>&);
//- Complement operator
inline PackedBoolList operator~() const;
//- And operator (lists may be dissimilar sizes)
PackedBoolList& operator&=(const PackedList<1>&);
inline PackedBoolList& operator&=(const PackedList<1>&);
//- And operator (lists may be dissimilar sizes)
// using the labels as indices to indicate which bits are set
inline PackedBoolList& operator&=(const UList<label>& indices);
//- And operator (lists may be dissimilar sizes)
// using the labels as indices to indicate which bits are set
inline PackedBoolList& operator&=(const UIndirectList<label>&);
//- Xor operator (lists may be dissimilar sizes)
// Retains unique entries
PackedBoolList& operator^=(const PackedList<1>&);
//- Or operator (lists may be dissimilar sizes)
PackedBoolList& operator|=(const PackedList<1>&);
inline PackedBoolList& operator|=(const PackedList<1>&);
//- Or operator (lists may be dissimilar sizes),
// using the labels as indices to indicate which bits are set
......@@ -213,7 +243,7 @@ public:
inline PackedBoolList& operator+=(const UIndirectList<label>&);
//- Remove entries from this list - unset the specified bits
PackedBoolList& operator-=(const PackedList<1>&);
inline PackedBoolList& operator-=(const PackedList<1>&);
//- Remove entries from this list - unset the specified bits
inline PackedBoolList& operator-=(const UList<label>& indices);
......
......@@ -151,6 +151,26 @@ Foam::PackedBoolList::operator=(const PackedList<1>& lst)
}
inline Foam::PackedBoolList&
Foam::PackedBoolList::operator=(const UList<label>& indices)
{
clear();
set(indices);
return *this;
}
inline Foam::PackedBoolList&
Foam::PackedBoolList::operator=(const UIndirectList<label>& indices)
{
clear();
set(indices);
return *this;
}
inline Foam::PackedBoolList
Foam::PackedBoolList::operator~() const
{
......@@ -161,6 +181,38 @@ Foam::PackedBoolList::operator~() const
}
inline Foam::PackedBoolList&
Foam::PackedBoolList::operator&=(const PackedList<1>& lst)
{
subset(lst);
return *this;
}
inline Foam::PackedBoolList&
Foam::PackedBoolList::operator&=(const UList<label>& indices)
{
subset(indices);
return *this;
}
inline Foam::PackedBoolList&
Foam::PackedBoolList::operator&=(const UIndirectList<label>& indices)
{
subset(indices);
return *this;
}
inline Foam::PackedBoolList&
Foam::PackedBoolList::operator|=(const PackedList<1>& lst)
{
set(lst);
return *this;
}
inline Foam::PackedBoolList&
Foam::PackedBoolList::operator|=(const UList<label>& indices)
{
......@@ -180,21 +232,29 @@ Foam::PackedBoolList::operator|=(const UIndirectList<label>& indices)
inline Foam::PackedBoolList&
Foam::PackedBoolList::operator+=(const PackedList<1>& lst)
{
return this->operator|=(lst);
return operator|=(lst);
}
inline Foam::PackedBoolList&
Foam::PackedBoolList::operator+=(const UList<label>& indices)
{
return this->operator|=(indices);
return operator|=(indices);
}
inline Foam::PackedBoolList&
Foam::PackedBoolList::operator+=(const UIndirectList<label>& indices)
{
return this->operator|=(indices);
return operator|=(indices);
}
inline Foam::PackedBoolList&
Foam::PackedBoolList::operator-=(const PackedList<1>& lst)
{
unset(lst);
return *this;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment