epoc32/include/stdapis/boost/mpl/base.hpp
branchSymbian2
changeset 3 e1b950c65cb4
parent 2 2fe1408b6811
child 4 837f303aceeb
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/epoc32/include/stdapis/boost/mpl/base.hpp	Wed Mar 31 12:27:01 2010 +0100
     1.3 @@ -0,0 +1,479 @@
     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