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