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_VIEW_HPP
0014 #define BOOST_MULTI_ARRAY_VIEW_HPP
0015 
0016 //
0017 // view.hpp - code for creating "views" of array data.
0018 //
0019 
0020 #include "boost/multi_array/base.hpp"
0021 #include "boost/multi_array/concept_checks.hpp"
0022 #include "boost/multi_array/iterator.hpp"
0023 #include "boost/multi_array/storage_order.hpp"
0024 #include "boost/multi_array/subarray.hpp"
0025 #include "boost/multi_array/algorithm.hpp"
0026 #include "boost/type_traits/is_integral.hpp"
0027 #include "boost/utility/enable_if.hpp"
0028 #include "boost/array.hpp"
0029 #include "boost/limits.hpp"
0030 #include <algorithm>
0031 #include <cstddef>
0032 #include <functional>
0033 #include <numeric>
0034 
0035 namespace boost {
0036 namespace detail {
0037 namespace multi_array {
0038 
0039 // TPtr = const T* defaulted in base.hpp
0040 template <typename T, std::size_t NumDims, typename TPtr>
0041 class const_multi_array_view :
0042     public boost::detail::multi_array::multi_array_impl_base<T,NumDims>
0043 {
0044   typedef boost::detail::multi_array::multi_array_impl_base<T,NumDims> super_type;
0045 public: 
0046   typedef typename super_type::value_type value_type;
0047   typedef typename super_type::const_reference const_reference;
0048   typedef typename super_type::const_iterator const_iterator;
0049   typedef typename super_type::const_reverse_iterator const_reverse_iterator;
0050   typedef typename super_type::element element;
0051   typedef typename super_type::size_type size_type;
0052   typedef typename super_type::difference_type difference_type;
0053   typedef typename super_type::index index;
0054   typedef typename super_type::extent_range extent_range;
0055 
0056   // template typedefs
0057   template <std::size_t NDims>
0058   struct const_array_view {
0059     typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
0060   };
0061 
0062   template <std::size_t NDims>
0063   struct array_view {
0064     typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
0065   };
0066 
0067   template <typename OPtr>
0068   const_multi_array_view(const 
0069                          const_multi_array_view<T,NumDims,OPtr>& other) :
0070     base_(other.base_), origin_offset_(other.origin_offset_),
0071     num_elements_(other.num_elements_), extent_list_(other.extent_list_),
0072     stride_list_(other.stride_list_), index_base_list_(other.index_base_list_)
0073   { }
0074 
0075 
0076   template <class BaseList>
0077 #ifdef BOOST_NO_SFINAE
0078   void
0079 #else
0080   typename
0081   disable_if<typename boost::is_integral<BaseList>::type,void >::type
0082 #endif
0083   reindex(const BaseList& values) {
0084     boost::function_requires<
0085       CollectionConcept<BaseList> >();
0086     boost::detail::multi_array::
0087       copy_n(values.begin(),num_dimensions(),index_base_list_.begin());
0088     origin_offset_ =
0089       this->calculate_indexing_offset(stride_list_,index_base_list_);
0090   }
0091 
0092   void reindex(index value) {
0093     index_base_list_.assign(value);
0094     origin_offset_ =
0095       this->calculate_indexing_offset(stride_list_,index_base_list_);
0096   }
0097 
0098   size_type num_dimensions() const { return NumDims; }
0099 
0100   size_type size() const { return extent_list_.front(); }
0101   size_type max_size() const { return num_elements(); }
0102   bool empty() const { return size() == 0; }
0103 
0104   const size_type* shape() const {
0105     return extent_list_.data();
0106   }
0107 
0108   const index* strides() const {
0109     return stride_list_.data();
0110   }
0111 
0112   const T* origin() const { return base_+origin_offset_; }
0113 
0114   size_type num_elements() const { return num_elements_; }
0115 
0116   const index* index_bases() const {
0117     return index_base_list_.data();
0118   }
0119 
0120   template <typename IndexList>
0121   const element& operator()(IndexList indices) const {
0122     boost::function_requires<
0123       CollectionConcept<IndexList> >();
0124     return super_type::access_element(boost::type<const element&>(),
0125                                       indices,origin(),
0126                                       shape(),strides(),index_bases());
0127   }
0128 
0129   // Only allow const element access
0130   const_reference operator[](index idx) const {
0131     return super_type::access(boost::type<const_reference>(),
0132                               idx,origin(),
0133                               shape(),strides(),
0134                               index_bases());
0135   }
0136 
0137   // see generate_array_view in base.hpp
0138   template <int NDims>
0139   typename const_array_view<NDims>::type 
0140   operator[](const boost::detail::multi_array::
0141              index_gen<NumDims,NDims>& indices)
0142     const {
0143     typedef typename const_array_view<NDims>::type return_type;
0144     return
0145       super_type::generate_array_view(boost::type<return_type>(),
0146                                       indices,
0147                                       shape(),
0148                                       strides(),
0149                                       index_bases(),
0150                                       origin());
0151   }
0152   const_iterator begin() const {
0153     return const_iterator(*index_bases(),origin(),
0154                           shape(),strides(),index_bases());
0155   }
0156 
0157   const_iterator end() const {
0158     return const_iterator(*index_bases()+(index)*shape(),origin(),
0159                           shape(),strides(),index_bases());
0160   }
0161   
0162   const_reverse_iterator rbegin() const {
0163     return const_reverse_iterator(end());
0164   }
0165 
0166   const_reverse_iterator rend() const {
0167     return const_reverse_iterator(begin());
0168   }
0169 
0170 
0171   template <typename OPtr>
0172   bool operator==(const
0173                   const_multi_array_view<T,NumDims,OPtr>& rhs)
0174     const {
0175     if(std::equal(extent_list_.begin(),
0176                   extent_list_.end(),
0177                   rhs.extent_list_.begin()))
0178       return std::equal(begin(),end(),rhs.begin());
0179     else return false;
0180   }
0181 
0182   template <typename OPtr>
0183   bool operator<(const
0184                  const_multi_array_view<T,NumDims,OPtr>& rhs)
0185     const {
0186     return std::lexicographical_compare(begin(),end(),rhs.begin(),rhs.end());
0187   }
0188 
0189   template <typename OPtr>
0190   bool operator!=(const
0191                   const_multi_array_view<T,NumDims,OPtr>& rhs)
0192     const {
0193     return !(*this == rhs);
0194   }
0195 
0196   template <typename OPtr>
0197   bool operator>(const
0198                  const_multi_array_view<T,NumDims,OPtr>& rhs)
0199     const {
0200     return rhs < *this;
0201   }
0202 
0203   template <typename OPtr>
0204   bool operator<=(const
0205                  const_multi_array_view<T,NumDims,OPtr>& rhs)
0206     const {
0207     return !(*this > rhs);
0208   }
0209 
0210   template <typename OPtr>
0211   bool operator>=(const
0212                  const_multi_array_view<T,NumDims,OPtr>& rhs)
0213     const {
0214     return !(*this < rhs);
0215   }
0216 
0217 
0218 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
0219 protected:
0220   template <typename,std::size_t> friend class multi_array_impl_base;
0221   template <typename,std::size_t,typename> friend class const_multi_array_view;
0222 #else
0223 public: // should be protected
0224 #endif
0225 
0226   // This constructor is used by multi_array_impl_base::generate_array_view
0227   // to create strides  
0228   template <typename ExtentList, typename Index>
0229   explicit const_multi_array_view(TPtr base,
0230                            const ExtentList& extents,
0231                            const boost::array<Index,NumDims>& strides): 
0232     base_(base), origin_offset_(0) {
0233 
0234     index_base_list_.assign(0);
0235 
0236     // Get the extents and strides
0237     boost::detail::multi_array::
0238       copy_n(extents.begin(),NumDims,extent_list_.begin());
0239     boost::detail::multi_array::
0240       copy_n(strides.begin(),NumDims,stride_list_.begin());
0241 
0242     // Calculate the array size
0243     num_elements_ = std::accumulate(extent_list_.begin(),extent_list_.end(),
0244                                     size_type(1),std::multiplies<size_type>());
0245   }
0246 
0247   typedef boost::array<size_type,NumDims> size_list;
0248   typedef boost::array<index,NumDims> index_list;
0249 
0250   TPtr base_;
0251   index origin_offset_;
0252   size_type num_elements_;
0253   size_list extent_list_;
0254   index_list stride_list_;
0255   index_list index_base_list_;
0256 
0257 private:
0258   // const_multi_array_view cannot be assigned to (no deep copies!)
0259   const_multi_array_view& operator=(const const_multi_array_view& other);
0260 };
0261 
0262 
0263 template <typename T, std::size_t NumDims>
0264 class multi_array_view :
0265   public const_multi_array_view<T,NumDims,T*>
0266 {
0267   typedef const_multi_array_view<T,NumDims,T*> super_type;
0268 public: 
0269   typedef typename super_type::value_type value_type;
0270   typedef typename super_type::reference reference;
0271   typedef typename super_type::iterator iterator;
0272   typedef typename super_type::reverse_iterator reverse_iterator;
0273   typedef typename super_type::const_reference const_reference;
0274   typedef typename super_type::const_iterator const_iterator;
0275   typedef typename super_type::const_reverse_iterator const_reverse_iterator;
0276   typedef typename super_type::element element;
0277   typedef typename super_type::size_type size_type;
0278   typedef typename super_type::difference_type difference_type;
0279   typedef typename super_type::index index;
0280   typedef typename super_type::extent_range extent_range;
0281 
0282   // template typedefs
0283   template <std::size_t NDims>
0284   struct const_array_view {
0285     typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
0286   };
0287 
0288   template <std::size_t NDims>
0289   struct array_view {
0290     typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
0291   };
0292 
0293   // Assignment from other ConstMultiArray types.
0294   template <typename ConstMultiArray>
0295   multi_array_view& operator=(const ConstMultiArray& other) {
0296     function_requires< 
0297       boost::multi_array_concepts::
0298       ConstMultiArrayConcept<ConstMultiArray,NumDims> >();
0299 
0300     // make sure the dimensions agree
0301     BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
0302     BOOST_ASSERT(std::equal(other.shape(),other.shape()+this->num_dimensions(),
0303                             this->shape()));
0304     // iterator-based copy
0305     std::copy(other.begin(),other.end(),begin());
0306     return *this;
0307   }
0308 
0309 
0310   multi_array_view& operator=(const multi_array_view& other) {
0311     if (&other != this) {
0312       // make sure the dimensions agree
0313       BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
0314       BOOST_ASSERT(std::equal(other.shape(),
0315                               other.shape()+this->num_dimensions(),
0316                               this->shape()));
0317       // iterator-based copy
0318       std::copy(other.begin(),other.end(),begin());
0319     }
0320     return *this;
0321   }
0322 
0323   element* origin() { return this->base_+this->origin_offset_; }
0324 
0325   template <class IndexList>
0326   element& operator()(const IndexList& indices) {
0327     boost::function_requires<
0328       CollectionConcept<IndexList> >();
0329     return super_type::access_element(boost::type<element&>(),
0330                                       indices,origin(),
0331                                       this->shape(),this->strides(),
0332                                       this->index_bases());
0333   }
0334 
0335 
0336   reference operator[](index idx) {
0337     return super_type::access(boost::type<reference>(),
0338                               idx,origin(),
0339                               this->shape(),this->strides(),
0340                               this->index_bases());
0341   }
0342 
0343 
0344   // see generate_array_view in base.hpp
0345   template <int NDims>
0346   typename array_view<NDims>::type 
0347   operator[](const boost::detail::multi_array::
0348              index_gen<NumDims,NDims>& indices) {
0349     typedef typename array_view<NDims>::type return_type;
0350     return
0351       super_type::generate_array_view(boost::type<return_type>(),
0352                                       indices,
0353                                       this->shape(),
0354                                       this->strides(),
0355                                       this->index_bases(),
0356                                       origin());
0357   }
0358   
0359   
0360   iterator begin() {
0361     return iterator(*this->index_bases(),origin(),
0362                     this->shape(),this->strides(),
0363                     this->index_bases());
0364   }
0365 
0366   iterator end() {
0367     return iterator(*this->index_bases()+(index)*this->shape(),origin(),
0368                     this->shape(),this->strides(),
0369                     this->index_bases());
0370   }
0371 
0372   reverse_iterator rbegin() {
0373     return reverse_iterator(end());
0374   }
0375 
0376   reverse_iterator rend() {
0377     return reverse_iterator(begin());
0378   }
0379 
0380   // Using declarations don't seem to work for g++
0381   // These are the proxies to work around this.
0382 
0383   const element* origin() const { return super_type::origin(); }
0384 
0385   template <class IndexList>
0386   const element& operator()(const IndexList& indices) const {
0387     boost::function_requires<
0388       CollectionConcept<IndexList> >();
0389     return super_type::operator()(indices);
0390   }
0391 
0392   const_reference operator[](index idx) const {
0393     return super_type::operator[](idx);
0394   }
0395 
0396   // see generate_array_view in base.hpp
0397   template <int NDims>
0398   typename const_array_view<NDims>::type 
0399   operator[](const boost::detail::multi_array::
0400              index_gen<NumDims,NDims>& indices)
0401     const {
0402     return super_type::operator[](indices);
0403   }
0404   
0405   const_iterator begin() const {
0406     return super_type::begin();
0407   }
0408 
0409   const_iterator end() const {
0410     return super_type::end();
0411   }
0412 
0413   const_reverse_iterator rbegin() const {
0414     return super_type::rbegin();
0415   }
0416 
0417   const_reverse_iterator rend() const {
0418     return super_type::rend();
0419   }
0420 
0421 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
0422 private:
0423   template <typename,std::size_t> friend class multi_array_impl_base;
0424 #else
0425 public: // should be private
0426 #endif
0427 
0428   // constructor used by multi_array_impl_base::generate_array_view to
0429   // generate array views
0430   template <typename ExtentList, typename Index>
0431   explicit multi_array_view(T* base,
0432                             const ExtentList& extents,
0433                             const boost::array<Index,NumDims>& strides) :
0434     super_type(base,extents,strides) { }
0435 
0436 };
0437 
0438 } // namespace multi_array
0439 } // namespace detail
0440 
0441 //
0442 // traits classes to get array_view types
0443 //
0444 template <typename Array, int N>
0445 class array_view_gen {
0446   typedef typename Array::element element;
0447 public:
0448   typedef boost::detail::multi_array::multi_array_view<element,N> type;
0449 };
0450 
0451 template <typename Array, int N>
0452 class const_array_view_gen {
0453   typedef typename Array::element element;
0454 public:
0455   typedef boost::detail::multi_array::const_multi_array_view<element,N> type;  
0456 };
0457 
0458 } // namespace boost
0459 
0460 #endif