ENH: Add swap method to XdmfArray. Swap works by swapping an XdmfArray's...

ENH: Add swap method to XdmfArray.  Swap works by swapping an XdmfArray's contents internally (no copy) between a std::vector<T>, boost::shared_ptr<std::vector<T> > or another XdmfArray.  Modify some methods in XdmfArray that did not require visitor operation but can just catch boost::bad_get exceptions.
parent de6cba62
......@@ -176,6 +176,7 @@ class XdmfArrayPtr(_object):
def getValuesPointer(self): return _Xdmf.XdmfArrayPtr_getValuesPointer(self)
def getValuesString(self): return _Xdmf.XdmfArrayPtr_getValuesString(self)
def printSelf(self): return _Xdmf.XdmfArrayPtr_printSelf(self)
def swap(self, *args): return _Xdmf.XdmfArrayPtr_swap(self, *args)
def write(self, *args): return _Xdmf.XdmfArrayPtr_write(self, *args)
def copyValueAsChar(self, *args): return _Xdmf.XdmfArrayPtr_copyValueAsChar(self, *args)
def copyValueAsShort(self, *args): return _Xdmf.XdmfArrayPtr_copyValueAsShort(self, *args)
......@@ -587,6 +588,7 @@ class XdmfArray(XdmfItem):
def getValuesPointer(self): return _Xdmf.XdmfArray_getValuesPointer(self)
def getValuesString(self): return _Xdmf.XdmfArray_getValuesString(self)
def printSelf(self): return _Xdmf.XdmfArray_printSelf(self)
def swap(self, *args): return _Xdmf.XdmfArray_swap(self, *args)
def write(self, *args): return _Xdmf.XdmfArray_write(self, *args)
def copyValueAsChar(self, *args): return _Xdmf.XdmfArray_copyValueAsChar(self, *args)
def copyValueAsShort(self, *args): return _Xdmf.XdmfArray_copyValueAsShort(self, *args)
......
......@@ -303,12 +303,14 @@ void XdmfArray::copyValues(int startIndex, boost::shared_ptr<XdmfArray> values,
mArray = values->mArray;
// Reinitialize variant array to contain new array with same type.
boost::apply_visitor( XdmfArrayNewArray(), mArray);
mInitialized = true;
}
boost::apply_visitor( XdmfArrayCopyArrayValues(startIndex, valuesStartIndex, numValues, arrayStride, valuesStride), mArray, values->mArray);
}
void XdmfArray::clear()
{
mInitialized = false;
return boost::apply_visitor( XdmfArrayClear(), mArray);
}
......@@ -347,6 +349,14 @@ std::string XdmfArray::printSelf() const
return "";
}
void XdmfArray::swap(boost::shared_ptr<XdmfArray> & array)
{
array->mArray.swap(mArray);
bool initialized = array->mInitialized;
array->mInitialized = mInitialized;
mInitialized = initialized;
}
void XdmfArray::write(boost::shared_ptr<XdmfVisitor> visitor) const
{
visitor->visit(this, visitor);
......
......@@ -98,11 +98,11 @@ public:
virtual int getSize() const;
/**
* Get the data type of this array.
*
* @return a string containing the Xdmf data type for the array, this is one of
* Char, Short, Int, Float, UChar, UShort, UInt.
*/
* Get the data type of this array.
*
* @return a string containing the Xdmf data type for the array, this is one of
* Char, Short, Int, Float, UChar, UShort, UInt.
*/
virtual std::string getType() const;
/**
......@@ -146,6 +146,34 @@ public:
template<typename T>
void setValues(boost::shared_ptr<std::vector<T> > array);
/**
* Exchange the contents of the vector with the contents of this XdmfArray. No copy is made. The internal arrays are swapped.
*
* @param array a vector to exchange values with.
* @return bool whether the swap was successful.
*/
template<typename T>
bool swap(std::vector<T> & array);
/**
* Exchange the contents of the vector with the contents of this XdmfArray. No copy is made. The internal arrays are swapped.
*
* @param array a smart pointer to a vector to exchange values with.
*/
template<typename T>
bool swap(boost::shared_ptr<std::vector<T> > array);
/**
* Exchange the contents of an XdmfArray with the contents of this XdmfArray. No copy is made. The internal arrays are swapped.
*
* @param array a smart pointer to a vector to exchange values with.
* @return bool whether the swap was successful.
*/
void swap(boost::shared_ptr<XdmfArray> & array);
/**
*
*/
virtual void write(boost::shared_ptr<XdmfVisitor>) const;
protected:
......
......@@ -40,46 +40,6 @@ private:
int mValuesStride;
};
template <typename T>
class XdmfArrayGetValues : public boost::static_visitor <boost::shared_ptr<std::vector<T> > > {
public:
XdmfArrayGetValues()
{
}
boost::shared_ptr<std::vector<T> > operator()(const boost::shared_ptr<std::vector<T> > & array) const
{
return array;
}
template <typename U>
boost::shared_ptr<std::vector<T> > operator()(const boost::shared_ptr<std::vector<U> > & array) const
{
return boost::shared_ptr<std::vector<T> >();
}
};
template <typename T>
class XdmfArrayGetValuesConst : public boost::static_visitor <const boost::shared_ptr<const std::vector<T> > > {
public:
XdmfArrayGetValuesConst()
{
}
const boost::shared_ptr<const std::vector<T> > operator()(const boost::shared_ptr<const std::vector<T> > & array) const
{
return array;
}
template <typename U>
const boost::shared_ptr<const std::vector<T> > operator()(const boost::shared_ptr<const std::vector<U> > & array) const
{
return boost::shared_ptr<std::vector<T> >();
}
};
template<typename T>
void XdmfArray::copyValues(int startIndex, T * valuesPointer, int numValues, int arrayStride, int valuesStride)
{
......@@ -96,17 +56,66 @@ void XdmfArray::copyValues(int startIndex, T * valuesPointer, int numValues, int
template <typename T>
boost::shared_ptr<std::vector<T> > XdmfArray::getValues()
{
return boost::apply_visitor( XdmfArrayGetValues<T>(), mArray);
try
{
boost::shared_ptr<std::vector<T> > currArray = boost::get<boost::shared_ptr<std::vector<T> > >(mArray);
return currArray;
}
catch(const boost::bad_get& exception)
{
return boost::shared_ptr<std::vector<T> >();
}
}
template <typename T>
const boost::shared_ptr<const std::vector<T> > XdmfArray::getValues() const
{
return boost::apply_visitor( XdmfArrayGetValuesConst<T>(), mArray);
try
{
boost::shared_ptr<std::vector<T> > currArray = boost::get<boost::shared_ptr<std::vector<T> > >(mArray);
return currArray;
}
catch(const boost::bad_get& exception)
{
return boost::shared_ptr<std::vector<T> >();
}
}
template<typename T>
void XdmfArray::setValues(boost::shared_ptr<std::vector<T> > array)
{
mArray = array;
mInitialized = true;
}
template<typename T>
bool XdmfArray::swap(std::vector<T> & array)
{
if(!mInitialized)
{
// Set type of variant to type of pointer
boost::shared_ptr<std::vector<T> > newArray(new std::vector<T>());
mArray = newArray;
mInitialized = true;
}
try
{
boost::shared_ptr<std::vector<T> > currArray = boost::get<boost::shared_ptr<std::vector<T> > >(mArray);
currArray->swap(array);
if(currArray->size() == 0)
{
mInitialized = false;
}
return true;
}
catch(const boost::bad_get& exception)
{
return false;
}
}
template<typename T>
bool XdmfArray::swap(boost::shared_ptr<std::vector<T> > array)
{
return this->swap(*array.get());
}
......@@ -5560,6 +5560,39 @@ fail:
}
SWIGINTERN PyObject *_wrap_XdmfArrayPtr_swap(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
boost::shared_ptr< XdmfArray > *arg1 = (boost::shared_ptr< XdmfArray > *) 0 ;
boost::shared_ptr< XdmfArray > *arg2 = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
void *argp2 = 0 ;
int res2 = 0 ;
PyObject * obj0 = 0 ;
PyObject * obj1 = 0 ;
if (!PyArg_ParseTuple(args,(char *)"OO:XdmfArrayPtr_swap",&obj0,&obj1)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_boost__shared_ptrT_XdmfArray_t, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "XdmfArrayPtr_swap" "', argument " "1"" of type '" "boost::shared_ptr< XdmfArray > *""'");
}
arg1 = reinterpret_cast< boost::shared_ptr< XdmfArray > * >(argp1);
res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_boost__shared_ptrT_XdmfArray_t, 0 );
if (!SWIG_IsOK(res2)) {
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "XdmfArrayPtr_swap" "', argument " "2"" of type '" "boost::shared_ptr< XdmfArray > &""'");
}
if (!argp2) {
SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "XdmfArrayPtr_swap" "', argument " "2"" of type '" "boost::shared_ptr< XdmfArray > &""'");
}
arg2 = reinterpret_cast< boost::shared_ptr< XdmfArray > * >(argp2);
(*arg1)->swap(*arg2);
resultobj = SWIG_Py_Void();
return resultobj;
fail:
return NULL;
}
SWIGINTERN PyObject *_wrap_XdmfArrayPtr_write(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
boost::shared_ptr< XdmfArray > *arg1 = (boost::shared_ptr< XdmfArray > *) 0 ;
......@@ -11068,6 +11101,39 @@ fail:
}
SWIGINTERN PyObject *_wrap_XdmfArray_swap(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
XdmfArray *arg1 = (XdmfArray *) 0 ;
boost::shared_ptr< XdmfArray > *arg2 = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
void *argp2 = 0 ;
int res2 = 0 ;
PyObject * obj0 = 0 ;
PyObject * obj1 = 0 ;
if (!PyArg_ParseTuple(args,(char *)"OO:XdmfArray_swap",&obj0,&obj1)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_XdmfArray, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "XdmfArray_swap" "', argument " "1"" of type '" "XdmfArray *""'");
}
arg1 = reinterpret_cast< XdmfArray * >(argp1);
res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_boost__shared_ptrT_XdmfArray_t, 0 );
if (!SWIG_IsOK(res2)) {
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "XdmfArray_swap" "', argument " "2"" of type '" "boost::shared_ptr< XdmfArray > &""'");
}
if (!argp2) {
SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "XdmfArray_swap" "', argument " "2"" of type '" "boost::shared_ptr< XdmfArray > &""'");
}
arg2 = reinterpret_cast< boost::shared_ptr< XdmfArray > * >(argp2);
(arg1)->swap(*arg2);
resultobj = SWIG_Py_Void();
return resultobj;
fail:
return NULL;
}
SWIGINTERN PyObject *_wrap_XdmfArray_write(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
XdmfArray *arg1 = (XdmfArray *) 0 ;
......@@ -13476,6 +13542,7 @@ static PyMethodDef SwigMethods[] = {
{ (char *)"XdmfArrayPtr_getValuesPointer", _wrap_XdmfArrayPtr_getValuesPointer, METH_VARARGS, NULL},
{ (char *)"XdmfArrayPtr_getValuesString", _wrap_XdmfArrayPtr_getValuesString, METH_VARARGS, NULL},
{ (char *)"XdmfArrayPtr_printSelf", _wrap_XdmfArrayPtr_printSelf, METH_VARARGS, NULL},
{ (char *)"XdmfArrayPtr_swap", _wrap_XdmfArrayPtr_swap, METH_VARARGS, NULL},
{ (char *)"XdmfArrayPtr_write", _wrap_XdmfArrayPtr_write, METH_VARARGS, NULL},
{ (char *)"XdmfArrayPtr_copyValueAsChar", _wrap_XdmfArrayPtr_copyValueAsChar, METH_VARARGS, NULL},
{ (char *)"XdmfArrayPtr_copyValueAsShort", _wrap_XdmfArrayPtr_copyValueAsShort, METH_VARARGS, NULL},
......@@ -13632,6 +13699,7 @@ static PyMethodDef SwigMethods[] = {
{ (char *)"XdmfArray_getValuesPointer", _wrap_XdmfArray_getValuesPointer, METH_VARARGS, NULL},
{ (char *)"XdmfArray_getValuesString", _wrap_XdmfArray_getValuesString, METH_VARARGS, NULL},
{ (char *)"XdmfArray_printSelf", _wrap_XdmfArray_printSelf, METH_VARARGS, NULL},
{ (char *)"XdmfArray_swap", _wrap_XdmfArray_swap, METH_VARARGS, NULL},
{ (char *)"XdmfArray_write", _wrap_XdmfArray_write, METH_VARARGS, NULL},
{ (char *)"XdmfArray_copyValueAsChar", _wrap_XdmfArray_copyValueAsChar, METH_VARARGS, NULL},
{ (char *)"XdmfArray_copyValueAsShort", _wrap_XdmfArray_copyValueAsShort, METH_VARARGS, NULL},
......
......@@ -2,7 +2,7 @@ set(XdmfCxxTests
TestXdmfAttribute
TestXdmfArray
TestXdmfDataItem
TestXdmfGeometry
TestXdmfGeometry
TestXdmfGrid
TestXdmfTopology
TestXdmfVisitor
......
......@@ -92,5 +92,51 @@ int main(int argc, char* argv[])
assert((*iter) == storedValues->operator[](i));
}
/**
* Swap values from a vector
*/
std::vector<short> values4;
values4.push_back(-1);
values4.push_back(0);
values4.push_back(1);
boost::shared_ptr<XdmfArray> array5 = XdmfArray::New();
array5->swap(values4);
assert(values4.size() == 0);
assert(array5->getSize() == 3);
assert(array5->getType().compare("Short") == 0);
assert(array5->getPrecision() == 2);
boost::shared_ptr<std::vector<short> > storedValues5 = array5->getValues<short>();
assert((*storedValues5)[0] == -1);
assert((*storedValues5)[1] == 0);
assert((*storedValues5)[2] == 1);
/**
* Swap values from a shared vector
*/
array5->clear();
array5->swap(storedValues3);
assert(storedValues3->size() == 0);
assert(array5->getSize() == 6);
/**
* Swap values from an XdmfArray
*/
array5->clear();
array5->swap(array4);
assert(array4->getSize() == 0);
assert(array5->getSize() == 4);
/**
* Get values via swap
*/
std::vector<int> valsInt;
bool success = array5->swap(valsInt);
assert(success == false);
std::vector<double> valsDouble;
success = array5->swap(valsDouble);
assert(success == true);
assert(valsDouble.size() == 4);
assert(array5->getSize() == 0);
return 0;
}
Markdown is supported
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