source: NonGTP/Boost/boost/multi_array/subarray.hpp @ 857

Revision 857, 12.2 KB checked in by igarcia, 19 years ago (diff)
RevLine 
[857]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    return super_type::access_element(boost::type<const element&>(),
83                                      origin(),
84                                      indices,strides());
85  }
86
87  // see generate_array_view in base.hpp
88#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
89  template <int NDims>
90#else
91  template <int NumDims, int NDims> // else ICE
92#endif // BOOST_MSVC
93  typename const_array_view<NDims>::type
94  operator[](const boost::detail::multi_array::
95             index_gen<NumDims,NDims>& indices)
96    const {
97    typedef typename const_array_view<NDims>::type return_type;
98    return
99      super_type::generate_array_view(boost::type<return_type>(),
100                                      indices,
101                                      shape(),
102                                      strides(),
103                                      index_bases(),
104                                      base_);
105  }
106
107  template <typename OPtr>
108  bool operator<(const const_sub_array<T,NumDims,OPtr>& rhs) const {
109    return std::lexicographical_compare(begin(),end(),rhs.begin(),rhs.end());
110  }
111
112  template <typename OPtr>
113  bool operator==(const const_sub_array<T,NumDims,OPtr>& rhs) const {
114    if(std::equal(shape(),shape()+num_dimensions(),rhs.shape()))
115      return std::equal(begin(),end(),rhs.begin());
116    else return false;
117  }
118
119  template <typename OPtr>
120  bool operator!=(const const_sub_array<T,NumDims,OPtr>& rhs) const {
121    return !(*this == rhs);
122  }
123
124  template <typename OPtr>
125  bool operator>(const const_sub_array<T,NumDims,OPtr>& rhs) const {
126    return rhs < *this;
127  }
128
129  template <typename OPtr>
130  bool operator<=(const const_sub_array<T,NumDims,OPtr>& rhs) const {
131    return !(*this > rhs);
132  }
133
134  template <typename OPtr>
135  bool operator>=(const const_sub_array<T,NumDims,OPtr>& rhs) const {
136    return !(*this < rhs);
137  }
138
139  const_iterator begin() const {
140    return const_iterator(*index_bases(),origin(),
141                          shape(),strides(),index_bases());
142  }
143
144  const_iterator end() const {
145    return const_iterator(*index_bases()+(index)*shape(),origin(),
146                          shape(),strides(),index_bases());
147  }
148
149  const_reverse_iterator rbegin() const {
150    return const_reverse_iterator(end());
151  }
152
153  const_reverse_iterator rend() const {
154    return const_reverse_iterator(begin());
155  }
156
157  TPtr origin() const { return base_; }
158  size_type size() const { return extents_[0]; }
159  size_type max_size() const { return num_elements(); }
160  bool empty() const { return size() == 0; }
161  size_type num_dimensions() const { return NumDims; }
162  const size_type*  shape() const { return extents_; }
163  const index* strides() const { return strides_; }
164  const index* index_bases() const { return index_base_; }
165
166  size_type num_elements() const {
167    return std::accumulate(shape(),shape() + num_dimensions(),
168                           size_type(1), std::multiplies<size_type>());
169  }
170
171
172#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
173protected:
174  template <typename,std::size_t> friend class value_accessor_n; 
175  template <typename,std::size_t,typename> friend class const_sub_array;
176#else   
177public:  // Should be protected
178#endif
179
180  const_sub_array (TPtr base,
181                 const size_type* extents,
182                 const index* strides,
183                 const index* index_base) :
184    base_(base), extents_(extents), strides_(strides),
185    index_base_(index_base) {
186  }
187
188  TPtr base_;
189  const size_type* extents_;
190  const index* strides_;
191  const index* index_base_;
192private:
193  // const_sub_array cannot be assigned to (no deep copies!)
194  const_sub_array& operator=(const const_sub_array&);
195};
196
197
198//
199// sub_array
200//    multi_array's proxy class to allow multiple overloads of
201//    operator[] in order to provide a clean multi-dimensional array
202//    interface.
203template <typename T, std::size_t NumDims>
204class sub_array : public const_sub_array<T,NumDims,T*>
205{
206  typedef const_sub_array<T,NumDims,T*> super_type;
207public:
208  typedef typename super_type::element element;
209  typedef typename super_type::reference reference;
210  typedef typename super_type::index index;
211  typedef typename super_type::size_type size_type;
212  typedef typename super_type::iterator iterator;
213  typedef typename super_type::reverse_iterator reverse_iterator;
214  typedef typename super_type::const_reference const_reference;
215  typedef typename super_type::const_iterator const_iterator;
216  typedef typename super_type::const_reverse_iterator const_reverse_iterator;
217
218  // template typedefs
219  template <std::size_t NDims>
220  struct const_array_view {
221    typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
222  };
223
224  template <std::size_t NDims>
225  struct array_view {
226    typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
227  };
228
229  // Assignment from other ConstMultiArray types.
230  template <typename ConstMultiArray>
231  sub_array& operator=(const ConstMultiArray& other) {
232    function_requires< boost::detail::multi_array::ConstMultiArrayConcept<
233        ConstMultiArray, NumDims> >();
234
235    // make sure the dimensions agree
236    assert(other.num_dimensions() == this->num_dimensions());
237    assert(std::equal(other.shape(),other.shape()+this->num_dimensions(),
238                      this->shape()));
239    // iterator-based copy
240    std::copy(other.begin(),other.end(),begin());
241    return *this;
242  }
243
244
245  sub_array& operator=(const sub_array& other) {
246    if (&other != this) {
247      // make sure the dimensions agree
248      assert(other.num_dimensions() == this->num_dimensions());
249      assert(std::equal(other.shape(),other.shape()+this->num_dimensions(),
250                        this->shape()));
251      // iterator-based copy
252      std::copy(other.begin(),other.end(),begin());
253    }
254    return *this;
255  }
256
257  T* origin() { return this->base_; }
258  const T* origin() const { return this->base_; }
259
260  reference operator[](index idx) {
261    return super_type::access(boost::type<reference>(),
262                              idx,this->base_,this->shape(),this->strides(),
263                              this->index_bases());
264  }
265
266  // see generate_array_view in base.hpp
267#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
268  template <int NDims>
269#else
270  template <int NumDims, int NDims> // else ICE
271#endif // BOOST_MSVC
272  typename array_view<NDims>::type
273  operator[](const boost::detail::multi_array::
274             index_gen<NumDims,NDims>& indices) {
275    typedef typename array_view<NDims>::type return_type;
276    return
277      super_type::generate_array_view(boost::type<return_type>(),
278                                      indices,
279                                      this->shape(),
280                                      this->strides(),
281                                      this->index_bases(),
282                                      origin());
283  }
284
285  template <class IndexList>
286  element& operator()(const IndexList& indices) {
287    return super_type::access_element(boost::type<element&>(),
288                                      origin(),
289                                      indices,this->strides());
290  }
291
292  iterator begin() {
293    return iterator(*this->index_bases(),origin(),
294                    this->shape(),this->strides(),this->index_bases());
295  }
296
297  iterator end() {
298    return iterator(*this->index_bases()+(index)*this->shape(),origin(),
299                    this->shape(),this->strides(),this->index_bases());
300  }
301
302  // RG - rbegin() and rend() written naively to thwart MSVC ICE.
303  reverse_iterator rbegin() {
304    reverse_iterator ri(end());
305    return ri;
306  }
307
308  reverse_iterator rend() {
309    reverse_iterator ri(begin());
310    return ri;
311  }
312
313  //
314  // proxies
315  //
316
317  template <class IndexList>
318  const element& operator()(const IndexList& indices) const {
319    return super_type::operator()(indices);
320  }
321
322  const_reference operator[](index idx) const {
323    return super_type::operator[](idx);
324  }
325
326  // see generate_array_view in base.hpp
327#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
328  template <int NDims>
329#else
330  template <int NumDims, int NDims> // else ICE
331#endif // BOOST_MSVC
332  typename const_array_view<NDims>::type
333  operator[](const boost::detail::multi_array::
334             index_gen<NumDims,NDims>& indices)
335    const {
336    return super_type::operator[](indices);
337  }
338
339  const_iterator begin() const {
340    return super_type::begin();
341  }
342 
343  const_iterator end() const {
344    return super_type::end();
345  }
346
347  const_reverse_iterator rbegin() const {
348    return super_type::rbegin();
349  }
350
351  const_reverse_iterator rend() const {
352    return super_type::rend();
353  }
354
355#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
356private:
357  template <typename,std::size_t> friend class value_accessor_n;
358#else
359public: // should be private
360#endif
361
362  sub_array (T* base,
363            const size_type* extents,
364            const index* strides,
365            const index* index_base) :
366    super_type(base,extents,strides,index_base) {
367  }
368
369};
370
371} // namespace multi_array
372} // namespace detail
373//
374// traits classes to get sub_array types
375//
376template <typename Array, int N>
377class subarray_gen {
378  typedef typename Array::element element;
379public:
380  typedef boost::detail::multi_array::sub_array<element,N> type;
381};
382
383template <typename Array, int N>
384class const_subarray_gen {
385  typedef typename Array::element element;
386public:
387  typedef boost::detail::multi_array::const_sub_array<element,N> type; 
388};
389} // namespace boost
390 
391#endif // SUBARRAY_RG071801_HPP
Note: See TracBrowser for help on using the repository browser.