epoc32/include/stdapis/boost/multi_array.hpp
branchSymbian2
changeset 2 2fe1408b6811
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/epoc32/include/stdapis/boost/multi_array.hpp	Tue Mar 16 16:12:26 2010 +0000
     1.3 @@ -0,0 +1,499 @@
     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_RG071801_HPP
    1.17 +#define BOOST_MULTI_ARRAY_RG071801_HPP
    1.18 +
    1.19 +//
    1.20 +// multi_array.hpp - contains the multi_array class template
    1.21 +// declaration and definition
    1.22 +//
    1.23 +
    1.24 +#include "boost/multi_array/base.hpp"
    1.25 +#include "boost/multi_array/collection_concept.hpp"
    1.26 +#include "boost/multi_array/copy_array.hpp"
    1.27 +#include "boost/multi_array/iterator.hpp"
    1.28 +#include "boost/multi_array/subarray.hpp"
    1.29 +#include "boost/multi_array/multi_array_ref.hpp"
    1.30 +#include "boost/multi_array/algorithm.hpp"
    1.31 +#include "boost/array.hpp"
    1.32 +#include "boost/mpl/if.hpp"
    1.33 +#include "boost/type_traits.hpp"
    1.34 +#include <algorithm>
    1.35 +#include <cstddef>
    1.36 +#include <functional>
    1.37 +#include <numeric>
    1.38 +#include <vector>
    1.39 +
    1.40 +
    1.41 +
    1.42 +namespace boost {
    1.43 +  namespace detail {
    1.44 +    namespace multi_array {
    1.45 +
    1.46 +      struct populate_index_ranges {
    1.47 +        multi_array_types::index_range
    1.48 +        // RG: underscore on extent_ to stifle strange MSVC warning.
    1.49 +        operator()(multi_array_types::index base,
    1.50 +                   multi_array_types::size_type extent_) {
    1.51 +          return multi_array_types::index_range(base,base+extent_);
    1.52 +        }
    1.53 +      };
    1.54 +
    1.55 +#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
    1.56 +//
    1.57 +// Compilers that don't support partial ordering may need help to
    1.58 +// disambiguate multi_array's templated constructors.  Even vc6/7 are
    1.59 +// capable of some limited SFINAE, so we take the most-general version
    1.60 +// out of the overload set with disable_multi_array_impl.
    1.61 +//
    1.62 +template <typename T, std::size_t NumDims, typename TPtr>
    1.63 +char is_multi_array_impl_help(const_multi_array_view<T,NumDims,TPtr>&);
    1.64 +template <typename T, std::size_t NumDims, typename TPtr>
    1.65 +char is_multi_array_impl_help(const_sub_array<T,NumDims,TPtr>&);
    1.66 +template <typename T, std::size_t NumDims, typename TPtr>
    1.67 +char is_multi_array_impl_help(const_multi_array_ref<T,NumDims,TPtr>&);
    1.68 +
    1.69 +char ( &is_multi_array_impl_help(...) )[2];
    1.70 +
    1.71 +template <class T>
    1.72 +struct is_multi_array_impl
    1.73 +{
    1.74 +    static T x;
    1.75 +    BOOST_STATIC_CONSTANT(bool, value = sizeof((is_multi_array_impl_help)(x)) == 1);
    1.76 +
    1.77 +  typedef mpl::bool_<value> type;
    1.78 +};
    1.79 +
    1.80 +template <bool multi_array = false>
    1.81 +struct disable_multi_array_impl_impl
    1.82 +{
    1.83 +    typedef int type;
    1.84 +};
    1.85 +
    1.86 +template <>
    1.87 +struct disable_multi_array_impl_impl<true>
    1.88 +{
    1.89 +    // forming a pointer to a reference triggers SFINAE
    1.90 +    typedef int& type; 
    1.91 +};
    1.92 +
    1.93 +
    1.94 +template <class T>
    1.95 +struct disable_multi_array_impl :
    1.96 +  disable_multi_array_impl_impl<is_multi_array_impl<T>::value>
    1.97 +{ };
    1.98 +
    1.99 +
   1.100 +template <>
   1.101 +struct disable_multi_array_impl<int>
   1.102 +{
   1.103 +  typedef int type;
   1.104 +};
   1.105 +
   1.106 +
   1.107 +#endif
   1.108 +
   1.109 +    } //namespace multi_array
   1.110 +  } // namespace detail
   1.111 +
   1.112 +template<typename T, std::size_t NumDims,
   1.113 +  typename Allocator>
   1.114 +class multi_array :
   1.115 +  public multi_array_ref<T,NumDims>
   1.116 +{
   1.117 +  typedef multi_array_ref<T,NumDims> super_type;
   1.118 +public:
   1.119 +  typedef typename super_type::value_type value_type;
   1.120 +  typedef typename super_type::reference reference;
   1.121 +  typedef typename super_type::const_reference const_reference;
   1.122 +  typedef typename super_type::iterator iterator;
   1.123 +  typedef typename super_type::const_iterator const_iterator;
   1.124 +  typedef typename super_type::reverse_iterator reverse_iterator;
   1.125 +  typedef typename super_type::const_reverse_iterator const_reverse_iterator;
   1.126 +  typedef typename super_type::element element;
   1.127 +  typedef typename super_type::size_type size_type;
   1.128 +  typedef typename super_type::difference_type difference_type;
   1.129 +  typedef typename super_type::index index;
   1.130 +  typedef typename super_type::extent_range extent_range;
   1.131 +
   1.132 +
   1.133 +  template <std::size_t NDims>
   1.134 +  struct const_array_view {
   1.135 +    typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
   1.136 +  };
   1.137 +
   1.138 +  template <std::size_t NDims>
   1.139 +  struct array_view {
   1.140 +    typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
   1.141 +  };
   1.142 +
   1.143 +  explicit multi_array() :
   1.144 +    super_type((T*)initial_base_,c_storage_order(),
   1.145 +               /*index_bases=*/0, /*extents=*/0) {
   1.146 +    allocate_space(); 
   1.147 +  }
   1.148 +
   1.149 +  template <class ExtentList>
   1.150 +  explicit multi_array(
   1.151 +      ExtentList const& extents
   1.152 +#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
   1.153 +      , typename mpl::if_<
   1.154 +      detail::multi_array::is_multi_array_impl<ExtentList>,
   1.155 +      int&,int>::type* = 0
   1.156 +#endif
   1.157 +      ) :
   1.158 +    super_type((T*)initial_base_,extents) {
   1.159 +    boost::function_requires<
   1.160 +      detail::multi_array::CollectionConcept<ExtentList> >();
   1.161 +    allocate_space();
   1.162 +  }
   1.163 +
   1.164 +    
   1.165 +  template <class ExtentList>
   1.166 +  explicit multi_array(ExtentList const& extents,
   1.167 +                       const general_storage_order<NumDims>& so) :
   1.168 +    super_type((T*)initial_base_,extents,so) {
   1.169 +    boost::function_requires<
   1.170 +      detail::multi_array::CollectionConcept<ExtentList> >();
   1.171 +    allocate_space();
   1.172 +  }
   1.173 +
   1.174 +  template <class ExtentList>
   1.175 +  explicit multi_array(ExtentList const& extents,
   1.176 +                       const general_storage_order<NumDims>& so,
   1.177 +                       Allocator const& alloc) :
   1.178 +    super_type((T*)initial_base_,extents,so), allocator_(alloc) {
   1.179 +    boost::function_requires<
   1.180 +      detail::multi_array::CollectionConcept<ExtentList> >();
   1.181 +    allocate_space();
   1.182 +  }
   1.183 +
   1.184 +
   1.185 +  explicit multi_array(const detail::multi_array
   1.186 +                       ::extent_gen<NumDims>& ranges) :
   1.187 +    super_type((T*)initial_base_,ranges) {
   1.188 +
   1.189 +    allocate_space();
   1.190 +  }
   1.191 +
   1.192 +
   1.193 +  explicit multi_array(const detail::multi_array
   1.194 +                       ::extent_gen<NumDims>& ranges,
   1.195 +                       const general_storage_order<NumDims>& so) :
   1.196 +    super_type((T*)initial_base_,ranges,so) {
   1.197 +
   1.198 +    allocate_space();
   1.199 +  }
   1.200 +
   1.201 +
   1.202 +  explicit multi_array(const detail::multi_array
   1.203 +                       ::extent_gen<NumDims>& ranges,
   1.204 +                       const general_storage_order<NumDims>& so,
   1.205 +                       Allocator const& alloc) :
   1.206 +    super_type((T*)initial_base_,ranges,so), allocator_(alloc) {
   1.207 +
   1.208 +    allocate_space();
   1.209 +  }
   1.210 +
   1.211 +  multi_array(const multi_array& rhs) :
   1.212 +  super_type(rhs), allocator_(rhs.allocator_) {
   1.213 +    allocate_space();
   1.214 +    boost::detail::multi_array::copy_n(rhs.base_,rhs.num_elements(),base_);
   1.215 +  }
   1.216 +
   1.217 +
   1.218 +  //
   1.219 +  // A multi_array is constructible from any multi_array_ref, subarray, or
   1.220 +  // array_view object.  The following constructors ensure that.
   1.221 +  //
   1.222 +
   1.223 +  // Due to limited support for partial template ordering, 
   1.224 +  // MSVC 6&7 confuse the following with the most basic ExtentList 
   1.225 +  // constructor.
   1.226 +#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
   1.227 +  template <typename OPtr>
   1.228 +  multi_array(const const_multi_array_ref<T,NumDims,OPtr>& rhs,
   1.229 +              const general_storage_order<NumDims>& so = c_storage_order())
   1.230 +    : super_type(0,so,rhs.index_bases(),rhs.shape()) 
   1.231 +  {
   1.232 +    allocate_space();
   1.233 +    // Warning! storage order may change, hence the following copy technique.
   1.234 +    std::copy(rhs.begin(),rhs.end(),this->begin());
   1.235 +  }
   1.236 +
   1.237 +  template <typename OPtr>
   1.238 +  multi_array(const detail::multi_array::
   1.239 +              const_sub_array<T,NumDims,OPtr>& rhs,
   1.240 +              const general_storage_order<NumDims>& so = c_storage_order())
   1.241 +    : super_type(0,so,rhs.index_bases(),rhs.shape()) 
   1.242 +  {
   1.243 +    allocate_space();
   1.244 +    std::copy(rhs.begin(),rhs.end(),this->begin());
   1.245 +  }
   1.246 +
   1.247 +
   1.248 +  template <typename OPtr>
   1.249 +  multi_array(const detail::multi_array::
   1.250 +              const_multi_array_view<T,NumDims,OPtr>& rhs,
   1.251 +              const general_storage_order<NumDims>& so = c_storage_order())
   1.252 +    : super_type(0,so,rhs.index_bases(),rhs.shape()) 
   1.253 +  {
   1.254 +    allocate_space();
   1.255 +    std::copy(rhs.begin(),rhs.end(),this->begin());
   1.256 +  }
   1.257 +
   1.258 +#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
   1.259 +  // More limited support for MSVC
   1.260 +
   1.261 +
   1.262 +  multi_array(const const_multi_array_ref<T,NumDims>& rhs)
   1.263 +    : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape()) 
   1.264 +  {
   1.265 +    allocate_space();
   1.266 +    // Warning! storage order may change, hence the following copy technique.
   1.267 +    std::copy(rhs.begin(),rhs.end(),this->begin());
   1.268 +  }
   1.269 +
   1.270 +  multi_array(const const_multi_array_ref<T,NumDims>& rhs,
   1.271 +              const general_storage_order<NumDims>& so)
   1.272 +    : super_type(0,so,rhs.index_bases(),rhs.shape()) 
   1.273 +  {
   1.274 +    allocate_space();
   1.275 +    // Warning! storage order may change, hence the following copy technique.
   1.276 +    std::copy(rhs.begin(),rhs.end(),this->begin());
   1.277 +  }
   1.278 +
   1.279 +  multi_array(const detail::multi_array::
   1.280 +              const_sub_array<T,NumDims>& rhs)
   1.281 +    : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape()) 
   1.282 +  {
   1.283 +    allocate_space();
   1.284 +    std::copy(rhs.begin(),rhs.end(),this->begin());
   1.285 +  }
   1.286 +
   1.287 +  multi_array(const detail::multi_array::
   1.288 +              const_sub_array<T,NumDims>& rhs,
   1.289 +              const general_storage_order<NumDims>& so)
   1.290 +    : super_type(0,so,rhs.index_bases(),rhs.shape()) 
   1.291 +  {
   1.292 +    allocate_space();
   1.293 +    std::copy(rhs.begin(),rhs.end(),this->begin());
   1.294 +  }
   1.295 +
   1.296 +
   1.297 +  multi_array(const detail::multi_array::
   1.298 +              const_multi_array_view<T,NumDims>& rhs)
   1.299 +    : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape()) 
   1.300 +  {
   1.301 +    allocate_space();
   1.302 +    std::copy(rhs.begin(),rhs.end(),this->begin());
   1.303 +  }
   1.304 +
   1.305 +  multi_array(const detail::multi_array::
   1.306 +              const_multi_array_view<T,NumDims>& rhs,
   1.307 +              const general_storage_order<NumDims>& so)
   1.308 +    : super_type(0,so,rhs.index_bases(),rhs.shape()) 
   1.309 +  {
   1.310 +    allocate_space();
   1.311 +    std::copy(rhs.begin(),rhs.end(),this->begin());
   1.312 +  }
   1.313 +
   1.314 +#endif // !BOOST_NO_FUNCTION_TEMPLATE_ORDERING
   1.315 +
   1.316 +  // Thes constructors are necessary because of more exact template matches.
   1.317 +  multi_array(const multi_array_ref<T,NumDims>& rhs)
   1.318 +    : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape()) 
   1.319 +  {
   1.320 +    allocate_space();
   1.321 +    // Warning! storage order may change, hence the following copy technique.
   1.322 +    std::copy(rhs.begin(),rhs.end(),this->begin());
   1.323 +  }
   1.324 +
   1.325 +  multi_array(const multi_array_ref<T,NumDims>& rhs,
   1.326 +              const general_storage_order<NumDims>& so)
   1.327 +    : super_type(0,so,rhs.index_bases(),rhs.shape()) 
   1.328 +  {
   1.329 +    allocate_space();
   1.330 +    // Warning! storage order may change, hence the following copy technique.
   1.331 +    std::copy(rhs.begin(),rhs.end(),this->begin());
   1.332 +  }
   1.333 +
   1.334 +
   1.335 +  multi_array(const detail::multi_array::
   1.336 +              sub_array<T,NumDims>& rhs)
   1.337 +    : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape()) 
   1.338 +  {
   1.339 +    allocate_space();
   1.340 +    std::copy(rhs.begin(),rhs.end(),this->begin());
   1.341 +  }
   1.342 +
   1.343 +  multi_array(const detail::multi_array::
   1.344 +              sub_array<T,NumDims>& rhs,
   1.345 +              const general_storage_order<NumDims>& so)
   1.346 +    : super_type(0,so,rhs.index_bases(),rhs.shape()) 
   1.347 +  {
   1.348 +    allocate_space();
   1.349 +    std::copy(rhs.begin(),rhs.end(),this->begin());
   1.350 +  }
   1.351 +
   1.352 +
   1.353 +  multi_array(const detail::multi_array::
   1.354 +              multi_array_view<T,NumDims>& rhs)
   1.355 +    : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape()) 
   1.356 +  {
   1.357 +    allocate_space();
   1.358 +    std::copy(rhs.begin(),rhs.end(),this->begin());
   1.359 +  }
   1.360 +    
   1.361 +  multi_array(const detail::multi_array::
   1.362 +              multi_array_view<T,NumDims>& rhs,
   1.363 +              const general_storage_order<NumDims>& so)
   1.364 +    : super_type(0,so,rhs.index_bases(),rhs.shape()) 
   1.365 +  {
   1.366 +    allocate_space();
   1.367 +    std::copy(rhs.begin(),rhs.end(),this->begin());
   1.368 +  }
   1.369 +    
   1.370 +  // Since assignment is a deep copy, multi_array_ref
   1.371 +  // contains all the necessary code.
   1.372 +  template <typename ConstMultiArray>
   1.373 +  multi_array& operator=(const ConstMultiArray& other) {
   1.374 +    super_type::operator=(other);
   1.375 +    return *this;
   1.376 +  }
   1.377 +
   1.378 +  multi_array& operator=(const multi_array& other) {
   1.379 +    if (&other != this) {
   1.380 +      super_type::operator=(other);
   1.381 +    }
   1.382 +    return *this;
   1.383 +  }
   1.384 +
   1.385 +
   1.386 +  template <typename ExtentList>
   1.387 +  multi_array& resize(const ExtentList& extents) {
   1.388 +    boost::function_requires<
   1.389 +      detail::multi_array::CollectionConcept<ExtentList> >();
   1.390 +
   1.391 +    typedef detail::multi_array::extent_gen<NumDims> gen_type;
   1.392 +    gen_type ranges;
   1.393 +
   1.394 +    for (int i=0; i != NumDims; ++i) {
   1.395 +      typedef typename gen_type::range range_type;
   1.396 +      ranges.ranges_[i] = range_type(0,extents[i]);
   1.397 +    }
   1.398 +    
   1.399 +    return this->resize(ranges);
   1.400 +  }
   1.401 +
   1.402 +
   1.403 +
   1.404 +  multi_array& resize(const detail::multi_array
   1.405 +                      ::extent_gen<NumDims>& ranges) {
   1.406 +
   1.407 +
   1.408 +    // build a multi_array with the specs given
   1.409 +    multi_array new_array(ranges,this->storage_order());
   1.410 +
   1.411 +
   1.412 +    // build a view of tmp with the minimum extents
   1.413 +
   1.414 +    // Get the minimum extents of the arrays.
   1.415 +    boost::array<size_type,NumDims> min_extents;
   1.416 +
   1.417 +    const size_type& (*min)(const size_type&, const size_type&) =
   1.418 +      std::min;
   1.419 +    std::transform(new_array.extent_list_.begin(),new_array.extent_list_.end(),
   1.420 +                   this->extent_list_.begin(),
   1.421 +                   min_extents.begin(),
   1.422 +                   min);
   1.423 +
   1.424 +
   1.425 +    // typedef boost::array<index,NumDims> index_list;
   1.426 +    // Build index_gen objects to create views with the same shape
   1.427 +
   1.428 +    // these need to be separate to handle non-zero index bases
   1.429 +    typedef detail::multi_array::index_gen<NumDims,NumDims> index_gen;
   1.430 +    index_gen old_idxes;
   1.431 +    index_gen new_idxes;
   1.432 +
   1.433 +    std::transform(new_array.index_base_list_.begin(),
   1.434 +                   new_array.index_base_list_.end(),
   1.435 +                   min_extents.begin(),old_idxes.ranges_.begin(),
   1.436 +                   detail::multi_array::populate_index_ranges());
   1.437 +
   1.438 +    std::transform(this->index_base_list_.begin(),
   1.439 +                   this->index_base_list_.end(),
   1.440 +                   min_extents.begin(),new_idxes.ranges_.begin(),
   1.441 +                   detail::multi_array::populate_index_ranges());
   1.442 +
   1.443 +    // Build same-shape views of the two arrays
   1.444 +    typename
   1.445 +      multi_array::BOOST_NESTED_TEMPLATE array_view<NumDims>::type view_old = (*this)[old_idxes];
   1.446 +    typename
   1.447 +      multi_array::BOOST_NESTED_TEMPLATE array_view<NumDims>::type view_new = new_array[new_idxes];
   1.448 +
   1.449 +    // Set the right portion of the new array
   1.450 +    view_new = view_old;
   1.451 +
   1.452 +    using std::swap;
   1.453 +    // Swap the internals of these arrays.
   1.454 +    swap(this->super_type::base_,new_array.super_type::base_);
   1.455 +    swap(this->storage_,new_array.storage_);
   1.456 +    swap(this->extent_list_,new_array.extent_list_);
   1.457 +    swap(this->stride_list_,new_array.stride_list_);
   1.458 +    swap(this->index_base_list_,new_array.index_base_list_);
   1.459 +    swap(this->origin_offset_,new_array.origin_offset_);
   1.460 +    swap(this->directional_offset_,new_array.directional_offset_);
   1.461 +    swap(this->num_elements_,new_array.num_elements_);
   1.462 +    swap(this->allocator_,new_array.allocator_);
   1.463 +    swap(this->base_,new_array.base_);
   1.464 +    swap(this->allocated_elements_,new_array.allocated_elements_);
   1.465 +
   1.466 +    return *this;
   1.467 +  }
   1.468 +
   1.469 +
   1.470 +  ~multi_array() {
   1.471 +    deallocate_space();
   1.472 +  }
   1.473 +
   1.474 +private:
   1.475 +  void allocate_space() {
   1.476 +    typename Allocator::const_pointer no_hint=0;
   1.477 +    base_ = allocator_.allocate(this->num_elements(),no_hint);
   1.478 +    this->set_base_ptr(base_);
   1.479 +    allocated_elements_ = this->num_elements();
   1.480 +    std::uninitialized_fill_n(base_,allocated_elements_,T());
   1.481 +  }
   1.482 +
   1.483 +  void deallocate_space() {
   1.484 +    if(base_) {
   1.485 +      for(T* i = base_; i != base_+allocated_elements_; ++i)
   1.486 +        allocator_.destroy(i);
   1.487 +      allocator_.deallocate(base_,allocated_elements_);
   1.488 +    }
   1.489 +  }
   1.490 +
   1.491 +  typedef boost::array<size_type,NumDims> size_list;
   1.492 +  typedef boost::array<index,NumDims> index_list;
   1.493 +
   1.494 +  Allocator allocator_;
   1.495 +  T* base_;
   1.496 +  size_type allocated_elements_;
   1.497 +  enum {initial_base_ = 0};
   1.498 +};
   1.499 +
   1.500 +} // namespace boost
   1.501 +
   1.502 +#endif // BOOST_MULTI_ARRAY_RG071801_HPP