epoc32/include/stdapis/boost/multi_array/view.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 BOOST_MULTI_ARRAY_VIEW_RG071301_HPP
       
    14 #define BOOST_MULTI_ARRAY_VIEW_RG071301_HPP
       
    15 
       
    16 //
       
    17 // view.hpp - code for creating "views" of array data.
       
    18 //
       
    19 
       
    20 #include "boost/multi_array/base.hpp"
       
    21 #include "boost/multi_array/concept_checks.hpp"
       
    22 #include "boost/multi_array/iterator.hpp"
       
    23 #include "boost/multi_array/storage_order.hpp"
       
    24 #include "boost/multi_array/subarray.hpp"
       
    25 #include "boost/multi_array/algorithm.hpp"
       
    26 #include "boost/type_traits/is_integral.hpp"
       
    27 #include "boost/array.hpp"
       
    28 #include "boost/limits.hpp"
       
    29 #include <algorithm>
       
    30 #include <cstddef>
       
    31 #include <functional>
       
    32 #include <numeric>
       
    33 
       
    34 namespace boost {
       
    35 namespace detail {
       
    36 namespace multi_array {
       
    37 
       
    38 // TPtr = const T* defaulted in base.hpp
       
    39 template <typename T, std::size_t NumDims, typename TPtr>
       
    40 class const_multi_array_view :
       
    41     public boost::detail::multi_array::multi_array_impl_base<T,NumDims>
       
    42 {
       
    43   typedef boost::detail::multi_array::multi_array_impl_base<T,NumDims> super_type;
       
    44 public: 
       
    45   typedef typename super_type::value_type value_type;
       
    46   typedef typename super_type::const_reference const_reference;
       
    47   typedef typename super_type::const_iterator const_iterator;
       
    48   typedef typename super_type::const_reverse_iterator const_reverse_iterator;
       
    49   typedef typename super_type::element element;
       
    50   typedef typename super_type::size_type size_type;
       
    51   typedef typename super_type::difference_type difference_type;
       
    52   typedef typename super_type::index index;
       
    53   typedef typename super_type::extent_range extent_range;
       
    54 
       
    55   // template typedefs
       
    56   template <std::size_t NDims>
       
    57   struct const_array_view {
       
    58     typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
       
    59   };
       
    60 
       
    61   template <std::size_t NDims>
       
    62   struct array_view {
       
    63     typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
       
    64   };
       
    65 
       
    66   template <typename OPtr>
       
    67   const_multi_array_view(const 
       
    68                          const_multi_array_view<T,NumDims,OPtr>& other) :
       
    69     base_(other.base_), origin_offset_(other.origin_offset_),
       
    70     num_elements_(other.num_elements_), extent_list_(other.extent_list_),
       
    71     stride_list_(other.stride_list_), index_base_list_(other.index_base_list_)
       
    72   { }
       
    73 
       
    74 
       
    75   template <class BaseList>
       
    76 #ifdef BOOST_NO_SFINAE
       
    77   void
       
    78 #else
       
    79   typename
       
    80   disable_if<typename boost::is_integral<BaseList>::type,void >::type
       
    81 #endif
       
    82   reindex(const BaseList& values) {
       
    83     boost::function_requires<
       
    84       detail::multi_array::CollectionConcept<BaseList> >();
       
    85     boost::detail::multi_array::
       
    86       copy_n(values.begin(),num_dimensions(),index_base_list_.begin());
       
    87     origin_offset_ =
       
    88       this->calculate_indexing_offset(stride_list_,index_base_list_);
       
    89   }
       
    90 
       
    91   void reindex(index value) {
       
    92     index_base_list_.assign(value);
       
    93     origin_offset_ =
       
    94       this->calculate_indexing_offset(stride_list_,index_base_list_);
       
    95   }
       
    96 
       
    97   size_type num_dimensions() const { return NumDims; }
       
    98 
       
    99   size_type size() const { return extent_list_.front(); }
       
   100   size_type max_size() const { return num_elements(); }
       
   101   bool empty() const { return size() == 0; }
       
   102 
       
   103   const size_type* shape() const {
       
   104     return extent_list_.data();
       
   105   }
       
   106 
       
   107   const index* strides() const {
       
   108     return stride_list_.data();
       
   109   }
       
   110 
       
   111   const T* origin() const { return base_+origin_offset_; }
       
   112 
       
   113   size_type num_elements() const { return num_elements_; }
       
   114 
       
   115   const index* index_bases() const {
       
   116     return index_base_list_.data();
       
   117   }
       
   118 
       
   119   template <typename IndexList>
       
   120   const element& operator()(IndexList indices) const {
       
   121     boost::function_requires<
       
   122       detail::multi_array::CollectionConcept<IndexList> >();
       
   123     return super_type::access_element(boost::type<const element&>(),
       
   124                                       indices,origin(),
       
   125                                       shape(),strides(),index_bases());
       
   126   }
       
   127 
       
   128   // Only allow const element access
       
   129   const_reference operator[](index idx) const {
       
   130     return super_type::access(boost::type<const_reference>(),
       
   131                               idx,origin(),
       
   132                               shape(),strides(),
       
   133                               index_bases());
       
   134   }
       
   135 
       
   136   // see generate_array_view in base.hpp
       
   137 #if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
       
   138   template <int NDims>
       
   139 #else
       
   140   template <int NumDims, int NDims> // else ICE
       
   141 #endif // BOOST_MSVC
       
   142   typename const_array_view<NDims>::type 
       
   143   operator[](const boost::detail::multi_array::
       
   144              index_gen<NumDims,NDims>& indices)
       
   145     const {
       
   146     typedef typename const_array_view<NDims>::type return_type;
       
   147     return
       
   148       super_type::generate_array_view(boost::type<return_type>(),
       
   149                                       indices,
       
   150                                       shape(),
       
   151                                       strides(),
       
   152                                       index_bases(),
       
   153                                       origin());
       
   154   }
       
   155   const_iterator begin() const {
       
   156     return const_iterator(*index_bases(),origin(),
       
   157                           shape(),strides(),index_bases());
       
   158   }
       
   159 
       
   160   const_iterator end() const {
       
   161     return const_iterator(*index_bases()+(index)*shape(),origin(),
       
   162                           shape(),strides(),index_bases());
       
   163   }
       
   164   
       
   165   const_reverse_iterator rbegin() const {
       
   166     return const_reverse_iterator(end());
       
   167   }
       
   168 
       
   169   const_reverse_iterator rend() const {
       
   170     return const_reverse_iterator(begin());
       
   171   }
       
   172 
       
   173 
       
   174   template <typename OPtr>
       
   175   bool operator==(const
       
   176                   const_multi_array_view<T,NumDims,OPtr>& rhs)
       
   177     const {
       
   178     if(std::equal(extent_list_.begin(),
       
   179                   extent_list_.end(),
       
   180                   rhs.extent_list_.begin()))
       
   181       return std::equal(begin(),end(),rhs.begin());
       
   182     else return false;
       
   183   }
       
   184 
       
   185   template <typename OPtr>
       
   186   bool operator<(const
       
   187                  const_multi_array_view<T,NumDims,OPtr>& rhs)
       
   188     const {
       
   189     return std::lexicographical_compare(begin(),end(),rhs.begin(),rhs.end());
       
   190   }
       
   191 
       
   192   template <typename OPtr>
       
   193   bool operator!=(const
       
   194                   const_multi_array_view<T,NumDims,OPtr>& rhs)
       
   195     const {
       
   196     return !(*this == rhs);
       
   197   }
       
   198 
       
   199   template <typename OPtr>
       
   200   bool operator>(const
       
   201                  const_multi_array_view<T,NumDims,OPtr>& rhs)
       
   202     const {
       
   203     return rhs < *this;
       
   204   }
       
   205 
       
   206   template <typename OPtr>
       
   207   bool operator<=(const
       
   208                  const_multi_array_view<T,NumDims,OPtr>& rhs)
       
   209     const {
       
   210     return !(*this > rhs);
       
   211   }
       
   212 
       
   213   template <typename OPtr>
       
   214   bool operator>=(const
       
   215                  const_multi_array_view<T,NumDims,OPtr>& rhs)
       
   216     const {
       
   217     return !(*this < rhs);
       
   218   }
       
   219 
       
   220 
       
   221 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
       
   222 protected:
       
   223   template <typename,std::size_t> friend class multi_array_impl_base;
       
   224   template <typename,std::size_t,typename> friend class const_multi_array_view;
       
   225 #else
       
   226 public: // should be protected
       
   227 #endif
       
   228 
       
   229   // This constructor is used by multi_array_impl_base::generate_array_view
       
   230   // to create strides  
       
   231   template <typename ExtentList, typename Index>
       
   232   explicit const_multi_array_view(TPtr base,
       
   233                            const ExtentList& extents,
       
   234                            const boost::array<Index,NumDims>& strides): 
       
   235     base_(base), origin_offset_(0) {
       
   236 
       
   237     index_base_list_.assign(0);
       
   238 
       
   239     // Get the extents and strides
       
   240     boost::detail::multi_array::
       
   241       copy_n(extents.begin(),NumDims,extent_list_.begin());
       
   242     boost::detail::multi_array::
       
   243       copy_n(strides.begin(),NumDims,stride_list_.begin());
       
   244 
       
   245     // Calculate the array size
       
   246     num_elements_ = std::accumulate(extent_list_.begin(),extent_list_.end(),
       
   247                             size_type(1),std::multiplies<size_type>());
       
   248 #if 0
       
   249     assert(num_elements_ != 0);
       
   250 #endif
       
   251   }
       
   252 
       
   253   typedef boost::array<size_type,NumDims> size_list;
       
   254   typedef boost::array<index,NumDims> index_list;
       
   255 
       
   256   TPtr base_;
       
   257   index origin_offset_;
       
   258   size_type num_elements_;
       
   259   size_list extent_list_;
       
   260   index_list stride_list_;
       
   261   index_list index_base_list_;
       
   262 
       
   263 private:
       
   264   // const_multi_array_view cannot be assigned to (no deep copies!)
       
   265   const_multi_array_view& operator=(const const_multi_array_view& other);
       
   266 };
       
   267 
       
   268 
       
   269 template <typename T, std::size_t NumDims>
       
   270 class multi_array_view :
       
   271   public const_multi_array_view<T,NumDims,T*>
       
   272 {
       
   273   typedef const_multi_array_view<T,NumDims,T*> super_type;
       
   274 public: 
       
   275   typedef typename super_type::value_type value_type;
       
   276   typedef typename super_type::reference reference;
       
   277   typedef typename super_type::iterator iterator;
       
   278   typedef typename super_type::reverse_iterator reverse_iterator;
       
   279   typedef typename super_type::const_reference const_reference;
       
   280   typedef typename super_type::const_iterator const_iterator;
       
   281   typedef typename super_type::const_reverse_iterator const_reverse_iterator;
       
   282   typedef typename super_type::element element;
       
   283   typedef typename super_type::size_type size_type;
       
   284   typedef typename super_type::difference_type difference_type;
       
   285   typedef typename super_type::index index;
       
   286   typedef typename super_type::extent_range extent_range;
       
   287 
       
   288   // template typedefs
       
   289   template <std::size_t NDims>
       
   290   struct const_array_view {
       
   291     typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
       
   292   };
       
   293 
       
   294   template <std::size_t NDims>
       
   295   struct array_view {
       
   296     typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
       
   297   };
       
   298 
       
   299   // Assignment from other ConstMultiArray types.
       
   300   template <typename ConstMultiArray>
       
   301   multi_array_view& operator=(const ConstMultiArray& other) {
       
   302     function_requires< 
       
   303       boost::detail::multi_array::
       
   304       ConstMultiArrayConcept<ConstMultiArray,NumDims> >();
       
   305 
       
   306     // make sure the dimensions agree
       
   307     assert(other.num_dimensions() == this->num_dimensions());
       
   308     assert(std::equal(other.shape(),other.shape()+this->num_dimensions(),
       
   309                       this->shape()));
       
   310     // iterator-based copy
       
   311     std::copy(other.begin(),other.end(),begin());
       
   312     return *this;
       
   313   }
       
   314 
       
   315 
       
   316   multi_array_view& operator=(const multi_array_view& other) {
       
   317     if (&other != this) {
       
   318       // make sure the dimensions agree
       
   319       assert(other.num_dimensions() == this->num_dimensions());
       
   320       assert(std::equal(other.shape(),other.shape()+this->num_dimensions(),
       
   321                         this->shape()));
       
   322       // iterator-based copy
       
   323       std::copy(other.begin(),other.end(),begin());
       
   324     }
       
   325     return *this;
       
   326   }
       
   327 
       
   328   element* origin() { return this->base_+this->origin_offset_; }
       
   329 
       
   330   template <class IndexList>
       
   331   element& operator()(const IndexList& indices) {
       
   332     boost::function_requires<
       
   333       detail::multi_array::CollectionConcept<IndexList> >();
       
   334     return super_type::access_element(boost::type<element&>(),
       
   335                                       indices,origin(),
       
   336                                       this->shape(),this->strides(),
       
   337                                       this->index_bases());
       
   338   }
       
   339 
       
   340 
       
   341   reference operator[](index idx) {
       
   342     return super_type::access(boost::type<reference>(),
       
   343                               idx,origin(),
       
   344                               this->shape(),this->strides(),
       
   345                               this->index_bases());
       
   346   }
       
   347 
       
   348 
       
   349   // see generate_array_view in base.hpp
       
   350 #if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
       
   351   template <int NDims>
       
   352 #else
       
   353   template <int NumDims, int NDims> // else ICE
       
   354 #endif // BOOST_MSVC
       
   355   typename array_view<NDims>::type 
       
   356   operator[](const boost::detail::multi_array::
       
   357              index_gen<NumDims,NDims>& indices) {
       
   358     typedef typename array_view<NDims>::type return_type;
       
   359     return
       
   360       super_type::generate_array_view(boost::type<return_type>(),
       
   361                                       indices,
       
   362                                       this->shape(),
       
   363                                       this->strides(),
       
   364                                       this->index_bases(),
       
   365                                       origin());
       
   366   }
       
   367   
       
   368   
       
   369   iterator begin() {
       
   370     return iterator(*this->index_bases(),origin(),
       
   371                     this->shape(),this->strides(),
       
   372                     this->index_bases());
       
   373   }
       
   374 
       
   375   iterator end() {
       
   376     return iterator(*this->index_bases()+(index)*this->shape(),origin(),
       
   377                     this->shape(),this->strides(),
       
   378                     this->index_bases());
       
   379   }
       
   380 
       
   381   reverse_iterator rbegin() {
       
   382     return reverse_iterator(end());
       
   383   }
       
   384 
       
   385   reverse_iterator rend() {
       
   386     return reverse_iterator(begin());
       
   387   }
       
   388 
       
   389   // Using declarations don't seem to work for g++
       
   390   // These are the proxies to work around this.
       
   391 
       
   392   const element* origin() const { return super_type::origin(); }
       
   393 
       
   394   template <class IndexList>
       
   395   const element& operator()(const IndexList& indices) const {
       
   396     boost::function_requires<
       
   397       detail::multi_array::CollectionConcept<IndexList> >();
       
   398     return super_type::operator()(indices);
       
   399   }
       
   400 
       
   401   const_reference operator[](index idx) const {
       
   402     return super_type::operator[](idx);
       
   403   }
       
   404 
       
   405   // see generate_array_view in base.hpp
       
   406 #if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
       
   407   template <int NDims>
       
   408 #else
       
   409   template <int NumDims, int NDims> // else ICE
       
   410 #endif // BOOST_MSVC
       
   411   typename const_array_view<NDims>::type 
       
   412   operator[](const boost::detail::multi_array::
       
   413              index_gen<NumDims,NDims>& indices)
       
   414     const {
       
   415     return super_type::operator[](indices);
       
   416   }
       
   417   
       
   418   const_iterator begin() const {
       
   419     return super_type::begin();
       
   420   }
       
   421 
       
   422   const_iterator end() const {
       
   423     return super_type::end();
       
   424   }
       
   425 
       
   426   const_reverse_iterator rbegin() const {
       
   427     return super_type::rbegin();
       
   428   }
       
   429 
       
   430   const_reverse_iterator rend() const {
       
   431     return super_type::rend();
       
   432   }
       
   433 
       
   434 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
       
   435 private:
       
   436   template <typename,std::size_t> friend class multi_array_impl_base;
       
   437 #else
       
   438 public: // should be private
       
   439 #endif
       
   440 
       
   441   // constructor used by multi_array_impl_base::generate_array_view to
       
   442   // generate array views
       
   443   template <typename ExtentList, typename Index>
       
   444   explicit multi_array_view(T* base,
       
   445                             const ExtentList& extents,
       
   446                             const boost::array<Index,NumDims>& strides) :
       
   447     super_type(base,extents,strides) { }
       
   448 
       
   449 };
       
   450 
       
   451 } // namespace multi_array
       
   452 } // namespace detail
       
   453 
       
   454 //
       
   455 // traits classes to get array_view types
       
   456 //
       
   457 template <typename Array, int N>
       
   458 class array_view_gen {
       
   459   typedef typename Array::element element;
       
   460 public:
       
   461   typedef boost::detail::multi_array::multi_array_view<element,N> type;
       
   462 };
       
   463 
       
   464 template <typename Array, int N>
       
   465 class const_array_view_gen {
       
   466   typedef typename Array::element element;
       
   467 public:
       
   468   typedef boost::detail::multi_array::const_multi_array_view<element,N> type;  
       
   469 };
       
   470 
       
   471 } // namespace boost
       
   472 
       
   473 #endif // BOOST_MULTI_ARRAY_VIEW_RG071301_HPP
       
   474