XdmfArray.hpp 15.9 KB
Newer Older
Kenneth Leiter's avatar
Kenneth Leiter committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/*****************************************************************************/
/*                                    XDMF                                   */
/*                       eXtensible Data Model and Format                    */
/*                                                                           */
/*  Id : XdmfArray.hpp                                                       */
/*                                                                           */
/*  Author:                                                                  */
/*     Kenneth Leiter                                                        */
/*     kenneth.leiter@arl.army.mil                                           */
/*     US Army Research Laboratory                                           */
/*     Aberdeen Proving Ground, MD                                           */
/*                                                                           */
/*     Copyright @ 2011 US Army Research Laboratory                          */
/*     All Rights Reserved                                                   */
/*     See Copyright.txt for details                                         */
/*                                                                           */
/*     This software is distributed WITHOUT ANY WARRANTY; without            */
/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
/*     for more information.                                                 */
/*                                                                           */
/*****************************************************************************/

Ken Leiter (Civ ARL/CISD) kleiter's avatar
ENH:  
Ken Leiter (Civ ARL/CISD) kleiter committed
24 25 26
#ifndef XDMFARRAY_HPP_
#define XDMFARRAY_HPP_

27
// Forward Declarations
28
class XdmfArrayType;
29
class XdmfHeavyDataController;
30

Ken Leiter (Civ ARL/CISD) kleiter's avatar
ENH:  
Ken Leiter (Civ ARL/CISD) kleiter committed
31
// Includes
32
#include "XdmfCore.hpp"
Ken Leiter (Civ ARL/CISD) kleiter's avatar
ENH:  
Ken Leiter (Civ ARL/CISD) kleiter committed
33
#include "XdmfItem.hpp"
34
#include <boost/shared_array.hpp>
Ken Leiter (Civ ARL/CISD) kleiter's avatar
ENH:  
Ken Leiter (Civ ARL/CISD) kleiter committed
35 36
#include <boost/variant.hpp>

37
/**
38
 * @brief Provides a single interface for storing a variety of data types.
39
 *
40
 * XdmfArray stores data values that are read in from or will be written to heavy data on disk. The
41 42 43 44 45
 * data type stored is determined by the type initially inserted into the XdmfArray.  XdmfArray
 * allows for insertion and retrieval of data in two fundamental ways:
 *
 * By Copy:
 *
46 47 48
 *	getValue
 * 	getValues
 *	insert
49 50 51 52 53 54
 *
 * 	XdmfArray stores its own copy of the data.  Modifications to the data stored in the XdmfArray will
 * 	not change values stored in the original array.
 *
 * By Shared Reference:
 *
55 56
 *	getValuesInternal
 * 	setValuesInternal
57 58 59 60 61 62
 *
 * 	XdmfArray shares a reference to the data.  No copy is made. XdmfArray holds a shared pointer to the original
 * 	data.  Modifications to the data stored in the XdmfArray also causes modification to values stored in the original
 * 	array.
 *
 * Xdmf supports the following datatypes:
63 64 65 66 67 68 69 70 71
 * 	Int8
 * 	Int16
 * 	Int32
 * 	Int64
 * 	Float32
 * 	Float64
 * 	UInt8
 * 	UInt16
 * 	UInt32
72
 */
