diff --git a/applications/test/xfer/Make/files b/applications/test/xfer/Make/files deleted file mode 100644 index bbe20a4c7ef003a845f11774d089102f5f3dbf43..0000000000000000000000000000000000000000 --- a/applications/test/xfer/Make/files +++ /dev/null @@ -1,3 +0,0 @@ -Test-xferList.C - -EXE = $(FOAM_USER_APPBIN)/Test-xferList diff --git a/applications/test/xfer1/Make/files b/applications/test/xfer1/Make/files new file mode 100644 index 0000000000000000000000000000000000000000..10a272c027317cc5a5be6cc3ec959f654fdf6461 --- /dev/null +++ b/applications/test/xfer1/Make/files @@ -0,0 +1,3 @@ +Test-xfer1.C + +EXE = $(FOAM_USER_APPBIN)/Test-xfer1 diff --git a/applications/test/xfer/Make/options b/applications/test/xfer1/Make/options similarity index 100% rename from applications/test/xfer/Make/options rename to applications/test/xfer1/Make/options diff --git a/applications/test/xfer/Test-xferList.C b/applications/test/xfer1/Test-xfer1.C similarity index 67% rename from applications/test/xfer/Test-xferList.C rename to applications/test/xfer1/Test-xfer1.C index 897e4270724bbfae63f792a7190d46a6e8faa6c3..e12d5fc48f4cb7f1e61c22405474e18e16e1ee12 100644 --- a/applications/test/xfer/Test-xferList.C +++ b/applications/test/xfer1/Test-xfer1.C @@ -39,61 +39,83 @@ Description using namespace Foam; - // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // Main program: int main(int argc, char *argv[]) { - List<label> lstA(10); - List<label> lstC + labelList lstA(10); + labelList lstC { 1, 2, 3, 4 }; forAll(lstA, i) { - lstA[i] = i; + lstA[i] = 5 - i; } - Info<< "lstA: " << lstA << endl; - Info<< "lstC: " << lstC << endl; + Info<< "lstA: " << lstA << nl + << "lstC: " << lstC << nl; + + Xfer<labelList> xA = xferMove(lstA); + Xfer<labelList> xB; - Xfer<List<label>> xA = xferMove(lstA); - Xfer<List<label>> xB; + labelList lstB( xA ); - List<label> lstB( xA ); + Info<< "xA: " << xA() << nl + << "xB: " << xB() << nl + << "lstA: " << lstA << nl + << "lstB: " << lstB << nl + << "lstC: " << lstC << nl; - Info<< "xA: " << xA() << endl; - Info<< "xB: " << xB() << endl; - Info<< "lstA: " << lstA << endl; - Info<< "lstB: " << lstB << endl; - Info<< "lstC: " << lstC << endl; + // Now illegal: xA = lstB; - xA = lstB; + xA->transfer(lstB); - Info<< "xA: " << xA() << endl; - Info<< "xB: " << xB() << endl; - Info<< "lstA: " << lstA << endl; - Info<< "lstB: " << lstB << endl; - Info<< "lstC: " << lstC << endl; + Info<< "xA: " << xA() << nl + << "xB: " << xB() << nl + << "lstA: " << lstA << nl + << "lstB: " << lstB << nl + << "lstC: " << lstC << nl; xB = xA; - List<label> lstD(xferCopy(lstC)); - List<label> lstE(xferMove(lstC)); + // Construct with forwarding. For this example, truly ugly. + Xfer<labelList> xFwdA = + Xfer<labelList>::New + ( + std::initializer_list<label> + { + 1, 2, 10, 20, 15, 24, 200 + } + ); + + Xfer<labelList> xFwdB = Xfer<labelList>::New(label(8), 123); + Xfer<labelList> xFwdC = Xfer<labelList>::New(); + + Info<< nl + << "Constructed with forwarding: " << nl + << *xFwdA << nl + << *xFwdB << nl + << *xFwdC << nl + << nl; + + + labelList lstD(xferCopy(lstC)); + labelList lstE(xferMove(lstC)); // this must be empty - List<label> lstF = xferCopy(lstC); + labelList lstF = xferCopy(lstC); - Info<< "xA: " << xA() << endl; - Info<< "xB: " << xB() << endl; - Info<< "lstA: " << lstA << endl; - Info<< "lstB: " << lstB << endl; - Info<< "lstC: " << lstC << endl; - Info<< "lstD: " << lstD << endl; - Info<< "lstE: " << lstE << endl; - Info<< "lstF: " << lstF << endl; + Info<< "xA: " << xA() << nl + << "xB: " << xB() << nl + << "lstA: " << lstA << nl + << "lstB: " << lstB << nl + << "lstC: " << lstC << nl + << "lstD: " << lstD << nl + << "lstE: " << lstE << nl + << "lstF: " << lstF << nl; Info<< "xB[" << xB->size() << "]\n"; @@ -102,7 +124,7 @@ int main(int argc, char *argv[]) Info<< "xB[" << xB->size() << "]\n"; - DynamicList<label> dl(10); + DynamicList<label> dl; for (label i = 0; i < 5; ++i) { dl.append(i); @@ -111,9 +133,9 @@ int main(int argc, char *argv[]) face f1(dl); face f2(xferCopy<labelList>(dl)); - Info<< "dl[" << dl.size() << "/" << dl.capacity() << "] " << dl << endl; - Info<< "f1: " << f1 << endl; - Info<< "f2: " << f2 << endl; + Info<< "dl[" << dl.size() << "/" << dl.capacity() << "] " << dl << nl; + Info<< "f1: " << f1 << nl; + Info<< "f2: " << f2 << nl; // add some more labels for (label i = 5; i < 8; ++i) @@ -123,18 +145,18 @@ int main(int argc, char *argv[]) // note: xfer() method returns a plain labelList face f3(dl.xfer()); - Info<< "dl[" << dl.size() << "/" << dl.capacity() << "] " << dl << endl; - Info<< "f3: " << f3 << endl; + Info<< "dl[" << dl.size() << "/" << dl.capacity() << "] " << dl << nl; + Info<< "f3: " << f3 << nl; - Info<<"\nflip faces:" << endl; + Info<<"\nflip faces:" << nl; f1.flip(); f3.flip(); - Info<< "f1: " << f1 << endl; - Info<< "f3: " << f3 << endl; + Info<< "f1: " << f1 << nl; + Info<< "f3: " << f3 << nl; { - Info<<"\nTest xfer with fields:" << endl; + Info<<"\nTest xfer with fields:" << nl; List<point> list1 { { 0, 1, 2 }, @@ -180,7 +202,6 @@ int main(int argc, char *argv[]) <<"xfer copy construct from Field (as Field): " << nl <<"input (field) = " << field4 << nl <<"output (dyn-field) = " << dyfield1 << nl; - } return 0; diff --git a/src/OpenFOAM/memory/Xfer/Xfer.H b/src/OpenFOAM/memory/Xfer/Xfer.H index 33dfec74633a3af3d24da0a1781503cc6f69cb23..1a68572f61c5928ef2551384d8c0a66d3027ecd2 100644 --- a/src/OpenFOAM/memory/Xfer/Xfer.H +++ b/src/OpenFOAM/memory/Xfer/Xfer.H @@ -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. @@ -38,29 +38,18 @@ Description When transferring between dissimilar types, the xferCopyTo() and xferMoveTo() functions can prove useful. An example is transferring - from a DynamicList to a List. Since the - List\<T\>::transfer(List\<T\>&) method could result in some allocated - memory becoming inaccessible, the xferMoveTo() function should be used to - invoke the correct List\<T\>::transfer(DynamicList\<T\>&) method. + from a DynamicList to a List. \code - DynamicList<label> dynLst; + List<label> list1; + DynamicList<label> list2; ... - labelList plainLst( xferMoveTo<labelList>(dynLst) ); - \endcode - - Of course, since this example is a very common operation, the - DynamicList::xfer() method transfers to a plain List anyhow. - It would thus be simpler (and clearer) just to use the following code: - \code - DynamicList<label> dynLst; - ... - labelList plainLst(dynLst.xfer()); + SomeClass obj(xferCopy(list1), xferMoveTo<labelList>(list1)); \endcode See also - xferCopy, xferCopyTo, xferMove, xferMoveTo, xferTmp + xferCopy, xferCopyTo, xferMove, xferMoveTo SourceFiles XferI.H @@ -75,9 +64,6 @@ SourceFiles namespace Foam { -// Forward declaration of classes -template<class T> class tmp; - /*---------------------------------------------------------------------------*\ Class Xfer Declaration \*---------------------------------------------------------------------------*/ @@ -95,81 +81,80 @@ public: typedef T Type; - // Constructors //- Store object pointer and manage its deletion // Can also be used later to transfer by assignment inline explicit Xfer(T* p = nullptr); - //- Construct by copying or by transferring the parameter contents - inline explicit Xfer(T& t, bool allowTransfer=false); - - //- Construct by copying the parameter contents - inline explicit Xfer(const T& t); - - //- Construct by transferring the contents - inline Xfer(const Xfer<T>& t); + //- Construct, transferring its contents + inline Xfer(const Xfer<T>& xf); //- Destructor inline ~Xfer(); - // Member Functions + // Static Member Functions //- Return a null object reference inline static const Xfer<T>& null(); + //- Construct new Xfer container with forwarding arguments to T + template<class... Args> + inline static Xfer<T> New(Args&&... args); + + + // Member Functions + + //- Pointer to the underlying object + inline T* get() const; + + //- Swaps the managed objects + void swap(Xfer<T>& other) noexcept; + // Member Operators - //- Transfer the contents into the object - inline void operator=(T& t); + //- Transfer contents into the object + inline void operator=(const Xfer<T>& xf); + + //- Reference to the underlying object + inline T& operator*() const; - //- Transfer the contents into the object - inline void operator=(const Xfer<T>& t); + //- Pointer to the underlying object + inline T* operator->() const; - //- Reference to the underlying datatype + //- Reference to the underlying object inline T& operator()() const; - //- Pointer to the underlying datatype - inline T* operator->() const; }; -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // -//- Construct by copying the contents of the \a arg -// -// \sa xferCopyTo, xferMove, xferMoveTo, xferTmp and Foam::Xfer -template<class T> -inline Xfer<T> xferCopy(const T& t); -//- Construct by transferring the contents of the \a arg +//- Copy construct contents of the \a obj // -// \sa xferCopy, xferCopyTo, xferMoveTo, xferTmp and Foam::Xfer +// \sa xferCopyTo, xferMove, xferMoveTo and Foam::Xfer template<class T> -inline Xfer<T> xferMove(T& t); - +inline Xfer<T> xferCopy(const T& obj); -//- Construct by transferring the contents of the \a arg +//- Transfer construct contents of the \a obj // -// \sa xferCopy, xferCopyTo, xferMove, xferMoveTo and Foam::Xfer +// \sa xferCopy, xferCopyTo, xferMoveTo and Foam::Xfer template<class T> -inline Xfer<T> xferTmp(Foam::tmp<T>& tt); +inline Xfer<T> xferMove(T& obj); -//- Construct by copying the contents of the \a arg -// between dissimilar types +//- Copy construct contents of the \a obj from dissimilar type // -// \sa xferCopy, xferMove, xferMoveTo, xferTmp and Foam::Xfer -template<class To, class From> -inline Xfer<To> xferCopyTo(const From& t); +// \sa xferCopy, xferMove, xferMoveTo and Foam::Xfer +template<class T, class From> +inline Xfer<T> xferCopyTo(const From& obj); -//- Construct by transferring the contents of the \a arg -// between dissimilar types +//- Transfer construct contents of the \a obj from dissimilar type // // \par Example Use // \code @@ -178,9 +163,9 @@ inline Xfer<To> xferCopyTo(const From& t); // labelList plainLst( xferMoveTo<labelList>(dynLst) ); // \endcode // -// \sa xferCopy, xferCopyTo, xferMove, xferTmp and Foam::Xfer -template<class To, class From> -inline Xfer<To> xferMoveTo(From& t); +// \sa xferCopy, xferCopyTo, xferMove and Foam::Xfer +template<class T, class From> +inline Xfer<T> xferMoveTo(From& obj); // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/OpenFOAM/memory/Xfer/XferI.H b/src/OpenFOAM/memory/Xfer/XferI.H index 26e11724db55dab719e0c71ee85ee67293d8a467..bcb21d8adb6f076492d656d9214da5187881ae04 100644 --- a/src/OpenFOAM/memory/Xfer/XferI.H +++ b/src/OpenFOAM/memory/Xfer/XferI.H @@ -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. @@ -24,6 +24,7 @@ License \*---------------------------------------------------------------------------*/ #include "nullObject.H" +#include <utility> // * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * * // @@ -34,6 +35,15 @@ inline const Foam::Xfer<T>& Foam::Xfer<T>::null() } +template<class T> +template<class... Args> +inline Foam::Xfer<T> Foam::Xfer<T>::New(Args&&... args) +{ + T* ptr = new T(std::forward<Args>(args)...); + return Foam::Xfer<T>(ptr); +} + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // template<class T> @@ -44,36 +54,35 @@ inline Foam::Xfer<T>::Xfer(T* p) template<class T> -inline Foam::Xfer<T>::Xfer(T& t, bool allowTransfer) +inline Foam::Xfer<T>::Xfer(const Xfer<T>& xf) : ptr_(new T) { - if (allowTransfer) - { - ptr_->transfer(t); - } - else + T* p = xf.get(); + + if (p && Foam::notNull(p)) { - ptr_->operator=(t); + ptr_->transfer(*p); } } +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + template<class T> -inline Foam::Xfer<T>::Xfer(const T& t) -: - ptr_(new T) +inline T* Foam::Xfer<T>::get() const { - ptr_->operator=(t); + return ptr_; } template<class T> -inline Foam::Xfer<T>::Xfer(const Xfer<T>& t) -: - ptr_(new T) +inline void Foam::Xfer<T>::swap(Xfer<T>& other) noexcept { - ptr_->transfer(*(t.ptr_)); + // Swap pointers + T* tmp = ptr_; + ptr_ = other.ptr; + other.ptr_ = tmp; } @@ -82,36 +91,29 @@ inline Foam::Xfer<T>::Xfer(const Xfer<T>& t) template<class T> inline Foam::Xfer<T>::~Xfer() { - delete ptr_; + if (ptr_ && Foam::notNull(ptr_)) + { + delete ptr_; + } ptr_ = nullptr; } -// * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * * // - - // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // template<class T> -inline void Foam::Xfer<T>::operator=(T& t) -{ - ptr_->transfer(t); -} - - -template<class T> -inline void Foam::Xfer<T>::operator=(const Xfer<T>& t) +inline void Foam::Xfer<T>::operator=(const Xfer<T>& xf) { - // silently ignore attempted copy to self - if (this != &t) + // Silently ignore attempted copy to self + if (this != &xf) { - ptr_->transfer(*(t.ptr_)); + ptr_->transfer(*xf); } } template<class T> -inline T& Foam::Xfer<T>::operator()() const +inline T& Foam::Xfer<T>::operator*() const { return *ptr_; } @@ -124,45 +126,46 @@ inline T* Foam::Xfer<T>::operator->() const } -// * * * * * * * * * * * * * Helper Functions * * * * * * * * * * * * * * * // - - template<class T> -inline Foam::Xfer<T> Foam::xferCopy(const T& t) +inline T& Foam::Xfer<T>::operator()() const { - return Foam::Xfer<T>(t); + return *ptr_; } +// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // + template<class T> -inline Foam::Xfer<T> Foam::xferMove(T& t) +inline Foam::Xfer<T> Foam::xferCopy(const T& obj) { - return Foam::Xfer<T>(t, true); + T* ptr = new T(obj); + return Foam::Xfer<T>(ptr); } -template<class T> -inline Foam::Xfer<T> Foam::xferTmp(Foam::tmp<T>& tt) +template<class T, class From> +inline Foam::Xfer<T> Foam::xferCopyTo(const From& obj) { - return Foam::Xfer<T>(tt(), tt.isTmp()); + T* ptr = new T(obj); + return Foam::Xfer<T>(ptr); } -template<class To, class From> -inline Foam::Xfer<To> Foam::xferCopyTo(const From& t) +template<class T> +inline Foam::Xfer<T> Foam::xferMove(T& obj) { - Foam::Xfer<To> xf; - xf() = t; - return xf; + T* ptr = new T; + ptr->transfer(obj); + return Foam::Xfer<T>(ptr); } -template<class To, class From> -inline Foam::Xfer<To> Foam::xferMoveTo(From& t) +template<class T, class From> +inline Foam::Xfer<T> Foam::xferMoveTo(From& obj) { - Foam::Xfer<To> xf; - xf().transfer(t); - return xf; + T* ptr = new T; + ptr->transfer(obj); + return Foam::Xfer<T>(ptr); } diff --git a/src/OpenFOAM/memory/tmp/tmp.H b/src/OpenFOAM/memory/tmp/tmp.H index 245b709722095e59330e50fbf24791df06f83537..52dc896a832ada90423d748af8766c2f5939af1c 100644 --- a/src/OpenFOAM/memory/tmp/tmp.H +++ b/src/OpenFOAM/memory/tmp/tmp.H @@ -63,12 +63,12 @@ class tmp CONST_REF }; - //- Type of object - type type_; - //- Pointer to object mutable T* ptr_; + //- Type of object + type type_; + // Private member operators diff --git a/src/OpenFOAM/memory/tmp/tmpI.H b/src/OpenFOAM/memory/tmp/tmpI.H index cd1183d49a565e05812f0384ad447efc055fc1ff..c789bc0dbff257c76b0d4038394dd322156b2f78 100644 --- a/src/OpenFOAM/memory/tmp/tmpI.H +++ b/src/OpenFOAM/memory/tmp/tmpI.H @@ -48,16 +48,16 @@ inline void Foam::tmp<T>::operator++() template<class T> inline Foam::tmp<T>::tmp() : - type_(TMP), - ptr_(nullptr) + ptr_(nullptr), + type_(TMP) {} template<class T> inline Foam::tmp<T>::tmp(T* p) : - type_(TMP), - ptr_(p) + ptr_(p), + type_(TMP) { if (p && !p->unique()) { @@ -72,16 +72,16 @@ inline Foam::tmp<T>::tmp(T* p) template<class T> inline Foam::tmp<T>::tmp(const T& t) : - type_(CONST_REF), - ptr_(const_cast<T*>(&t)) + ptr_(const_cast<T*>(&t)), + type_(CONST_REF) {} template<class T> inline Foam::tmp<T>::tmp(const tmp<T>& t) : - type_(t.type_), - ptr_(t.ptr_) + ptr_(t.ptr_), + type_(t.type_) { if (isTmp()) { @@ -102,8 +102,8 @@ inline Foam::tmp<T>::tmp(const tmp<T>& t) template<class T> inline Foam::tmp<T>::tmp(const tmp<T>&& t) : - type_(t.type_), - ptr_(t.ptr_) + ptr_(t.ptr_), + type_(t.type_) { if (isTmp()) { @@ -115,8 +115,8 @@ inline Foam::tmp<T>::tmp(const tmp<T>&& t) template<class T> inline Foam::tmp<T>::tmp(const tmp<T>& t, bool allowTransfer) : - type_(t.type_), - ptr_(t.ptr_) + ptr_(t.ptr_), + type_(t.type_) { if (isTmp()) { @@ -335,8 +335,8 @@ inline void Foam::tmp<T>::operator=(T* p) << abort(FatalError); } - type_ = TMP; ptr_ = p; + type_ = TMP; }