~ubuntu-branches/ubuntu/warty/aqsis/warty

« back to all changes in this revision

Viewing changes to boost/boost/multi_array/subarray.hpp

  • Committer: Bazaar Package Importer
  • Author(s): LaMont Jones
  • Date: 2004-08-24 07:25:04 UTC
  • Revision ID: james.westby@ubuntu.com-20040824072504-zf993vnevvisdsvb
Tags: upstream-0.9.1
ImportĀ upstreamĀ versionĀ 0.9.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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