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