Merge branch 'feature-ptrlist' into 'develop'

Updated/modified PtrList implementation

See merge request Development/OpenFOAM-plus!193
This commit is contained in:
Mark Olesen
2018-03-26 18:41:42 +01:00
15 changed files with 1488 additions and 192 deletions

View File

@ -29,7 +29,7 @@ Description
#include "scalar.H"
#include "IOstreams.H"
#include "PtrList.H"
#include "PtrDynList.H"
#include "DLPtrList.H"
#include "SLPtrList.H"
#include "plane.H"
@ -58,6 +58,16 @@ public:
Info<<"delete Scalar: " << data_ << endl;
}
const scalar& value() const
{
return data_;
}
scalar& value()
{
return data_;
}
autoPtr<Scalar> clone() const
{
return autoPtr<Scalar>::New(data_);
@ -71,6 +81,151 @@ public:
};
// As per
//
// template<class T>
// Ostream& operator<<(Ostream& os, const UPtrList<T>& list)
//
// but handle nullptr
template<class T>
Ostream& printAddr
(
Ostream& os,
const UPtrList<T>& list
)
{
const label len = list.size();
// Size and start delimiter
os << nl << indent << len << nl
<< indent << token::BEGIN_LIST << incrIndent << nl;
for (label i=0; i < len; ++i)
{
os << "addr=" << long(list(i)) << nl;
}
// End delimiter
os << decrIndent << indent << token::END_LIST << nl;
return os;
}
// As per
//
// template<class T>
// Ostream& operator<<(Ostream& os, const UPtrList<T>& list)
//
// but handle nullptr
template<class T>
Ostream& print
(
Ostream& os,
const UPtrList<T>& list,
const bool debug=false
)
{
const label len = list.size();
// Size and start delimiter
os << nl << indent << len << nl
<< indent << token::BEGIN_LIST << incrIndent << nl;
for (label i=0; i < len; ++i)
{
const T* ptr = list(i);
if (ptr)
{
os << *ptr << nl;
}
else
{
os << "nullptr" << nl;
}
}
// End delimiter
os << decrIndent << indent << token::END_LIST << nl;
return os;
}
template<class T, int SizeMin>
Ostream& print
(
Ostream& os,
const PtrDynList<T, SizeMin>& list,
const bool debug=false
)
{
const label len = list.size();
// Size and start delimiter
os << nl << indent << len << nl
<< indent << token::BEGIN_LIST << incrIndent << nl;
for (label i=0; i < len; ++i)
{
const T* ptr = list(i);
if (ptr)
{
os << *ptr << nl;
}
else
{
os << "nullptr" << nl;
}
}
if (debug)
{
const label cap = list.capacity();
for (label i=len; i < cap; ++i)
{
const T* ptr = list(i);
os << "unused " << long(ptr) << nl;
}
}
// End delimiter
os << decrIndent << indent << token::END_LIST << nl;
return os;
}
template<class T>
Ostream& report
(
Ostream& os,
const UPtrList<T>& list,
const bool debug=false
)
{
return print(os, list, debug);
}
template<class T, int SizeMin>
Ostream& report
(
Ostream& os,
const PtrDynList<T,SizeMin>& list,
const bool debug=false
)
{
os << "capacity=" << list.capacity() << nl;
return print(os, list, debug);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
@ -110,6 +265,23 @@ int main(int argc, char *argv[])
}
}
// Same but as SLPtrList
{
SLPtrList<Scalar> llist1;
llist1.insert(new Scalar(100));
llist1.insert(new Scalar(200));
llist1.insert(new Scalar(300));
for (const auto& it : llist1)
{
Info<< typeid(it).name() << nl
<< "for-: " << it << endl;
}
PtrList<Scalar> list1b(llist1);
Info<< list1b << endl;
}
forAll(list1, i)
{
list1.set(i, new Scalar(1.3*i));
@ -133,7 +305,7 @@ int main(int argc, char *argv[])
Info<<"indirectly delete some items via set(.., 0) :" << endl;
for (label i = 0; i < 3; i++)
{
list1.set(i, 0);
list1.set(i, nullptr);
}
Info<<"transfer list2 -> list1:" << endl;
@ -147,6 +319,36 @@ int main(int argc, char *argv[])
Info<<"list1: " << list1 << endl;
{
PtrList<Scalar> list1a(list1, false);
Info<<"Clone constructed" << endl;
Info<<"in: " << list1 << nl
<<"out: " << list1a << nl
<<"addresses:" << nl;
printAddr(Info, list1);
printAddr(Info, list1a);
PtrList<Scalar> list1b(list1a, true);
Info<<"Reuse constructed" << endl;
Info<<"in: " << list1a << nl
<<"out: " << list1b << nl
<<"addresses:" << nl;
printAddr(Info, list1a);
printAddr(Info, list1b);
PtrList<Scalar> list1c(list1b.clone());
Info<<"Explicit clone()" << endl;
Info<<"in: " << list1b << nl
<<"out: " << list1c << nl
<<"addresses:" << nl;
printAddr(Info, list1b);
printAddr(Info, list1c);
}
PtrList<Scalar> list3(std::move(list1));
Info<<"Move constructed" << endl;
@ -174,6 +376,26 @@ int main(int argc, char *argv[])
UPtrList<Scalar> ulist1(list3);
Info<<"ulist1: " << ulist1 << nl;
Info<<"PtrList addresses:";
printAddr(Info, list3);
Info<<"UPtrList addresses:";
printAddr(Info, ulist1);
Info<< nl;
{
Info<<"UPtrList(const UPtrList&)" << nl;
const UPtrList<Scalar>& cref = ulist1;
UPtrList<Scalar> ulist1cp(cref);
Info<<"src addresses:";
printAddr(Info, cref);
Info<<"dst addresses:";
printAddr(Info, ulist1cp);
Info<< nl;
}
Info<<"Move construct:" << endl;
@ -204,6 +426,10 @@ int main(int argc, char *argv[])
Info<< "iter[2]=" << iter1[2] << nl;
Info<< "iter1 < iter2 : " << (iter1 < iter2) << nl;
Info<< "iter1 >= iter2 : " << (iter1 >= iter2) << nl;
Info<<"->" << iter1->value() << nl;
Info<<"*" << (*iter1).value() << nl;
Info<<"()" << iter1().value() << nl;
}
PtrList<plane> planes;
@ -216,6 +442,46 @@ int main(int argc, char *argv[])
Info<< " plane " << p << endl;
}
Info<<"Testing PtrDynList" << nl;
PtrDynList<plane> dynPlanes;
{
dynPlanes.append(new plane(vector::one, vector::one));
dynPlanes.append(new plane(vector(1,2,3), vector::one));
dynPlanes.append(nullptr);
dynPlanes.set(6, new plane(vector(2,2,1), vector::one));
dynPlanes.set(10, new plane(vector(4,5,6), vector::one));
}
Info<< nl << "PtrList: ";
report(Info, dynPlanes, true);
dynPlanes.resize(9);
Info<< nl << "resize()";
report(Info, dynPlanes, true);
dynPlanes.clear();
Info<<"clear()" << nl;
report(Info, dynPlanes);
Info<<"now append again" << endl;
{
dynPlanes.append(new plane(vector::one, vector::one));
dynPlanes.append(new plane(vector(1,2,3), vector::one));
dynPlanes.set(5, new plane(vector(2,2,1), vector::one));
}
report(Info, dynPlanes, true);
Info<<"free()" << endl;
dynPlanes.free();
report(Info, dynPlanes, true);
Info<< nl << "Done." << endl;
return 0;
}

