~ubuntu-branches/ubuntu/breezy/aqsis/breezy

« back to all changes in this revision

Viewing changes to boost/boost/multi_array.hpp

  • Committer: Bazaar Package Importer
  • Author(s): Will Newton
  • Date: 2004-12-07 20:06:49 UTC
  • Revision ID: james.westby@ubuntu.com-20041207200649-fccswkrvp4oc8lmn
Tags: upstream-0.9.3
ImportĀ upstreamĀ versionĀ 0.9.3

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
//  See http://www.boost.org/libs/multi_array for documentation.
 
14
 
 
15
#ifndef BOOST_MULTI_ARRAY_RG071801_HPP
 
16
#define BOOST_MULTI_ARRAY_RG071801_HPP
 
17
 
 
18
//
 
19
// multi_array.hpp - contains the multi_array class template
 
20
// declaration and definition
 
21
//
 
22
 
 
23
#include "boost/multi_array/base.hpp"
 
24
#include "boost/multi_array/collection_concept.hpp"
 
25
#include "boost/multi_array/copy_array.hpp"
 
26
#include "boost/multi_array/iterator.hpp"
 
27
#include "boost/multi_array/subarray.hpp"
 
28
#include "boost/multi_array/multi_array_ref.hpp"
 
29
#include "boost/multi_array/algorithm.hpp"
 
30
#include "boost/array.hpp"
 
31
#include "boost/type_traits.hpp"
 
32
#include <algorithm>
 
33
#include <cstddef>
 
34
#include <functional>
 
35
#include <numeric>
 
36
#include <vector>
 
