Commit a5e5ba31 authored by Mark Olesen's avatar Mark Olesen
Browse files

ENH: add bitSet-type of methods for boolList

- test(), get(), set(), unset() with behaviour as per bitSet,
  to allow easier swapping out of boolList <-> bitSet.
parent c89e13f8
......@@ -25,7 +25,7 @@ Application
Test-bitSet1
Description
Test bitSet functionality
Basic bitSet characteristics
\*---------------------------------------------------------------------------*/
......@@ -64,8 +64,6 @@ inline Ostream& report
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
bitSet set1(100);
......
......@@ -38,8 +38,11 @@ Description
#include "bitSet.H"
#include "FlatOutput.H"
using namespace Foam;
// #define TEST_SFINAE
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
using namespace Foam;
inline Ostream& extent(const bitSet& bitset)
{
......@@ -99,7 +102,8 @@ inline Ostream& report
inline Ostream& report(const UList<bool>& bools)
{
return info(bools);
info(bools);
return Info;
}
......@@ -167,6 +171,70 @@ int main(int argc, char *argv[])
Info<< "\nalternating bit pattern\n";
compare(list1, "..........1..1..1..1..1..1..1..1");
// As boolList
{
boolList bools = list1.values();
Info<<"===============" << nl;
Info<<"bools: " << flatOutput(bools) << nl;
for (int i : { -10, 0, 8, 15, 32})
{
Info<< i << " is " << (bools.test(i) ? "set" : "unset")
<< " = " << bools.get(i) << nl;
}
Info<<"bools: " << flatOutput(bools) << nl;
for (int i : { -10, 5, 24})
{
Info<< "set(" << i << ") = "
<< (bools.set(i) ? "true" : "false")
<< nl;
}
Info<<"bools: " << flatOutput(bools) << nl;
for (int i : { -10, 12, 32, 150})
{
Info<< "unset(" << i << ") = "
<< (bools.unset(i) ? "true" : "false")
<< nl;
}
Info<<"bools: " << flatOutput(bools) << nl;
#if 0
boolList bools2(6, false);
Info<<"other bools: " << flatOutput(bools2) << nl;
bools2.set(4);
Info<<"other bools: " << flatOutput(bools2) << nl;
bools2.clear();
bools2.set(3);
bools2.resize(8);
Info<<"other bools: " << flatOutput(bools2) << nl;
#endif
Info<<"===============" << nl;
}
#ifdef TEST_SFINAE
{
labelList labels = list1.toc();
if (labels.test(0))
{
Info<<"no" << endl;
}
List<double*> ptrs(10, nullptr);
if (ptrs.get(0))
{
Info<<"no" << endl;
}
}
#endif
list1.unset(labelRange(13, 20)); // In range
Info<< "\nafter clear [13,..]\n";
......
......@@ -579,8 +579,7 @@ inline unsigned int Foam::PackedList<Width>::get(const label i) const
}
#endif
// Lazy evaluation - return 0 for out-of-range
return 0u;
return 0u; // Out-of-bounds (lazy): return 0 (false)
}
return reference(const_cast<PackedList<Width>*>(this), i).get();
......@@ -603,19 +602,16 @@ inline bool Foam::PackedList<Width>::set
<< endl;
#endif
// Lazy evaluation - ignore out-of-bounds
return false;
return false; // Out-of-bounds: ignore
}
else if (i >= size())
{
if (!val)
if (!val) // Unset out-of-bounds: ignore
{
// Same as unset out-of-bounds = noop
return false;
}
// Lazy evaluation - increase size on assigment
resize(i + 1);
resize(i + 1); // Lazy evaluation: adjust size for assign
}
return reference(this, i).set(val);
......@@ -627,8 +623,7 @@ inline bool Foam::PackedList<Width>::unset(const label i)
{
if (i < 0 || i >= size())
{
// Unset out-of-bounds = noop
return false;
return false; // Unset out-of-bounds: ignore
}
return reference(this, i).set(0u);
......
......@@ -35,6 +35,57 @@ License
#include <utility>
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class T>
void Foam::List<T>::doResize(const label newSize)
{
if (newSize < 0)
{
FatalErrorInFunction
<< "bad size " << newSize
<< abort(FatalError);
}
if (newSize != this->size_)
{
if (newSize > 0)
{
T* nv = new T[newSize];
const label overlap = min(this->size_, newSize);
if (overlap)
{
#ifdef USEMEMCPY
if (contiguous<T>())
{
memcpy(nv, this->v_, overlap*sizeof(T));
}
else
#endif
{
// No speedup observed for copy assignment on simple types
List_ACCESS(T, *this, vp);
for (label i = 0; i < overlap; ++i)
{
nv[i] = std::move(vp[i]);
}
}
}
clear();
this->size_ = newSize;
this->v_ = nv;
}
else
{
clear();
}
}
}
// * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
template<class T>
......@@ -49,7 +100,7 @@ Foam::List<T>::List(const label len)
<< abort(FatalError);
}
alloc();
doAlloc();
}
......@@ -67,7 +118,7 @@ Foam::List<T>::List(const label len, const T& val)
if (len)
{
alloc();
doAlloc();
List_ACCESS(T, (*this), vp);
for (label i=0; i < len; ++i)
......@@ -92,7 +143,7 @@ Foam::List<T>::List(const label len, const zero)
if (len)
{
alloc();
doAlloc();
List_ACCESS(T, (*this), vp);
for (label i=0; i < len; ++i)
......@@ -137,7 +188,7 @@ Foam::List<T>::List(const UList<T>& a)
{
if (this->size_)
{
alloc();
doAlloc();
#ifdef USEMEMCPY
if (contiguous<T>())
......@@ -165,7 +216,7 @@ Foam::List<T>::List(const List<T>& a)
{
if (this->size_)
{
alloc();
doAlloc();
#ifdef USEMEMCPY
if (contiguous<T>())
......@@ -200,7 +251,7 @@ Foam::List<T>::List(List<T>& a, bool reuse)
}
else if (this->size_)
{
alloc();
doAlloc();
#ifdef USEMEMCPY
if (contiguous<T>())
......@@ -222,7 +273,7 @@ Foam::List<T>::List(List<T>& a, bool reuse)
template<class T>
Foam::List<T>::List(const UList<T>& lst, const labelUList& mapAddressing)
Foam::List<T>::List(const UList<T>& list, const labelUList& mapAddressing)
:
UList<T>(nullptr, mapAddressing.size())
{
......@@ -230,13 +281,13 @@ Foam::List<T>::List(const UList<T>& lst, const labelUList& mapAddressing)
if (len)
{
alloc();
doAlloc();
List_ACCESS(T, (*this), vp);
for (label i=0; i < len; ++i)
{
vp[i] = lst[mapAddressing[i]];
vp[i] = list[mapAddressing[i]];
}
}
}
......@@ -252,94 +303,94 @@ Foam::List<T>::List(InputIterator begIter, InputIterator endIter)
template<class T>
template<unsigned Size>
Foam::List<T>::List(const FixedList<T, Size>& lst)
Foam::List<T>::List(const FixedList<T, Size>& list)
:
UList<T>(nullptr, Size)
{
alloc();
copyList(lst);
doAlloc();
copyList(list);
}
template<class T>
Foam::List<T>::List(const PtrList<T>& lst)
Foam::List<T>::List(const PtrList<T>& list)
:
UList<T>(nullptr, lst.size())
UList<T>(nullptr, list.size())
{
alloc();
copyList(lst);
doAlloc();
copyList(list);
}
template<class T>
Foam::List<T>::List(const SLList<T>& lst)
Foam::List<T>::List(const SLList<T>& list)
:
List<T>(lst.begin(), lst.end(), lst.size())
List<T>(list.begin(), list.end(), list.size())
{}
template<class T>
Foam::List<T>::List(const UIndirectList<T>& lst)
Foam::List<T>::List(const UIndirectList<T>& list)
:
UList<T>(nullptr, lst.size())
UList<T>(nullptr, list.size())
{
alloc();
copyList(lst);
doAlloc();
copyList(list);
}
template<class T>
Foam::List<T>::List(const BiIndirectList<T>& lst)
Foam::List<T>::List(const BiIndirectList<T>& list)
:
UList<T>(nullptr, lst.size())
UList<T>(nullptr, list.size())
{
alloc();
copyList(lst);
doAlloc();
copyList(list);
}
template<class T>
Foam::List<T>::List(std::initializer_list<T> lst)
Foam::List<T>::List(std::initializer_list<T> list)
:
List<T>(lst.begin(), lst.end(), lst.size())
List<T>(list.begin(), list.end(), list.size())
{}
template<class T>
Foam::List<T>::List(List<T>&& lst)
Foam::List<T>::List(List<T>&& list)
:
UList<T>(nullptr, 0)
{
// Can use transfer or swap to manage content
transfer(lst);
transfer(list);
}
template<class T>
template<int SizeMin>
Foam::List<T>::List(DynamicList<T, SizeMin>&& lst)
Foam::List<T>::List(DynamicList<T, SizeMin>&& list)
:
UList<T>(nullptr, 0)
{
transfer(lst);
transfer(list);
}
template<class T>
Foam::List<T>::List(SortableList<T>&& lst)
Foam::List<T>::List(SortableList<T>&& list)
:
UList<T>(nullptr, 0)
{
transfer(lst);
transfer(list);
}
template<class T>
Foam::List<T>::List(SLList<T>&& lst)
Foam::List<T>::List(SLList<T>&& list)
:
UList<T>(nullptr, 0)
{
operator=(std::move(lst));
operator=(std::move(list));
}
......@@ -358,59 +409,10 @@ Foam::List<T>::~List()
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class T>
void Foam::List<T>::setSize(const label newSize)
{
if (newSize < 0)
{
FatalErrorInFunction
<< "bad size " << newSize
<< abort(FatalError);
}
if (newSize != this->size_)
{
if (newSize > 0)
{
T* nv = new T[newSize];
const label overlap = min(this->size_, newSize);
if (overlap)
{
#ifdef USEMEMCPY
if (contiguous<T>())
{
memcpy(nv, this->v_, overlap*sizeof(T));
}
else
#endif
{
// No speedup observed for copy assignment on simple types
List_ACCESS(T, *this, vp);
for (label i = 0; i < overlap; ++i)
{
nv[i] = std::move(vp[i]);
}
}
}
clear();
this->size_ = newSize;
this->v_ = nv;
}
else
{
clear();
}
}
}
template<class T>
void Foam::List<T>::setSize(const label newSize, const T& val)
void Foam::List<T>::resize(const label newSize, const T& val)
{
const label oldSize = this->size_;
this->setSize(newSize);
this->doResize(newSize);
List_ACCESS(T, *this, vp);
for (label i = oldSize; i < newSize; ++i)
......@@ -421,37 +423,37 @@ void Foam::List<T>::setSize(const label newSize, const T& val)
template<class T>
void Foam::List<T>::transfer(List<T>& lst)
void Foam::List<T>::transfer(List<T>& list)
{
// Clear and swap - could also check for self assignment
clear();
this->size_ = lst.size_;
this->v_ = lst.v_;
this->size_ = list.size_;
this->v_ = list.v_;
lst.size_ = 0;
lst.v_ = nullptr;
list.size_ = 0;
list.v_ = nullptr;
}
template<class T>
template<int SizeMin>
void Foam::List<T>::transfer(DynamicList<T, SizeMin>& lst)
void Foam::List<T>::transfer(DynamicList<T, SizeMin>& list)
{
// Shrink the allocated space to the number of elements used
lst.shrink();
transfer(static_cast<List<T>&>(lst));
list.shrink();
transfer(static_cast<List<T>&>(list));
// Ensure DynamicList has proper capacity=0 too
lst.clearStorage();
list.clearStorage();
}
template<class T>
void Foam::List<T>::transfer(SortableList<T>& lst)
void Foam::List<T>::transfer(SortableList<T>& list)
{
// Shrink away the sort indices
lst.shrink();
transfer(static_cast<List<T>&>(lst));
list.shrink();
transfer(static_cast<List<T>&>(list));
}
......@@ -484,23 +486,23 @@ void Foam::List<T>::operator=(const UList<T>& a)
template<class T>
void Foam::List<T>::operator=(const List<T>& lst)
void Foam::List<T>::operator=(const List<T>& list)
{
if (this == &lst)
if (this == &list)
{
FatalErrorInFunction
<< "attempted assignment to self"
<< abort(FatalError);
}
operator=(static_cast<const UList<T>&>(lst));
operator=(static_cast<const UList<T>&>(list));
}
template<class T>
void Foam::List<T>::operator=(const SLList<T>& lst)
void Foam::List<T>::operator=(const SLList<T>& list)
{
const label len = lst.size();
const label len = list.size();
reAlloc(len);
......@@ -509,7 +511,7 @@ void Foam::List<T>::operator=(const SLList<T>& lst)
List_ACCESS(T, (*this), vp);
label i = 0;
for (auto iter = lst.cbegin(); iter != lst.cend(); ++iter)
for (auto iter = list.cbegin(); iter != list.cend(); ++iter)
{
vp[i] = *iter;
++i;
......@@ -519,9 +521,9 @@ void Foam::List<T>::operator=(const SLList<T>& lst)
template<class T>
void Foam::List<T>::operator=(const UIndirectList<T>& lst)
void Foam::List<T>::operator=(const UIndirectList<T>& list)
{
const label len = lst.size();
const label len = list.size();
reAlloc(len);
......@@ -531,16 +533,16 @@ void Foam::List<T>::operator=(const UIndirectList<T>& lst)
for (label i=0; i<len; ++i)
{
vp[i] = lst[i];
vp[i] = list[i];
}
}
}
template<class T>
void Foam::List<T>::operator=(const BiIndirectList<T>& lst)
void Foam::List<T>::operator=(const BiIndirectList<T>& list)
{
const label len = lst.size();
const label len = list.size();
reAlloc(len);
......@@ -550,16 +552,16 @@ void Foam::List<T>::operator=(const BiIndirectList<T>& lst)
for (label i=0; i<len; ++i)
{
vp[i] = lst[i];
vp[i] = list[i];
}
}
}
template<class T>
void Foam::List<T>::operator=(std::initializer_list<T> lst)
void Foam::List<T>::operator=(std::initializer_list<T> list)
{
const label len = lst.size();
const label len = list.size();
reAlloc(len);
......@@ -568,7 +570,7 @@ void Foam::List<T>::operator=(std::initializer_list<T> lst)
List_ACCESS(T, (*this), vp);
label i = 0;
for (const auto& val : lst)
for (const auto& val : list)
{
vp[i] = val;
++i;
......@@ -578,38 +580,38 @@ void Foam::List<T>::operator=(std::initializer_list<T> lst)