]> git.lyx.org Git - lyx.git/blob - boost/boost/multi_array/subarray.hpp
Upgrade to boost 1.33.1
[lyx.git] / boost / boost / multi_array / subarray.hpp
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
29 namespace boost {
30 namespace detail {
31 namespace 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.
38 template <typename T, std::size_t NumDims, typename TPtr>
39 class 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;
43 public: 
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
173 protected:
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    
177 public:  // 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_;
192 private:
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.
203 template <typename T, std::size_t NumDims>
204 class sub_array : public const_sub_array<T,NumDims,T*>
205 {
206   typedef const_sub_array<T,NumDims,T*> super_type;
207 public: 
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
356 private:
357   template <typename,std::size_t> friend class value_accessor_n;
358 #else
359 public: // 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 //
376 template <typename Array, int N>
377 class subarray_gen {
378   typedef typename Array::element element;
379 public:
380   typedef boost::detail::multi_array::sub_array<element,N> type;
381 };
382
383 template <typename Array, int N>
384 class const_subarray_gen {
385   typedef typename Array::element element;
386 public:
387   typedef boost::detail::multi_array::const_sub_array<element,N> type;  
388 };
389 } // namespace boost
390   
391 #endif // SUBARRAY_RG071801_HPP