73
class XDMFCORE_EXPORT XdmfArray : public XdmfItem {
74

Ken Leiter (Civ ARL/CISD) kleiter's avatar
ENH:  
Ken Leiter (Civ ARL/CISD) kleiter committed
75 76
public:

77 78 79 80 81
	/**
	 * Create a new XdmfArray.
	 *
	 * @return constructed XdmfArray.
	 */
82
	static boost::shared_ptr<XdmfArray> New();
83

84 85
	virtual ~XdmfArray();

86
	LOKI_DEFINE_VISITABLE(XdmfArray, XdmfItem)
87
	static const std::string ItemTag;
88

89
	/**
90
	 * Remove all values from this array.
91
	 */
92
	void clear();
93

94 95 96 97 98
	/**
	 * Remove a value from this array.
	 */
	void erase(const unsigned int index);

99 100 101 102 103 104 105 106
	/**
	 * 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.
	 */
	boost::shared_ptr<const XdmfArrayType> getArrayType() const;

107 108
	/**
	 * Get the capacity of this array (the number of values this array can store without reallocation).
109 110
	 *
	 * @return the capacity of this array.
111 112 113
	 */
	unsigned int getCapacity() const;

114 115 116 117 118 119
	/**
	 * Get the original dimensions string from the stored array
	 *
	 * @return the dimension string from the stored array
	 */
	std::string getDimensionString() const;
120

121
	/**
122
	 * Get the heavy data controller attached to this XdmfArray.
123
	 *
124
	 * @return the heavy data controller attached to this XdmfArray.
125
	 */
126
	boost::shared_ptr<XdmfHeavyDataController> getHeavyDataController();
127 128

	/**
129
	 * Get the heavy data controller attached to this XdmfArray (const version).
130
	 *
131
	 * @return the heavy data controller attached to this XdmfArray.
132
	 */
133
	boost::shared_ptr<const XdmfHeavyDataController> getHeavyDataController() const;
134

135 136 137 138
	std::map<std::string, std::string> getItemProperties() const;

	std::string getItemTag() const;

139 140 141 142 143 144 145
	/**
	 * Get the name of the array.
	 *
	 * @return a string containing the name of the array.
	 */
	std::string getName() const;

146
	/**
147
	 * Get the number of values stored in this array.
148
	 *
149
	 * @return the number of values stored in this array.
150
	 */
151
	unsigned int getSize() const;
152

Ken Leiter (Civ ARL/CISD) kleiter's avatar
ENH:  
Ken Leiter (Civ ARL/CISD) kleiter committed
153
	/**
154
	 * Get a copy of a single value stored in this array.
Ken Leiter (Civ ARL/CISD) kleiter's avatar
ENH:  
Ken Leiter (Civ ARL/CISD) kleiter committed
155
	 *
156
	 * @return the requested value.
Ken Leiter (Civ ARL/CISD) kleiter's avatar
ENH:  
Ken Leiter (Civ ARL/CISD) kleiter committed
157
	 */
158
	template <typename T>
159
	T getValue(const unsigned int index) const;
Ken Leiter (Civ ARL/CISD) kleiter's avatar
ENH:  
Ken Leiter (Civ ARL/CISD) kleiter committed
160

161 162 163 164 165 166 167 168 169 170
	/**
	 * Get a copy of the values stored in this array
	 *
	 * @param startIndex the index in this XdmfArray to begin copying from.
	 * @param valuesPointer a pointer to an array to copy into.
	 * @param numValues the number of values to copy.
	 * @param arrayStride number of values to stride in this XdmfArray between each copy.
	 * @param valuesStride number of values to stride in the pointer between each copy.
	 */
	template <typename T>
171 172 173 174 175 176 177 178 179
	void getValues(const unsigned int startIndex, T * const valuesPointer, const unsigned int numValues = 1, const unsigned int arrayStride = 1, const unsigned int valuesStride = 1) const;

