Commit 60d17345 authored by Mark Olesen's avatar Mark Olesen
Browse files

add xferCopyTo and xferMoveTo functions

parent 1faad839
......@@ -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;
}
......
......@@ -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
......
......@@ -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;
}
// ************************************************************************* //
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment