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