annotate DEPENDENCIES/generic/include/boost/multi_array/multi_array_ref.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents c530137014c0
children
rev   line source
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_REF_RG071801_HPP
Chris@16 14 #define BOOST_MULTI_ARRAY_REF_RG071801_HPP
Chris@16 15
Chris@16 16 //
Chris@16 17 // multi_array_ref.hpp - code for creating "views" of array data.
Chris@16 18 //
Chris@16 19
Chris@16 20 #include "boost/multi_array/base.hpp"
Chris@16 21 #include "boost/multi_array/collection_concept.hpp"
Chris@16 22 #include "boost/multi_array/concept_checks.hpp"
Chris@16 23 #include "boost/multi_array/iterator.hpp"
Chris@16 24 #include "boost/multi_array/storage_order.hpp"
Chris@16 25 #include "boost/multi_array/subarray.hpp"
Chris@16 26 #include "boost/multi_array/view.hpp"
Chris@16 27 #include "boost/multi_array/algorithm.hpp"
Chris@16 28 #include "boost/type_traits/is_integral.hpp"
Chris@16 29 #include "boost/utility/enable_if.hpp"
Chris@16 30 #include "boost/array.hpp"
Chris@16 31 #include "boost/concept_check.hpp"
Chris@16 32 #include "boost/functional.hpp"
Chris@16 33 #include "boost/limits.hpp"
Chris@16 34 #include <algorithm>
Chris@16 35 #include <cstddef>
Chris@16 36 #include <functional>
Chris@16 37 #include <numeric>
Chris@16 38
Chris@16 39 namespace boost {
Chris@16 40
Chris@16 41 template <typename T, std::size_t NumDims,
Chris@16 42 typename TPtr = const T*
Chris@16 43 >
Chris@16 44 class const_multi_array_ref :
Chris@16 45 public detail::multi_array::multi_array_impl_base<T,NumDims>
Chris@16 46 {
Chris@16 47 typedef detail::multi_array::multi_array_impl_base<T,NumDims> super_type;
Chris@16 48 public:
Chris@16 49 typedef typename super_type::value_type value_type;
Chris@16 50 typedef typename super_type::const_reference const_reference;
Chris@16 51 typedef typename super_type::const_iterator const_iterator;
Chris@16 52 typedef typename super_type::const_reverse_iterator const_reverse_iterator;
Chris@16 53 typedef typename super_type::element element;
Chris@16 54 typedef typename super_type::size_type size_type;
Chris@16 55 typedef typename super_type::difference_type difference_type;
Chris@16 56 typedef typename super_type::index index;
Chris@16 57 typedef typename super_type::extent_range extent_range;
Chris@16 58 typedef general_storage_order<NumDims> storage_order_type;
Chris@16 59
Chris@16 60 // template typedefs
Chris@16 61 template <std::size_t NDims>
Chris@16 62 struct const_array_view {
Chris@16 63 typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
Chris@16 64 };
Chris@16 65
Chris@16 66 template <std::size_t NDims>
Chris@16 67 struct array_view {
Chris@16 68 typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
Chris@16 69 };
Chris@16 70
Chris@16 71 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
Chris@16 72 // make const_multi_array_ref a friend of itself
Chris@16 73 template <typename,std::size_t,typename>
Chris@16 74 friend class const_multi_array_ref;
Chris@16 75 #endif
Chris@16 76
Chris@16 77 // This ensures that const_multi_array_ref types with different TPtr
Chris@16 78 // types can convert to each other
Chris@16 79 template <typename OPtr>
Chris@16 80 const_multi_array_ref(const const_multi_array_ref<T,NumDims,OPtr>& other)
Chris@16 81 : base_(other.base_), storage_(other.storage_),
Chris@16 82 extent_list_(other.extent_list_),
Chris@16 83 stride_list_(other.stride_list_),
Chris@16 84 index_base_list_(other.index_base_list_),
Chris@16 85 origin_offset_(other.origin_offset_),
Chris@16 86 directional_offset_(other.directional_offset_),
Chris@16 87 num_elements_(other.num_elements_) { }
Chris@16 88
Chris@16 89 template <typename ExtentList>
Chris@16 90 explicit const_multi_array_ref(TPtr base, const ExtentList& extents) :
Chris@16 91 base_(base), storage_(c_storage_order()) {
Chris@16 92 boost::function_requires<
Chris@16 93 CollectionConcept<ExtentList> >();
Chris@16 94
Chris@16 95 index_base_list_.assign(0);
Chris@16 96 init_multi_array_ref(extents.begin());
Chris@16 97 }
Chris@16 98
Chris@16 99 template <typename ExtentList>
Chris@16 100 explicit const_multi_array_ref(TPtr base, const ExtentList& extents,
Chris@16 101 const general_storage_order<NumDims>& so) :
Chris@16 102 base_(base), storage_(so) {
Chris@16 103 boost::function_requires<
Chris@16 104 CollectionConcept<ExtentList> >();
Chris@16 105
Chris@16 106 index_base_list_.assign(0);
Chris@16 107 init_multi_array_ref(extents.begin());
Chris@16 108 }
Chris@16 109
Chris@16 110 explicit const_multi_array_ref(TPtr base,
Chris@16 111 const detail::multi_array::
Chris@16 112 extent_gen<NumDims>& ranges) :
Chris@16 113 base_(base), storage_(c_storage_order()) {
Chris@16 114
Chris@16 115 init_from_extent_gen(ranges);
Chris@16 116 }
Chris@16 117
Chris@16 118 explicit const_multi_array_ref(TPtr base,
Chris@16 119 const detail::multi_array::
Chris@16 120 extent_gen<NumDims>& ranges,
Chris@16 121 const general_storage_order<NumDims>& so) :
Chris@16 122 base_(base), storage_(so) {
Chris@16 123
Chris@16 124 init_from_extent_gen(ranges);
Chris@16 125 }
Chris@16 126
Chris@16 127 template <class InputIterator>
Chris@16 128 void assign(InputIterator begin, InputIterator end) {
Chris@16 129 boost::function_requires<InputIteratorConcept<InputIterator> >();
Chris@16 130
Chris@16 131 InputIterator in_iter = begin;
Chris@16 132 T* out_iter = base_;
Chris@16 133 std::size_t copy_count=0;
Chris@16 134 while (in_iter != end && copy_count < num_elements_) {
Chris@16 135 *out_iter++ = *in_iter++;
Chris@16 136 copy_count++;
Chris@16 137 }
Chris@16 138 }
Chris@16 139
Chris@16 140 template <class BaseList>
Chris@16 141 #ifdef BOOST_NO_SFINAE
Chris@16 142 void
Chris@16 143 #else
Chris@16 144 typename
Chris@16 145 disable_if<typename boost::is_integral<BaseList>::type,void >::type
Chris@16 146 #endif // BOOST_NO_SFINAE
Chris@16 147 reindex(const BaseList& values) {
Chris@16 148 boost::function_requires<
Chris@16 149 CollectionConcept<BaseList> >();
Chris@16 150 boost::detail::multi_array::
Chris@16 151 copy_n(values.begin(),num_dimensions(),index_base_list_.begin());
Chris@16 152 origin_offset_ =
Chris@16 153 this->calculate_origin_offset(stride_list_,extent_list_,
Chris@16 154 storage_,index_base_list_);
Chris@16 155 }
Chris@16 156
Chris@16 157 void reindex(index value) {
Chris@16 158 index_base_list_.assign(value);
Chris@16 159 origin_offset_ =
Chris@16 160 this->calculate_origin_offset(stride_list_,extent_list_,
Chris@16 161 storage_,index_base_list_);
Chris@16 162 }
Chris@16 163
Chris@16 164 template <typename SizeList>
Chris@16 165 void reshape(const SizeList& extents) {
Chris@16 166 boost::function_requires<
Chris@16 167 CollectionConcept<SizeList> >();
Chris@16 168 BOOST_ASSERT(num_elements_ ==
Chris@16 169 std::accumulate(extents.begin(),extents.end(),
Chris@16 170 size_type(1),std::multiplies<size_type>()));
Chris@16 171
Chris@16 172 std::copy(extents.begin(),extents.end(),extent_list_.begin());
Chris@16 173 this->compute_strides(stride_list_,extent_list_,storage_);
Chris@16 174
Chris@16 175 origin_offset_ =
Chris@16 176 this->calculate_origin_offset(stride_list_,extent_list_,
Chris@16 177 storage_,index_base_list_);
Chris@16 178 }
Chris@16 179
Chris@16 180 size_type num_dimensions() const { return NumDims; }
Chris@16 181
Chris@16 182 size_type size() const { return extent_list_.front(); }
Chris@16 183
Chris@16 184 // given reshaping functionality, this is the max possible size.
Chris@16 185 size_type max_size() const { return num_elements(); }
Chris@16 186
Chris@16 187 bool empty() const { return size() == 0; }
Chris@16 188
Chris@16 189 const size_type* shape() const {
Chris@16 190 return extent_list_.data();
Chris@16 191 }
Chris@16 192
Chris@16 193 const index* strides() const {
Chris@16 194 return stride_list_.data();
Chris@16 195 }
Chris@16 196
Chris@16 197 const element* origin() const { return base_+origin_offset_; }
Chris@16 198 const element* data() const { return base_; }
Chris@16 199
Chris@16 200 size_type num_elements() const { return num_elements_; }
Chris@16 201
Chris@16 202 const index* index_bases() const {
Chris@16 203 return index_base_list_.data();
Chris@16 204 }
Chris@16 205
Chris@16 206
Chris@16 207 const storage_order_type& storage_order() const {
Chris@16 208 return storage_;
Chris@16 209 }
Chris@16 210
Chris@16 211 template <typename IndexList>
Chris@16 212 const element& operator()(IndexList indices) const {
Chris@16 213 boost::function_requires<
Chris@16 214 CollectionConcept<IndexList> >();
Chris@16 215 return super_type::access_element(boost::type<const element&>(),
Chris@16 216 indices,origin(),
Chris@16 217 shape(),strides(),index_bases());
Chris@16 218 }
Chris@16 219
Chris@16 220 // Only allow const element access
Chris@16 221 const_reference operator[](index idx) const {
Chris@16 222 return super_type::access(boost::type<const_reference>(),
Chris@16 223 idx,origin(),
Chris@16 224 shape(),strides(),index_bases());
Chris@16 225 }
Chris@16 226
Chris@16 227 // see generate_array_view in base.hpp
Chris@16 228 template <int NDims>
Chris@16 229 typename const_array_view<NDims>::type
Chris@16 230 operator[](const detail::multi_array::
Chris@16 231 index_gen<NumDims,NDims>& indices)
Chris@16 232 const {
Chris@16 233 typedef typename const_array_view<NDims>::type return_type;
Chris@16 234 return
Chris@16 235 super_type::generate_array_view(boost::type<return_type>(),
Chris@16 236 indices,
Chris@16 237 shape(),
Chris@16 238 strides(),
Chris@16 239 index_bases(),
Chris@16 240 origin());
Chris@16 241 }
Chris@16 242
Chris@16 243 const_iterator begin() const {
Chris@16 244 return const_iterator(*index_bases(),origin(),
Chris@16 245 shape(),strides(),index_bases());
Chris@16 246 }
Chris@16 247
Chris@16 248 const_iterator end() const {
Chris@16 249 return const_iterator(*index_bases()+(index)*shape(),origin(),
Chris@16 250 shape(),strides(),index_bases());
Chris@16 251 }
Chris@16 252
Chris@16 253 const_reverse_iterator rbegin() const {
Chris@16 254 return const_reverse_iterator(end());
Chris@16 255 }
Chris@16 256
Chris@16 257 const_reverse_iterator rend() const {
Chris@16 258 return const_reverse_iterator(begin());
Chris@16 259 }
Chris@16 260
Chris@16 261
Chris@16 262 template <typename OPtr>
Chris@16 263 bool operator==(const
Chris@16 264 const_multi_array_ref<T,NumDims,OPtr>& rhs)
Chris@16 265 const {
Chris@16 266 if(std::equal(extent_list_.begin(),
Chris@16 267 extent_list_.end(),
Chris@16 268 rhs.extent_list_.begin()))
Chris@16 269 return std::equal(begin(),end(),rhs.begin());
Chris@16 270 else return false;
Chris@16 271 }
Chris@16 272
Chris@16 273 template <typename OPtr>
Chris@16 274 bool operator<(const
Chris@16 275 const_multi_array_ref<T,NumDims,OPtr>& rhs)
Chris@16 276 const {
Chris@16 277 return std::lexicographical_compare(begin(),end(),rhs.begin(),rhs.end());
Chris@16 278 }
Chris@16 279
Chris@16 280 template <typename OPtr>
Chris@16 281 bool operator!=(const
Chris@16 282 const_multi_array_ref<T,NumDims,OPtr>& rhs)
Chris@16 283 const {
Chris@16 284 return !(*this == rhs);
Chris@16 285 }
Chris@16 286
Chris@16 287 template <typename OPtr>
Chris@16 288 bool operator>(const
Chris@16 289 const_multi_array_ref<T,NumDims,OPtr>& rhs)
Chris@16 290 const {
Chris@16 291 return rhs < *this;
Chris@16 292 }
Chris@16 293
Chris@16 294 template <typename OPtr>
Chris@16 295 bool operator<=(const
Chris@16 296 const_multi_array_ref<T,NumDims,OPtr>& rhs)
Chris@16 297 const {
Chris@16 298 return !(*this > rhs);
Chris@16 299 }
Chris@16 300
Chris@16 301 template <typename OPtr>
Chris@16 302 bool operator>=(const
Chris@16 303 const_multi_array_ref<T,NumDims,OPtr>& rhs)
Chris@16 304 const {
Chris@16 305 return !(*this < rhs);
Chris@16 306 }
Chris@16 307
Chris@16 308
Chris@16 309 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
Chris@16 310 protected:
Chris@16 311 #else
Chris@16 312 public:
Chris@16 313 #endif
Chris@16 314
Chris@16 315 typedef boost::array<size_type,NumDims> size_list;
Chris@16 316 typedef boost::array<index,NumDims> index_list;
Chris@16 317
Chris@16 318 // This is used by multi_array, which is a subclass of this
Chris@16 319 void set_base_ptr(TPtr new_base) { base_ = new_base; }
Chris@16 320
Chris@16 321
Chris@16 322 // This constructor supports multi_array's default constructor
Chris@16 323 // and constructors from multi_array_ref, subarray, and array_view
Chris@16 324 explicit
Chris@16 325 const_multi_array_ref(TPtr base,
Chris@16 326 const storage_order_type& so,
Chris@16 327 const index * index_bases,
Chris@16 328 const size_type* extents) :
Chris@16 329 base_(base), storage_(so), origin_offset_(0), directional_offset_(0)
Chris@16 330 {
Chris@16 331 // If index_bases or extents is null, then initialize the corresponding
Chris@16 332 // private data to zeroed lists.
Chris@16 333 if(index_bases) {
Chris@16 334 boost::detail::multi_array::
Chris@16 335 copy_n(index_bases,NumDims,index_base_list_.begin());
Chris@16 336 } else {
Chris@16 337 std::fill_n(index_base_list_.begin(),NumDims,0);
Chris@16 338 }
Chris@16 339 if(extents) {
Chris@16 340 init_multi_array_ref(extents);
Chris@16 341 } else {
Chris@16 342 boost::array<index,NumDims> extent_list;
Chris@16 343 extent_list.assign(0);
Chris@16 344 init_multi_array_ref(extent_list.begin());
Chris@16 345 }
Chris@16 346 }
Chris@16 347
Chris@16 348
Chris@16 349 TPtr base_;
Chris@16 350 storage_order_type storage_;
Chris@16 351 size_list extent_list_;
Chris@16 352 index_list stride_list_;
Chris@16 353 index_list index_base_list_;
Chris@16 354 index origin_offset_;
Chris@16 355 index directional_offset_;
Chris@16 356 size_type num_elements_;
Chris@16 357
Chris@16 358 private:
Chris@16 359 // const_multi_array_ref cannot be assigned to (no deep copies!)
Chris@16 360 const_multi_array_ref& operator=(const const_multi_array_ref& other);
Chris@16 361
Chris@16 362 void init_from_extent_gen(const
Chris@16 363 detail::multi_array::
Chris@16 364 extent_gen<NumDims>& ranges) {
Chris@16 365
Chris@16 366 typedef boost::array<index,NumDims> extent_list;
Chris@16 367
Chris@16 368 // get the index_base values
Chris@16 369 std::transform(ranges.ranges_.begin(),ranges.ranges_.end(),
Chris@16 370 index_base_list_.begin(),
Chris@16 371 boost::mem_fun_ref(&extent_range::start));
Chris@16 372
Chris@16 373 // calculate the extents
Chris@16 374 extent_list extents;
Chris@16 375 std::transform(ranges.ranges_.begin(),ranges.ranges_.end(),
Chris@16 376 extents.begin(),
Chris@16 377 boost::mem_fun_ref(&extent_range::size));
Chris@16 378
Chris@16 379 init_multi_array_ref(extents.begin());
Chris@16 380 }
Chris@16 381
Chris@16 382
Chris@16 383 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
Chris@16 384 protected:
Chris@16 385 #else
Chris@16 386 public:
Chris@16 387 #endif
Chris@16 388 // RG - move me!
Chris@16 389 template <class InputIterator>
Chris@16 390 void init_multi_array_ref(InputIterator extents_iter) {
Chris@16 391 boost::function_requires<InputIteratorConcept<InputIterator> >();
Chris@16 392
Chris@16 393 boost::detail::multi_array::
Chris@16 394 copy_n(extents_iter,num_dimensions(),extent_list_.begin());
Chris@16 395
Chris@16 396 // Calculate the array size
Chris@16 397 num_elements_ = std::accumulate(extent_list_.begin(),extent_list_.end(),
Chris@16 398 size_type(1),std::multiplies<size_type>());
Chris@16 399
Chris@16 400 this->compute_strides(stride_list_,extent_list_,storage_);
Chris@16 401
Chris@16 402 origin_offset_ =
Chris@16 403 this->calculate_origin_offset(stride_list_,extent_list_,
Chris@16 404 storage_,index_base_list_);
Chris@16 405 directional_offset_ =
Chris@16 406 this->calculate_descending_dimension_offset(stride_list_,extent_list_,
Chris@16 407 storage_);
Chris@16 408 }
Chris@16 409 };
Chris@16 410
Chris@16 411 template <typename T, std::size_t NumDims>
Chris@16 412 class multi_array_ref :
Chris@16 413 public const_multi_array_ref<T,NumDims,T*>
Chris@16 414 {
Chris@16 415 typedef const_multi_array_ref<T,NumDims,T*> super_type;
Chris@16 416 public:
Chris@16 417 typedef typename super_type::value_type value_type;
Chris@16 418 typedef typename super_type::reference reference;
Chris@16 419 typedef typename super_type::iterator iterator;
Chris@16 420 typedef typename super_type::reverse_iterator reverse_iterator;
Chris@16 421 typedef typename super_type::const_reference const_reference;
Chris@16 422 typedef typename super_type::const_iterator const_iterator;
Chris@16 423 typedef typename super_type::const_reverse_iterator const_reverse_iterator;
Chris@16 424 typedef typename super_type::element element;
Chris@16 425 typedef typename super_type::size_type size_type;
Chris@16 426 typedef typename super_type::difference_type difference_type;
Chris@16 427 typedef typename super_type::index index;
Chris@16 428 typedef typename super_type::extent_range extent_range;
Chris@16 429
Chris@16 430 typedef typename super_type::storage_order_type storage_order_type;
Chris@16 431 typedef typename super_type::index_list index_list;
Chris@16 432 typedef typename super_type::size_list size_list;
Chris@16 433
Chris@16 434 template <std::size_t NDims>
Chris@16 435 struct const_array_view {
Chris@16 436 typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
Chris@16 437 };
Chris@16 438
Chris@16 439 template <std::size_t NDims>
Chris@16 440 struct array_view {
Chris@16 441 typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
Chris@16 442 };
Chris@16 443
Chris@16 444 template <class ExtentList>
Chris@16 445 explicit multi_array_ref(T* base, const ExtentList& extents) :
Chris@16 446 super_type(base,extents) {
Chris@16 447 boost::function_requires<
Chris@16 448 CollectionConcept<ExtentList> >();
Chris@16 449 }
Chris@16 450
Chris@16 451 template <class ExtentList>
Chris@16 452 explicit multi_array_ref(T* base, const ExtentList& extents,
Chris@16 453 const general_storage_order<NumDims>& so) :
Chris@16 454 super_type(base,extents,so) {
Chris@16 455 boost::function_requires<
Chris@16 456 CollectionConcept<ExtentList> >();
Chris@16 457 }
Chris@16 458
Chris@16 459
Chris@16 460 explicit multi_array_ref(T* base,
Chris@16 461 const detail::multi_array::
Chris@16 462 extent_gen<NumDims>& ranges) :
Chris@16 463 super_type(base,ranges) { }
Chris@16 464
Chris@16 465
Chris@16 466 explicit multi_array_ref(T* base,
Chris@16 467 const detail::multi_array::
Chris@16 468 extent_gen<NumDims>&
Chris@16 469 ranges,
Chris@16 470 const general_storage_order<NumDims>& so) :
Chris@16 471 super_type(base,ranges,so) { }
Chris@16 472
Chris@16 473
Chris@16 474 // Assignment from other ConstMultiArray types.
Chris@16 475 template <typename ConstMultiArray>
Chris@16 476 multi_array_ref& operator=(const ConstMultiArray& other) {
Chris@16 477 function_requires<
Chris@16 478 multi_array_concepts::
Chris@16 479 ConstMultiArrayConcept<ConstMultiArray,NumDims> >();
Chris@16 480
Chris@16 481 // make sure the dimensions agree
Chris@16 482 BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
Chris@16 483 BOOST_ASSERT(std::equal(other.shape(),other.shape()+this->num_dimensions(),
Chris@16 484 this->shape()));
Chris@16 485 // iterator-based copy
Chris@16 486 std::copy(other.begin(),other.end(),this->begin());
Chris@16 487 return *this;
Chris@16 488 }
Chris@16 489
Chris@16 490 multi_array_ref& operator=(const multi_array_ref& other) {
Chris@16 491 if (&other != this) {
Chris@16 492 // make sure the dimensions agree
Chris@16 493
Chris@16 494 BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
Chris@16 495 BOOST_ASSERT(std::equal(other.shape(),
Chris@16 496 other.shape()+this->num_dimensions(),
Chris@16 497 this->shape()));
Chris@16 498 // iterator-based copy
Chris@16 499 std::copy(other.begin(),other.end(),this->begin());
Chris@16 500 }
Chris@16 501 return *this;
Chris@16 502 }
Chris@16 503
Chris@16 504 element* origin() { return super_type::base_+super_type::origin_offset_; }
Chris@16 505
Chris@16 506 element* data() { return super_type::base_; }
Chris@16 507
Chris@16 508 template <class IndexList>
Chris@16 509 element& operator()(const IndexList& indices) {
Chris@16 510 boost::function_requires<
Chris@16 511 CollectionConcept<IndexList> >();
Chris@16 512 return super_type::access_element(boost::type<element&>(),
Chris@16 513 indices,origin(),
Chris@16 514 this->shape(),this->strides(),
Chris@16 515 this->index_bases());
Chris@16 516 }
Chris@16 517
Chris@16 518
Chris@16 519 reference operator[](index idx) {
Chris@16 520 return super_type::access(boost::type<reference>(),
Chris@16 521 idx,origin(),
Chris@16 522 this->shape(),this->strides(),
Chris@16 523 this->index_bases());
Chris@16 524 }
Chris@16 525
Chris@16 526
Chris@16 527 // See note attached to generate_array_view in base.hpp
Chris@16 528 template <int NDims>
Chris@16 529 typename array_view<NDims>::type
Chris@16 530 operator[](const detail::multi_array::
Chris@16 531 index_gen<NumDims,NDims>& indices) {
Chris@16 532 typedef typename array_view<NDims>::type return_type;
Chris@16 533 return
Chris@16 534 super_type::generate_array_view(boost::type<return_type>(),
Chris@16 535 indices,
Chris@16 536 this->shape(),
Chris@16 537 this->strides(),
Chris@16 538 this->index_bases(),
Chris@16 539 origin());
Chris@16 540 }
Chris@16 541
Chris@16 542
Chris@16 543 iterator begin() {
Chris@16 544 return iterator(*this->index_bases(),origin(),this->shape(),
Chris@16 545 this->strides(),this->index_bases());
Chris@16 546 }
Chris@16 547
Chris@16 548 iterator end() {
Chris@16 549 return iterator(*this->index_bases()+(index)*this->shape(),origin(),
Chris@16 550 this->shape(),this->strides(),
Chris@16 551 this->index_bases());
Chris@16 552 }
Chris@16 553
Chris@16 554 // rbegin() and rend() written naively to thwart MSVC ICE.
Chris@16 555 reverse_iterator rbegin() {
Chris@16 556 reverse_iterator ri(end());
Chris@16 557 return ri;
Chris@16 558 }
Chris@16 559
Chris@16 560 reverse_iterator rend() {
Chris@16 561 reverse_iterator ri(begin());
Chris@16 562 return ri;
Chris@16 563 }
Chris@16 564
Chris@16 565 // Using declarations don't seem to work for g++
Chris@16 566 // These are the proxies to work around this.
Chris@16 567
Chris@16 568 const element* origin() const { return super_type::origin(); }
Chris@16 569 const element* data() const { return super_type::data(); }
Chris@16 570
Chris@16 571 template <class IndexList>
Chris@16 572 const element& operator()(const IndexList& indices) const {
Chris@16 573 boost::function_requires<
Chris@16 574 CollectionConcept<IndexList> >();
Chris@16 575 return super_type::operator()(indices);
Chris@16 576 }
Chris@16 577
Chris@16 578 const_reference operator[](index idx) const {
Chris@16 579 return super_type::access(boost::type<const_reference>(),
Chris@16 580 idx,origin(),
Chris@16 581 this->shape(),this->strides(),
Chris@16 582 this->index_bases());
Chris@16 583 }
Chris@16 584
Chris@16 585 // See note attached to generate_array_view in base.hpp
Chris@16 586 template <int NDims>
Chris@16 587 typename const_array_view<NDims>::type
Chris@16 588 operator[](const detail::multi_array::
Chris@16 589 index_gen<NumDims,NDims>& indices)
Chris@16 590 const {
Chris@16 591 return super_type::operator[](indices);
Chris@16 592 }
Chris@16 593
Chris@16 594 const_iterator begin() const {
Chris@16 595 return super_type::begin();
Chris@16 596 }
Chris@16 597
Chris@16 598 const_iterator end() const {
Chris@16 599 return super_type::end();
Chris@16 600 }
Chris@16 601
Chris@16 602 const_reverse_iterator rbegin() const {
Chris@16 603 return super_type::rbegin();
Chris@16 604 }
Chris@16 605
Chris@16 606 const_reverse_iterator rend() const {
Chris@16 607 return super_type::rend();
Chris@16 608 }
Chris@16 609
Chris@16 610 protected:
Chris@16 611 // This is only supplied to support multi_array's default constructor
Chris@16 612 explicit multi_array_ref(T* base,
Chris@16 613 const storage_order_type& so,
Chris@16 614 const index* index_bases,
Chris@16 615 const size_type* extents) :
Chris@16 616 super_type(base,so,index_bases,extents) { }
Chris@16 617
Chris@16 618 };
Chris@16 619
Chris@16 620 } // namespace boost
Chris@16 621
Chris@16 622 #endif // BOOST_MULTI_ARRAY_REF_RG071801_HPP