source: XIOS/dev/dev_olga/src/extern/boost/include/boost/multi_array/subarray.hpp @ 1022

Last change on this file since 1022 was 1022, checked in by mhnguyen, 7 years ago
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    BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
239    BOOST_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      BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
251      BOOST_ASSERT(std::equal(other.shape(),
252                              other.shape()+this->num_dimensions(),
253                              this->shape()));
254      // iterator-based copy
255      std::copy(other.begin(),other.end(),begin());
256    }
257    return *this;
258  }
259
260  T* origin() { return this->base_; }
261  const T* origin() const { return this->base_; }
262
263  reference operator[](index idx) {
264    return super_type::access(boost::type<reference>(),
265                              idx,this->base_,this->shape(),this->strides(),
266                              this->index_bases());
267  }
268
269  // see generate_array_view in base.hpp
270#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
271  template <int NDims>
272#else
273  template <int NumDims, int NDims> // else ICE
274#endif // BOOST_MSVC
275  typename array_view<NDims>::type
276  operator[](const boost::detail::multi_array::
277             index_gen<NumDims,NDims>& indices) {
278    typedef typename array_view<NDims>::type return_type;
279    return
280      super_type::generate_array_view(boost::type<return_type>(),
281                                      indices,
282                                      this->shape(),
283                                      this->strides(),
284                                      this->index_bases(),
285                                      origin());
286  }
287
288  template <class IndexList>
289  element& operator()(const IndexList& indices) {
290    boost::function_requires<
291      detail::multi_array::CollectionConcept<IndexList> >();
292    return super_type::access_element(boost::type<element&>(),
293                                      indices,origin(),
294                                      this->shape(),this->strides(),
295                                      this->index_bases());
296  }
297
298  iterator begin() {
299    return iterator(*this->index_bases(),origin(),
300                    this->shape(),this->strides(),this->index_bases());
301  }
302
303  iterator end() {
304    return iterator(*this->index_bases()+(index)*this->shape(),origin(),
305                    this->shape(),this->strides(),this->index_bases());
306  }
307
308  // RG - rbegin() and rend() written naively to thwart MSVC ICE.
309  reverse_iterator rbegin() {
310    reverse_iterator ri(end());
311    return ri;
312  }
313
314  reverse_iterator rend() {
315    reverse_iterator ri(begin());
316    return ri;
317  }
318
319  //
320  // proxies
321  //
322
323  template <class IndexList>
324  const element& operator()(const IndexList& indices) const {
325    boost::function_requires<
326      detail::multi_array::CollectionConcept<IndexList> >();
327    return super_type::operator()(indices);
328  }
329
330  const_reference operator[](index idx) const {
331    return super_type::operator[](idx);
332  }
333
334  // see generate_array_view in base.hpp
335#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
336  template <int NDims>
337#else
338  template <int NumDims, int NDims> // else ICE
339#endif // BOOST_MSVC
340  typename const_array_view<NDims>::type
341  operator[](const boost::detail::multi_array::
342             index_gen<NumDims,NDims>& indices)
343    const {
344    return super_type::operator[](indices);
345  }
346
347  const_iterator begin() const {
348    return super_type::begin();
349  }
350 
351  const_iterator end() const {
352    return super_type::end();
353  }
354
355  const_reverse_iterator rbegin() const {
356    return super_type::rbegin();
357  }
358
359  const_reverse_iterator rend() const {
360    return super_type::rend();
361  }
362
363#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
364private:
365  template <typename,std::size_t> friend class value_accessor_n;
366#else
367public: // should be private
368#endif
369
370  sub_array (T* base,
371            const size_type* extents,
372            const index* strides,
373            const index* index_base) :
374    super_type(base,extents,strides,index_base) {
375  }
376
377};
378
379} // namespace multi_array
380} // namespace detail
381//
382// traits classes to get sub_array types
383//
384template <typename Array, int N>
385class subarray_gen {
386  typedef typename Array::element element;
387public:
388  typedef boost::detail::multi_array::sub_array<element,N> type;
389};
390
391template <typename Array, int N>
392class const_subarray_gen {
393  typedef typename Array::element element;
394public:
395  typedef boost::detail::multi_array::const_sub_array<element,N> type; 
396};
397} // namespace boost
398 
399#endif // SUBARRAY_RG071801_HPP
Note: See TracBrowser for help on using the repository browser.