New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
view.hpp in vendors/XIOS/current/extern/boost/include/boost/multi_array – NEMO

source: vendors/XIOS/current/extern/boost/include/boost/multi_array/view.hpp @ 3408

Last change on this file since 3408 was 3408, checked in by rblod, 12 years ago

importing initial XIOS vendor drop

  • Property svn:keywords set to Id
File size: 14.4 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  }
249
250  typedef boost::array<size_type,NumDims> size_list;
251  typedef boost::array<index,NumDims> index_list;
252
253  TPtr base_;
254  index origin_offset_;
255  size_type num_elements_;
256  size_list extent_list_;
257  index_list stride_list_;
258  index_list index_base_list_;
259
260private:
261  // const_multi_array_view cannot be assigned to (no deep copies!)
262  const_multi_array_view& operator=(const const_multi_array_view& other);
263};
264
265
266template <typename T, std::size_t NumDims>
267class multi_array_view :
268  public const_multi_array_view<T,NumDims,T*>
269{
270  typedef const_multi_array_view<T,NumDims,T*> super_type;
271public: 
272  typedef typename super_type::value_type value_type;
273  typedef typename super_type::reference reference;
274  typedef typename super_type::iterator iterator;
275  typedef typename super_type::reverse_iterator reverse_iterator;
276  typedef typename super_type::const_reference const_reference;
277  typedef typename super_type::const_iterator const_iterator;
278  typedef typename super_type::const_reverse_iterator const_reverse_iterator;
279  typedef typename super_type::element element;
280  typedef typename super_type::size_type size_type;
281  typedef typename super_type::difference_type difference_type;
282  typedef typename super_type::index index;
283  typedef typename super_type::extent_range extent_range;
284
285  // template typedefs
286  template <std::size_t NDims>
287  struct const_array_view {
288    typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
289  };
290
291  template <std::size_t NDims>
292  struct array_view {
293    typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
294  };
295
296  // Assignment from other ConstMultiArray types.
297  template <typename ConstMultiArray>
298  multi_array_view& operator=(const ConstMultiArray& other) {
299    function_requires< 
300      boost::detail::multi_array::
301      ConstMultiArrayConcept<ConstMultiArray,NumDims> >();
302
303    // make sure the dimensions agree
304    BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
305    BOOST_ASSERT(std::equal(other.shape(),other.shape()+this->num_dimensions(),
306                            this->shape()));
307    // iterator-based copy
308    std::copy(other.begin(),other.end(),begin());
309    return *this;
310  }
311
312
313  multi_array_view& operator=(const multi_array_view& other) {
314    if (&other != this) {
315      // make sure the dimensions agree
316      BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
317      BOOST_ASSERT(std::equal(other.shape(),
318                              other.shape()+this->num_dimensions(),
319                              this->shape()));
320      // iterator-based copy
321      std::copy(other.begin(),other.end(),begin());
322    }
323    return *this;
324  }
325
326  element* origin() { return this->base_+this->origin_offset_; }
327
328  template <class IndexList>
329  element& operator()(const IndexList& indices) {
330    boost::function_requires<
331      detail::multi_array::CollectionConcept<IndexList> >();
332    return super_type::access_element(boost::type<element&>(),
333                                      indices,origin(),
334                                      this->shape(),this->strides(),
335                                      this->index_bases());
336  }
337
338
339  reference operator[](index idx) {
340    return super_type::access(boost::type<reference>(),
341                              idx,origin(),
342                              this->shape(),this->strides(),
343                              this->index_bases());
344  }
345
346
347  // see generate_array_view in base.hpp
348#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
349  template <int NDims>
350#else
351  template <int NumDims, int NDims> // else ICE
352#endif // BOOST_MSVC
353  typename array_view<NDims>::type
354  operator[](const boost::detail::multi_array::
355             index_gen<NumDims,NDims>& indices) {
356    typedef typename array_view<NDims>::type return_type;
357    return
358      super_type::generate_array_view(boost::type<return_type>(),
359                                      indices,
360                                      this->shape(),
361                                      this->strides(),
362                                      this->index_bases(),
363                                      origin());
364  }
365 
366 
367  iterator begin() {
368    return iterator(*this->index_bases(),origin(),
369                    this->shape(),this->strides(),
370                    this->index_bases());
371  }
372
373  iterator end() {
374    return iterator(*this->index_bases()+(index)*this->shape(),origin(),
375                    this->shape(),this->strides(),
376                    this->index_bases());
377  }
378
379  reverse_iterator rbegin() {
380    return reverse_iterator(end());
381  }
382
383  reverse_iterator rend() {
384    return reverse_iterator(begin());
385  }
386
387  // Using declarations don't seem to work for g++
388  // These are the proxies to work around this.
389
390  const element* origin() const { return super_type::origin(); }
391
392  template <class IndexList>
393  const element& operator()(const IndexList& indices) const {
394    boost::function_requires<
395      detail::multi_array::CollectionConcept<IndexList> >();
396    return super_type::operator()(indices);
397  }
398
399  const_reference operator[](index idx) const {
400    return super_type::operator[](idx);
401  }
402
403  // see generate_array_view in base.hpp
404#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
405  template <int NDims>
406#else
407  template <int NumDims, int NDims> // else ICE
408#endif // BOOST_MSVC
409  typename const_array_view<NDims>::type
410  operator[](const boost::detail::multi_array::
411             index_gen<NumDims,NDims>& indices)
412    const {
413    return super_type::operator[](indices);
414  }
415 
416  const_iterator begin() const {
417    return super_type::begin();
418  }
419
420  const_iterator end() const {
421    return super_type::end();
422  }
423
424  const_reverse_iterator rbegin() const {
425    return super_type::rbegin();
426  }
427
428  const_reverse_iterator rend() const {
429    return super_type::rend();
430  }
431
432#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
433private:
434  template <typename,std::size_t> friend class multi_array_impl_base;
435#else
436public: // should be private
437#endif
438
439  // constructor used by multi_array_impl_base::generate_array_view to
440  // generate array views
441  template <typename ExtentList, typename Index>
442  explicit multi_array_view(T* base,
443                            const ExtentList& extents,
444                            const boost::array<Index,NumDims>& strides) :
445    super_type(base,extents,strides) { }
446
447};
448
449} // namespace multi_array
450} // namespace detail
451
452//
453// traits classes to get array_view types
454//
455template <typename Array, int N>
456class array_view_gen {
457  typedef typename Array::element element;
458public:
459  typedef boost::detail::multi_array::multi_array_view<element,N> type;
460};
461
462template <typename Array, int N>
463class const_array_view_gen {
464  typedef typename Array::element element;
465public:
466  typedef boost::detail::multi_array::const_multi_array_view<element,N> type; 
467};
468
469} // namespace boost
470
471#endif // BOOST_MULTI_ARRAY_VIEW_RG071301_HPP
472
Note: See TracBrowser for help on using the repository browser.