37
 
 
38
 
 
39
 
 
40
namespace boost {
 
41
  namespace detail {
 
42
    namespace multi_array {
 
43
      struct populate_index_ranges {
 
44
        multi_array_types::index_range
 
45
        operator()(multi_array_types::index base,
 
46
                   multi_array_types::size_type extent) {
 
47
          return multi_array_types::index_range(base,base+extent);
 
48
        }
 
49
      };
 
50
    } //namespace multi_array
 
51
  } // namespace detail
 
52
 
 
53
template<typename T, std::size_t NumDims,
 
54
  typename Allocator>
 
55
class multi_array : 
 
56
  public multi_array_ref<T,NumDims>
 
57
{
 
58
  typedef multi_array_ref<T,NumDims> super_type;
 
59
public: 
 
60
  typedef typename super_type::value_type value_type;
 
61
  typedef typename super_type::reference reference;
 
62
  typedef typename super_type::const_reference const_reference;
 
63
  typedef typename super_type::iterator iterator;
 
64
  typedef typename super_type::const_iterator const_iterator;
 
65
  typedef typename super_type::iter_base iter_base;
 
66
  typedef typename super_type::const_iter_base const_iter_base;
 
67
  typedef typename super_type::reverse_iterator reverse_iterator;
 
68
  typedef typename super_type::const_reverse_iterator const_reverse_iterator;
 
69
  typedef typename super_type::element element;
 
70
  typedef typename super_type::size_type size_type;
 
71
  typedef typename super_type::difference_type difference_type;
 
72
  typedef typename super_type::index index;
 
73
  typedef typename super_type::extent_range extent_range;
 
74
 
 
75
 
 
76
  template <std::size_t NDims>
 
77
  struct const_array_view {
 
78
    typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
 
79
  };
 
80
 
 
81
  template <std::size_t NDims>
 
82
  struct array_view {
 
83
    typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
 
84
  };
 
85
 
 
86
  template <class ExtentList>
 
87
  explicit multi_array(ExtentList const& extents) :
 
88
    super_type((T*)initial_base_,extents) {
 
89
    boost::function_requires<
 
90
      detail::multi_array::CollectionConcept<ExtentList> >();
 
91
    allocate_space();
 
92
  }
 
93
 
 
94
  template <class ExtentList>
 
95
  explicit multi_array(ExtentList const& extents,
 
96
                       const general_storage_order<NumDims>& so) : 
 
97
    super_type((T*)initial_base_,extents,so) {
 
98
    boost::function_requires<
 
99
      detail::multi_array::CollectionConcept<ExtentList> >();
 
100
    allocate_space();
 
101
  }
 
102
 
 
103
  template <class ExtentList>
 
104
  explicit multi_array(ExtentList const& extents,
 
105
                       const general_storage_order<NumDims>& so,
 
106
                       Allocator const& alloc) :
 
107
    super_type((T*)initial_base_,extents,so), allocator_(alloc) {
 
108
    boost::function_requires<
 
109
      detail::multi_array::CollectionConcept<ExtentList> >();
 
110
    allocate_space();
 
111
  }
 
112
 
 
113
 
 
114
  explicit multi_array(const detail::multi_array
 
115
                       ::extent_gen<NumDims>& ranges) :
 
116
    super_type((T*)initial_base_,ranges) {
 
117
 
 
118
    allocate_space();
 
119
  }
 
120
 
 
121
 
 
122
  explicit multi_array(const detail::multi_array
 
123
                       ::extent_gen<NumDims>& ranges,
 
124
                       const general_storage_order<NumDims>& so) :
 
125
    super_type((T*)initial_base_,ranges,so) {
 
126
 
 
127
    allocate_space();
 
128
  }
 
129
 
 
130
 
 
131
  explicit multi_array(const detail::multi_array
 
132
                       ::extent_gen<NumDims>& ranges,
 
133
                       const general_storage_order<NumDims>& so,
 
134
                       Allocator const& alloc) :
 
135
    super_type((T*)initial_base_,ranges,so), allocator_(alloc) {
 
136
 
 
137
    allocate_space();
 
138
  }
 
139
 
 
140
  multi_array(const multi_array& rhs) :
 
141
  super_type(rhs), allocator_(rhs.allocator_) {
 
142
    allocate_space();
 
143
    boost::copy_n(rhs.base_,rhs.num_elements(),base_);
 
144
  }
 
145
 
 
146
  template <typename OPtr>
 
147
  multi_array(const detail::multi_array::
 
148
              const_sub_array<T,NumDims,OPtr>& rhs) :
 
149
    super_type(rhs) {
 
150
    allocate_space();
 
151
    std::copy(rhs.begin(),rhs.end(),this->begin());
 
152
  }
 
153
 
 
154
  // For some reason, gcc 2.95.2 doesn't pick the above template
 
155
  // member function when passed a subarray, so i was forced to
 
156
  // duplicate the functionality here...
 
157
  multi_array(const detail::multi_array::
 
158
              sub_array<T,NumDims>& rhs) :
 
159
    super_type(rhs) {
 
160
    allocate_space();
 
161
    std::copy(rhs.begin(),rhs.end(),this->begin());
 
162
  }
 
163
 
 
164
  // Since assignment is a deep copy, multi_array_ref 
 
165
  // contains all the necessary code.
 
166
  template <typename ConstMultiArray>
 
167
  multi_array& operator=(const ConstMultiArray& other) {
 
168
    super_type::operator=(other);
 
169
    return *this;
 
170
  }
 
171
 
 
172
  multi_array& operator=(const multi_array& other) {
 
173
    if (&other != this) {
 
174
      super_type::operator=(other);
 
175
    }
 
176
    return *this;
 
177
  }
 
178
 
 
179
 
 
180
  multi_array& resize(const detail::multi_array
 
181
                      ::extent_gen<NumDims>& ranges) {
 
182
 
 
183
 
 
184
    // build a multi_array with the specs given
 
185
    multi_array new_array(ranges);
 
186
 
 
187
 
 
188
    // build a view of tmp with the minimum extents
 
189
 
 
190
    // Get the minimum extents of the arrays.
 
191
    boost::array<size_type,NumDims> min_extents;
 
192
 
 
193
    const size_type& (*min)(const size_type&, const size_type&) =
 
194
      std::min<size_type>;
 
195
    std::transform(new_array.extent_list_.begin(),new_array.extent_list_.end(),
 
196
                   this->extent_list_.begin(),
 
197
                   min_extents.begin(),
 
198
                   min);
 
199
 
 
200
    
 
201
    // typedef boost::array<index,NumDims> index_list;
 
202
    // Build index_gen objects to create views with the same shape
 
203
 
 
204
    // these need to be separate to handle non-zero index bases
 
205
    typedef detail::multi_array::index_gen<NumDims,NumDims> index_gen;
 
206
    index_gen old_idxes;
 
207
    index_gen new_idxes;
 
208
 
 
209
    std::transform(new_array.index_base_list_.begin(),
 
210
                   new_array.index_base_list_.end(),
 
211
                   min_extents.begin(),old_idxes.ranges_.begin(),
 
212
                   detail::multi_array::populate_index_ranges());
 
213
 
 
214
    std::transform(this->index_base_list_.begin(),
 
215
                   this->index_base_list_.end(),
 
216
                   min_extents.begin(),new_idxes.ranges_.begin(),
 
217
                   detail::multi_array::populate_index_ranges());
 
218
 
 
219
    // Build same-shape views of the two arrays
 
220
    typename multi_array::array_view<3>::type view_old = (*this)[old_idxes];
 
221
    typename multi_array::array_view<3>::type view_new = new_array[new_idxes];
 
222
 
 
223
    // Set the right portion of the new array
 
224
    view_new = view_old;
 
225
 
 
226
    using std::swap;
 
227
    // Swap the internals of these arrays.
 
228
    swap(this->super_type::base_,new_array.super_type::base_);
 
229
    swap(this->storage_,new_array.storage_);
 
230
    swap(this->extent_list_,new_array.extent_list_);
 
231
    swap(this->stride_list_,new_array.stride_list_);
 
232
    swap(this->index_base_list_,new_array.index_base_list_);
 
233
    swap(this->origin_offset_,new_array.origin_offset_);
 
234
    swap(this->directional_offset_,new_array.directional_offset_);
 
235
    swap(this->num_elements_,new_array.num_elements_);
 
236
    swap(this->allocator_,new_array.allocator_);
 
237
    swap(this->base_,new_array.base_);
 
238
    swap(this->allocated_elements_,new_array.allocated_elements_);
 
239
 
 
240
    return *this;
 
241
  }
 
242
 
 
243
 
 
244
  ~multi_array() {
 
245
    deallocate_space();
 
246
  }
 
247
 
 
248
private:
 
249
  void allocate_space() {
 
250
    typename Allocator::const_pointer no_hint=0;
 
251
    base_ = allocator_.allocate(this->num_elements(),no_hint);
 
252
    this->set_base_ptr(base_);
 
253
    allocated_elements_ = this->num_elements();
 
254
    std::uninitialized_fill_n(base_,allocated_elements_,T());
 
255
  }
 
256
 
 
257
  void deallocate_space() {
 
258
    if(base_) {
 
259
      for(T* i = base_; i != base_+allocated_elements_; ++i)
 
260
        allocator_.destroy(i);
 
261
      allocator_.deallocate(base_,allocated_elements_);
 
262
    }
 
263
  }    
 
264
  
 
265
  typedef boost::array<size_type,NumDims> size_list;
 
266
  typedef boost::array<index,NumDims> index_list;
 
267
 
 
268
  Allocator allocator_;
 
269
  T* base_;
 
270
  size_type allocated_elements_;
 
271
  enum {initial_base_ = 0};
 
272
};
 
273
 
 
274
} // namespace boost
 
275
 
 
276
#endif // BOOST_MULTI_ARRAY_RG071801_HPP