PageRenderTime 63ms CodeModel.GetById 34ms app.highlight 25ms RepoModel.GetById 1ms app.codeStats 1ms

/Src/Dependencies/Boost/boost/multi_array/subarray.hpp

http://hadesmem.googlecode.com/
C++ Header | 399 lines | 295 code | 60 blank | 44 comment | 11 complexity | 35eef657811fe892a74d270bc8753f1e MD5 | raw file
  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      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::multi_array_concepts::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      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      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