1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/epoc32/include/stdapis/boost/multi_array/subarray.hpp Tue Mar 16 16:12:26 2010 +0000
1.3 @@ -0,0 +1,398 @@
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 SUBARRAY_RG071801_HPP
1.17 +#define SUBARRAY_RG071801_HPP
1.18 +
1.19 +//
1.20 +// subarray.hpp - used to implement standard operator[] on
1.21 +// multi_arrays
1.22 +//
1.23 +
1.24 +#include "boost/multi_array/base.hpp"
1.25 +#include "boost/multi_array/concept_checks.hpp"
1.26 +#include "boost/limits.hpp"
1.27 +#include "boost/type.hpp"
1.28 +#include <algorithm>
1.29 +#include <cstddef>
1.30 +#include <functional>
1.31 +
1.32 +namespace boost {
1.33 +namespace detail {
1.34 +namespace multi_array {
1.35 +
1.36 +//
1.37 +// const_sub_array
1.38 +// multi_array's proxy class to allow multiple overloads of
1.39 +// operator[] in order to provide a clean multi-dimensional array
1.40 +// interface.
1.41 +template <typename T, std::size_t NumDims, typename TPtr>
1.42 +class const_sub_array :
1.43 + public boost::detail::multi_array::multi_array_impl_base<T,NumDims>
1.44 +{
1.45 + typedef boost::detail::multi_array::multi_array_impl_base<T,NumDims> super_type;
1.46 +public:
1.47 + typedef typename super_type::value_type value_type;
1.48 + typedef typename super_type::const_reference const_reference;
1.49 + typedef typename super_type::const_iterator const_iterator;
1.50 + typedef typename super_type::const_reverse_iterator const_reverse_iterator;
1.51 + typedef typename super_type::element element;
1.52 + typedef typename super_type::size_type size_type;
1.53 + typedef typename super_type::difference_type difference_type;
1.54 + typedef typename super_type::index index;
1.55 + typedef typename super_type::extent_range extent_range;
1.56 +
1.57 + // template typedefs
1.58 + template <std::size_t NDims>
1.59 + struct const_array_view {
1.60 + typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
1.61 + };
1.62 +
1.63 + template <std::size_t NDims>
1.64 + struct array_view {
1.65 + typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
1.66 + };
1.67 +
1.68 + // Allow default copy constructor as well.
1.69 +
1.70 + template <typename OPtr>
1.71 + const_sub_array (const const_sub_array<T,NumDims,OPtr>& rhs) :
1.72 + base_(rhs.base_), extents_(rhs.extents_), strides_(rhs.strides_),
1.73 + index_base_(rhs.index_base_) {
1.74 + }
1.75 +
1.76 + // const_sub_array always returns const types, regardless of its own
1.77 + // constness.
1.78 + const_reference operator[](index idx) const {
1.79 + return super_type::access(boost::type<const_reference>(),
1.80 + idx,base_,shape(),strides(),index_bases());
1.81 + }
1.82 +
1.83 + template <typename IndexList>
1.84 + const element& operator()(const IndexList& indices) const {
1.85 + boost::function_requires<
1.86 + detail::multi_array::CollectionConcept<IndexList> >();
1.87 + return super_type::access_element(boost::type<const element&>(),
1.88 + indices,origin(),
1.89 + shape(),strides(),index_bases());
1.90 + }
1.91 +
1.92 + // see generate_array_view in base.hpp
1.93 +#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
1.94 + template <int NDims>
1.95 +#else
1.96 + template <int NumDims, int NDims> // else ICE
1.97 +#endif // BOOST_MSVC
1.98 + typename const_array_view<NDims>::type
1.99 + operator[](const boost::detail::multi_array::
1.100 + index_gen<NumDims,NDims>& indices)
1.101 + const {
1.102 + typedef typename const_array_view<NDims>::type return_type;
1.103 + return
1.104 + super_type::generate_array_view(boost::type<return_type>(),
1.105 + indices,
1.106 + shape(),
1.107 + strides(),
1.108 + index_bases(),
1.109 + base_);
1.110 + }
1.111 +
1.112 + template <typename OPtr>
1.113 + bool operator<(const const_sub_array<T,NumDims,OPtr>& rhs) const {
1.114 + return std::lexicographical_compare(begin(),end(),rhs.begin(),rhs.end());
1.115 + }
1.116 +
1.117 + template <typename OPtr>
1.118 + bool operator==(const const_sub_array<T,NumDims,OPtr>& rhs) const {
1.119 + if(std::equal(shape(),shape()+num_dimensions(),rhs.shape()))
1.120 + return std::equal(begin(),end(),rhs.begin());
1.121 + else return false;
1.122 + }
1.123 +
1.124 + template <typename OPtr>
1.125 + bool operator!=(const const_sub_array<T,NumDims,OPtr>& rhs) const {
1.126 + return !(*this == rhs);
1.127 + }
1.128 +
1.129 + template <typename OPtr>
1.130 + bool operator>(const const_sub_array<T,NumDims,OPtr>& rhs) const {
1.131 + return rhs < *this;
1.132 + }
1.133 +
1.134 + template <typename OPtr>
1.135 + bool operator<=(const const_sub_array<T,NumDims,OPtr>& rhs) const {
1.136 + return !(*this > rhs);
1.137 + }
1.138 +
1.139 + template <typename OPtr>
1.140 + bool operator>=(const const_sub_array<T,NumDims,OPtr>& rhs) const {
1.141 + return !(*this < rhs);
1.142 + }
1.143 +
1.144 + const_iterator begin() const {
1.145 + return const_iterator(*index_bases(),origin(),
1.146 + shape(),strides(),index_bases());
1.147 + }
1.148 +
1.149 + const_iterator end() const {
1.150 + return const_iterator(*index_bases()+(index)*shape(),origin(),
1.151 + shape(),strides(),index_bases());
1.152 + }
1.153 +
1.154 + const_reverse_iterator rbegin() const {
1.155 + return const_reverse_iterator(end());
1.156 + }
1.157 +
1.158 + const_reverse_iterator rend() const {
1.159 + return const_reverse_iterator(begin());
1.160 + }
1.161 +
1.162 + TPtr origin() const { return base_; }
1.163 + size_type size() const { return extents_[0]; }
1.164 + size_type max_size() const { return num_elements(); }
1.165 + bool empty() const { return size() == 0; }
1.166 + size_type num_dimensions() const { return NumDims; }
1.167 + const size_type* shape() const { return extents_; }
1.168 + const index* strides() const { return strides_; }
1.169 + const index* index_bases() const { return index_base_; }
1.170 +
1.171 + size_type num_elements() const {
1.172 + return std::accumulate(shape(),shape() + num_dimensions(),
1.173 + size_type(1), std::multiplies<size_type>());
1.174 + }
1.175 +
1.176 +
1.177 +#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
1.178 +protected:
1.179 + template <typename,std::size_t> friend class value_accessor_n;
1.180 + template <typename,std::size_t,typename> friend class const_sub_array;
1.181 +#else
1.182 +public: // Should be protected
1.183 +#endif
1.184 +
1.185 + const_sub_array (TPtr base,
1.186 + const size_type* extents,
1.187 + const index* strides,
1.188 + const index* index_base) :
1.189 + base_(base), extents_(extents), strides_(strides),
1.190 + index_base_(index_base) {
1.191 + }
1.192 +
1.193 + TPtr base_;
1.194 + const size_type* extents_;
1.195 + const index* strides_;
1.196 + const index* index_base_;
1.197 +private:
1.198 + // const_sub_array cannot be assigned to (no deep copies!)
1.199 + const_sub_array& operator=(const const_sub_array&);
1.200 +};
1.201 +
1.202 +
1.203 +//
1.204 +// sub_array
1.205 +// multi_array's proxy class to allow multiple overloads of
1.206 +// operator[] in order to provide a clean multi-dimensional array
1.207 +// interface.
1.208 +template <typename T, std::size_t NumDims>
1.209 +class sub_array : public const_sub_array<T,NumDims,T*>
1.210 +{
1.211 + typedef const_sub_array<T,NumDims,T*> super_type;
1.212 +public:
1.213 + typedef typename super_type::element element;
1.214 + typedef typename super_type::reference reference;
1.215 + typedef typename super_type::index index;
1.216 + typedef typename super_type::size_type size_type;
1.217 + typedef typename super_type::iterator iterator;
1.218 + typedef typename super_type::reverse_iterator reverse_iterator;
1.219 + typedef typename super_type::const_reference const_reference;
1.220 + typedef typename super_type::const_iterator const_iterator;
1.221 + typedef typename super_type::const_reverse_iterator const_reverse_iterator;
1.222 +
1.223 + // template typedefs
1.224 + template <std::size_t NDims>
1.225 + struct const_array_view {
1.226 + typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
1.227 + };
1.228 +
1.229 + template <std::size_t NDims>
1.230 + struct array_view {
1.231 + typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
1.232 + };
1.233 +
1.234 + // Assignment from other ConstMultiArray types.
1.235 + template <typename ConstMultiArray>
1.236 + sub_array& operator=(const ConstMultiArray& other) {
1.237 + function_requires< boost::detail::multi_array::ConstMultiArrayConcept<
1.238 + ConstMultiArray, NumDims> >();
1.239 +
1.240 + // make sure the dimensions agree
1.241 + assert(other.num_dimensions() == this->num_dimensions());
1.242 + assert(std::equal(other.shape(),other.shape()+this->num_dimensions(),
1.243 + this->shape()));
1.244 + // iterator-based copy
1.245 + std::copy(other.begin(),other.end(),begin());
1.246 + return *this;
1.247 + }
1.248 +
1.249 +
1.250 + sub_array& operator=(const sub_array& other) {
1.251 + if (&other != this) {
1.252 + // make sure the dimensions agree
1.253 + assert(other.num_dimensions() == this->num_dimensions());
1.254 + assert(std::equal(other.shape(),other.shape()+this->num_dimensions(),
1.255 + this->shape()));
1.256 + // iterator-based copy
1.257 + std::copy(other.begin(),other.end(),begin());
1.258 + }
1.259 + return *this;
1.260 + }
1.261 +
1.262 + T* origin() { return this->base_; }
1.263 + const T* origin() const { return this->base_; }
1.264 +
1.265 + reference operator[](index idx) {
1.266 + return super_type::access(boost::type<reference>(),
1.267 + idx,this->base_,this->shape(),this->strides(),
1.268 + this->index_bases());
1.269 + }
1.270 +
1.271 + // see generate_array_view in base.hpp
1.272 +#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
1.273 + template <int NDims>
1.274 +#else
1.275 + template <int NumDims, int NDims> // else ICE
1.276 +#endif // BOOST_MSVC
1.277 + typename array_view<NDims>::type
1.278 + operator[](const boost::detail::multi_array::
1.279 + index_gen<NumDims,NDims>& indices) {
1.280 + typedef typename array_view<NDims>::type return_type;
1.281 + return
1.282 + super_type::generate_array_view(boost::type<return_type>(),
1.283 + indices,
1.284 + this->shape(),
1.285 + this->strides(),
1.286 + this->index_bases(),
1.287 + origin());
1.288 + }
1.289 +
1.290 + template <class IndexList>
1.291 + element& operator()(const IndexList& indices) {
1.292 + boost::function_requires<
1.293 + detail::multi_array::CollectionConcept<IndexList> >();
1.294 + return super_type::access_element(boost::type<element&>(),
1.295 + indices,origin(),
1.296 + this->shape(),this->strides(),
1.297 + this->index_bases());
1.298 + }
1.299 +
1.300 + iterator begin() {
1.301 + return iterator(*this->index_bases(),origin(),
1.302 + this->shape(),this->strides(),this->index_bases());
1.303 + }
1.304 +
1.305 + iterator end() {
1.306 + return iterator(*this->index_bases()+(index)*this->shape(),origin(),
1.307 + this->shape(),this->strides(),this->index_bases());
1.308 + }
1.309 +
1.310 + // RG - rbegin() and rend() written naively to thwart MSVC ICE.
1.311 + reverse_iterator rbegin() {
1.312 + reverse_iterator ri(end());
1.313 + return ri;
1.314 + }
1.315 +
1.316 + reverse_iterator rend() {
1.317 + reverse_iterator ri(begin());
1.318 + return ri;
1.319 + }
1.320 +
1.321 + //
1.322 + // proxies
1.323 + //
1.324 +
1.325 + template <class IndexList>
1.326 + const element& operator()(const IndexList& indices) const {
1.327 + boost::function_requires<
1.328 + detail::multi_array::CollectionConcept<IndexList> >();
1.329 + return super_type::operator()(indices);
1.330 + }
1.331 +
1.332 + const_reference operator[](index idx) const {
1.333 + return super_type::operator[](idx);
1.334 + }
1.335 +
1.336 + // see generate_array_view in base.hpp
1.337 +#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
1.338 + template <int NDims>
1.339 +#else
1.340 + template <int NumDims, int NDims> // else ICE
1.341 +#endif // BOOST_MSVC
1.342 + typename const_array_view<NDims>::type
1.343 + operator[](const boost::detail::multi_array::
1.344 + index_gen<NumDims,NDims>& indices)
1.345 + const {
1.346 + return super_type::operator[](indices);
1.347 + }
1.348 +
1.349 + const_iterator begin() const {
1.350 + return super_type::begin();
1.351 + }
1.352 +
1.353 + const_iterator end() const {
1.354 + return super_type::end();
1.355 + }
1.356 +
1.357 + const_reverse_iterator rbegin() const {
1.358 + return super_type::rbegin();
1.359 + }
1.360 +
1.361 + const_reverse_iterator rend() const {
1.362 + return super_type::rend();
1.363 + }
1.364 +
1.365 +#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
1.366 +private:
1.367 + template <typename,std::size_t> friend class value_accessor_n;
1.368 +#else
1.369 +public: // should be private
1.370 +#endif
1.371 +
1.372 + sub_array (T* base,
1.373 + const size_type* extents,
1.374 + const index* strides,
1.375 + const index* index_base) :
1.376 + super_type(base,extents,strides,index_base) {
1.377 + }
1.378 +
1.379 +};
1.380 +
1.381 +} // namespace multi_array
1.382 +} // namespace detail
1.383 +//
1.384 +// traits classes to get sub_array types
1.385 +//
1.386 +template <typename Array, int N>
1.387 +class subarray_gen {
1.388 + typedef typename Array::element element;
1.389 +public:
1.390 + typedef boost::detail::multi_array::sub_array<element,N> type;
1.391 +};
1.392 +
1.393 +template <typename Array, int N>
1.394 +class const_subarray_gen {
1.395 + typedef typename Array::element element;
1.396 +public:
1.397 + typedef boost::detail::multi_array::const_sub_array<element,N> type;
1.398 +};
1.399 +} // namespace boost
1.400 +
1.401 +#endif // SUBARRAY_RG071801_HPP