annotate DEPENDENCIES/generic/include/boost/multi_array/view.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_VIEW_RG071301_HPP
Chris@16 14 #define BOOST_MULTI_ARRAY_VIEW_RG071301_HPP
Chris@16 15
Chris@16 16 //
Chris@16 17 // view.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/concept_checks.hpp"
Chris@16 22 #include "boost/multi_array/iterator.hpp"
Chris@16 23 #include "boost/multi_array/storage_order.hpp"
Chris@16 24 #include "boost/multi_array/subarray.hpp"
Chris@16 25 #include "boost/multi_array/algorithm.hpp"
Chris@16 26 #include "boost/type_traits/is_integral.hpp"
Chris@16 27 #include "boost/utility/enable_if.hpp"
Chris@16 28 #include "boost/array.hpp"
Chris@16 29 #include "boost/limits.hpp"
Chris@16 30 #include <algorithm>
Chris@16 31 #include <cstddef>
Chris@16 32 #include <functional>
Chris@16 33 #include <numeric>
Chris@16 34
Chris@16 35 namespace boost {
Chris@16 36 namespace detail {
Chris@16 37 namespace multi_array {
Chris@16 38
Chris@16 39 // TPtr = const T* defaulted in base.hpp
Chris@16 40 template <typename T, std::size_t NumDims, typename TPtr>
Chris@16 41 class const_multi_array_view :
Chris@16 42 public boost::detail::multi_array::multi_array_impl_base<T,NumDims>
Chris@16 43 {
Chris@16 44 typedef boost::detail::multi_array::multi_array_impl_base<T,NumDims> super_type;
Chris@16 45 public:
Chris@16 46 typedef typename super_type::value_type value_type;
Chris@16 47 typedef typename super_type::const_reference const_reference;
Chris@16 48 typedef typename super_type::const_iterator const_iterator;
Chris@16 49 typedef typename super_type::const_reverse_iterator const_reverse_iterator;
Chris@16 50 typedef typename super_type::element element;
Chris@16 51 typedef typename super_type::size_type size_type;
Chris@16 52 typedef typename super_type::difference_type difference_type;
Chris@16 53 typedef typename super_type::index index;
Chris@16 54 typedef typename super_type::extent_range extent_range;
Chris@16 55
Chris@16 56 // template typedefs
Chris@16 57 template <std::size_t NDims>
Chris@16 58 struct const_array_view {
Chris@16 59 typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
Chris@16 60 };
Chris@16 61
Chris@16 62 template <std::size_t NDims>
Chris@16 63 struct array_view {
Chris@16 64 typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
Chris@16 65 };
Chris@16 66
Chris@16 67 template <typename OPtr>
Chris@16 68 const_multi_array_view(const
Chris@16 69 const_multi_array_view<T,NumDims,OPtr>& other) :
Chris@16 70 base_(other.base_), origin_offset_(other.origin_offset_),
Chris@16 71 num_elements_(other.num_elements_), extent_list_(other.extent_list_),
Chris@16 72 stride_list_(other.stride_list_), index_base_list_(other.index_base_list_)
Chris@16 73 { }
Chris@16 74
Chris@16 75
Chris@16 76 template <class BaseList>
Chris@16 77 #ifdef BOOST_NO_SFINAE
Chris@16 78 void
Chris@16 79 #else
Chris@16 80 typename
Chris@16 81 disable_if<typename boost::is_integral<BaseList>::type,void >::type
Chris@16 82 #endif
Chris@16 83 reindex(const BaseList& values) {
Chris@16 84 boost::function_requires<
Chris@16 85 CollectionConcept<BaseList> >();
Chris@16 86 boost::detail::multi_array::
Chris@16 87 copy_n(values.begin(),num_dimensions(),index_base_list_.begin());
Chris@16 88 origin_offset_ =
Chris@16 89 this->calculate_indexing_offset(stride_list_,index_base_list_);
Chris@16 90 }
Chris@16 91
Chris@16 92 void reindex(index value) {
Chris@16 93 index_base_list_.assign(value);
Chris@16 94 origin_offset_ =
Chris@16 95 this->calculate_indexing_offset(stride_list_,index_base_list_);
Chris@16 96 }
Chris@16 97
Chris@16 98 size_type num_dimensions() const { return NumDims; }
Chris@16 99
Chris@16 100 size_type size() const { return extent_list_.front(); }
Chris@16 101 size_type max_size() const { return num_elements(); }
Chris@16 102 bool empty() const { return size() == 0; }
Chris@16 103
Chris@16 104 const size_type* shape() const {
Chris@16 105 return extent_list_.data();
Chris@16 106 }
Chris@16 107
Chris@16 108 const index* strides() const {
Chris@16 109 return stride_list_.data();
Chris@16 110 }
Chris@16 111
Chris@16 112 const T* origin() const { return base_+origin_offset_; }
Chris@16 113
Chris@16 114 size_type num_elements() const { return num_elements_; }
Chris@16 115
Chris@16 116 const index* index_bases() const {
Chris@16 117 return index_base_list_.data();
Chris@16 118 }
Chris@16 119
Chris@16 120 template <typename IndexList>
Chris@16 121 const element& operator()(IndexList indices) const {
Chris@16 122 boost::function_requires<
Chris@16 123 CollectionConcept<IndexList> >();
Chris@16 124 return super_type::access_element(boost::type<const element&>(),
Chris@16 125 indices,origin(),
Chris@16 126 shape(),strides(),index_bases());
Chris@16 127 }
Chris@16 128
Chris@16 129 // Only allow const element access
Chris@16 130 const_reference operator[](index idx) const {
Chris@16 131 return super_type::access(boost::type<const_reference>(),
Chris@16 132 idx,origin(),
Chris@16 133 shape(),strides(),
Chris@16 134 index_bases());
Chris@16 135 }
Chris@16 136
Chris@16 137 // see generate_array_view in base.hpp
Chris@16 138 template <int NDims>
Chris@16 139 typename const_array_view<NDims>::type
Chris@16 140 operator[](const boost::detail::multi_array::
Chris@16 141 index_gen<NumDims,NDims>& indices)
Chris@16 142 const {
Chris@16 143 typedef typename const_array_view<NDims>::type return_type;
Chris@16 144 return
Chris@16 145 super_type::generate_array_view(boost::type<return_type>(),
Chris@16 146 indices,
Chris@16 147 shape(),
Chris@16 148 strides(),
Chris@16 149 index_bases(),
Chris@16 150 origin());
Chris@16 151 }
Chris@16 152 const_iterator begin() const {
Chris@16 153 return const_iterator(*index_bases(),origin(),
Chris@16 154 shape(),strides(),index_bases());
Chris@16 155 }
Chris@16 156
Chris@16 157 const_iterator end() const {
Chris@16 158 return const_iterator(*index_bases()+(index)*shape(),origin(),
Chris@16 159 shape(),strides(),index_bases());
Chris@16 160 }
Chris@16 161
Chris@16 162 const_reverse_iterator rbegin() const {
Chris@16 163 return const_reverse_iterator(end());
Chris@16 164 }
Chris@16 165
Chris@16 166 const_reverse_iterator rend() const {
Chris@16 167 return const_reverse_iterator(begin());
Chris@16 168 }
Chris@16 169
Chris@16 170
Chris@16 171 template <typename OPtr>
Chris@16 172 bool operator==(const
Chris@16 173 const_multi_array_view<T,NumDims,OPtr>& rhs)
Chris@16 174 const {
Chris@16 175 if(std::equal(extent_list_.begin(),
Chris@16 176 extent_list_.end(),
Chris@16 177 rhs.extent_list_.begin()))
Chris@16 178 return std::equal(begin(),end(),rhs.begin());
Chris@16 179 else return false;
Chris@16 180 }
Chris@16 181
Chris@16 182 template <typename OPtr>
Chris@16 183 bool operator<(const
Chris@16 184 const_multi_array_view<T,NumDims,OPtr>& rhs)
Chris@16 185 const {
Chris@16 186 return std::lexicographical_compare(begin(),end(),rhs.begin(),rhs.end());
Chris@16 187 }
Chris@16 188
Chris@16 189 template <typename OPtr>
Chris@16 190 bool operator!=(const
Chris@16 191 const_multi_array_view<T,NumDims,OPtr>& rhs)
Chris@16 192 const {
Chris@16 193 return !(*this == rhs);
Chris@16 194 }
Chris@16 195
Chris@16 196 template <typename OPtr>
Chris@16 197 bool operator>(const
Chris@16 198 const_multi_array_view<T,NumDims,OPtr>& rhs)
Chris@16 199 const {
Chris@16 200 return rhs < *this;
Chris@16 201 }
Chris@16 202
Chris@16 203 template <typename OPtr>
Chris@16 204 bool operator<=(const
Chris@16 205 const_multi_array_view<T,NumDims,OPtr>& rhs)
Chris@16 206 const {
Chris@16 207 return !(*this > rhs);
Chris@16 208 }
Chris@16 209
Chris@16 210 template <typename OPtr>
Chris@16 211 bool operator>=(const
Chris@16 212 const_multi_array_view<T,NumDims,OPtr>& rhs)
Chris@16 213 const {
Chris@16 214 return !(*this < rhs);
Chris@16 215 }
Chris@16 216
Chris@16 217
Chris@16 218 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
Chris@16 219 protected:
Chris@16 220 template <typename,std::size_t> friend class multi_array_impl_base;
Chris@16 221 template <typename,std::size_t,typename> friend class const_multi_array_view;
Chris@16 222 #else
Chris@16 223 public: // should be protected
Chris@16 224 #endif
Chris@16 225
Chris@16 226 // This constructor is used by multi_array_impl_base::generate_array_view
Chris@16 227 // to create strides
Chris@16 228 template <typename ExtentList, typename Index>
Chris@16 229 explicit const_multi_array_view(TPtr base,
Chris@16 230 const ExtentList& extents,
Chris@16 231 const boost::array<Index,NumDims>& strides):
Chris@16 232 base_(base), origin_offset_(0) {
Chris@16 233
Chris@16 234 index_base_list_.assign(0);
Chris@16 235
Chris@16 236 // Get the extents and strides
Chris@16 237 boost::detail::multi_array::
Chris@16 238 copy_n(extents.begin(),NumDims,extent_list_.begin());
Chris@16 239 boost::detail::multi_array::
Chris@16 240 copy_n(strides.begin(),NumDims,stride_list_.begin());
Chris@16 241
Chris@16 242 // Calculate the array size
Chris@16 243 num_elements_ = std::accumulate(extent_list_.begin(),extent_list_.end(),
Chris@16 244 size_type(1),std::multiplies<size_type>());
Chris@16 245 }
Chris@16 246
Chris@16 247 typedef boost::array<size_type,NumDims> size_list;
Chris@16 248 typedef boost::array<index,NumDims> index_list;
Chris@16 249
Chris@16 250 TPtr base_;
Chris@16 251 index origin_offset_;
Chris@16 252 size_type num_elements_;
Chris@16 253 size_list extent_list_;
Chris@16 254 index_list stride_list_;
Chris@16 255 index_list index_base_list_;
Chris@16 256
Chris@16 257 private:
Chris@16 258 // const_multi_array_view cannot be assigned to (no deep copies!)
Chris@16 259 const_multi_array_view& operator=(const const_multi_array_view& other);
Chris@16 260 };
Chris@16 261
Chris@16 262
Chris@16 263 template <typename T, std::size_t NumDims>
Chris@16 264 class multi_array_view :
Chris@16 265 public const_multi_array_view<T,NumDims,T*>
Chris@16 266 {
Chris@16 267 typedef const_multi_array_view<T,NumDims,T*> super_type;
Chris@16 268 public:
Chris@16 269 typedef typename super_type::value_type value_type;
Chris@16 270 typedef typename super_type::reference reference;
Chris@16 271 typedef typename super_type::iterator iterator;
Chris@16 272 typedef typename super_type::reverse_iterator reverse_iterator;
Chris@16 273 typedef typename super_type::const_reference const_reference;
Chris@16 274 typedef typename super_type::const_iterator const_iterator;
Chris@16 275 typedef typename super_type::const_reverse_iterator const_reverse_iterator;
Chris@16 276 typedef typename super_type::element element;
Chris@16 277 typedef typename super_type::size_type size_type;
Chris@16 278 typedef typename super_type::difference_type difference_type;
Chris@16 279 typedef typename super_type::index index;
Chris@16 280 typedef typename super_type::extent_range extent_range;
Chris@16 281
Chris@16 282 // template typedefs
Chris@16 283 template <std::size_t NDims>
Chris@16 284 struct const_array_view {
Chris@16 285 typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
Chris@16 286 };
Chris@16 287
Chris@16 288 template <std::size_t NDims>
Chris@16 289 struct array_view {
Chris@16 290 typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
Chris@16 291 };
Chris@16 292
Chris@16 293 // Assignment from other ConstMultiArray types.
Chris@16 294 template <typename ConstMultiArray>
Chris@16 295 multi_array_view& operator=(const ConstMultiArray& other) {
Chris@16 296 function_requires<
Chris@16 297 boost::multi_array_concepts::
Chris@16 298 ConstMultiArrayConcept<ConstMultiArray,NumDims> >();
Chris@16 299
Chris@16 300 // make sure the dimensions agree
Chris@16 301 BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
Chris@16 302 BOOST_ASSERT(std::equal(other.shape(),other.shape()+this->num_dimensions(),
Chris@16 303 this->shape()));
Chris@16 304 // iterator-based copy
Chris@16 305 std::copy(other.begin(),other.end(),begin());
Chris@16 306 return *this;
Chris@16 307 }
Chris@16 308
Chris@16 309
Chris@16 310 multi_array_view& operator=(const multi_array_view& other) {
Chris@16 311 if (&other != this) {
Chris@16 312 // make sure the dimensions agree
Chris@16 313 BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
Chris@16 314 BOOST_ASSERT(std::equal(other.shape(),
Chris@16 315 other.shape()+this->num_dimensions(),
Chris@16 316 this->shape()));
Chris@16 317 // iterator-based copy
Chris@16 318 std::copy(other.begin(),other.end(),begin());
Chris@16 319 }
Chris@16 320 return *this;
Chris@16 321 }
Chris@16 322
Chris@16 323 element* origin() { return this->base_+this->origin_offset_; }
Chris@16 324
Chris@16 325 template <class IndexList>
Chris@16 326 element& operator()(const IndexList& indices) {
Chris@16 327 boost::function_requires<
Chris@16 328 CollectionConcept<IndexList> >();
Chris@16 329 return super_type::access_element(boost::type<element&>(),
Chris@16 330 indices,origin(),
Chris@16 331 this->shape(),this->strides(),
Chris@16 332 this->index_bases());
Chris@16 333 }
Chris@16 334
Chris@16 335
Chris@16 336 reference operator[](index idx) {
Chris@16 337 return super_type::access(boost::type<reference>(),
Chris@16 338 idx,origin(),
Chris@16 339 this->shape(),this->strides(),
Chris@16 340 this->index_bases());
Chris@16 341 }
Chris@16 342
Chris@16 343
Chris@16 344 // see generate_array_view in base.hpp
Chris@16 345 template <int NDims>
Chris@16 346 typename array_view<NDims>::type
Chris@16 347 operator[](const boost::detail::multi_array::
Chris@16 348 index_gen<NumDims,NDims>& indices) {
Chris@16 349 typedef typename array_view<NDims>::type return_type;
Chris@16 350 return
Chris@16 351 super_type::generate_array_view(boost::type<return_type>(),
Chris@16 352 indices,
Chris@16 353 this->shape(),
Chris@16 354 this->strides(),
Chris@16 355 this->index_bases(),
Chris@16 356 origin());
Chris@16 357 }
Chris@16 358
Chris@16 359
Chris@16 360 iterator begin() {
Chris@16 361 return iterator(*this->index_bases(),origin(),
Chris@16 362 this->shape(),this->strides(),
Chris@16 363 this->index_bases());
Chris@16 364 }
Chris@16 365
Chris@16 366 iterator end() {
Chris@16 367 return iterator(*this->index_bases()+(index)*this->shape(),origin(),
Chris@16 368 this->shape(),this->strides(),
Chris@16 369 this->index_bases());
Chris@16 370 }
Chris@16 371
Chris@16 372 reverse_iterator rbegin() {
Chris@16 373 return reverse_iterator(end());
Chris@16 374 }
Chris@16 375
Chris@16 376 reverse_iterator rend() {
Chris@16 377 return reverse_iterator(begin());
Chris@16 378 }
Chris@16 379
Chris@16 380 // Using declarations don't seem to work for g++
Chris@16 381 // These are the proxies to work around this.
Chris@16 382
Chris@16 383 const element* origin() const { return super_type::origin(); }
Chris@16 384
Chris@16 385 template <class IndexList>
Chris@16 386 const element& operator()(const IndexList& indices) const {
Chris@16 387 boost::function_requires<
Chris@16 388 CollectionConcept<IndexList> >();
Chris@16 389 return super_type::operator()(indices);
Chris@16 390 }
Chris@16 391
Chris@16 392 const_reference operator[](index idx) const {
Chris@16 393 return super_type::operator[](idx);
Chris@16 394 }
Chris@16 395
Chris@16 396 // see generate_array_view in base.hpp
Chris@16 397 template <int NDims>
Chris@16 398 typename const_array_view<NDims>::type
Chris@16 399 operator[](const boost::detail::multi_array::
Chris@16 400 index_gen<NumDims,NDims>& indices)
Chris@16 401 const {
Chris@16 402 return super_type::operator[](indices);
Chris@16 403 }
Chris@16 404
Chris@16 405 const_iterator begin() const {
Chris@16 406 return super_type::begin();
Chris@16 407 }
Chris@16 408
Chris@16 409 const_iterator end() const {
Chris@16 410 return super_type::end();
Chris@16 411 }
Chris@16 412
Chris@16 413 const_reverse_iterator rbegin() const {
Chris@16 414 return super_type::rbegin();
Chris@16 415 }
Chris@16 416
Chris@16 417 const_reverse_iterator rend() const {
Chris@16 418 return super_type::rend();
Chris@16 419 }
Chris@16 420
Chris@16 421 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
Chris@16 422 private:
Chris@16 423 template <typename,std::size_t> friend class multi_array_impl_base;
Chris@16 424 #else
Chris@16 425 public: // should be private
Chris@16 426 #endif
Chris@16 427
Chris@16 428 // constructor used by multi_array_impl_base::generate_array_view to
Chris@16 429 // generate array views
Chris@16 430 template <typename ExtentList, typename Index>
Chris@16 431 explicit multi_array_view(T* base,
Chris@16 432 const ExtentList& extents,
Chris@16 433 const boost::array<Index,NumDims>& strides) :
Chris@16 434 super_type(base,extents,strides) { }
Chris@16 435
Chris@16 436 };
Chris@16 437
Chris@16 438 } // namespace multi_array
Chris@16 439 } // namespace detail
Chris@16 440
Chris@16 441 //
Chris@16 442 // traits classes to get array_view types
Chris@16 443 //
Chris@16 444 template <typename Array, int N>
Chris@16 445 class array_view_gen {
Chris@16 446 typedef typename Array::element element;
Chris@16 447 public:
Chris@16 448 typedef boost::detail::multi_array::multi_array_view<element,N> type;
Chris@16 449 };
Chris@16 450
Chris@16 451 template <typename Array, int N>
Chris@16 452 class const_array_view_gen {
Chris@16 453 typedef typename Array::element element;
Chris@16 454 public:
Chris@16 455 typedef boost::detail::multi_array::const_multi_array_view<element,N> type;
Chris@16 456 };
Chris@16 457
Chris@16 458 } // namespace boost
Chris@16 459
Chris@16 460 #endif // BOOST_MULTI_ARRAY_VIEW_RG071301_HPP
Chris@16 461