ENH: minor update of PackedList methods

- additional convenience constructors
This commit is contained in:
Mark Olesen
2017-10-07 16:10:35 +02:00
parent f76552f7f9
commit 4ba4899660
6 changed files with 131 additions and 93 deletions

View File

@ -41,7 +41,7 @@ using namespace Foam;
template<unsigned nBits>
inline void reportInfo()
{
unsigned offset = PackedList<nBits>::packing();
const unsigned offset = PackedList<nBits>::packing();
unsigned useSHL = ((1u << (nBits * offset)) - 1);
unsigned useSHR = (~0u >> (sizeof(unsigned)*CHAR_BIT - nBits * offset));

View File

@ -92,13 +92,15 @@ bool Foam::PackedBoolList::bitorPrepare
template<class LabelListType>
Foam::label Foam::PackedBoolList::setIndices(const LabelListType& indices)
{
// no better information, just guess something about the size
reserve(indices.size());
const label len = indices.size();
// No better information, just guess something from the size
reserve(len);
label cnt = 0;
forAll(indices, elemI)
for (label i = 0; i < len; ++i)
{
if (set(indices[elemI]))
if (set(indices[i]))
{
++cnt;
}
@ -112,9 +114,10 @@ template<class LabelListType>
Foam::label Foam::PackedBoolList::unsetIndices(const LabelListType& indices)
{
label cnt = 0;
forAll(indices, elemI)
const label len = indices.size();
for (label i = 0; i < len; ++i)
{
if (unset(indices[elemI]))
if (unset(indices[i]))
{
++cnt;
}
@ -127,29 +130,30 @@ Foam::label Foam::PackedBoolList::unsetIndices(const LabelListType& indices)
template<class LabelListType>
Foam::label Foam::PackedBoolList::subsetIndices(const LabelListType& indices)
{
// handle trivial case
if (empty() || indices.empty())
const label len = indices.size();
// Handle trivial case
if (empty() || !len)
{
clear();
return 0;
}
// normal case
PackedBoolList anded;
anded.reserve(size());
PackedBoolList result;
result.reserve(size());
label cnt = 0;
forAll(indices, elemI)
for (label i = 0; i < len; ++i)
{
const label& index = indices[elemI];
if (operator[](index))
const label index = indices[i];
if (get(index))
{
anded.set(index);
result.set(index);
++cnt;
}
}
transfer(anded);
transfer(result);
return cnt;
}
@ -176,7 +180,7 @@ void Foam::PackedBoolList::set(const PackedList<1>& lst)
StorageList& lhs = this->storage();
const StorageList& rhs = lst.storage();
for (label i=0; i < len; ++i)
for (label i = 0; i < len; ++i)
{
lhs[i] |= rhs[i];
}
@ -209,7 +213,7 @@ void Foam::PackedBoolList::unset(const PackedList<1>& lst)
// overlapping storage size
const label len = min(this->packedLength(), lst.packedLength());
for (label i=0; i < len; ++i)
for (label i = 0; i < len; ++i)
{
lhs[i] &= ~rhs[i];
}
@ -242,7 +246,7 @@ void Foam::PackedBoolList::subset(const PackedList<1>& lst)
const label len = this->packedLength();
for (label i=0; i < len; ++i)
for (label i = 0; i < len; ++i)
{
lhs[i] &= rhs[i];
}
@ -288,12 +292,13 @@ Foam::Xfer<Foam::labelList> Foam::PackedBoolList::used() const
void Foam::PackedBoolList::operator=(const UList<bool>& lst)
{
this->setSize(lst.size());
const label len = lst.size();
this->setSize(len);
// overwrite with new true/false values
forAll(*this, elemI)
// Overwrite with new true/false values
for (label i = 0; i < len; ++i)
{
set(elemI, lst[elemI]);
set(i, lst[i]);
}
}
@ -301,15 +306,15 @@ void Foam::PackedBoolList::operator=(const UList<bool>& lst)
Foam::PackedBoolList&
Foam::PackedBoolList::operator^=(const PackedList<1>& lst)
{
// extend addressable area if needed, return maximum size possible
// Extend addressable area if needed, return maximum size possible
label len = 0;
const bool needTrim = bitorPrepare(lst, len);
// operate directly with the underlying storage
// Operate directly with the underlying storage
StorageList& lhs = this->storage();
const StorageList& rhs = lst.storage();
for (label i=0; i < len; ++i)
for (label i = 0; i < len; ++i)
{
lhs[i] ^= rhs[i];
}
@ -334,7 +339,7 @@ Foam::PackedBoolList Foam::operator&
PackedBoolList result(lst1);
result &= lst2;
// trim to bits actually used
// Trim to bits actually used
result.trim();
return result;
@ -350,7 +355,7 @@ Foam::PackedBoolList Foam::operator^
PackedBoolList result(lst1);
result ^= lst2;
// trim to bits actually used
// Trim to bits actually used
result.trim();
return result;

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -96,7 +96,7 @@ public:
//- Construct from Istream
PackedBoolList(Istream& is);
//- Construct with given size, initializes list to 0
//- Construct with given size, initializes list to 0 (false)
explicit inline PackedBoolList(const label size);
//- Construct with given size and value for all elements
@ -114,6 +114,20 @@ public:
//- Construct by transferring the parameter contents
inline PackedBoolList(const Xfer<PackedList<1>>& lst);
//- Construct with given size and list of labels to set as true.
inline PackedBoolList
(
const label size,
const labelUList& indices
);
//- Construct with given size and list of labels to set as true.
inline PackedBoolList
(
const label size,
const UIndirectList<label>& indices
);
//- Construct from a list of bools
explicit inline PackedBoolList(const UList<bool>& lst);

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -75,23 +75,52 @@ inline Foam::PackedBoolList::PackedBoolList(const Xfer<PackedList<1>>& lst)
inline Foam::PackedBoolList::PackedBoolList(const UList<bool>& lst)
:
PackedList<1>()
PackedList<1>(lst.size())
{
operator=(lst);
// Set according to indices that are true
const label len = lst.size();
for (label i = 0; i < len; ++i)
{
if (lst[i])
{
this->set(i, 1u);
}
}
}
inline Foam::PackedBoolList::PackedBoolList(const labelUList& indices)
:
PackedList<1>(indices.size(), 0u)
PackedBoolList(indices.size(), indices)
{}
inline Foam::PackedBoolList::PackedBoolList(const UIndirectList<label>& indices)
:
PackedBoolList(indices.size(), indices)
{}
inline Foam::PackedBoolList::PackedBoolList
(
const label size,
const labelUList& indices
)
:
PackedList<1>(size)
{
set(indices);
}
inline Foam::PackedBoolList::PackedBoolList(const UIndirectList<label>& indices)
inline Foam::PackedBoolList::PackedBoolList
(
const label size,
const UIndirectList<label>& indices
)
:
PackedList<1>(indices.size(), 0u)
PackedList<1>(size)
{
set(indices);
}

View File

@ -48,8 +48,9 @@ Note
list[1] = list[5] = list[6]; // propagates value
\endcode
Using get() or the '[]' operator are similarly fast. Looping and reading
via an iterator is approx. 15% slower, but can be more flexible.
Reading via the get() or the '[]' operator are identical.
Looping and reading via an iterator is approx. 15% slower,
but can be more flexible.
Using the set() operator (and the '[]' operator) are marginally slower
(approx. 5%) than using an iterator, but the set() method has the
@ -157,7 +158,7 @@ protected:
// Protected Member Functions
//- Calculate the list length when packed
inline static label packedLength(const label);
inline static label packedLength(const label nElem);
//- Read a list entry (allows for specialization)
inline static unsigned int readValue(Istream& is);
@ -200,14 +201,14 @@ public:
//- The max. number of bits that can be templated.
// Might someday be useful for a template assert.
inline static unsigned int max_bits();
inline static constexpr unsigned int max_bits();
//- The max. value for an entry, which simultaneously the bit-mask
// eg, ((1 << 2) - 1) yields 0b0011
inline static unsigned int max_value();
inline static constexpr unsigned int max_value();
//- The number of entries per packed storage element
inline static unsigned int packing();
inline static constexpr unsigned int packing();
//- Masking for all bits below the offset
inline static unsigned int maskLower(unsigned offset);
@ -393,11 +394,11 @@ public:
//- Remove and return the last element
inline unsigned int remove();
//- Get value at index I
//- Identical to get() - get value at index.
// Never auto-vivify entries.
inline unsigned int operator[](const label i) const;
//- Set value at index I.
//- Non-const access to value at index.
// Returns iterator to perform the actual operation.
// Does not auto-vivify entries, but will when assigned to.
inline iteratorBase operator[](const label i);
@ -496,11 +497,11 @@ public:
//- Disallow copy constructor from const_iterator
// This would violate const-ness!
iterator(const const_iterator& iter);
iterator(const const_iterator& iter) = delete;
//- Disallow assignment from const_iterator
// This would violate const-ness!
void operator=(const const_iterator& iter);
void operator=(const const_iterator& iter) = delete;
public:

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -25,24 +25,24 @@ License
#include <climits>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
template<unsigned nBits>
inline unsigned int Foam::PackedList<nBits>::max_bits()
inline constexpr unsigned int Foam::PackedList<nBits>::max_bits()
{
return sizeof(StorageType)*CHAR_BIT - 1;
}
template<unsigned nBits>
inline unsigned int Foam::PackedList<nBits>::max_value()
inline constexpr unsigned int Foam::PackedList<nBits>::max_value()
{
return (1u << nBits) - 1;
}
template<unsigned nBits>
inline unsigned int Foam::PackedList<nBits>::packing()
inline constexpr unsigned int Foam::PackedList<nBits>::packing()
{
return sizeof(StorageType)*CHAR_BIT / nBits;
}
@ -65,6 +65,8 @@ inline Foam::label Foam::PackedList<nBits>::packedLength(const label nElem)
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
namespace Foam
{
// Template specialization for bool entries
@ -88,13 +90,10 @@ namespace Foam
if (this->get())
{
os << index_;
return true;
}
else
{
return false;
}
return false;
}
}
@ -119,12 +118,12 @@ inline unsigned int Foam::PackedList<nBits>::readValue(Istream& is)
template<unsigned nBits>
inline void Foam::PackedList<nBits>::setPair(Istream& is)
{
is.readBegin("Tuple2<label, unsigned int>");
is.readBegin("Tuple2<label,unsigned int>");
const label ind = readLabel(is);
const unsigned int val = readLabel(is);
is.readEnd("Tuple2<label, unsigned int>");
is.readEnd("Tuple2<label,unsigned int>");
if (val > max_value())
{
@ -154,10 +153,8 @@ inline bool Foam::PackedList<nBits>::iteratorBase::writeIfSet(Ostream& os) const
return true;
}
else
{
return false;
}
return false;
}
@ -233,7 +230,8 @@ inline Foam::PackedList<nBits>::PackedList(const labelUList& lst)
StorageList(packedLength(lst.size()), 0u),
size_(lst.size())
{
forAll(lst, i)
const label len = lst.size();
for (label i = 0; i < len; ++i)
{
set(i, lst[i]);
}
@ -247,7 +245,8 @@ inline Foam::PackedList<nBits>::PackedList(const UIndirectList<label>& lst)
StorageList(packedLength(lst.size()), 0u),
size_(lst.size())
{
forAll(lst, i)
const label len = lst.size();
for (label i = 0; i < len; ++i)
{
set(i, lst[i]);
}
@ -862,16 +861,16 @@ inline void Foam::PackedList<nBits>::reserve(const label nElem)
{
const label len = packedLength(nElem);
// Need more capacity?
// Allocate more capacity if necessary
if (len > StorageList::size())
{
// Like DynamicList with SizeInc=0, SizeMult=2, SizeDiv=1
StorageList::setSize
(
max
(
len,
StorageList::size()*2
// SizeInc=0, SizeMult=2, SizeDiv=1
2 * StorageList::size()
),
0u
);
@ -964,27 +963,17 @@ inline unsigned int Foam::PackedList<nBits>::get(const label i) const
// Lazy evaluation - return 0 for out-of-range
if (i < 0 || i >= size_)
{
return 0;
}
else
{
return iteratorBase(this, i).get();
return 0u;
}
return iteratorBase(this, i).get();
}
template<unsigned nBits>
inline unsigned int Foam::PackedList<nBits>::operator[](const label i) const
{
// Lazy evaluation - return 0 for out-of-range
if (i < 0 || i >= size_)
{
return 0;
}
else
{
return iteratorBase(this, i).get();
}
return get(i);
}
@ -1024,10 +1013,8 @@ inline bool Foam::PackedList<nBits>::unset(const label i)
{
return false;
}
else
{
return iteratorBase(this, i).set(0u);
}
return iteratorBase(this, i).set(0u);
}
@ -1035,11 +1022,11 @@ template<unsigned nBits>
inline Foam::PackedList<nBits>&
Foam::PackedList<nBits>::append(const unsigned int val)
{
const label elemI = size_;
reserve(elemI + 1);
const label idx = size_;
reserve(idx + 1);
size_++;
iteratorBase(this, elemI).set(val);
iteratorBase(this, idx).set(val);
return *this;
}
@ -1047,15 +1034,17 @@ Foam::PackedList<nBits>::append(const unsigned int val)
template<unsigned nBits>
inline unsigned int Foam::PackedList<nBits>::remove()
{
if (!size_)
// Location of last element and simultaneously the new size
const label idx = size_ - 1;
if (idx < 0)
{
FatalErrorInFunction
<< "List is empty" << abort(FatalError);
}
label elemI = size_ - 1;
const unsigned int val = iteratorBase(this, elemI).get();
resize(elemI);
const unsigned int val = iteratorBase(this, idx).get();
resize(idx);
return val;
}