Squashed 'third_party/boostorg/multi_array/' content from commit abcb283
Change-Id: I4b93f75f0b15b00216d918bd6db5fc4fcb9c4cc2
git-subtree-dir: third_party/boostorg/multi_array
git-subtree-split: abcb2839d56669d1b5bb8a240ec644f47c66beb2
diff --git a/include/boost/multi_array/algorithm.hpp b/include/boost/multi_array/algorithm.hpp
new file mode 100644
index 0000000..c749c3f
--- /dev/null
+++ b/include/boost/multi_array/algorithm.hpp
@@ -0,0 +1,103 @@
+#ifndef BOOST_ALGORITHM_RG071801_HPP
+#define BOOST_ALGORITHM_RG071801_HPP
+
+//
+//
+// Copyright (c) 1994
+// Hewlett-Packard Company
+//
+// Permission to use, copy, modify, distribute and sell this software
+// and its documentation for any purpose is hereby granted without fee,
+// provided that the above copyright notice appear in all copies and
+// that both that copyright notice and this permission notice appear
+// in supporting documentation. Hewlett-Packard Company makes no
+// representations about the suitability of this software for any
+// purpose. It is provided "as is" without express or implied warranty.
+//
+//
+// Copyright (c) 1996-1998
+// Silicon Graphics Computer Systems, Inc.
+//
+// Permission to use, copy, modify, distribute and sell this software
+// and its documentation for any purpose is hereby granted without fee,
+// provided that the above copyright notice appear in all copies and
+// that both that copyright notice and this permission notice appear
+// in supporting documentation. Silicon Graphics makes no
+// representations about the suitability of this software for any
+// purpose. It is provided "as is" without express or implied warranty.
+//
+
+// 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.
+
+
+#include "boost/iterator.hpp"
+
+namespace boost {
+namespace detail {
+namespace multi_array {
+//--------------------------------------------------
+// copy_n (not part of the C++ standard)
+#if 1
+
+template <class InputIter, class Size, class OutputIter>
+OutputIter copy_n(InputIter first, Size count,
+ OutputIter result) {
+ for ( ; count > 0; --count) {
+ *result = *first;
+ ++first;
+ ++result;
+ }
+ return result;
+}
+#else // !1
+
+template <class InputIter, class Size, class OutputIter>
+OutputIter copy_n__(InputIter first, Size count,
+ OutputIter result,
+ std::input_iterator_tag) {
+ for ( ; count > 0; --count) {
+ *result = *first;
+ ++first;
+ ++result;
+ }
+ return result;
+}
+
+template <class RAIter, class Size, class OutputIter>
+inline OutputIter
+copy_n__(RAIter first, Size count,
+ OutputIter result,
+ std::random_access_iterator_tag) {
+ RAIter last = first + count;
+ return std::copy(first, last, result);
+}
+
+template <class InputIter, class Size, class OutputIter>
+inline OutputIter
+copy_n__(InputIter first, Size count, OutputIter result) {
+ typedef typename std::iterator_traits<InputIter>::iterator_category cat;
+ return copy_n__(first, count, result, cat());
+}
+
+template <class InputIter, class Size, class OutputIter>
+inline OutputIter
+copy_n(InputIter first, Size count, OutputIter result) {
+ return copy_n__(first, count, result);
+}
+
+#endif // 1
+} // namespace multi_array
+} // namespace detail
+} // namespace boost
+
+#endif // BOOST_ALGORITHM_RG071801_HPP
diff --git a/include/boost/multi_array/base.hpp b/include/boost/multi_array/base.hpp
new file mode 100644
index 0000000..62e5397
--- /dev/null
+++ b/include/boost/multi_array/base.hpp
@@ -0,0 +1,501 @@
+// 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 BASE_RG071801_HPP
+#define BASE_RG071801_HPP
+
+//
+// base.hpp - some implementation base classes for from which
+// functionality is acquired
+//
+
+#include "boost/multi_array/extent_range.hpp"
+#include "boost/multi_array/extent_gen.hpp"
+#include "boost/multi_array/index_range.hpp"
+#include "boost/multi_array/index_gen.hpp"
+#include "boost/multi_array/storage_order.hpp"
+#include "boost/multi_array/types.hpp"
+#include "boost/config.hpp"
+#include "boost/multi_array/concept_checks.hpp" //for ignore_unused_...
+#include "boost/mpl/eval_if.hpp"
+#include "boost/mpl/if.hpp"
+#include "boost/mpl/size_t.hpp"
+#include "boost/iterator/reverse_iterator.hpp"
+#include "boost/static_assert.hpp"
+#include "boost/type.hpp"
+#include "boost/assert.hpp"
+#include <cstddef>
+#include <memory>
+
+namespace boost {
+
+/////////////////////////////////////////////////////////////////////////
+// class declarations
+/////////////////////////////////////////////////////////////////////////
+
+template<typename T, std::size_t NumDims,
+ typename Allocator = std::allocator<T> >
+class multi_array;
+
+// This is a public interface for use by end users!
+namespace multi_array_types {
+ typedef boost::detail::multi_array::size_type size_type;
+ typedef std::ptrdiff_t difference_type;
+ typedef boost::detail::multi_array::index index;
+ typedef detail::multi_array::index_range<index,size_type> index_range;
+ typedef detail::multi_array::extent_range<index,size_type> extent_range;
+ typedef detail::multi_array::index_gen<0,0> index_gen;
+ typedef detail::multi_array::extent_gen<0> extent_gen;
+}
+
+
+// boost::extents and boost::indices are now a part of the public
+// interface. That way users don't necessarily have to create their
+// own objects. On the other hand, one may not want the overhead of
+// object creation in small-memory environments. Thus, the objects
+// can be left undefined by defining BOOST_MULTI_ARRAY_NO_GENERATORS
+// before loading multi_array.hpp.
+#ifndef BOOST_MULTI_ARRAY_NO_GENERATORS
+namespace {
+ multi_array_types::extent_gen extents;
+ multi_array_types::index_gen indices;
+}
+#endif // BOOST_MULTI_ARRAY_NO_GENERATORS
+
+namespace detail {
+namespace multi_array {
+
+template <typename T, std::size_t NumDims>
+class sub_array;
+
+template <typename T, std::size_t NumDims, typename TPtr = const T*>
+class const_sub_array;
+
+ template <typename T, typename TPtr, typename NumDims, typename Reference,
+ typename IteratorCategory>
+class array_iterator;
+
+template <typename T, std::size_t NumDims, typename TPtr = const T*>
+class const_multi_array_view;
+
+template <typename T, std::size_t NumDims>
+class multi_array_view;
+
+/////////////////////////////////////////////////////////////////////////
+// class interfaces
+/////////////////////////////////////////////////////////////////////////
+
+class multi_array_base {
+public:
+ typedef multi_array_types::size_type size_type;
+ typedef multi_array_types::difference_type difference_type;
+ typedef multi_array_types::index index;
+ typedef multi_array_types::index_range index_range;
+ typedef multi_array_types::extent_range extent_range;
+ typedef multi_array_types::index_gen index_gen;
+ typedef multi_array_types::extent_gen extent_gen;
+};
+
+//
+// value_accessor_n
+// contains the routines for accessing elements from
+// N-dimensional views.
+//
+template<typename T, std::size_t NumDims>
+class value_accessor_n : public multi_array_base {
+ typedef multi_array_base super_type;
+public:
+ typedef typename super_type::index index;
+
+ //
+ // public typedefs used by classes that inherit from this base
+ //
+ typedef T element;
+ typedef boost::multi_array<T,NumDims-1> value_type;
+ typedef sub_array<T,NumDims-1> reference;
+ typedef const_sub_array<T,NumDims-1> const_reference;
+
+protected:
+ // used by array operator[] and iterators to get reference types.
+ template <typename Reference, typename TPtr>
+ Reference access(boost::type<Reference>,index idx,TPtr base,
+ const size_type* extents,
+ const index* strides,
+ const index* index_bases) const {
+
+ BOOST_ASSERT(idx - index_bases[0] >= 0);
+ BOOST_ASSERT(size_type(idx - index_bases[0]) < extents[0]);
+ // return a sub_array<T,NDims-1> proxy object
+ TPtr newbase = base + idx * strides[0];
+ return Reference(newbase,extents+1,strides+1,index_bases+1);
+
+ }
+
+ value_accessor_n() { }
+ ~value_accessor_n() { }
+};
+
+
+
+//
+// value_accessor_one
+// contains the routines for accessing reference elements from
+// 1-dimensional views.
+//
+template<typename T>
+class value_accessor_one : public multi_array_base {
+ typedef multi_array_base super_type;
+public:
+ typedef typename super_type::index index;
+ //
+ // public typedefs for use by classes that inherit it.
+ //
+ typedef T element;
+ typedef T value_type;
+ typedef T& reference;
+ typedef T const& const_reference;
+
+protected:
+ // used by array operator[] and iterators to get reference types.
+ template <typename Reference, typename TPtr>
+ Reference access(boost::type<Reference>,index idx,TPtr base,
+ const size_type* extents,
+ const index* strides,
+ const index* index_bases) const {
+
+ ignore_unused_variable_warning(index_bases);
+ ignore_unused_variable_warning(extents);
+ BOOST_ASSERT(idx - index_bases[0] >= 0);
+ BOOST_ASSERT(size_type(idx - index_bases[0]) < extents[0]);
+ return *(base + idx * strides[0]);
+ }
+
+ value_accessor_one() { }
+ ~value_accessor_one() { }
+};
+
+
+/////////////////////////////////////////////////////////////////////////
+// choose value accessor begins
+//
+
+template <typename T, std::size_t NumDims>
+struct choose_value_accessor_n {
+ typedef value_accessor_n<T,NumDims> type;
+};
+
+template <typename T>
+struct choose_value_accessor_one {
+ typedef value_accessor_one<T> type;
+};
+
+template <typename T, typename NumDims>
+struct value_accessor_generator {
+ BOOST_STATIC_CONSTANT(std::size_t, dimensionality = NumDims::value);
+
+ typedef typename
+ mpl::eval_if_c<(dimensionality == 1),
+ choose_value_accessor_one<T>,
+ choose_value_accessor_n<T,dimensionality>
+ >::type type;
+};
+
+template <class T, class NumDims>
+struct associated_types
+ : value_accessor_generator<T,NumDims>::type
+{};
+
+//
+// choose value accessor ends
+/////////////////////////////////////////////////////////////////////////
+
+// Due to some imprecision in the C++ Standard,
+// MSVC 2010 is broken in debug mode: it requires
+// that an Output Iterator have output_iterator_tag in its iterator_category if
+// that iterator is not bidirectional_iterator or random_access_iterator.
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1600)
+struct mutable_iterator_tag
+ : boost::random_access_traversal_tag, std::input_iterator_tag
+{
+ operator std::output_iterator_tag() const {
+ return std::output_iterator_tag();
+ }
+};
+#endif
+
+////////////////////////////////////////////////////////////////////////
+// multi_array_base
+////////////////////////////////////////////////////////////////////////
+template <typename T, std::size_t NumDims>
+class multi_array_impl_base
+ :
+ public value_accessor_generator<T,mpl::size_t<NumDims> >::type
+{
+ typedef associated_types<T,mpl::size_t<NumDims> > types;
+public:
+ typedef typename types::index index;
+ typedef typename types::size_type size_type;
+ typedef typename types::element element;
+ typedef typename types::index_range index_range;
+ typedef typename types::value_type value_type;
+ typedef typename types::reference reference;
+ typedef typename types::const_reference const_reference;
+
+ template <std::size_t NDims>
+ struct subarray {
+ typedef boost::detail::multi_array::sub_array<T,NDims> type;
+ };
+
+ template <std::size_t NDims>
+ struct const_subarray {
+ typedef boost::detail::multi_array::const_sub_array<T,NDims> type;
+ };
+
+ template <std::size_t NDims>
+ struct array_view {
+ typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
+ };
+
+ template <std::size_t NDims>
+ struct const_array_view {
+ public:
+ typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
+ };
+
+ //
+ // iterator support
+ //
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1600)
+ // Deal with VC 2010 output_iterator_tag requirement
+ typedef array_iterator<T,T*,mpl::size_t<NumDims>,reference,
+ mutable_iterator_tag> iterator;
+#else
+ typedef array_iterator<T,T*,mpl::size_t<NumDims>,reference,
+ boost::random_access_traversal_tag> iterator;
+#endif
+ typedef array_iterator<T,T const*,mpl::size_t<NumDims>,const_reference,
+ boost::random_access_traversal_tag> const_iterator;
+
+ typedef ::boost::reverse_iterator<iterator> reverse_iterator;
+ typedef ::boost::reverse_iterator<const_iterator> const_reverse_iterator;
+
+ BOOST_STATIC_CONSTANT(std::size_t, dimensionality = NumDims);
+protected:
+
+ multi_array_impl_base() { }
+ ~multi_array_impl_base() { }
+
+ // Used by operator() in our array classes
+ template <typename Reference, typename IndexList, typename TPtr>
+ Reference access_element(boost::type<Reference>,
+ const IndexList& indices,
+ TPtr base,
+ const size_type* extents,
+ const index* strides,
+ const index* index_bases) const {
+ boost::function_requires<
+ CollectionConcept<IndexList> >();
+ ignore_unused_variable_warning(index_bases);
+ ignore_unused_variable_warning(extents);
+#if !defined(NDEBUG) && !defined(BOOST_DISABLE_ASSERTS)
+ for (size_type i = 0; i != NumDims; ++i) {
+ BOOST_ASSERT(indices[i] - index_bases[i] >= 0);
+ BOOST_ASSERT(size_type(indices[i] - index_bases[i]) < extents[i]);
+ }
+#endif
+
+ index offset = 0;
+ {
+ typename IndexList::const_iterator i = indices.begin();
+ size_type n = 0;
+ while (n != NumDims) {
+ offset += (*i) * strides[n];
+ ++n;
+ ++i;
+ }
+ }
+ return base[offset];
+ }
+
+ template <typename StrideList, typename ExtentList>
+ void compute_strides(StrideList& stride_list, ExtentList& extent_list,
+ const general_storage_order<NumDims>& storage)
+ {
+ // invariant: stride = the stride for dimension n
+ index stride = 1;
+ for (size_type n = 0; n != NumDims; ++n) {
+ index stride_sign = +1;
+
+ if (!storage.ascending(storage.ordering(n)))
+ stride_sign = -1;
+
+ // The stride for this dimension is the product of the
+ // lengths of the ranks minor to it.
+ stride_list[storage.ordering(n)] = stride * stride_sign;
+
+ stride *= extent_list[storage.ordering(n)];
+ }
+ }
+
+ // This calculates the offset to the array base pointer due to:
+ // 1. dimensions stored in descending order
+ // 2. non-zero dimension index bases
+ template <typename StrideList, typename ExtentList, typename BaseList>
+ index
+ calculate_origin_offset(const StrideList& stride_list,
+ const ExtentList& extent_list,
+ const general_storage_order<NumDims>& storage,
+ const BaseList& index_base_list)
+ {
+ return
+ calculate_descending_dimension_offset(stride_list,extent_list,
+ storage) +
+ calculate_indexing_offset(stride_list,index_base_list);
+ }
+
+ // This calculates the offset added to the base pointer that are
+ // caused by descending dimensions
+ template <typename StrideList, typename ExtentList>
+ index
+ calculate_descending_dimension_offset(const StrideList& stride_list,
+ const ExtentList& extent_list,
+ const general_storage_order<NumDims>& storage)
+ {
+ index offset = 0;
+ if (!storage.all_dims_ascending())
+ for (size_type n = 0; n != NumDims; ++n)
+ if (!storage.ascending(n))
+ offset -= (extent_list[n] - 1) * stride_list[n];
+
+ return offset;
+ }
+
+ // This is used to reindex array_views, which are no longer
+ // concerned about storage order (specifically, whether dimensions
+ // are ascending or descending) since the viewed array handled it.
+
+ template <typename StrideList, typename BaseList>
+ index
+ calculate_indexing_offset(const StrideList& stride_list,
+ const BaseList& index_base_list)
+ {
+ index offset = 0;
+ for (size_type n = 0; n != NumDims; ++n)
+ offset -= stride_list[n] * index_base_list[n];
+ return offset;
+ }
+
+ // Slicing using an index_gen.
+ // Note that populating an index_gen creates a type that encodes
+ // both the number of dimensions in the current Array (NumDims), and
+ // the Number of dimensions for the resulting view. This allows the
+ // compiler to fail if the dimensions aren't completely accounted
+ // for. For reasons unbeknownst to me, a BOOST_STATIC_ASSERT
+ // within the member function template does not work. I should add a
+ // note to the documentation specifying that you get a damn ugly
+ // error message if you screw up in your slicing code.
+ template <typename ArrayRef, int NDims, typename TPtr>
+ ArrayRef
+ generate_array_view(boost::type<ArrayRef>,
+ const boost::detail::multi_array::
+ index_gen<NumDims,NDims>& indices,
+ const size_type* extents,
+ const index* strides,
+ const index* index_bases,
+ TPtr base) const {
+
+ boost::array<index,NDims> new_strides;
+ boost::array<index,NDims> new_extents;
+
+ index offset = 0;
+ size_type dim = 0;
+ for (size_type n = 0; n != NumDims; ++n) {
+
+ // Use array specs and input specs to produce real specs.
+ const index default_start = index_bases[n];
+ const index default_finish = default_start+extents[n];
+ const index_range& current_range = indices.ranges_[n];
+ index start = current_range.get_start(default_start);
+ index finish = current_range.get_finish(default_finish);
+ index stride = current_range.stride();
+ BOOST_ASSERT(stride != 0);
+
+ // An index range indicates a half-open strided interval
+ // [start,finish) (with stride) which faces upward when stride
+ // is positive and downward when stride is negative,
+
+ // RG: The following code for calculating length suffers from
+ // some representation issues: if finish-start cannot be represented as
+ // by type index, then overflow may result.
+
+ index len;
+ if ((finish - start) / stride < 0) {
+ // [start,finish) is empty according to the direction imposed by
+ // the stride.
+ len = 0;
+ } else {
+ // integral trick for ceiling((finish-start) / stride)
+ // taking into account signs.
+ index shrinkage = stride > 0 ? 1 : -1;
+ len = (finish - start + (stride - shrinkage)) / stride;
+ }
+
+ // start marks the closed side of the range, so it must lie
+ // exactly in the set of legal indices
+ // with a special case for empty arrays
+ BOOST_ASSERT(index_bases[n] <= start &&
+ ((start <= index_bases[n]+index(extents[n])) ||
+ (start == index_bases[n] && extents[n] == 0)));
+
+#ifndef BOOST_DISABLE_ASSERTS
+ // finish marks the open side of the range, so it can go one past
+ // the "far side" of the range (the top if stride is positive, the bottom
+ // if stride is negative).
+ index bound_adjustment = stride < 0 ? 1 : 0;
+ BOOST_ASSERT(((index_bases[n] - bound_adjustment) <= finish) &&
+ (finish <= (index_bases[n] + index(extents[n]) - bound_adjustment)));
+ ignore_unused_variable_warning(bound_adjustment);
+#endif // BOOST_DISABLE_ASSERTS
+
+
+ // the array data pointer is modified to account for non-zero
+ // bases during slicing (see [Garcia] for the math involved)
+ offset += start * strides[n];
+
+ if (!current_range.is_degenerate()) {
+
+ // The stride for each dimension is included into the
+ // strides for the array_view (see [Garcia] for the math involved).
+ new_strides[dim] = stride * strides[n];
+
+ // calculate new extents
+ new_extents[dim] = len;
+ ++dim;
+ }
+ }
+ BOOST_ASSERT(dim == NDims);
+
+ return
+ ArrayRef(base+offset,
+ new_extents,
+ new_strides);
+ }
+
+
+};
+
+} // namespace multi_array
+} // namespace detail
+
+} // namespace boost
+
+#endif // BASE_RG071801_HPP
diff --git a/include/boost/multi_array/collection_concept.hpp b/include/boost/multi_array/collection_concept.hpp
new file mode 100644
index 0000000..c2cd403
--- /dev/null
+++ b/include/boost/multi_array/collection_concept.hpp
@@ -0,0 +1,26 @@
+// 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 COLLECTION_CONCEPT_RG103101_HPP
+#define COLLECTION_CONCEPT_RG103101_HPP
+
+#include "boost/concept_check.hpp"
+
+namespace boost {
+namespace detail {
+namespace multi_array { // Old location for this
+ using boost::CollectionConcept;
+}
+}
+
+}
+#endif // COLLECTION_CONCEPT_RG103101_HPP
diff --git a/include/boost/multi_array/concept_checks.hpp b/include/boost/multi_array/concept_checks.hpp
new file mode 100644
index 0000000..9f70ae1
--- /dev/null
+++ b/include/boost/multi_array/concept_checks.hpp
@@ -0,0 +1,221 @@
+// 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_CONCEPT_CHECKS_RG110101_HPP
+#define BOOST_MULTI_ARRAY_CONCEPT_CHECKS_RG110101_HPP
+
+//
+// concept-checks.hpp - Checks out Const MultiArray and MultiArray
+// concepts
+//
+
+#include "boost/concept_check.hpp"
+#include "boost/iterator/iterator_concepts.hpp"
+
+namespace boost {
+namespace multi_array_concepts {
+
+namespace detail {
+ //
+ // idgen_helper -
+ // This is a helper for generating index_gen instantiations with
+ // the right type in order to test the call to
+ // operator[](index_gen). Since one would normally write:
+ // A[ indices[range1][range2] ]; // or
+ // B[ indices[index1][index2][range1] ];
+ // idgen helper allows us to generate the "indices" type by
+ // creating it through recursive calls.
+ template <std::size_t N>
+ struct idgen_helper {
+
+ template <typename Array, typename IdxGen, typename Call_Type>
+ static void call(Array& a, const IdxGen& idgen, Call_Type c) {
+ idgen_helper<N-1>::call(a,idgen[c],c);
+ }
+ };
+
+ template <>
+ struct idgen_helper<0> {
+
+ template <typename Array, typename IdxGen, typename Call_Type>
+ static void call(Array& a, const IdxGen& idgen, Call_Type) {
+ a[ idgen ];
+ }
+ };
+
+} // namespace detail
+
+
+ template <typename Array, std::size_t NumDims >
+ struct ConstMultiArrayConcept
+ {
+ void constraints() {
+ // function_requires< CopyConstructibleConcept<Array> >();
+ function_requires< boost_concepts::ForwardTraversalConcept<iterator> >();
+ function_requires< boost_concepts::ReadableIteratorConcept<iterator> >();
+ function_requires< boost_concepts::ForwardTraversalConcept<const_iterator> >();
+ function_requires< boost_concepts::ReadableIteratorConcept<const_iterator> >();
+
+ // RG - a( CollectionArchetype) when available...
+ a[ id ];
+ // Test slicing, keeping only the first dimension, losing the rest
+ detail::idgen_helper<NumDims-1>::call(a,idgen[range],id);
+
+ // Test slicing, keeping all dimensions.
+ detail::idgen_helper<NumDims-1>::call(a,idgen[range],range);
+
+ st = a.size();
+ st = a.num_dimensions();
+ st = Array::dimensionality;
+ st = a.num_elements();
+ stp = a.shape();
+ idp = a.strides();
+ idp = a.index_bases();
+ cit = a.begin();
+ cit = a.end();
+ crit = a.rbegin();
+ crit = a.rend();
+ eltp = a.origin();
+ }
+
+ typedef typename Array::value_type value_type;
+ typedef typename Array::reference reference;
+ typedef typename Array::const_reference const_reference;
+ typedef typename Array::size_type size_type;
+ typedef typename Array::difference_type difference_type;
+ typedef typename Array::iterator iterator;
+ typedef typename Array::const_iterator const_iterator;
+ typedef typename Array::reverse_iterator reverse_iterator;
+ typedef typename Array::const_reverse_iterator const_reverse_iterator;
+ typedef typename Array::element element;
+ typedef typename Array::index index;
+ typedef typename Array::index_gen index_gen;
+ typedef typename Array::index_range index_range;
+ typedef typename Array::extent_gen extent_gen;
+ typedef typename Array::extent_range extent_range;
+
+ Array a;
+ size_type st;
+ const size_type* stp;
+ index id;
+ const index* idp;
+ const_iterator cit;
+ const_reverse_iterator crit;
+ const element* eltp;
+ index_gen idgen;
+ index_range range;
+ };
+
+
+ template <typename Array, std::size_t NumDims >
+ struct MutableMultiArrayConcept
+ {
+ void constraints() {
+ // function_requires< CopyConstructibleConcept<Array> >();
+
+ function_requires< boost_concepts::ForwardTraversalConcept<iterator> >();
+ function_requires< boost_concepts::ReadableIteratorConcept<iterator> >();
+ function_requires< boost_concepts::WritableIteratorConcept<iterator> >();
+ function_requires< boost_concepts::ForwardTraversalConcept<const_iterator> >();
+ function_requires< boost_concepts::ReadableIteratorConcept<const_iterator> >();
+ function_requires< boost::OutputIterator<iterator,value_type> >();
+
+ // RG - a( CollectionArchetype) when available...
+ value_type vt = a[ id ];
+
+ // Test slicing, keeping only the first dimension, losing the rest
+ detail::idgen_helper<NumDims-1>::call(a,idgen[range],id);
+
+ // Test slicing, keeping all dimensions.
+ detail::idgen_helper<NumDims-1>::call(a,idgen[range],range);
+
+ st = a.size();
+ st = a.num_dimensions();
+ st = a.num_elements();
+ stp = a.shape();
+ idp = a.strides();
+ idp = a.index_bases();
+ it = a.begin();
+ it = a.end();
+ rit = a.rbegin();
+ rit = a.rend();
+ eltp = a.origin();
+ const_constraints(a);
+ }
+
+ void const_constraints(const Array& a) {
+
+ // value_type vt = a[ id ];
+
+ // Test slicing, keeping only the first dimension, losing the rest
+ detail::idgen_helper<NumDims-1>::call(a,idgen[range],id);
+
+ // Test slicing, keeping all dimensions.
+ detail::idgen_helper<NumDims-1>::call(a,idgen[range],range);
+
+ st = a.size();
+ st = a.num_dimensions();
+ st = a.num_elements();
+ stp = a.shape();
+ idp = a.strides();
+ idp = a.index_bases();
+ cit = a.begin();
+ cit = a.end();
+ crit = a.rbegin();
+ crit = a.rend();
+ eltp = a.origin();
+ }
+
+ typedef typename Array::value_type value_type;
+ typedef typename Array::reference reference;
+ typedef typename Array::const_reference const_reference;
+ typedef typename Array::size_type size_type;
+ typedef typename Array::difference_type difference_type;
+ typedef typename Array::iterator iterator;
+ typedef typename Array::const_iterator const_iterator;
+ typedef typename Array::reverse_iterator reverse_iterator;
+ typedef typename Array::const_reverse_iterator const_reverse_iterator;
+ typedef typename Array::element element;
+ typedef typename Array::index index;
+ typedef typename Array::index_gen index_gen;
+ typedef typename Array::index_range index_range;
+ typedef typename Array::extent_gen extent_gen;
+ typedef typename Array::extent_range extent_range;
+
+ Array a;
+ size_type st;
+ const size_type* stp;
+ index id;
+ const index* idp;
+ iterator it;
+ const_iterator cit;
+ reverse_iterator rit;
+ const_reverse_iterator crit;
+ const element* eltp;
+ index_gen idgen;
+ index_range range;
+ };
+
+
+} // namespace multi_array
+
+namespace detail {
+ namespace multi_array { // Old locations for these
+ using boost::multi_array_concepts::ConstMultiArrayConcept;
+ using boost::multi_array_concepts::MutableMultiArrayConcept;
+ }
+}
+
+} // namespace boost
+
+
+#endif // BOOST_MULTI_ARRAY_CONCEPT_CHECKS_RG110101_HPP
diff --git a/include/boost/multi_array/copy_array.hpp b/include/boost/multi_array/copy_array.hpp
new file mode 100644
index 0000000..f358b2b
--- /dev/null
+++ b/include/boost/multi_array/copy_array.hpp
@@ -0,0 +1,68 @@
+// 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 COPY_ARRAY_RG092101_HPP
+#define COPY_ARRAY_RG092101_HPP
+
+//
+// copy_array.hpp - generic code for copying the contents of one
+// Basic_MultiArray to another. We assume that they are of the same
+// shape
+//
+#include "boost/type.hpp"
+#include "boost/assert.hpp"
+
+namespace boost {
+namespace detail {
+namespace multi_array {
+
+template <typename Element>
+class copy_dispatch {
+public:
+ template <typename SourceIterator, typename DestIterator>
+ static void copy_array (SourceIterator first, SourceIterator last,
+ DestIterator result) {
+ while (first != last) {
+ copy_array(*first++,*result++);
+ }
+ }
+private:
+ // Array2 has to be passed by VALUE here because subarray
+ // pseudo-references are temporaries created by iterator::operator*()
+ template <typename Array1, typename Array2>
+ static void copy_array (const Array1& source, Array2 dest) {
+ copy_array(source.begin(),source.end(),dest.begin());
+ }
+
+ static void copy_array (const Element& source, Element& dest) {
+ dest = source;
+ }
+
+};
+
+
+template <typename Array1, typename Array2>
+void copy_array (Array1& source, Array2& dest) {
+ BOOST_ASSERT(std::equal(source.shape(),source.shape()+source.num_dimensions(),
+ dest.shape()));
+ // Dispatch to the proper function
+ typedef typename Array1::element element_type;
+ copy_dispatch<element_type>::
+ copy_array(source.begin(),source.end(),dest.begin());
+}
+
+
+} // namespace multi_array
+} // namespace detail
+} // namespace boost
+
+#endif // COPY_ARRAY_RG092101_HPP
diff --git a/include/boost/multi_array/extent_gen.hpp b/include/boost/multi_array/extent_gen.hpp
new file mode 100644
index 0000000..b009f66
--- /dev/null
+++ b/include/boost/multi_array/extent_gen.hpp
@@ -0,0 +1,75 @@
+// 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_EXTENT_GEN_RG071801_HPP
+#define BOOST_EXTENT_GEN_RG071801_HPP
+
+#include "boost/multi_array/extent_range.hpp"
+#include "boost/multi_array/range_list.hpp"
+#include "boost/multi_array/types.hpp"
+#include "boost/array.hpp"
+#include <algorithm>
+
+namespace boost {
+namespace detail {
+namespace multi_array {
+
+
+template <std::size_t NumRanges>
+class extent_gen {
+public:
+ typedef boost::detail::multi_array::index index;
+ typedef boost::detail::multi_array::size_type size_type;
+ typedef extent_range<index,size_type> range;
+private:
+ typedef typename range_list_generator<range,NumRanges>::type range_list;
+public:
+ template <std::size_t Ranges>
+ struct gen_type {
+ typedef extent_gen<Ranges> type;
+ };
+
+ range_list ranges_;
+
+ extent_gen() { }
+
+ // Used by operator[] to expand extent_gens
+ extent_gen(const extent_gen<NumRanges-1>& rhs,
+ const range& a_range)
+ {
+ std::copy(rhs.ranges_.begin(),rhs.ranges_.end(),ranges_.begin());
+ *ranges_.rbegin() = a_range;
+ }
+
+ extent_gen<NumRanges+1>
+ operator[](const range& a_range)
+ {
+ return extent_gen<NumRanges+1>(*this,a_range);
+ }
+
+ extent_gen<NumRanges+1>
+ operator[](index idx)
+ {
+ return extent_gen<NumRanges+1>(*this,range(0,idx));
+ }
+
+ static extent_gen<0> extents() {
+ return extent_gen<0>();
+ }
+};
+
+} // namespace multi_array
+} // namespace detail
+} // namespace boost
+
+
+#endif // BOOST_EXTENT_GEN_RG071801_HPP
diff --git a/include/boost/multi_array/extent_range.hpp b/include/boost/multi_array/extent_range.hpp
new file mode 100644
index 0000000..d7a2eaf
--- /dev/null
+++ b/include/boost/multi_array/extent_range.hpp
@@ -0,0 +1,49 @@
+// 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_EXTENT_RANGE_RG071801_HPP
+#define BOOST_EXTENT_RANGE_RG071801_HPP
+
+#include <utility>
+
+namespace boost {
+namespace detail {
+namespace multi_array {
+
+template <typename Extent, typename SizeType>
+class extent_range : private std::pair<Extent,Extent> {
+ typedef std::pair<Extent,Extent> super_type;
+public:
+ typedef Extent index;
+ typedef SizeType size_type;
+
+ extent_range(index start, index finish) :
+ super_type(start,finish) { }
+
+ extent_range(index finish) :
+ super_type(0,finish) { }
+
+ extent_range() : super_type(0,0) { }
+
+ index start() const { return super_type::first; }
+
+ index finish() const { return super_type::second; }
+
+ size_type size() const { return super_type::second - super_type::first; }
+};
+
+} // namespace multi_array
+} // namespace detail
+} // namespace boost
+
+
+#endif // BOOST_EXTENT_RANGE_RG071801_HPP
diff --git a/include/boost/multi_array/index_gen.hpp b/include/boost/multi_array/index_gen.hpp
new file mode 100644
index 0000000..da8e1fd
--- /dev/null
+++ b/include/boost/multi_array/index_gen.hpp
@@ -0,0 +1,81 @@
+// 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_INDEX_GEN_RG071801_HPP
+#define BOOST_INDEX_GEN_RG071801_HPP
+
+#include "boost/array.hpp"
+#include "boost/multi_array/index_range.hpp"
+#include "boost/multi_array/range_list.hpp"
+#include "boost/multi_array/types.hpp"
+#include <algorithm>
+#include <cstddef>
+
+namespace boost {
+namespace detail {
+namespace multi_array {
+
+
+template <int NumRanges, int NumDims>
+struct index_gen {
+private:
+ typedef ::boost::detail::multi_array::index index;
+ typedef ::boost::detail::multi_array::size_type size_type;
+ typedef index_range<index,size_type> range;
+public:
+ template <int Dims, int Ranges>
+ struct gen_type {
+ typedef index_gen<Ranges,Dims> type;
+ };
+
+ typedef typename range_list_generator<range,NumRanges>::type range_list;
+ range_list ranges_;
+
+ index_gen() { }
+
+ template <int ND>
+ explicit index_gen(const index_gen<NumRanges-1,ND>& rhs,
+ const range& r)
+ {
+ std::copy(rhs.ranges_.begin(),rhs.ranges_.end(),ranges_.begin());
+ *ranges_.rbegin() = r;
+ }
+
+ index_gen<NumRanges+1,NumDims+1>
+ operator[](const range& r) const
+ {
+ index_gen<NumRanges+1,NumDims+1> tmp;
+ std::copy(ranges_.begin(),ranges_.end(),tmp.ranges_.begin());
+ *tmp.ranges_.rbegin() = r;
+ return tmp;
+ }
+
+ index_gen<NumRanges+1,NumDims>
+ operator[](index idx) const
+ {
+ index_gen<NumRanges+1,NumDims> tmp;
+ std::copy(ranges_.begin(),ranges_.end(),tmp.ranges_.begin());
+ *tmp.ranges_.rbegin() = range(idx);
+ return tmp;
+ }
+
+ static index_gen<0,0> indices() {
+ return index_gen<0,0>();
+ }
+};
+
+} // namespace multi_array
+} // namespace detail
+} // namespace boost
+
+
+#endif // BOOST_INDEX_GEN_RG071801_HPP
diff --git a/include/boost/multi_array/index_range.hpp b/include/boost/multi_array/index_range.hpp
new file mode 100644
index 0000000..3d6035e
--- /dev/null
+++ b/include/boost/multi_array/index_range.hpp
@@ -0,0 +1,188 @@
+// 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_INDEX_RANGE_RG071801_HPP
+#define BOOST_INDEX_RANGE_RG071801_HPP
+
+#include <boost/config.hpp>
+#include <utility>
+#include <boost/limits.hpp>
+
+// For representing intervals, also with stride.
+// A degenerate range is a range with one element.
+
+// Thanks to Doug Gregor for the really cool idea of using the
+// comparison operators to express various interval types!
+
+// Internally, we represent the interval as half-open.
+
+namespace boost {
+namespace detail {
+namespace multi_array {
+
+ template <typename Index,typename SizeType>
+ class index_range {
+ public:
+ typedef Index index;
+ typedef SizeType size_type;
+
+ private:
+ static index from_start()
+ { return (std::numeric_limits<index>::min)(); }
+
+ static index to_end()
+ { return (std::numeric_limits<index>::max)(); }
+
+ public:
+
+ index_range()
+ {
+ start_ = from_start();
+ finish_ = to_end();
+ stride_ = 1;
+ degenerate_ = false;
+ }
+
+ explicit index_range(index pos)
+ {
+ start_ = pos;
+ finish_ = pos+1;
+ stride_ = 1;
+ degenerate_ = true;
+ }
+
+ explicit index_range(index start, index finish, index stride=1)
+ : start_(start), finish_(finish), stride_(stride),
+ degenerate_(false)
+ { }
+
+
+ // These are for chaining assignments to an index_range
+ index_range& start(index s) {
+ start_ = s;
+ degenerate_ = false;
+ return *this;
+ }
+
+ index_range& finish(index f) {
+ finish_ = f;
+ degenerate_ = false;
+ return *this;
+ }
+
+ index_range& stride(index s) { stride_ = s; return *this; }
+
+ index start() const
+ {
+ return start_;
+ }
+
+ index get_start(index low_index_range = index_range::from_start()) const
+ {
+ if (start_ == from_start())
+ return low_index_range;
+ return start_;
+ }
+
+ index finish() const
+ {
+ return finish_;
+ }
+
+ index get_finish(index high_index_range = index_range::to_end()) const
+ {
+ if (finish_ == to_end())
+ return high_index_range;
+ return finish_;
+ }
+
+ index stride() const { return stride_; }
+
+ void set_index_range(index start, index finish, index stride=1)
+ {
+ start_ = start;
+ finish_ = finish;
+ stride_ = stride;
+ }
+
+ static index_range all()
+ { return index_range(from_start(), to_end(), 1); }
+
+ bool is_degenerate() const { return degenerate_; }
+
+ index_range operator-(index shift) const
+ {
+ return index_range(start_ - shift, finish_ - shift, stride_);
+ }
+
+ index_range operator+(index shift) const
+ {
+ return index_range(start_ + shift, finish_ + shift, stride_);
+ }
+
+ index operator[](unsigned i) const
+ {
+ return start_ + i * stride_;
+ }
+
+ index operator()(unsigned i) const
+ {
+ return start_ + i * stride_;
+ }
+
+ // add conversion to std::slice?
+
+ public:
+ index start_, finish_, stride_;
+ bool degenerate_;
+ };
+
+ // Express open and closed interval end-points using the comparison
+ // operators.
+
+ // left closed
+ template <typename Index, typename SizeType>
+ inline index_range<Index,SizeType>
+ operator<=(Index s, const index_range<Index,SizeType>& r)
+ {
+ return index_range<Index,SizeType>(s, r.finish(), r.stride());
+ }
+
+ // left open
+ template <typename Index, typename SizeType>
+ inline index_range<Index,SizeType>
+ operator<(Index s, const index_range<Index,SizeType>& r)
+ {
+ return index_range<Index,SizeType>(s + 1, r.finish(), r.stride());
+ }
+
+ // right open
+ template <typename Index, typename SizeType>
+ inline index_range<Index,SizeType>
+ operator<(const index_range<Index,SizeType>& r, Index f)
+ {
+ return index_range<Index,SizeType>(r.start(), f, r.stride());
+ }
+
+ // right closed
+ template <typename Index, typename SizeType>
+ inline index_range<Index,SizeType>
+ operator<=(const index_range<Index,SizeType>& r, Index f)
+ {
+ return index_range<Index,SizeType>(r.start(), f + 1, r.stride());
+ }
+
+} // namespace multi_array
+} // namespace detail
+} // namespace boost
+
+#endif // BOOST_INDEX_RANGE_RG071801_HPP
diff --git a/include/boost/multi_array/iterator.hpp b/include/boost/multi_array/iterator.hpp
new file mode 100644
index 0000000..5cde330
--- /dev/null
+++ b/include/boost/multi_array/iterator.hpp
@@ -0,0 +1,165 @@
+// 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 ITERATOR_RG071801_HPP
+#define ITERATOR_RG071801_HPP
+
+//
+// iterator.hpp - implementation of iterators for the
+// multi-dimensional array class
+//
+
+#include "boost/multi_array/base.hpp"
+#include "boost/iterator/iterator_facade.hpp"
+#include <algorithm>
+#include <cstddef>
+#include <iterator>
+
+namespace boost {
+namespace detail {
+namespace multi_array {
+
+/////////////////////////////////////////////////////////////////////////
+// iterator components
+/////////////////////////////////////////////////////////////////////////
+
+template <class T>
+struct operator_arrow_proxy
+{
+ operator_arrow_proxy(T const& px) : value_(px) {}
+ T* operator->() const { return &value_; }
+ // This function is needed for MWCW and BCC, which won't call operator->
+ // again automatically per 13.3.1.2 para 8
+ operator T*() const { return &value_; }
+ mutable T value_;
+};
+
+template <typename T, typename TPtr, typename NumDims, typename Reference,
+ typename IteratorCategory>
+class array_iterator;
+
+template <typename T, typename TPtr, typename NumDims, typename Reference,
+ typename IteratorCategory>
+class array_iterator
+ : public
+ iterator_facade<
+ array_iterator<T,TPtr,NumDims,Reference,IteratorCategory>
+ , typename associated_types<T,NumDims>::value_type
+ , IteratorCategory
+ , Reference
+ >
+ , private
+ value_accessor_generator<T,NumDims>::type
+{
+ friend class ::boost::iterator_core_access;
+ typedef detail::multi_array::associated_types<T,NumDims> access_t;
+
+ typedef iterator_facade<
+ array_iterator<T,TPtr,NumDims,Reference,IteratorCategory>
+ , typename detail::multi_array::associated_types<T,NumDims>::value_type
+ , boost::random_access_traversal_tag
+ , Reference
+ > facade_type;
+
+ typedef typename access_t::index index;
+ typedef typename access_t::size_type size_type;
+
+#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
+ template <typename, typename, typename, typename, typename>
+ friend class array_iterator;
+#else
+ public:
+#endif
+
+ index idx_;
+ TPtr base_;
+ const size_type* extents_;
+ const index* strides_;
+ const index* index_base_;
+
+public:
+ // Typedefs to circumvent ambiguities between parent classes
+ typedef typename facade_type::reference reference;
+ typedef typename facade_type::value_type value_type;
+ typedef typename facade_type::difference_type difference_type;
+
+ array_iterator() {}
+
+ array_iterator(index idx, TPtr base, const size_type* extents,
+ const index* strides,
+ const index* index_base) :
+ idx_(idx), base_(base), extents_(extents),
+ strides_(strides), index_base_(index_base) { }
+
+ template <typename OPtr, typename ORef, typename Cat>
+ array_iterator(
+ const array_iterator<T,OPtr,NumDims,ORef,Cat>& rhs
+ , typename boost::enable_if_convertible<OPtr,TPtr>::type* = 0
+ )
+ : idx_(rhs.idx_), base_(rhs.base_), extents_(rhs.extents_),
+ strides_(rhs.strides_), index_base_(rhs.index_base_) { }
+
+
+ // RG - we make our own operator->
+ operator_arrow_proxy<reference>
+ operator->() const
+ {
+ return operator_arrow_proxy<reference>(this->dereference());
+ }
+
+
+ reference dereference() const
+ {
+ typedef typename value_accessor_generator<T,NumDims>::type accessor;
+ return accessor::access(boost::type<reference>(),
+ idx_,
+ base_,
+ extents_,
+ strides_,
+ index_base_);
+ }
+
+ void increment() { ++idx_; }
+ void decrement() { --idx_; }
+
+ template <class IteratorAdaptor>
+ bool equal(IteratorAdaptor& rhs) const {
+ const std::size_t N = NumDims::value;
+ return (idx_ == rhs.idx_) &&
+ (base_ == rhs.base_) &&
+ ( (extents_ == rhs.extents_) ||
+ std::equal(extents_,extents_+N,rhs.extents_) ) &&
+ ( (strides_ == rhs.strides_) ||
+ std::equal(strides_,strides_+N,rhs.strides_) ) &&
+ ( (index_base_ == rhs.index_base_) ||
+ std::equal(index_base_,index_base_+N,rhs.index_base_) );
+ }
+
+ template <class DifferenceType>
+ void advance(DifferenceType n) {
+ idx_ += n;
+ }
+
+ template <class IteratorAdaptor>
+ typename facade_type::difference_type
+ distance_to(IteratorAdaptor& rhs) const {
+ return rhs.idx_ - idx_;
+ }
+
+
+};
+
+} // namespace multi_array
+} // namespace detail
+} // namespace boost
+
+#endif // ITERATOR_RG071801_HPP
diff --git a/include/boost/multi_array/multi_array_ref.hpp b/include/boost/multi_array/multi_array_ref.hpp
new file mode 100644
index 0000000..7c0fb03
--- /dev/null
+++ b/include/boost/multi_array/multi_array_ref.hpp
@@ -0,0 +1,622 @@
+// 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_REF_RG071801_HPP
+#define BOOST_MULTI_ARRAY_REF_RG071801_HPP
+
+//
+// multi_array_ref.hpp - code for creating "views" of array data.
+//
+
+#include "boost/multi_array/base.hpp"
+#include "boost/multi_array/collection_concept.hpp"
+#include "boost/multi_array/concept_checks.hpp"
+#include "boost/multi_array/iterator.hpp"
+#include "boost/multi_array/storage_order.hpp"
+#include "boost/multi_array/subarray.hpp"
+#include "boost/multi_array/view.hpp"
+#include "boost/multi_array/algorithm.hpp"
+#include "boost/type_traits/is_integral.hpp"
+#include "boost/utility/enable_if.hpp"
+#include "boost/array.hpp"
+#include "boost/concept_check.hpp"
+#include "boost/functional.hpp"
+#include "boost/limits.hpp"
+#include <algorithm>
+#include <cstddef>
+#include <functional>
+#include <numeric>
+
+namespace boost {
+
+template <typename T, std::size_t NumDims,
+ typename TPtr = const T*
+>
+class const_multi_array_ref :
+ public detail::multi_array::multi_array_impl_base<T,NumDims>
+{
+ typedef detail::multi_array::multi_array_impl_base<T,NumDims> super_type;
+public:
+ typedef typename super_type::value_type value_type;
+ typedef typename super_type::const_reference const_reference;
+ typedef typename super_type::const_iterator const_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;
+ typedef general_storage_order<NumDims> storage_order_type;
+
+ // template typedefs
+ 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;
+ };
+
+#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
+ // make const_multi_array_ref a friend of itself
+ template <typename,std::size_t,typename>
+ friend class const_multi_array_ref;
+#endif
+
+ // This ensures that const_multi_array_ref types with different TPtr
+ // types can convert to each other
+ template <typename OPtr>
+ const_multi_array_ref(const const_multi_array_ref<T,NumDims,OPtr>& other)
+ : base_(other.base_), storage_(other.storage_),
+ extent_list_(other.extent_list_),
+ stride_list_(other.stride_list_),
+ index_base_list_(other.index_base_list_),
+ origin_offset_(other.origin_offset_),
+ directional_offset_(other.directional_offset_),
+ num_elements_(other.num_elements_) { }
+
+ template <typename ExtentList>
+ explicit const_multi_array_ref(TPtr base, const ExtentList& extents) :
+ base_(base), storage_(c_storage_order()) {
+ boost::function_requires<
+ CollectionConcept<ExtentList> >();
+
+ index_base_list_.assign(0);
+ init_multi_array_ref(extents.begin());
+ }
+
+ template <typename ExtentList>
+ explicit const_multi_array_ref(TPtr base, const ExtentList& extents,
+ const general_storage_order<NumDims>& so) :
+ base_(base), storage_(so) {
+ boost::function_requires<
+ CollectionConcept<ExtentList> >();
+
+ index_base_list_.assign(0);
+ init_multi_array_ref(extents.begin());
+ }
+
+ explicit const_multi_array_ref(TPtr base,
+ const detail::multi_array::
+ extent_gen<NumDims>& ranges) :
+ base_(base), storage_(c_storage_order()) {
+
+ init_from_extent_gen(ranges);
+ }
+
+ explicit const_multi_array_ref(TPtr base,
+ const detail::multi_array::
+ extent_gen<NumDims>& ranges,
+ const general_storage_order<NumDims>& so) :
+ base_(base), storage_(so) {
+
+ init_from_extent_gen(ranges);
+ }
+
+ template <class InputIterator>
+ void assign(InputIterator begin, InputIterator end) {
+ boost::function_requires<InputIteratorConcept<InputIterator> >();
+
+ InputIterator in_iter = begin;
+ T* out_iter = base_;
+ std::size_t copy_count=0;
+ while (in_iter != end && copy_count < num_elements_) {
+ *out_iter++ = *in_iter++;
+ copy_count++;
+ }
+ }
+
+ template <class BaseList>
+#ifdef BOOST_NO_SFINAE
+ void
+#else
+ typename
+ disable_if<typename boost::is_integral<BaseList>::type,void >::type
+#endif // BOOST_NO_SFINAE
+ reindex(const BaseList& values) {
+ boost::function_requires<
+ CollectionConcept<BaseList> >();
+ boost::detail::multi_array::
+ copy_n(values.begin(),num_dimensions(),index_base_list_.begin());
+ origin_offset_ =
+ this->calculate_origin_offset(stride_list_,extent_list_,
+ storage_,index_base_list_);
+ }
+
+ void reindex(index value) {
+ index_base_list_.assign(value);
+ origin_offset_ =
+ this->calculate_origin_offset(stride_list_,extent_list_,
+ storage_,index_base_list_);
+ }
+
+ template <typename SizeList>
+ void reshape(const SizeList& extents) {
+ boost::function_requires<
+ CollectionConcept<SizeList> >();
+ BOOST_ASSERT(num_elements_ ==
+ std::accumulate(extents.begin(),extents.end(),
+ size_type(1),std::multiplies<size_type>()));
+
+ std::copy(extents.begin(),extents.end(),extent_list_.begin());
+ this->compute_strides(stride_list_,extent_list_,storage_);
+
+ origin_offset_ =
+ this->calculate_origin_offset(stride_list_,extent_list_,
+ storage_,index_base_list_);
+ }
+
+ size_type num_dimensions() const { return NumDims; }
+
+ size_type size() const { return extent_list_.front(); }
+
+ // given reshaping functionality, this is the max possible size.
+ size_type max_size() const { return num_elements(); }
+
+ bool empty() const { return size() == 0; }
+
+ const size_type* shape() const {
+ return extent_list_.data();
+ }
+
+ const index* strides() const {
+ return stride_list_.data();
+ }
+
+ const element* origin() const { return base_+origin_offset_; }
+ const element* data() const { return base_; }
+
+ size_type num_elements() const { return num_elements_; }
+
+ const index* index_bases() const {
+ return index_base_list_.data();
+ }
+
+
+ const storage_order_type& storage_order() const {
+ return storage_;
+ }
+
+ template <typename IndexList>
+ const element& operator()(IndexList indices) const {
+ boost::function_requires<
+ CollectionConcept<IndexList> >();
+ return super_type::access_element(boost::type<const element&>(),
+ indices,origin(),
+ shape(),strides(),index_bases());
+ }
+
+ // Only allow const element access
+ const_reference operator[](index idx) const {
+ return super_type::access(boost::type<const_reference>(),
+ idx,origin(),
+ shape(),strides(),index_bases());
+ }
+
+ // see generate_array_view in base.hpp
+ template <int NDims>
+ typename const_array_view<NDims>::type
+ operator[](const detail::multi_array::
+ index_gen<NumDims,NDims>& indices)
+ const {
+ typedef typename const_array_view<NDims>::type return_type;
+ return
+ super_type::generate_array_view(boost::type<return_type>(),
+ indices,
+ shape(),
+ strides(),
+ index_bases(),
+ origin());
+ }
+
+ const_iterator begin() const {
+ return const_iterator(*index_bases(),origin(),
+ shape(),strides(),index_bases());
+ }
+
+ const_iterator end() const {
+ return const_iterator(*index_bases()+(index)*shape(),origin(),
+ shape(),strides(),index_bases());
+ }
+
+ const_reverse_iterator rbegin() const {
+ return const_reverse_iterator(end());
+ }
+
+ const_reverse_iterator rend() const {
+ return const_reverse_iterator(begin());
+ }
+
+
+ template <typename OPtr>
+ bool operator==(const
+ const_multi_array_ref<T,NumDims,OPtr>& rhs)
+ const {
+ if(std::equal(extent_list_.begin(),
+ extent_list_.end(),
+ rhs.extent_list_.begin()))
+ return std::equal(begin(),end(),rhs.begin());
+ else return false;
+ }
+
+ template <typename OPtr>
+ bool operator<(const
+ const_multi_array_ref<T,NumDims,OPtr>& rhs)
+ const {
+ return std::lexicographical_compare(begin(),end(),rhs.begin(),rhs.end());
+ }
+
+ template <typename OPtr>
+ bool operator!=(const
+ const_multi_array_ref<T,NumDims,OPtr>& rhs)
+ const {
+ return !(*this == rhs);
+ }
+
+ template <typename OPtr>
+ bool operator>(const
+ const_multi_array_ref<T,NumDims,OPtr>& rhs)
+ const {
+ return rhs < *this;
+ }
+
+ template <typename OPtr>
+ bool operator<=(const
+ const_multi_array_ref<T,NumDims,OPtr>& rhs)
+ const {
+ return !(*this > rhs);
+ }
+
+ template <typename OPtr>
+ bool operator>=(const
+ const_multi_array_ref<T,NumDims,OPtr>& rhs)
+ const {
+ return !(*this < rhs);
+ }
+
+
+#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
+protected:
+#else
+public:
+#endif
+
+ typedef boost::array<size_type,NumDims> size_list;
+ typedef boost::array<index,NumDims> index_list;
+
+ // This is used by multi_array, which is a subclass of this
+ void set_base_ptr(TPtr new_base) { base_ = new_base; }
+
+
+ // This constructor supports multi_array's default constructor
+ // and constructors from multi_array_ref, subarray, and array_view
+ explicit
+ const_multi_array_ref(TPtr base,
+ const storage_order_type& so,
+ const index * index_bases,
+ const size_type* extents) :
+ base_(base), storage_(so), origin_offset_(0), directional_offset_(0)
+ {
+ // If index_bases or extents is null, then initialize the corresponding
+ // private data to zeroed lists.
+ if(index_bases) {
+ boost::detail::multi_array::
+ copy_n(index_bases,NumDims,index_base_list_.begin());
+ } else {
+ std::fill_n(index_base_list_.begin(),NumDims,0);
+ }
+ if(extents) {
+ init_multi_array_ref(extents);
+ } else {
+ boost::array<index,NumDims> extent_list;
+ extent_list.assign(0);
+ init_multi_array_ref(extent_list.begin());
+ }
+ }
+
+
+ TPtr base_;
+ storage_order_type storage_;
+ size_list extent_list_;
+ index_list stride_list_;
+ index_list index_base_list_;
+ index origin_offset_;
+ index directional_offset_;
+ size_type num_elements_;
+
+private:
+ // const_multi_array_ref cannot be assigned to (no deep copies!)
+ const_multi_array_ref& operator=(const const_multi_array_ref& other);
+
+ void init_from_extent_gen(const
+ detail::multi_array::
+ extent_gen<NumDims>& ranges) {
+
+ typedef boost::array<index,NumDims> extent_list;
+
+ // get the index_base values
+ std::transform(ranges.ranges_.begin(),ranges.ranges_.end(),
+ index_base_list_.begin(),
+ boost::mem_fun_ref(&extent_range::start));
+
+ // calculate the extents
+ extent_list extents;
+ std::transform(ranges.ranges_.begin(),ranges.ranges_.end(),
+ extents.begin(),
+ boost::mem_fun_ref(&extent_range::size));
+
+ init_multi_array_ref(extents.begin());
+ }
+
+
+#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
+protected:
+#else
+public:
+#endif
+ // RG - move me!
+ template <class InputIterator>
+ void init_multi_array_ref(InputIterator extents_iter) {
+ boost::function_requires<InputIteratorConcept<InputIterator> >();
+
+ boost::detail::multi_array::
+ copy_n(extents_iter,num_dimensions(),extent_list_.begin());
+
+ // Calculate the array size
+ num_elements_ = std::accumulate(extent_list_.begin(),extent_list_.end(),
+ size_type(1),std::multiplies<size_type>());
+
+ this->compute_strides(stride_list_,extent_list_,storage_);
+
+ origin_offset_ =
+ this->calculate_origin_offset(stride_list_,extent_list_,
+ storage_,index_base_list_);
+ directional_offset_ =
+ this->calculate_descending_dimension_offset(stride_list_,extent_list_,
+ storage_);
+ }
+};
+
+template <typename T, std::size_t NumDims>
+class multi_array_ref :
+ public const_multi_array_ref<T,NumDims,T*>
+{
+ typedef const_multi_array_ref<T,NumDims,T*> super_type;
+public:
+ typedef typename super_type::value_type value_type;
+ typedef typename super_type::reference reference;
+ typedef typename super_type::iterator iterator;
+ typedef typename super_type::reverse_iterator reverse_iterator;
+ typedef typename super_type::const_reference const_reference;
+ typedef typename super_type::const_iterator const_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;
+
+ typedef typename super_type::storage_order_type storage_order_type;
+ typedef typename super_type::index_list index_list;
+ typedef typename super_type::size_list size_list;
+
+ 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;
+ };
+
+ template <class ExtentList>
+ explicit multi_array_ref(T* base, const ExtentList& extents) :
+ super_type(base,extents) {
+ boost::function_requires<
+ CollectionConcept<ExtentList> >();
+ }
+
+ template <class ExtentList>
+ explicit multi_array_ref(T* base, const ExtentList& extents,
+ const general_storage_order<NumDims>& so) :
+ super_type(base,extents,so) {
+ boost::function_requires<
+ CollectionConcept<ExtentList> >();
+ }
+
+
+ explicit multi_array_ref(T* base,
+ const detail::multi_array::
+ extent_gen<NumDims>& ranges) :
+ super_type(base,ranges) { }
+
+
+ explicit multi_array_ref(T* base,
+ const detail::multi_array::
+ extent_gen<NumDims>&
+ ranges,
+ const general_storage_order<NumDims>& so) :
+ super_type(base,ranges,so) { }
+
+
+ // Assignment from other ConstMultiArray types.
+ template <typename ConstMultiArray>
+ multi_array_ref& operator=(const ConstMultiArray& other) {
+ function_requires<
+ multi_array_concepts::
+ ConstMultiArrayConcept<ConstMultiArray,NumDims> >();
+
+ // make sure the dimensions agree
+ BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
+ BOOST_ASSERT(std::equal(other.shape(),other.shape()+this->num_dimensions(),
+ this->shape()));
+ // iterator-based copy
+ std::copy(other.begin(),other.end(),this->begin());
+ return *this;
+ }
+
+ multi_array_ref& operator=(const multi_array_ref& other) {
+ if (&other != this) {
+ // make sure the dimensions agree
+
+ BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
+ BOOST_ASSERT(std::equal(other.shape(),
+ other.shape()+this->num_dimensions(),
+ this->shape()));
+ // iterator-based copy
+ std::copy(other.begin(),other.end(),this->begin());
+ }
+ return *this;
+ }
+
+ element* origin() { return super_type::base_+super_type::origin_offset_; }
+
+ element* data() { return super_type::base_; }
+
+ template <class IndexList>
+ element& operator()(const IndexList& indices) {
+ boost::function_requires<
+ CollectionConcept<IndexList> >();
+ return super_type::access_element(boost::type<element&>(),
+ indices,origin(),
+ this->shape(),this->strides(),
+ this->index_bases());
+ }
+
+
+ reference operator[](index idx) {
+ return super_type::access(boost::type<reference>(),
+ idx,origin(),
+ this->shape(),this->strides(),
+ this->index_bases());
+ }
+
+
+ // See note attached to generate_array_view in base.hpp
+ template <int NDims>
+ typename array_view<NDims>::type
+ operator[](const detail::multi_array::
+ index_gen<NumDims,NDims>& indices) {
+ typedef typename array_view<NDims>::type return_type;
+ return
+ super_type::generate_array_view(boost::type<return_type>(),
+ indices,
+ this->shape(),
+ this->strides(),
+ this->index_bases(),
+ origin());
+ }
+
+
+ iterator begin() {
+ return iterator(*this->index_bases(),origin(),this->shape(),
+ this->strides(),this->index_bases());
+ }
+
+ iterator end() {
+ return iterator(*this->index_bases()+(index)*this->shape(),origin(),
+ this->shape(),this->strides(),
+ this->index_bases());
+ }
+
+ // rbegin() and rend() written naively to thwart MSVC ICE.
+ reverse_iterator rbegin() {
+ reverse_iterator ri(end());
+ return ri;
+ }
+
+ reverse_iterator rend() {
+ reverse_iterator ri(begin());
+ return ri;
+ }
+
+ // Using declarations don't seem to work for g++
+ // These are the proxies to work around this.
+
+ const element* origin() const { return super_type::origin(); }
+ const element* data() const { return super_type::data(); }
+
+ template <class IndexList>
+ const element& operator()(const IndexList& indices) const {
+ boost::function_requires<
+ CollectionConcept<IndexList> >();
+ return super_type::operator()(indices);
+ }
+
+ const_reference operator[](index idx) const {
+ return super_type::access(boost::type<const_reference>(),
+ idx,origin(),
+ this->shape(),this->strides(),
+ this->index_bases());
+ }
+
+ // See note attached to generate_array_view in base.hpp
+ template <int NDims>
+ typename const_array_view<NDims>::type
+ operator[](const detail::multi_array::
+ index_gen<NumDims,NDims>& indices)
+ const {
+ return super_type::operator[](indices);
+ }
+
+ const_iterator begin() const {
+ return super_type::begin();
+ }
+
+ const_iterator end() const {
+ return super_type::end();
+ }
+
+ const_reverse_iterator rbegin() const {
+ return super_type::rbegin();
+ }
+
+ const_reverse_iterator rend() const {
+ return super_type::rend();
+ }
+
+protected:
+ // This is only supplied to support multi_array's default constructor
+ explicit multi_array_ref(T* base,
+ const storage_order_type& so,
+ const index* index_bases,
+ const size_type* extents) :
+ super_type(base,so,index_bases,extents) { }
+
+};
+
+} // namespace boost
+
+#endif // BOOST_MULTI_ARRAY_REF_RG071801_HPP
diff --git a/include/boost/multi_array/range_list.hpp b/include/boost/multi_array/range_list.hpp
new file mode 100644
index 0000000..406571c
--- /dev/null
+++ b/include/boost/multi_array/range_list.hpp
@@ -0,0 +1,70 @@
+// 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 RANGE_LIST_RG072501_HPP
+#define RANGE_LIST_RG072501_HPP
+//
+// range_list.hpp - helper to build boost::arrays for *_set types
+//
+
+#include "boost/array.hpp"
+
+namespace boost {
+namespace detail {
+namespace multi_array {
+
+/////////////////////////////////////////////////////////////////////////
+// choose range list begins
+//
+
+struct choose_range_list_n {
+ template <typename T, std::size_t NumRanges>
+ struct bind {
+ typedef boost::array<T,NumRanges> type;
+ };
+};
+
+struct choose_range_list_zero {
+ template <typename T, std::size_t NumRanges>
+ struct bind {
+ typedef boost::array<T,1> type;
+ };
+};
+
+
+template <std::size_t NumRanges>
+struct range_list_gen_helper {
+ typedef choose_range_list_n choice;
+};
+
+template <>
+struct range_list_gen_helper<0> {
+ typedef choose_range_list_zero choice;
+};
+
+template <typename T, std::size_t NumRanges>
+struct range_list_generator {
+private:
+ typedef typename range_list_gen_helper<NumRanges>::choice Choice;
+public:
+ typedef typename Choice::template bind<T,NumRanges>::type type;
+};
+
+//
+// choose range list ends
+/////////////////////////////////////////////////////////////////////////
+
+} // namespace multi_array
+} // namespace detail
+} // namespace boost
+
+#endif // RANGE_LIST_RG072501_HPP
diff --git a/include/boost/multi_array/storage_order.hpp b/include/boost/multi_array/storage_order.hpp
new file mode 100644
index 0000000..3eb7136
--- /dev/null
+++ b/include/boost/multi_array/storage_order.hpp
@@ -0,0 +1,125 @@
+// 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_STORAGE_ORDER_RG071801_HPP
+#define BOOST_STORAGE_ORDER_RG071801_HPP
+
+#include "boost/multi_array/types.hpp"
+#include "boost/array.hpp"
+#include "boost/multi_array/algorithm.hpp"
+#include <algorithm>
+#include <cstddef>
+#include <functional>
+#include <numeric>
+#include <vector>
+
+namespace boost {
+
+ // RG - This is to make things work with VC++. So sad, so sad.
+ class c_storage_order;
+ class fortran_storage_order;
+
+ template <std::size_t NumDims>
+ class general_storage_order
+ {
+ public:
+ typedef detail::multi_array::size_type size_type;
+ template <typename OrderingIter, typename AscendingIter>
+ general_storage_order(OrderingIter ordering,
+ AscendingIter ascending) {
+ boost::detail::multi_array::copy_n(ordering,NumDims,ordering_.begin());
+ boost::detail::multi_array::copy_n(ascending,NumDims,ascending_.begin());
+ }
+
+ // RG - ideally these would not be necessary, but some compilers
+ // don't like template conversion operators. I suspect that not
+ // too many folk will feel the need to use customized
+ // storage_order objects, I sacrifice that feature for compiler support.
+ general_storage_order(const c_storage_order&) {
+ for (size_type i=0; i != NumDims; ++i) {
+ ordering_[i] = NumDims - 1 - i;
+ }
+ ascending_.assign(true);
+ }
+
+ general_storage_order(const fortran_storage_order&) {
+ for (size_type i=0; i != NumDims; ++i) {
+ ordering_[i] = i;
+ }
+ ascending_.assign(true);
+ }
+
+ size_type ordering(size_type dim) const { return ordering_[dim]; }
+ bool ascending(size_type dim) const { return ascending_[dim]; }
+
+ bool all_dims_ascending() const {
+ return std::accumulate(ascending_.begin(),ascending_.end(),true,
+ std::logical_and<bool>());
+ }
+
+ bool operator==(general_storage_order const& rhs) const {
+ return (ordering_ == rhs.ordering_) &&
+ (ascending_ == rhs.ascending_);
+ }
+
+ protected:
+ boost::array<size_type,NumDims> ordering_;
+ boost::array<bool,NumDims> ascending_;
+ };
+
+ class c_storage_order
+ {
+ typedef detail::multi_array::size_type size_type;
+ public:
+ // This is the idiom for creating your own custom storage orders.
+ // Not supported by all compilers though!
+#ifndef __MWERKS__ // Metrowerks screams "ambiguity!"
+ template <std::size_t NumDims>
+ operator general_storage_order<NumDims>() const {
+ boost::array<size_type,NumDims> ordering;
+ boost::array<bool,NumDims> ascending;
+
+ for (size_type i=0; i != NumDims; ++i) {
+ ordering[i] = NumDims - 1 - i;
+ ascending[i] = true;
+ }
+ return general_storage_order<NumDims>(ordering.begin(),
+ ascending.begin());
+ }
+#endif
+ };
+
+ class fortran_storage_order
+ {
+ typedef detail::multi_array::size_type size_type;
+ public:
+ // This is the idiom for creating your own custom storage orders.
+ // Not supported by all compilers though!
+#ifndef __MWERKS__ // Metrowerks screams "ambiguity!"
+ template <std::size_t NumDims>
+ operator general_storage_order<NumDims>() const {
+ boost::array<size_type,NumDims> ordering;
+ boost::array<bool,NumDims> ascending;
+
+ for (size_type i=0; i != NumDims; ++i) {
+ ordering[i] = i;
+ ascending[i] = true;
+ }
+ return general_storage_order<NumDims>(ordering.begin(),
+ ascending.begin());
+ }
+#endif
+ };
+
+} // namespace boost
+
+#endif // BOOST_ARRAY_STORAGE_RG071801_HPP
diff --git a/include/boost/multi_array/subarray.hpp b/include/boost/multi_array/subarray.hpp
new file mode 100644
index 0000000..5c36599
--- /dev/null
+++ b/include/boost/multi_array/subarray.hpp
@@ -0,0 +1,387 @@
+// 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 SUBARRAY_RG071801_HPP
+#define SUBARRAY_RG071801_HPP
+
+//
+// subarray.hpp - used to implement standard operator[] on
+// multi_arrays
+//
+
+#include "boost/multi_array/base.hpp"
+#include "boost/multi_array/concept_checks.hpp"
+#include "boost/limits.hpp"
+#include "boost/type.hpp"
+#include <algorithm>
+#include <cstddef>
+#include <functional>
+
+namespace boost {
+namespace detail {
+namespace multi_array {
+
+//
+// const_sub_array
+// multi_array's proxy class to allow multiple overloads of
+// operator[] in order to provide a clean multi-dimensional array
+// interface.
+template <typename T, std::size_t NumDims, typename TPtr>
+class const_sub_array :
+ public boost::detail::multi_array::multi_array_impl_base<T,NumDims>
+{
+ typedef boost::detail::multi_array::multi_array_impl_base<T,NumDims> super_type;
+public:
+ typedef typename super_type::value_type value_type;
+ typedef typename super_type::const_reference const_reference;
+ typedef typename super_type::const_iterator const_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 typedefs
+ 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;
+ };
+
+ // Allow default copy constructor as well.
+
+ template <typename OPtr>
+ const_sub_array (const const_sub_array<T,NumDims,OPtr>& rhs) :
+ base_(rhs.base_), extents_(rhs.extents_), strides_(rhs.strides_),
+ index_base_(rhs.index_base_) {
+ }
+
+ // const_sub_array always returns const types, regardless of its own
+ // constness.
+ const_reference operator[](index idx) const {
+ return super_type::access(boost::type<const_reference>(),
+ idx,base_,shape(),strides(),index_bases());
+ }
+
+ template <typename IndexList>
+ const element& operator()(const IndexList& indices) const {
+ boost::function_requires<
+ CollectionConcept<IndexList> >();
+ return super_type::access_element(boost::type<const element&>(),
+ indices,origin(),
+ shape(),strides(),index_bases());
+ }
+
+ // see generate_array_view in base.hpp
+ template <int NDims>
+ typename const_array_view<NDims>::type
+ operator[](const boost::detail::multi_array::
+ index_gen<NumDims,NDims>& indices)
+ const {
+ typedef typename const_array_view<NDims>::type return_type;
+ return
+ super_type::generate_array_view(boost::type<return_type>(),
+ indices,
+ shape(),
+ strides(),
+ index_bases(),
+ base_);
+ }
+
+ template <typename OPtr>
+ bool operator<(const const_sub_array<T,NumDims,OPtr>& rhs) const {
+ return std::lexicographical_compare(begin(),end(),rhs.begin(),rhs.end());
+ }
+
+ template <typename OPtr>
+ bool operator==(const const_sub_array<T,NumDims,OPtr>& rhs) const {
+ if(std::equal(shape(),shape()+num_dimensions(),rhs.shape()))
+ return std::equal(begin(),end(),rhs.begin());
+ else return false;
+ }
+
+ template <typename OPtr>
+ bool operator!=(const const_sub_array<T,NumDims,OPtr>& rhs) const {
+ return !(*this == rhs);
+ }
+
+ template <typename OPtr>
+ bool operator>(const const_sub_array<T,NumDims,OPtr>& rhs) const {
+ return rhs < *this;
+ }
+
+ template <typename OPtr>
+ bool operator<=(const const_sub_array<T,NumDims,OPtr>& rhs) const {
+ return !(*this > rhs);
+ }
+
+ template <typename OPtr>
+ bool operator>=(const const_sub_array<T,NumDims,OPtr>& rhs) const {
+ return !(*this < rhs);
+ }
+
+ const_iterator begin() const {
+ return const_iterator(*index_bases(),origin(),
+ shape(),strides(),index_bases());
+ }
+
+ const_iterator end() const {
+ return const_iterator(*index_bases()+(index)*shape(),origin(),
+ shape(),strides(),index_bases());
+ }
+
+ const_reverse_iterator rbegin() const {
+ return const_reverse_iterator(end());
+ }
+
+ const_reverse_iterator rend() const {
+ return const_reverse_iterator(begin());
+ }
+
+ TPtr origin() const { return base_; }
+ size_type size() const { return extents_[0]; }
+ size_type max_size() const { return num_elements(); }
+ bool empty() const { return size() == 0; }
+ size_type num_dimensions() const { return NumDims; }
+ const size_type* shape() const { return extents_; }
+ const index* strides() const { return strides_; }
+ const index* index_bases() const { return index_base_; }
+
+ size_type num_elements() const {
+ return std::accumulate(shape(),shape() + num_dimensions(),
+ size_type(1), std::multiplies<size_type>());
+ }
+
+
+#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
+protected:
+ template <typename,std::size_t> friend class value_accessor_n;
+ template <typename,std::size_t,typename> friend class const_sub_array;
+#else
+public: // Should be protected
+#endif
+
+ const_sub_array (TPtr base,
+ const size_type* extents,
+ const index* strides,
+ const index* index_base) :
+ base_(base), extents_(extents), strides_(strides),
+ index_base_(index_base) {
+ }
+
+ TPtr base_;
+ const size_type* extents_;
+ const index* strides_;
+ const index* index_base_;
+private:
+ // const_sub_array cannot be assigned to (no deep copies!)
+ const_sub_array& operator=(const const_sub_array&);
+};
+
+
+//
+// sub_array
+// multi_array's proxy class to allow multiple overloads of
+// operator[] in order to provide a clean multi-dimensional array
+// interface.
+template <typename T, std::size_t NumDims>
+class sub_array : public const_sub_array<T,NumDims,T*>
+{
+ typedef const_sub_array<T,NumDims,T*> super_type;
+public:
+ typedef typename super_type::element element;
+ typedef typename super_type::reference reference;
+ typedef typename super_type::index index;
+ typedef typename super_type::size_type size_type;
+ typedef typename super_type::iterator iterator;
+ typedef typename super_type::reverse_iterator reverse_iterator;
+ typedef typename super_type::const_reference const_reference;
+ typedef typename super_type::const_iterator const_iterator;
+ typedef typename super_type::const_reverse_iterator const_reverse_iterator;
+
+ // template typedefs
+ 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;
+ };
+
+ // Assignment from other ConstMultiArray types.
+ template <typename ConstMultiArray>
+ sub_array& operator=(const ConstMultiArray& other) {
+ function_requires< boost::multi_array_concepts::ConstMultiArrayConcept<
+ ConstMultiArray, NumDims> >();
+
+ // make sure the dimensions agree
+ BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
+ BOOST_ASSERT(std::equal(other.shape(),other.shape()+this->num_dimensions(),
+ this->shape()));
+ // iterator-based copy
+ std::copy(other.begin(),other.end(),begin());
+ return *this;
+ }
+
+
+ sub_array& operator=(const sub_array& other) {
+ if (&other != this) {
+ // make sure the dimensions agree
+ BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
+ BOOST_ASSERT(std::equal(other.shape(),
+ other.shape()+this->num_dimensions(),
+ this->shape()));
+ // iterator-based copy
+ std::copy(other.begin(),other.end(),begin());
+ }
+ return *this;
+ }
+
+ T* origin() { return this->base_; }
+ const T* origin() const { return this->base_; }
+
+ reference operator[](index idx) {
+ return super_type::access(boost::type<reference>(),
+ idx,this->base_,this->shape(),this->strides(),
+ this->index_bases());
+ }
+
+ // see generate_array_view in base.hpp
+ template <int NDims>
+ typename array_view<NDims>::type
+ operator[](const boost::detail::multi_array::
+ index_gen<NumDims,NDims>& indices) {
+ typedef typename array_view<NDims>::type return_type;
+ return
+ super_type::generate_array_view(boost::type<return_type>(),
+ indices,
+ this->shape(),
+ this->strides(),
+ this->index_bases(),
+ origin());
+ }
+
+ template <class IndexList>
+ element& operator()(const IndexList& indices) {
+ boost::function_requires<
+ CollectionConcept<IndexList> >();
+ return super_type::access_element(boost::type<element&>(),
+ indices,origin(),
+ this->shape(),this->strides(),
+ this->index_bases());
+ }
+
+ iterator begin() {
+ return iterator(*this->index_bases(),origin(),
+ this->shape(),this->strides(),this->index_bases());
+ }
+
+ iterator end() {
+ return iterator(*this->index_bases()+(index)*this->shape(),origin(),
+ this->shape(),this->strides(),this->index_bases());
+ }
+
+ // RG - rbegin() and rend() written naively to thwart MSVC ICE.
+ reverse_iterator rbegin() {
+ reverse_iterator ri(end());
+ return ri;
+ }
+
+ reverse_iterator rend() {
+ reverse_iterator ri(begin());
+ return ri;
+ }
+
+ //
+ // proxies
+ //
+
+ template <class IndexList>
+ const element& operator()(const IndexList& indices) const {
+ boost::function_requires<
+ CollectionConcept<IndexList> >();
+ return super_type::operator()(indices);
+ }
+
+ const_reference operator[](index idx) const {
+ return super_type::operator[](idx);
+ }
+
+ // see generate_array_view in base.hpp
+ template <int NDims>
+ typename const_array_view<NDims>::type
+ operator[](const boost::detail::multi_array::
+ index_gen<NumDims,NDims>& indices)
+ const {
+ return super_type::operator[](indices);
+ }
+
+ const_iterator begin() const {
+ return super_type::begin();
+ }
+
+ const_iterator end() const {
+ return super_type::end();
+ }
+
+ const_reverse_iterator rbegin() const {
+ return super_type::rbegin();
+ }
+
+ const_reverse_iterator rend() const {
+ return super_type::rend();
+ }
+
+#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
+private:
+ template <typename,std::size_t> friend class value_accessor_n;
+#else
+public: // should be private
+#endif
+
+ sub_array (T* base,
+ const size_type* extents,
+ const index* strides,
+ const index* index_base) :
+ super_type(base,extents,strides,index_base) {
+ }
+
+};
+
+} // namespace multi_array
+} // namespace detail
+//
+// traits classes to get sub_array types
+//
+template <typename Array, int N>
+class subarray_gen {
+ typedef typename Array::element element;
+public:
+ typedef boost::detail::multi_array::sub_array<element,N> type;
+};
+
+template <typename Array, int N>
+class const_subarray_gen {
+ typedef typename Array::element element;
+public:
+ typedef boost::detail::multi_array::const_sub_array<element,N> type;
+};
+} // namespace boost
+
+#endif // SUBARRAY_RG071801_HPP
diff --git a/include/boost/multi_array/types.hpp b/include/boost/multi_array/types.hpp
new file mode 100644
index 0000000..5ef173b
--- /dev/null
+++ b/include/boost/multi_array/types.hpp
@@ -0,0 +1,38 @@
+// 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_TYPES_RG071801_HPP
+#define BOOST_MULTI_ARRAY_TYPES_RG071801_HPP
+
+//
+// types.hpp - supply types that are needed by several headers
+//
+#include "boost/config.hpp"
+#include <cstddef>
+
+namespace boost {
+namespace detail {
+namespace multi_array{
+
+// needed typedefs
+typedef std::size_t size_type;
+typedef std::ptrdiff_t index;
+
+} // namespace multi_array
+} // namespace detail
+} // namespace boost
+
+
+
+
+#endif // BOOST_MULTI_ARRAY_TYPES_RG071801_HPP
diff --git a/include/boost/multi_array/view.hpp b/include/boost/multi_array/view.hpp
new file mode 100644
index 0000000..59ac089
--- /dev/null
+++ b/include/boost/multi_array/view.hpp
@@ -0,0 +1,461 @@
+// 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_VIEW_RG071301_HPP
+#define BOOST_MULTI_ARRAY_VIEW_RG071301_HPP
+
+//
+// view.hpp - code for creating "views" of array data.
+//
+
+#include "boost/multi_array/base.hpp"
+#include "boost/multi_array/concept_checks.hpp"
+#include "boost/multi_array/iterator.hpp"
+#include "boost/multi_array/storage_order.hpp"
+#include "boost/multi_array/subarray.hpp"
+#include "boost/multi_array/algorithm.hpp"
+#include "boost/type_traits/is_integral.hpp"
+#include "boost/utility/enable_if.hpp"
+#include "boost/array.hpp"
+#include "boost/limits.hpp"
+#include <algorithm>
+#include <cstddef>
+#include <functional>
+#include <numeric>
+
+namespace boost {
+namespace detail {
+namespace multi_array {
+
+// TPtr = const T* defaulted in base.hpp
+template <typename T, std::size_t NumDims, typename TPtr>
+class const_multi_array_view :
+ public boost::detail::multi_array::multi_array_impl_base<T,NumDims>
+{
+ typedef boost::detail::multi_array::multi_array_impl_base<T,NumDims> super_type;
+public:
+ typedef typename super_type::value_type value_type;
+ typedef typename super_type::const_reference const_reference;
+ typedef typename super_type::const_iterator const_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 typedefs
+ 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;
+ };
+
+ template <typename OPtr>
+ const_multi_array_view(const
+ const_multi_array_view<T,NumDims,OPtr>& other) :
+ base_(other.base_), origin_offset_(other.origin_offset_),
+ num_elements_(other.num_elements_), extent_list_(other.extent_list_),
+ stride_list_(other.stride_list_), index_base_list_(other.index_base_list_)
+ { }
+
+
+ template <class BaseList>
+#ifdef BOOST_NO_SFINAE
+ void
+#else
+ typename
+ disable_if<typename boost::is_integral<BaseList>::type,void >::type
+#endif
+ reindex(const BaseList& values) {
+ boost::function_requires<
+ CollectionConcept<BaseList> >();
+ boost::detail::multi_array::
+ copy_n(values.begin(),num_dimensions(),index_base_list_.begin());
+ origin_offset_ =
+ this->calculate_indexing_offset(stride_list_,index_base_list_);
+ }
+
+ void reindex(index value) {
+ index_base_list_.assign(value);
+ origin_offset_ =
+ this->calculate_indexing_offset(stride_list_,index_base_list_);
+ }
+
+ size_type num_dimensions() const { return NumDims; }
+
+ size_type size() const { return extent_list_.front(); }
+ size_type max_size() const { return num_elements(); }
+ bool empty() const { return size() == 0; }
+
+ const size_type* shape() const {
+ return extent_list_.data();
+ }
+
+ const index* strides() const {
+ return stride_list_.data();
+ }
+
+ const T* origin() const { return base_+origin_offset_; }
+
+ size_type num_elements() const { return num_elements_; }
+
+ const index* index_bases() const {
+ return index_base_list_.data();
+ }
+
+ template <typename IndexList>
+ const element& operator()(IndexList indices) const {
+ boost::function_requires<
+ CollectionConcept<IndexList> >();
+ return super_type::access_element(boost::type<const element&>(),
+ indices,origin(),
+ shape(),strides(),index_bases());
+ }
+
+ // Only allow const element access
+ const_reference operator[](index idx) const {
+ return super_type::access(boost::type<const_reference>(),
+ idx,origin(),
+ shape(),strides(),
+ index_bases());
+ }
+
+ // see generate_array_view in base.hpp
+ template <int NDims>
+ typename const_array_view<NDims>::type
+ operator[](const boost::detail::multi_array::
+ index_gen<NumDims,NDims>& indices)
+ const {
+ typedef typename const_array_view<NDims>::type return_type;
+ return
+ super_type::generate_array_view(boost::type<return_type>(),
+ indices,
+ shape(),
+ strides(),
+ index_bases(),
+ origin());
+ }
+ const_iterator begin() const {
+ return const_iterator(*index_bases(),origin(),
+ shape(),strides(),index_bases());
+ }
+
+ const_iterator end() const {
+ return const_iterator(*index_bases()+(index)*shape(),origin(),
+ shape(),strides(),index_bases());
+ }
+
+ const_reverse_iterator rbegin() const {
+ return const_reverse_iterator(end());
+ }
+
+ const_reverse_iterator rend() const {
+ return const_reverse_iterator(begin());
+ }
+
+
+ template <typename OPtr>
+ bool operator==(const
+ const_multi_array_view<T,NumDims,OPtr>& rhs)
+ const {
+ if(std::equal(extent_list_.begin(),
+ extent_list_.end(),
+ rhs.extent_list_.begin()))
+ return std::equal(begin(),end(),rhs.begin());
+ else return false;
+ }
+
+ template <typename OPtr>
+ bool operator<(const
+ const_multi_array_view<T,NumDims,OPtr>& rhs)
+ const {
+ return std::lexicographical_compare(begin(),end(),rhs.begin(),rhs.end());
+ }
+
+ template <typename OPtr>
+ bool operator!=(const
+ const_multi_array_view<T,NumDims,OPtr>& rhs)
+ const {
+ return !(*this == rhs);
+ }
+
+ template <typename OPtr>
+ bool operator>(const
+ const_multi_array_view<T,NumDims,OPtr>& rhs)
+ const {
+ return rhs < *this;
+ }
+
+ template <typename OPtr>
+ bool operator<=(const
+ const_multi_array_view<T,NumDims,OPtr>& rhs)
+ const {
+ return !(*this > rhs);
+ }
+
+ template <typename OPtr>
+ bool operator>=(const
+ const_multi_array_view<T,NumDims,OPtr>& rhs)
+ const {
+ return !(*this < rhs);
+ }
+
+
+#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
+protected:
+ template <typename,std::size_t> friend class multi_array_impl_base;
+ template <typename,std::size_t,typename> friend class const_multi_array_view;
+#else
+public: // should be protected
+#endif
+
+ // This constructor is used by multi_array_impl_base::generate_array_view
+ // to create strides
+ template <typename ExtentList, typename Index>
+ explicit const_multi_array_view(TPtr base,
+ const ExtentList& extents,
+ const boost::array<Index,NumDims>& strides):
+ base_(base), origin_offset_(0) {
+
+ index_base_list_.assign(0);
+
+ // Get the extents and strides
+ boost::detail::multi_array::
+ copy_n(extents.begin(),NumDims,extent_list_.begin());
+ boost::detail::multi_array::
+ copy_n(strides.begin(),NumDims,stride_list_.begin());
+
+ // Calculate the array size
+ num_elements_ = std::accumulate(extent_list_.begin(),extent_list_.end(),
+ size_type(1),std::multiplies<size_type>());
+ }
+
+ typedef boost::array<size_type,NumDims> size_list;
+ typedef boost::array<index,NumDims> index_list;
+
+ TPtr base_;
+ index origin_offset_;
+ size_type num_elements_;
+ size_list extent_list_;
+ index_list stride_list_;
+ index_list index_base_list_;
+
+private:
+ // const_multi_array_view cannot be assigned to (no deep copies!)
+ const_multi_array_view& operator=(const const_multi_array_view& other);
+};
+
+
+template <typename T, std::size_t NumDims>
+class multi_array_view :
+ public const_multi_array_view<T,NumDims,T*>
+{
+ typedef const_multi_array_view<T,NumDims,T*> super_type;
+public:
+ typedef typename super_type::value_type value_type;
+ typedef typename super_type::reference reference;
+ typedef typename super_type::iterator iterator;
+ typedef typename super_type::reverse_iterator reverse_iterator;
+ typedef typename super_type::const_reference const_reference;
+ typedef typename super_type::const_iterator const_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 typedefs
+ 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;
+ };
+
+ // Assignment from other ConstMultiArray types.
+ template <typename ConstMultiArray>
+ multi_array_view& operator=(const ConstMultiArray& other) {
+ function_requires<
+ boost::multi_array_concepts::
+ ConstMultiArrayConcept<ConstMultiArray,NumDims> >();
+
+ // make sure the dimensions agree
+ BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
+ BOOST_ASSERT(std::equal(other.shape(),other.shape()+this->num_dimensions(),
+ this->shape()));
+ // iterator-based copy
+ std::copy(other.begin(),other.end(),begin());
+ return *this;
+ }
+
+
+ multi_array_view& operator=(const multi_array_view& other) {
+ if (&other != this) {
+ // make sure the dimensions agree
+ BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
+ BOOST_ASSERT(std::equal(other.shape(),
+ other.shape()+this->num_dimensions(),
+ this->shape()));
+ // iterator-based copy
+ std::copy(other.begin(),other.end(),begin());
+ }
+ return *this;
+ }
+
+ element* origin() { return this->base_+this->origin_offset_; }
+
+ template <class IndexList>
+ element& operator()(const IndexList& indices) {
+ boost::function_requires<
+ CollectionConcept<IndexList> >();
+ return super_type::access_element(boost::type<element&>(),
+ indices,origin(),
+ this->shape(),this->strides(),
+ this->index_bases());
+ }
+
+
+ reference operator[](index idx) {
+ return super_type::access(boost::type<reference>(),
+ idx,origin(),
+ this->shape(),this->strides(),
+ this->index_bases());
+ }
+
+
+ // see generate_array_view in base.hpp
+ template <int NDims>
+ typename array_view<NDims>::type
+ operator[](const boost::detail::multi_array::
+ index_gen<NumDims,NDims>& indices) {
+ typedef typename array_view<NDims>::type return_type;
+ return
+ super_type::generate_array_view(boost::type<return_type>(),
+ indices,
+ this->shape(),
+ this->strides(),
+ this->index_bases(),
+ origin());
+ }
+
+
+ iterator begin() {
+ return iterator(*this->index_bases(),origin(),
+ this->shape(),this->strides(),
+ this->index_bases());
+ }
+
+ iterator end() {
+ return iterator(*this->index_bases()+(index)*this->shape(),origin(),
+ this->shape(),this->strides(),
+ this->index_bases());
+ }
+
+ reverse_iterator rbegin() {
+ return reverse_iterator(end());
+ }
+
+ reverse_iterator rend() {
+ return reverse_iterator(begin());
+ }
+
+ // Using declarations don't seem to work for g++
+ // These are the proxies to work around this.
+
+ const element* origin() const { return super_type::origin(); }
+
+ template <class IndexList>
+ const element& operator()(const IndexList& indices) const {
+ boost::function_requires<
+ CollectionConcept<IndexList> >();
+ return super_type::operator()(indices);
+ }
+
+ const_reference operator[](index idx) const {
+ return super_type::operator[](idx);
+ }
+
+ // see generate_array_view in base.hpp
+ template <int NDims>
+ typename const_array_view<NDims>::type
+ operator[](const boost::detail::multi_array::
+ index_gen<NumDims,NDims>& indices)
+ const {
+ return super_type::operator[](indices);
+ }
+
+ const_iterator begin() const {
+ return super_type::begin();
+ }
+
+ const_iterator end() const {
+ return super_type::end();
+ }
+
+ const_reverse_iterator rbegin() const {
+ return super_type::rbegin();
+ }
+
+ const_reverse_iterator rend() const {
+ return super_type::rend();
+ }
+
+#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
+private:
+ template <typename,std::size_t> friend class multi_array_impl_base;
+#else
+public: // should be private
+#endif
+
+ // constructor used by multi_array_impl_base::generate_array_view to
+ // generate array views
+ template <typename ExtentList, typename Index>
+ explicit multi_array_view(T* base,
+ const ExtentList& extents,
+ const boost::array<Index,NumDims>& strides) :
+ super_type(base,extents,strides) { }
+
+};
+
+} // namespace multi_array
+} // namespace detail
+
+//
+// traits classes to get array_view types
+//
+template <typename Array, int N>
+class array_view_gen {
+ typedef typename Array::element element;
+public:
+ typedef boost::detail::multi_array::multi_array_view<element,N> type;
+};
+
+template <typename Array, int N>
+class const_array_view_gen {
+ typedef typename Array::element element;
+public:
+ typedef boost::detail::multi_array::const_multi_array_view<element,N> type;
+};
+
+} // namespace boost
+
+#endif // BOOST_MULTI_ARRAY_VIEW_RG071301_HPP
+