View File

@ -57,8 +57,6 @@ using namespace Foam;
#include "emptyPolyPatch.H"
#include "preservePatchTypes.H"
#include "cellShape.H"
#include "SLList.H"
#include "SLPtrList.H"
label nPoints = 0;
label nCells = 0;

View File

@ -0,0 +1,195 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::PtrDynList
Description
A dynamically resizable PtrList with allocation management.
See Also
Foam::UPtrList
Foam::PtrList
SourceFiles
PtrDynListI.H
\*---------------------------------------------------------------------------*/
#ifndef PtrDynList_H
#define PtrDynList_H
#include "PtrList.H"
#include <type_traits>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declarations
template<class T, int SizeMin> class PtrDynList;
/*---------------------------------------------------------------------------*\
Class PtrDynList Declaration
\*---------------------------------------------------------------------------*/
template<class T, int SizeMin=64>
class PtrDynList
:
public PtrList<T>
{
static_assert(SizeMin > 0, "Invalid min size parameter");
// Private data
//- The capacity (allocated size) of the list.
label capacity_;
public:
// Constructors
//- Construct null
inline constexpr PtrDynList() noexcept;
//- Construct with given capacity.
explicit inline PtrDynList(const label len);
//- Copy construct using 'clone()' method on each element
inline PtrDynList(const PtrDynList<T, SizeMin>& list);
//- Move construct
inline PtrDynList(PtrDynList<T, SizeMin>&& list);
//- Destructor
~PtrDynList() = default;
// Member Functions
// Access
//- Size of the underlying storage.
inline label capacity() const;
// Edit
//- Delete the allocated entries, but retain the list size.
using PtrList<T>::free;
//- Alter the size of the underlying storage.
inline void setCapacity(const label nElem);
//- Alter the addressed list size.
inline void resize(const label newLen);
//- Alter the addressed list size.
inline void setSize(const label newLen);
//- Reserve allocation space for at least this size.
// Never shrinks the allocated size, use setCapacity() for that.
inline void reserve(const label nElem);
//- Clear the addressed list, i.e. set the size to zero.
// Allocated size does not change
inline void clear();
//- Clear the list and delete storage.
inline void clearStorage();
//- Expand the addressable size to fit the allocated capacity.
// Returns the previous addressable size.
inline label expandStorage();
//- Shrink the allocated space to the number of elements used.
inline void shrink();
//- Append an element to the end of the list
inline void append(T* ptr);
//- Append an element to the end of the list
inline void append(const autoPtr<T>& aptr);
//- Append an element to the end of the list
inline void append(const tmp<T>& tptr);
//- Remove and return the top element
inline autoPtr<T> remove();
//- Return true if element is set (ie, not a nullptr)
inline bool set(const label i) const;
//- Set element to given pointer and return old element (can be null)
inline autoPtr<T> set(const label i, T* ptr);
//- Set element to given autoPtr and return old element
inline autoPtr<T> set(const label i, const autoPtr<T>& aptr);
//- Set element to given tmp and return old element
inline autoPtr<T> set(const label i, const tmp<T>& tptr);
//- Reorder elements. Reordering must be unique (ie, shuffle).
inline void reorder(const labelUList& oldToNew);
// Member Operators
//- Copy (clone) assignment
inline void operator=(const PtrList<T>& list);
//- Copy (clone) assignment
inline void operator=(const PtrDynList<T, SizeMin>& list);
//- Copy (clone) assignment with different sizing parameters
template<int AnySizeMin>
inline void operator=(const PtrDynList<T, AnySizeMin>& list);
//- Move assignment
inline void operator=(PtrList<T>&& list);
//- Move assignment
inline void operator=(PtrDynList<T, SizeMin>&& list);
//- Move assignment with different sizing parameters
template<int AnySizeMin>
inline void operator=(PtrDynList<T, AnySizeMin>&& list);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "PtrDynListI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,373 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "autoPtr.H"
#include "tmp.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class T, int SizeMin>
inline constexpr Foam::PtrDynList<T, SizeMin>::PtrDynList() noexcept
:
PtrList<T>(),
capacity_(0)
{}
template<class T, int SizeMin>
inline Foam::PtrDynList<T, SizeMin>::PtrDynList(const label len)
:
PtrList<T>(len),
capacity_(len)
{
PtrList<T>::size(0);
}
template<class T, int SizeMin>
inline Foam::PtrDynList<T, SizeMin>::PtrDynList
(
const PtrDynList<T, SizeMin>& list
)
:
PtrList<T>(list),
capacity_(PtrList<T>::size())
{}
template<class T, int SizeMin>
inline Foam::PtrDynList<T, SizeMin>::PtrDynList
(
PtrDynList<T, SizeMin>&& list
)
:
PtrList<T>(std::move(list)),
capacity_(list.capacity_)
{
list.clearStorage();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class T, int SizeMin>
inline Foam::label Foam::PtrDynList<T, SizeMin>::capacity() const
{
return capacity_;
}
template<class T, int SizeMin>
inline void Foam::PtrDynList<T, SizeMin>::setCapacity(const label nElem)
{
label nextFree = PtrList<T>::size();
capacity_ = nElem;
if (nextFree > capacity_)
{
// Truncate addressed sizes too
nextFree = capacity_;
}
PtrList<T>::resize(capacity_);
(this->ptrs_).setAddressableSize(nextFree);
}
template<class T, int SizeMin>
inline void Foam::PtrDynList<T, SizeMin>::reserve(const label nElem)
{
if (nElem > capacity_)
{
// Allocate more capacity if necessary
capacity_ = max(SizeMin, max(nElem, label(2*capacity_)));
// Adjust allocated size, leave addressed size untouched
const label nextFree = PtrList<T>::size();
PtrList<T>::resize(capacity_);
(this->ptrs_).setAddressableSize(nextFree);
}
}
template<class T, int SizeMin>
inline void Foam::PtrDynList<T, SizeMin>::resize(const label newLen)
{
auto& ptrs = this->ptrs_;
const label oldLen = ptrs.size();
if (newLen > capacity_)
{
// Allocate more capacity if necessary
capacity_ = max(SizeMin, max(newLen, label(2*capacity_)));
PtrList<T>::resize(capacity_);
}
else if (newLen != oldLen)
{
// Truncation frees old pointers
for (label i=newLen; i<oldLen; ++i)
{
T* ptr = ptrs[i];
if (ptr)
{
delete ptr;
}
ptrs[i] = nullptr;
}
}
// Adjust addressed size
ptrs.setAddressableSize(newLen);
}
template<class T, int SizeMin>
inline void Foam::PtrDynList<T, SizeMin>::setSize(const label newLen)
{
this->resize(newLen);
}
template<class T, int SizeMin>
inline void Foam::PtrDynList<T, SizeMin>::clear()
{
(this->ptrs_).free(); // free old pointers
(this->ptrs_).setAddressableSize(0);
}
template<class T, int SizeMin>
inline void Foam::PtrDynList<T, SizeMin>::clearStorage()
{
PtrList<T>::clear();
capacity_ = 0;
}
template<class T, int SizeMin>
inline Foam::label Foam::PtrDynList<T, SizeMin>::expandStorage()
{
const label nextFree = PtrList<T>::size();
// Allow addressing into the entire list
PtrList<T>::size(capacity_);
return nextFree;
}
template<class T, int SizeMin>
inline void Foam::PtrDynList<T, SizeMin>::shrink()
{
label nextFree = PtrList<T>::size();
if (capacity_ > nextFree)
{
// Use the full list when resizing
PtrList<T>::size(capacity_);
// The new size
capacity_ = nextFree;
PtrList<T>::resize(capacity_);
PtrList<T>::size(nextFree);
}
return *this;
}
template<class T, int SizeMin>
inline void Foam::PtrDynList<T, SizeMin>::append(T* ptr)
{
const label idx = this->size();
resize(idx + 1);
this->ptrs_[idx] = ptr;
}
template<class T, int SizeMin>
inline void Foam::PtrDynList<T, SizeMin>::append(const autoPtr<T>& aptr)
{
return this->append(const_cast<autoPtr<T>&>(aptr).release());
}
template<class T, int SizeMin>
inline void Foam::PtrDynList<T, SizeMin>::append(const tmp<T>& tptr)
{
return this->append(const_cast<autoPtr<T>&>(tptr).ptr());
}
template<class T, int SizeMin>
inline Foam::autoPtr<T> Foam::PtrDynList<T, SizeMin>::remove()
{
// Location of last element and simultaneously the new size
const label idx = (this->size() - 1);
if (idx < 0)
{
return nullptr; // List is empty
}
autoPtr<T> old(this->ptrs_[idx]);
this->ptrs_[idx] = nullptr;
(this->ptrs_).setAddressableSize(idx);
return old;
}
template<class T, int SizeMin>
inline bool Foam::PtrDynList<T, SizeMin>::set(const label i) const
{
return (i >= 0 && i < PtrList<T>::size()) ? PtrList<T>::set(i) : false;
}
template<class T, int SizeMin>
inline Foam::autoPtr<T> Foam::PtrDynList<T, SizeMin>::set
(
const label i,
T* ptr
)
{
if (i >= this->size())
{
resize(i+1);
}
return autoPtr<T>(UPtrList<T>::set(i, ptr));
}
template<class T, int SizeMin>
inline Foam::autoPtr<T> Foam::PtrDynList<T, SizeMin>::set
(
const label i,
const autoPtr<T>& aptr
)
{
this->set(i, const_cast<autoPtr<T>&>(aptr).release());
}
template<class T, int SizeMin>
inline Foam::autoPtr<T> Foam::PtrDynList<T, SizeMin>::set
(
const label i,
const tmp<T>& tptr
)
{
this->set(i, tptr.ptr());
}
template<class T, int SizeMin>
inline void Foam::PtrDynList<T, SizeMin>::reorder(const labelUList& oldToNew)
{
// Shrinking first is a bit annoying, but saves needing a special version.
shrink();
PtrList<T>::reorder(oldToNew);
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class T, int SizeMin>
inline void Foam::PtrDynList<T, SizeMin>::operator=
(
const PtrList<T>& list
)
{
PtrList<T>::operator=(list);
capacity_ = PtrList<T>::size();
}
template<class T, int SizeMin>
inline void Foam::PtrDynList<T, SizeMin>::operator=
(
const PtrDynList<T, SizeMin>& list
)
{
PtrList<T>::operator=(list);
capacity_ = PtrList<T>::size();
}
template<class T, int SizeMin>
template<int AnySizeMin>
inline void Foam::PtrDynList<T, SizeMin>::operator=
(
const PtrDynList<T, AnySizeMin>& list
)
{
PtrList<T>::operator=(list);
capacity_ = PtrList<T>::size();
}
template<class T, int SizeMin>
inline void Foam::PtrDynList<T, SizeMin>::operator=
(
PtrList<T>&& list
)
{
PtrList<T>::transfer(list);
capacity_ = PtrList<T>::size();
list.clearStorage();
}
template<class T, int SizeMin>
inline void Foam::PtrDynList<T, SizeMin>::operator=
(
PtrDynList<T, SizeMin>&& list
)
{
PtrList<T>::transfer(list);
capacity_ = list.capacity();
list.clearStorage();
}
template<class T, int SizeMin>
template<int AnySizeMin>
inline void Foam::PtrDynList<T, SizeMin>::operator=
(
PtrDynList<T, AnySizeMin>&& list
)
{
PtrList<T>::transfer(list);
capacity_ = list.capacity();
list.clearStorage();
}
// ************************************************************************* //

View File

@ -25,38 +25,10 @@ License
#include "PtrList.H"
#include "SLPtrList.H"
#include <utility>
// * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
template<class T>
Foam::PtrList<T>::PtrList(const PtrList<T>& list)
:
UPtrList<T>(list.size())
{
const label len = this->size();
for (label i=0; i<len; ++i)
{
this->ptrs_[i] = (list[i]).clone().ptr();
}
}
template<class T>
template<class CloneArg>
Foam::PtrList<T>::PtrList(const PtrList<T>& list, const CloneArg& cloneArg)
:
UPtrList<T>(list.size())
{
const label len = this->size();
for (label i=0; i<len; ++i)
{
this->ptrs_[i] = (list[i]).clone(cloneArg).ptr();
}
}
template<class T>
Foam::PtrList<T>::PtrList(PtrList<T>& list, bool reuse)
:
@ -64,6 +36,7 @@ Foam::PtrList<T>::PtrList(PtrList<T>& list, bool reuse)
{
if (!reuse)
{
// This works like an inplace clone method
const label len = this->size();
for (label i=0; i<len; ++i)
@ -90,67 +63,63 @@ Foam::PtrList<T>::PtrList(const SLPtrList<T>& list)
}
// * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
template<class T>
Foam::PtrList<T>::~PtrList()
{
const label len = this->size();
// Free old pointers
for (label i=0; i<len; ++i)
{
if (this->ptrs_[i])
{
delete this->ptrs_[i];
}
}
(this->ptrs_).free();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class T>
void Foam::PtrList<T>::clear()
template<class... Args>
Foam::PtrList<T> Foam::PtrList<T>::clone(Args&&... args) const
{
const label len = this->size();
PtrList<T> cloned(len);
for (label i=0; i<len; ++i)
{
if (this->ptrs_[i])
const T* ptr = this->ptrs_[i];
if (ptr)
{
delete this->ptrs_[i];
cloned.ptrs_[i] = ptr->clone(std::forward<Args>(args)...).ptr();
}
}
UPtrList<T>::clear();
return cloned;
}
template<class T>
void Foam::PtrList<T>::resize(const label newLen)
{
const label oldLen = this->size();
if (newLen <= 0)
{
clear();
return;
}
const label oldLen = this->size();
if (newLen != oldLen)
else if (newLen != oldLen)
{
// Truncation frees old pointers
for (label i=newLen; i<oldLen; ++i)
{
if (this->ptrs_[i])
T* ptr = this->ptrs_[i];
if (ptr)
{
delete this->ptrs_[i];
delete ptr;
}
}
// Any new elements are initialized to nullptr.
this->ptrs_.resize(newLen, reinterpret_cast<T*>(0));
(this->ptrs_).resize(newLen);
}
}

View File

@ -30,7 +30,8 @@ Description
The operator[] returns a reference to the object, not the pointer.
See Also
Foam::PtrList
Foam::UPtrList
Foam::PtrDynList
SourceFiles
PtrListI.H
@ -56,7 +57,7 @@ template<class T> class autoPtr;
template<class T> class tmp;
template<class T> class PtrList;
template<class T> Istream& operator>>(Istream& is, PtrList<T>& lst);
template<class T> Istream& operator>>(Istream& is, PtrList<T>& list);
/*---------------------------------------------------------------------------*\
@ -68,7 +69,6 @@ class PtrList
:
public UPtrList<T>
{
protected:
// Protected Member Functions
@ -77,6 +77,8 @@ protected:
template<class INew>
void read(Istream& is, const INew& inew);
//- Delete the allocated entries, but retain the list size.
inline void free();
public:
@ -86,22 +88,22 @@ public:
inline constexpr PtrList() noexcept;
//- Construct with specified size, each element initialized to nullptr
explicit inline PtrList(const label nElem);
explicit inline PtrList(const label len);
//- Copy construct using 'clone()' method on each element
PtrList(const PtrList<T>& list);
inline PtrList(const PtrList<T>& list);
//- Move construct
inline PtrList(PtrList<T>&& list);
//- Copy construct with additional argument for 'clone()'
//- Copy construct using 'clone()' method on each element
template<class CloneArg>
PtrList(const PtrList<T>& list, const CloneArg& cloneArg);
inline PtrList(const PtrList<T>& list, const CloneArg& cloneArgs);
//- Construct as copy or re-use as specified
PtrList(PtrList<T>& list, bool reuse);
//- Construct as copy of SLPtrList<T>
//- Copy construct using 'clone()' on each element of SLPtrList\<T\>
explicit PtrList(const SLPtrList<T>& list);
//- Construct from Istream using given Istream constructor class
@ -118,24 +120,31 @@ public:
// Member Functions
//- Clear the PtrList. Set size to zero and delete allocated entries
void clear();
//- Make a copy by cloning each of the list elements.
template<class... Args>
PtrList<T> clone(Args&&... args) const;
//- Reset size of PtrList.
//- Clear the PtrList. Delete allocated entries and set size to zero.
inline void clear();
//- Adjust size of PtrList.
// New entries are initialized to nullptr, removed entries are deleted
void resize(const label newLen);
//- Reset size of PtrList.
//- Adjust size of PtrList.
// New entries are initialized to nullptr, removed entries are deleted
inline void setSize(const label newLen);
//- Append an element at the end of the list
using UPtrList<T>::append;
//- Append an element to the end of the list
inline void append(T* ptr);
//- Append an element at the end of the list
inline void append(const autoPtr<T>& aptr);
//- Move append an element to the end of the list
inline void append(autoPtr<T>& aptr);
//- Append an element at the end of the list
//- Move append an element to the end of the list
inline void append(autoPtr<T>&& aptr);
//- Move or clone append a tmp to the end of the list
inline void append(const tmp<T>& tptr);
//- Transfer into this list and annul the argument list
@ -145,16 +154,19 @@ public:
inline bool set(const label i) const;
//- Set element to given pointer and return old element (can be null)
inline autoPtr<T> set(const label i, T* ptr);
inline autoPtr<T> set(label i, T* ptr);
//- Set element to given autoPtr and return old element
inline autoPtr<T> set(const label i, const autoPtr<T>& aptr);
inline autoPtr<T> set(label i, autoPtr<T>& aptr);
//- Set element to given autoPtr and return old element
inline autoPtr<T> set(label i, autoPtr<T>&& aptr);
//- Set element to given tmp and return old element
inline autoPtr<T> set(const label i, const tmp<T>& tptr);
inline autoPtr<T> set(label i, const tmp<T>& tptr);
// Member operators
// Member Operators
//- Copy assignment.
// For existing list entries, values are copied from the list.
@ -167,7 +179,7 @@ public:
// IOstream operator
//- Read PtrList from Istream, discarding contents of existing PtrList
//- Read from Istream, discarding contents of existing list
friend Istream& operator>> <T>(Istream& is, PtrList<T>& list);
};

View File

@ -26,6 +26,15 @@ License
#include "autoPtr.H"
#include "tmp.H"
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
template<class T>
inline void Foam::PtrList<T>::free()
{
(this->ptrs_).free();
}
// * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
template<class T>
@ -36,9 +45,16 @@ inline constexpr Foam::PtrList<T>::PtrList() noexcept
template<class T>
inline Foam::PtrList<T>::PtrList(const label nElem)
inline Foam::PtrList<T>::PtrList(const label len)
:
UPtrList<T>(nElem)
UPtrList<T>(len)
{}
template<class T>
inline Foam::PtrList<T>::PtrList(const PtrList<T>& list)
:
UPtrList<T>(list.ptrs_.clone())
{}
@ -49,8 +65,28 @@ inline Foam::PtrList<T>::PtrList(PtrList<T>&& list)
{}
template<class T>
template<class CloneArg>
inline Foam::PtrList<T>::PtrList
(
const PtrList<T>& list,
const CloneArg& cloneArg
)
:
UPtrList<T>(list.clone(cloneArg)())
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class T>
inline void Foam::PtrList<T>::clear()
{
(this->ptrs_).free();
UPtrList<T>::clear();
}
template<class T>
inline void Foam::PtrList<T>::setSize(const label newLen)
{
@ -59,16 +95,30 @@ inline void Foam::PtrList<T>::setSize(const label newLen)
template<class T>
inline void Foam::PtrList<T>::append(const autoPtr<T>& aptr)
inline void Foam::PtrList<T>::append(T* ptr)
{
return UPtrList<T>::append(const_cast<autoPtr<T>&>(aptr).ptr());
UPtrList<T>::append(ptr);
}
template<class T>
inline void Foam::PtrList<T>::append(autoPtr<T>& aptr)
{
return UPtrList<T>::append(aptr.release());
}
template<class T>
inline void Foam::PtrList<T>::append(autoPtr<T>&& aptr)
{
return UPtrList<T>::append(aptr.release());
}
template<class T>
inline void Foam::PtrList<T>::append(const tmp<T>& tptr)
{
return UPtrList<T>::append(const_cast<tmp<T>&>(tptr).ptr());
return UPtrList<T>::append(tptr.ptr());
}
@ -80,38 +130,37 @@ inline bool Foam::PtrList<T>::set(const label i) const
template<class T>
inline Foam::autoPtr<T> Foam::PtrList<T>::set(const label i, T* ptr)
inline Foam::autoPtr<T> Foam::PtrList<T>::set(label i, T* ptr)
{
return autoPtr<T>(UPtrList<T>::set(i, ptr));
}
template<class T>
inline Foam::autoPtr<T> Foam::PtrList<T>::set
(
const label i,
const autoPtr<T>& aptr
)
inline Foam::autoPtr<T> Foam::PtrList<T>::set(label i, autoPtr<T>& aptr)
{
return set(i, const_cast<autoPtr<T>&>(aptr).ptr());
return set(i, aptr.release());
}
template<class T>
inline Foam::autoPtr<T> Foam::PtrList<T>::set
(
const label i,
const tmp<T>& tptr
)
inline Foam::autoPtr<T> Foam::PtrList<T>::set(label i, autoPtr<T>&& aptr)
{
return set(i, const_cast<tmp<T>&>(tptr).ptr());
return set(i, aptr.release());
}
template<class T>
inline Foam::autoPtr<T> Foam::PtrList<T>::set(label i, const tmp<T>& tptr)
{
return set(i, tptr.ptr());
}
template<class T>
inline void Foam::PtrList<T>::transfer(PtrList<T>& list)
{
this->clear();
this->free(); // free old pointers
UPtrList<T>::transfer(list);
}

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) 2018 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -26,7 +26,6 @@ License
#include "PtrList.H"
#include "SLList.H"
#include "Istream.H"
#include "Ostream.H"
#include "INew.H"
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
@ -35,6 +34,8 @@ template<class T>
template<class INew>
void Foam::PtrList<T>::read(Istream& is, const INew& inew)
{
clear(); // Delete old pointers and reset the list size
is.fatalCheck(FUNCTION_NAME);
token firstToken(is);
@ -53,7 +54,7 @@ void Foam::PtrList<T>::read(Istream& is, const INew& inew)
const label len = firstToken.labelToken();
// Set list length to that read
setSize(len);
resize(len);
// Read beginning of contents
const char delimiter = is.readBeginList("PtrList");
@ -100,6 +101,8 @@ void Foam::PtrList<T>::read(Istream& is, const INew& inew)
// "(...)" : read as SLList and transfer contents
// This would be more efficient (fewer allocations, lower overhead)
// using a DynamicList, but then we have circular dependencies
if (firstToken.isPunctuation())
{
if (firstToken.pToken() != token::BEGIN_LIST)
@ -111,7 +114,7 @@ void Foam::PtrList<T>::read(Istream& is, const INew& inew)
<< exit(FatalIOError);
}
SLList<T*> sllPtrs;
SLList<T*> slList;
token lastToken(is);
while
@ -133,15 +136,15 @@ void Foam::PtrList<T>::read(Istream& is, const INew& inew)
<< exit(FatalIOError);
}
sllPtrs.append(inew(is).ptr());
slList.append(inew(is).ptr());
is >> lastToken;
}
setSize(sllPtrs.size());
resize(slList.size());
// A list of pointers - can simply copy
// A list of pointers - can simply shallow copy them
label i = 0;
for (T* ptr : sllPtrs)
for (T* ptr : slList)
{
set(i++, ptr);
}
@ -178,11 +181,9 @@ Foam::PtrList<T>::PtrList(Istream& is)
// * * * * * * * * * * * * * * * Istream Operator * * * * * * * * * * * * * //
template<class T>
Foam::Istream& Foam::operator>>(Istream& is, PtrList<T>& lst)
Foam::Istream& Foam::operator>>(Istream& is, PtrList<T>& list)
{
lst.clear();
lst.read(is, INew<T>());
list.read(is, INew<T>());
return is;
}

View File

@ -0,0 +1,92 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "PtrListDetail.H"
#include <utility>
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class T>
Foam::label Foam::Detail::PtrListDetail<T>::count() const
{
label ngood = 0;
for (const T* ptr : *this)
{
if (ptr)
{
++ngood;
}
}
return ngood;
}
template<class T>
void Foam::Detail::PtrListDetail<T>::free()
{
List<T*>& ptrs = *this;
const label len = ptrs.size();
for (label i=0; i<len; ++i)
{
T* ptr = ptrs[i];
if (ptr)
{
delete ptr;
}
ptrs[i] = nullptr;
}
}
template<class T>
template<class... Args>
Foam::Detail::PtrListDetail<T>
Foam::Detail::PtrListDetail<T>::clone(Args&&... args) const
{
const List<T*>& ptrs = *this;
const label len = ptrs.size();
PtrListDetail<T> cloned(len);
for (label i=0; i<len; ++i)
{
const T* ptr = ptrs[i];
if (ptr)
{
cloned[i] = ptr->clone(std::forward<Args>(args)...).ptr();
}
}
return cloned;
}
// ************************************************************************* //

View File

@ -0,0 +1,147 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::Detail::PtrListDetail
Description
A rudimentary list of pointers used for PtrList, UPtrList, etc.
This class is considered implementation detail and should not normally
be used other than by OpenFOAM container classes.
SourceFiles
PtrListDetailI.H
PtrListDetail.C
PtrListDetailIO.C
\*---------------------------------------------------------------------------*/
#ifndef PtrListDetail_H
#define PtrListDetail_H
#include "List.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declarations
class Ostream;
namespace Detail
{
/*---------------------------------------------------------------------------*\
Class Detail::PtrListDetail Declaration
\*---------------------------------------------------------------------------*/
template<class T>
class PtrListDetail
:
public List<T*>
{
public:
// Constructors
//- Construct null
inline constexpr PtrListDetail() noexcept;
//- Construct with specified size, each element initialized to nullptr
inline PtrListDetail(const label len);
//- Copy construct (shallow copies addresses)
inline PtrListDetail(const PtrListDetail<T>& list);
//- Move construct
inline PtrListDetail(PtrListDetail<T>&& list);
//- Copy or move (reuse) construct as specified
inline PtrListDetail(PtrListDetail<T>& list, bool reuse);
// Member Functions
//- Return the count of non-nullptr entries
label count() const;
//- Delete the allocated entries, but retain the list size.
void free();
//- Make a copy by cloning each of the list pointers.
template<class... Args>
PtrListDetail<T> clone(Args&&... args) const;
//- Reset size of list.
// New entries are initialized to nullptr.
inline void resize(const label newLen);
//- Override size to be inconsistent with allocated storage.
// Use with care
inline void setAddressableSize(const label n);
//- Write output, optionally silently trimming nullptrs
Ostream& write(Ostream& os, const bool trimNull=false) const;
// Member Operators
//- Copy assignment (shallow copies addresses)
inline void operator=(const PtrListDetail<T>& list);
//- Move assignment
inline void operator=(PtrListDetail<T>&& list);
// Housekeeping
// Just use resize().
void setSize(const label) = delete;
void setSize(const label, const T&) = delete;
void setSize(const label, const T*) = delete;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Detail
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "PtrListDetailI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "PtrListDetail.C"
#include "PtrListDetailIO.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,119 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
template<class T>
inline constexpr Foam::Detail::PtrListDetail<T>::PtrListDetail() noexcept
:
List<T*>()
{}
template<class T>
inline Foam::Detail::PtrListDetail<T>::PtrListDetail(const label len)
:
List<T*>(len, reinterpret_cast<T*>(0))
{}
template<class T>
inline Foam::Detail::PtrListDetail<T>::PtrListDetail
(
const PtrListDetail<T>& list
)
:
List<T*>(list)
{}
template<class T>
inline Foam::Detail::PtrListDetail<T>::PtrListDetail
(
PtrListDetail<T>&& list
)
:
List<T*>(std::move(list))
{}
template<class T>
inline Foam::Detail::PtrListDetail<T>::PtrListDetail
(
PtrListDetail<T>& list,
bool reuse
)
:
List<T*>(list, reuse)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class T>
inline void Foam::Detail::PtrListDetail<T>::setAddressableSize(const label n)
{
List<T*>::size(n);
}
template<class T>
inline void Foam::Detail::PtrListDetail<T>::resize(const label newLen)
{
if (newLen <= 0)
{
List<T*>::clear();
}
else if (newLen != List<T*>::size())
{
// Truncate or extend. Any new elements are initialized to nullptr.
List<T*>::resize(newLen, reinterpret_cast<T*>(0));
}
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class T>
inline void Foam::Detail::PtrListDetail<T>::operator=
(
const PtrListDetail<T>& list
)
{
List<T*>::operator=(list); // shallow copy
}
template<class T>
inline void Foam::Detail::PtrListDetail<T>::operator=
(
PtrListDetail<T>&& list
)
{
List<T*>::transfer(list);
}
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -23,24 +23,40 @@ License
\*---------------------------------------------------------------------------*/
#include "UPtrList.H"
#include "PtrListDetail.H"
#include "error.H"
#include "Ostream.H"
// * * * * * * * * * * * * * * * Ostream Operators * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class T>
Foam::Ostream& Foam::operator<<(Ostream& os, const UPtrList<T>& lst)
Foam::Ostream& Foam::Detail::PtrListDetail<T>::write
(
Ostream& os,
const bool trimNull
) const
{
const label len = lst.size();
const label len = this->size();
// Size and start delimiter
os << nl << indent << len << nl
// The (output) size and start delimiter
os << nl << indent << (trimNull ? this->count() : len) << nl
<< indent << token::BEGIN_LIST << incrIndent << nl;
// Contents
for (label i=0; i < len; ++i)
{
os << lst[i] << nl;
const T* ptr = (*this)[i];
if (ptr)
{
os << *ptr << nl;
}
else if (!trimNull)
{
FatalErrorInFunction
<< "cannot dereference nullptr at index " << i
<< " in range [0," << len << ")"
<< abort(FatalError);
}
}
// End delimiter

View File

@ -24,21 +24,16 @@ License
\*---------------------------------------------------------------------------*/
#include "UPtrList.H"
#include "PtrList.H"
#include "Ostream.H"
// * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
template<class T>
Foam::UPtrList<T>::UPtrList(UList<T>& lst)
Foam::UPtrList<T>::UPtrList(PtrList<T>& list)
:
ptrs_(lst.size())
{
const label len = lst.size();
for (label i=0; i<len; ++i)
{
ptrs_[i] = &(lst[i]);
}
}
ptrs_(list.ptrs_) // shallow copy (via const reference)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
@ -57,8 +52,7 @@ void Foam::UPtrList<T>::reorder(const labelUList& oldToNew)
<< abort(FatalError);
}
// New list of pointers
List<T*> ptrLst(len, reinterpret_cast<T*>(0));
Detail::PtrListDetail<T> newList(len);
for (label i=0; i<len; ++i)
{
@ -68,25 +62,25 @@ void Foam::UPtrList<T>::reorder(const labelUList& oldToNew)
{
FatalErrorInFunction
<< "Illegal index " << idx << nl
<< "Valid indices are 0.." << len-1
<< " for type " << typeid(T).name() << nl
<< "Valid indices are [0," << len << ") for type "
<< typeid(T).name() << nl
<< abort(FatalError);
}
if (ptrLst[idx])
if (newList[idx])
{
FatalErrorInFunction
<< "reorder map is not unique; element " << idx
<< " already set for type " << typeid(T).name()
<< abort(FatalError);
}
ptrLst[idx] = ptrs_[i];
newList[idx] = ptrs_[i];
}
// Verify that all pointers were set
// Verify that all pointers were indeed set
for (label i=0; i<len; ++i)
{
if (!ptrLst[i])
if (!newList[i])
{
FatalErrorInFunction
<< "Element " << i << " not set after reordering." << nl
@ -94,7 +88,16 @@ void Foam::UPtrList<T>::reorder(const labelUList& oldToNew)
}
}
ptrs_.swap(ptrLst);
ptrs_.transfer(newList);
}
// * * * * * * * * * * * * * * * Ostream Operators * * * * * * * * * * * * * //
template<class T>
Foam::Ostream& Foam::operator<<(Ostream& os, const UPtrList<T>& list)
{
return list.ptrs_.write(os);
}

View File

@ -29,21 +29,25 @@ Description
management of the pointers - this is to be done elsewhere.
The operator[] returns a reference to the object, not the pointer.
Note
The class definition is such that it contains a list of pointers, but
itself does not inherit from a list of pointers since this would
wreak havoc later inheritance resolution.
See Also
Foam::PtrList
Foam::PtrDynList
SourceFiles
UPtrListI.H
UPtrList.C
UPtrListIO.C
\*---------------------------------------------------------------------------*/
#ifndef UPtrList_H
#define UPtrList_H
#include "List.H"
#include "PtrList.H"
#include "PtrListDetail.H"
#include <iterator>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -68,9 +72,16 @@ class UPtrList
{
protected:
// Protected data
// Protected Member Data
List<T*> ptrs_;
//- The list of pointers
Detail::PtrListDetail<T> ptrs_;
// Constructors
//- Low-level move construct
inline UPtrList(Detail::PtrListDetail<T>&& ptrs);
public:
@ -101,32 +112,34 @@ public:
//- Construct with specified size, each element initialized to nullptr
explicit inline UPtrList(const label len);
//- Construct from PtrList, copying addresses of each list element.
// The argument is non-const access since this UPtrList can be used
// to change its values.
explicit inline UPtrList(PtrList<T>& list);
//- Construct from UList, taking addresses of each list element
explicit UPtrList(UList<T>& list);
//- Construct as copy or re-use as specified
inline UPtrList(UPtrList<T>& list, bool reuse);
//- Copy construct
inline UPtrList(const UPtrList<T>& list) = default;
//- Copy construct (shallow copies addresses)
inline UPtrList(const UPtrList<T>& list);
//- Move construct
inline UPtrList(UPtrList<T>&& list);
//- Construct as shallow copy or re-use as specified
inline UPtrList(UPtrList<T>& list, bool reuse);
//- Shallow copy from PtrList.
// The argument is non-const to reflect that the UPtrList can change
// the values (but not the addresses) of the original list.
explicit UPtrList(PtrList<T>& list);
//- Construct from UList, taking the address of each list element
// The argument is non-const to reflect that the UPtrList can change
// the values of the original list.
explicit inline UPtrList(UList<T>& list);
// Member functions
// Access
//- Return the number of elements in the UPtrList
//- Return the number of elements in the list
inline label size() const;
//- Return true if the UPtrList is empty (ie, size() is zero)
//- Return true if the list is empty (ie, size() is zero)
inline bool empty() const;
//- Return reference to the first element of the list
@ -147,11 +160,11 @@ public:
//- Set list size to zero.
inline void clear();
//- Reset size of UPtrList.
//- Reset size of list.
// New entries are initialized to nullptr.
inline void resize(const label newLen);
//- Reset size of UPtrList.
//- Reset size of list.
// New entries are initialized to nullptr.
inline void setSize(const label newLen);
@ -164,10 +177,11 @@ public:
//- Transfer contents into this list and annul the argument
inline void transfer(UPtrList<T>& list);
//- Return true if element is set (ie, not a nullptr)
//- Return true if element is set (not a nullptr)
inline bool set(const label i) const;
//- Set element to given pointer and return old element (can be null).
//- Set element to specified pointer and return the old list element,
//- which can be a nullptr.
// No checks on new element
inline T* set(const label i, T* ptr);
@ -175,19 +189,19 @@ public:
void reorder(const labelUList& oldToNew);
// Member operators
// Member Operators
//- Return element const reference
//- Return const reference to the element
inline const T& operator[](const label i) const;
//- Return element reference
//- Return reference to the element
inline T& operator[](const label i);
//- Return element const pointer
//- Return const pointer to the element
inline const T* operator()(const label i) const;
//- Copy assignment
UPtrList<T>& operator=(const UPtrList<T>& list) = default;
//- Copy assignment (shallow copies addresses)
inline void operator=(const UPtrList<T>& list);
//- Move assignment
inline void operator=(UPtrList<T>&& list);
@ -217,7 +231,9 @@ public:
inline bool operator==(const iterator& iter) const;
inline bool operator!=(const iterator& iter) const;
inline pointer operator->() const;
inline reference operator*() const;
inline reference operator()() const;
// Forward iteration
@ -269,7 +285,9 @@ public:
inline bool operator==(const const_iterator& iter) const;
inline bool operator!=(const const_iterator& iter) const;
inline pointer operator->() const;
inline reference operator*() const;
inline reference operator()() const;
// Forward iteration
@ -319,7 +337,11 @@ public:
// IOstream operator
//- Write UPtrList to Ostream
friend Ostream& operator<< <T>(Ostream& os, const UPtrList<T>& list);
friend Ostream& operator<< <T>
(
Ostream& os,
const UPtrList<T>& list
);
};
@ -336,7 +358,6 @@ public:
#ifdef NoRepository
#include "UPtrList.C"
#include "UPtrListIO.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -35,12 +35,19 @@ inline constexpr Foam::UPtrList<T>::UPtrList() noexcept
template<class T>
inline Foam::UPtrList<T>::UPtrList(const label len)
:
ptrs_(len, reinterpret_cast<T*>(0))
ptrs_(len)
{}
template<class T>
inline Foam::UPtrList<T>::UPtrList(PtrList<T>& list)
inline Foam::UPtrList<T>::UPtrList(Detail::PtrListDetail<T>&& ptrs)
:
ptrs_(std::move(ptrs))
{}
template<class T>
inline Foam::UPtrList<T>::UPtrList(const UPtrList<T>& list)
:
ptrs_(list.ptrs_)
{}
@ -60,6 +67,20 @@ inline Foam::UPtrList<T>::UPtrList(UPtrList<T>& list, bool reuse)
{}
template<class T>
inline Foam::UPtrList<T>::UPtrList(UList<T>& list)
:
ptrs_(list.size())
{
const label len = ptrs_.size();
for (label i=0; i<len; ++i)
{
ptrs_[i] = &(list[i]);
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class T>
@ -128,25 +149,14 @@ inline const T& Foam::UPtrList<T>::last() const
template<class T>
inline void Foam::UPtrList<T>::resize(const label newLen)
{
if (newLen <= 0)
{
clear();
return;
}
const label oldLen = this->size();
if (newLen != oldLen)
{
// Truncate or extend. Any new elements are initialized to nullptr.
ptrs_.resize(newLen, reinterpret_cast<T*>(0));
}
ptrs_.resize(newLen);
}
template<class T>
inline void Foam::UPtrList<T>::setSize(const label newLen)
{
this->resize(newLen);
ptrs_.resize(newLen);
}
@ -180,30 +190,34 @@ inline T* Foam::UPtrList<T>::set(const label i, T* ptr)
template<class T>
inline const T& Foam::UPtrList<T>::operator[](const label i) const
{
if (!ptrs_[i])
const T* ptr = ptrs_[i];
if (!ptr)
{
FatalErrorInFunction
<< "cannot dereference nullptr at index " << i
<< " (size " << size() << ")"
<< " in range [0," << size() << ")"
<< abort(FatalError);
}
return *(ptrs_[i]);
return *ptr;
}
template<class T>
inline T& Foam::UPtrList<T>::operator[](const label i)
{
if (!ptrs_[i])
T* ptr = ptrs_[i];
if (!ptr)
{
FatalErrorInFunction
<< "cannot dereference nullptr at index " << i
<< " (size " << size() << ")"
<< " in range [0," << size() << ")"
<< abort(FatalError);
}
return *(ptrs_[i]);
return *ptr;
}
@ -214,7 +228,7 @@ inline const T* Foam::UPtrList<T>::operator()(const label i) const
}
// * * * * * * * * * * * * * * * * STL iterator * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * iterator * * * * * * * * * * * * * * * * //
template<class T>
inline Foam::UPtrList<T>::iterator::iterator(T** ptr)
@ -237,6 +251,13 @@ inline bool Foam::UPtrList<T>::iterator::operator!=(const iterator& iter) const
}
template<class T>
inline T* Foam::UPtrList<T>::iterator::operator->() const
{
return *ptr_;
}
template<class T>
inline T& Foam::UPtrList<T>::iterator::operator*() const
{
@ -366,7 +387,7 @@ inline bool Foam::UPtrList<T>::iterator::operator>=(const iterator& iter) const
}
// * * * * * * * * * * * * * * * STL const_iterator * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * const_iterator * * * * * * * * * * * * * * //
template<class T>
inline Foam::UPtrList<T>::const_iterator::const_iterator(const T* const* ptr)
@ -402,6 +423,13 @@ inline bool Foam::UPtrList<T>::const_iterator::operator!=
}
template<class T>
inline const T* Foam::UPtrList<T>::const_iterator::operator->() const
{
return *ptr_;
}
template<class T>
inline const T& Foam::UPtrList<T>::const_iterator::operator*() const
{
@ -596,10 +624,17 @@ Foam::UPtrList<T>::end() const
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class T>
inline void Foam::UPtrList<T>::operator=(const UPtrList<T>& list)
{
ptrs_ = list.ptrs_; // shallow copy
}
template<class T>
inline void Foam::UPtrList<T>::operator=(UPtrList<T>&& list)
{
this->transfer(list);
ptrs_.transfer(list.ptrs_);
}