	/**
	 * Get a smart pointer to the internal values stored in this array.
	 *
	 * @return a smart pointer to the internal vector of values stored in this array.
	 */
	template <typename T>
	boost::shared_ptr<std::vector<T> > getValuesInternal();
180

181
	/**
182
	 * Get a pointer to the internal values stored in this array.
183 184 185
	 *
	 * @return a void pointer to the first value stored in this array.
	 */
186
	void * getValuesInternal();
187

Ken Leiter (Civ ARL/CISD) kleiter's avatar
ENH:  
Ken Leiter (Civ ARL/CISD) kleiter committed
188
	/**
189
	 * Get a pointer to the internal values stored in this array (const version).
Ken Leiter (Civ ARL/CISD) kleiter's avatar
ENH:  
Ken Leiter (Civ ARL/CISD) kleiter committed
190 191 192
	 *
	 * @return a void pointer to the first value stored in this array.
	 */
193
	const void * getValuesInternal() const;
Ken Leiter (Civ ARL/CISD) kleiter's avatar
ENH:  
Ken Leiter (Civ ARL/CISD) kleiter committed
194

195 196 197 198 199
	/**
	 * Get the values stored in this array as a string.
	 *
	 * @return a string containing the contents of the array.
	 */
200
	std::string getValuesString() const;
201

202 203
	/**
	 * Initializes the array to contain an empty container of a particular type.
204
	 *
205
	 * @param size the number of values in the initialized array.
206
	 *
207
	 * @return a smart pointer to the internal vector of values initialized in this array.
208 209
	 */
	template <typename T>
210
	boost::shared_ptr<std::vector<T> > initialize(const unsigned int size = 0);
211

212 213
	/**
	 * Initializes the array to contain an empty container of a particular XdmfArrayType.
214 215 216
	 *
	 * @param arrayType the type of array to initialize.
	 * @param size the number of values in the initialized array.
217
	 */
218
	void initialize(const boost::shared_ptr<const XdmfArrayType> arrayType, const unsigned int size = 0);
219

220
	/**
221 222 223 224 225 226 227 228 229 230
	 * Insert value into this array
	 *
	 * @param index the index in this array to insert.
	 * @param value the value to insert
	 */
	template<typename T>
	void insert(const unsigned int index, const T & value);

	/**
	 * Insert values from an XdmfArray into this array.
231 232 233 234 235 236 237 238 239 240 241
	 *
	 * @param startIndex the index in this array to begin insertion.
	 * @param values a shared pointer to an XdmfArray to copy into this array.
	 * @param valuesStartIndex the index in the XdmfArray to begin copying.
	 * @param numValues the number of values to copy into this array.
	 * @param arrayStride number of values to stride in this array between each copy.
	 * @param valuesStride number of values to stride in the XdmfArray between each copy.
	 */
	void insert(const unsigned int startIndex, const boost::shared_ptr<const XdmfArray> values, const unsigned int valuesStartIndex= 0, const unsigned int numValues = 1, const unsigned int arrayStride = 1, const unsigned int valuesStride = 1);

