--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/epoc32/include/stdapis/boost/multi_array.hpp Tue Mar 16 16:12:26 2010 +0000
@@ -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 <algorithm>
+#include <cstddef>
+#include <functional>
+#include <numeric>
+#include <vector>
+
+
+
+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 <typename T, std::size_t NumDims, typename TPtr>
+char is_multi_array_impl_help(const_multi_array_view<T,NumDims,TPtr>&);
+template <typename T, std::size_t NumDims, typename TPtr>
+char is_multi_array_impl_help(const_sub_array<T,NumDims,TPtr>&);
+template <typename T, std::size_t NumDims, typename TPtr>
+char is_multi_array_impl_help(const_multi_array_ref<T,NumDims,TPtr>&);
+
+char ( &is_multi_array_impl_help(...) )[2];
+
+template <class T>
+struct is_multi_array_impl
+{
+ static T x;
+ BOOST_STATIC_CONSTANT(bool, value = sizeof((is_multi_array_impl_help)(x)) == 1);
+
+ typedef mpl::bool_<value> type;
+};
+
+template <bool multi_array = false>
+struct disable_multi_array_impl_impl
+{
+ typedef int type;
+};
+
+template <>
+struct disable_multi_array_impl_impl<true>
+{
+ // forming a pointer to a reference triggers SFINAE
+ typedef int& type;
+};
+
+
+template <class T>
+struct disable_multi_array_impl :
+ disable_multi_array_impl_impl<is_multi_array_impl<T>::value>
+{ };
+
+
+template <>
+struct disable_multi_array_impl<int>
+{
+ typedef int type;
+};
+
+
+#endif
+
+ } //namespace multi_array
+ } // namespace detail
+
+template<typename T, std::size_t NumDims,
+ typename Allocator>
+class multi_array :
+ public multi_array_ref<T,NumDims>
+{
+ typedef multi_array_ref<T,NumDims> 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 <std::size_t NDims>
+ struct const_array_view {
+ typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
+ };
+
+ template <std::size_t NDims>
+ struct array_view {
+ typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
+ };
+
+ explicit multi_array() :
+ super_type((T*)initial_base_,c_storage_order(),
+ /*index_bases=*/0, /*extents=*/0) {
+ allocate_space();
+ }
+
+ template <class ExtentList>
+ explicit multi_array(
+ ExtentList const& extents
+#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+ , typename mpl::if_<
+ detail::multi_array::is_multi_array_impl<ExtentList>,
+ int&,int>::type* = 0
+#endif
+ ) :
+ super_type((T*)initial_base_,extents) {
+ boost::function_requires<
+ detail::multi_array::CollectionConcept<ExtentList> >();
+ allocate_space();
+ }
+
+
+ template <class ExtentList>
+ explicit multi_array(ExtentList const& extents,
+ const general_storage_order<NumDims>& so) :
+ super_type((T*)initial_base_,extents,so) {
+ boost::function_requires<
+ detail::multi_array::CollectionConcept<ExtentList> >();
+ allocate_space();
+ }
+
+ template <class ExtentList>
+ explicit multi_array(ExtentList const& extents,
+ const general_storage_order<NumDims>& so,
+ Allocator const& alloc) :
+ super_type((T*)initial_base_,extents,so), allocator_(alloc) {
+ boost::function_requires<
+ detail::multi_array::CollectionConcept<ExtentList> >();
+ allocate_space();
+ }
+
+
+ explicit multi_array(const detail::multi_array
+ ::extent_gen<NumDims>& ranges) :
+ super_type((T*)initial_base_,ranges) {
+
+ allocate_space();
+ }
+
+
+ explicit multi_array(const detail::multi_array
+ ::extent_gen<NumDims>& ranges,
+ const general_storage_order<NumDims>& so) :
+ super_type((T*)initial_base_,ranges,so) {
+
+ allocate_space();
+ }
+
+
+ explicit multi_array(const detail::multi_array
+ ::extent_gen<NumDims>& ranges,
+ const general_storage_order<NumDims>& 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 <typename OPtr>
+ multi_array(const const_multi_array_ref<T,NumDims,OPtr>& rhs,
+ const general_storage_order<NumDims>& 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 <typename OPtr>
+ multi_array(const detail::multi_array::
+ const_sub_array<T,NumDims,OPtr>& rhs,
+ const general_storage_order<NumDims>& so = c_storage_order())
+ : super_type(0,so,rhs.index_bases(),rhs.shape())
+ {
+ allocate_space();
+ std::copy(rhs.begin(),rhs.end(),this->begin());
+ }
+
+
+ template <typename OPtr>
+ multi_array(const detail::multi_array::
+ const_multi_array_view<T,NumDims,OPtr>& rhs,
+ const general_storage_order<NumDims>& 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<T,NumDims>& 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<T,NumDims>& rhs,
+ const general_storage_order<NumDims>& 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<T,NumDims>& 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<T,NumDims>& rhs,
+ const general_storage_order<NumDims>& 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<T,NumDims>& 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<T,NumDims>& rhs,
+ const general_storage_order<NumDims>& 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<T,NumDims>& 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<T,NumDims>& rhs,
+ const general_storage_order<NumDims>& 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<T,NumDims>& 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<T,NumDims>& rhs,
+ const general_storage_order<NumDims>& 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<T,NumDims>& 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<T,NumDims>& rhs,
+ const general_storage_order<NumDims>& 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 <typename ConstMultiArray>
+ 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 <typename ExtentList>
+ multi_array& resize(const ExtentList& extents) {
+ boost::function_requires<
+ detail::multi_array::CollectionConcept<ExtentList> >();
+
+ typedef detail::multi_array::extent_gen<NumDims> 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<NumDims>& 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<size_type,NumDims> 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,NumDims> 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<NumDims,NumDims> 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<NumDims>::type view_old = (*this)[old_idxes];
+ typename
+ multi_array::BOOST_NESTED_TEMPLATE array_view<NumDims>::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_type,NumDims> size_list;
+ typedef boost::array<index,NumDims> index_list;
+
+ Allocator allocator_;
+ T* base_;
+ size_type allocated_elements_;
+ enum {initial_base_ = 0};
+};
+
+} // namespace boost
+
+#endif // BOOST_MULTI_ARRAY_RG071801_HPP