Update contrib.
1 // Copyright 2002 The Trustees of Indiana University.
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)
7 // Boost.MultiArray Library
8 // Authors: Ronald Garcia
11 // See http://www.boost.org/libs/multi_array for documentation.
13 #ifndef BOOST_MULTI_ARRAY_VIEW_RG071301_HPP
14 #define BOOST_MULTI_ARRAY_VIEW_RG071301_HPP
17 // view.hpp - code for creating "views" of array data.
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"
36 namespace multi_array {
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>
43 typedef boost::detail::multi_array::multi_array_impl_base<T,NumDims> super_type;
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;
56 template <std::size_t NDims>
57 struct const_array_view {
58 typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
61 template <std::size_t NDims>
63 typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
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_)
75 template <class BaseList>
76 #ifdef BOOST_NO_SFINAE
80 disable_if<typename boost::is_integral<BaseList>::type,void >::type
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());
88 this->calculate_indexing_offset(stride_list_,index_base_list_);
91 void reindex(index value) {
92 index_base_list_.assign(value);
94 this->calculate_indexing_offset(stride_list_,index_base_list_);
97 size_type num_dimensions() const { return NumDims; }
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; }
103 const size_type* shape() const {
104 return extent_list_.data();
107 const index* strides() const {
108 return stride_list_.data();
111 const T* origin() const { return base_+origin_offset_; }
113 size_type num_elements() const { return num_elements_; }
115 const index* index_bases() const {
116 return index_base_list_.data();
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&>(),
125 shape(),strides(),index_bases());
128 // Only allow const element access
129 const_reference operator[](index idx) const {
130 return super_type::access(boost::type<const_reference>(),
136 // see generate_array_view in base.hpp
137 #if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
140 template <int NumDims, int NDims> // else ICE
142 typename const_array_view<NDims>::type
143 operator[](const boost::detail::multi_array::
144 index_gen<NumDims,NDims>& indices)
146 typedef typename const_array_view<NDims>::type return_type;
148 super_type::generate_array_view(boost::type<return_type>(),
155 const_iterator begin() const {
156 return const_iterator(*index_bases(),origin(),
157 shape(),strides(),index_bases());
160 const_iterator end() const {
161 return const_iterator(*index_bases()+(index)*shape(),origin(),
162 shape(),strides(),index_bases());
165 const_reverse_iterator rbegin() const {
166 return const_reverse_iterator(end());
169 const_reverse_iterator rend() const {
170 return const_reverse_iterator(begin());
174 template <typename OPtr>
175 bool operator==(const
176 const_multi_array_view<T,NumDims,OPtr>& rhs)
178 if(std::equal(extent_list_.begin(),
180 rhs.extent_list_.begin()))
181 return std::equal(begin(),end(),rhs.begin());
185 template <typename OPtr>
187 const_multi_array_view<T,NumDims,OPtr>& rhs)
189 return std::lexicographical_compare(begin(),end(),rhs.begin(),rhs.end());
192 template <typename OPtr>
193 bool operator!=(const
194 const_multi_array_view<T,NumDims,OPtr>& rhs)
196 return !(*this == rhs);
199 template <typename OPtr>
201 const_multi_array_view<T,NumDims,OPtr>& rhs)
206 template <typename OPtr>
207 bool operator<=(const
208 const_multi_array_view<T,NumDims,OPtr>& rhs)
210 return !(*this > rhs);
213 template <typename OPtr>
214 bool operator>=(const
215 const_multi_array_view<T,NumDims,OPtr>& rhs)
217 return !(*this < rhs);
221 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
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;
226 public: // should be protected
229 // This constructor is used by multi_array_impl_base::generate_array_view
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) {
237 index_base_list_.assign(0);
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());
245 // Calculate the array size
246 num_elements_ = std::accumulate(extent_list_.begin(),extent_list_.end(),
247 size_type(1),std::multiplies<size_type>());
249 assert(num_elements_ != 0);
253 typedef boost::array<size_type,NumDims> size_list;
254 typedef boost::array<index,NumDims> index_list;
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_;
264 // const_multi_array_view cannot be assigned to (no deep copies!)
265 const_multi_array_view& operator=(const const_multi_array_view& other);
269 template <typename T, std::size_t NumDims>
270 class multi_array_view :
271 public const_multi_array_view<T,NumDims,T*>
273 typedef const_multi_array_view<T,NumDims,T*> super_type;
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;
289 template <std::size_t NDims>
290 struct const_array_view {
291 typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
294 template <std::size_t NDims>
296 typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
299 // Assignment from other ConstMultiArray types.
300 template <typename ConstMultiArray>
301 multi_array_view& operator=(const ConstMultiArray& other) {
303 boost::detail::multi_array::
304 ConstMultiArrayConcept<ConstMultiArray,NumDims> >();
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(),
310 // iterator-based copy
311 std::copy(other.begin(),other.end(),begin());
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(),
322 // iterator-based copy
323 std::copy(other.begin(),other.end(),begin());
328 element* origin() { return this->base_+this->origin_offset_; }
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&>(),
336 this->shape(),this->strides(),
337 this->index_bases());
341 reference operator[](index idx) {
342 return super_type::access(boost::type<reference>(),
344 this->shape(),this->strides(),
345 this->index_bases());
349 // see generate_array_view in base.hpp
350 #if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
353 template <int NumDims, int NDims> // else ICE
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;
360 super_type::generate_array_view(boost::type<return_type>(),
370 return iterator(*this->index_bases(),origin(),
371 this->shape(),this->strides(),
372 this->index_bases());
376 return iterator(*this->index_bases()+(index)*this->shape(),origin(),
377 this->shape(),this->strides(),
378 this->index_bases());
381 reverse_iterator rbegin() {
382 return reverse_iterator(end());
385 reverse_iterator rend() {
386 return reverse_iterator(begin());
389 // Using declarations don't seem to work for g++
390 // These are the proxies to work around this.
392 const element* origin() const { return super_type::origin(); }
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);
401 const_reference operator[](index idx) const {
402 return super_type::operator[](idx);
405 // see generate_array_view in base.hpp
406 #if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
409 template <int NumDims, int NDims> // else ICE
411 typename const_array_view<NDims>::type
412 operator[](const boost::detail::multi_array::
413 index_gen<NumDims,NDims>& indices)
415 return super_type::operator[](indices);
418 const_iterator begin() const {
419 return super_type::begin();
422 const_iterator end() const {
423 return super_type::end();
426 const_reverse_iterator rbegin() const {
427 return super_type::rbegin();
430 const_reverse_iterator rend() const {
431 return super_type::rend();
434 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
436 template <typename,std::size_t> friend class multi_array_impl_base;
438 public: // should be private
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) { }
451 } // namespace multi_array
452 } // namespace detail
455 // traits classes to get array_view types
457 template <typename Array, int N>
458 class array_view_gen {
459 typedef typename Array::element element;
461 typedef boost::detail::multi_array::multi_array_view<element,N> type;
464 template <typename Array, int N>
465 class const_array_view_gen {
466 typedef typename Array::element element;
468 typedef boost::detail::multi_array::const_multi_array_view<element,N> type;
473 #endif // BOOST_MULTI_ARRAY_VIEW_RG071301_HPP