epoc32/include/stdapis/boost/multi_array/subarray.hpp
author William Roberts <williamr@symbian.org>
Tue, 16 Mar 2010 16:12:26 +0000
branchSymbian2
changeset 2 2fe1408b6811
permissions -rw-r--r--
Final list of Symbian^2 public API header files
     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