epoc32/include/stdapis/boost/multi_array/subarray.hpp
branchSymbian2
changeset 2 2fe1408b6811
equal deleted inserted replaced
1:666f914201fb 2:2fe1408b6811
       
     1 // Copyright 2002 The Trustees of Indiana University.
       
     2 
       
     3 // Use, modification and distribution is subject to the Boost Software 
       
     4 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
       
     5 // http://www.boost.org/LICENSE_1_0.txt)
       
     6 
       
     7 //  Boost.MultiArray Library
       
     8 //  Authors: Ronald Garcia
       
     9 //           Jeremy Siek
       
    10 //           Andrew Lumsdaine
       
    11 //  See http://www.boost.org/libs/multi_array for documentation.
       
    12 
       
    13 #ifndef SUBARRAY_RG071801_HPP
       
    14 #define SUBARRAY_RG071801_HPP
       
    15 
       
    16 //
       
    17 // subarray.hpp - used to implement standard operator[] on
       
    18 // multi_arrays
       
    19 //
       
    20 
       
    21 #include "boost/multi_array/base.hpp"
       
    22 #include "boost/multi_array/concept_checks.hpp"
       
    23 #include "boost/limits.hpp"
       
    24 #include "boost/type.hpp"
       
    25 #include <algorithm>
       
    26 #include <cstddef>
       
    27 #include <functional>
       
    28 
       
    29 namespace boost {
       
    30 namespace detail {
       
    31 namespace multi_array {
       
    32 
       
    33 //
       
    34 // const_sub_array
       
    35 //    multi_array's proxy class to allow multiple overloads of
       
    36 //    operator[] in order to provide a clean multi-dimensional array 
       
    37 //    interface.
       
    38 template <typename T, std::size_t NumDims, typename TPtr>
       
    39 class const_sub_array :
       
    40   public boost::detail::multi_array::multi_array_impl_base<T,NumDims>
       
    41 {
       
    42   typedef boost::detail::multi_array::multi_array_impl_base<T,NumDims> super_type;
       
    43 public: 
       
    44   typedef typename super_type::value_type value_type;
       
    45   typedef typename super_type::const_reference const_reference;
       
    46   typedef typename super_type::const_iterator const_iterator;
       
    47   typedef typename super_type::const_reverse_iterator const_reverse_iterator;
       
    48   typedef typename super_type::element element;
       
    49   typedef typename super_type::size_type size_type;
       
    50   typedef typename super_type::difference_type difference_type;
       
    51   typedef typename super_type::index index;
       
    52   typedef typename super_type::extent_range extent_range;
       
    53 
       
    54   // template typedefs
       
    55   template <std::size_t NDims>
       
    56   struct const_array_view {
       
    57     typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
       
    58   };
       
    59 
       
    60   template <std::size_t NDims>
       
    61   struct array_view {
       
    62     typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
       
    63   };
       
    64 
       
    65   // Allow default copy constructor as well.
       
    66 
       
    67   template <typename OPtr>
       
    68   const_sub_array (const const_sub_array<T,NumDims,OPtr>& rhs) :
       
    69     base_(rhs.base_), extents_(rhs.extents_), strides_(rhs.strides_),
       
    70     index_base_(rhs.index_base_) {
       
    71   }
       
    72 
       
    73   // const_sub_array always returns const types, regardless of its own
       
    74   // constness.
       
    75   const_reference operator[](index idx) const {
       
    76     return super_type::access(boost::type<const_reference>(),
       
    77                               idx,base_,shape(),strides(),index_bases());
       
    78   }
       
    79   
       
    80   template <typename IndexList>
       
    81   const element& operator()(const IndexList& indices) const {
       
    82     boost::function_requires<
       
    83       detail::multi_array::CollectionConcept<IndexList> >();
       
    84     return super_type::access_element(boost::type<const element&>(),
       
    85                                       indices,origin(),
       
    86                                       shape(),strides(),index_bases());
       
    87   }
       
    88 
       
    89   // see generate_array_view in base.hpp
       
    90 #if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
       
    91   template <int NDims>
       
    92 #else
       
    93   template <int NumDims, int NDims> // else ICE
       
    94 #endif // BOOST_MSVC
       
    95   typename const_array_view<NDims>::type 
       
    96   operator[](const boost::detail::multi_array::
       
    97              index_gen<NumDims,NDims>& indices)
       
    98     const {
       
    99     typedef typename const_array_view<NDims>::type return_type;
       
   100     return
       
   101       super_type::generate_array_view(boost::type<return_type>(),
       
   102                                       indices,
       
   103                                       shape(),
       
   104                                       strides(),
       
   105                                       index_bases(),
       
   106                                       base_);
       
   107   }
       
   108 
       
   109   template <typename OPtr>
       
   110   bool operator<(const const_sub_array<T,NumDims,OPtr>& rhs) const {
       
   111     return std::lexicographical_compare(begin(),end(),rhs.begin(),rhs.end());
       
   112   }
       
   113 
       
   114   template <typename OPtr>
       
   115   bool operator==(const const_sub_array<T,NumDims,OPtr>& rhs) const {
       
   116     if(std::equal(shape(),shape()+num_dimensions(),rhs.shape()))
       
   117       return std::equal(begin(),end(),rhs.begin());
       
   118     else return false;
       
   119   }
       
   120 
       
   121   template <typename OPtr>
       
   122   bool operator!=(const const_sub_array<T,NumDims,OPtr>& rhs) const {
       
   123     return !(*this == rhs);
       
   124   }
       
   125 
       
   126   template <typename OPtr>
       
   127   bool operator>(const const_sub_array<T,NumDims,OPtr>& rhs) const {
       
   128     return rhs < *this;
       
   129   }
       
   130 
       
   131   template <typename OPtr>
       
   132   bool operator<=(const const_sub_array<T,NumDims,OPtr>& rhs) const {
       
   133     return !(*this > rhs);
       
   134   }
       
   135 
       
   136   template <typename OPtr>
       
   137   bool operator>=(const const_sub_array<T,NumDims,OPtr>& rhs) const {
       
   138     return !(*this < rhs);
       
   139   }
       
   140 
       
   141   const_iterator begin() const {
       
   142     return const_iterator(*index_bases(),origin(),
       
   143                           shape(),strides(),index_bases());
       
   144   }
       
   145 
       
   146   const_iterator end() const {
       
   147     return const_iterator(*index_bases()+(index)*shape(),origin(),
       
   148                           shape(),strides(),index_bases());
       
   149   }
       
   150 
       
   151   const_reverse_iterator rbegin() const {
       
   152     return const_reverse_iterator(end());
       
   153   }
       
   154 
       
   155   const_reverse_iterator rend() const {
       
   156     return const_reverse_iterator(begin());
       
   157   }
       
   158 
       
   159   TPtr origin() const { return base_; }
       
   160   size_type size() const { return extents_[0]; }
       
   161   size_type max_size() const { return num_elements(); }
       
   162   bool empty() const { return size() == 0; }
       
   163   size_type num_dimensions() const { return NumDims; }
       
   164   const size_type*  shape() const { return extents_; }
       
   165   const index* strides() const { return strides_; }
       
   166   const index* index_bases() const { return index_base_; }
       
   167 
       
   168   size_type num_elements() const { 
       
   169     return std::accumulate(shape(),shape() + num_dimensions(),
       
   170                            size_type(1), std::multiplies<size_type>());
       
   171   }
       
   172 
       
   173 
       
   174 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
       
   175 protected:
       
   176   template <typename,std::size_t> friend class value_accessor_n;  
       
   177   template <typename,std::size_t,typename> friend class const_sub_array;
       
   178 #else    
       
   179 public:  // Should be protected
       
   180 #endif
       
   181 
       
   182   const_sub_array (TPtr base,
       
   183                  const size_type* extents,
       
   184                  const index* strides,
       
   185                  const index* index_base) :
       
   186     base_(base), extents_(extents), strides_(strides),
       
   187     index_base_(index_base) {
       
   188   }
       
   189 
       
   190   TPtr base_;
       
   191   const size_type* extents_;
       
   192   const index* strides_;
       
   193   const index* index_base_;
       
   194 private:
       
   195   // const_sub_array cannot be assigned to (no deep copies!)
       
   196   const_sub_array& operator=(const const_sub_array&);
       
   197 };
       
   198 
       
   199 
       
   200 //
       
   201 // sub_array
       
   202 //    multi_array's proxy class to allow multiple overloads of
       
   203 //    operator[] in order to provide a clean multi-dimensional array 
       
   204 //    interface.
       
   205 template <typename T, std::size_t NumDims>
       
   206 class sub_array : public const_sub_array<T,NumDims,T*>
       
   207 {
       
   208   typedef const_sub_array<T,NumDims,T*> super_type;
       
   209 public: 
       
   210   typedef typename super_type::element element;
       
   211   typedef typename super_type::reference reference;
       
   212   typedef typename super_type::index index;
       
   213   typedef typename super_type::size_type size_type;
       
   214   typedef typename super_type::iterator iterator;
       
   215   typedef typename super_type::reverse_iterator reverse_iterator;
       
   216   typedef typename super_type::const_reference const_reference;
       
   217   typedef typename super_type::const_iterator const_iterator;
       
   218   typedef typename super_type::const_reverse_iterator const_reverse_iterator;
       
   219 
       
   220   // template typedefs
       
   221   template <std::size_t NDims>
       
   222   struct const_array_view {
       
   223     typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
       
   224   };
       
   225 
       
   226   template <std::size_t NDims>
       
   227   struct array_view {
       
   228     typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
       
   229   };
       
   230 
       
   231   // Assignment from other ConstMultiArray types.
       
   232   template <typename ConstMultiArray>
       
   233   sub_array& operator=(const ConstMultiArray& other) {
       
   234     function_requires< boost::detail::multi_array::ConstMultiArrayConcept< 
       
   235         ConstMultiArray, NumDims> >();
       
   236 
       
   237     // make sure the dimensions agree
       
   238     assert(other.num_dimensions() == this->num_dimensions());
       
   239     assert(std::equal(other.shape(),other.shape()+this->num_dimensions(),
       
   240                       this->shape()));
       
   241     // iterator-based copy
       
   242     std::copy(other.begin(),other.end(),begin());
       
   243     return *this;
       
   244   }
       
   245 
       
   246 
       
   247   sub_array& operator=(const sub_array& other) {
       
   248     if (&other != this) {
       
   249       // make sure the dimensions agree
       
   250       assert(other.num_dimensions() == this->num_dimensions());
       
   251       assert(std::equal(other.shape(),other.shape()+this->num_dimensions(),
       
   252                         this->shape()));
       
   253       // iterator-based copy
       
   254       std::copy(other.begin(),other.end(),begin());
       
   255     }
       
   256     return *this;
       
   257   }
       
   258 
       
   259   T* origin() { return this->base_; }
       
   260   const T* origin() const { return this->base_; }
       
   261 
       
   262   reference operator[](index idx) {
       
   263     return super_type::access(boost::type<reference>(),
       
   264                               idx,this->base_,this->shape(),this->strides(),
       
   265                               this->index_bases());
       
   266   }
       
   267 
       
   268   // see generate_array_view in base.hpp
       
   269 #if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
       
   270   template <int NDims>
       
   271 #else
       
   272   template <int NumDims, int NDims> // else ICE
       
   273 #endif // BOOST_MSVC
       
   274   typename array_view<NDims>::type 
       
   275   operator[](const boost::detail::multi_array::
       
   276              index_gen<NumDims,NDims>& indices) {
       
   277     typedef typename array_view<NDims>::type return_type;
       
   278     return
       
   279       super_type::generate_array_view(boost::type<return_type>(),
       
   280                                       indices,
       
   281                                       this->shape(),
       
   282                                       this->strides(),
       
   283                                       this->index_bases(),
       
   284                                       origin());
       
   285   }
       
   286 
       
   287   template <class IndexList>
       
   288   element& operator()(const IndexList& indices) {
       
   289     boost::function_requires<
       
   290       detail::multi_array::CollectionConcept<IndexList> >();
       
   291     return super_type::access_element(boost::type<element&>(),
       
   292                                       indices,origin(),
       
   293                                       this->shape(),this->strides(),
       
   294                                       this->index_bases());
       
   295   }
       
   296 
       
   297   iterator begin() {
       
   298     return iterator(*this->index_bases(),origin(),
       
   299                     this->shape(),this->strides(),this->index_bases());
       
   300   }
       
   301 
       
   302   iterator end() {
       
   303     return iterator(*this->index_bases()+(index)*this->shape(),origin(),
       
   304                     this->shape(),this->strides(),this->index_bases());
       
   305   }
       
   306 
       
   307   // RG - rbegin() and rend() written naively to thwart MSVC ICE.
       
   308   reverse_iterator rbegin() {
       
   309     reverse_iterator ri(end());
       
   310     return ri;
       
   311   }
       
   312 
       
   313   reverse_iterator rend() {
       
   314     reverse_iterator ri(begin());
       
   315     return ri;
       
   316   }
       
   317 
       
   318   //
       
   319   // proxies
       
   320   //
       
   321 
       
   322   template <class IndexList>
       
   323   const element& operator()(const IndexList& indices) const {
       
   324     boost::function_requires<
       
   325       detail::multi_array::CollectionConcept<IndexList> >();
       
   326     return super_type::operator()(indices);
       
   327   }
       
   328 
       
   329   const_reference operator[](index idx) const {
       
   330     return super_type::operator[](idx);
       
   331   }
       
   332 
       
   333   // see generate_array_view in base.hpp
       
   334 #if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
       
   335   template <int NDims>
       
   336 #else
       
   337   template <int NumDims, int NDims> // else ICE
       
   338 #endif // BOOST_MSVC
       
   339   typename const_array_view<NDims>::type 
       
   340   operator[](const boost::detail::multi_array::
       
   341              index_gen<NumDims,NDims>& indices)
       
   342     const {
       
   343     return super_type::operator[](indices);
       
   344   }
       
   345 
       
   346   const_iterator begin() const {
       
   347     return super_type::begin();
       
   348   }
       
   349   
       
   350   const_iterator end() const {
       
   351     return super_type::end();
       
   352   }
       
   353 
       
   354   const_reverse_iterator rbegin() const {
       
   355     return super_type::rbegin();
       
   356   }
       
   357 
       
   358   const_reverse_iterator rend() const {
       
   359     return super_type::rend();
       
   360   }
       
   361 
       
   362 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
       
   363 private:
       
   364   template <typename,std::size_t> friend class value_accessor_n;
       
   365 #else
       
   366 public: // should be private
       
   367 #endif
       
   368 
       
   369   sub_array (T* base,
       
   370             const size_type* extents,
       
   371             const index* strides,
       
   372             const index* index_base) :
       
   373     super_type(base,extents,strides,index_base) {
       
   374   }
       
   375 
       
   376 };
       
   377 
       
   378 } // namespace multi_array
       
   379 } // namespace detail
       
   380 //
       
   381 // traits classes to get sub_array types
       
   382 //
       
   383 template <typename Array, int N>
       
   384 class subarray_gen {
       
   385   typedef typename Array::element element;
       
   386 public:
       
   387   typedef boost::detail::multi_array::sub_array<element,N> type;
       
   388 };
       
   389 
       
   390 template <typename Array, int N>
       
   391 class const_subarray_gen {
       
   392   typedef typename Array::element element;
       
   393 public:
       
   394   typedef boost::detail::multi_array::const_sub_array<element,N> type;  
       
   395 };
       
   396 } // namespace boost
       
   397   
       
   398 #endif // SUBARRAY_RG071801_HPP