]> git.lyx.org Git - lyx.git/blob - boost/boost/multi_array/subarray.hpp
major boost update
[lyx.git] / boost / boost / multi_array / subarray.hpp
1 #ifndef SUBARRAY_RG071801_HPP
2 #define SUBARRAY_RG071801_HPP
3
4 //
5 // subarray.hpp - used to implement standard operator[] on
6 // multi_arrays
7 //
8
9 #include "boost/multi_array/base.hpp"
10 #include "boost/multi_array/concept_checks.hpp"
11 #include "boost/limits.hpp"
12 #include "boost/type.hpp"
13 #include <algorithm>
14 #include <cstddef>
15 #include <functional>
16
17 namespace boost {
18 namespace detail {
19 namespace multi_array {
20
21 //
22 // const_sub_array
23 //    multi_array's proxy class to allow multiple overloads of
24 //    operator[] in order to provide a clean multi-dimensional array 
25 //    interface.
26 template <typename T, std::size_t NumDims, typename TPtr>
27 class const_sub_array :
28   public boost::detail::multi_array::multi_array_impl_base<T,NumDims>
29 {
30   typedef boost::detail::multi_array::multi_array_impl_base<T,NumDims> super_type;
31 public: 
32   typedef typename super_type::value_type value_type;
33   typedef typename super_type::const_reference const_reference;
34   typedef typename super_type::const_iterator const_iterator;
35   typedef typename super_type::const_iter_base const_iter_base;
36   typedef typename super_type::const_reverse_iterator const_reverse_iterator;
37   typedef typename super_type::element element;
38   typedef typename super_type::size_type size_type;
39   typedef typename super_type::difference_type difference_type;
40   typedef typename super_type::index index;
41   typedef typename super_type::extent_range extent_range;
42
43   // template typedefs
44   template <std::size_t NDims>
45   struct const_array_view {
46     typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
47   };
48
49   template <std::size_t NDims>
50   struct array_view {
51     typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
52   };
53
54   // Allow default copy constructor as well.
55
56   template <typename OPtr>
57   const_sub_array (const const_sub_array<T,NumDims,OPtr>& rhs) :
58     base_(rhs.base_), extents_(rhs.extents_), strides_(rhs.strides_),
59     index_base_(rhs.index_base_) {
60   }
61
62   // const_sub_array always returns const types, regardless of its own
63   // constness.
64   const_reference operator[](index idx) const {
65     return super_type::access(boost::type<const_reference>(),
66                               idx,base_,shape(),strides(),index_bases());
67   }
68   
69   template <typename IndexList>
70   const element& operator()(const IndexList& indices) const {
71     return super_type::access_element(boost::type<const element&>(),
72                                       origin(),
73                                       indices,strides());
74   }
75
76   // see generate_array_view in base.hpp
77 #ifndef BOOST_MSVC
78   template <int NDims>
79 #else
80   template <int NumDims, int NDims> // else ICE
81 #endif // BOOST_MSVC
82   typename const_array_view<NDims>::type 
83   operator[](const boost::detail::multi_array::
84              index_gen<NumDims,NDims>& indices)
85     const {
86     typedef const_array_view<NDims>::type return_type;
87     return
88       super_type::generate_array_view(boost::type<return_type>(),
89                                       indices,
90                                       shape(),
91                                       strides(),
92                                       index_bases(),
93                                       base_);
94   }
95
96   template <typename OPtr>
97   bool operator<(const const_sub_array<T,NumDims,OPtr>& rhs) const {
98     return std::lexicographical_compare(begin(),end(),rhs.begin(),rhs.end());
99   }
100
101   template <typename OPtr>
102   bool operator==(const const_sub_array<T,NumDims,OPtr>& rhs) const {
103     if(std::equal(shape(),shape()+num_dimensions(),rhs.shape()))
104       return std::equal(begin(),end(),rhs.begin());
105     else return false;
106   }
107
108   template <typename OPtr>
109   bool operator!=(const const_sub_array<T,NumDims,OPtr>& rhs) const {
110     return !(*this == rhs);
111   }
112
113   template <typename OPtr>
114   bool operator>(const const_sub_array<T,NumDims,OPtr>& rhs) const {
115     return rhs < *this;
116   }
117
118   template <typename OPtr>
119   bool operator<=(const const_sub_array<T,NumDims,OPtr>& rhs) const {
120     return !(*this > rhs);
121   }
122
123   template <typename OPtr>
124   bool operator>=(const const_sub_array<T,NumDims,OPtr>& rhs) const {
125     return !(*this < rhs);
126   }
127
128   const_iterator begin() const {
129     return const_iterator(const_iter_base(*index_bases(),origin(),
130                                    shape(),strides(),index_bases()));
131   }
132
133   const_iterator end() const {
134     return const_iterator(const_iter_base(*index_bases()+*shape(),origin(),
135                                    shape(),strides(),index_bases()));
136   }
137
138   const_reverse_iterator rbegin() const {
139     return const_reverse_iterator(end());
140   }
141
142   const_reverse_iterator rend() const {
143     return const_reverse_iterator(begin());
144   }
145
146   TPtr origin() const { return base_; }
147   size_type size() const { return extents_[0]; }
148   size_type max_size() const { return num_elements(); }
149   bool empty() const { return size() == 0; }
150   size_type num_dimensions() const { return NumDims; }
151   const size_type*  shape() const { return extents_; }
152   const index* strides() const { return strides_; }
153   const index* index_bases() const { return index_base_; }
154
155   size_type num_elements() const { 
156     return std::accumulate(shape(),shape() + num_dimensions(),
157                            size_type(1), std::multiplies<size_type>());
158   }
159
160
161 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
162 protected:
163   template <typename,std::size_t> friend class value_accessor_n;  
164   template <typename,std::size_t,typename> friend class const_sub_array;
165 #else    
166 public:  // Should be protected
167 #endif
168
169   const_sub_array (TPtr base,
170                  const size_type* extents,
171                  const index* strides,
172                  const index* index_base) :
173     base_(base), extents_(extents), strides_(strides),
174     index_base_(index_base) {
175   }
176
177   TPtr base_;
178   const size_type* extents_;
179   const index* strides_;
180   const index* index_base_;
181 private:
182   // const_sub_array cannot be assigned to (no deep copies!)
183   const_sub_array& operator=(const const_sub_array&);
184 };
185
186 //
187 // sub_array
188 //    multi_array's proxy class to allow multiple overloads of
189 //    operator[] in order to provide a clean multi-dimensional array 
190 //    interface.
191 template <typename T, std::size_t NumDims>
192 class sub_array : public const_sub_array<T,NumDims,T*>
193 {
194   typedef const_sub_array<T,NumDims,T*> super_type;
195 public: 
196   typedef typename super_type::element element;
197   typedef typename super_type::reference reference;
198   typedef typename super_type::index index;
199   typedef typename super_type::size_type size_type;
200   typedef typename super_type::iterator iterator;
201   typedef typename super_type::reverse_iterator reverse_iterator;
202   typedef typename super_type::iter_base iter_base;
203   typedef typename super_type::const_reference const_reference;
204   typedef typename super_type::const_iterator const_iterator;
205   typedef typename super_type::const_reverse_iterator const_reverse_iterator;
206   typedef typename super_type::const_iter_base const_iter_base;
207
208   // template typedefs
209   template <std::size_t NDims>
210   struct const_array_view {
211     typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
212   };
213
214   template <std::size_t NDims>
215   struct array_view {
216     typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
217   };
218
219   // Assignment from other ConstMultiArray types.
220   template <typename ConstMultiArray>
221   sub_array& operator=(const ConstMultiArray& other) {
222     function_requires< boost::detail::multi_array::ConstMultiArrayConcept< 
223         ConstMultiArray, NumDims> >();
224
225     // make sure the dimensions agree
226     assert(other.num_dimensions() == num_dimensions());
227     assert(std::equal(other.shape(),other.shape()+num_dimensions(),
228                       shape()));
229     // iterator-based copy
230     std::copy(other.begin(),other.end(),begin());
231     return *this;
232   }
233
234
235   sub_array& operator=(const sub_array& other) {
236     if (&other != this) {
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     }
244     return *this;
245   }
246
247   T* origin() { return base_; }
248   const T* origin() const { return base_; }
249
250   reference operator[](index idx) {
251     return super_type::access(boost::type<reference>(),
252                               idx,base_,shape(),strides(),index_bases());
253   }
254
255   // see generate_array_view in base.hpp
256 #ifndef BOOST_MSVC
257   template <int NDims>
258 #else
259   template <int NumDims, int NDims> // else ICE
260 #endif // BOOST_MSVC
261   typename array_view<NDims>::type 
262   operator[](const boost::detail::multi_array::
263              index_gen<NumDims,NDims>& indices) {
264     typedef array_view<NDims>::type return_type;
265     return
266       super_type::generate_array_view(boost::type<return_type>(),
267                                       indices,
268                                       shape(),
269                                       strides(),
270                                       index_bases(),
271                                       origin());
272   }
273
274   template <class IndexList>
275   element& operator()(const IndexList& indices) {
276     return super_type::access_element(boost::type<element&>(),
277                                       origin(),
278                                       indices,strides());
279   }
280
281   iterator begin() {
282     return iterator(iter_base(*index_bases(),origin(),
283                                    shape(),strides(),index_bases()));
284   }
285
286   iterator end() {
287     return iterator(iter_base(*index_bases()+*shape(),origin(),
288                                    shape(),strides(),index_bases()));
289   }
290
291   // RG - rbegin() and rend() written naively to thwart MSVC ICE.
292   reverse_iterator rbegin() {
293     reverse_iterator ri(end());
294     return ri;
295   }
296
297   reverse_iterator rend() {
298     reverse_iterator ri(begin());
299     return ri;
300   }
301
302   //
303   // proxies
304   //
305
306   template <class IndexList>
307   const element& operator()(const IndexList& indices) const {
308     return super_type::operator()(indices);
309   }
310
311   const_reference operator[](index idx) const {
312     return super_type::operator[](idx);
313   }
314
315   // see generate_array_view in base.hpp
316 #ifndef BOOST_MSVC
317   template <int NDims>
318 #else
319   template <int NumDims, int NDims> // else ICE
320 #endif // BOOST_MSVC
321   typename const_array_view<NDims>::type 
322   operator[](const boost::detail::multi_array::
323              index_gen<NumDims,NDims>& indices)
324     const {
325     return super_type::operator[](indices);
326   }
327
328   const_iterator begin() const {
329     return super_type::begin();
330   }
331   
332   const_iterator end() const {
333     return super_type::end();
334   }
335
336   const_reverse_iterator rbegin() const {
337     return super_type::rbegin();
338   }
339
340   const_reverse_iterator rend() const {
341     return super_type::rend();
342   }
343
344 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
345 private:
346   template <typename,std::size_t> friend class value_accessor_n;
347 #else
348 public: // should be private
349 #endif
350
351   sub_array (T* base,
352             const size_type* extents,
353             const index* strides,
354             const index* index_base) :
355     super_type(base,extents,strides,index_base) {
356   }
357
358 };
359
360 } // namespace multi_array
361 } // namespace detail
362 //
363 // traits classes to get sub_array types
364 //
365 template <typename Array, int N>
366 class subarray_gen {
367   typedef typename Array::element element;
368 public:
369   typedef boost::detail::multi_array::sub_array<element,N> type;
370 };
371
372 template <typename Array, int N>
373 class const_subarray_gen {
374   typedef typename Array::element element;
375 public:
376   typedef boost::detail::multi_array::const_sub_array<element,N> type;  
377 };
378 } // namespace boost
379   
380 #endif // SUBARRAY_RG071801_HPP