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



Page generated by Doxygen 1.7.3 for MRPT 0.9.4 SVN: at Sat Mar 26 06:16:28 UTC 2011