00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef _MRPT_CArray_H
00029 #define _MRPT_CArray_H
00030
00031 #include <iterator>
00032 #include <mrpt/utils/utils_defs.h>
00033 #include <mrpt/math/math_frwds.h>
00034 #include <mrpt/math/ops_containers.h>
00035
00036 namespace mrpt
00037 {
00038 namespace math
00039 {
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 template <typename T, std::size_t N>
00070 class CArray {
00071 public:
00072 T elems[N];
00073
00074 public:
00075
00076 typedef T value_type;
00077 typedef T* iterator;
00078 typedef const T* const_iterator;
00079 typedef T& reference;
00080 typedef const T& const_reference;
00081 typedef std::size_t size_type;
00082 typedef std::ptrdiff_t difference_type;
00083
00084
00085 inline iterator begin() { return elems; }
00086 inline const_iterator begin() const { return elems; }
00087 inline iterator end() { return elems+N; }
00088 inline const_iterator end() const { return elems+N; }
00089
00090
00091 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
00092 typedef std::reverse_iterator<iterator> reverse_iterator;
00093 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00094 #elif defined(_MSC_VER) && (_MSC_VER == 1300) && defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB == 310)
00095
00096 typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, iterator,
00097 reference, iterator, reference> > reverse_iterator;
00098 typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, const_iterator,
00099 const_reference, iterator, reference> > const_reverse_iterator;
00100 #else
00101
00102 typedef std::reverse_iterator<iterator,T> reverse_iterator;
00103 typedef std::reverse_iterator<const_iterator,T> const_reverse_iterator;
00104 #endif
00105
00106 reverse_iterator rbegin() { return reverse_iterator(end()); }
00107 const_reverse_iterator rbegin() const {
00108 return const_reverse_iterator(end());
00109 }
00110 reverse_iterator rend() { return reverse_iterator(begin()); }
00111 const_reverse_iterator rend() const {
00112 return const_reverse_iterator(begin());
00113 }
00114
00115
00116 inline reference operator[](size_type i) { return elems[i]; }
00117 inline const_reference operator[](size_type i) const { return elems[i]; }
00118
00119
00120 reference at(size_type i) { rangecheck(i); return elems[i]; }
00121 const_reference at(size_type i) const { rangecheck(i); return elems[i]; }
00122
00123
00124 reference front() { return elems[0]; }
00125 const_reference front() const { return elems[0]; }
00126 reference back() { return elems[N-1]; }
00127 const_reference back() const { return elems[N-1]; }
00128
00129
00130 static inline size_type size() { return N; }
00131 static bool empty() { return false; }
00132 static size_type max_size() { return N; }
00133 enum { static_size = N };
00134
00135
00136 inline void resize(const size_t nElements) {
00137 if (nElements!=N)
00138 throw std::logic_error(format("Try to change the size of a %u-CArray to %u.",static_cast<unsigned>(N),static_cast<unsigned>(nElements)));
00139 }
00140
00141
00142 void swap (CArray<T,N>& y) {
00143 std::swap_ranges(begin(),end(),y.begin());
00144 }
00145
00146
00147 const T* data() const { return elems; }
00148
00149
00150 T* data() { return elems; }
00151
00152
00153 template <typename T2>
00154 CArray<T,N>& operator= (const CArray<T2,N>& rhs) {
00155 std::copy(rhs.begin(),rhs.end(), begin());
00156 return *this;
00157 }
00158
00159
00160 void assign (const T& value)
00161 {
00162 std::fill_n(begin(),size(),value);
00163 }
00164
00165 void assign (const size_t n, const T& value)
00166 {
00167 ASSERTDEB_(N==n);
00168 std::fill_n(begin(),size(),value);
00169 }
00170
00171
00172 template<typename I> void assign(I b,const I &e) {
00173 ASSERTDEB_(std::distance(b,e)==N);
00174 for (iterator i=begin();i<end();++i) *i=*(b++);
00175 }
00176
00177 private:
00178
00179 static void rangecheck (size_type i) {
00180 if (i >= size()) {
00181 throw std::out_of_range("CArray<>: index out of range");
00182 }
00183 }
00184
00185 };
00186
00187
00188 template <typename T>
00189 class CArray<T,0> {
00190 public:
00191 char c;
00192
00193 public:
00194
00195 typedef T value_type;
00196 typedef T* iterator;
00197 typedef const T* const_iterator;
00198 typedef T& reference;
00199 typedef const T& const_reference;
00200 typedef std::size_t size_type;
00201 typedef std::ptrdiff_t difference_type;
00202
00203
00204 iterator begin() { return reinterpret_cast< iterator >( &c ); }
00205 const_iterator begin() const { return reinterpret_cast< const_iterator >( &c ); }
00206 iterator end() { return reinterpret_cast< iterator >( &c ); }
00207 const_iterator end() const { return reinterpret_cast< const_iterator >( &c ); }
00208
00209
00210 #if !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
00211 typedef std::reverse_iterator<iterator> reverse_iterator;
00212 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00213 #elif defined(_MSC_VER) && (_MSC_VER == 1300) && defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB == 310)
00214
00215 typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, iterator,
00216 reference, iterator, reference> > reverse_iterator;
00217 typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, const_iterator,
00218 const_reference, iterator, reference> > const_reverse_iterator;
00219 #else
00220
00221 typedef std::reverse_iterator<iterator,T> reverse_iterator;
00222 typedef std::reverse_iterator<const_iterator,T> const_reverse_iterator;
00223 #endif
00224
00225 reverse_iterator rbegin() { return reverse_iterator(end()); }
00226 const_reverse_iterator rbegin() const {
00227 return const_reverse_iterator(end());
00228 }
00229 reverse_iterator rend() { return reverse_iterator(begin()); }
00230 const_reverse_iterator rend() const {
00231 return const_reverse_iterator(begin());
00232 }
00233
00234
00235 reference at(size_type i) {
00236 throw std::out_of_range("CArray<0>: index out of range");
00237 }
00238 const_reference at(size_type i) const {
00239 throw std::out_of_range("<0>: index out of range");
00240 }
00241
00242
00243 static size_type size() { return 0; }
00244 static bool empty() { return true; }
00245 static size_type max_size() { return 0; }
00246 enum { static_size = 0 };
00247
00248
00249 void swap (CArray<T,0>& y) {
00250
00251 }
00252
00253
00254 const T* data() const { return NULL; }
00255 T* data() { return NULL; }
00256
00257
00258 template < typename T2 >
00259 CArray< T,0 >& operator= (const CArray< T2, 0>& rhs) {
00260 return *this;
00261 }
00262
00263
00264
00265
00266 inline reference operator[](size_type i) { makes_no_sense(); static T dumm=0; return dumm; }
00267 inline const_reference operator[](size_type i) const { makes_no_sense(); static T dumm=0; return dumm; }
00268
00269
00270 reference front() { makes_no_sense(); }
00271 const_reference front() const { makes_no_sense(); }
00272 reference back() { makes_no_sense(); }
00273 const_reference back() const { makes_no_sense(); }
00274
00275 private:
00276
00277
00278 static void makes_no_sense () {
00279
00280 throw std::out_of_range("CArray<0>: index out of range");
00281 }
00282 };
00283
00284
00285 template<class T, std::size_t N>
00286 bool operator== (const CArray<T,N>& x, const CArray<T,N>& y) {
00287 return std::equal(x.begin(), x.end(), y.begin());
00288 }
00289 template<class T, std::size_t N>
00290 bool operator< (const CArray<T,N>& x, const CArray<T,N>& y) {
00291 return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
00292 }
00293 template<class T, std::size_t N>
00294 bool operator!= (const CArray<T,N>& x, const CArray<T,N>& y) {
00295 return !(x==y);
00296 }
00297 template<class T, std::size_t N>
00298 bool operator> (const CArray<T,N>& x, const CArray<T,N>& y) {
00299 return y<x;
00300 }
00301 template<class T, std::size_t N>
00302 bool operator<= (const CArray<T,N>& x, const CArray<T,N>& y) {
00303 return !(y<x);
00304 }
00305 template<class T, std::size_t N>
00306 bool operator>= (const CArray<T,N>& x, const CArray<T,N>& y) {
00307 return !(x<y);
00308 }
00309
00310
00311
00312
00313
00314
00315
00316
00317 template <typename T, std::size_t N>
00318 class CArrayPOD : public CArray<T,N>
00319 {
00320 public:
00321 CArrayPOD() {}
00322
00323 CArrayPOD(const T*ptr)
00324 {
00325 if (!ptr) THROW_EXCEPTION("ptr is a NULL pointer.")
00326 ::memcpy(&CArray<T,N>::elems[0],ptr,sizeof(T)*N);
00327 }
00328
00329
00330 template <class ARRAYLIKE>
00331 explicit CArrayPOD(const ARRAYLIKE &obj) {
00332 for (size_t i=0;i<N;i++)
00333 this->operator[](i) = static_cast<T>(obj[i]);
00334 }
00335
00336 };
00337
00338
00339
00340
00341
00342
00343 template <typename T, std::size_t N>
00344 class CArrayNumeric : public CArrayPOD<T,N>
00345 {
00346 public:
00347
00348 typedef CArrayNumeric<T,N> mrpt_autotype;
00349 DECLARE_MRPT_CONTAINER_TYPES
00350 DECLARE_MRPT_CONTAINER_IS_VECTOR
00351 DECLARE_COMMON_CONTAINERS_MEMBERS(T)
00352
00353 CArrayNumeric() {}
00354
00355 CArrayNumeric(const T*ptr) : CArrayPOD<T,N>(ptr) {}
00356
00357
00358 template <class ARRAYLIKE>
00359 explicit CArrayNumeric(const ARRAYLIKE &obj) : CArrayPOD<T,N>(obj) {}
00360
00361
00362 CArrayNumeric<T,N> & operator += (const CArrayNumeric<T,N>&o) {
00363 for (size_t i=0;i<N;i++)
00364 CArray<T,N>::elems[i]+=o.elems[i];
00365 return *this;
00366 }
00367
00368 CArrayNumeric<T,N> & operator -= (const CArrayNumeric<T,N>&o) {
00369 for (size_t i=0;i<N;i++)
00370 CArray<T,N>::elems[i]-=o.elems[i];
00371 return *this;
00372 }
00373 };
00374
00375
00376
00377
00378
00379
00380 template <std::size_t N>
00381 class CArrayFloat : public CArrayNumeric<float,N>
00382 {
00383 public:
00384 CArrayFloat() {}
00385 CArrayFloat(const float*ptr) : CArrayNumeric<float,N>(ptr) {}
00386
00387 template <class ARRAYLIKE>
00388 explicit CArrayFloat(const ARRAYLIKE &obj) : CArrayNumeric<float,N>(obj) {}
00389 };
00390
00391
00392
00393 template <std::size_t N>
00394 class CArrayDouble : public CArrayNumeric<double,N>
00395 {
00396 public:
00397 CArrayDouble() {}
00398 CArrayDouble(const double*ptr) : CArrayNumeric<double,N>(ptr) {}
00399
00400
00401 template <class ARRAYLIKE>
00402 explicit CArrayDouble(const ARRAYLIKE &obj) : CArrayNumeric<double,N>(obj) {}
00403 };
00404
00405
00406
00407 template <std::size_t N>
00408 class CArrayInt : public CArrayNumeric<int,N>
00409 {
00410 public:
00411 CArrayInt() {}
00412 CArrayInt(const int*ptr) : CArrayNumeric<int,N>(ptr) {}
00413 };
00414
00415
00416
00417 template <std::size_t N>
00418 class CArrayUInt : public CArrayNumeric<unsigned int,N>
00419 {
00420 public:
00421 CArrayUInt() {}
00422 CArrayUInt(const unsigned int*ptr) : CArrayNumeric<unsigned int,N>(ptr) {}
00423 };
00424
00425
00426 struct CMatrixTemplateSize : public CArrayPOD<size_t,2>
00427 {
00428 CMatrixTemplateSize() : CArrayPOD<size_t,2>() {}
00429 CMatrixTemplateSize(const size_t *d) : CArrayPOD<size_t,2>(d) {}
00430
00431 bool operator==(const CMatrixTemplateSize&o) const { return CArrayPOD<size_t,2>::elems[0]==o[0] && CArrayPOD<size_t,2>::elems[1]==o[1]; }
00432 bool operator!=(const CMatrixTemplateSize&o) const { return !(*this==o); }
00433
00434 operator size_t(void) const { return CArrayPOD<size_t,2>::elems[0]*CArrayPOD<size_t,2>::elems[1]; }
00435 };
00436
00437
00438
00439
00440
00441
00442 template <typename T, std::size_t N, class VECTORLIKE>
00443 CArrayNumeric<T,N> operator +(const CArrayNumeric<T,N> &A, const VECTORLIKE &B) {
00444 ASSERT_(A.size()==B.size())
00445 CArrayNumeric<T,N> ret;
00446 for (size_t i=0;i<N;i++) ret[i]=A[i]+B[i];
00447 return ret;
00448 }
00449
00450
00451 template <typename T, std::size_t N, class VECTORLIKE>
00452 CArrayNumeric<T,N> operator -(const CArrayNumeric<T,N> &A, const VECTORLIKE &B) {
00453 ASSERT_(A.size()==B.size())
00454 CArrayNumeric<T,N> ret;
00455 for (size_t i=0;i<N;i++) ret[i]=A[i]-B[i];
00456 return ret;
00457 }
00458
00459
00460 template <typename T, std::size_t N, class VECTORLIKE>
00461 CArrayNumeric<T,N> operator *(const CArrayNumeric<T,N> &A, const VECTORLIKE &B) {
00462 ASSERT_(A.size()==B.size())
00463 CArrayNumeric<T,N> ret;
00464 for (size_t i=0;i<N;i++) ret[i]=A[i]*B[i];
00465 return ret;
00466 }
00467
00468
00469
00470
00471 template <typename T,size_t N>
00472 std::ostream& operator << (std::ostream& ostrm, const CArray<T,N>& a)
00473 {
00474 ostrm << std::setprecision(4);
00475 for (size_t i=0; i < N; i++) ostrm << std::setw(13) << a[i];
00476 return ostrm;
00477 }
00478
00479
00480
00481
00482
00483 }
00484 }
00485
00486
00487 namespace std
00488 {
00489
00490 template<class T, std::size_t N>
00491 inline void swap (mrpt::math::CArray<T,N>& x, mrpt::math::CArray<T,N>& y) {
00492 x.swap(y);
00493 }
00494 }
00495
00496 #endif