	/**
242
	 * Insert values into this array.
243 244 245 246 247 248 249 250 251 252
	 *
	 * @param startIndex the index in this XdmfArray to begin insertion.
	 * @param valuesPointer a pointer to the values to copy into this XdmfArray.
	 * @param numValues the number of values to copy into this array.
	 * @param arrayStride number of values to stride in this XdmfArray between each copy.
	 * @param valuesStride number of values to stride in the pointer between each copy.
	 */
	template<typename T>
	void insert(const unsigned int startIndex, const T * const valuesPointer, const unsigned int numValues = 1, const unsigned int arrayStride = 1, const unsigned int valuesStride = 1);

253 254 255
	/**
	 * Returns whether the array is initialized (contains values in memory).
	 */
256
	bool isInitialized() const;
257

258 259 260 261
	/**
	 * Copy a value to the back of this array
	 */
	template <typename T>
262
	void pushBack(const T & value);
263

264 265 266 267 268
	/**
	 * Read data from disk into memory.
	 */
	void read();

269
	/**
270
	 * Release all data currently held in memory.
271
	 */
272
	void release();
273

274 275 276 277 278 279 280
	/**
	 * Set the capacity of the XdmfArray to at least size.
	 *
	 * @param size the capacity to set this XdmfArray to.
	 */
	void reserve(const unsigned int size);

281
	/**
282
	 * Resizes the XdmfArray to contain numValues.  If numValues is larger than the current size, append values to the end equal
283 284 285
	 * to val.  If numValues is less than the current size, values at indices larger than numValues are removed.
	 *
	 * @param numValues the number of values to resize this array to.
286
	 * @param value the number to initialize newly created values to, if needed.
287 288
	 */
	template<typename T>
289
	void resize(const unsigned int numValues, const T & value = 0);
290

291 292 293 294 295
	/**
	 * Attach an hdf5 controller to this XdmfArray.
	 *
	 * @param hdf5Controller the hdf5 controller to attach to this XdmfArray.
	 */
296
	void setHeavyDataController(const boost::shared_ptr<XdmfHeavyDataController> hdf5Controller);
297

298 299 300 301 302 303 304
	/**
	 * Set the name of the array.
	 *
	 * @param name a string containing the name to set.
	 */
	void setName(const std::string & name);

305 306 307 308 309 310 311 312 313 314 315 316 317 318 319
	/**
	 * Sets the values of this array to the values stored in the arrayPointer array.  No copy is made.  Modifications to the array are
	 * not permitted through the XdmfArray API.  Any calls through the XdmfArray API to modify the array (i.e. any non-const function)
	 * will result in the array being copied into internal storage.  The internal copy is then modified.
	 * This prevents situations where a realloc of the pointer could cause other references to become invalid.
	 * The caller of this method can continue to modify the values stored in arrayPointer on its own.
	 * This function is meant for applications that have their own array data structures that merely use Xdmf to output the data,
	 * an operation that should not require a copy.  Other applications that use Xdmf for in memory data storage should avoid
	 * this function.
	 *
	 * @param arrayPointer a pointer to an array to store in this XdmfArray.
	 * @param numValues the number of values in the array.
	 * @param transferOwnership whether to transfer responsibility for deletion of the array to XdmfArray.
	 */
	template<typename T>
320
	void setValuesInternal(const T * const arrayPointer, const unsigned int numValues, const bool transferOwnership = 0);
321

322 323 324 325 326
	/**
	 * Sets the values of this array to the values stored in the vector.  No copy is made.  The caller of this method retains
	 * ownership of the data and must ensure that the array is still valid for the entire time Xdmf needs it.
	 *
	 * @param array a vector to store in this array.
327
	 * @param transferOwnership whether to transfer responsibility for deletion of the array to XdmfArray.
328 329
	 */
	template<typename T>
330
	void setValuesInternal(std::vector<T> & array, const bool transferOwnership = 0);
331

Ken Leiter (Civ ARL/CISD) kleiter's avatar
ENH:  
Ken Leiter (Civ ARL/CISD) kleiter committed
332
	/**
333 334
	 * Sets the values of this array to the values stored in the vector.  No copy is made.  This array shares ownership with
	 * other references to the smart pointer.
Ken Leiter (Civ ARL/CISD) kleiter's avatar
ENH:  
Ken Leiter (Civ ARL/CISD) kleiter committed
335
	 *
336
	 * @param array a smart pointer to a vector to store in this array.
Ken Leiter (Civ ARL/CISD) kleiter's avatar
ENH:  
Ken Leiter (Civ ARL/CISD) kleiter committed
337
	 */
338
	template<typename T>
339
	void setValuesInternal(const boost::shared_ptr<std::vector<T> > array);
340

341 342 343 344 345 346 347 348 349 350 351 352 353 354 355
	/**
	 * 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>
356
	bool swap(const boost::shared_ptr<std::vector<T> > array);
357 358 359 360 361 362 363

	/**
	 * 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.
	 */
364
	void swap(const boost::shared_ptr<XdmfArray> array);
365

Ken Leiter (Civ ARL/CISD) kleiter's avatar
ENH:  
Ken Leiter (Civ ARL/CISD) kleiter committed
366 367 368
protected:

	XdmfArray();
369
	virtual void populateItem(const std::map<std::string, std::string> & itemProperties, std::vector<boost::shared_ptr<XdmfItem> > & childItems, const XdmfCoreReader * const reader);
Ken Leiter (Civ ARL/CISD) kleiter's avatar
ENH:  
Ken Leiter (Civ ARL/CISD) kleiter committed
370 371 372

private:

373 374 375
	XdmfArray(const XdmfArray & array);  // Not implemented.
	void operator=(const XdmfArray & array);  // Not implemented.

376 377
	// Variant Visitor Operations
	class Clear;
378
	class Erase;
379
	class GetArrayType;
380
	class GetCapacity;
381

382
	template <typename T>
383
	class GetValues;
384

385 386
	class GetValuesPointer;
	class GetValuesString;
387 388 389 390 391

