]> git.lyx.org Git - lyx.git/blob - boost/boost/multi_array/subarray.hpp
update boost to pre-1.30.0
[lyx.git] / boost / boost / multi_array / subarray.hpp
1 // Copyright (C) 2002 Ronald Garcia
2 //
3 // Permission to copy, use, sell and distribute this software is granted
4 // provided this copyright notice appears in all copies. 
5 // Permission to modify the code and to distribute modified code is granted
6 // provided this copyright notice appears in all copies, and a notice 
7 // that the code was modified is included with the copyright notice.
8 //
9 // This software is provided "as is" without express or implied warranty, 
10 // and with no claim as to its suitability for any purpose.
11 //
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_iter_base const_iter_base;
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   // Allow default copy constructor as well.
67
68   template <typename OPtr>
69   const_sub_array (const const_sub_array<T,NumDims,OPtr>& rhs) :
70     base_(rhs.base_), extents_(rhs.extents_), strides_(rhs.strides_),
71     index_base_(rhs.index_base_) {
72   }
73
74   // const_sub_array always returns const types, regardless of its own
75   // constness.
76   const_reference operator[](index idx) const {
77     return super_type::access(boost::type<const_reference>(),
78                               idx,base_,shape(),strides(),index_bases());
79   }
80   
81   template <typename IndexList>
82   const element& operator()(const IndexList& indices) const {
83     return super_type::access_element(boost::type<const element&>(),
84                                       origin(),
85                                       indices,strides());
86   }
87
88   // see generate_array_view in base.hpp
89 #if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
90   template <int NDims>
91 #else
92   template <int NumDims, int NDims> // else ICE
93 #endif // BOOST_MSVC
94   typename const_array_view<NDims>::type 
95   operator[](const boost::detail::multi_array::
96              index_gen<NumDims,NDims>& indices)
97     const {
98     typedef typename const_array_view<NDims>::type return_type;
99     return
100       super_type::generate_array_view(boost::type<return_type>(),
101                                       indices,
102                                       shape(),
103                                       strides(),
104                                       index_bases(),
105                                       base_);
106   }
107
108   template <typename OPtr>
109   bool operator<(const const_sub_array<T,NumDims,OPtr>& rhs) const {
110     return std::lexicographical_compare(begin(),end(),rhs.begin(),rhs.end());
111   }
112
113   template <typename OPtr>
114   bool operator==(const const_sub_array<T,NumDims,OPtr>& rhs) const {
115     if(std::equal(shape(),shape()+num_dimensions(),rhs.shape()))
116       return std::equal(begin(),end(),rhs.begin());
117     else return false;
118   }
119
120   template <typename OPtr>
121   bool operator!=(const const_sub_array<T,NumDims,OPtr>& rhs) const {
122     return !(*this == rhs);
123   }
124
125   template <typename OPtr>
126   bool operator>(const const_sub_array<T,NumDims,OPtr>& rhs) const {
127     return rhs < *this;
128   }
129
130   template <typename OPtr>
131   bool operator<=(const const_sub_array<T,NumDims,OPtr>& rhs) const {
132     return !(*this > rhs);
133   }
134
135   template <typename OPtr>
136   bool operator>=(const const_sub_array<T,NumDims,OPtr>& rhs) const {
137     return !(*this < rhs);
138   }
139
140   const_iterator begin() const {
141     return const_iterator(const_iter_base(*index_bases(),origin(),
142                                    shape(),strides(),index_bases()));
143   }
144
145   const_iterator end() const {
146     return const_iterator(const_iter_base(*index_bases()+*shape(),origin(),
147                                    shape(),strides(),index_bases()));
148   }
149
150   const_reverse_iterator rbegin() const {
151     return const_reverse_iterator(end());
152   }
153
154   const_reverse_iterator rend() const {
155     return const_reverse_iterator(begin());
156   }
157
158   TPtr origin() const { return base_; }
159   size_type size() const { return extents_[0]; }
160   size_type max_size() const { return num_elements(); }
161   bool empty() const { return size() == 0; }
162   size_type num_dimensions() const { return NumDims; }
163   const size_type*  shape() const { return extents_; }
164   const index* strides() const { return strides_; }
165   const index* index_bases() const { return index_base_; }
166
167   size_type num_elements() const { 
168     return std::accumulate(shape(),shape() + num_dimensions(),
169                            size_type(1), std::multiplies<size_type>());
170   }
171
172
173 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
174 protected:
175   template <typename,std::size_t> friend class value_accessor_n;  
176   template <typename,std::size_t,typename> friend class const_sub_array;
177 #else    
178 public:  // Should be protected
179 #endif
180
181   const_sub_array (TPtr base,
182                  const size_type* extents,
183                  const index* strides,
184                  const index* index_base) :
185     base_(base), extents_(extents), strides_(strides),
186     index_base_(index_base) {
187   }
188
189   TPtr base_;
190   const size_type* extents_;
191   const index* strides_;
192   const index* index_base_;
193 private:
194   // const_sub_array cannot be assigned to (no deep copies!)
195   const_sub_array& operator=(const const_sub_array&);
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::iter_base iter_base;
215   typedef typename super_type::const_reference const_reference;
216   typedef typename super_type::const_iterator const_iterator;
217   typedef typename super_type::const_reverse_iterator const_reverse_iterator;
218   typedef typename super_type::const_iter_base const_iter_base;
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     assert(other.num_dimensions() == this->num_dimensions());
239     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       assert(other.num_dimensions() == this->num_dimensions());
251       assert(std::equal(other.shape(),other.shape()+this->num_dimensions(),
252                         this->shape()));
253       // iterator-based copy
254       std::copy(other.begin(),other.end(),begin());
255     }
256     return *this;
257   }
258
259   T* origin() { return this->base_; }
260   const T* origin() const { return this->base_; }
261
262   reference operator[](index idx) {
263     return super_type::access(boost::type<reference>(),
264                               idx,this->base_,this->shape(),this->strides(),
265                               this->index_bases());
266   }
267
268   // see generate_array_view in base.hpp
269 #if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
270   template <int NDims>
271 #else
272   template <int NumDims, int NDims> // else ICE
273 #endif // BOOST_MSVC
274   typename array_view<NDims>::type 
275   operator[](const boost::detail::multi_array::
276              index_gen<NumDims,NDims>& indices) {
277     typedef typename array_view<NDims>::type return_type;
278     return
279       super_type::generate_array_view(boost::type<return_type>(),
280                                       indices,
281                                       this->shape(),
282                                       this->strides(),
283                                       this->index_bases(),
284                                       origin());
285   }
286
287   template <class IndexList>
288   element& operator()(const IndexList& indices) {
289     return super_type::access_element(boost::type<element&>(),
290                                       origin(),
291                                       indices,this->strides());
292   }
293
294   iterator begin() {
295     return iterator(iter_base(*this->index_bases(),origin(),
296                                    this->shape(),this->strides(),this->index_bases()));
297   }
298
299   iterator end() {
300     return iterator(iter_base(*this->index_bases()+*this->shape(),origin(),
301                                    this->shape(),this->strides(),this->index_bases()));
302   }
303
304   // RG - rbegin() and rend() written naively to thwart MSVC ICE.
305   reverse_iterator rbegin() {
306     reverse_iterator ri(end());
307     return ri;
308   }
309
310   reverse_iterator rend() {
311     reverse_iterator ri(begin());
312     return ri;
313   }
314
315   //
316   // proxies
317   //
318
319   template <class IndexList>
320   const element& operator()(const IndexList& indices) const {
321     return super_type::operator()(indices);
322   }
323
324   const_reference operator[](index idx) const {
325     return super_type::operator[](idx);
326   }
327
328   // see generate_array_view in base.hpp
329 #if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
330   template <int NDims>
331 #else
332   template <int NumDims, int NDims> // else ICE
333 #endif // BOOST_MSVC
334   typename const_array_view<NDims>::type 
335   operator[](const boost::detail::multi_array::
336              index_gen<NumDims,NDims>& indices)
337     const {
338     return super_type::operator[](indices);
339   }
340
341   const_iterator begin() const {
342     return super_type::begin();
343   }
344   
345   const_iterator end() const {
346     return super_type::end();
347   }
348
349   const_reverse_iterator rbegin() const {
350     return super_type::rbegin();
351   }
352
353   const_reverse_iterator rend() const {
354     return super_type::rend();
355   }
356
357 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
358 private:
359   template <typename,std::size_t> friend class value_accessor_n;
360 #else
361 public: // should be private
362 #endif
363
364   sub_array (T* base,
365             const size_type* extents,
366             const index* strides,
367             const index* index_base) :
368     super_type(base,extents,strides,index_base) {
369   }
370
371 };
372
373 } // namespace multi_array
374 } // namespace detail
375 //
376 // traits classes to get sub_array types
377 //
378 template <typename Array, int N>
379 class subarray_gen {
380   typedef typename Array::element element;
381 public:
382   typedef boost::detail::multi_array::sub_array<element,N> type;
383 };
384
385 template <typename Array, int N>
386 class const_subarray_gen {
387   typedef typename Array::element element;
388 public:
389   typedef boost::detail::multi_array::const_sub_array<element,N> type;  
390 };
391 } // namespace boost
392   
393 #endif // SUBARRAY_RG071801_HPP