Main MRPT website > C++ reference
MRPT logo
CArray.h
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | The Mobile Robot Programming Toolkit (MRPT) C++ library |
3  | |
4  | http://www.mrpt.org/ |
5  | |
6  | Copyright (C) 2005-2012 University of Malaga |
7  | |
8  | This software was written by the Machine Perception and Intelligent |
9  | Robotics Lab, University of Malaga (Spain). |
10  | Contact: Jose-Luis Blanco <jlblanco@ctima.uma.es> |
11  | |
12  | This file is part of the MRPT project. |
13  | |
14  | MRPT is free software: you can redistribute it and/or modify |
15  | it under the terms of the GNU General Public License as published by |
16  | the Free Software Foundation, either version 3 of the License, or |
17  | (at your option) any later version. |
18  | |
19  | MRPT is distributed in the hope that it will be useful, |
20  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
21  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
22  | GNU General Public License for more details. |
23  | |
24  | You should have received a copy of the GNU General Public License |
25  | along with MRPT. If not, see <http://www.gnu.org/licenses/>. |
26  | |
27  +---------------------------------------------------------------------------+ */
28 #ifndef _MRPT_CArray_H
29 #define _MRPT_CArray_H
30 
31 #include <mrpt/utils/utils_defs.h>
32 #include <mrpt/math/math_frwds.h>
34 #include <mrpt/utils/CSerializable.h> // Used only for the extension to TTypeName
35 
36 namespace mrpt
37 {
38 namespace math
39 {
40  // ---------------- CArray -------------------------
41  /** A STL container (as wrapper) for arrays of constant size defined at compile time - <b>Users will most likely prefer to use CArrayPOD and its derived classes instead</b>.
42  *
43  * This code is an adapted version from Boost, modifed for its integration
44  * within MRPT (JLBC, Dec/2009) (Renamed array -> CArray to avoid possible potential conflicts).
45  *
46  * See
47  * http://www.josuttis.com/cppcode
48  * for details and the latest version.
49  * See
50  * http://www.boost.org/libs/array for Documentation.
51  * for documentation.
52  *
53  * (C) Copyright Nicolai M. Josuttis 2001.
54  * Permission to copy, use, modify, sell and distribute this software
55  * is granted provided this copyright notice appears in all copies.
56  * This software is provided "as is" without express or implied
57  * warranty, and with no claim as to its suitability for any purpose.
58  *
59  * 29 Jan 2004 - minor fixes (Nico Josuttis)
60  * 04 Dec 2003 - update to synch with library TR1 (Alisdair Meredith)
61  * 23 Aug 2002 - fix for Non-MSVC compilers combined with MSVC libraries.
62  * 05 Aug 2001 - minor update (Nico Josuttis)
63  * 20 Jan 2001 - STLport fix (Beman Dawes)
64  * 29 Sep 2000 - Initial Revision (Nico Josuttis)
65  *
66  * Jan 30, 2004
67  *
68  * \note This class DOES NOT support mathematical operations on its elements: it's a generic container, it doesn't assume they are numerical.
69  * \note For a summary and classification of all MRPT vector, array and matrix classes see: http://www.mrpt.org/Matrices_vectors_arrays_and_Linear_Algebra_MRPT_and_Eigen_classes
70  *
71  * \sa CArrayNumeric (for another, non-related base template class that DOES support maths)
72  * \ingroup mrpt_base_grp
73  */
74  template <typename T, std::size_t N>
75  class CArray {
76  public:
77  T elems[N]; // fixed-size array of elements of type T
78 
79  public:
80  // type definitions
81  typedef T value_type;
82  typedef T* iterator;
83  typedef const T* const_iterator;
84  typedef T& reference;
85  typedef const T& const_reference;
86  typedef std::size_t size_type;
87  typedef std::ptrdiff_t difference_type;
88 
89  // iterator support
90  inline iterator begin() { return elems; }
91  inline const_iterator begin() const { return elems; }
92  inline iterator end() { return elems+N; }
93  inline const_iterator end() const { return elems+N; }
94 
95  // reverse iterator support
96 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
97  typedef std::reverse_iterator<iterator> reverse_iterator;
98  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
99 #elif defined(_MSC_VER) && (_MSC_VER == 1300) && defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB == 310)
100  // workaround for broken reverse_iterator in VC7
101  typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, iterator,
103  typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, const_iterator,
105 #else
106  // workaround for broken reverse_iterator implementations
107  typedef std::reverse_iterator<iterator,T> reverse_iterator;
108  typedef std::reverse_iterator<const_iterator,T> const_reverse_iterator;
109 #endif
110 
113  return const_reverse_iterator(end());
114  }
117  return const_reverse_iterator(begin());
118  }
119 
120  // operator[]
121  inline reference operator[](size_type i) { return elems[i]; }
122  inline const_reference operator[](size_type i) const { return elems[i]; }
123 
124  // at() with range check
125  reference at(size_type i) { rangecheck(i); return elems[i]; }
126  const_reference at(size_type i) const { rangecheck(i); return elems[i]; }
127 
128  // front() and back()
129  reference front() { return elems[0]; }
130  const_reference front() const { return elems[0]; }
131  reference back() { return elems[N-1]; }
132  const_reference back() const { return elems[N-1]; }
133 
134  // size is constant
135  static inline size_type size() { return N; }
136  static bool empty() { return false; }
137  static size_type max_size() { return N; }
138  enum { static_size = N };
139 
140  /** This method has no effects in this class, but raises an exception if the expected size does not match */
141  inline void resize(const size_t nElements) {
142  if (nElements!=N)
143  throw std::logic_error(format("Try to change the size of a %u-CArray to %u.",static_cast<unsigned>(N),static_cast<unsigned>(nElements)));
144  }
145 
146  // swap (note: linear complexity in N, constant for given instantiation)
147  void swap (CArray<T,N>& y) {
148  std::swap_ranges(begin(),end(),y.begin());
149  }
150 
151  // direct access to data (read-only)
152  const T* data() const { return elems; }
153 
154  // use array as C array (direct read/write access to data)
155  T* data() { return elems; }
156 
157  // assignment with type conversion
158  template <typename T2>
160  std::copy(rhs.begin(),rhs.end(), begin());
161  return *this;
162  }
163 
164  // assign one value to all elements
165  inline void assign (const T& value)
166  {
167  for (size_t i=0;i<N;i++) elems[i]=value;
168  }
169  // assign (compatible with std::vector's one) (by JLBC for MRPT)
170  void assign (const size_t n, const T& value)
171  {
172  ASSERTDEB_(N==n);
173  for (size_t i=0;i<N;i++) elems[i]=value;
174  }
175 
176  //assign a range of values corresponding to a pair of iterators (by PMO for MRPT)
177  template<typename I> void assign(I b,const I &e) {
178  ASSERTDEB_(std::distance(b,e)==N);
179  for (iterator i=begin();i<end();++i) *i=*(b++);
180  }
181 
182  private:
183  // check range (may be private because it is static)
184  static void rangecheck (size_type i) {
185  if (i >= size()) {
186  throw std::out_of_range("CArray<>: index out of range");
187  }
188  }
189 
190  };
191 
192 // partial specialization for arrays of size 0
193  template <typename T>
194  class CArray<T,0> {
195  public:
196  char c; // to ensure different array intances return unique values for begin/end
197 
198  public:
199  // type definitions
200  typedef T value_type;
201  typedef T* iterator;
202  typedef const T* const_iterator;
203  typedef T& reference;
204  typedef const T& const_reference;
205  typedef std::size_t size_type;
206  typedef std::ptrdiff_t difference_type;
207 
208  // iterator support
209  iterator begin() { return reinterpret_cast< iterator >( &c ); }
210  const_iterator begin() const { return reinterpret_cast< const_iterator >( &c ); }
211  iterator end() { return reinterpret_cast< iterator >( &c ); }
212  const_iterator end() const { return reinterpret_cast< const_iterator >( &c ); }
213 
214  // reverse iterator support
215 #if !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
216  typedef std::reverse_iterator<iterator> reverse_iterator;
217  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
218 #elif defined(_MSC_VER) && (_MSC_VER == 1300) && defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB == 310)
219  // workaround for broken reverse_iterator in VC7
220  typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, iterator,
222  typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, const_iterator,
224 #else
225  // workaround for broken reverse_iterator implementations
226  typedef std::reverse_iterator<iterator,T> reverse_iterator;
227  typedef std::reverse_iterator<const_iterator,T> const_reverse_iterator;
228 #endif
229 
232  return const_reverse_iterator(end());
233  }
236  return const_reverse_iterator(begin());
237  }
238 
239  // at() with range check
241  throw std::out_of_range("CArray<0>: index out of range");
242  }
244  throw std::out_of_range("<0>: index out of range");
245  }
246 
247  // size is constant
248  static size_type size() { return 0; }
249  static bool empty() { return true; }
250  static size_type max_size() { return 0; }
251  enum { static_size = 0 };
252 
253  // swap
254  void swap (CArray<T,0>& y) {
255  // could swap value of c, but value is not part of documented array state
256  }
257 
258  // direct access to data
259  const T* data() const { return NULL; }
260  T* data() { return NULL; }
261 
262  // assignment with type conversion
263  template < typename T2 >
265  return *this;
266  }
267 
268  // Calling these operations are undefined behaviour for 0-size arrays,
269  // but Library TR1 requires their presence.
270  // operator[]
271  inline reference operator[](size_type i) { makes_no_sense(); static T dumm=0; return dumm; }
272  inline const_reference operator[](size_type i) const { makes_no_sense(); static T dumm=0; return dumm; }
273 
274  // front() and back()
275  reference front() { makes_no_sense(); }
276  const_reference front() const { makes_no_sense(); }
277  reference back() { makes_no_sense(); }
278  const_reference back() const { makes_no_sense(); }
279 
280  private:
281  // helper for operations that have undefined behaviour for 0-size arrays,
282  // assert( false ); added to make lack of support clear
283  static void makes_no_sense () {
284  //assert(true);
285  throw std::out_of_range("CArray<0>: index out of range");
286  }
287  };
288 
289  // comparisons
290  template<class T, std::size_t N>
291  bool operator== (const CArray<T,N>& x, const CArray<T,N>& y) {
292  return std::equal(x.begin(), x.end(), y.begin());
293  }
294  template<class T, std::size_t N>
295  bool operator< (const CArray<T,N>& x, const CArray<T,N>& y) {
296  return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
297  }
298  template<class T, std::size_t N>
299  bool operator!= (const CArray<T,N>& x, const CArray<T,N>& y) {
300  return !(x==y);
301  }
302  template<class T, std::size_t N>
303  bool operator> (const CArray<T,N>& x, const CArray<T,N>& y) {
304  return y<x;
305  }
306  template<class T, std::size_t N>
307  bool operator<= (const CArray<T,N>& x, const CArray<T,N>& y) {
308  return !(y<x);
309  }
310  template<class T, std::size_t N>
311  bool operator>= (const CArray<T,N>& x, const CArray<T,N>& y) {
312  return !(x<y);
313  }
314 
315 
316 
317 
318  // ---------------- CArrayNumeric -------------------------
319 
320  /** CArrayNumeric is an array for numeric types supporting several mathematical operations (actually, just a wrapper on Eigen::Matrix<T,N,1>)
321  * \sa CArrayFloat, CArrayDouble, CArray
322  */
323  template <typename T, std::size_t N>
324  class CArrayNumeric : public Eigen::Matrix<T,N,1>
325  {
326  public:
327  typedef Eigen::Matrix<T,N,1> Base;
328 
329  CArrayNumeric() {} //!< Default constructor
330  /** Constructor from initial values ptr[0]-ptr[N-1] */
331  CArrayNumeric(const T*ptr) : Eigen::Matrix<T,N,1>(ptr) {}
332 
334 
335  /** Initialization from a vector-like source, that is, anything implementing operator[]. */
336  template <class ARRAYLIKE>
337  explicit CArrayNumeric(const ARRAYLIKE &obj) : Eigen::Matrix<T,N,1>(obj) {}
338 
339  template<typename OtherDerived>
340  inline CArrayNumeric<T,N> & operator= (const Eigen::MatrixBase <OtherDerived>& other) {
341  Base::operator=(other);
342  return *this;
343  }
344 
345  };
346 
347  // -------------- Partial specializations of CArrayNumeric -----------
348 
349  /** A partial specialization of CArrayNumeric for float numbers.
350  * \sa CArrayNumeric, CArray */
351  template <std::size_t N>
352  class CArrayFloat : public CArrayNumeric<float,N>
353  {
354  public:
357 
358  CArrayFloat() {} //!< Default constructor
359  CArrayFloat(const float*ptr) : CArrayNumeric<float,N>(ptr) {} //!< Constructor from initial values ptr[0]-ptr[N-1]
360 
362 
363  /** Initialization from a vector-like source, that is, anything implementing operator[]. */
364  template <class ARRAYLIKE>
365  explicit CArrayFloat(const ARRAYLIKE &obj) : CArrayNumeric<float,N>(obj) {}
366  MRPT_EIGEN_DERIVED_CLASS_CTOR_OPERATOR_EQUAL(CArrayFloat) // Implements ctor and "operator =" for any other Eigen class
367  };
368 
369  /** A partial specialization of CArrayNumeric for double numbers.
370  * \sa CArrayNumeric, CArray */
371  template <std::size_t N>
372  class CArrayDouble : public CArrayNumeric<double,N>
373  {
374  public:
377 
378  CArrayDouble() {} //!< Default constructor
379  CArrayDouble(const double*ptr) : CArrayNumeric<double,N>(ptr) {} //!< Constructor from initial values ptr[0]-ptr[N-1]
380 
382 
383  /** Initialization from a vector-like source, that is, anything implementing operator[]. */
384  template <class ARRAYLIKE>
385  explicit CArrayDouble(const ARRAYLIKE &obj) : CArrayNumeric<double,N>(obj) {}
386  MRPT_EIGEN_DERIVED_CLASS_CTOR_OPERATOR_EQUAL(CArrayDouble) // Implements ctor and "operator =" for any other Eigen class
387  };
388 
389  /** A partial specialization of CArrayNumeric for int numbers.
390  * \sa CArrayNumeric, CArray */
391  template <std::size_t N>
392  class CArrayInt : public CArrayNumeric<int,N>
393  {
394  public:
397 
398  CArrayInt() {} //!< Default constructor
399  CArrayInt(const int*ptr) : CArrayNumeric<int,N>(ptr) {} //!< Constructor from initial values ptr[0]-ptr[N-1]
400  MRPT_EIGEN_DERIVED_CLASS_CTOR_OPERATOR_EQUAL(CArrayInt) // Implements ctor and "operator =" for any other Eigen class
401  };
402 
403  /** A partial specialization of CArrayNumeric for unsigned int numbers.
404  * \sa CArrayNumeric, CArray */
405  template <std::size_t N>
406  class CArrayUInt : public CArrayNumeric<unsigned int,N>
407  {
408  public:
411 
412  CArrayUInt() {} //!< Default constructor
413  CArrayUInt(const unsigned int*ptr) : CArrayNumeric<unsigned int,N>(ptr) {} //!< Constructor from initial values ptr[0]-ptr[N-1]
414  MRPT_EIGEN_DERIVED_CLASS_CTOR_OPERATOR_EQUAL(CArrayUInt) // Implements ctor and "operator =" for any other Eigen class
415  };
416 
417  /** Auxiliary class used in CMatrixTemplate:size(), CMatrixTemplate::resize(), CMatrixFixedNumeric::size(), CMatrixFixedNumeric::resize(), to mimic the behavior of STL-containers */
418  struct CMatrixTemplateSize : public Eigen::Matrix<size_t,2,1>
419  {
420  typedef Eigen::Matrix<size_t,2,1> Base;
422 
423  inline CMatrixTemplateSize() : Eigen::Matrix<size_t,2,1>() {}
424  inline CMatrixTemplateSize(const size_t *d) : Eigen::Matrix<size_t,2,1>(d) {}
425 
426  inline bool operator==(const CMatrixTemplateSize&o) const { return Eigen::Matrix<size_t,2,1>::operator()(0)==o[0] && Eigen::Matrix<size_t,2,1>::operator()(1)==o[1]; }
427  inline bool operator!=(const CMatrixTemplateSize&o) const { return !(*this==o); }
428  /** This operator allows the size(N,M) to be compared with a plain size_t N*M */
429  inline operator size_t(void) const { return Eigen::Matrix<size_t,2,1>::operator()(0)*Eigen::Matrix<size_t,2,1>::operator()(1); }
430  MRPT_EIGEN_DERIVED_CLASS_CTOR_OPERATOR_EQUAL(CMatrixTemplateSize) // Implements ctor and "operator =" for any other Eigen class
431  };
432 
433 } // End of namespace
434 
435  namespace utils
436  {
437  // Extensions to mrpt::utils::TTypeName for matrices:
438  template<typename T,size_t N> struct TTypeName <mrpt::math::CArrayNumeric<T,N> > {
439  static std::string get() { return mrpt::format("CArrayNumeric<%s,%u>",TTypeName<T>::get().c_str(),static_cast<unsigned int>(N)); } };
440  template<size_t N> struct TTypeName <mrpt::math::CArrayDouble<N> > {
441  static std::string get() { return mrpt::format("CArrayNumeric<double,%u>",static_cast<unsigned int>(N)); } };
442  template<size_t N> struct TTypeName <mrpt::math::CArrayFloat<N> > {
443  static std::string get() { return mrpt::format("CArrayNumeric<float,%u>",static_cast<unsigned int>(N)); } };
444  }
445 
446 
447 } // End of namespace
448 
449 
450 #endif



Page generated by Doxygen 1.8.3 for MRPT 0.9.6 SVN: at Fri Feb 15 22:05:02 EST 2013