diff -r 000000000000 -r e4d67989cc36 ossrv_pub/boost_apis/boost/multi_array.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ossrv_pub/boost_apis/boost/multi_array.hpp Tue Feb 02 02:01:42 2010 +0200 @@ -0,0 +1,499 @@ +// Copyright 2002 The Trustees of Indiana University. + +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// Boost.MultiArray Library +// Authors: Ronald Garcia +// Jeremy Siek +// Andrew Lumsdaine +// See http://www.boost.org/libs/multi_array for documentation. + +#ifndef BOOST_MULTI_ARRAY_RG071801_HPP +#define BOOST_MULTI_ARRAY_RG071801_HPP + +// +// multi_array.hpp - contains the multi_array class template +// declaration and definition +// + +#include "boost/multi_array/base.hpp" +#include "boost/multi_array/collection_concept.hpp" +#include "boost/multi_array/copy_array.hpp" +#include "boost/multi_array/iterator.hpp" +#include "boost/multi_array/subarray.hpp" +#include "boost/multi_array/multi_array_ref.hpp" +#include "boost/multi_array/algorithm.hpp" +#include "boost/array.hpp" +#include "boost/mpl/if.hpp" +#include "boost/type_traits.hpp" +#include +#include +#include +#include +#include + + + +namespace boost { + namespace detail { + namespace multi_array { + + struct populate_index_ranges { + multi_array_types::index_range + // RG: underscore on extent_ to stifle strange MSVC warning. + operator()(multi_array_types::index base, + multi_array_types::size_type extent_) { + return multi_array_types::index_range(base,base+extent_); + } + }; + +#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING +// +// Compilers that don't support partial ordering may need help to +// disambiguate multi_array's templated constructors. Even vc6/7 are +// capable of some limited SFINAE, so we take the most-general version +// out of the overload set with disable_multi_array_impl. +// +template +char is_multi_array_impl_help(const_multi_array_view&); +template +char is_multi_array_impl_help(const_sub_array&); +template +char is_multi_array_impl_help(const_multi_array_ref&); + +char ( &is_multi_array_impl_help(...) )[2]; + +template +struct is_multi_array_impl +{ + static T x; + BOOST_STATIC_CONSTANT(bool, value = sizeof((is_multi_array_impl_help)(x)) == 1); + + typedef mpl::bool_ type; +}; + +template +struct disable_multi_array_impl_impl +{ + typedef int type; +}; + +template <> +struct disable_multi_array_impl_impl +{ + // forming a pointer to a reference triggers SFINAE + typedef int& type; +}; + + +template +struct disable_multi_array_impl : + disable_multi_array_impl_impl::value> +{ }; + + +template <> +struct disable_multi_array_impl +{ + typedef int type; +}; + + +#endif + + } //namespace multi_array + } // namespace detail + +template +class multi_array : + public multi_array_ref +{ + typedef multi_array_ref super_type; +public: + typedef typename super_type::value_type value_type; + typedef typename super_type::reference reference; + typedef typename super_type::const_reference const_reference; + typedef typename super_type::iterator iterator; + typedef typename super_type::const_iterator const_iterator; + typedef typename super_type::reverse_iterator reverse_iterator; + typedef typename super_type::const_reverse_iterator const_reverse_iterator; + typedef typename super_type::element element; + typedef typename super_type::size_type size_type; + typedef typename super_type::difference_type difference_type; + typedef typename super_type::index index; + typedef typename super_type::extent_range extent_range; + + + template + struct const_array_view { + typedef boost::detail::multi_array::const_multi_array_view type; + }; + + template + struct array_view { + typedef boost::detail::multi_array::multi_array_view type; + }; + + explicit multi_array() : + super_type((T*)initial_base_,c_storage_order(), + /*index_bases=*/0, /*extents=*/0) { + allocate_space(); + } + + template + explicit multi_array( + ExtentList const& extents +#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + , typename mpl::if_< + detail::multi_array::is_multi_array_impl, + int&,int>::type* = 0 +#endif + ) : + super_type((T*)initial_base_,extents) { + boost::function_requires< + detail::multi_array::CollectionConcept >(); + allocate_space(); + } + + + template + explicit multi_array(ExtentList const& extents, + const general_storage_order& so) : + super_type((T*)initial_base_,extents,so) { + boost::function_requires< + detail::multi_array::CollectionConcept >(); + allocate_space(); + } + + template + explicit multi_array(ExtentList const& extents, + const general_storage_order& so, + Allocator const& alloc) : + super_type((T*)initial_base_,extents,so), allocator_(alloc) { + boost::function_requires< + detail::multi_array::CollectionConcept >(); + allocate_space(); + } + + + explicit multi_array(const detail::multi_array + ::extent_gen& ranges) : + super_type((T*)initial_base_,ranges) { + + allocate_space(); + } + + + explicit multi_array(const detail::multi_array + ::extent_gen& ranges, + const general_storage_order& so) : + super_type((T*)initial_base_,ranges,so) { + + allocate_space(); + } + + + explicit multi_array(const detail::multi_array + ::extent_gen& ranges, + const general_storage_order& so, + Allocator const& alloc) : + super_type((T*)initial_base_,ranges,so), allocator_(alloc) { + + allocate_space(); + } + + multi_array(const multi_array& rhs) : + super_type(rhs), allocator_(rhs.allocator_) { + allocate_space(); + boost::detail::multi_array::copy_n(rhs.base_,rhs.num_elements(),base_); + } + + + // + // A multi_array is constructible from any multi_array_ref, subarray, or + // array_view object. The following constructors ensure that. + // + + // Due to limited support for partial template ordering, + // MSVC 6&7 confuse the following with the most basic ExtentList + // constructor. +#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + template + multi_array(const const_multi_array_ref& rhs, + const general_storage_order& so = c_storage_order()) + : super_type(0,so,rhs.index_bases(),rhs.shape()) + { + allocate_space(); + // Warning! storage order may change, hence the following copy technique. + std::copy(rhs.begin(),rhs.end(),this->begin()); + } + + template + multi_array(const detail::multi_array:: + const_sub_array& rhs, + const general_storage_order& so = c_storage_order()) + : super_type(0,so,rhs.index_bases(),rhs.shape()) + { + allocate_space(); + std::copy(rhs.begin(),rhs.end(),this->begin()); + } + + + template + multi_array(const detail::multi_array:: + const_multi_array_view& rhs, + const general_storage_order& so = c_storage_order()) + : super_type(0,so,rhs.index_bases(),rhs.shape()) + { + allocate_space(); + std::copy(rhs.begin(),rhs.end(),this->begin()); + } + +#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING + // More limited support for MSVC + + + multi_array(const const_multi_array_ref& rhs) + : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape()) + { + allocate_space(); + // Warning! storage order may change, hence the following copy technique. + std::copy(rhs.begin(),rhs.end(),this->begin()); + } + + multi_array(const const_multi_array_ref& rhs, + const general_storage_order& so) + : super_type(0,so,rhs.index_bases(),rhs.shape()) + { + allocate_space(); + // Warning! storage order may change, hence the following copy technique. + std::copy(rhs.begin(),rhs.end(),this->begin()); + } + + multi_array(const detail::multi_array:: + const_sub_array& rhs) + : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape()) + { + allocate_space(); + std::copy(rhs.begin(),rhs.end(),this->begin()); + } + + multi_array(const detail::multi_array:: + const_sub_array& rhs, + const general_storage_order& so) + : super_type(0,so,rhs.index_bases(),rhs.shape()) + { + allocate_space(); + std::copy(rhs.begin(),rhs.end(),this->begin()); + } + + + multi_array(const detail::multi_array:: + const_multi_array_view& rhs) + : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape()) + { + allocate_space(); + std::copy(rhs.begin(),rhs.end(),this->begin()); + } + + multi_array(const detail::multi_array:: + const_multi_array_view& rhs, + const general_storage_order& so) + : super_type(0,so,rhs.index_bases(),rhs.shape()) + { + allocate_space(); + std::copy(rhs.begin(),rhs.end(),this->begin()); + } + +#endif // !BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + // Thes constructors are necessary because of more exact template matches. + multi_array(const multi_array_ref& rhs) + : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape()) + { + allocate_space(); + // Warning! storage order may change, hence the following copy technique. + std::copy(rhs.begin(),rhs.end(),this->begin()); + } + + multi_array(const multi_array_ref& rhs, + const general_storage_order& so) + : super_type(0,so,rhs.index_bases(),rhs.shape()) + { + allocate_space(); + // Warning! storage order may change, hence the following copy technique. + std::copy(rhs.begin(),rhs.end(),this->begin()); + } + + + multi_array(const detail::multi_array:: + sub_array& rhs) + : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape()) + { + allocate_space(); + std::copy(rhs.begin(),rhs.end(),this->begin()); + } + + multi_array(const detail::multi_array:: + sub_array& rhs, + const general_storage_order& so) + : super_type(0,so,rhs.index_bases(),rhs.shape()) + { + allocate_space(); + std::copy(rhs.begin(),rhs.end(),this->begin()); + } + + + multi_array(const detail::multi_array:: + multi_array_view& rhs) + : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape()) + { + allocate_space(); + std::copy(rhs.begin(),rhs.end(),this->begin()); + } + + multi_array(const detail::multi_array:: + multi_array_view& rhs, + const general_storage_order& so) + : super_type(0,so,rhs.index_bases(),rhs.shape()) + { + allocate_space(); + std::copy(rhs.begin(),rhs.end(),this->begin()); + } + + // Since assignment is a deep copy, multi_array_ref + // contains all the necessary code. + template + multi_array& operator=(const ConstMultiArray& other) { + super_type::operator=(other); + return *this; + } + + multi_array& operator=(const multi_array& other) { + if (&other != this) { + super_type::operator=(other); + } + return *this; + } + + + template + multi_array& resize(const ExtentList& extents) { + boost::function_requires< + detail::multi_array::CollectionConcept >(); + + typedef detail::multi_array::extent_gen gen_type; + gen_type ranges; + + for (int i=0; i != NumDims; ++i) { + typedef typename gen_type::range range_type; + ranges.ranges_[i] = range_type(0,extents[i]); + } + + return this->resize(ranges); + } + + + + multi_array& resize(const detail::multi_array + ::extent_gen& ranges) { + + + // build a multi_array with the specs given + multi_array new_array(ranges,this->storage_order()); + + + // build a view of tmp with the minimum extents + + // Get the minimum extents of the arrays. + boost::array min_extents; + + const size_type& (*min)(const size_type&, const size_type&) = + std::min; + std::transform(new_array.extent_list_.begin(),new_array.extent_list_.end(), + this->extent_list_.begin(), + min_extents.begin(), + min); + + + // typedef boost::array index_list; + // Build index_gen objects to create views with the same shape + + // these need to be separate to handle non-zero index bases + typedef detail::multi_array::index_gen index_gen; + index_gen old_idxes; + index_gen new_idxes; + + std::transform(new_array.index_base_list_.begin(), + new_array.index_base_list_.end(), + min_extents.begin(),old_idxes.ranges_.begin(), + detail::multi_array::populate_index_ranges()); + + std::transform(this->index_base_list_.begin(), + this->index_base_list_.end(), + min_extents.begin(),new_idxes.ranges_.begin(), + detail::multi_array::populate_index_ranges()); + + // Build same-shape views of the two arrays + typename + multi_array::BOOST_NESTED_TEMPLATE array_view::type view_old = (*this)[old_idxes]; + typename + multi_array::BOOST_NESTED_TEMPLATE array_view::type view_new = new_array[new_idxes]; + + // Set the right portion of the new array + view_new = view_old; + + using std::swap; + // Swap the internals of these arrays. + swap(this->super_type::base_,new_array.super_type::base_); + swap(this->storage_,new_array.storage_); + swap(this->extent_list_,new_array.extent_list_); + swap(this->stride_list_,new_array.stride_list_); + swap(this->index_base_list_,new_array.index_base_list_); + swap(this->origin_offset_,new_array.origin_offset_); + swap(this->directional_offset_,new_array.directional_offset_); + swap(this->num_elements_,new_array.num_elements_); + swap(this->allocator_,new_array.allocator_); + swap(this->base_,new_array.base_); + swap(this->allocated_elements_,new_array.allocated_elements_); + + return *this; + } + + + ~multi_array() { + deallocate_space(); + } + +private: + void allocate_space() { + typename Allocator::const_pointer no_hint=0; + base_ = allocator_.allocate(this->num_elements(),no_hint); + this->set_base_ptr(base_); + allocated_elements_ = this->num_elements(); + std::uninitialized_fill_n(base_,allocated_elements_,T()); + } + + void deallocate_space() { + if(base_) { + for(T* i = base_; i != base_+allocated_elements_; ++i) + allocator_.destroy(i); + allocator_.deallocate(base_,allocated_elements_); + } + } + + typedef boost::array size_list; + typedef boost::array index_list; + + Allocator allocator_; + T* base_; + size_type allocated_elements_; + enum {initial_base_ = 0}; +}; + +} // namespace boost + +#endif // BOOST_MULTI_ARRAY_RG071801_HPP