1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/epoc32/include/stdapis/boost/multi_array/view.hpp Tue Mar 16 16:12:26 2010 +0000
1.3 @@ -0,0 +1,474 @@
1.4 +// Copyright 2002 The Trustees of Indiana University.
1.5 +
1.6 +// Use, modification and distribution is subject to the Boost Software
1.7 +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
1.8 +// http://www.boost.org/LICENSE_1_0.txt)
1.9 +
1.10 +// Boost.MultiArray Library
1.11 +// Authors: Ronald Garcia
1.12 +// Jeremy Siek
1.13 +// Andrew Lumsdaine
1.14 +// See http://www.boost.org/libs/multi_array for documentation.
1.15 +
1.16 +#ifndef BOOST_MULTI_ARRAY_VIEW_RG071301_HPP
1.17 +#define BOOST_MULTI_ARRAY_VIEW_RG071301_HPP
1.18 +
1.19 +//
1.20 +// view.hpp - code for creating "views" of array data.
1.21 +//
1.22 +
1.23 +#include "boost/multi_array/base.hpp"
1.24 +#include "boost/multi_array/concept_checks.hpp"
1.25 +#include "boost/multi_array/iterator.hpp"
1.26 +#include "boost/multi_array/storage_order.hpp"
1.27 +#include "boost/multi_array/subarray.hpp"
1.28 +#include "boost/multi_array/algorithm.hpp"
1.29 +#include "boost/type_traits/is_integral.hpp"
1.30 +#include "boost/array.hpp"
1.31 +#include "boost/limits.hpp"
1.32 +#include <algorithm>
1.33 +#include <cstddef>
1.34 +#include <functional>
1.35 +#include <numeric>
1.36 +
1.37 +namespace boost {
1.38 +namespace detail {
1.39 +namespace multi_array {
1.40 +
1.41 +// TPtr = const T* defaulted in base.hpp
1.42 +template <typename T, std::size_t NumDims, typename TPtr>
1.43 +class const_multi_array_view :
1.44 + public boost::detail::multi_array::multi_array_impl_base<T,NumDims>
1.45 +{
1.46 + typedef boost::detail::multi_array::multi_array_impl_base<T,NumDims> super_type;
1.47 +public:
1.48 + typedef typename super_type::value_type value_type;
1.49 + typedef typename super_type::const_reference const_reference;
1.50 + typedef typename super_type::const_iterator const_iterator;
1.51 + typedef typename super_type::const_reverse_iterator const_reverse_iterator;
1.52 + typedef typename super_type::element element;
1.53 + typedef typename super_type::size_type size_type;
1.54 + typedef typename super_type::difference_type difference_type;
1.55 + typedef typename super_type::index index;
1.56 + typedef typename super_type::extent_range extent_range;
1.57 +
1.58 + // template typedefs
1.59 + template <std::size_t NDims>
1.60 + struct const_array_view {
1.61 + typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
1.62 + };
1.63 +
1.64 + template <std::size_t NDims>
1.65 + struct array_view {
1.66 + typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
1.67 + };
1.68 +
1.69 + template <typename OPtr>
1.70 + const_multi_array_view(const
1.71 + const_multi_array_view<T,NumDims,OPtr>& other) :
1.72 + base_(other.base_), origin_offset_(other.origin_offset_),
1.73 + num_elements_(other.num_elements_), extent_list_(other.extent_list_),
1.74 + stride_list_(other.stride_list_), index_base_list_(other.index_base_list_)
1.75 + { }
1.76 +
1.77 +
1.78 + template <class BaseList>
1.79 +#ifdef BOOST_NO_SFINAE
1.80 + void
1.81 +#else
1.82 + typename
1.83 + disable_if<typename boost::is_integral<BaseList>::type,void >::type
1.84 +#endif
1.85 + reindex(const BaseList& values) {
1.86 + boost::function_requires<
1.87 + detail::multi_array::CollectionConcept<BaseList> >();
1.88 + boost::detail::multi_array::
1.89 + copy_n(values.begin(),num_dimensions(),index_base_list_.begin());
1.90 + origin_offset_ =
1.91 + this->calculate_indexing_offset(stride_list_,index_base_list_);
1.92 + }
1.93 +
1.94 + void reindex(index value) {
1.95 + index_base_list_.assign(value);
1.96 + origin_offset_ =
1.97 + this->calculate_indexing_offset(stride_list_,index_base_list_);
1.98 + }
1.99 +
1.100 + size_type num_dimensions() const { return NumDims; }
1.101 +
1.102 + size_type size() const { return extent_list_.front(); }
1.103 + size_type max_size() const { return num_elements(); }
1.104 + bool empty() const { return size() == 0; }
1.105 +
1.106 + const size_type* shape() const {
1.107 + return extent_list_.data();
1.108 + }
1.109 +
1.110 + const index* strides() const {
1.111 + return stride_list_.data();
1.112 + }
1.113 +
1.114 + const T* origin() const { return base_+origin_offset_; }
1.115 +
1.116 + size_type num_elements() const { return num_elements_; }
1.117 +
1.118 + const index* index_bases() const {
1.119 + return index_base_list_.data();
1.120 + }
1.121 +
1.122 + template <typename IndexList>
1.123 + const element& operator()(IndexList indices) const {
1.124 + boost::function_requires<
1.125 + detail::multi_array::CollectionConcept<IndexList> >();
1.126 + return super_type::access_element(boost::type<const element&>(),
1.127 + indices,origin(),
1.128 + shape(),strides(),index_bases());
1.129 + }
1.130 +
1.131 + // Only allow const element access
1.132 + const_reference operator[](index idx) const {
1.133 + return super_type::access(boost::type<const_reference>(),
1.134 + idx,origin(),
1.135 + shape(),strides(),
1.136 + index_bases());
1.137 + }
1.138 +
1.139 + // see generate_array_view in base.hpp
1.140 +#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
1.141 + template <int NDims>
1.142 +#else
1.143 + template <int NumDims, int NDims> // else ICE
1.144 +#endif // BOOST_MSVC
1.145 + typename const_array_view<NDims>::type
1.146 + operator[](const boost::detail::multi_array::
1.147 + index_gen<NumDims,NDims>& indices)
1.148 + const {
1.149 + typedef typename const_array_view<NDims>::type return_type;
1.150 + return
1.151 + super_type::generate_array_view(boost::type<return_type>(),
1.152 + indices,
1.153 + shape(),
1.154 + strides(),
1.155 + index_bases(),
1.156 + origin());
1.157 + }
1.158 + const_iterator begin() const {
1.159 + return const_iterator(*index_bases(),origin(),
1.160 + shape(),strides(),index_bases());
1.161 + }
1.162 +
1.163 + const_iterator end() const {
1.164 + return const_iterator(*index_bases()+(index)*shape(),origin(),
1.165 + shape(),strides(),index_bases());
1.166 + }
1.167 +
1.168 + const_reverse_iterator rbegin() const {
1.169 + return const_reverse_iterator(end());
1.170 + }
1.171 +
1.172 + const_reverse_iterator rend() const {
1.173 + return const_reverse_iterator(begin());
1.174 + }
1.175 +
1.176 +
1.177 + template <typename OPtr>
1.178 + bool operator==(const
1.179 + const_multi_array_view<T,NumDims,OPtr>& rhs)
1.180 + const {
1.181 + if(std::equal(extent_list_.begin(),
1.182 + extent_list_.end(),
1.183 + rhs.extent_list_.begin()))
1.184 + return std::equal(begin(),end(),rhs.begin());
1.185 + else return false;
1.186 + }
1.187 +
1.188 + template <typename OPtr>
1.189 + bool operator<(const
1.190 + const_multi_array_view<T,NumDims,OPtr>& rhs)
1.191 + const {
1.192 + return std::lexicographical_compare(begin(),end(),rhs.begin(),rhs.end());
1.193 + }
1.194 +
1.195 + template <typename OPtr>
1.196 + bool operator!=(const
1.197 + const_multi_array_view<T,NumDims,OPtr>& rhs)
1.198 + const {
1.199 + return !(*this == rhs);
1.200 + }
1.201 +
1.202 + template <typename OPtr>
1.203 + bool operator>(const
1.204 + const_multi_array_view<T,NumDims,OPtr>& rhs)
1.205 + const {
1.206 + return rhs < *this;
1.207 + }
1.208 +
1.209 + template <typename OPtr>
1.210 + bool operator<=(const
1.211 + const_multi_array_view<T,NumDims,OPtr>& rhs)
1.212 + const {
1.213 + return !(*this > rhs);
1.214 + }
1.215 +
1.216 + template <typename OPtr>
1.217 + bool operator>=(const
1.218 + const_multi_array_view<T,NumDims,OPtr>& rhs)
1.219 + const {
1.220 + return !(*this < rhs);
1.221 + }
1.222 +
1.223 +
1.224 +#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
1.225 +protected:
1.226 + template <typename,std::size_t> friend class multi_array_impl_base;
1.227 + template <typename,std::size_t,typename> friend class const_multi_array_view;
1.228 +#else
1.229 +public: // should be protected
1.230 +#endif
1.231 +
1.232 + // This constructor is used by multi_array_impl_base::generate_array_view
1.233 + // to create strides
1.234 + template <typename ExtentList, typename Index>
1.235 + explicit const_multi_array_view(TPtr base,
1.236 + const ExtentList& extents,
1.237 + const boost::array<Index,NumDims>& strides):
1.238 + base_(base), origin_offset_(0) {
1.239 +
1.240 + index_base_list_.assign(0);
1.241 +
1.242 + // Get the extents and strides
1.243 + boost::detail::multi_array::
1.244 + copy_n(extents.begin(),NumDims,extent_list_.begin());
1.245 + boost::detail::multi_array::
1.246 + copy_n(strides.begin(),NumDims,stride_list_.begin());
1.247 +
1.248 + // Calculate the array size
1.249 + num_elements_ = std::accumulate(extent_list_.begin(),extent_list_.end(),
1.250 + size_type(1),std::multiplies<size_type>());
1.251 +#if 0
1.252 + assert(num_elements_ != 0);
1.253 +#endif
1.254 + }
1.255 +
1.256 + typedef boost::array<size_type,NumDims> size_list;
1.257 + typedef boost::array<index,NumDims> index_list;
1.258 +
1.259 + TPtr base_;
1.260 + index origin_offset_;
1.261 + size_type num_elements_;
1.262 + size_list extent_list_;
1.263 + index_list stride_list_;
1.264 + index_list index_base_list_;
1.265 +
1.266 +private:
1.267 + // const_multi_array_view cannot be assigned to (no deep copies!)
1.268 + const_multi_array_view& operator=(const const_multi_array_view& other);
1.269 +};
1.270 +
1.271 +
1.272 +template <typename T, std::size_t NumDims>
1.273 +class multi_array_view :
1.274 + public const_multi_array_view<T,NumDims,T*>
1.275 +{
1.276 + typedef const_multi_array_view<T,NumDims,T*> super_type;
1.277 +public:
1.278 + typedef typename super_type::value_type value_type;
1.279 + typedef typename super_type::reference reference;
1.280 + typedef typename super_type::iterator iterator;
1.281 + typedef typename super_type::reverse_iterator reverse_iterator;
1.282 + typedef typename super_type::const_reference const_reference;
1.283 + typedef typename super_type::const_iterator const_iterator;
1.284 + typedef typename super_type::const_reverse_iterator const_reverse_iterator;
1.285 + typedef typename super_type::element element;
1.286 + typedef typename super_type::size_type size_type;
1.287 + typedef typename super_type::difference_type difference_type;
1.288 + typedef typename super_type::index index;
1.289 + typedef typename super_type::extent_range extent_range;
1.290 +
1.291 + // template typedefs
1.292 + template <std::size_t NDims>
1.293 + struct const_array_view {
1.294 + typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
1.295 + };
1.296 +
1.297 + template <std::size_t NDims>
1.298 + struct array_view {
1.299 + typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
1.300 + };
1.301 +
1.302 + // Assignment from other ConstMultiArray types.
1.303 + template <typename ConstMultiArray>
1.304 + multi_array_view& operator=(const ConstMultiArray& other) {
1.305 + function_requires<
1.306 + boost::detail::multi_array::
1.307 + ConstMultiArrayConcept<ConstMultiArray,NumDims> >();
1.308 +
1.309 + // make sure the dimensions agree
1.310 + assert(other.num_dimensions() == this->num_dimensions());
1.311 + assert(std::equal(other.shape(),other.shape()+this->num_dimensions(),
1.312 + this->shape()));
1.313 + // iterator-based copy
1.314 + std::copy(other.begin(),other.end(),begin());
1.315 + return *this;
1.316 + }
1.317 +
1.318 +
1.319 + multi_array_view& operator=(const multi_array_view& other) {
1.320 + if (&other != this) {
1.321 + // make sure the dimensions agree
1.322 + assert(other.num_dimensions() == this->num_dimensions());
1.323 + assert(std::equal(other.shape(),other.shape()+this->num_dimensions(),
1.324 + this->shape()));
1.325 + // iterator-based copy
1.326 + std::copy(other.begin(),other.end(),begin());
1.327 + }
1.328 + return *this;
1.329 + }
1.330 +
1.331 + element* origin() { return this->base_+this->origin_offset_; }
1.332 +
1.333 + template <class IndexList>
1.334 + element& operator()(const IndexList& indices) {
1.335 + boost::function_requires<
1.336 + detail::multi_array::CollectionConcept<IndexList> >();
1.337 + return super_type::access_element(boost::type<element&>(),
1.338 + indices,origin(),
1.339 + this->shape(),this->strides(),
1.340 + this->index_bases());
1.341 + }
1.342 +
1.343 +
1.344 + reference operator[](index idx) {
1.345 + return super_type::access(boost::type<reference>(),
1.346 + idx,origin(),
1.347 + this->shape(),this->strides(),
1.348 + this->index_bases());
1.349 + }
1.350 +
1.351 +
1.352 + // see generate_array_view in base.hpp
1.353 +#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
1.354 + template <int NDims>
1.355 +#else
1.356 + template <int NumDims, int NDims> // else ICE
1.357 +#endif // BOOST_MSVC
1.358 + typename array_view<NDims>::type
1.359 + operator[](const boost::detail::multi_array::
1.360 + index_gen<NumDims,NDims>& indices) {
1.361 + typedef typename array_view<NDims>::type return_type;
1.362 + return
1.363 + super_type::generate_array_view(boost::type<return_type>(),
1.364 + indices,
1.365 + this->shape(),
1.366 + this->strides(),
1.367 + this->index_bases(),
1.368 + origin());
1.369 + }
1.370 +
1.371 +
1.372 + iterator begin() {
1.373 + return iterator(*this->index_bases(),origin(),
1.374 + this->shape(),this->strides(),
1.375 + this->index_bases());
1.376 + }
1.377 +
1.378 + iterator end() {
1.379 + return iterator(*this->index_bases()+(index)*this->shape(),origin(),
1.380 + this->shape(),this->strides(),
1.381 + this->index_bases());
1.382 + }
1.383 +
1.384 + reverse_iterator rbegin() {
1.385 + return reverse_iterator(end());
1.386 + }
1.387 +
1.388 + reverse_iterator rend() {
1.389 + return reverse_iterator(begin());
1.390 + }
1.391 +
1.392 + // Using declarations don't seem to work for g++
1.393 + // These are the proxies to work around this.
1.394 +
1.395 + const element* origin() const { return super_type::origin(); }
1.396 +
1.397 + template <class IndexList>
1.398 + const element& operator()(const IndexList& indices) const {
1.399 + boost::function_requires<
1.400 + detail::multi_array::CollectionConcept<IndexList> >();
1.401 + return super_type::operator()(indices);
1.402 + }
1.403 +
1.404 + const_reference operator[](index idx) const {
1.405 + return super_type::operator[](idx);
1.406 + }
1.407 +
1.408 + // see generate_array_view in base.hpp
1.409 +#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
1.410 + template <int NDims>
1.411 +#else
1.412 + template <int NumDims, int NDims> // else ICE
1.413 +#endif // BOOST_MSVC
1.414 + typename const_array_view<NDims>::type
1.415 + operator[](const boost::detail::multi_array::
1.416 + index_gen<NumDims,NDims>& indices)
1.417 + const {
1.418 + return super_type::operator[](indices);
1.419 + }
1.420 +
1.421 + const_iterator begin() const {
1.422 + return super_type::begin();
1.423 + }
1.424 +
1.425 + const_iterator end() const {
1.426 + return super_type::end();
1.427 + }
1.428 +
1.429 + const_reverse_iterator rbegin() const {
1.430 + return super_type::rbegin();
1.431 + }
1.432 +
1.433 + const_reverse_iterator rend() const {
1.434 + return super_type::rend();
1.435 + }
1.436 +
1.437 +#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
1.438 +private:
1.439 + template <typename,std::size_t> friend class multi_array_impl_base;
1.440 +#else
1.441 +public: // should be private
1.442 +#endif
1.443 +
1.444 + // constructor used by multi_array_impl_base::generate_array_view to
1.445 + // generate array views
1.446 + template <typename ExtentList, typename Index>
1.447 + explicit multi_array_view(T* base,
1.448 + const ExtentList& extents,
1.449 + const boost::array<Index,NumDims>& strides) :
1.450 + super_type(base,extents,strides) { }
1.451 +
1.452 +};
1.453 +
1.454 +} // namespace multi_array
1.455 +} // namespace detail
1.456 +
1.457 +//
1.458 +// traits classes to get array_view types
1.459 +//
1.460 +template <typename Array, int N>
1.461 +class array_view_gen {
1.462 + typedef typename Array::element element;
1.463 +public:
1.464 + typedef boost::detail::multi_array::multi_array_view<element,N> type;
1.465 +};
1.466 +
1.467 +template <typename Array, int N>
1.468 +class const_array_view_gen {
1.469 + typedef typename Array::element element;
1.470 +public:
1.471 + typedef boost::detail::multi_array::const_multi_array_view<element,N> type;
1.472 +};
1.473 +
1.474 +} // namespace boost
1.475 +
1.476 +#endif // BOOST_MULTI_ARRAY_VIEW_RG071301_HPP
1.477 +