epoc32/include/stdapis/boost/multi_array/view.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 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