Warning, file /include/boost/multi_array.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef BOOST_MULTI_ARRAY_HPP
0017 #define BOOST_MULTI_ARRAY_HPP
0018
0019
0020
0021
0022
0023
0024 #if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 406)
0025 # pragma GCC diagnostic push
0026 # pragma GCC diagnostic ignored "-Wshadow"
0027 #endif
0028
0029 #include "boost/multi_array/base.hpp"
0030 #include "boost/multi_array/collection_concept.hpp"
0031 #include "boost/multi_array/copy_array.hpp"
0032 #include "boost/multi_array/iterator.hpp"
0033 #include "boost/multi_array/subarray.hpp"
0034 #include "boost/multi_array/multi_array_ref.hpp"
0035 #include "boost/multi_array/algorithm.hpp"
0036 #include "boost/core/alloc_construct.hpp"
0037 #include "boost/core/empty_value.hpp"
0038 #include "boost/array.hpp"
0039 #include "boost/mpl/if.hpp"
0040 #include "boost/type_traits.hpp"
0041 #include <algorithm>
0042 #include <cstddef>
0043 #include <functional>
0044 #include <numeric>
0045 #include <vector>
0046
0047
0048
0049 namespace boost {
0050 namespace detail {
0051 namespace multi_array {
0052
0053 struct populate_index_ranges {
0054 multi_array_types::index_range
0055
0056 operator()(multi_array_types::index base,
0057 multi_array_types::size_type extent_) {
0058 return multi_array_types::index_range(base,base+extent_);
0059 }
0060 };
0061
0062 #ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
0063
0064
0065
0066
0067
0068
0069 template <typename T, std::size_t NumDims, typename TPtr>
0070 char is_multi_array_impl_help(const_multi_array_view<T,NumDims,TPtr>&);
0071 template <typename T, std::size_t NumDims, typename TPtr>
0072 char is_multi_array_impl_help(const_sub_array<T,NumDims,TPtr>&);
0073 template <typename T, std::size_t NumDims, typename TPtr>
0074 char is_multi_array_impl_help(const_multi_array_ref<T,NumDims,TPtr>&);
0075
0076 char ( &is_multi_array_impl_help(...) )[2];
0077
0078 template <class T>
0079 struct is_multi_array_impl
0080 {
0081 static T x;
0082 BOOST_STATIC_CONSTANT(bool, value = sizeof((is_multi_array_impl_help)(x)) == 1);
0083
0084 typedef mpl::bool_<value> type;
0085 };
0086
0087 template <bool multi_array = false>
0088 struct disable_multi_array_impl_impl
0089 {
0090 typedef int type;
0091 };
0092
0093 template <>
0094 struct disable_multi_array_impl_impl<true>
0095 {
0096
0097 typedef int& type;
0098 };
0099
0100
0101 template <class T>
0102 struct disable_multi_array_impl :
0103 disable_multi_array_impl_impl<is_multi_array_impl<T>::value>
0104 { };
0105
0106
0107 template <>
0108 struct disable_multi_array_impl<int>
0109 {
0110 typedef int type;
0111 };
0112
0113
0114 #endif
0115
0116 }
0117 }
0118
0119 template<typename T, std::size_t NumDims,
0120 typename Allocator>
0121 class multi_array :
0122 public multi_array_ref<T,NumDims>,
0123 private boost::empty_value<Allocator>
0124 {
0125 typedef boost::empty_value<Allocator> alloc_base;
0126 typedef multi_array_ref<T,NumDims> super_type;
0127 public:
0128 typedef typename super_type::value_type value_type;
0129 typedef typename super_type::reference reference;
0130 typedef typename super_type::const_reference const_reference;
0131 typedef typename super_type::iterator iterator;
0132 typedef typename super_type::const_iterator const_iterator;
0133 typedef typename super_type::reverse_iterator reverse_iterator;
0134 typedef typename super_type::const_reverse_iterator const_reverse_iterator;
0135 typedef typename super_type::element element;
0136 typedef typename super_type::size_type size_type;
0137 typedef typename super_type::difference_type difference_type;
0138 typedef typename super_type::index index;
0139 typedef typename super_type::extent_range extent_range;
0140
0141
0142 template <std::size_t NDims>
0143 struct const_array_view {
0144 typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
0145 };
0146
0147 template <std::size_t NDims>
0148 struct array_view {
0149 typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
0150 };
0151
0152 explicit multi_array(const Allocator& alloc = Allocator()) :
0153 super_type((T*)initial_base_,c_storage_order(),
0154 0, 0),
0155 alloc_base(boost::empty_init_t(),alloc) {
0156 allocate_space();
0157 }
0158
0159 template <class ExtentList>
0160 explicit multi_array(
0161 ExtentList const& extents,
0162 const Allocator& alloc = Allocator()
0163 #ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
0164 , typename mpl::if_<
0165 detail::multi_array::is_multi_array_impl<ExtentList>,
0166 int&,int>::type* = 0
0167 #endif
0168 ) :
0169 super_type((T*)initial_base_,extents),
0170 alloc_base(boost::empty_init_t(),alloc) {
0171 boost::function_requires<
0172 detail::multi_array::CollectionConcept<ExtentList> >();
0173 allocate_space();
0174 }
0175
0176
0177 template <class ExtentList>
0178 explicit multi_array(ExtentList const& extents,
0179 const general_storage_order<NumDims>& so) :
0180 super_type((T*)initial_base_,extents,so),
0181 alloc_base(boost::empty_init_t()) {
0182 boost::function_requires<
0183 detail::multi_array::CollectionConcept<ExtentList> >();
0184 allocate_space();
0185 }
0186
0187 template <class ExtentList>
0188 explicit multi_array(ExtentList const& extents,
0189 const general_storage_order<NumDims>& so,
0190 Allocator const& alloc) :
0191 super_type((T*)initial_base_,extents,so),
0192 alloc_base(boost::empty_init_t(),alloc) {
0193 boost::function_requires<
0194 detail::multi_array::CollectionConcept<ExtentList> >();
0195 allocate_space();
0196 }
0197
0198
0199 explicit multi_array(const detail::multi_array
0200 ::extent_gen<NumDims>& ranges,
0201 const Allocator& alloc = Allocator()) :
0202 super_type((T*)initial_base_,ranges),
0203 alloc_base(boost::empty_init_t(),alloc) {
0204
0205 allocate_space();
0206 }
0207
0208
0209 explicit multi_array(const detail::multi_array
0210 ::extent_gen<NumDims>& ranges,
0211 const general_storage_order<NumDims>& so) :
0212 super_type((T*)initial_base_,ranges,so),
0213 alloc_base(boost::empty_init_t()) {
0214
0215 allocate_space();
0216 }
0217
0218
0219 explicit multi_array(const detail::multi_array
0220 ::extent_gen<NumDims>& ranges,
0221 const general_storage_order<NumDims>& so,
0222 Allocator const& alloc) :
0223 super_type((T*)initial_base_,ranges,so),
0224 alloc_base(boost::empty_init_t(),alloc) {
0225
0226 allocate_space();
0227 }
0228
0229 multi_array(const multi_array& rhs) :
0230 super_type(rhs),
0231 alloc_base(static_cast<const alloc_base&>(rhs)) {
0232 allocate_space();
0233 boost::detail::multi_array::copy_n(rhs.base_,rhs.num_elements(),base_);
0234 }
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245 #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
0246 template <typename OPtr>
0247 multi_array(const const_multi_array_ref<T,NumDims,OPtr>& rhs,
0248 const general_storage_order<NumDims>& so = c_storage_order(),
0249 const Allocator& alloc = Allocator())
0250 : super_type(0,so,rhs.index_bases(),rhs.shape()),
0251 alloc_base(boost::empty_init_t(),alloc)
0252 {
0253 allocate_space();
0254
0255 std::copy(rhs.begin(),rhs.end(),this->begin());
0256 }
0257
0258 template <typename OPtr>
0259 multi_array(const detail::multi_array::
0260 const_sub_array<T,NumDims,OPtr>& rhs,
0261 const general_storage_order<NumDims>& so = c_storage_order(),
0262 const Allocator& alloc = Allocator())
0263 : super_type(0,so,rhs.index_bases(),rhs.shape()),
0264 alloc_base(boost::empty_init_t(),alloc)
0265 {
0266 allocate_space();
0267 std::copy(rhs.begin(),rhs.end(),this->begin());
0268 }
0269
0270
0271 template <typename OPtr>
0272 multi_array(const detail::multi_array::
0273 const_multi_array_view<T,NumDims,OPtr>& rhs,
0274 const general_storage_order<NumDims>& so = c_storage_order(),
0275 const Allocator& alloc = Allocator())
0276 : super_type(0,so,rhs.index_bases(),rhs.shape()),
0277 alloc_base(boost::empty_init_t(),alloc)
0278 {
0279 allocate_space();
0280 std::copy(rhs.begin(),rhs.end(),this->begin());
0281 }
0282
0283 #else
0284
0285
0286
0287 multi_array(const const_multi_array_ref<T,NumDims>& rhs,
0288 const Allocator& alloc = Allocator())
0289 : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape()),
0290 alloc_base(boost::empty_init_t(),alloc)
0291 {
0292 allocate_space();
0293
0294 std::copy(rhs.begin(),rhs.end(),this->begin());
0295 }
0296
0297 multi_array(const const_multi_array_ref<T,NumDims>& rhs,
0298 const general_storage_order<NumDims>& so,
0299 const Allocator& alloc = Allocator())
0300 : super_type(0,so,rhs.index_bases(),rhs.shape()),
0301 alloc_base(boost::empty_init_t(),alloc)
0302 {
0303 allocate_space();
0304
0305 std::copy(rhs.begin(),rhs.end(),this->begin());
0306 }
0307
0308 multi_array(const detail::multi_array::
0309 const_sub_array<T,NumDims>& rhs,
0310 const Allocator& alloc = Allocator())
0311 : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape()),
0312 alloc_base(boost::empty_init_t(),alloc)
0313 {
0314 allocate_space();
0315 std::copy(rhs.begin(),rhs.end(),this->begin());
0316 }
0317
0318 multi_array(const detail::multi_array::
0319 const_sub_array<T,NumDims>& rhs,
0320 const general_storage_order<NumDims>& so,
0321 const Allocator& alloc = Allocator())
0322 : super_type(0,so,rhs.index_bases(),rhs.shape()),
0323 alloc_base(boost::empty_init_t(),alloc)
0324 {
0325 allocate_space();
0326 std::copy(rhs.begin(),rhs.end(),this->begin());
0327 }
0328
0329
0330 multi_array(const detail::multi_array::
0331 const_multi_array_view<T,NumDims>& rhs,
0332 const Allocator& alloc = Allocator())
0333 : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape()),
0334 alloc_base(boost::empty_init_t(),alloc)
0335 {
0336 allocate_space();
0337 std::copy(rhs.begin(),rhs.end(),this->begin());
0338 }
0339
0340 multi_array(const detail::multi_array::
0341 const_multi_array_view<T,NumDims>& rhs,
0342 const general_storage_order<NumDims>& so,
0343 const Allocator& alloc = Allocator())
0344 : super_type(0,so,rhs.index_bases(),rhs.shape()),
0345 alloc_base(boost::empty_init_t(),alloc)
0346 {
0347 allocate_space();
0348 std::copy(rhs.begin(),rhs.end(),this->begin());
0349 }
0350
0351 #endif
0352
0353
0354 multi_array(const multi_array_ref<T,NumDims>& rhs,
0355 const Allocator& alloc = Allocator())
0356 : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape()),
0357 alloc_base(boost::empty_init_t(),alloc)
0358 {
0359 allocate_space();
0360
0361 std::copy(rhs.begin(),rhs.end(),this->begin());
0362 }
0363
0364 multi_array(const multi_array_ref<T,NumDims>& rhs,
0365 const general_storage_order<NumDims>& so,
0366 const Allocator& alloc = Allocator())
0367 : super_type(0,so,rhs.index_bases(),rhs.shape()),
0368 alloc_base(boost::empty_init_t(),alloc)
0369 {
0370 allocate_space();
0371
0372 std::copy(rhs.begin(),rhs.end(),this->begin());
0373 }
0374
0375
0376 multi_array(const detail::multi_array::
0377 sub_array<T,NumDims>& rhs,
0378 const Allocator& alloc = Allocator())
0379 : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape()),
0380 alloc_base(boost::empty_init_t(),alloc)
0381 {
0382 allocate_space();
0383 std::copy(rhs.begin(),rhs.end(),this->begin());
0384 }
0385
0386 multi_array(const detail::multi_array::
0387 sub_array<T,NumDims>& rhs,
0388 const general_storage_order<NumDims>& so,
0389 const Allocator& alloc = Allocator())
0390 : super_type(0,so,rhs.index_bases(),rhs.shape()),
0391 alloc_base(boost::empty_init_t(),alloc)
0392 {
0393 allocate_space();
0394 std::copy(rhs.begin(),rhs.end(),this->begin());
0395 }
0396
0397
0398 multi_array(const detail::multi_array::
0399 multi_array_view<T,NumDims>& rhs,
0400 const Allocator& alloc = Allocator())
0401 : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape()),
0402 alloc_base(boost::empty_init_t(),alloc)
0403 {
0404 allocate_space();
0405 std::copy(rhs.begin(),rhs.end(),this->begin());
0406 }
0407
0408 multi_array(const detail::multi_array::
0409 multi_array_view<T,NumDims>& rhs,
0410 const general_storage_order<NumDims>& so,
0411 const Allocator& alloc = Allocator())
0412 : super_type(0,so,rhs.index_bases(),rhs.shape()),
0413 alloc_base(boost::empty_init_t(),alloc)
0414 {
0415 allocate_space();
0416 std::copy(rhs.begin(),rhs.end(),this->begin());
0417 }
0418
0419
0420
0421 template <typename ConstMultiArray>
0422 multi_array& operator=(const ConstMultiArray& other) {
0423 super_type::operator=(other);
0424 return *this;
0425 }
0426
0427 multi_array& operator=(const multi_array& other) {
0428 if (&other != this) {
0429 super_type::operator=(other);
0430 }
0431 return *this;
0432 }
0433
0434
0435 template <typename ExtentList>
0436 multi_array& resize(const ExtentList& extents) {
0437 boost::function_requires<
0438 detail::multi_array::CollectionConcept<ExtentList> >();
0439
0440 typedef detail::multi_array::extent_gen<NumDims> gen_type;
0441 gen_type ranges;
0442
0443 for (int i=0; i != NumDims; ++i) {
0444 typedef typename gen_type::range range_type;
0445 ranges.ranges_[i] = range_type(0,extents[i]);
0446 }
0447
0448 return this->resize(ranges);
0449 }
0450
0451
0452
0453 multi_array& resize(const detail::multi_array
0454 ::extent_gen<NumDims>& ranges) {
0455
0456
0457
0458 multi_array new_array(ranges,this->storage_order(),allocator());
0459
0460
0461
0462
0463
0464 boost::array<size_type,NumDims> min_extents;
0465
0466 const size_type& (*min)(const size_type&, const size_type&) =
0467 std::min;
0468 std::transform(new_array.extent_list_.begin(),new_array.extent_list_.end(),
0469 this->extent_list_.begin(),
0470 min_extents.begin(),
0471 min);
0472
0473
0474
0475
0476
0477
0478 typedef detail::multi_array::index_gen<NumDims,NumDims> index_gen;
0479 index_gen old_idxes;
0480 index_gen new_idxes;
0481
0482 std::transform(new_array.index_base_list_.begin(),
0483 new_array.index_base_list_.end(),
0484 min_extents.begin(),new_idxes.ranges_.begin(),
0485 detail::multi_array::populate_index_ranges());
0486
0487 std::transform(this->index_base_list_.begin(),
0488 this->index_base_list_.end(),
0489 min_extents.begin(),old_idxes.ranges_.begin(),
0490 detail::multi_array::populate_index_ranges());
0491
0492
0493 typename
0494 multi_array::BOOST_NESTED_TEMPLATE array_view<NumDims>::type view_old = (*this)[old_idxes];
0495 typename
0496 multi_array::BOOST_NESTED_TEMPLATE array_view<NumDims>::type view_new = new_array[new_idxes];
0497
0498
0499 view_new = view_old;
0500
0501 using std::swap;
0502
0503 swap(this->super_type::base_,new_array.super_type::base_);
0504 swap(this->allocator(),new_array.allocator());
0505 swap(this->storage_,new_array.storage_);
0506 swap(this->extent_list_,new_array.extent_list_);
0507 swap(this->stride_list_,new_array.stride_list_);
0508 swap(this->index_base_list_,new_array.index_base_list_);
0509 swap(this->origin_offset_,new_array.origin_offset_);
0510 swap(this->directional_offset_,new_array.directional_offset_);
0511 swap(this->num_elements_,new_array.num_elements_);
0512 swap(this->base_,new_array.base_);
0513 swap(this->allocated_elements_,new_array.allocated_elements_);
0514
0515 return *this;
0516 }
0517
0518
0519 ~multi_array() {
0520 deallocate_space();
0521 }
0522
0523 private:
0524 friend inline bool operator==(const multi_array& a, const multi_array& b) {
0525 return a.base() == b.base();
0526 }
0527
0528 friend inline bool operator!=(const multi_array& a, const multi_array& b) {
0529 return !(a == b);
0530 }
0531
0532 const super_type& base() const {
0533 return *this;
0534 }
0535
0536 const Allocator& allocator() const {
0537 return alloc_base::get();
0538 }
0539
0540 Allocator& allocator() {
0541 return alloc_base::get();
0542 }
0543
0544 void allocate_space() {
0545 base_ = allocator().allocate(this->num_elements());
0546 this->set_base_ptr(base_);
0547 allocated_elements_ = this->num_elements();
0548 boost::alloc_construct_n(allocator(),base_,allocated_elements_);
0549 }
0550
0551 void deallocate_space() {
0552 if(base_) {
0553 boost::alloc_destroy_n(allocator(),base_,allocated_elements_);
0554 allocator().deallocate(base_,allocated_elements_);
0555 }
0556 }
0557
0558 typedef boost::array<size_type,NumDims> size_list;
0559 typedef boost::array<index,NumDims> index_list;
0560
0561 T* base_;
0562 size_type allocated_elements_;
0563 enum {initial_base_ = 0};
0564 };
0565
0566 }
0567
0568 #if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 406)
0569 # pragma GCC diagnostic pop
0570 #endif
0571
0572 #endif