Chris@16
|
1 // Copyright 2002 The Trustees of Indiana University.
|
Chris@16
|
2
|
Chris@16
|
3 // Use, modification and distribution is subject to the Boost Software
|
Chris@16
|
4 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
5 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
6
|
Chris@16
|
7 // Boost.MultiArray Library
|
Chris@16
|
8 // Authors: Ronald Garcia
|
Chris@16
|
9 // Jeremy Siek
|
Chris@16
|
10 // Andrew Lumsdaine
|
Chris@16
|
11 // See http://www.boost.org/libs/multi_array for documentation.
|
Chris@16
|
12
|
Chris@16
|
13 #ifndef BOOST_MULTI_ARRAY_RG071801_HPP
|
Chris@16
|
14 #define BOOST_MULTI_ARRAY_RG071801_HPP
|
Chris@16
|
15
|
Chris@16
|
16 //
|
Chris@16
|
17 // multi_array.hpp - contains the multi_array class template
|
Chris@16
|
18 // declaration and definition
|
Chris@16
|
19 //
|
Chris@16
|
20
|
Chris@16
|
21 #include "boost/multi_array/base.hpp"
|
Chris@16
|
22 #include "boost/multi_array/collection_concept.hpp"
|
Chris@16
|
23 #include "boost/multi_array/copy_array.hpp"
|
Chris@16
|
24 #include "boost/multi_array/iterator.hpp"
|
Chris@16
|
25 #include "boost/multi_array/subarray.hpp"
|
Chris@16
|
26 #include "boost/multi_array/multi_array_ref.hpp"
|
Chris@16
|
27 #include "boost/multi_array/algorithm.hpp"
|
Chris@16
|
28 #include "boost/array.hpp"
|
Chris@16
|
29 #include "boost/mpl/if.hpp"
|
Chris@16
|
30 #include "boost/type_traits.hpp"
|
Chris@16
|
31 #include <algorithm>
|
Chris@16
|
32 #include <cstddef>
|
Chris@16
|
33 #include <functional>
|
Chris@16
|
34 #include <numeric>
|
Chris@16
|
35 #include <vector>
|
Chris@16
|
36
|
Chris@16
|
37
|
Chris@16
|
38
|
Chris@16
|
39 namespace boost {
|
Chris@16
|
40 namespace detail {
|
Chris@16
|
41 namespace multi_array {
|
Chris@16
|
42
|
Chris@16
|
43 struct populate_index_ranges {
|
Chris@16
|
44 multi_array_types::index_range
|
Chris@16
|
45 // RG: underscore on extent_ to stifle strange MSVC warning.
|
Chris@16
|
46 operator()(multi_array_types::index base,
|
Chris@16
|
47 multi_array_types::size_type extent_) {
|
Chris@16
|
48 return multi_array_types::index_range(base,base+extent_);
|
Chris@16
|
49 }
|
Chris@16
|
50 };
|
Chris@16
|
51
|
Chris@16
|
52 #ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
Chris@16
|
53 //
|
Chris@16
|
54 // Compilers that don't support partial ordering may need help to
|
Chris@16
|
55 // disambiguate multi_array's templated constructors. Even vc6/7 are
|
Chris@16
|
56 // capable of some limited SFINAE, so we take the most-general version
|
Chris@16
|
57 // out of the overload set with disable_multi_array_impl.
|
Chris@16
|
58 //
|
Chris@16
|
59 template <typename T, std::size_t NumDims, typename TPtr>
|
Chris@16
|
60 char is_multi_array_impl_help(const_multi_array_view<T,NumDims,TPtr>&);
|
Chris@16
|
61 template <typename T, std::size_t NumDims, typename TPtr>
|
Chris@16
|
62 char is_multi_array_impl_help(const_sub_array<T,NumDims,TPtr>&);
|
Chris@16
|
63 template <typename T, std::size_t NumDims, typename TPtr>
|
Chris@16
|
64 char is_multi_array_impl_help(const_multi_array_ref<T,NumDims,TPtr>&);
|
Chris@16
|
65
|
Chris@16
|
66 char ( &is_multi_array_impl_help(...) )[2];
|
Chris@16
|
67
|
Chris@16
|
68 template <class T>
|
Chris@16
|
69 struct is_multi_array_impl
|
Chris@16
|
70 {
|
Chris@16
|
71 static T x;
|
Chris@16
|
72 BOOST_STATIC_CONSTANT(bool, value = sizeof((is_multi_array_impl_help)(x)) == 1);
|
Chris@16
|
73
|
Chris@16
|
74 typedef mpl::bool_<value> type;
|
Chris@16
|
75 };
|
Chris@16
|
76
|
Chris@16
|
77 template <bool multi_array = false>
|
Chris@16
|
78 struct disable_multi_array_impl_impl
|
Chris@16
|
79 {
|
Chris@16
|
80 typedef int type;
|
Chris@16
|
81 };
|
Chris@16
|
82
|
Chris@16
|
83 template <>
|
Chris@16
|
84 struct disable_multi_array_impl_impl<true>
|
Chris@16
|
85 {
|
Chris@16
|
86 // forming a pointer to a reference triggers SFINAE
|
Chris@16
|
87 typedef int& type;
|
Chris@16
|
88 };
|
Chris@16
|
89
|
Chris@16
|
90
|
Chris@16
|
91 template <class T>
|
Chris@16
|
92 struct disable_multi_array_impl :
|
Chris@16
|
93 disable_multi_array_impl_impl<is_multi_array_impl<T>::value>
|
Chris@16
|
94 { };
|
Chris@16
|
95
|
Chris@16
|
96
|
Chris@16
|
97 template <>
|
Chris@16
|
98 struct disable_multi_array_impl<int>
|
Chris@16
|
99 {
|
Chris@16
|
100 typedef int type;
|
Chris@16
|
101 };
|
Chris@16
|
102
|
Chris@16
|
103
|
Chris@16
|
104 #endif
|
Chris@16
|
105
|
Chris@16
|
106 } //namespace multi_array
|
Chris@16
|
107 } // namespace detail
|
Chris@16
|
108
|
Chris@16
|
109 template<typename T, std::size_t NumDims,
|
Chris@16
|
110 typename Allocator>
|
Chris@16
|
111 class multi_array :
|
Chris@16
|
112 public multi_array_ref<T,NumDims>
|
Chris@16
|
113 {
|
Chris@16
|
114 typedef multi_array_ref<T,NumDims> super_type;
|
Chris@16
|
115 public:
|
Chris@16
|
116 typedef typename super_type::value_type value_type;
|
Chris@16
|
117 typedef typename super_type::reference reference;
|
Chris@16
|
118 typedef typename super_type::const_reference const_reference;
|
Chris@16
|
119 typedef typename super_type::iterator iterator;
|
Chris@16
|
120 typedef typename super_type::const_iterator const_iterator;
|
Chris@16
|
121 typedef typename super_type::reverse_iterator reverse_iterator;
|
Chris@16
|
122 typedef typename super_type::const_reverse_iterator const_reverse_iterator;
|
Chris@16
|
123 typedef typename super_type::element element;
|
Chris@16
|
124 typedef typename super_type::size_type size_type;
|
Chris@16
|
125 typedef typename super_type::difference_type difference_type;
|
Chris@16
|
126 typedef typename super_type::index index;
|
Chris@16
|
127 typedef typename super_type::extent_range extent_range;
|
Chris@16
|
128
|
Chris@16
|
129
|
Chris@16
|
130 template <std::size_t NDims>
|
Chris@16
|
131 struct const_array_view {
|
Chris@16
|
132 typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
|
Chris@16
|
133 };
|
Chris@16
|
134
|
Chris@16
|
135 template <std::size_t NDims>
|
Chris@16
|
136 struct array_view {
|
Chris@16
|
137 typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
|
Chris@16
|
138 };
|
Chris@16
|
139
|
Chris@16
|
140 explicit multi_array() :
|
Chris@16
|
141 super_type((T*)initial_base_,c_storage_order(),
|
Chris@16
|
142 /*index_bases=*/0, /*extents=*/0) {
|
Chris@16
|
143 allocate_space();
|
Chris@16
|
144 }
|
Chris@16
|
145
|
Chris@16
|
146 template <class ExtentList>
|
Chris@16
|
147 explicit multi_array(
|
Chris@16
|
148 ExtentList const& extents
|
Chris@16
|
149 #ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
Chris@16
|
150 , typename mpl::if_<
|
Chris@16
|
151 detail::multi_array::is_multi_array_impl<ExtentList>,
|
Chris@16
|
152 int&,int>::type* = 0
|
Chris@16
|
153 #endif
|
Chris@16
|
154 ) :
|
Chris@16
|
155 super_type((T*)initial_base_,extents) {
|
Chris@16
|
156 boost::function_requires<
|
Chris@16
|
157 detail::multi_array::CollectionConcept<ExtentList> >();
|
Chris@16
|
158 allocate_space();
|
Chris@16
|
159 }
|
Chris@16
|
160
|
Chris@16
|
161
|
Chris@16
|
162 template <class ExtentList>
|
Chris@16
|
163 explicit multi_array(ExtentList const& extents,
|
Chris@16
|
164 const general_storage_order<NumDims>& so) :
|
Chris@16
|
165 super_type((T*)initial_base_,extents,so) {
|
Chris@16
|
166 boost::function_requires<
|
Chris@16
|
167 detail::multi_array::CollectionConcept<ExtentList> >();
|
Chris@16
|
168 allocate_space();
|
Chris@16
|
169 }
|
Chris@16
|
170
|
Chris@16
|
171 template <class ExtentList>
|
Chris@16
|
172 explicit multi_array(ExtentList const& extents,
|
Chris@16
|
173 const general_storage_order<NumDims>& so,
|
Chris@16
|
174 Allocator const& alloc) :
|
Chris@16
|
175 super_type((T*)initial_base_,extents,so), allocator_(alloc) {
|
Chris@16
|
176 boost::function_requires<
|
Chris@16
|
177 detail::multi_array::CollectionConcept<ExtentList> >();
|
Chris@16
|
178 allocate_space();
|
Chris@16
|
179 }
|
Chris@16
|
180
|
Chris@16
|
181
|
Chris@16
|
182 explicit multi_array(const detail::multi_array
|
Chris@16
|
183 ::extent_gen<NumDims>& ranges) :
|
Chris@16
|
184 super_type((T*)initial_base_,ranges) {
|
Chris@16
|
185
|
Chris@16
|
186 allocate_space();
|
Chris@16
|
187 }
|
Chris@16
|
188
|
Chris@16
|
189
|
Chris@16
|
190 explicit multi_array(const detail::multi_array
|
Chris@16
|
191 ::extent_gen<NumDims>& ranges,
|
Chris@16
|
192 const general_storage_order<NumDims>& so) :
|
Chris@16
|
193 super_type((T*)initial_base_,ranges,so) {
|
Chris@16
|
194
|
Chris@16
|
195 allocate_space();
|
Chris@16
|
196 }
|
Chris@16
|
197
|
Chris@16
|
198
|
Chris@16
|
199 explicit multi_array(const detail::multi_array
|
Chris@16
|
200 ::extent_gen<NumDims>& ranges,
|
Chris@16
|
201 const general_storage_order<NumDims>& so,
|
Chris@16
|
202 Allocator const& alloc) :
|
Chris@16
|
203 super_type((T*)initial_base_,ranges,so), allocator_(alloc) {
|
Chris@16
|
204
|
Chris@16
|
205 allocate_space();
|
Chris@16
|
206 }
|
Chris@16
|
207
|
Chris@16
|
208 multi_array(const multi_array& rhs) :
|
Chris@16
|
209 super_type(rhs), allocator_(rhs.allocator_) {
|
Chris@16
|
210 allocate_space();
|
Chris@16
|
211 boost::detail::multi_array::copy_n(rhs.base_,rhs.num_elements(),base_);
|
Chris@16
|
212 }
|
Chris@16
|
213
|
Chris@16
|
214
|
Chris@16
|
215 //
|
Chris@16
|
216 // A multi_array is constructible from any multi_array_ref, subarray, or
|
Chris@16
|
217 // array_view object. The following constructors ensure that.
|
Chris@16
|
218 //
|
Chris@16
|
219
|
Chris@16
|
220 // Due to limited support for partial template ordering,
|
Chris@16
|
221 // MSVC 6&7 confuse the following with the most basic ExtentList
|
Chris@16
|
222 // constructor.
|
Chris@16
|
223 #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
Chris@16
|
224 template <typename OPtr>
|
Chris@16
|
225 multi_array(const const_multi_array_ref<T,NumDims,OPtr>& rhs,
|
Chris@16
|
226 const general_storage_order<NumDims>& so = c_storage_order())
|
Chris@16
|
227 : super_type(0,so,rhs.index_bases(),rhs.shape())
|
Chris@16
|
228 {
|
Chris@16
|
229 allocate_space();
|
Chris@16
|
230 // Warning! storage order may change, hence the following copy technique.
|
Chris@16
|
231 std::copy(rhs.begin(),rhs.end(),this->begin());
|
Chris@16
|
232 }
|
Chris@16
|
233
|
Chris@16
|
234 template <typename OPtr>
|
Chris@16
|
235 multi_array(const detail::multi_array::
|
Chris@16
|
236 const_sub_array<T,NumDims,OPtr>& rhs,
|
Chris@16
|
237 const general_storage_order<NumDims>& so = c_storage_order())
|
Chris@16
|
238 : super_type(0,so,rhs.index_bases(),rhs.shape())
|
Chris@16
|
239 {
|
Chris@16
|
240 allocate_space();
|
Chris@16
|
241 std::copy(rhs.begin(),rhs.end(),this->begin());
|
Chris@16
|
242 }
|
Chris@16
|
243
|
Chris@16
|
244
|
Chris@16
|
245 template <typename OPtr>
|
Chris@16
|
246 multi_array(const detail::multi_array::
|
Chris@16
|
247 const_multi_array_view<T,NumDims,OPtr>& rhs,
|
Chris@16
|
248 const general_storage_order<NumDims>& so = c_storage_order())
|
Chris@16
|
249 : super_type(0,so,rhs.index_bases(),rhs.shape())
|
Chris@16
|
250 {
|
Chris@16
|
251 allocate_space();
|
Chris@16
|
252 std::copy(rhs.begin(),rhs.end(),this->begin());
|
Chris@16
|
253 }
|
Chris@16
|
254
|
Chris@16
|
255 #else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
Chris@16
|
256 // More limited support for MSVC
|
Chris@16
|
257
|
Chris@16
|
258
|
Chris@16
|
259 multi_array(const const_multi_array_ref<T,NumDims>& rhs)
|
Chris@16
|
260 : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape())
|
Chris@16
|
261 {
|
Chris@16
|
262 allocate_space();
|
Chris@16
|
263 // Warning! storage order may change, hence the following copy technique.
|
Chris@16
|
264 std::copy(rhs.begin(),rhs.end(),this->begin());
|
Chris@16
|
265 }
|
Chris@16
|
266
|
Chris@16
|
267 multi_array(const const_multi_array_ref<T,NumDims>& rhs,
|
Chris@16
|
268 const general_storage_order<NumDims>& so)
|
Chris@16
|
269 : super_type(0,so,rhs.index_bases(),rhs.shape())
|
Chris@16
|
270 {
|
Chris@16
|
271 allocate_space();
|
Chris@16
|
272 // Warning! storage order may change, hence the following copy technique.
|
Chris@16
|
273 std::copy(rhs.begin(),rhs.end(),this->begin());
|
Chris@16
|
274 }
|
Chris@16
|
275
|
Chris@16
|
276 multi_array(const detail::multi_array::
|
Chris@16
|
277 const_sub_array<T,NumDims>& rhs)
|
Chris@16
|
278 : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape())
|
Chris@16
|
279 {
|
Chris@16
|
280 allocate_space();
|
Chris@16
|
281 std::copy(rhs.begin(),rhs.end(),this->begin());
|
Chris@16
|
282 }
|
Chris@16
|
283
|
Chris@16
|
284 multi_array(const detail::multi_array::
|
Chris@16
|
285 const_sub_array<T,NumDims>& rhs,
|
Chris@16
|
286 const general_storage_order<NumDims>& so)
|
Chris@16
|
287 : super_type(0,so,rhs.index_bases(),rhs.shape())
|
Chris@16
|
288 {
|
Chris@16
|
289 allocate_space();
|
Chris@16
|
290 std::copy(rhs.begin(),rhs.end(),this->begin());
|
Chris@16
|
291 }
|
Chris@16
|
292
|
Chris@16
|
293
|
Chris@16
|
294 multi_array(const detail::multi_array::
|
Chris@16
|
295 const_multi_array_view<T,NumDims>& rhs)
|
Chris@16
|
296 : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape())
|
Chris@16
|
297 {
|
Chris@16
|
298 allocate_space();
|
Chris@16
|
299 std::copy(rhs.begin(),rhs.end(),this->begin());
|
Chris@16
|
300 }
|
Chris@16
|
301
|
Chris@16
|
302 multi_array(const detail::multi_array::
|
Chris@16
|
303 const_multi_array_view<T,NumDims>& rhs,
|
Chris@16
|
304 const general_storage_order<NumDims>& so)
|
Chris@16
|
305 : super_type(0,so,rhs.index_bases(),rhs.shape())
|
Chris@16
|
306 {
|
Chris@16
|
307 allocate_space();
|
Chris@16
|
308 std::copy(rhs.begin(),rhs.end(),this->begin());
|
Chris@16
|
309 }
|
Chris@16
|
310
|
Chris@16
|
311 #endif // !BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
Chris@16
|
312
|
Chris@16
|
313 // Thes constructors are necessary because of more exact template matches.
|
Chris@16
|
314 multi_array(const multi_array_ref<T,NumDims>& rhs)
|
Chris@16
|
315 : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape())
|
Chris@16
|
316 {
|
Chris@16
|
317 allocate_space();
|
Chris@16
|
318 // Warning! storage order may change, hence the following copy technique.
|
Chris@16
|
319 std::copy(rhs.begin(),rhs.end(),this->begin());
|
Chris@16
|
320 }
|
Chris@16
|
321
|
Chris@16
|
322 multi_array(const multi_array_ref<T,NumDims>& rhs,
|
Chris@16
|
323 const general_storage_order<NumDims>& so)
|
Chris@16
|
324 : super_type(0,so,rhs.index_bases(),rhs.shape())
|
Chris@16
|
325 {
|
Chris@16
|
326 allocate_space();
|
Chris@16
|
327 // Warning! storage order may change, hence the following copy technique.
|
Chris@16
|
328 std::copy(rhs.begin(),rhs.end(),this->begin());
|
Chris@16
|
329 }
|
Chris@16
|
330
|
Chris@16
|
331
|
Chris@16
|
332 multi_array(const detail::multi_array::
|
Chris@16
|
333 sub_array<T,NumDims>& rhs)
|
Chris@16
|
334 : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape())
|
Chris@16
|
335 {
|
Chris@16
|
336 allocate_space();
|
Chris@16
|
337 std::copy(rhs.begin(),rhs.end(),this->begin());
|
Chris@16
|
338 }
|
Chris@16
|
339
|
Chris@16
|
340 multi_array(const detail::multi_array::
|
Chris@16
|
341 sub_array<T,NumDims>& rhs,
|
Chris@16
|
342 const general_storage_order<NumDims>& so)
|
Chris@16
|
343 : super_type(0,so,rhs.index_bases(),rhs.shape())
|
Chris@16
|
344 {
|
Chris@16
|
345 allocate_space();
|
Chris@16
|
346 std::copy(rhs.begin(),rhs.end(),this->begin());
|
Chris@16
|
347 }
|
Chris@16
|
348
|
Chris@16
|
349
|
Chris@16
|
350 multi_array(const detail::multi_array::
|
Chris@16
|
351 multi_array_view<T,NumDims>& rhs)
|
Chris@16
|
352 : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape())
|
Chris@16
|
353 {
|
Chris@16
|
354 allocate_space();
|
Chris@16
|
355 std::copy(rhs.begin(),rhs.end(),this->begin());
|
Chris@16
|
356 }
|
Chris@16
|
357
|
Chris@16
|
358 multi_array(const detail::multi_array::
|
Chris@16
|
359 multi_array_view<T,NumDims>& rhs,
|
Chris@16
|
360 const general_storage_order<NumDims>& so)
|
Chris@16
|
361 : super_type(0,so,rhs.index_bases(),rhs.shape())
|
Chris@16
|
362 {
|
Chris@16
|
363 allocate_space();
|
Chris@16
|
364 std::copy(rhs.begin(),rhs.end(),this->begin());
|
Chris@16
|
365 }
|
Chris@16
|
366
|
Chris@16
|
367 // Since assignment is a deep copy, multi_array_ref
|
Chris@16
|
368 // contains all the necessary code.
|
Chris@16
|
369 template <typename ConstMultiArray>
|
Chris@16
|
370 multi_array& operator=(const ConstMultiArray& other) {
|
Chris@16
|
371 super_type::operator=(other);
|
Chris@16
|
372 return *this;
|
Chris@16
|
373 }
|
Chris@16
|
374
|
Chris@16
|
375 multi_array& operator=(const multi_array& other) {
|
Chris@16
|
376 if (&other != this) {
|
Chris@16
|
377 super_type::operator=(other);
|
Chris@16
|
378 }
|
Chris@16
|
379 return *this;
|
Chris@16
|
380 }
|
Chris@16
|
381
|
Chris@16
|
382
|
Chris@16
|
383 template <typename ExtentList>
|
Chris@16
|
384 multi_array& resize(const ExtentList& extents) {
|
Chris@16
|
385 boost::function_requires<
|
Chris@16
|
386 detail::multi_array::CollectionConcept<ExtentList> >();
|
Chris@16
|
387
|
Chris@16
|
388 typedef detail::multi_array::extent_gen<NumDims> gen_type;
|
Chris@16
|
389 gen_type ranges;
|
Chris@16
|
390
|
Chris@16
|
391 for (int i=0; i != NumDims; ++i) {
|
Chris@16
|
392 typedef typename gen_type::range range_type;
|
Chris@16
|
393 ranges.ranges_[i] = range_type(0,extents[i]);
|
Chris@16
|
394 }
|
Chris@16
|
395
|
Chris@16
|
396 return this->resize(ranges);
|
Chris@16
|
397 }
|
Chris@16
|
398
|
Chris@16
|
399
|
Chris@16
|
400
|
Chris@16
|
401 multi_array& resize(const detail::multi_array
|
Chris@16
|
402 ::extent_gen<NumDims>& ranges) {
|
Chris@16
|
403
|
Chris@16
|
404
|
Chris@16
|
405 // build a multi_array with the specs given
|
Chris@16
|
406 multi_array new_array(ranges,this->storage_order());
|
Chris@16
|
407
|
Chris@16
|
408
|
Chris@16
|
409 // build a view of tmp with the minimum extents
|
Chris@16
|
410
|
Chris@16
|
411 // Get the minimum extents of the arrays.
|
Chris@16
|
412 boost::array<size_type,NumDims> min_extents;
|
Chris@16
|
413
|
Chris@16
|
414 const size_type& (*min)(const size_type&, const size_type&) =
|
Chris@16
|
415 std::min;
|
Chris@16
|
416 std::transform(new_array.extent_list_.begin(),new_array.extent_list_.end(),
|
Chris@16
|
417 this->extent_list_.begin(),
|
Chris@16
|
418 min_extents.begin(),
|
Chris@16
|
419 min);
|
Chris@16
|
420
|
Chris@16
|
421
|
Chris@16
|
422 // typedef boost::array<index,NumDims> index_list;
|
Chris@16
|
423 // Build index_gen objects to create views with the same shape
|
Chris@16
|
424
|
Chris@16
|
425 // these need to be separate to handle non-zero index bases
|
Chris@16
|
426 typedef detail::multi_array::index_gen<NumDims,NumDims> index_gen;
|
Chris@16
|
427 index_gen old_idxes;
|
Chris@16
|
428 index_gen new_idxes;
|
Chris@16
|
429
|
Chris@16
|
430 std::transform(new_array.index_base_list_.begin(),
|
Chris@16
|
431 new_array.index_base_list_.end(),
|
Chris@16
|
432 min_extents.begin(),new_idxes.ranges_.begin(),
|
Chris@16
|
433 detail::multi_array::populate_index_ranges());
|
Chris@16
|
434
|
Chris@16
|
435 std::transform(this->index_base_list_.begin(),
|
Chris@16
|
436 this->index_base_list_.end(),
|
Chris@16
|
437 min_extents.begin(),old_idxes.ranges_.begin(),
|
Chris@16
|
438 detail::multi_array::populate_index_ranges());
|
Chris@16
|
439
|
Chris@16
|
440 // Build same-shape views of the two arrays
|
Chris@16
|
441 typename
|
Chris@16
|
442 multi_array::BOOST_NESTED_TEMPLATE array_view<NumDims>::type view_old = (*this)[old_idxes];
|
Chris@16
|
443 typename
|
Chris@16
|
444 multi_array::BOOST_NESTED_TEMPLATE array_view<NumDims>::type view_new = new_array[new_idxes];
|
Chris@16
|
445
|
Chris@16
|
446 // Set the right portion of the new array
|
Chris@16
|
447 view_new = view_old;
|
Chris@16
|
448
|
Chris@16
|
449 using std::swap;
|
Chris@16
|
450 // Swap the internals of these arrays.
|
Chris@16
|
451 swap(this->super_type::base_,new_array.super_type::base_);
|
Chris@16
|
452 swap(this->storage_,new_array.storage_);
|
Chris@16
|
453 swap(this->extent_list_,new_array.extent_list_);
|
Chris@16
|
454 swap(this->stride_list_,new_array.stride_list_);
|
Chris@16
|
455 swap(this->index_base_list_,new_array.index_base_list_);
|
Chris@16
|
456 swap(this->origin_offset_,new_array.origin_offset_);
|
Chris@16
|
457 swap(this->directional_offset_,new_array.directional_offset_);
|
Chris@16
|
458 swap(this->num_elements_,new_array.num_elements_);
|
Chris@16
|
459 swap(this->allocator_,new_array.allocator_);
|
Chris@16
|
460 swap(this->base_,new_array.base_);
|
Chris@16
|
461 swap(this->allocated_elements_,new_array.allocated_elements_);
|
Chris@16
|
462
|
Chris@16
|
463 return *this;
|
Chris@16
|
464 }
|
Chris@16
|
465
|
Chris@16
|
466
|
Chris@16
|
467 ~multi_array() {
|
Chris@16
|
468 deallocate_space();
|
Chris@16
|
469 }
|
Chris@16
|
470
|
Chris@16
|
471 private:
|
Chris@16
|
472 void allocate_space() {
|
Chris@16
|
473 typename Allocator::const_pointer no_hint=0;
|
Chris@16
|
474 base_ = allocator_.allocate(this->num_elements(),no_hint);
|
Chris@16
|
475 this->set_base_ptr(base_);
|
Chris@16
|
476 allocated_elements_ = this->num_elements();
|
Chris@16
|
477 std::uninitialized_fill_n(base_,allocated_elements_,T());
|
Chris@16
|
478 }
|
Chris@16
|
479
|
Chris@16
|
480 void deallocate_space() {
|
Chris@16
|
481 if(base_) {
|
Chris@16
|
482 for(T* i = base_; i != base_+allocated_elements_; ++i)
|
Chris@16
|
483 allocator_.destroy(i);
|
Chris@16
|
484 allocator_.deallocate(base_,allocated_elements_);
|
Chris@16
|
485 }
|
Chris@16
|
486 }
|
Chris@16
|
487
|
Chris@16
|
488 typedef boost::array<size_type,NumDims> size_list;
|
Chris@16
|
489 typedef boost::array<index,NumDims> index_list;
|
Chris@16
|
490
|
Chris@16
|
491 Allocator allocator_;
|
Chris@16
|
492 T* base_;
|
Chris@16
|
493 size_type allocated_elements_;
|
Chris@16
|
494 enum {initial_base_ = 0};
|
Chris@16
|
495 };
|
Chris@16
|
496
|
Chris@16
|
497 } // namespace boost
|
Chris@16
|
498
|
Chris@16
|
499 #endif // BOOST_MULTI_ARRAY_RG071801_HPP
|