500 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			500 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
								 | 
							
								// 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(),new_idxes.ranges_.begin(),
							 | 
						||
| 
								 | 
							
								                   detail::multi_array::populate_index_ranges());
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    std::transform(this->index_base_list_.begin(),
							 | 
						||
| 
								 | 
							
								                   this->index_base_list_.end(),
							 | 
						||
| 
								 | 
							
								                   min_extents.begin(),old_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
							 |