XdmfArray.tpp 6.75 KB
Newer Older
1 2 3
// Includes
#include "XdmfArray.hpp"

4
template <typename T>
5
class XdmfArray::GetValues : public boost::static_visitor<void> {
6 7
public:

8
	GetValues(const unsigned int startIndex, T * valuesPointer, const unsigned int numValues, const unsigned int arrayStride, const unsigned int valuesStride) :
9 10 11 12 13 14 15 16
		mStartIndex(startIndex),
		mValuesPointer(valuesPointer),
		mNumValues(numValues),
		mArrayStride(arrayStride),
		mValuesStride(valuesStride)
	{
	}

17
	template<typename U>
18
	void operator()(const boost::shared_array<const U> & array) const
19
	{
20
		for(unsigned int i=0; i<mNumValues; ++i)
21
		{
22
			mValuesPointer[i*mValuesStride] = (T)array[mStartIndex + i*mArrayStride];
23
		}
24 25 26 27 28 29
	}

	template<typename U>
	void operator()(const boost::shared_ptr<std::vector<U> > & array) const
	{
		for(unsigned int i=0; i<mNumValues; ++i)
30
		{
31
			mValuesPointer[i*mValuesStride] = (T)array->operator[](mStartIndex + i*mArrayStride);
32 33 34 35 36
		}
	}

private:

37
	const unsigned int mStartIndex;
38
	T * mValuesPointer;
39 40 41
	const unsigned int mNumValues;
	const unsigned int mArrayStride;
	const unsigned int mValuesStride;
42 43
};

44
template <typename T>
45
class XdmfArray::Insert : public boost::static_visitor<void> {
46 47
public:

48
	Insert(const unsigned int startIndex, const T * const valuesPointer, const unsigned int numValues, const unsigned int arrayStride, const unsigned int valuesStride) :
49 50 51 52 53 54 55 56 57
		mStartIndex(startIndex),
		mValuesPointer(valuesPointer),
		mNumValues(numValues),
		mArrayStride(arrayStride),
		mValuesStride(valuesStride)
	{
	}

	template<typename U>
58
	void operator()(boost::shared_ptr<std::vector<U> > & array) const
59
	{
60 61
		unsigned int size = mStartIndex + mNumValues;
		if(mArrayStride > 1)
62
		{
63
			size = mStartIndex + mNumValues * mArrayStride - 1;
64
		}
65
		if(array->size() < size)
66
		{
67 68 69 70 71
			array->resize(size);
		}
		for(unsigned int i=0; i<mNumValues; ++i)
		{
			array->operator[](mStartIndex + i*mArrayStride) = (U)mValuesPointer[i*mValuesStride];
72 73 74 75 76 77
		}
	}

private:

	const unsigned int mStartIndex;
78
	const T * const mValuesPointer;
79 80 81 82 83
	const unsigned int mNumValues;
	const unsigned int mArrayStride;
	const unsigned int mValuesStride;
};

84
template <typename T>
85
class XdmfArray::PushBack : public boost::static_visitor<void> {
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
public:

	PushBack(const T & val) :
		mVal(val)
	{
	}

	template<typename U>
	void operator()(boost::shared_ptr<std::vector<U> > & array) const
	{
		array->push_back((U)mVal);
	}

private:

	const T & mVal;
};

template <typename T>
105
class XdmfArray::Resize : public boost::static_visitor<void> {
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
public:

	Resize(const unsigned int numValues, const T & val) :
		mNumValues(numValues),
		mVal(val)
	{
	}

	template<typename U>
	void operator()(boost::shared_ptr<std::vector<U> > & array) const
	{
		array->resize(mNumValues, (U)mVal);
	}

private:

	const unsigned int mNumValues;
	const T & mVal;
};

126
struct XdmfArray::NullDeleter
127 128 129 130 131 132
{
    void operator()(void const *) const
    {
    }
};

133
template <typename T>
134
T XdmfArray::getValue(const unsigned int index) const
135
{
136 137 138
	T toReturn;
	this->getValues(index, &toReturn, 1);
	return toReturn;
139 140
}

141
template <typename T>
142
void XdmfArray::getValues(const unsigned int startIndex, T * const valuesPointer, const unsigned int numValues, const unsigned int arrayStride, const unsigned int valuesStride) const
143
{
144 145 146 147 148 149 150 151
	if(mHaveArray)
	{
		boost::apply_visitor(GetValues<T>(startIndex, valuesPointer, numValues, arrayStride, valuesStride), mArray);
	}
	else if(mHaveArrayPointer)
	{
		boost::apply_visitor(GetValues<T>(startIndex, valuesPointer, numValues, arrayStride, valuesStride), mArrayPointer);
	}
152 153
}

