Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:48:16

0001 // Copyright 2002 The Trustees of Indiana University.
0002 
0003 // Use, modification and distribution is subject to the Boost Software 
0004 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0005 // http://www.boost.org/LICENSE_1_0.txt)
0006 
0007 //  Boost.MultiArray Library
0008 //  Authors: Ronald Garcia
0009 //           Jeremy Siek
0010 //           Andrew Lumsdaine
0011 //  See http://www.boost.org/libs/multi_array for documentation.
0012 
0013 #ifndef BOOST_MULTI_ARRAY_SUBARRAY_HPP
0014 #define BOOST_MULTI_ARRAY_SUBARRAY_HPP
0015 
0016 //
0017 // subarray.hpp - used to implement standard operator[] on
0018 // multi_arrays
0019 //
0020 
0021 #include "boost/multi_array/base.hpp"
0022 #include "boost/multi_array/concept_checks.hpp"
0023 #include "boost/limits.hpp"
0024 #include "boost/type.hpp"
0025 #include <algorithm>
0026 #include <cstddef>
0027 #include <functional>
0028 
0029 namespace boost {
0030 namespace detail {
0031 namespace multi_array {
0032 
0033 //
0034 // const_sub_array
0035 //    multi_array's proxy class to allow multiple overloads of
0036 //    operator[] in order to provide a clean multi-dimensional array 
0037 //    interface.
0038 template <typename T, std::size_t NumDims, typename TPtr>
0039 class const_sub_array :
0040   public boost::detail::multi_array::multi_array_impl_base<T,NumDims>
0041 {
0042   typedef boost::detail::multi_array::multi_array_impl_base<T,NumDims> super_type;
0043 public: 
0044   typedef typename super_type::value_type value_type;
0045   typedef typename super_type::const_reference const_reference;
0046   typedef typename super_type::const_iterator const_iterator;
0047   typedef typename super_type::const_reverse_iterator const_reverse_iterator;
0048   typedef typename super_type::element element;
0049   typedef typename super_type::size_type size_type;
0050   typedef typename super_type::difference_type difference_type;
0051   typedef typename super_type::index index;
0052   typedef typename super_type::extent_range extent_range;
0053 
0054   // template typedefs
0055   template <std::size_t NDims>
0056   struct const_array_view {
0057     typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
0058   };
0059 
0060   template <std::size_t NDims>
0061   struct array_view {
0062     typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
0063   };
0064 
0065   // Allow default copy constructor as well.
0066 
0067   template <typename OPtr>
0068   const_sub_array (const const_sub_array<T,NumDims,OPtr>& rhs) :
0069     base_(rhs.base_), extents_(rhs.extents_), strides_(rhs.strides_),
0070     index_base_(rhs.index_base_) {
0071   }
0072 
0073   // const_sub_array always returns const types, regardless of its own
0074   // constness.
0075   const_reference operator[](index idx) const {
0076     return super_type::access(boost::type<const_reference>(),
0077                               idx,base_,shape(),strides(),index_bases());
0078   }
0079   
0080   template <typename IndexList>
0081   const element& operator()(const IndexList& indices) const {
0082     boost::function_requires<
0083       CollectionConcept<IndexList> >();
0084     return super_type::access_element(boost::type<const element&>(),
0085                                       indices,origin(),
0086                                       shape(),strides(),index_bases());
0087   }
0088 
0089   // see generate_array_view in base.hpp
0090   template <int NDims>
0091   typename const_array_view<NDims>::type 
0092   operator[](const boost::detail::multi_array::
0093              index_gen<NumDims,NDims>& indices)
0094     const {
0095     typedef typename const_array_view<NDims>::type return_type;
0096     return
0097       super_type::generate_array_view(boost::type<return_type>(),
0098                                       indices,
0099                                       shape(),
0100                                       strides(),
0101                                       index_bases(),
0102                                       base_);
0103   }
0104 
0105   template <typename OPtr>
0106   bool operator<(const const_sub_array<T,NumDims,OPtr>& rhs) const {
0107     return std::lexicographical_compare(begin(),end(),rhs.begin(),rhs.end());
0108   }
0109 
0110   template <typename OPtr>
0111   bool operator==(const const_sub_array<T,NumDims,OPtr>& rhs) const {
0112     if(std::equal(shape(),shape()+num_dimensions(),rhs.shape()))
0113       return std::equal(begin(),end(),rhs.begin());
0114     else return false;
0115   }
0116 
0117   template <typename OPtr>
0118   bool operator!=(const const_sub_array<T,NumDims,OPtr>& rhs) const {
0119     return !(*this == rhs);
0120   }
0121 
0122   template <typename OPtr>
0123   bool operator>(const const_sub_array<T,NumDims,OPtr>& rhs) const {
0124     return rhs < *this;
0125   }
0126 
0127   template <typename OPtr>
0128   bool operator<=(const const_sub_array<T,NumDims,OPtr>& rhs) const {
0129     return !(*this > rhs);
0130   }
0131 
0132   template <typename OPtr>
0133   bool operator>=(const const_sub_array<T,NumDims,OPtr>& rhs) const {
0134     return !(*this < rhs);
0135   }
0136 
0137   const_iterator begin() const {
0138     return const_iterator(*index_bases(),origin(),
0139                           shape(),strides(),index_bases());
0140   }
0141 
0142   const_iterator end() const {
0143     return const_iterator(*index_bases()+(index)*shape(),origin(),
0144                           shape(),strides(),index_bases());
0145   }
0146 
0147   const_reverse_iterator rbegin() const {
0148     return const_reverse_iterator(end());
0149   }
0150 
0151   const_reverse_iterator rend() const {
0152     return const_reverse_iterator(begin());
0153   }
0154 
0155   TPtr origin() const { return base_; }
0156   size_type size() const { return extents_[0]; }
0157   size_type max_size() const { return num_elements(); }
0158   bool empty() const { return size() == 0; }
0159   size_type num_dimensions() const { return NumDims; }
0160   const size_type*  shape() const { return extents_; }
0161   const index* strides() const { return strides_; }
0162   const index* index_bases() const { return index_base_; }
0163 
0164   size_type num_elements() const { 
0165     return std::accumulate(shape(),shape() + num_dimensions(),
0166                            size_type(1), std::multiplies<size_type>());
0167   }
0168 
0169 
0170 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
0171 protected:
0172   template <typename,std::size_t> friend class value_accessor_n;  
0173   template <typename,std::size_t,typename> friend class const_sub_array;
0174 #else    
0175 public:  // Should be protected
0176 #endif
0177 
0178   const_sub_array (TPtr base,
0179                  const size_type* extents,
0180                  const index* strides,
0181                  const index* index_base) :
0182     base_(base), extents_(extents), strides_(strides),
0183     index_base_(index_base) {
0184   }
0185 
0186   TPtr base_;
0187   const size_type* extents_;
0188   const index* strides_;
0189   const index* index_base_;
0190 private:
0191   // const_sub_array cannot be assigned to (no deep copies!)
0192   const_sub_array& operator=(const const_sub_array&);
0193 };
0194 
0195 
0196 //
0197 // sub_array
0198 //    multi_array's proxy class to allow multiple overloads of
0199 //    operator[] in order to provide a clean multi-dimensional array 
0200 //    interface.
0201 template <typename T, std::size_t NumDims>
0202 class sub_array : public const_sub_array<T,NumDims,T*>
0203 {
0204   typedef const_sub_array<T,NumDims,T*> super_type;
0205 public: 
0206   typedef typename super_type::element element;
0207   typedef typename super_type::reference reference;
0208   typedef typename super_type::index index;
0209   typedef typename super_type::size_type size_type;
0210   typedef typename super_type::iterator iterator;
0211   typedef typename super_type::reverse_iterator reverse_iterator;
0212   typedef typename super_type::const_reference const_reference;
0213   typedef typename super_type::const_iterator const_iterator;
0214   typedef typename super_type::const_reverse_iterator const_reverse_iterator;
0215 
0216   // template typedefs
0217   template <std::size_t NDims>
0218   struct const_array_view {
0219     typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
0220   };
0221 
0222   template <std::size_t NDims>
0223   struct array_view {
0224     typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
0225   };
0226 
0227   // Assignment from other ConstMultiArray types.
0228   template <typename ConstMultiArray>
0229   sub_array& operator=(const ConstMultiArray& other) {
0230     function_requires< boost::multi_array_concepts::ConstMultiArrayConcept< 
0231         ConstMultiArray, NumDims> >();
0232 
0233     // make sure the dimensions agree
0234     BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
0235     BOOST_ASSERT(std::equal(other.shape(),other.shape()+this->num_dimensions(),
0236                             this->shape()));
0237     // iterator-based copy
0238     std::copy(other.begin(),other.end(),begin());
0239     return *this;
0240   }
0241 
0242 
0243   sub_array& operator=(const sub_array& other) {
0244     if (&other != this) {
0245       // make sure the dimensions agree
0246       BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
0247       BOOST_ASSERT(std::equal(other.shape(),
0248                               other.shape()+this->num_dimensions(),
0249                               this->shape()));
0250       // iterator-based copy
0251       std::copy(other.begin(),other.end(),begin());
0252     }
0253     return *this;
0254   }
0255 
0256   T* origin() { return this->base_; }
0257   const T* origin() const { return this->base_; }
0258 
0259   reference operator[](index idx) {
0260     return super_type::access(boost::type<reference>(),
0261                               idx,this->base_,this->shape(),this->strides(),
0262                               this->index_bases());
0263   }
0264 
0265   // see generate_array_view in base.hpp
0266   template <int NDims>
0267   typename array_view<NDims>::type 
0268   operator[](const boost::detail::multi_array::
0269              index_gen<NumDims,NDims>& indices) {
0270     typedef typename array_view<NDims>::type return_type;
0271     return
0272       super_type::generate_array_view(boost::type<return_type>(),
0273                                       indices,
0274                                       this->shape(),
0275                                       this->strides(),
0276                                       this->index_bases(),
0277                                       origin());
0278   }
0279 
0280   template <class IndexList>
0281   element& operator()(const IndexList& indices) {
0282     boost::function_requires<
0283       CollectionConcept<IndexList> >();
0284     return super_type::access_element(boost::type<element&>(),
0285                                       indices,origin(),
0286                                       this->shape(),this->strides(),
0287                                       this->index_bases());
0288   }
0289 
0290   iterator begin() {
0291     return iterator(*this->index_bases(),origin(),
0292                     this->shape(),this->strides(),this->index_bases());
0293   }
0294 
0295   iterator end() {
0296     return iterator(*this->index_bases()+(index)*this->shape(),origin(),
0297                     this->shape(),this->strides(),this->index_bases());
0298   }
0299 
0300   // RG - rbegin() and rend() written naively to thwart MSVC ICE.
0301   reverse_iterator rbegin() {
0302     reverse_iterator ri(end());
0303     return ri;
0304   }
0305 
0306   reverse_iterator rend() {
0307     reverse_iterator ri(begin());
0308     return ri;
0309   }
0310 
0311   //
0312   // proxies
0313   //
0314 
0315   template <class IndexList>
0316   const element& operator()(const IndexList& indices) const {
0317     boost::function_requires<
0318       CollectionConcept<IndexList> >();
0319     return super_type::operator()(indices);
0320   }
0321 
0322   const_reference operator[](index idx) const {
0323     return super_type::operator[](idx);
0324   }
0325 
0326   // see generate_array_view in base.hpp
0327   template <int NDims>
0328   typename const_array_view<NDims>::type 
0329   operator[](const boost::detail::multi_array::
0330              index_gen<NumDims,NDims>& indices)
0331     const {
0332     return super_type::operator[](indices);
0333   }
0334 
0335   const_iterator begin() const {
0336     return super_type::begin();
0337   }
0338   
0339   const_iterator end() const {
0340     return super_type::end();
0341   }
0342 
0343   const_reverse_iterator rbegin() const {
0344     return super_type::rbegin();
0345   }
0346 
0347   const_reverse_iterator rend() const {
0348     return super_type::rend();
0349   }
0350 
0351 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
0352 private:
0353   template <typename,std::size_t> friend class value_accessor_n;
0354 #else
0355 public: // should be private
0356 #endif
0357 
0358   sub_array (T* base,
0359             const size_type* extents,
0360             const index* strides,
0361             const index* index_base) :
0362     super_type(base,extents,strides,index_base) {
0363   }
0364 
0365 };
0366 
0367 } // namespace multi_array
0368 } // namespace detail
0369 //
0370 // traits classes to get sub_array types
0371 //
0372 template <typename Array, int N>
0373 class subarray_gen {
0374   typedef typename Array::element element;
0375 public:
0376   typedef boost::detail::multi_array::sub_array<element,N> type;
0377 };
0378 
0379 template <typename Array, int N>
0380 class const_subarray_gen {
0381   typedef typename Array::element element;
0382 public:
0383   typedef boost::detail::multi_array::const_sub_array<element,N> type;  
0384 };
0385 } // namespace boost
0386   
0387 #endif