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 <mrpt/utils/utils_defs.h>
00032
00033 namespace mrpt
00034 {
00035 namespace math
00036 {
00037
00038
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 template <typename T, std::size_t N>
00067 class CArray {
00068 public:
00069 T elems[N];
00070
00071 public:
00072
00073 typedef T value_type;
00074 typedef T* iterator;
00075 typedef const T* const_iterator;
00076 typedef T& reference;
00077 typedef const T& const_reference;
00078 typedef std::size_t size_type;
00079 typedef std::ptrdiff_t difference_type;
00080
00081
00082 iterator begin() { return elems; }
00083 const_iterator begin() const { return elems; }
00084 iterator end() { return elems+N; }
00085 const_iterator end() const { return elems+N; }
00086
00087
00088 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
00089 typedef std::reverse_iterator<iterator> reverse_iterator;
00090 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00091 #elif defined(_MSC_VER) && (_MSC_VER == 1300) && defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB == 310)
00092
00093 typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, iterator,
00094 reference, iterator, reference> > reverse_iterator;
00095 typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, const_iterator,
00096 const_reference, iterator, reference> > const_reverse_iterator;
00097 #else
00098
00099 typedef std::reverse_iterator<iterator,T> reverse_iterator;
00100 typedef std::reverse_iterator<const_iterator,T> const_reverse_iterator;
00101 #endif
00102
00103 reverse_iterator rbegin() { return reverse_iterator(end()); }
00104 const_reverse_iterator rbegin() const {
00105 return const_reverse_iterator(end());
00106 }
00107 reverse_iterator rend() { return reverse_iterator(begin()); }
00108 const_reverse_iterator rend() const {
00109 return const_reverse_iterator(begin());
00110 }
00111
00112
00113 inline reference operator[](size_type i) { return elems[i]; }
00114 inline const_reference operator[](size_type i) const { return elems[i]; }
00115
00116
00117 reference at(size_type i) { rangecheck(i); return elems[i]; }
00118 const_reference at(size_type i) const { rangecheck(i); return elems[i]; }
00119
00120
00121 reference front() { return elems[0]; }
00122 const_reference front() const { return elems[0]; }
00123 reference back() { return elems[N-1]; }
00124 const_reference back() const { return elems[N-1]; }
00125
00126
00127 static inline size_type size() { return N; }
00128 static bool empty() { return false; }
00129 static size_type max_size() { return N; }
00130 enum { static_size = N };
00131
00132
00133 void swap (CArray<T,N>& y) {
00134 std::swap_ranges(begin(),end(),y.begin());
00135 }
00136
00137
00138 const T* data() const { return elems; }
00139
00140
00141 T* data() { return elems; }
00142
00143
00144 template <typename T2>
00145 CArray<T,N>& operator= (const CArray<T2,N>& rhs) {
00146 std::copy(rhs.begin(),rhs.end(), begin());
00147 return *this;
00148 }
00149
00150
00151 void assign (const T& value)
00152 {
00153 std::fill_n(begin(),size(),value);
00154 }
00155
00156 private:
00157
00158 static void rangecheck (size_type i) {
00159 if (i >= size()) {
00160 throw std::out_of_range("CArray<>: index out of range");
00161 }
00162 }
00163
00164 };
00165
00166
00167 template <typename T>
00168 class CArray<T,0> {
00169 public:
00170 char c;
00171
00172 public:
00173
00174 typedef T value_type;
00175 typedef T* iterator;
00176 typedef const T* const_iterator;
00177 typedef T& reference;
00178 typedef const T& const_reference;
00179 typedef std::size_t size_type;
00180 typedef std::ptrdiff_t difference_type;
00181
00182
00183 iterator begin() { return reinterpret_cast< iterator >( &c ); }
00184 const_iterator begin() const { return reinterpret_cast< const_iterator >( &c ); }
00185 iterator end() { return reinterpret_cast< iterator >( &c ); }
00186 const_iterator end() const { return reinterpret_cast< const_iterator >( &c ); }
00187
00188
00189 #if !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
00190 typedef std::reverse_iterator<iterator> reverse_iterator;
00191 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00192 #elif defined(_MSC_VER) && (_MSC_VER == 1300) && defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB == 310)
00193
00194 typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, iterator,
00195 reference, iterator, reference> > reverse_iterator;
00196 typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, const_iterator,
00197 const_reference, iterator, reference> > const_reverse_iterator;
00198 #else
00199
00200 typedef std::reverse_iterator<iterator,T> reverse_iterator;
00201 typedef std::reverse_iterator<const_iterator,T> const_reverse_iterator;
00202 #endif
00203
00204 reverse_iterator rbegin() { return reverse_iterator(end()); }
00205 const_reverse_iterator rbegin() const {
00206 return const_reverse_iterator(end());
00207 }
00208 reverse_iterator rend() { return reverse_iterator(begin()); }
00209 const_reverse_iterator rend() const {
00210 return const_reverse_iterator(begin());
00211 }
00212
00213
00214 reference at(size_type i) {
00215 throw std::out_of_range("CArray<0>: index out of range");
00216 }
00217 const_reference at(size_type i) const {
00218 throw std::out_of_range("<0>: index out of range");
00219 }
00220
00221
00222 static size_type size() { return 0; }
00223 static bool empty() { return true; }
00224 static size_type max_size() { return 0; }
00225 enum { static_size = 0 };
00226
00227
00228 void swap (CArray<T,0>& y) {
00229
00230 }
00231
00232
00233 const T* data() const { return NULL; }
00234 T* data() { return NULL; }
00235
00236
00237 template < typename T2 >
00238 CArray< T,0 >& operator= (const CArray< T2, 0>& rhs) {
00239 return *this;
00240 }
00241
00242
00243
00244
00245 inline reference operator[](size_type i) { makes_no_sense(); static T dumm=0; return dumm; }
00246 inline const_reference operator[](size_type i) const { makes_no_sense(); static T dumm=0; return dumm; }
00247
00248
00249 reference front() { makes_no_sense(); }
00250 const_reference front() const { makes_no_sense(); }
00251 reference back() { makes_no_sense(); }
00252 const_reference back() const { makes_no_sense(); }
00253
00254 private:
00255
00256
00257 static void makes_no_sense () {
00258
00259 throw std::out_of_range("CArray<0>: index out of range");
00260 }
00261 };
00262
00263
00264 template<class T, std::size_t N>
00265 bool operator== (const CArray<T,N>& x, const CArray<T,N>& y) {
00266 return std::equal(x.begin(), x.end(), y.begin());
00267 }
00268 template<class T, std::size_t N>
00269 bool operator< (const CArray<T,N>& x, const CArray<T,N>& y) {
00270 return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
00271 }
00272 template<class T, std::size_t N>
00273 bool operator!= (const CArray<T,N>& x, const CArray<T,N>& y) {
00274 return !(x==y);
00275 }
00276 template<class T, std::size_t N>
00277 bool operator> (const CArray<T,N>& x, const CArray<T,N>& y) {
00278 return y<x;
00279 }
00280 template<class T, std::size_t N>
00281 bool operator<= (const CArray<T,N>& x, const CArray<T,N>& y) {
00282 return !(y<x);
00283 }
00284 template<class T, std::size_t N>
00285 bool operator>= (const CArray<T,N>& x, const CArray<T,N>& y) {
00286 return !(x<y);
00287 }
00288
00289
00290
00291
00292
00293
00294
00295
00296 template <typename T, std::size_t N>
00297 class CArrayPOD : public CArray<T,N>
00298 {
00299 public:
00300 CArrayPOD() {}
00301
00302 CArrayPOD(const T*ptr)
00303 {
00304 if (!ptr) THROW_EXCEPTION("ptr is a NULL pointer.")
00305 ::memcpy(&CArray<T,N>::elems[0],ptr,sizeof(T)*N);
00306 }
00307
00308
00309 template <class ARRAYLIKE>
00310 explicit CArrayPOD(const ARRAYLIKE &obj) {
00311 for (size_t i=0;i<N;i++)
00312 this->operator[](i) = static_cast<T>(obj[i]);
00313 }
00314
00315 };
00316
00317
00318
00319
00320
00321
00322 template <typename T, std::size_t N>
00323 class CArrayNumeric : public CArrayPOD<T,N>
00324 {
00325 public:
00326 CArrayNumeric() {}
00327
00328 CArrayNumeric(const T*ptr) : CArrayPOD<T,N>(ptr) {}
00329
00330
00331 template <class ARRAYLIKE>
00332 explicit CArrayNumeric(const ARRAYLIKE &obj) : CArrayPOD<T,N>(obj) {}
00333
00334
00335 CArrayNumeric<T,N> & operator += (const CArrayNumeric<T,N>&o) {
00336 for (size_t i=0;i<N;i++)
00337 CArray<T,N>::elems[i]+=o.elems[i];
00338 return *this;
00339 }
00340
00341 CArrayNumeric<T,N> & operator -= (const CArrayNumeric<T,N>&o) {
00342 for (size_t i=0;i<N;i++)
00343 CArray<T,N>::elems[i]-=o.elems[i];
00344 return *this;
00345 }
00346 };
00347
00348
00349
00350
00351
00352
00353 template <std::size_t N>
00354 class CArrayFloat : public CArrayNumeric<float,N>
00355 {
00356 public:
00357 CArrayFloat() {}
00358 CArrayFloat(const float*ptr) : CArrayNumeric<float,N>(ptr) {}
00359
00360 template <class ARRAYLIKE>
00361 explicit CArrayFloat(const ARRAYLIKE &obj) : CArrayNumeric<float,N>(obj) {}
00362 };
00363
00364
00365
00366 template <std::size_t N>
00367 class CArrayDouble : public CArrayNumeric<double,N>
00368 {
00369 public:
00370 CArrayDouble() {}
00371 CArrayDouble(const double*ptr) : CArrayNumeric<double,N>(ptr) {}
00372
00373
00374 template <class ARRAYLIKE>
00375 explicit CArrayDouble(const ARRAYLIKE &obj) : CArrayNumeric<double,N>(obj) {}
00376 };
00377
00378
00379
00380 template <std::size_t N>
00381 class CArrayInt : public CArrayNumeric<int,N>
00382 {
00383 public:
00384 CArrayInt() {}
00385 CArrayInt(const int*ptr) : CArrayNumeric<int,N>(ptr) {}
00386 };
00387
00388
00389
00390 template <std::size_t N>
00391 class CArrayUInt : public CArrayNumeric<unsigned int,N>
00392 {
00393 public:
00394 CArrayUInt() {}
00395 CArrayUInt(const unsigned int*ptr) : CArrayNumeric<unsigned int,N>(ptr) {}
00396 };
00397
00398
00399 }
00400 }
00401
00402
00403 namespace std
00404 {
00405
00406 template<class T, std::size_t N>
00407 inline void swap (mrpt::math::CArray<T,N>& x, mrpt::math::CArray<T,N>& y) {
00408 x.swap(y);
00409 }
00410 }
00411
00412 #endif