154
template <typename T>
155
boost::shared_ptr<std::vector<T> > XdmfArray::getValuesInternal()
156
{
157
	if(mHaveArrayPointer)
158
	{
159
		internalizeArrayPointer();
160 161 162 163 164 165
	}
	try
	{
		boost::shared_ptr<std::vector<T> > currArray = boost::get<boost::shared_ptr<std::vector<T> > >(mArray);
		return currArray;
	}
166
	catch(const boost::bad_get & exception)
167 168 169
	{
		return boost::shared_ptr<std::vector<T> >();
	}
170 171
}

172
template <typename T>
173
boost::shared_ptr<std::vector<T> > XdmfArray::initialize(const unsigned int size)
174
{
175 176 177 178
	if(mHaveArrayPointer)
	{
		releaseArrayPointer();
	}
179
	// Set type of variant to type of pointer
180
	boost::shared_ptr<std::vector<T> > newArray(new std::vector<T>(size));
181 182 183 184 185
	if(mTmpReserveSize > 0)
	{
		newArray->reserve(mTmpReserveSize);
		mTmpReserveSize = 0;
	}
186
	mArray = newArray;
187
	mHaveArray = true;
188 189 190
	return newArray;
}

191 192 193 194 195 196 197 198 199 200 201 202 203 204
template <typename T>
void XdmfArray::insert(const unsigned int startIndex, const T * const valuesPointer, const unsigned int numValues, const unsigned int arrayStride, const unsigned int valuesStride)
{
	if(mHaveArrayPointer)
	{
		internalizeArrayPointer();
	}
	if(!mHaveArray)
	{
		initialize<T>();
	}
	boost::apply_visitor(Insert<T>(startIndex, valuesPointer, numValues, arrayStride, valuesStride), mArray);
}

205
template <typename T>
206
void XdmfArray::pushBack(const T & value)
207 208 209 210 211
{
	if(mHaveArrayPointer)
	{
		internalizeArrayPointer();
	}
212 213 214 215
	if(!mHaveArray)
	{
		initialize<T>();
	}
216 217 218
	return boost::apply_visitor(PushBack<T>(value), mArray);
}

219
template<typename T>
220
void XdmfArray::resize(const unsigned int numValues, const T & value)
221 222 223 224 225 226 227 228 229
{
	if(mHaveArrayPointer)
	{
		internalizeArrayPointer();
	}
	if(!mHaveArray)
	{
		initialize<T>();
	}
230
	return boost::apply_visitor(Resize<T>(numValues, value), mArray);
231 232
}

233
template <typename T>
234
void XdmfArray::setValuesInternal(const T * const arrayPointer, const unsigned int numValues, const bool transferOwnership)
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254
{
	// Remove contents of internal array.
	if(mHaveArray)
	{
		releaseArray();
	}
	if(transferOwnership)
	{
		const boost::shared_array<const T> newArrayPointer(arrayPointer);
		mArrayPointer = newArrayPointer;
	}
	else
	{
		const boost::shared_array<const T> newArrayPointer(arrayPointer, NullDeleter());
		mArrayPointer = newArrayPointer;
	}
	mHaveArrayPointer = true;
	mArrayPointerNumValues = numValues;
}

255
template <typename T>
256
void XdmfArray::setValuesInternal(std::vector<T> & array, const bool transferOwnership)
257
{
258 259 260 261
	if(mHaveArrayPointer)
	{
		releaseArrayPointer();
	}
262 263 264 265 266 267 268 269 270 271
	if(transferOwnership)
	{
		boost::shared_ptr<std::vector<T> > newArray(&array);
		mArray = newArray;
	}
	else
	{
		boost::shared_ptr<std::vector<T> > newArray(&array, NullDeleter());
		mArray = newArray;
	}
272
	mHaveArray = true;
273 274
}

275
template <typename T>
276
void XdmfArray::setValuesInternal(const boost::shared_ptr<std::vector<T> > array)
277
{
278 279 280 281
	if(mHaveArrayPointer)
	{
		releaseArrayPointer();
	}
282
	mArray = array;
283
	mHaveArray = true;
284 285
}

286
template <typename T>
287 288
bool XdmfArray::swap(std::vector<T> & array)
{
289 290 291 292 293
	if(mHaveArrayPointer)
	{
		internalizeArrayPointer();
	}
	if(!mHaveArray)
294
	{
295
		initialize<T>();
296 297 298 299 300 301 302 303 304 305 306 307 308
	}
	try
	{
		boost::shared_ptr<std::vector<T> > currArray = boost::get<boost::shared_ptr<std::vector<T> > >(mArray);
		currArray->swap(array);
		return true;
	}
	catch(const boost::bad_get& exception)
	{
		return false;
	}
}

309
template <typename T>
310
bool XdmfArray::swap(const boost::shared_ptr<std::vector<T> > array)
311 312
{
	return this->swap(*array.get());
313
}