/* * Copyright (C) 2009 * Robert Bosch LLC * Research and Technology Center North America * Palo Alto, California * * All rights reserved. * *------------------------------------------------------------------------------ * project ....: Autonomous Technologies * file .......: rtcArray.h * authors ....: Benjamin Pitzer * organization: Robert Bosch LLC * creation ...: 08/16/2006 * modified ...: $Date: 2009-01-21 18:19:16 -0800 (Wed, 21 Jan 2009) $ * changed by .: $Author: benjaminpitzer $ * revision ...: $Revision: 14 $ */ #ifndef RTC_ARRAY_H #define RTC_ARRAY_H //== INCLUDES ================================================================== #include "rtcMath.h" #include "rtcVec.h" //== NAMESPACES ================================================================ namespace rtc { // Forward declarations template class Vec; // M-d vector template class Array; // Arbitrary-dimensional array class Exception; /** * A K-Dimensional Array of type T */ template class Array { public: // Constructors/Destructor Array(); Array(const Vec dim); Array(const Array& a); ~Array(); // Mutators void deleteArray() { reset(); } void reset(); void setSize(const Vec dim_); void set(const T v); void set(const T* v, int i0 = 0, int vlen = -1); void set(const Array& a); void addTo(const T* v, int i0 = 0, int vlen = -1); // Accessors Vec size() const; int size(int i) const; int length() const; T& at(int i); T& at(const Vec ind); const T& at(int i) const; const T& at(const Vec ind) const; T operator () (int i) const; T& operator () (int i); T operator () (const Vec ind) const; T& operator () (const Vec ind); T operator [] (int i) const; T& operator [] (int i); T operator [] (const Vec ind) const; T& operator [] (const Vec ind); // Assignment operator Array& operator = (const Array& a); // Equality and inequality tests bool equalTo(const Array& a) const; // Serialization bool write(OutputHandler& oh) const; bool read(InputHandler& ih); // Helper functions int indexOf(Vec ind) const; // Data T* x; ///< storage array protected: Vec dim; ///< array dimensions Vec mul; ///< multipliers for computing linear index int len; ///< linear length of array }; // ASCII stream IO template std::ostream& operator << (std::ostream& os, const Array& a); template std::istream& operator >> (std::istream& is, Array& a); //============================================================================== // Array //============================================================================== // Constructors/Destructor /** Ctor that does no initalization. */ template inline Array::Array() { x = NULL; len = 0; dim.set(0); mul.set(0); } /** Ctor that starts with given dimensions * @param dim_ are the sizes in the several dimension */ template inline Array::Array(const Vec dim_) { x=NULL; len = 0; dim.set(0); mul.set(0); setSize(dim_); } /** Copy Ctor * @param a the other vector */ template inline Array::Array(const Array& a) { x=NULL; len = 0; dim.set(0); mul.set(0); set(a); } /** Dtor that does no initalization. */ template inline Array::~Array() { reset(); } // Mutators /** Deletes contents of array and frees memory */ template inline void Array::reset() { len = 0; dim.set(0); mul.set(0); if (x) { delete [] x; x = NULL; } } /** Set the size of the array * @param dim_ the sizes of the array in each dimension */ template inline void Array::setSize(const Vec dim_) { if (!dim_.equalTo(dim)) { if (x != NULL) reset(); // for (int k=0;k1) { // std::cout << dim_; // std::cout << "Warning, negative or zero dimensions not allowed." << std::endl << std::flush; // } // } dim = dim_; len = dim.prod(); mul(K-1) = 1; for (int d=1,k=K-2;d0) { x = new T[len]; } } } /** Set the values of all the elements in the array to v * @param v is the value to set the array to */ template inline void Array::set(const T v) { for (int i=0;i inline void Array::set(const T* v, int i0, int vlen) { int i1 = (vlen == -1)? len:rtc_clamp(i0+vlen,0,len); for (int i=i0,j=0;i inline void Array::set(const Array& a) { Vec dim_ = a.Array::size(); Array::setSize(dim_); Array::set(a.x); } /** Add the values in array v to this array * @param v is the value to set the array to * @param i0 is offset where to start copying * @param vlen is the number of elements to copy */ template inline void Array::addTo(const T* v, int i0, int vlen) { int i1 = (vlen == -1)? len:rtc_clamp(i0+vlen,0,len); for (int i=i0,j=0;i inline T& Array::at(int i) { return x[i]; } /** Returns mutable reference to array element * @param ind is the index list * @return a reference to the array element */ template inline T& Array::at(const Vec ind) { return x[indexOf(ind)]; } /** Returns mutable reference to array element * @param i is the index list * @return a reference to the array element */ template inline const T& Array::at(int i) const { return x[i]; } /** Returns mutable reference to array element * @param ind is the index list * @return a reference to the array element */ template inline const T& Array::at(const Vec ind) const { return x[indexOf(ind)]; } /** Returns mutable reference to array element * @param ind is the index list * @return a reference to the array element */ template inline T& Array::operator () (const Vec ind) { return x[indexOf(ind)]; } /** Returns mutable reference to array element * @param i is the linear index * @return a reference to the array element */ template inline T& Array::operator () (int i) { #if AR_CHECK_BOUNDS if (i<0 || i>=len) { std::stringstream ss; ss << "Error. Index " << i << " exceeds bounds [0, "; ss << len << "]." << std::endl << std::flush; throw Exception(ss.str()); } #endif return x[i]; } /** Returns array element * @param ind is the index list * @return array element */ template inline T Array::operator () (const Vec ind) const { return x[indexOf(ind)]; } /** Returns array element * @param i is the linear index * @return array element */ template inline T Array::operator () (int i) const { #if AR_CHECK_BOUNDS if (i<0 || i>=len) { std::stringstream ss; ss << "Error. Index " << i << " exceeds bounds [0, "; ss << len << "]." << std::endl << std::flush; throw Exception(ss.str()); } #endif return x[i]; } /** Returns mutable reference to array element * @param ind is the index list * @return a reference to the array element */ template inline T& Array::operator [] (const Vec ind) { return x[indexOf(ind)]; } /** Returns mutable reference to array element * @param i is the linear index * @return a reference to the array element */ template inline T& Array::operator [] (int i) { #if AR_CHECK_BOUNDS if (i<0 || i>=len) { std::stringstream ss; ss << "Error. Index " << i << " exceeds bounds [0, "; ss << len << "]." << std::endl << std::flush; throw Exception(ss.str()); } #endif return x[i]; } /** Returns array element * @param ind is the index list * @return array element */ template inline T Array::operator [] (const Vec ind) const { return x[indexOf(ind)]; } /** Returns array element * @param i is the linear index * @return array element */ template inline T Array::operator [] (int i) const { #if AR_CHECK_BOUNDS if (i<0 || i>=len) { std::stringstream ss; ss << "Error. Index " << i << " exceeds bounds [0, "; ss << len << "]." << std::endl << std::flush; throw Exception(ss.str()); } #endif return x[i]; } /** Set this array equal to passed array * @param a the array to replicate */ template inline Array& Array::operator = (const Array& a) { set(a); return *this; } /** Compare the entire array to the passed array. * @returns true of all corresponding elements are the same */ template inline bool Array::equalTo(const Array& other) const { for (int i=0;i of array dimension lengths */ template inline Vec Array::size() const { return dim; } /** Returns vector of array dimensions @return Vec of array dimension lengths */ template inline int Array::size(int i) const { return dim(i); } /** Returns linear length of data @return integer legth of data */ template inline int Array::length() const { return len; } // Serialization routines /** Write state to a binary stream. */ template inline bool Array::write(OutputHandler& oh) const { dim.write(oh); if (len>0) oh.write((char *)(x),len*sizeof(T)); return oh.good(); } /** Restore state from a binary stream. */ template inline bool Array::read(InputHandler& ih) { Vec dim_; dim_.read(ih); if (!dim_.equalTo(Array::size())) Array::setSize(dim_); if (len>0) ih.read((char *)(x),len*sizeof(T)); return ih.good(); } /** Write state to stream as formated ASCII */ template std::ostream& operator << (std::ostream& os, const Array& a) { int minFieldWidth = os.precision()+5; Vec dim = a.template size(); os << dim; for (int i=0;i0 && i%dim(0) == 0) os << std::endl; if (K>2) if (i>0 && i%(dim(0)*dim(1)) == 0) os << std::endl; if (K>3) if (i>0 && i%(dim(0)*dim(1)*dim(2)) == 0) os << std::endl; os << std::setw(minFieldWidth) << a(i) << std::endl; } os << std::endl; return os; } /** Read state from stream of formated ASCII */ template std::istream& operator >> (std::istream& is, Array& a) { Vec dim; is >> dim; // read in dimensions if (!dim.equalTo(a.template Array::size())) a.setSize(dim); for (int i=0;i> a(i); } return is; } // Helper functions (used internally only) /** Returns linear index of given array indices * @param ind is the vector of indices to be converted * @return the linear index in the data array x */ template inline int Array::indexOf(Vec ind) const { #if AR_CHECK_BOUNDS for (int k=0;k= dim(k)) { std::stringstream ss; ss << "Error. Index " << ind(k) << " exceeds bounds [0, "; ss << dim(k) << "]"; throw Exception(ss.str()); } #endif return (ind*mul).sum(); } /** * handler functions with standard storable interface */ template bool rtc_write(OutputHandler& oh, const Array& data) { return data.write(oh); }; /** * handler functions with standard storable interface */ template bool rtc_read(InputHandler& ih, Array& data) { return data.read(ih); }; //============================================================================== } // namespace rtc //============================================================================== #endif // ARRAY_H defined //==============================================================================