Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/boost/multi_array/view.hpp @ 35

Last change on this file since 35 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

File size: 14.3 KB
Line 
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
34namespace boost {
35namespace detail {
36namespace multi_array {
37
38// TPtr = const T* defaulted in base.hpp
39template <typename T, std::size_t NumDims, typename TPtr>
40class 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;
44public: 
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
222protected:
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
226public: // 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
263private:
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
269template <typename T, std::size_t NumDims>
270class multi_array_view :
271  public const_multi_array_view<T,NumDims,T*>
272{
273  typedef const_multi_array_view<T,NumDims,T*> super_type;
274public: 
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
435private:
436  template <typename,std::size_t> friend class multi_array_impl_base;
437#else
438public: // 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//
457template <typename Array, int N>
458class array_view_gen {
459  typedef typename Array::element element;
460public:
461  typedef boost::detail::multi_array::multi_array_view<element,N> type;
462};
463
464template <typename Array, int N>
465class const_array_view_gen {
466  typedef typename Array::element element;
467public:
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
Note: See TracBrowser for help on using the repository browser.