	template <typename T>
	class Insert;

	class InsertArray;
392
	class InternalizeArrayPointer;
393
	class NewArray;
394
	struct NullDeleter;
395 396 397 398

	template <typename T>
	class PushBack;

399
	class Reserve;
400

401
	template <typename T>
402 403
	class Resize;

404
	class Size;
405

406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423
	/**
	 * After setValues(const T * const array) is called, XdmfArray stores a pointer that is not allowed to be modified through
	 * the XdmfArray API.  If the user desires to modify the contents of the pointer, they must do so without calling any
	 * non-const functions of XdmfArray.  If they do call non-const functions of XdmfArray, we try to accommodate by copying
	 * the array pointer into internal data structures.
	 */
	void internalizeArrayPointer();

	/**
	 * Release references to internal data.
	 */
	void releaseArray();

	/**
	 * Release references to held array pointer internal data;
	 */
	void releaseArrayPointer();

424 425 426 427 428 429 430 431 432 433 434
	typedef boost::variant<
		boost::shared_ptr<std::vector<char> >,
		boost::shared_ptr<std::vector<short> >,
		boost::shared_ptr<std::vector<int> >,
		boost::shared_ptr<std::vector<long> >,
		boost::shared_ptr<std::vector<float> >,
		boost::shared_ptr<std::vector<double> >,
		boost::shared_ptr<std::vector<unsigned char> >,
		boost::shared_ptr<std::vector<unsigned short> >,
		boost::shared_ptr<std::vector<unsigned int> > > ArrayVariant;

435 436 437 438 439 440 441 442 443 444
	typedef boost::variant<
		boost::shared_array<const char>,
		boost::shared_array<const short>,
		boost::shared_array<const int>,
		boost::shared_array<const long>,
		boost::shared_array<const float>,
		boost::shared_array<const double>,
		boost::shared_array<const unsigned char>,
		boost::shared_array<const unsigned short>,
		boost::shared_array<const unsigned int> > ArrayPointerVariant;
445

446
	ArrayVariant mArray;
447
	ArrayPointerVariant mArrayPointer;
448
	unsigned int mArrayPointerNumValues;
449 450
	bool mHaveArray;
	bool mHaveArrayPointer;
451
	boost::shared_ptr<XdmfHeavyDataController> mHeavyDataController;
452
	std::string mName;
453
	unsigned int mTmpReserveSize;
454
	std::string mDimensionString;
Ken Leiter (Civ ARL/CISD) kleiter's avatar
ENH:  
Ken Leiter (Civ ARL/CISD) kleiter committed
455 456
};

457 458
#include "XdmfArray.tpp"

459 460 461 462 463 464 465 466
#ifdef _WIN32
    XDMFCORE_TEMPLATE template class XDMFCORE_EXPORT boost::shared_ptr<const XdmfArrayType>;
    XDMFCORE_TEMPLATE template class XDMFCORE_EXPORT boost::shared_ptr<XdmfHeavyDataController>;
    XDMFCORE_TEMPLATE template class XDMFCORE_EXPORT boost::shared_ptr<const XdmfHeavyDataController>;
    XDMFCORE_TEMPLATE template class XDMFCORE_EXPORT boost::shared_ptr<Loki::BaseVisitor>;
    XDMFCORE_TEMPLATE template class XDMFCORE_EXPORT Loki::Visitor<boost::shared_ptr<XdmfArray>, boost::shared_ptr<XdmfItem> >;
#endif

Ken Leiter (Civ ARL/CISD) kleiter's avatar
ENH:  
Ken Leiter (Civ ARL/CISD) kleiter committed
467
#endif /* XDMFARRAY_HPP_ */