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