⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 array_n.h

📁 mean-shift. pointer sample
💻 H
字号:
/*! \file  \verbatim      Copyright (c) 2007, Sylvain Paris and Fr閐o Durand    Permission is hereby granted, free of charge, to any person    obtaining a copy of this software and associated documentation    files (the "Software"), to deal in the Software without    restriction, including without limitation the rights to use, copy,    modify, merge, publish, distribute, sublicense, and/or sell copies    of the Software, and to permit persons to whom the Software is    furnished to do so, subject to the following conditions:    The above copyright notice and this permission notice shall be    included in all copies or substantial portions of the Software.    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER    DEALINGS IN THE SOFTWARE.  \endverbatim*/#ifndef __ARRAY_N__#define __ARRAY_N__#ifdef ARRAY_EXCEPTION#  include <stdexcept>#else#  include <iostream>#endif  #include <algorithm>#include <vector>#include "geom.h"//! Class representing a n D array./*!  Optimised for an access in order :  \code  for(x0=...){ for(x1=...){...} }  \endcode    at() and the operator[]() accept a vector that provides an  access to its elements through an [] operator. */template<unsigned int N,typename T,typename A = std::allocator<T> >class Array_ND{private:  //! Type of the storage structure.  typedef std::vector<T,A> storage_type;  public:  //@{  //! Standard type.  typedef typename storage_type::value_type             value_type;  typedef typename storage_type::allocator_type         allocator_type;    typedef typename storage_type::size_type              size_type;  typedef typename storage_type::difference_type        difference_type;  typedef typename storage_type::iterator               iterator;  typedef typename storage_type::const_iterator         const_iterator;  typedef typename storage_type::reverse_iterator       reverse_iterator;  typedef typename storage_type::const_reverse_iterator const_reverse_iterator;  typedef typename storage_type::reference              reference;  typedef typename storage_type::const_reference        const_reference;  typedef Geometry::Vec<N,unsigned int> key_type;  //@}  //! Standard value  static const size_type dimension = N;      //@{  //! Classical constructor.    explicit inline Array_ND(const A& a = A());  template<typename Vector_ND>  explicit inline Array_ND(const Vector_ND& size_vector,			   const T& val = T(),const A& a = A());    template<typename Element_iterator,typename Vector_ND>  inline Array_ND(Element_iterator begin_elt,		  Element_iterator end_elt,		  const Vector_ND& size_vector,		  const A& a = A());      inline Array_ND(const Array_ND<N,T,A>& a);  //@}  //! Assignement of a default value.  template<typename Vector_ND>  void assign(const Vector_ND& size_vector,	      const T& val);  //@{  //! Handle the array dimension.  inline bool empty() const;    template<typename Vector_ND>  inline void all_sizes(Vector_ND* const size) const;    inline size_type dimension_size(const size_type dim) const;  inline size_type size() const;  inline size_type max_size() const;    template<typename Vector_ND>  inline void resize(const Vector_ND& size_vector);#ifdef ARRAY_N_ENABLE_ORIGIN_SHIFT  template<typename Vector_ND>  inline void set_origin(const Vector_ND& size_vector);    template<typename Vector_ND>  inline void get_origin(Vector_ND* const o) const;  #endif    //@}  //! Efficient swapping of two 2D arrays.  inline void swap(Array_ND<N,T,A>& a); /* A reference is used as in the STL. */  //! Gives the memory allocator.  inline allocator_type get_allocator() const;     //@{  //! Classical operator.    inline Array_ND<N,T,A>& operator=(const Array_ND<N,T,A>& a);  inline bool operator==(const Array_ND<N,T,A>& a);  inline bool operator!=(const Array_ND<N,T,A>& a);   //@}    //@{  //! Access operator.  template<typename Vector_ND>  inline reference       operator[](const Vector_ND& v);    template<typename Vector_ND>  inline const_reference operator[](const Vector_ND& v) const;  template<typename Vector_ND>  inline reference       at(const Vector_ND& v);    template<typename Vector_ND>  inline const_reference at(const Vector_ND& v) const;  //@}    //@{  //! Points on the (0,0) element.  /*!    Goes through the array in the order    \code      for(x0=...){ for(x1=...){...} }.    \endcode   */    inline iterator       begin();  inline const_iterator begin() const;  //@}  //@{  //! Points on the element after the last one.  /*!    Goes through the array in the order    \code      for(x0=...){ for(x1=...){...} }.    \endcode   */    inline iterator       end();  inline const_iterator end() const;  //@}  //@{  //! Reverse iterator.  inline reverse_iterator       rbegin();    inline const_reverse_iterator rbegin() const;  inline reverse_iterator       rend();  inline const_reverse_iterator rend() const;  //@}  //! Advance \p index by one step to achieve a scan order  //! for(x0=start[0];x0<end[0];x0++){for(x1=...){}}  //! Return \e false when all elements have been scanned.  template<typename Vector_ND_1,typename Vector_ND_2,typename Vector_ND_3>  inline bool advance(Vector_ND_1* const index,		      const Vector_ND_2& start,		      const Vector_ND_3& end) const;  //! Advance \p index by one step to achieve a scan order  //! for(x0=0;x0<size[0];x0++){for(x1=...){}}  //! Return \e false when all elements have been scanned.  /*! A typical usage is:    \code    key_type index; // assumes that index is properly initialized.    do{      // some operations    }    while(advance(&index));    \endcode  */  template<typename Vector_ND>  inline bool advance(Vector_ND* const index) const;private:  //! Dimension of the array.  key_type dim_size;  #ifdef ARRAY_N_ENABLE_ORIGIN_SHIFT  //! The first element is at \e origin.  key_type origin;#endif    //! Storage structure.  storage_type storage;  //! Computation of the position in the storage structure.  template<typename Vector_ND>  inline size_type offset(const Vector_ND& v) const;  };/*    #############################################  #############################################  #############################################  ######                                 ######  ######   I M P L E M E N T A T I O N   ######  ######                                 ######  #############################################  #############################################  #############################################  */template<unsigned int N,typename T,typename A>Array_ND<N,T,A>::Array_ND(const A& a)  :dim_size(),storage(a){}template<unsigned int N,typename T,typename A>template<typename Vector_ND>Array_ND<N,T,A>::Array_ND(const Vector_ND& size_vector,			  const T& val,const A& a):  storage(a){  size_type s = 1;    for(size_type n=0;n<N;n++){    const size_type a = size_vector[n];        dim_size[n] = a;    s *= a;  }  storage.assign(s,val);}/*!  Fills in the array with the elements between \p begin_elt and  \p \e end_elt.  Throw the length_error() exception if not enough elements. */template<unsigned int N,typename T,typename A>template<typename Element_iterator,typename Vector_ND>Array_ND<N,T,A>::Array_ND(Element_iterator begin_elt,			  Element_iterator end_elt,			  const Vector_ND& size_vector,			  const A& a):  storage(a){  size_type s = 1;    for(size_type n=0;n<N;n++){    const size_type a = size_vector[n];        dim_size[n] = a;    s *= a;  }  storage.reserve(s);    Element_iterator elt;  size_type index;  for(elt=begin_elt,index=0;(elt!=end_elt)&&(index<s);elt++,index++){    storage.push_back(*elt);  }  if (index!=s) {    storage.clear();    storage.reserve(0);#ifdef ARRAY_EXCEPTION    throw std::length_error("Not enough elements to initialize the array");#else    std::cerr<<"[Array_ND<T,A>::Array_ND] Not enough elements to initialize the array"<<std::endl;#endif  }}    template<unsigned int N,typename T,typename A>Array_ND<N,T,A>::Array_ND(const Array_ND<N,T,A>& a):  dim_size(a.dim_size),storage(a.storage){}template<unsigned int N,typename T,typename A>template<typename Vector_ND>voidArray_ND<N,T,A>::assign(const Vector_ND& size_vector,			const T& val){  size_type s = 1;    for(size_type n=0;n<N;n++){    const size_type a = size_vector[n];        dim_size[n] = a;    s *= a;  }  storage.assign(s,val);}template<unsigned int N,typename T,typename A>boolArray_ND<N,T,A>::empty() const{  return storage.empty();}template<unsigned int N,typename T,typename A>template<typename Vector_ND>voidArray_ND<N,T,A>::all_sizes(Vector_ND* const size) const{  for(size_type n=0;n<N;n++){    (*size)[n] = dim_size[n];  }}template<unsigned int N,typename T,typename A>typename Array_ND<N,T,A>::size_typeArray_ND<N,T,A>::dimension_size(const size_type dim) const{  return dim_size[dim];}template<unsigned int N,typename T,typename A>typename Array_ND<N,T,A>::size_typeArray_ND<N,T,A>::size() const{  return storage.size();}template<unsigned int N,typename T,typename A>typename Array_ND<N,T,A>::size_typeArray_ND<N,T,A>::max_size() const{    return storage.max_size();}template<unsigned int N,typename T,typename A>template<typename Vector_ND>voidArray_ND<N,T,A>::resize(const Vector_ND& size_vector){  size_type s = 1;    for(size_type n=0;n<N;n++){    const size_type a = size_vector[n];        dim_size[n] = a;    s *= a;  }  storage.resize(s);}#ifdef ARRAY_N_ENABLE_ORIGIN_SHIFTtemplate<unsigned int N,typename T,typename A>template<typename Vector_ND>voidArray_ND<N,T,A>::set_origin(const Vector_ND& o){  origin = o;}template<unsigned int N,typename T,typename A>template<typename Vector_ND>voidArray_ND<N,T,A>::get_origin(Vector_ND* const o) const{  for(size_type n = 0;n < N;++n){    (*o)[n] = origin[n];  }}#endiftemplate<unsigned int N,typename T,typename A>void Array_ND<N,T,A>::swap(Array_ND<N,T,A>& a){  const key_type buf = dim_size;  dim_size           = a.dim_size;  a.dim_size         = buf;//   swap(dim_size,a.dim_size);    storage.swap(a.storage);  }template<unsigned int N,typename T,typename A>typename Array_ND<N,T,A>::allocator_typeArray_ND<N,T,A>::get_allocator() const{    return storage.get_allocator();}template<unsigned int N,typename T,typename A>Array_ND<N,T,A>&Array_ND<N,T,A>::operator=(const Array_ND<N,T,A>& a){  if (&a!=this){    dim_size = a.dim_size;    storage  = a.storage;  }  return *this;}template<unsigned int N,typename T,typename A>boolArray_ND<N,T,A>::operator==(const Array_ND<N,T,A>& a){  return ((dim_size == a.dim_size) && (storage == a.storage));}template<unsigned int N,typename T,typename A>boolArray_ND<N,T,A>::operator!=(const Array_ND<N,T,A>& a){  return !(*this==a);}template<unsigned int N,typename T,typename A>template<typename Vector_ND>typename Array_ND<N,T,A>::referenceArray_ND<N,T,A>::operator[](const Vector_ND& v){  return storage[offset(v)];}  template<unsigned int N,typename T,typename A>template<typename Vector_ND>typename Array_ND<N,T,A>::const_referenceArray_ND<N,T,A>::operator[](const Vector_ND& v) const{  return storage[offset(v)];}template<unsigned int N,typename T,typename A>template<typename Vector_ND>typename Array_ND<N,T,A>::referenceArray_ND<N,T,A>::at(const Vector_ND& v){  for(size_type n=0;n<N;n++){    if (v[n] >= dim_size[n]){#ifdef ARRAY_EXCEPTION      throw std::out_of_range("Out of range");    #else      std::cerr<<"[Array_ND<T,A>::at] Out of range"<<std::endl;      exit(1);#endif    }  }  return storage[offset(v)];}template<unsigned int N,typename T,typename A>template<typename Vector_ND>typename Array_ND<N,T,A>::const_referenceArray_ND<N,T,A>::at(const Vector_ND& v) const{  for(size_type n=0;n<N;n++){    if (v[n] >= dim_size[n]){#ifdef ARRAY_EXCEPTION      throw std::out_of_range("Out of range");    #else      std::cerr<<"[Array_ND<T,A>::at] Out of range"<<std::endl;      exit(1);#endif    }  }  return storage[offset(v)];}template<unsigned int N,typename T,typename A>typename Array_ND<N,T,A>::iteratorArray_ND<N,T,A>::begin(){  return storage.begin();}template<unsigned int N,typename T,typename A>typename Array_ND<N,T,A>::const_iteratorArray_ND<N,T,A>::begin() const{  return storage.begin();}template<unsigned int N,typename T,typename A>typename Array_ND<N,T,A>::iteratorArray_ND<N,T,A>::end(){  return storage.end();}template<unsigned int N,typename T,typename A>typename Array_ND<N,T,A>::const_iteratorArray_ND<N,T,A>::end() const{  return storage.end();}template<unsigned int N,typename T,typename A>typename Array_ND<N,T,A>::reverse_iteratorArray_ND<N,T,A>::rbegin(){  return storage.rbegin();}template<unsigned int N,typename T,typename A>typename Array_ND<N,T,A>::const_reverse_iteratorArray_ND<N,T,A>::rbegin() const{  return storage.rbegin();}template<unsigned int N,typename T,typename A>typename Array_ND<N,T,A>::reverse_iteratorArray_ND<N,T,A>::rend(){  return storage.rend();}template<unsigned int N,typename T,typename A>typename Array_ND<N,T,A>::const_reverse_iteratorArray_ND<N,T,A>::rend() const{  return storage.rend();}template<unsigned int N,typename T,typename A>template<typename Vector_ND>typename Array_ND<N,T,A>::size_typeArray_ND<N,T,A>::offset(const Vector_ND& v) const{  size_type res = v[0];  #ifdef ARRAY_N_ENABLE_ORIGIN_SHIFT  res -= origin[0];#endif    for(size_type n=1;n<N;n++){    res *= dim_size[n];    res += v[n];    #ifdef ARRAY_N_ENABLE_ORIGIN_SHIFT    res -= origin[n];#endif  }    return res;}/*! There is no test to check that \p index is actually "after" \p start. */template<unsigned int N,typename T,typename A>template<typename Vector_ND_1,typename Vector_ND_2,typename Vector_ND_3>boolArray_ND<N,T,A>::advance(Vector_ND_1* const index,			 const Vector_ND_2& start,			 const Vector_ND_3& end) const{  bool valid_increase = false;    for(int n = N - 1;      (!valid_increase) && (n>=0);      --n){    typename Vector_ND_1::value_type& i = (*index)[n];    i++;    valid_increase =      (i < static_cast<typename Vector_ND_1::value_type>(end[n]));    if (!valid_increase){      i = start[n];    }  }  return valid_increase;}template<unsigned int N,typename T,typename A>template<typename Vector_ND>boolArray_ND<N,T,A>::advance(Vector_ND* const index) const{#ifdef ARRAY_N_ENABLE_ORIGIN_SHIFT    return advance(index,origin,origin+dim_size);#else  static const Vector_ND zero_start;  return advance(index,zero_start,dim_size);  #endif}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -