File indexing completed on 2025-01-30 09:48:16
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef BOOST_MULTI_ARRAY_VIEW_HPP
0014 #define BOOST_MULTI_ARRAY_VIEW_HPP
0015
0016
0017
0018
0019
0020 #include "boost/multi_array/base.hpp"
0021 #include "boost/multi_array/concept_checks.hpp"
0022 #include "boost/multi_array/iterator.hpp"
0023 #include "boost/multi_array/storage_order.hpp"
0024 #include "boost/multi_array/subarray.hpp"
0025 #include "boost/multi_array/algorithm.hpp"
0026 #include "boost/type_traits/is_integral.hpp"
0027 #include "boost/utility/enable_if.hpp"
0028 #include "boost/array.hpp"
0029 #include "boost/limits.hpp"
0030 #include <algorithm>
0031 #include <cstddef>
0032 #include <functional>
0033 #include <numeric>
0034
0035 namespace boost {
0036 namespace detail {
0037 namespace multi_array {
0038
0039
0040 template <typename T, std::size_t NumDims, typename TPtr>
0041 class const_multi_array_view :
0042 public boost::detail::multi_array::multi_array_impl_base<T,NumDims>
0043 {
0044 typedef boost::detail::multi_array::multi_array_impl_base<T,NumDims> super_type;
0045 public:
0046 typedef typename super_type::value_type value_type;
0047 typedef typename super_type::const_reference const_reference;
0048 typedef typename super_type::const_iterator const_iterator;
0049 typedef typename super_type::const_reverse_iterator const_reverse_iterator;
0050 typedef typename super_type::element element;
0051 typedef typename super_type::size_type size_type;
0052 typedef typename super_type::difference_type difference_type;
0053 typedef typename super_type::index index;
0054 typedef typename super_type::extent_range extent_range;
0055
0056
0057 template <std::size_t NDims>
0058 struct const_array_view {
0059 typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
0060 };
0061
0062 template <std::size_t NDims>
0063 struct array_view {
0064 typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
0065 };
0066
0067 template <typename OPtr>
0068 const_multi_array_view(const
0069 const_multi_array_view<T,NumDims,OPtr>& other) :
0070 base_(other.base_), origin_offset_(other.origin_offset_),
0071 num_elements_(other.num_elements_), extent_list_(other.extent_list_),
0072 stride_list_(other.stride_list_), index_base_list_(other.index_base_list_)
0073 { }
0074
0075
0076 template <class BaseList>
0077 #ifdef BOOST_NO_SFINAE
0078 void
0079 #else
0080 typename
0081 disable_if<typename boost::is_integral<BaseList>::type,void >::type
0082 #endif
0083 reindex(const BaseList& values) {
0084 boost::function_requires<
0085 CollectionConcept<BaseList> >();
0086 boost::detail::multi_array::
0087 copy_n(values.begin(),num_dimensions(),index_base_list_.begin());
0088 origin_offset_ =
0089 this->calculate_indexing_offset(stride_list_,index_base_list_);
0090 }
0091
0092 void reindex(index value) {
0093 index_base_list_.assign(value);
0094 origin_offset_ =
0095 this->calculate_indexing_offset(stride_list_,index_base_list_);
0096 }
0097
0098 size_type num_dimensions() const { return NumDims; }
0099
0100 size_type size() const { return extent_list_.front(); }
0101 size_type max_size() const { return num_elements(); }
0102 bool empty() const { return size() == 0; }
0103
0104 const size_type* shape() const {
0105 return extent_list_.data();
0106 }
0107
0108 const index* strides() const {
0109 return stride_list_.data();
0110 }
0111
0112 const T* origin() const { return base_+origin_offset_; }
0113
0114 size_type num_elements() const { return num_elements_; }
0115
0116 const index* index_bases() const {
0117 return index_base_list_.data();
0118 }
0119
0120 template <typename IndexList>
0121 const element& operator()(IndexList indices) const {
0122 boost::function_requires<
0123 CollectionConcept<IndexList> >();
0124 return super_type::access_element(boost::type<const element&>(),
0125 indices,origin(),
0126 shape(),strides(),index_bases());
0127 }
0128
0129
0130 const_reference operator[](index idx) const {
0131 return super_type::access(boost::type<const_reference>(),
0132 idx,origin(),
0133 shape(),strides(),
0134 index_bases());
0135 }
0136
0137
0138 template <int NDims>
0139 typename const_array_view<NDims>::type
0140 operator[](const boost::detail::multi_array::
0141 index_gen<NumDims,NDims>& indices)
0142 const {
0143 typedef typename const_array_view<NDims>::type return_type;
0144 return
0145 super_type::generate_array_view(boost::type<return_type>(),
0146 indices,
0147 shape(),
0148 strides(),
0149 index_bases(),
0150 origin());
0151 }
0152 const_iterator begin() const {
0153 return const_iterator(*index_bases(),origin(),
0154 shape(),strides(),index_bases());
0155 }
0156
0157 const_iterator end() const {
0158 return const_iterator(*index_bases()+(index)*shape(),origin(),
0159 shape(),strides(),index_bases());
0160 }
0161
0162 const_reverse_iterator rbegin() const {
0163 return const_reverse_iterator(end());
0164 }
0165
0166 const_reverse_iterator rend() const {
0167 return const_reverse_iterator(begin());
0168 }
0169
0170
0171 template <typename OPtr>
0172 bool operator==(const
0173 const_multi_array_view<T,NumDims,OPtr>& rhs)
0174 const {
0175 if(std::equal(extent_list_.begin(),
0176 extent_list_.end(),
0177 rhs.extent_list_.begin()))
0178 return std::equal(begin(),end(),rhs.begin());
0179 else return false;
0180 }
0181
0182 template <typename OPtr>
0183 bool operator<(const
0184 const_multi_array_view<T,NumDims,OPtr>& rhs)
0185 const {
0186 return std::lexicographical_compare(begin(),end(),rhs.begin(),rhs.end());
0187 }
0188
0189 template <typename OPtr>
0190 bool operator!=(const
0191 const_multi_array_view<T,NumDims,OPtr>& rhs)
0192 const {
0193 return !(*this == rhs);
0194 }
0195
0196 template <typename OPtr>
0197 bool operator>(const
0198 const_multi_array_view<T,NumDims,OPtr>& rhs)
0199 const {
0200 return rhs < *this;
0201 }
0202
0203 template <typename OPtr>
0204 bool operator<=(const
0205 const_multi_array_view<T,NumDims,OPtr>& rhs)
0206 const {
0207 return !(*this > rhs);
0208 }
0209
0210 template <typename OPtr>
0211 bool operator>=(const
0212 const_multi_array_view<T,NumDims,OPtr>& rhs)
0213 const {
0214 return !(*this < rhs);
0215 }
0216
0217
0218 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
0219 protected:
0220 template <typename,std::size_t> friend class multi_array_impl_base;
0221 template <typename,std::size_t,typename> friend class const_multi_array_view;
0222 #else
0223 public:
0224 #endif
0225
0226
0227
0228 template <typename ExtentList, typename Index>
0229 explicit const_multi_array_view(TPtr base,
0230 const ExtentList& extents,
0231 const boost::array<Index,NumDims>& strides):
0232 base_(base), origin_offset_(0) {
0233
0234 index_base_list_.assign(0);
0235
0236
0237 boost::detail::multi_array::
0238 copy_n(extents.begin(),NumDims,extent_list_.begin());
0239 boost::detail::multi_array::
0240 copy_n(strides.begin(),NumDims,stride_list_.begin());
0241
0242
0243 num_elements_ = std::accumulate(extent_list_.begin(),extent_list_.end(),
0244 size_type(1),std::multiplies<size_type>());
0245 }
0246
0247 typedef boost::array<size_type,NumDims> size_list;
0248 typedef boost::array<index,NumDims> index_list;
0249
0250 TPtr base_;
0251 index origin_offset_;
0252 size_type num_elements_;
0253 size_list extent_list_;
0254 index_list stride_list_;
0255 index_list index_base_list_;
0256
0257 private:
0258
0259 const_multi_array_view& operator=(const const_multi_array_view& other);
0260 };
0261
0262
0263 template <typename T, std::size_t NumDims>
0264 class multi_array_view :
0265 public const_multi_array_view<T,NumDims,T*>
0266 {
0267 typedef const_multi_array_view<T,NumDims,T*> super_type;
0268 public:
0269 typedef typename super_type::value_type value_type;
0270 typedef typename super_type::reference reference;
0271 typedef typename super_type::iterator iterator;
0272 typedef typename super_type::reverse_iterator reverse_iterator;
0273 typedef typename super_type::const_reference const_reference;
0274 typedef typename super_type::const_iterator const_iterator;
0275 typedef typename super_type::const_reverse_iterator const_reverse_iterator;
0276 typedef typename super_type::element element;
0277 typedef typename super_type::size_type size_type;
0278 typedef typename super_type::difference_type difference_type;
0279 typedef typename super_type::index index;
0280 typedef typename super_type::extent_range extent_range;
0281
0282
0283 template <std::size_t NDims>
0284 struct const_array_view {
0285 typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
0286 };
0287
0288 template <std::size_t NDims>
0289 struct array_view {
0290 typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
0291 };
0292
0293
0294 template <typename ConstMultiArray>
0295 multi_array_view& operator=(const ConstMultiArray& other) {
0296 function_requires<
0297 boost::multi_array_concepts::
0298 ConstMultiArrayConcept<ConstMultiArray,NumDims> >();
0299
0300
0301 BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
0302 BOOST_ASSERT(std::equal(other.shape(),other.shape()+this->num_dimensions(),
0303 this->shape()));
0304
0305 std::copy(other.begin(),other.end(),begin());
0306 return *this;
0307 }
0308
0309
0310 multi_array_view& operator=(const multi_array_view& other) {
0311 if (&other != this) {
0312
0313 BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
0314 BOOST_ASSERT(std::equal(other.shape(),
0315 other.shape()+this->num_dimensions(),
0316 this->shape()));
0317
0318 std::copy(other.begin(),other.end(),begin());
0319 }
0320 return *this;
0321 }
0322
0323 element* origin() { return this->base_+this->origin_offset_; }
0324
0325 template <class IndexList>
0326 element& operator()(const IndexList& indices) {
0327 boost::function_requires<
0328 CollectionConcept<IndexList> >();
0329 return super_type::access_element(boost::type<element&>(),
0330 indices,origin(),
0331 this->shape(),this->strides(),
0332 this->index_bases());
0333 }
0334
0335
0336 reference operator[](index idx) {
0337 return super_type::access(boost::type<reference>(),
0338 idx,origin(),
0339 this->shape(),this->strides(),
0340 this->index_bases());
0341 }
0342
0343
0344
0345 template <int NDims>
0346 typename array_view<NDims>::type
0347 operator[](const boost::detail::multi_array::
0348 index_gen<NumDims,NDims>& indices) {
0349 typedef typename array_view<NDims>::type return_type;
0350 return
0351 super_type::generate_array_view(boost::type<return_type>(),
0352 indices,
0353 this->shape(),
0354 this->strides(),
0355 this->index_bases(),
0356 origin());
0357 }
0358
0359
0360 iterator begin() {
0361 return iterator(*this->index_bases(),origin(),
0362 this->shape(),this->strides(),
0363 this->index_bases());
0364 }
0365
0366 iterator end() {
0367 return iterator(*this->index_bases()+(index)*this->shape(),origin(),
0368 this->shape(),this->strides(),
0369 this->index_bases());
0370 }
0371
0372 reverse_iterator rbegin() {
0373 return reverse_iterator(end());
0374 }
0375
0376 reverse_iterator rend() {
0377 return reverse_iterator(begin());
0378 }
0379
0380
0381
0382
0383 const element* origin() const { return super_type::origin(); }
0384
0385 template <class IndexList>
0386 const element& operator()(const IndexList& indices) const {
0387 boost::function_requires<
0388 CollectionConcept<IndexList> >();
0389 return super_type::operator()(indices);
0390 }
0391
0392 const_reference operator[](index idx) const {
0393 return super_type::operator[](idx);
0394 }
0395
0396
0397 template <int NDims>
0398 typename const_array_view<NDims>::type
0399 operator[](const boost::detail::multi_array::
0400 index_gen<NumDims,NDims>& indices)
0401 const {
0402 return super_type::operator[](indices);
0403 }
0404
0405 const_iterator begin() const {
0406 return super_type::begin();
0407 }
0408
0409 const_iterator end() const {
0410 return super_type::end();
0411 }
0412
0413 const_reverse_iterator rbegin() const {
0414 return super_type::rbegin();
0415 }
0416
0417 const_reverse_iterator rend() const {
0418 return super_type::rend();
0419 }
0420
0421 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
0422 private:
0423 template <typename,std::size_t> friend class multi_array_impl_base;
0424 #else
0425 public:
0426 #endif
0427
0428
0429
0430 template <typename ExtentList, typename Index>
0431 explicit multi_array_view(T* base,
0432 const ExtentList& extents,
0433 const boost::array<Index,NumDims>& strides) :
0434 super_type(base,extents,strides) { }
0435
0436 };
0437
0438 }
0439 }
0440
0441
0442
0443
0444 template <typename Array, int N>
0445 class array_view_gen {
0446 typedef typename Array::element element;
0447 public:
0448 typedef boost::detail::multi_array::multi_array_view<element,N> type;
0449 };
0450
0451 template <typename Array, int N>
0452 class const_array_view_gen {
0453 typedef typename Array::element element;
0454 public:
0455 typedef boost::detail::multi_array::const_multi_array_view<element,N> type;
0456 };
0457
0458 }
0459
0460 #endif