multi_array_ref.hpp

来自「CGAL is a collaborative effort of severa」· HPP 代码 · 共 623 行 · 第 1/2 页

HPP
623
字号
  // This is used by multi_array, which is a subclass of this  void set_base_ptr(TPtr new_base) { base_ = new_base; }  // This constructor supports multi_array's default constructor  // and constructors from multi_array_ref, subarray, and array_view  explicit  const_multi_array_ref(TPtr base,                        const storage_order_type& so,                        const index * index_bases,                        const size_type* extents) :    base_(base), storage_(so), origin_offset_(0), directional_offset_(0) {   // If index_bases or extents is null, then initialize the corresponding   // private data to zeroed lists.   if(index_bases) {     boost::copy_n(index_bases,NumDims,index_base_list_.begin());   } else {     std::fill_n(index_base_list_.begin(),NumDims,0);   }   if(extents) {     init_multi_array_ref(extents);   } else {     boost::array<index,NumDims> extent_list;     extent_list.assign(0);     init_multi_array_ref(extent_list.begin());   } }  TPtr base_;  storage_order_type storage_;  size_list extent_list_;  index_list stride_list_;  index_list index_base_list_;  index origin_offset_;  index directional_offset_;  size_type num_elements_;private:  // const_multi_array_ref cannot be assigned to (no deep copies!)  const_multi_array_ref& operator=(const const_multi_array_ref& other);  void init_from_extent_gen(const                        detail::multi_array::                        extent_gen<NumDims>& ranges) {         typedef boost::array<index,NumDims> extent_list;    // get the index_base values    std::transform(ranges.ranges_.begin(),ranges.ranges_.end(),              index_base_list_.begin(),              boost::mem_fun_ref(&extent_range::start));    // calculate the extents    extent_list extents;    std::transform(ranges.ranges_.begin(),ranges.ranges_.end(),              extents.begin(),              boost::mem_fun_ref(&extent_range::size));    init_multi_array_ref(extents.begin());  }#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDSprotected:#elsepublic:#endif  // RG - move me!  template <class InputIterator>  void init_multi_array_ref(InputIterator extents_iter) {    boost::function_requires<InputIteratorConcept<InputIterator> >();    boost::copy_n(extents_iter,num_dimensions(),extent_list_.begin());    // Calculate the array size    num_elements_ = std::accumulate(extent_list_.begin(),extent_list_.end(),                            1,std::multiplies<index>());    this->compute_strides(stride_list_,extent_list_,storage_);    origin_offset_ =      this->calculate_origin_offset(stride_list_,extent_list_,                              storage_,index_base_list_);    directional_offset_ =      this->calculate_descending_dimension_offset(stride_list_,extent_list_,                                            storage_);  }};template <typename T, std::size_t NumDims>class multi_array_ref :  public const_multi_array_ref<T,NumDims,T*>{  typedef const_multi_array_ref<T,NumDims,T*> super_type;public:   typedef typename super_type::value_type value_type;  typedef typename super_type::reference reference;  typedef typename super_type::iterator iterator;  typedef typename super_type::reverse_iterator reverse_iterator;  typedef typename super_type::const_reference const_reference;  typedef typename super_type::const_iterator const_iterator;  typedef typename super_type::const_reverse_iterator const_reverse_iterator;  typedef typename super_type::element element;  typedef typename super_type::size_type size_type;  typedef typename super_type::difference_type difference_type;  typedef typename super_type::index index;  typedef typename super_type::extent_range extent_range;  typedef typename super_type::storage_order_type storage_order_type;  typedef typename super_type::index_list index_list;  typedef typename super_type::size_list size_list;  template <std::size_t NDims>  struct const_array_view {    typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;  };  template <std::size_t NDims>  struct array_view {    typedef boost::detail::multi_array::multi_array_view<T,NDims> type;  };  template <class ExtentList>  explicit multi_array_ref(T* base, const ExtentList& extents) :    super_type(base,extents) {    boost::function_requires<      detail::multi_array::CollectionConcept<ExtentList> >();  }  template <class ExtentList>  explicit multi_array_ref(T* base, const ExtentList& extents,                           const general_storage_order<NumDims>& so) :    super_type(base,extents,so) {    boost::function_requires<      detail::multi_array::CollectionConcept<ExtentList> >();  }  explicit multi_array_ref(T* base,                           const detail::multi_array::                           extent_gen<NumDims>& ranges) :    super_type(base,ranges) { }  explicit multi_array_ref(T* base,                           const detail::multi_array::                           extent_gen<NumDims>&                             ranges,                           const general_storage_order<NumDims>& so) :    super_type(base,ranges,so) { }  // Assignment from other ConstMultiArray types.  template <typename ConstMultiArray>  multi_array_ref& operator=(const ConstMultiArray& other) {    function_requires<       detail::multi_array::      ConstMultiArrayConcept<ConstMultiArray,NumDims> >();    // make sure the dimensions agree    assert(other.num_dimensions() == this->num_dimensions());    assert(std::equal(other.shape(),other.shape()+this->num_dimensions(),                      this->shape()));    // iterator-based copy    std::copy(other.begin(),other.end(),this->begin());    return *this;  }  multi_array_ref& operator=(const multi_array_ref& other) {    if (&other != this) {      // make sure the dimensions agree            assert(other.num_dimensions() == this->num_dimensions());      assert(std::equal(other.shape(),other.shape()+this->num_dimensions(),                        this->shape()));      // iterator-based copy      std::copy(other.begin(),other.end(),this->begin());    }    return *this;  }  element* origin() { return super_type::base_+super_type::origin_offset_; }  element* data() { return super_type::base_; }  template <class IndexList>  element& operator()(const IndexList& indices) {  boost::function_requires<    detail::multi_array::CollectionConcept<IndexList> >();  return super_type::access_element(boost::type<element&>(),                                      origin(),                                      indices,this->strides());  }  reference operator[](index idx) {    return super_type::access(boost::type<reference>(),                              idx,origin(),                              this->shape(),this->strides(),                              this->index_bases());  }  // See note attached to generate_array_view in base.hpp#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300  template <int NDims>#else  template <int NumDims, int NDims> // else ICE#endif // BOOST_MSVC  typename array_view<NDims>::type   operator[](const detail::multi_array::             index_gen<NumDims,NDims>& indices) {    typedef typename array_view<NDims>::type return_type;    return      super_type::generate_array_view(boost::type<return_type>(),                                      indices,                                      this->shape(),                                      this->strides(),                                      this->index_bases(),                                      origin());  }      iterator begin() {    return iterator(*this->index_bases(),origin(),this->shape(),                    this->strides(),this->index_bases());  }  iterator end() {    return iterator(*this->index_bases()+*this->shape(),origin(),                    this->shape(),this->strides(),                    this->index_bases());  }  // rbegin() and rend() written naively to thwart MSVC ICE.  reverse_iterator rbegin() {    reverse_iterator ri(end());    return ri;  }  reverse_iterator rend() {    reverse_iterator ri(begin());    return ri;  }  // Using declarations don't seem to work for g++  // These are the proxies to work around this.  const element* origin() const { return super_type::origin(); }  const element* data() const { return super_type::data(); }  template <class IndexList>  const element& operator()(const IndexList& indices) const {    boost::function_requires<      detail::multi_array::CollectionConcept<IndexList> >();    return super_type::operator()(indices);  }  const_reference operator[](index idx) const {    return super_type::access(boost::type<const_reference>(),                              idx,origin(),                              this->shape(),this->strides(),                              this->index_bases());  }  // See note attached to generate_array_view in base.hpp#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300  template <int NDims>#else  template <int NumDims, int NDims> // else ICE#endif // BOOST_MSVC  typename const_array_view<NDims>::type   operator[](const detail::multi_array::             index_gen<NumDims,NDims>& indices)    const {    return super_type::operator[](indices);  }    const_iterator begin() const {    return super_type::begin();  }  const_iterator end() const {    return super_type::end();  }  const_reverse_iterator rbegin() const {    return super_type::rbegin();  }  const_reverse_iterator rend() const {    return super_type::rend();  }protected:  // This is only supplied to support multi_array's default constructor  explicit multi_array_ref(T* base,                           const storage_order_type& so,                           const index* index_bases,                           const size_type* extents) :    super_type(base,so,index_bases,extents) { }};} // namespace boost#endif // BOOST_MULTI_ARRAY_REF_RG071801_HPP

⌨️ 快捷键说明

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