Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/boost/multi_array/subarray.hpp @ 29

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

updated boost from 1_33_1 to 1_34_1

File size: 12.2 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 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
29namespace boost {
30namespace detail {
31namespace 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.
38template <typename T, std::size_t NumDims, typename TPtr>
39class 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;
43public: 
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
175protected:
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   
179public:  // 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_;
194private:
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.
205template <typename T, std::size_t NumDims>
206class sub_array : public const_sub_array<T,NumDims,T*>
207{
208  typedef const_sub_array<T,NumDims,T*> super_type;
209public: 
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
363private:
364  template <typename,std::size_t> friend class value_accessor_n;
365#else
366public: // 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//
383template <typename Array, int N>
384class subarray_gen {
385  typedef typename Array::element element;
386public:
387  typedef boost::detail::multi_array::sub_array<element,N> type;
388};
389
390template <typename Array, int N>
391class const_subarray_gen {
392  typedef typename Array::element element;
393public:
394  typedef boost::detail::multi_array::const_sub_array<element,N> type; 
395};
396} // namespace boost
397 
398#endif // SUBARRAY_RG071801_HPP
Note: See TracBrowser for help on using the repository browser.