1.1 --- a/epoc32/include/stdapis/boost/multi_array/base.hpp Tue Mar 16 16:12:26 2010 +0000
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,479 +0,0 @@
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 BASE_RG071801_HPP
1.17 -#define BASE_RG071801_HPP
1.18 -
1.19 -//
1.20 -// base.hpp - some implementation base classes for from which
1.21 -// functionality is acquired
1.22 -//
1.23 -
1.24 -#include "boost/multi_array/extent_range.hpp"
1.25 -#include "boost/multi_array/extent_gen.hpp"
1.26 -#include "boost/multi_array/index_range.hpp"
1.27 -#include "boost/multi_array/index_gen.hpp"
1.28 -#include "boost/multi_array/storage_order.hpp"
1.29 -#include "boost/multi_array/types.hpp"
1.30 -#include "boost/config.hpp"
1.31 -#include "boost/multi_array/concept_checks.hpp" //for ignore_unused_...
1.32 -#include "boost/mpl/eval_if.hpp"
1.33 -#include "boost/mpl/if.hpp"
1.34 -#include "boost/mpl/size_t.hpp"
1.35 -#include "boost/mpl/aux_/msvc_eti_base.hpp"
1.36 -#include "boost/iterator/reverse_iterator.hpp"
1.37 -#include "boost/static_assert.hpp"
1.38 -#include "boost/type.hpp"
1.39 -#include "boost/assert.hpp"
1.40 -#include <cstddef>
1.41 -#include <memory>
1.42 -
1.43 -namespace boost {
1.44 -
1.45 -/////////////////////////////////////////////////////////////////////////
1.46 -// class declarations
1.47 -/////////////////////////////////////////////////////////////////////////
1.48 -
1.49 -template<typename T, std::size_t NumDims,
1.50 - typename Allocator = std::allocator<T> >
1.51 -class multi_array;
1.52 -
1.53 -// This is a public interface for use by end users!
1.54 -namespace multi_array_types {
1.55 - typedef boost::detail::multi_array::size_type size_type;
1.56 - typedef std::ptrdiff_t difference_type;
1.57 - typedef boost::detail::multi_array::index index;
1.58 - typedef detail::multi_array::index_range<index,size_type> index_range;
1.59 - typedef detail::multi_array::extent_range<index,size_type> extent_range;
1.60 - typedef detail::multi_array::index_gen<0,0> index_gen;
1.61 - typedef detail::multi_array::extent_gen<0> extent_gen;
1.62 -}
1.63 -
1.64 -
1.65 -// boost::extents and boost::indices are now a part of the public
1.66 -// interface. That way users don't necessarily have to create their
1.67 -// own objects. On the other hand, one may not want the overhead of
1.68 -// object creation in small-memory environments. Thus, the objects
1.69 -// can be left undefined by defining BOOST_MULTI_ARRAY_NO_GENERATORS
1.70 -// before loading multi_array.hpp.
1.71 -#if !BOOST_MULTI_ARRAY_NO_GENERATORS
1.72 -namespace {
1.73 - multi_array_types::extent_gen extents;
1.74 - multi_array_types::index_gen indices;
1.75 -}
1.76 -#endif // BOOST_MULTI_ARRAY_NO_GENERATORS
1.77 -
1.78 -namespace detail {
1.79 -namespace multi_array {
1.80 -
1.81 -template <typename T, std::size_t NumDims>
1.82 -class sub_array;
1.83 -
1.84 -template <typename T, std::size_t NumDims, typename TPtr = const T*>
1.85 -class const_sub_array;
1.86 -
1.87 -template <typename T, typename TPtr, typename NumDims, typename Reference>
1.88 -class array_iterator;
1.89 -
1.90 -template <typename T, std::size_t NumDims, typename TPtr = const T*>
1.91 -class const_multi_array_view;
1.92 -
1.93 -template <typename T, std::size_t NumDims>
1.94 -class multi_array_view;
1.95 -
1.96 -/////////////////////////////////////////////////////////////////////////
1.97 -// class interfaces
1.98 -/////////////////////////////////////////////////////////////////////////
1.99 -
1.100 -class multi_array_base {
1.101 -public:
1.102 - typedef multi_array_types::size_type size_type;
1.103 - typedef multi_array_types::difference_type difference_type;
1.104 - typedef multi_array_types::index index;
1.105 - typedef multi_array_types::index_range index_range;
1.106 - typedef multi_array_types::extent_range extent_range;
1.107 - typedef multi_array_types::index_gen index_gen;
1.108 - typedef multi_array_types::extent_gen extent_gen;
1.109 -};
1.110 -
1.111 -//
1.112 -// value_accessor_n
1.113 -// contains the routines for accessing elements from
1.114 -// N-dimensional views.
1.115 -//
1.116 -template<typename T, std::size_t NumDims>
1.117 -class value_accessor_n : public multi_array_base {
1.118 - typedef multi_array_base super_type;
1.119 -public:
1.120 - typedef typename super_type::index index;
1.121 -
1.122 - //
1.123 - // public typedefs used by classes that inherit from this base
1.124 - //
1.125 - typedef T element;
1.126 - typedef boost::multi_array<T,NumDims-1> value_type;
1.127 - typedef sub_array<T,NumDims-1> reference;
1.128 - typedef const_sub_array<T,NumDims-1> const_reference;
1.129 -
1.130 -protected:
1.131 - // used by array operator[] and iterators to get reference types.
1.132 - template <typename Reference, typename TPtr>
1.133 - Reference access(boost::type<Reference>,index idx,TPtr base,
1.134 - const size_type* extents,
1.135 - const index* strides,
1.136 - const index* index_bases) const {
1.137 -
1.138 - BOOST_ASSERT(idx - index_bases[0] >= 0);
1.139 - BOOST_ASSERT(size_type(idx - index_bases[0]) < extents[0]);
1.140 - // return a sub_array<T,NDims-1> proxy object
1.141 - TPtr newbase = base + idx * strides[0];
1.142 - return Reference(newbase,extents+1,strides+1,index_bases+1);
1.143 -
1.144 - }
1.145 -
1.146 - value_accessor_n() { }
1.147 - ~value_accessor_n() { }
1.148 -};
1.149 -
1.150 -
1.151 -
1.152 -//
1.153 -// value_accessor_one
1.154 -// contains the routines for accessing reference elements from
1.155 -// 1-dimensional views.
1.156 -//
1.157 -template<typename T>
1.158 -class value_accessor_one : public multi_array_base {
1.159 - typedef multi_array_base super_type;
1.160 -public:
1.161 - typedef typename super_type::index index;
1.162 - //
1.163 - // public typedefs for use by classes that inherit it.
1.164 - //
1.165 - typedef T element;
1.166 - typedef T value_type;
1.167 - typedef T& reference;
1.168 - typedef T const& const_reference;
1.169 -
1.170 -protected:
1.171 - // used by array operator[] and iterators to get reference types.
1.172 - template <typename Reference, typename TPtr>
1.173 - Reference access(boost::type<Reference>,index idx,TPtr base,
1.174 - const size_type* extents,
1.175 - const index* strides,
1.176 - const index* index_bases) const {
1.177 -
1.178 - ignore_unused_variable_warning(index_bases);
1.179 - ignore_unused_variable_warning(extents);
1.180 - BOOST_ASSERT(idx - index_bases[0] >= 0);
1.181 - BOOST_ASSERT(size_type(idx - index_bases[0]) < extents[0]);
1.182 - return *(base + idx * strides[0]);
1.183 - }
1.184 -
1.185 - value_accessor_one() { }
1.186 - ~value_accessor_one() { }
1.187 -};
1.188 -
1.189 -
1.190 -/////////////////////////////////////////////////////////////////////////
1.191 -// choose value accessor begins
1.192 -//
1.193 -
1.194 -template <typename T, std::size_t NumDims>
1.195 -struct choose_value_accessor_n {
1.196 - typedef value_accessor_n<T,NumDims> type;
1.197 -};
1.198 -
1.199 -template <typename T>
1.200 -struct choose_value_accessor_one {
1.201 - typedef value_accessor_one<T> type;
1.202 -};
1.203 -
1.204 -template <typename T, typename NumDims>
1.205 -struct value_accessor_generator {
1.206 - BOOST_STATIC_CONSTANT(std::size_t, dimensionality = NumDims::value);
1.207 -
1.208 - typedef typename
1.209 - mpl::eval_if_c<(dimensionality == 1),
1.210 - choose_value_accessor_one<T>,
1.211 - choose_value_accessor_n<T,dimensionality>
1.212 - >::type type;
1.213 -};
1.214 -
1.215 -#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
1.216 -
1.217 -struct eti_value_accessor
1.218 -{
1.219 - typedef int index;
1.220 - typedef int size_type;
1.221 - typedef int element;
1.222 - typedef int index_range;
1.223 - typedef int value_type;
1.224 - typedef int reference;
1.225 - typedef int const_reference;
1.226 -};
1.227 -
1.228 -template <>
1.229 -struct value_accessor_generator<int,int>
1.230 -{
1.231 - typedef eti_value_accessor type;
1.232 -};
1.233 -
1.234 -template <class T, class NumDims>
1.235 -struct associated_types
1.236 - : mpl::aux::msvc_eti_base<
1.237 - typename value_accessor_generator<T,NumDims>::type
1.238 - >::type
1.239 -{};
1.240 -
1.241 -template <>
1.242 -struct associated_types<int,int> : eti_value_accessor {};
1.243 -
1.244 -#else
1.245 -
1.246 -template <class T, class NumDims>
1.247 -struct associated_types
1.248 - : value_accessor_generator<T,NumDims>::type
1.249 -{};
1.250 -
1.251 -#endif
1.252 -
1.253 -//
1.254 -// choose value accessor ends
1.255 -/////////////////////////////////////////////////////////////////////////
1.256 -
1.257 -
1.258 -
1.259 -////////////////////////////////////////////////////////////////////////
1.260 -// multi_array_base
1.261 -////////////////////////////////////////////////////////////////////////
1.262 -template <typename T, std::size_t NumDims>
1.263 -class multi_array_impl_base
1.264 - :
1.265 -#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
1.266 - public mpl::aux::msvc_eti_base<
1.267 - typename value_accessor_generator<T,mpl::size_t<NumDims> >::type
1.268 - >::type
1.269 -#else
1.270 - public value_accessor_generator<T,mpl::size_t<NumDims> >::type
1.271 -#endif
1.272 -{
1.273 - typedef associated_types<T,mpl::size_t<NumDims> > types;
1.274 -public:
1.275 - typedef typename types::index index;
1.276 - typedef typename types::size_type size_type;
1.277 - typedef typename types::element element;
1.278 - typedef typename types::index_range index_range;
1.279 - typedef typename types::value_type value_type;
1.280 - typedef typename types::reference reference;
1.281 - typedef typename types::const_reference const_reference;
1.282 -
1.283 - template <std::size_t NDims>
1.284 - struct subarray {
1.285 - typedef boost::detail::multi_array::sub_array<T,NDims> type;
1.286 - };
1.287 -
1.288 - template <std::size_t NDims>
1.289 - struct const_subarray {
1.290 - typedef boost::detail::multi_array::const_sub_array<T,NDims> type;
1.291 - };
1.292 -
1.293 - template <std::size_t NDims>
1.294 - struct array_view {
1.295 - typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
1.296 - };
1.297 -
1.298 - template <std::size_t NDims>
1.299 - struct const_array_view {
1.300 - public:
1.301 - typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
1.302 - };
1.303 -
1.304 - //
1.305 - // iterator support
1.306 - //
1.307 - typedef array_iterator<T,T*,mpl::size_t<NumDims>,reference> iterator;
1.308 - typedef array_iterator<T,T const*,mpl::size_t<NumDims>,const_reference> const_iterator;
1.309 -
1.310 - typedef ::boost::reverse_iterator<iterator> reverse_iterator;
1.311 - typedef ::boost::reverse_iterator<const_iterator> const_reverse_iterator;
1.312 -
1.313 - BOOST_STATIC_CONSTANT(std::size_t, dimensionality = NumDims);
1.314 -protected:
1.315 -
1.316 - multi_array_impl_base() { }
1.317 - ~multi_array_impl_base() { }
1.318 -
1.319 - // Used by operator() in our array classes
1.320 - template <typename Reference, typename IndexList, typename TPtr>
1.321 - Reference access_element(boost::type<Reference>,
1.322 - const IndexList& indices,
1.323 - TPtr base,
1.324 - const size_type* extents,
1.325 - const index* strides,
1.326 - const index* index_bases) const {
1.327 -
1.328 - ignore_unused_variable_warning(index_bases);
1.329 - ignore_unused_variable_warning(extents);
1.330 -#if !defined(NDEBUG) && !defined(BOOST_DISABLE_ASSERTS)
1.331 - for (size_type i = 0; i != NumDims; ++i) {
1.332 - BOOST_ASSERT(indices[i] - index_bases[i] >= 0);
1.333 - BOOST_ASSERT(size_type(indices[i] - index_bases[i]) < extents[i]);
1.334 - }
1.335 -#endif
1.336 -
1.337 - index offset = 0;
1.338 - for (size_type n = 0; n != NumDims; ++n)
1.339 - offset += indices[n] * strides[n];
1.340 -
1.341 - return base[offset];
1.342 - }
1.343 -
1.344 - template <typename StrideList, typename ExtentList>
1.345 - void compute_strides(StrideList& stride_list, ExtentList& extent_list,
1.346 - const general_storage_order<NumDims>& storage)
1.347 - {
1.348 - // invariant: stride = the stride for dimension n
1.349 - index stride = 1;
1.350 - for (size_type n = 0; n != NumDims; ++n) {
1.351 - index stride_sign = +1;
1.352 -
1.353 - if (!storage.ascending(storage.ordering(n)))
1.354 - stride_sign = -1;
1.355 -
1.356 - // The stride for this dimension is the product of the
1.357 - // lengths of the ranks minor to it.
1.358 - stride_list[storage.ordering(n)] = stride * stride_sign;
1.359 -
1.360 - stride *= extent_list[storage.ordering(n)];
1.361 - }
1.362 - }
1.363 -
1.364 - // This calculates the offset to the array base pointer due to:
1.365 - // 1. dimensions stored in descending order
1.366 - // 2. non-zero dimension index bases
1.367 - template <typename StrideList, typename ExtentList, typename BaseList>
1.368 - index
1.369 - calculate_origin_offset(const StrideList& stride_list,
1.370 - const ExtentList& extent_list,
1.371 - const general_storage_order<NumDims>& storage,
1.372 - const BaseList& index_base_list)
1.373 - {
1.374 - return
1.375 - calculate_descending_dimension_offset(stride_list,extent_list,
1.376 - storage) +
1.377 - calculate_indexing_offset(stride_list,index_base_list);
1.378 - }
1.379 -
1.380 - // This calculates the offset added to the base pointer that are
1.381 - // caused by descending dimensions
1.382 - template <typename StrideList, typename ExtentList>
1.383 - index
1.384 - calculate_descending_dimension_offset(const StrideList& stride_list,
1.385 - const ExtentList& extent_list,
1.386 - const general_storage_order<NumDims>& storage)
1.387 - {
1.388 - index offset = 0;
1.389 - if (!storage.all_dims_ascending())
1.390 - for (size_type n = 0; n != NumDims; ++n)
1.391 - if (!storage.ascending(n))
1.392 - offset -= (extent_list[n] - 1) * stride_list[n];
1.393 -
1.394 - return offset;
1.395 - }
1.396 -
1.397 - // This is used to reindex array_views, which are no longer
1.398 - // concerned about storage order (specifically, whether dimensions
1.399 - // are ascending or descending) since the viewed array handled it.
1.400 -
1.401 - template <typename StrideList, typename BaseList>
1.402 - index
1.403 - calculate_indexing_offset(const StrideList& stride_list,
1.404 - const BaseList& index_base_list)
1.405 - {
1.406 - index offset = 0;
1.407 - for (size_type n = 0; n != NumDims; ++n)
1.408 - offset -= stride_list[n] * index_base_list[n];
1.409 - return offset;
1.410 - }
1.411 -
1.412 - // Slicing using an index_gen.
1.413 - // Note that populating an index_gen creates a type that encodes
1.414 - // both the number of dimensions in the current Array (NumDims), and
1.415 - // the Number of dimensions for the resulting view. This allows the
1.416 - // compiler to fail if the dimensions aren't completely accounted
1.417 - // for. For reasons unbeknownst to me, a BOOST_STATIC_ASSERT
1.418 - // within the member function template does not work. I should add a
1.419 - // note to the documentation specifying that you get a damn ugly
1.420 - // error message if you screw up in your slicing code.
1.421 - template <typename ArrayRef, int NDims, typename TPtr>
1.422 - ArrayRef
1.423 - generate_array_view(boost::type<ArrayRef>,
1.424 - const boost::detail::multi_array::
1.425 - index_gen<NumDims,NDims>& indices,
1.426 - const size_type* extents,
1.427 - const index* strides,
1.428 - const index* index_bases,
1.429 - TPtr base) const {
1.430 -
1.431 - boost::array<index,NDims> new_strides;
1.432 - boost::array<index,NDims> new_extents;
1.433 -
1.434 - index offset = 0;
1.435 - size_type dim = 0;
1.436 - for (size_type n = 0; n != NumDims; ++n) {
1.437 - const index default_start = index_bases[n];
1.438 - const index default_finish = default_start+extents[n];
1.439 - const index_range& current_range = indices.ranges_[n];
1.440 - index start = current_range.get_start(default_start);
1.441 - index finish = current_range.get_finish(default_finish);
1.442 - index index_factor = current_range.stride();
1.443 - index len = (finish - start + (index_factor - 1)) / index_factor;
1.444 -
1.445 - BOOST_ASSERT(index_bases[n] <= start &&
1.446 - start <= index_bases[n]+index(extents[n]));
1.447 - BOOST_ASSERT(index_bases[n] <= finish &&
1.448 - finish <= index_bases[n]+index(extents[n]));
1.449 - BOOST_ASSERT(index_factor > 0);
1.450 -
1.451 - // the array data pointer is modified to account for non-zero
1.452 - // bases during slicing (see [Garcia] for the math involved)
1.453 - offset += start * strides[n];
1.454 -
1.455 - if (!current_range.is_degenerate()) {
1.456 -
1.457 - // The index_factor for each dimension is included into the
1.458 - // strides for the array_view (see [Garcia] for the math involved).
1.459 - new_strides[dim] = index_factor * strides[n];
1.460 -
1.461 - // calculate new extents
1.462 - new_extents[dim] = len;
1.463 - ++dim;
1.464 - }
1.465 - }
1.466 - BOOST_ASSERT(dim == NDims);
1.467 -
1.468 - return
1.469 - ArrayRef(base+offset,
1.470 - new_extents,
1.471 - new_strides);
1.472 - }
1.473 -
1.474 -
1.475 -};
1.476 -
1.477 -} // namespace multi_array
1.478 -} // namespace detail
1.479 -
1.480 -} // namespace boost
1.481 -
1.482 -#endif // BASE_RG071801_HPP