Main MRPT website > C++ reference
MRPT logo
CArray.h
Go to the documentation of this file.
00001 /* +---------------------------------------------------------------------------+
00002    |          The Mobile Robot Programming Toolkit (MRPT) C++ library          |
00003    |                                                                           |
00004    |                       http://www.mrpt.org/                                |
00005    |                                                                           |
00006    |   Copyright (C) 2005-2011  University of Malaga                           |
00007    |                                                                           |
00008    |    This software was written by the Machine Perception and Intelligent    |
00009    |      Robotics Lab, University of Malaga (Spain).                          |
00010    |    Contact: Jose-Luis Blanco  <jlblanco@ctima.uma.es>                     |
00011    |                                                                           |
00012    |  This file is part of the MRPT project.                                   |
00013    |                                                                           |
00014    |     MRPT is free software: you can redistribute it and/or modify          |
00015    |     it under the terms of the GNU General Public License as published by  |
00016    |     the Free Software Foundation, either version 3 of the License, or     |
00017    |     (at your option) any later version.                                   |
00018    |                                                                           |
00019    |   MRPT is distributed in the hope that it will be useful,                 |
00020    |     but WITHOUT ANY WARRANTY; without even the implied warranty of        |
00021    |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         |
00022    |     GNU General Public License for more details.                          |
00023    |                                                                           |
00024    |     You should have received a copy of the GNU General Public License     |
00025    |     along with MRPT.  If not, see <http://www.gnu.org/licenses/>.         |
00026    |                                                                           |
00027    +---------------------------------------------------------------------------+ */
00028 #ifndef _MRPT_CArray_H
00029 #define _MRPT_CArray_H
00030 
00031 #include <mrpt/utils/utils_defs.h>
00032 #include <mrpt/math/math_frwds.h>
00033 #include <mrpt/math/ops_containers.h>
00034 #include <mrpt/utils/CSerializable.h>  // Used only for the extension to TTypeName
00035 
00036 namespace mrpt
00037 {
00038 namespace math
00039 {
00040         // ----------------  CArray -------------------------
00041         /** 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>.
00042          *
00043          * This code is an adapted version from Boost, modifed for its integration
00044          *      within MRPT (JLBC, Dec/2009) (Renamed array -> CArray to avoid possible potential conflicts).
00045          *
00046          * See
00047          *      http://www.josuttis.com/cppcode
00048          * for details and the latest version.
00049          * See
00050          *      http://www.boost.org/libs/array for Documentation.
00051          * for documentation.
00052          *
00053          * (C) Copyright Nicolai M. Josuttis 2001.
00054          * Permission to copy, use, modify, sell and distribute this software
00055          * is granted provided this copyright notice appears in all copies.
00056          * This software is provided "as is" without express or implied
00057          * warranty, and with no claim as to its suitability for any purpose.
00058          *
00059          * 29 Jan 2004 - minor fixes (Nico Josuttis)
00060          * 04 Dec 2003 - update to synch with library TR1 (Alisdair Meredith)
00061          * 23 Aug 2002 - fix for Non-MSVC compilers combined with MSVC libraries.
00062          * 05 Aug 2001 - minor update (Nico Josuttis)
00063          * 20 Jan 2001 - STLport fix (Beman Dawes)
00064          * 29 Sep 2000 - Initial Revision (Nico Josuttis)
00065          *
00066          * Jan 30, 2004
00067          *
00068          * \note This class DOES NOT support mathematical operations on its elements: it's a generic container, it doesn't assume they are numerical.
00069          * \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
00070          *
00071      * \sa CArrayNumeric (for another, non-related base template class that DOES support maths)
00072          * \ingroup mrpt_base_grp
00073          */
00074     template <typename T, std::size_t N>
00075     class CArray {
00076       public:
00077         T elems[N];    // fixed-size array of elements of type T
00078 
00079       public:
00080         // type definitions
00081         typedef T              value_type;
00082         typedef T*             iterator;
00083         typedef const T*       const_iterator;
00084         typedef T&             reference;
00085         typedef const T&       const_reference;
00086         typedef std::size_t    size_type;
00087         typedef std::ptrdiff_t difference_type;
00088 
00089         // iterator support
00090         inline iterator begin() { return elems; }
00091         inline const_iterator begin() const { return elems; }
00092         inline iterator end() { return elems+N; }
00093         inline const_iterator end() const { return elems+N; }
00094 
00095         // reverse iterator support
00096 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
00097         typedef std::reverse_iterator<iterator> reverse_iterator;
00098         typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00099 #elif defined(_MSC_VER) && (_MSC_VER == 1300) && defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB == 310)
00100         // workaround for broken reverse_iterator in VC7
00101         typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, iterator,
00102                                       reference, iterator, reference> > reverse_iterator;
00103         typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, const_iterator,
00104                                       const_reference, iterator, reference> > const_reverse_iterator;
00105 #else
00106         // workaround for broken reverse_iterator implementations
00107         typedef std::reverse_iterator<iterator,T> reverse_iterator;
00108         typedef std::reverse_iterator<const_iterator,T> const_reverse_iterator;
00109 #endif
00110 
00111         reverse_iterator rbegin() { return reverse_iterator(end()); }
00112         const_reverse_iterator rbegin() const {
00113             return const_reverse_iterator(end());
00114         }
00115         reverse_iterator rend() { return reverse_iterator(begin()); }
00116         const_reverse_iterator rend() const {
00117             return const_reverse_iterator(begin());
00118         }
00119 
00120         // operator[]
00121         inline reference operator[](size_type i) { return elems[i]; }
00122         inline const_reference operator[](size_type i) const { return elems[i]; }
00123 
00124         // at() with range check
00125         reference at(size_type i) { rangecheck(i); return elems[i]; }
00126         const_reference at(size_type i) const { rangecheck(i); return elems[i]; }
00127 
00128         // front() and back()
00129         reference front() { return elems[0]; }
00130         const_reference front() const { return elems[0]; }
00131         reference back() { return elems[N-1]; }
00132         const_reference back() const { return elems[N-1]; }
00133 
00134         // size is constant
00135         static inline size_type size() { return N; }
00136         static bool empty() { return false; }
00137         static size_type max_size() { return N; }
00138         enum { static_size = N };
00139 
00140                 /** This method has no effects in this class, but raises an exception if the expected size does not match */
00141                 inline void resize(const size_t nElements) {
00142                         if (nElements!=N)
00143                                 throw std::logic_error(format("Try to change the size of a %u-CArray to %u.",static_cast<unsigned>(N),static_cast<unsigned>(nElements)));
00144                 }
00145 
00146         // swap (note: linear complexity in N, constant for given instantiation)
00147         void swap (CArray<T,N>& y) {
00148             std::swap_ranges(begin(),end(),y.begin());
00149         }
00150 
00151         // direct access to data (read-only)
00152         const T* data() const { return elems; }
00153 
00154         // use array as C array (direct read/write access to data)
00155         T* data() { return elems; }
00156 
00157         // assignment with type conversion
00158         template <typename T2>
00159         CArray<T,N>& operator= (const CArray<T2,N>& rhs) {
00160             std::copy(rhs.begin(),rhs.end(), begin());
00161             return *this;
00162         }
00163 
00164         // assign one value to all elements
00165         inline void assign (const T& value)
00166         {
00167                         for (size_t i=0;i<N;i++) elems[i]=value;
00168         }
00169         // assign (compatible with std::vector's one) (by JLBC for MRPT)
00170         void assign (const size_t n, const T& value)
00171         {
00172                 ASSERTDEB_(N==n);
00173                         for (size_t i=0;i<N;i++) elems[i]=value;
00174         }
00175 
00176                 //assign a range of values corresponding to a pair of iterators (by PMO for MRPT)
00177                 template<typename I> void assign(I b,const I &e)        {
00178                         ASSERTDEB_(std::distance(b,e)==N);
00179                         for (iterator i=begin();i<end();++i) *i=*(b++);
00180                 }
00181 
00182       private:
00183         // check range (may be private because it is static)
00184         static void rangecheck (size_type i) {
00185             if (i >= size()) {
00186                 throw std::out_of_range("CArray<>: index out of range");
00187             }
00188         }
00189 
00190     };
00191 
00192 // partial specialization for arrays of size 0
00193     template <typename T>
00194     class CArray<T,0> {
00195       public:
00196         char c;  // to ensure different array intances return unique values for begin/end
00197 
00198       public:
00199         // type definitions
00200         typedef T              value_type;
00201         typedef T*             iterator;
00202         typedef const T*       const_iterator;
00203         typedef T&             reference;
00204         typedef const T&       const_reference;
00205         typedef std::size_t    size_type;
00206         typedef std::ptrdiff_t difference_type;
00207 
00208         // iterator support
00209         iterator begin() { return reinterpret_cast< iterator >( &c ); }
00210         const_iterator begin() const { return reinterpret_cast< const_iterator >( &c ); }
00211         iterator end() { return reinterpret_cast< iterator >( &c ); }
00212         const_iterator end() const { return reinterpret_cast< const_iterator >( &c ); }
00213 
00214         // reverse iterator support
00215 #if !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
00216         typedef std::reverse_iterator<iterator> reverse_iterator;
00217         typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00218 #elif defined(_MSC_VER) && (_MSC_VER == 1300) && defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB == 310)
00219         // workaround for broken reverse_iterator in VC7
00220         typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, iterator,
00221                                       reference, iterator, reference> > reverse_iterator;
00222         typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, const_iterator,
00223                                       const_reference, iterator, reference> > const_reverse_iterator;
00224 #else
00225         // workaround for broken reverse_iterator implementations
00226         typedef std::reverse_iterator<iterator,T> reverse_iterator;
00227         typedef std::reverse_iterator<const_iterator,T> const_reverse_iterator;
00228 #endif
00229 
00230         reverse_iterator rbegin() { return reverse_iterator(end()); }
00231         const_reverse_iterator rbegin() const {
00232             return const_reverse_iterator(end());
00233         }
00234         reverse_iterator rend() { return reverse_iterator(begin()); }
00235         const_reverse_iterator rend() const {
00236             return const_reverse_iterator(begin());
00237         }
00238 
00239         // at() with range check
00240         reference at(size_type i) {
00241             throw std::out_of_range("CArray<0>: index out of range");
00242         }
00243         const_reference at(size_type i) const {
00244             throw std::out_of_range("<0>: index out of range");
00245         }
00246 
00247         // size is constant
00248         static size_type size() { return 0; }
00249         static bool empty() { return true; }
00250         static size_type max_size() { return 0; }
00251         enum { static_size = 0 };
00252 
00253         // swap
00254         void swap (CArray<T,0>& y) {
00255             //  could swap value of c, but value is not part of documented array state
00256         }
00257 
00258         // direct access to data
00259         const T* data() const { return NULL; }
00260         T* data() { return NULL; }
00261 
00262         // assignment with type conversion
00263         template < typename T2 >
00264         CArray< T,0 >& operator= (const CArray< T2, 0>& rhs) {
00265             return *this;
00266         }
00267 
00268         //  Calling these operations are undefined behaviour for 0-size arrays,
00269         //  but Library TR1 requires their presence.
00270         // operator[]
00271         inline reference operator[](size_type i) { makes_no_sense(); static T dumm=0; return dumm; }
00272         inline const_reference operator[](size_type i) const { makes_no_sense(); static T dumm=0; return dumm; }
00273 
00274         // front() and back()
00275         reference front() { makes_no_sense(); }
00276         const_reference front() const { makes_no_sense(); }
00277         reference back() { makes_no_sense(); }
00278         const_reference back() const { makes_no_sense(); }
00279 
00280       private:
00281         // helper for operations that have undefined behaviour for 0-size arrays,
00282         //  assert( false ); added to make lack of support clear
00283         static void makes_no_sense () {
00284             //assert(true);
00285             throw std::out_of_range("CArray<0>: index out of range");
00286         }
00287     };
00288 
00289     // comparisons
00290     template<class T, std::size_t N>
00291     bool operator== (const CArray<T,N>& x, const CArray<T,N>& y) {
00292         return std::equal(x.begin(), x.end(), y.begin());
00293     }
00294     template<class T, std::size_t N>
00295     bool operator< (const CArray<T,N>& x, const CArray<T,N>& y) {
00296         return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
00297     }
00298     template<class T, std::size_t N>
00299     bool operator!= (const CArray<T,N>& x, const CArray<T,N>& y) {
00300         return !(x==y);
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 !(y<x);
00309     }
00310     template<class T, std::size_t N>
00311     bool operator>= (const CArray<T,N>& x, const CArray<T,N>& y) {
00312         return !(x<y);
00313     }
00314 
00315 
00316 
00317 
00318         // ----------------  CArrayNumeric -------------------------
00319 
00320     /** CArrayNumeric is an array for numeric types supporting several mathematical operations (actually, just a wrapper on Eigen::Matrix<T,N,1>)
00321       * \sa CArrayFloat, CArrayDouble, CArray
00322       */
00323     template <typename T, std::size_t N>
00324     class CArrayNumeric : public Eigen::Matrix<T,N,1>
00325     {
00326         public:
00327                 typedef Eigen::Matrix<T,N,1> Base;
00328 
00329         CArrayNumeric() {}  //!< Default constructor
00330         /** Constructor from initial values ptr[0]-ptr[N-1] */
00331         CArrayNumeric(const T*ptr) : Eigen::Matrix<T,N,1>(ptr) {}
00332 
00333                 MRPT_MATRIX_CONSTRUCTORS_FROM_POSES(CArrayNumeric)
00334 
00335                 /** Initialization from a vector-like source, that is, anything implementing operator[]. */
00336         template <class ARRAYLIKE>
00337         explicit CArrayNumeric(const ARRAYLIKE &obj) : Eigen::Matrix<T,N,1>(obj) {}
00338 
00339                 template<typename OtherDerived>
00340                 inline CArrayNumeric<T,N> & operator= (const Eigen::MatrixBase <OtherDerived>& other) {
00341                         Base::operator=(other);
00342                         return *this;
00343                 }
00344 
00345     };
00346 
00347         // --------------  Partial specializations of CArrayNumeric -----------
00348 
00349     /** A partial specialization of CArrayNumeric for float numbers.
00350       * \sa CArrayNumeric, CArray */
00351     template <std::size_t N>
00352     class CArrayFloat : public CArrayNumeric<float,N>
00353     {
00354         public:
00355                 typedef CArrayNumeric<float,N> Base;
00356                 typedef CArrayFloat<N> mrpt_autotype;
00357 
00358         CArrayFloat() {}  //!< Default constructor
00359         CArrayFloat(const float*ptr) : CArrayNumeric<float,N>(ptr) {} //!< Constructor from initial values ptr[0]-ptr[N-1]
00360 
00361                 MRPT_MATRIX_CONSTRUCTORS_FROM_POSES(CArrayFloat)
00362 
00363                 /** Initialization from a vector-like source, that is, anything implementing operator[]. */
00364         template <class ARRAYLIKE>
00365         explicit CArrayFloat(const ARRAYLIKE &obj) : CArrayNumeric<float,N>(obj) {}
00366                 MRPT_EIGEN_DERIVED_CLASS_CTOR_OPERATOR_EQUAL(CArrayFloat) // Implements ctor and "operator =" for any other Eigen class
00367     };
00368 
00369     /** A partial specialization of CArrayNumeric for double numbers.
00370       * \sa CArrayNumeric, CArray */
00371     template <std::size_t N>
00372     class CArrayDouble : public CArrayNumeric<double,N>
00373     {
00374         public:
00375                 typedef CArrayNumeric<double,N> Base;
00376                 typedef CArrayDouble<N> mrpt_autotype;
00377 
00378         CArrayDouble() {}  //!< Default constructor
00379         CArrayDouble(const double*ptr) : CArrayNumeric<double,N>(ptr) {} //!< Constructor from initial values ptr[0]-ptr[N-1]
00380 
00381                 MRPT_MATRIX_CONSTRUCTORS_FROM_POSES(CArrayDouble)
00382 
00383                 /** Initialization from a vector-like source, that is, anything implementing operator[]. */
00384         template <class ARRAYLIKE>
00385         explicit CArrayDouble(const ARRAYLIKE &obj) : CArrayNumeric<double,N>(obj) {}
00386                 MRPT_EIGEN_DERIVED_CLASS_CTOR_OPERATOR_EQUAL(CArrayDouble) // Implements ctor and "operator =" for any other Eigen class
00387     };
00388 
00389     /** A partial specialization of CArrayNumeric for int numbers.
00390       * \sa CArrayNumeric, CArray */
00391     template <std::size_t N>
00392     class CArrayInt : public CArrayNumeric<int,N>
00393     {
00394         public:
00395                 typedef CArrayNumeric<int,N> Base;
00396                 typedef CArrayInt<N> mrpt_autotype;
00397 
00398         CArrayInt() {}  //!< Default constructor
00399         CArrayInt(const int*ptr) : CArrayNumeric<int,N>(ptr) {} //!< Constructor from initial values ptr[0]-ptr[N-1]
00400                 MRPT_EIGEN_DERIVED_CLASS_CTOR_OPERATOR_EQUAL(CArrayInt) // Implements ctor and "operator =" for any other Eigen class
00401     };
00402 
00403     /** A partial specialization of CArrayNumeric for unsigned int numbers.
00404       * \sa CArrayNumeric, CArray */
00405     template <std::size_t N>
00406     class CArrayUInt : public CArrayNumeric<unsigned int,N>
00407     {
00408         public:
00409                 typedef CArrayNumeric<unsigned int,N> Base;
00410                 typedef CArrayUInt<N> mrpt_autotype;
00411 
00412         CArrayUInt() {}  //!< Default constructor
00413         CArrayUInt(const unsigned int*ptr) : CArrayNumeric<unsigned int,N>(ptr) {} //!< Constructor from initial values ptr[0]-ptr[N-1]
00414                 MRPT_EIGEN_DERIVED_CLASS_CTOR_OPERATOR_EQUAL(CArrayUInt) // Implements ctor and "operator =" for any other Eigen class
00415     };
00416 
00417         /** Auxiliary class used in CMatrixTemplate:size(), CMatrixTemplate::resize(), CMatrixFixedNumeric::size(), CMatrixFixedNumeric::resize(), to mimic the behavior of STL-containers */
00418         struct CMatrixTemplateSize : public Eigen::Matrix<size_t,2,1>
00419         {
00420                 typedef Eigen::Matrix<size_t,2,1> Base;
00421                 typedef CMatrixTemplateSize mrpt_autotype;
00422 
00423                 inline CMatrixTemplateSize() : Eigen::Matrix<size_t,2,1>() {}
00424                 inline CMatrixTemplateSize(const size_t *d) : Eigen::Matrix<size_t,2,1>(d) {}
00425 
00426                 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]; }
00427                 inline bool operator!=(const CMatrixTemplateSize&o) const { return !(*this==o); }
00428                 /** This operator allows the size(N,M) to be compared with a plain size_t N*M  */
00429                 inline operator size_t(void) const { return Eigen::Matrix<size_t,2,1>::operator()(0)*Eigen::Matrix<size_t,2,1>::operator()(1); }
00430                 MRPT_EIGEN_DERIVED_CLASS_CTOR_OPERATOR_EQUAL(CMatrixTemplateSize) // Implements ctor and "operator =" for any other Eigen class
00431         };
00432 
00433 } // End of namespace
00434 
00435         namespace utils
00436         {
00437                 // Extensions to mrpt::utils::TTypeName for matrices:
00438                 template<typename T,size_t N> struct TTypeName <mrpt::math::CArrayNumeric<T,N> > {
00439                         static std::string get() { return mrpt::format("CArrayNumeric<%s,%u>",TTypeName<T>::get().c_str(),static_cast<unsigned int>(N)); } };
00440                 template<size_t N> struct TTypeName <mrpt::math::CArrayDouble<N> > {
00441                         static std::string get() { return mrpt::format("CArrayNumeric<double,%u>",static_cast<unsigned int>(N)); } };
00442                 template<size_t N> struct TTypeName <mrpt::math::CArrayFloat<N> > {
00443                         static std::string get() { return mrpt::format("CArrayNumeric<float,%u>",static_cast<unsigned int>(N)); } };
00444         }
00445 
00446 
00447 } // End of namespace
00448 
00449 
00450 #endif



Page generated by Doxygen 1.7.5 for MRPT 0.9.5 SVN: at Thu Oct 13 21:25:36 UTC 2011