diff --git a/applications/test/xfer/xferListTest.C b/applications/test/xfer/xferListTest.C index 019ca3bfd1ebccf34e714729a1b5e4e10619830e..6f2af0932adcc94403b833840810f338dd29c857 100644 --- a/applications/test/xfer/xferListTest.C +++ b/applications/test/xfer/xferListTest.C @@ -38,6 +38,8 @@ Description using namespace Foam; + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // Main program: @@ -104,21 +106,17 @@ int main(int argc, char *argv[]) } face f1(dl); + face f2(xferCopy<labelList>(dl)); Info<< "dl[" << dl.size() << "/" << dl.allocSize() << "] " << dl << endl; Info<< "f1: " << f1 << endl; - - // note: the allocated size will be wrong, but we can at least avoid - // wasting memory by using a shrink - - face f2(xferMove<labelList>(dl.shrink())); - Info<< "dl[" << dl.size() << "/" << dl.allocSize() << "] " << dl << endl; Info<< "f2: " << f2 << endl; - dl.clearStorage(); - + // note: using xferMoveTo to ensure the correct transfer() method is called + face f3( xferMoveTo<labelList>(dl) ); Info<< "dl[" << dl.size() << "/" << dl.allocSize() << "] " << dl << endl; - + Info<< "f3: " << f3 << endl; + return 0; } diff --git a/src/OpenFOAM/memory/xfer/xfer.H b/src/OpenFOAM/memory/xfer/xfer.H index e13782c9f4c35854f590245536a09dd896f265b5..cec4624c13a5bc04e4e1f5aa6e01cb788d28e8ef 100644 --- a/src/OpenFOAM/memory/xfer/xfer.H +++ b/src/OpenFOAM/memory/xfer/xfer.H @@ -26,19 +26,33 @@ Class Foam::xfer Description - A simple container that can be used to copy or transfer the contents - of objects of type \<T\>. - - Since it is decided upon construction of the xfer object whether the - parameter is to be copied or transferred, the contents of the resulting - object can be transferred unconditionally. - - This greatly simplifies defining the constructors for other classes - with mixed transfer/copy semantics. + A simple container for copying or transferring objects of type \<T\>. The wrapped object of type \<T\> must implement a transfer() method and an operator=() copy method. + Since it is decided upon construction of the xfer object whether the + parameter is to be copied or transferred, the contents of the resulting + xfer object can be transferred unconditionally. This greatly simplifies + defining constructors or methods in other classes with mixed + transfer/copy semantics without requiring 2^N different versions. + + 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 can be used to + invoke the correct List\<T\>::transfer(DynamicList\<T\>&) method. + + @code + DynamicList<label> dynLst; + ... + labelList plainLst( xferMoveTo<labelList>(dynLst) ); + @endcode + +SeeAlso + xferCopy, xferCopyTo, xferMove, xferMoveTo, xferTmp + SourceFiles xferI.H @@ -64,7 +78,7 @@ class xfer { // Private data - //- Pointer to temporary object + //- Pointer to underlying datatype mutable T* ptr_; public: @@ -108,49 +122,56 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // /** - * @fn template<class T> xferCopy(const T&) * Construct by copying the contents of the @a arg * - * @sa xferMove, xferTmp and Foam::xfer + * @sa xferCopyTo, xferMove, xferMoveTo, xferTmp and Foam::xfer */ template<class T> -Foam::xfer<T> xferCopy(const T& t) -{ - return Foam::xfer<T>(t); -} - +inline xfer<T> xferCopy(const T&); /** - * @fn template<class T> xferMove(T&) * Construct by transferring the contents of the @a arg * - * @par Example Use - * @code - * List<label> a; - * ... - * List<label> b(xferMove(a)); - * @endcode - * - * @sa xferCopy, xferTmp and Foam::xfer + * @sa xferCopy, xferCopyTo, xferMoveTo, xferTmp and Foam::xfer */ template<class T> -Foam::xfer<T> xferMove(T& t) -{ - return Foam::xfer<T>(t, true); -} +inline xfer<T> xferMove(T&); /** - * @fn template<class T> xferTmp(tmp<T>&) * Construct by transferring the contents of the @a arg * - * @sa xferCopy, xferMove and Foam::xfer + * @sa xferCopy, xferCopyTo, xferMove, xferMoveTo and Foam::xfer */ template<class T> -Foam::xfer<T> xferTmp(Foam::tmp<T>& tt) -{ - return Foam::xfer<T>(tt(), tt.isTmp()); -} +inline xfer<T> xferTmp(Foam::tmp<T>&); + + +/** + * Construct by copying the contents of the @a arg + * between dissimilar types + * + * @sa xferCopy, xferMove, xferMoveTo, xferTmp and Foam::xfer +*/ +template<class To, class From> +inline xfer<To> xferCopyTo(const From&); + + +/** + * Construct by transferring the contents of the @a arg + * between dissimilar types + * + * @par Example Use + * @code + * DynamicList<label> dynLst; + * ... + * labelList plainLst( xferMoveTo<labelList>(dynLst) ); + * @endcode + * + * @sa xferCopy, xferCopyTo, xferMove, xferTmp and Foam::xfer +*/ +template<class To, class From> +inline xfer<To> xferMoveTo(From&); } // End namespace Foam diff --git a/src/OpenFOAM/memory/xfer/xferI.H b/src/OpenFOAM/memory/xfer/xferI.H index 55830008a981dd1d1619ba7b56d9045e4cbb2c9b..aabeaaf1de3140974086208f40b845d28b9dfda5 100644 --- a/src/OpenFOAM/memory/xfer/xferI.H +++ b/src/OpenFOAM/memory/xfer/xferI.H @@ -89,7 +89,7 @@ inline void Foam::xfer<T>::operator=(T& t) template<class T> inline void Foam::xfer<T>::operator=(const xfer<T>& t) { - // silently ignore copy to self + // silently ignore attempted copy to self if (this != &t) { ptr_->transfer(*(t.ptr_)); @@ -110,4 +110,46 @@ inline T* Foam::xfer<T>::operator->() const return ptr_; } + +// * * * * * * * * * * * * * Helper Functions * * * * * * * * * * * * * * * // + + +template<class T> +inline Foam::xfer<T> Foam::xferCopy(const T& t) +{ + return Foam::xfer<T>(t); +} + +template<class T> +inline Foam::xfer<T> Foam::xferMove(T& t) +{ + return Foam::xfer<T>(t, true); +} + + +template<class T> +inline Foam::xfer<T> Foam::xferTmp(Foam::tmp<T>& tt) +{ + return Foam::xfer<T>(tt(), tt.isTmp()); +} + + +template<class To, class From> +inline Foam::xfer<To> Foam::xferCopyTo(const From& t) +{ + Foam::xfer<To> xf; + xf() = t; + return xf; +} + + +template<class To, class From> +inline Foam::xfer<To> Foam::xferMoveTo(From& t) +{ + Foam::xfer<To> xf; + xf().transfer(t); + return xf; +} + + // ************************************************************************* //