diff --git a/ThirdParty/boost/functional.hpp b/ThirdParty/boost/functional.hpp new file mode 100644 index 0000000000000000000000000000000000000000..644307847087b0bc587a1ca9490b4b85e811d072 --- /dev/null +++ b/ThirdParty/boost/functional.hpp @@ -0,0 +1,581 @@ +// ------------------------------------------------------------------------------ +// Copyright (c) 2000 Cadenza New Zealand Ltd +// Distributed under the Boost Software License, Version 1.0. (See accompany- +// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// ------------------------------------------------------------------------------ +// Boost functional.hpp header file +// See http://www.boost.org/libs/functional for documentation. +// ------------------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------------------ + +#ifndef BOOST_FUNCTIONAL_HPP +#define BOOST_FUNCTIONAL_HPP + +#include <boost/config.hpp> +#include <boost/call_traits.hpp> +#include <functional> + +namespace boost +{ + namespace functional + { + namespace detail { +#if defined(_HAS_AUTO_PTR_ETC) && !_HAS_AUTO_PTR_ETC + // std::unary_function and std::binary_function were both removed + // in C++17. + + template <typename Arg1, typename Result> + struct unary_function + { + typedef Arg1 argument_type; + typedef Result result_type; + }; + + template <typename Arg1, typename Arg2, typename Result> + struct binary_function + { + typedef Arg1 first_argument_type; + typedef Arg2 second_argument_type; + typedef Result result_type; + }; +#else + // Use the standard objects when we have them. + + using std::unary_function; + using std::binary_function; +#endif + } + } + +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + // -------------------------------------------------------------------------- + // The following traits classes allow us to avoid the need for ptr_fun + // because the types of arguments and the result of a function can be + // deduced. + // + // In addition to the standard types defined in unary_function and + // binary_function, we add + // + // - function_type, the type of the function or function object itself. + // + // - param_type, the type that should be used for passing the function or + // function object as an argument. + // -------------------------------------------------------------------------- + namespace detail + { + template <class Operation> + struct unary_traits_imp; + + template <class Operation> + struct unary_traits_imp<Operation*> + { + typedef Operation function_type; + typedef const function_type & param_type; + typedef typename Operation::result_type result_type; + typedef typename Operation::argument_type argument_type; + }; + + template <class R, class A> + struct unary_traits_imp<R(*)(A)> + { + typedef R (*function_type)(A); + typedef R (*param_type)(A); + typedef R result_type; + typedef A argument_type; + }; + + template <class Operation> + struct binary_traits_imp; + + template <class Operation> + struct binary_traits_imp<Operation*> + { + typedef Operation function_type; + typedef const function_type & param_type; + typedef typename Operation::result_type result_type; + typedef typename Operation::first_argument_type first_argument_type; + typedef typename Operation::second_argument_type second_argument_type; + }; + + template <class R, class A1, class A2> + struct binary_traits_imp<R(*)(A1,A2)> + { + typedef R (*function_type)(A1,A2); + typedef R (*param_type)(A1,A2); + typedef R result_type; + typedef A1 first_argument_type; + typedef A2 second_argument_type; + }; + } // namespace detail + + template <class Operation> + struct unary_traits + { + typedef typename detail::unary_traits_imp<Operation*>::function_type function_type; + typedef typename detail::unary_traits_imp<Operation*>::param_type param_type; + typedef typename detail::unary_traits_imp<Operation*>::result_type result_type; + typedef typename detail::unary_traits_imp<Operation*>::argument_type argument_type; + }; + + template <class R, class A> + struct unary_traits<R(*)(A)> + { + typedef R (*function_type)(A); + typedef R (*param_type)(A); + typedef R result_type; + typedef A argument_type; + }; + + template <class Operation> + struct binary_traits + { + typedef typename detail::binary_traits_imp<Operation*>::function_type function_type; + typedef typename detail::binary_traits_imp<Operation*>::param_type param_type; + typedef typename detail::binary_traits_imp<Operation*>::result_type result_type; + typedef typename detail::binary_traits_imp<Operation*>::first_argument_type first_argument_type; + typedef typename detail::binary_traits_imp<Operation*>::second_argument_type second_argument_type; + }; + + template <class R, class A1, class A2> + struct binary_traits<R(*)(A1,A2)> + { + typedef R (*function_type)(A1,A2); + typedef R (*param_type)(A1,A2); + typedef R result_type; + typedef A1 first_argument_type; + typedef A2 second_argument_type; + }; +#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + // -------------------------------------------------------------------------- + // If we have no partial specialisation available, decay to a situation + // that is no worse than in the Standard, i.e., ptr_fun will be required. + // -------------------------------------------------------------------------- + + template <class Operation> + struct unary_traits + { + typedef Operation function_type; + typedef const Operation& param_type; + typedef typename Operation::result_type result_type; + typedef typename Operation::argument_type argument_type; + }; + + template <class Operation> + struct binary_traits + { + typedef Operation function_type; + typedef const Operation & param_type; + typedef typename Operation::result_type result_type; + typedef typename Operation::first_argument_type first_argument_type; + typedef typename Operation::second_argument_type second_argument_type; + }; +#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + // -------------------------------------------------------------------------- + // unary_negate, not1 + // -------------------------------------------------------------------------- + template <class Predicate> + class unary_negate + : public boost::functional::detail::unary_function<typename unary_traits<Predicate>::argument_type,bool> + { + public: + explicit unary_negate(typename unary_traits<Predicate>::param_type x) + : + pred(x) + {} + bool operator()(typename call_traits<typename unary_traits<Predicate>::argument_type>::param_type x) const + { + return !pred(x); + } + private: + typename unary_traits<Predicate>::function_type pred; + }; + + template <class Predicate> + unary_negate<Predicate> not1(const Predicate &pred) + { + // The cast is to placate Borland C++Builder in certain circumstances. + // I don't think it should be necessary. + return unary_negate<Predicate>((typename unary_traits<Predicate>::param_type)pred); + } + + template <class Predicate> + unary_negate<Predicate> not1(Predicate &pred) + { + return unary_negate<Predicate>(pred); + } + + // -------------------------------------------------------------------------- + // binary_negate, not2 + // -------------------------------------------------------------------------- + template <class Predicate> + class binary_negate + : public boost::functional::detail::binary_function< + typename binary_traits<Predicate>::first_argument_type, + typename binary_traits<Predicate>::second_argument_type, + bool> + { + public: + explicit binary_negate(typename binary_traits<Predicate>::param_type x) + : + pred(x) + {} + bool operator()(typename call_traits<typename binary_traits<Predicate>::first_argument_type>::param_type x, + typename call_traits<typename binary_traits<Predicate>::second_argument_type>::param_type y) const + { + return !pred(x,y); + } + private: + typename binary_traits<Predicate>::function_type pred; + }; + + template <class Predicate> + binary_negate<Predicate> not2(const Predicate &pred) + { + // The cast is to placate Borland C++Builder in certain circumstances. + // I don't think it should be necessary. + return binary_negate<Predicate>((typename binary_traits<Predicate>::param_type)pred); + } + + template <class Predicate> + binary_negate<Predicate> not2(Predicate &pred) + { + return binary_negate<Predicate>(pred); + } + + // -------------------------------------------------------------------------- + // binder1st, bind1st + // -------------------------------------------------------------------------- + template <class Operation> + class binder1st + : public boost::functional::detail::unary_function< + typename binary_traits<Operation>::second_argument_type, + typename binary_traits<Operation>::result_type> + { + public: + binder1st(typename binary_traits<Operation>::param_type x, + typename call_traits<typename binary_traits<Operation>::first_argument_type>::param_type y) + : + op(x), value(y) + {} + + typename binary_traits<Operation>::result_type + operator()(typename call_traits<typename binary_traits<Operation>::second_argument_type>::param_type x) const + { + return op(value, x); + } + + protected: + typename binary_traits<Operation>::function_type op; + typename binary_traits<Operation>::first_argument_type value; + }; + + template <class Operation> + inline binder1st<Operation> bind1st(const Operation &op, + typename call_traits< + typename binary_traits<Operation>::first_argument_type + >::param_type x) + { + // The cast is to placate Borland C++Builder in certain circumstances. + // I don't think it should be necessary. + return binder1st<Operation>((typename binary_traits<Operation>::param_type)op, x); + } + + template <class Operation> + inline binder1st<Operation> bind1st(Operation &op, + typename call_traits< + typename binary_traits<Operation>::first_argument_type + >::param_type x) + { + return binder1st<Operation>(op, x); + } + + // -------------------------------------------------------------------------- + // binder2nd, bind2nd + // -------------------------------------------------------------------------- + template <class Operation> + class binder2nd + : public boost::functional::detail::unary_function< + typename binary_traits<Operation>::first_argument_type, + typename binary_traits<Operation>::result_type> + { + public: + binder2nd(typename binary_traits<Operation>::param_type x, + typename call_traits<typename binary_traits<Operation>::second_argument_type>::param_type y) + : + op(x), value(y) + {} + + typename binary_traits<Operation>::result_type + operator()(typename call_traits<typename binary_traits<Operation>::first_argument_type>::param_type x) const + { + return op(x, value); + } + + protected: + typename binary_traits<Operation>::function_type op; + typename binary_traits<Operation>::second_argument_type value; + }; + + template <class Operation> + inline binder2nd<Operation> bind2nd(const Operation &op, + typename call_traits< + typename binary_traits<Operation>::second_argument_type + >::param_type x) + { + // The cast is to placate Borland C++Builder in certain circumstances. + // I don't think it should be necessary. + return binder2nd<Operation>((typename binary_traits<Operation>::param_type)op, x); + } + + template <class Operation> + inline binder2nd<Operation> bind2nd(Operation &op, + typename call_traits< + typename binary_traits<Operation>::second_argument_type + >::param_type x) + { + return binder2nd<Operation>(op, x); + } + + // -------------------------------------------------------------------------- + // mem_fun, etc + // -------------------------------------------------------------------------- + template <class S, class T> + class mem_fun_t : public boost::functional::detail::unary_function<T*, S> + { + public: + explicit mem_fun_t(S (T::*p)()) + : + ptr(p) + {} + S operator()(T* p) const + { + return (p->*ptr)(); + } + private: + S (T::*ptr)(); + }; + + template <class S, class T, class A> + class mem_fun1_t : public boost::functional::detail::binary_function<T*, A, S> + { + public: + explicit mem_fun1_t(S (T::*p)(A)) + : + ptr(p) + {} + S operator()(T* p, typename call_traits<A>::param_type x) const + { + return (p->*ptr)(x); + } + private: + S (T::*ptr)(A); + }; + + template <class S, class T> + class const_mem_fun_t : public boost::functional::detail::unary_function<const T*, S> + { + public: + explicit const_mem_fun_t(S (T::*p)() const) + : + ptr(p) + {} + S operator()(const T* p) const + { + return (p->*ptr)(); + } + private: + S (T::*ptr)() const; + }; + + template <class S, class T, class A> + class const_mem_fun1_t : public boost::functional::detail::binary_function<const T*, A, S> + { + public: + explicit const_mem_fun1_t(S (T::*p)(A) const) + : + ptr(p) + {} + S operator()(const T* p, typename call_traits<A>::param_type x) const + { + return (p->*ptr)(x); + } + private: + S (T::*ptr)(A) const; + }; + + template<class S, class T> + inline mem_fun_t<S,T> mem_fun(S (T::*f)()) + { + return mem_fun_t<S,T>(f); + } + + template<class S, class T, class A> + inline mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A)) + { + return mem_fun1_t<S,T,A>(f); + } + +#ifndef BOOST_NO_POINTER_TO_MEMBER_CONST + template<class S, class T> + inline const_mem_fun_t<S,T> mem_fun(S (T::*f)() const) + { + return const_mem_fun_t<S,T>(f); + } + + template<class S, class T, class A> + inline const_mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A) const) + { + return const_mem_fun1_t<S,T,A>(f); + } +#endif // BOOST_NO_POINTER_TO_MEMBER_CONST + + // -------------------------------------------------------------------------- + // mem_fun_ref, etc + // -------------------------------------------------------------------------- + template <class S, class T> + class mem_fun_ref_t : public boost::functional::detail::unary_function<T&, S> + { + public: + explicit mem_fun_ref_t(S (T::*p)()) + : + ptr(p) + {} + S operator()(T& p) const + { + return (p.*ptr)(); + } + private: + S (T::*ptr)(); + }; + + template <class S, class T, class A> + class mem_fun1_ref_t : public boost::functional::detail::binary_function<T&, A, S> + { + public: + explicit mem_fun1_ref_t(S (T::*p)(A)) + : + ptr(p) + {} + S operator()(T& p, typename call_traits<A>::param_type x) const + { + return (p.*ptr)(x); + } + private: + S (T::*ptr)(A); + }; + + template <class S, class T> + class const_mem_fun_ref_t : public boost::functional::detail::unary_function<const T&, S> + { + public: + explicit const_mem_fun_ref_t(S (T::*p)() const) + : + ptr(p) + {} + + S operator()(const T &p) const + { + return (p.*ptr)(); + } + private: + S (T::*ptr)() const; + }; + + template <class S, class T, class A> + class const_mem_fun1_ref_t : public boost::functional::detail::binary_function<const T&, A, S> + { + public: + explicit const_mem_fun1_ref_t(S (T::*p)(A) const) + : + ptr(p) + {} + + S operator()(const T& p, typename call_traits<A>::param_type x) const + { + return (p.*ptr)(x); + } + private: + S (T::*ptr)(A) const; + }; + + template<class S, class T> + inline mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)()) + { + return mem_fun_ref_t<S,T>(f); + } + + template<class S, class T, class A> + inline mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A)) + { + return mem_fun1_ref_t<S,T,A>(f); + } + +#ifndef BOOST_NO_POINTER_TO_MEMBER_CONST + template<class S, class T> + inline const_mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)() const) + { + return const_mem_fun_ref_t<S,T>(f); + } + + template<class S, class T, class A> + inline const_mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A) const) + { + return const_mem_fun1_ref_t<S,T,A>(f); + } +#endif // BOOST_NO_POINTER_TO_MEMBER_CONST + + // -------------------------------------------------------------------------- + // ptr_fun + // -------------------------------------------------------------------------- + template <class Arg, class Result> + class pointer_to_unary_function : public boost::functional::detail::unary_function<Arg,Result> + { + public: + explicit pointer_to_unary_function(Result (*f)(Arg)) + : + func(f) + {} + + Result operator()(typename call_traits<Arg>::param_type x) const + { + return func(x); + } + + private: + Result (*func)(Arg); + }; + + template <class Arg, class Result> + inline pointer_to_unary_function<Arg,Result> ptr_fun(Result (*f)(Arg)) + { + return pointer_to_unary_function<Arg,Result>(f); + } + + template <class Arg1, class Arg2, class Result> + class pointer_to_binary_function : public boost::functional::detail::binary_function<Arg1,Arg2,Result> + { + public: + explicit pointer_to_binary_function(Result (*f)(Arg1, Arg2)) + : + func(f) + {} + + Result operator()(typename call_traits<Arg1>::param_type x, typename call_traits<Arg2>::param_type y) const + { + return func(x,y); + } + + private: + Result (*func)(Arg1, Arg2); + }; + + template <class Arg1, class Arg2, class Result> + inline pointer_to_binary_function<Arg1,Arg2,Result> ptr_fun(Result (*f)(Arg1, Arg2)) + { + return pointer_to_binary_function<Arg1,Arg2,Result>(f); + } +} // namespace boost + +#endif diff --git a/ThirdParty/boost/multi_array.hpp b/ThirdParty/boost/multi_array.hpp new file mode 100644 index 0000000000000000000000000000000000000000..c9ed215bbd0978941b823669fa904612159d4772 --- /dev/null +++ b/ThirdParty/boost/multi_array.hpp @@ -0,0 +1,572 @@ +// Copyright 2002 The Trustees of Indiana University. + +// Copyright 2018 Glen Joseph Fernandes +// (glenjofe@gmail.com) + +// 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_HPP +#define BOOST_MULTI_ARRAY_HPP + +// +// multi_array.hpp - contains the multi_array class template +// declaration and definition +// + +#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 406) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#include "boost/multi_array/base.hpp" +#include "boost/multi_array/collection_concept.hpp" +#include "boost/multi_array/copy_array.hpp" +#include "boost/multi_array/iterator.hpp" +#include "boost/multi_array/subarray.hpp" +#include "boost/multi_array/multi_array_ref.hpp" +#include "boost/multi_array/algorithm.hpp" +#include "boost/core/alloc_construct.hpp" +#include "boost/core/empty_value.hpp" +#include "boost/array.hpp" +#include "boost/mpl/if.hpp" +#include "boost/type_traits.hpp" +#include <algorithm> +#include <cstddef> +#include <functional> +#include <numeric> +#include <vector> + + + +namespace boost { + namespace detail { + namespace multi_array { + + struct populate_index_ranges { + multi_array_types::index_range + // RG: underscore on extent_ to stifle strange MSVC warning. + operator()(multi_array_types::index base, + multi_array_types::size_type extent_) { + return multi_array_types::index_range(base,base+extent_); + } + }; + +#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING +// +// Compilers that don't support partial ordering may need help to +// disambiguate multi_array's templated constructors. Even vc6/7 are +// capable of some limited SFINAE, so we take the most-general version +// out of the overload set with disable_multi_array_impl. +// +template <typename T, std::size_t NumDims, typename TPtr> +char is_multi_array_impl_help(const_multi_array_view<T,NumDims,TPtr>&); +template <typename T, std::size_t NumDims, typename TPtr> +char is_multi_array_impl_help(const_sub_array<T,NumDims,TPtr>&); +template <typename T, std::size_t NumDims, typename TPtr> +char is_multi_array_impl_help(const_multi_array_ref<T,NumDims,TPtr>&); + +char ( &is_multi_array_impl_help(...) )[2]; + +template <class T> +struct is_multi_array_impl +{ + static T x; + BOOST_STATIC_CONSTANT(bool, value = sizeof((is_multi_array_impl_help)(x)) == 1); + + typedef mpl::bool_<value> type; +}; + +template <bool multi_array = false> +struct disable_multi_array_impl_impl +{ + typedef int type; +}; + +template <> +struct disable_multi_array_impl_impl<true> +{ + // forming a pointer to a reference triggers SFINAE + typedef int& type; +}; + + +template <class T> +struct disable_multi_array_impl : + disable_multi_array_impl_impl<is_multi_array_impl<T>::value> +{ }; + + +template <> +struct disable_multi_array_impl<int> +{ + typedef int type; +}; + + +#endif + + } //namespace multi_array + } // namespace detail + +template<typename T, std::size_t NumDims, + typename Allocator> +class multi_array : + public multi_array_ref<T,NumDims>, + private boost::empty_value<Allocator> +{ + typedef boost::empty_value<Allocator> alloc_base; + typedef multi_array_ref<T,NumDims> super_type; +public: + typedef typename super_type::value_type value_type; + typedef typename super_type::reference reference; + typedef typename super_type::const_reference const_reference; + typedef typename super_type::iterator iterator; + typedef typename super_type::const_iterator const_iterator; + typedef typename super_type::reverse_iterator reverse_iterator; + typedef typename super_type::const_reverse_iterator const_reverse_iterator; + typedef typename super_type::element element; + typedef typename super_type::size_type size_type; + typedef typename super_type::difference_type difference_type; + typedef typename super_type::index index; + typedef typename super_type::extent_range extent_range; + + + template <std::size_t NDims> + struct const_array_view { + typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type; + }; + + template <std::size_t NDims> + struct array_view { + typedef boost::detail::multi_array::multi_array_view<T,NDims> type; + }; + + explicit multi_array(const Allocator& alloc = Allocator()) : + super_type((T*)initial_base_,c_storage_order(), + /*index_bases=*/0, /*extents=*/0), + alloc_base(boost::empty_init_t(),alloc) { + allocate_space(); + } + + template <class ExtentList> + explicit multi_array( + ExtentList const& extents, + const Allocator& alloc = Allocator() +#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + , typename mpl::if_< + detail::multi_array::is_multi_array_impl<ExtentList>, + int&,int>::type* = 0 +#endif + ) : + super_type((T*)initial_base_,extents), + alloc_base(boost::empty_init_t(),alloc) { + boost::function_requires< + detail::multi_array::CollectionConcept<ExtentList> >(); + allocate_space(); + } + + + template <class ExtentList> + explicit multi_array(ExtentList const& extents, + const general_storage_order<NumDims>& so) : + super_type((T*)initial_base_,extents,so), + alloc_base(boost::empty_init_t()) { + boost::function_requires< + detail::multi_array::CollectionConcept<ExtentList> >(); + allocate_space(); + } + + template <class ExtentList> + explicit multi_array(ExtentList const& extents, + const general_storage_order<NumDims>& so, + Allocator const& alloc) : + super_type((T*)initial_base_,extents,so), + alloc_base(boost::empty_init_t(),alloc) { + boost::function_requires< + detail::multi_array::CollectionConcept<ExtentList> >(); + allocate_space(); + } + + + explicit multi_array(const detail::multi_array + ::extent_gen<NumDims>& ranges, + const Allocator& alloc = Allocator()) : + super_type((T*)initial_base_,ranges), + alloc_base(boost::empty_init_t(),alloc) { + + allocate_space(); + } + + + explicit multi_array(const detail::multi_array + ::extent_gen<NumDims>& ranges, + const general_storage_order<NumDims>& so) : + super_type((T*)initial_base_,ranges,so), + alloc_base(boost::empty_init_t()) { + + allocate_space(); + } + + + explicit multi_array(const detail::multi_array + ::extent_gen<NumDims>& ranges, + const general_storage_order<NumDims>& so, + Allocator const& alloc) : + super_type((T*)initial_base_,ranges,so), + alloc_base(boost::empty_init_t(),alloc) { + + allocate_space(); + } + + multi_array(const multi_array& rhs) : + super_type(rhs), + alloc_base(static_cast<const alloc_base&>(rhs)) { + allocate_space(); + boost::detail::multi_array::copy_n(rhs.base_,rhs.num_elements(),base_); + } + + + // + // A multi_array is constructible from any multi_array_ref, subarray, or + // array_view object. The following constructors ensure that. + // + + // Due to limited support for partial template ordering, + // MSVC 6&7 confuse the following with the most basic ExtentList + // constructor. +#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + template <typename OPtr> + multi_array(const const_multi_array_ref<T,NumDims,OPtr>& rhs, + const general_storage_order<NumDims>& so = c_storage_order(), + const Allocator& alloc = Allocator()) + : super_type(0,so,rhs.index_bases(),rhs.shape()), + alloc_base(boost::empty_init_t(),alloc) + { + allocate_space(); + // Warning! storage order may change, hence the following copy technique. + std::copy(rhs.begin(),rhs.end(),this->begin()); + } + + template <typename OPtr> + multi_array(const detail::multi_array:: + const_sub_array<T,NumDims,OPtr>& rhs, + const general_storage_order<NumDims>& so = c_storage_order(), + const Allocator& alloc = Allocator()) + : super_type(0,so,rhs.index_bases(),rhs.shape()), + alloc_base(boost::empty_init_t(),alloc) + { + allocate_space(); + std::copy(rhs.begin(),rhs.end(),this->begin()); + } + + + template <typename OPtr> + multi_array(const detail::multi_array:: + const_multi_array_view<T,NumDims,OPtr>& rhs, + const general_storage_order<NumDims>& so = c_storage_order(), + const Allocator& alloc = Allocator()) + : super_type(0,so,rhs.index_bases(),rhs.shape()), + alloc_base(boost::empty_init_t(),alloc) + { + allocate_space(); + std::copy(rhs.begin(),rhs.end(),this->begin()); + } + +#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING + // More limited support for MSVC + + + multi_array(const const_multi_array_ref<T,NumDims>& rhs, + const Allocator& alloc = Allocator()) + : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape()), + alloc_base(boost::empty_init_t(),alloc) + { + allocate_space(); + // Warning! storage order may change, hence the following copy technique. + std::copy(rhs.begin(),rhs.end(),this->begin()); + } + + multi_array(const const_multi_array_ref<T,NumDims>& rhs, + const general_storage_order<NumDims>& so, + const Allocator& alloc = Allocator()) + : super_type(0,so,rhs.index_bases(),rhs.shape()), + alloc_base(boost::empty_init_t(),alloc) + { + allocate_space(); + // Warning! storage order may change, hence the following copy technique. + std::copy(rhs.begin(),rhs.end(),this->begin()); + } + + multi_array(const detail::multi_array:: + const_sub_array<T,NumDims>& rhs, + const Allocator& alloc = Allocator()) + : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape()), + alloc_base(boost::empty_init_t(),alloc) + { + allocate_space(); + std::copy(rhs.begin(),rhs.end(),this->begin()); + } + + multi_array(const detail::multi_array:: + const_sub_array<T,NumDims>& rhs, + const general_storage_order<NumDims>& so, + const Allocator& alloc = Allocator()) + : super_type(0,so,rhs.index_bases(),rhs.shape()), + alloc_base(boost::empty_init_t(),alloc) + { + allocate_space(); + std::copy(rhs.begin(),rhs.end(),this->begin()); + } + + + multi_array(const detail::multi_array:: + const_multi_array_view<T,NumDims>& rhs, + const Allocator& alloc = Allocator()) + : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape()), + alloc_base(boost::empty_init_t(),alloc) + { + allocate_space(); + std::copy(rhs.begin(),rhs.end(),this->begin()); + } + + multi_array(const detail::multi_array:: + const_multi_array_view<T,NumDims>& rhs, + const general_storage_order<NumDims>& so, + const Allocator& alloc = Allocator()) + : super_type(0,so,rhs.index_bases(),rhs.shape()), + alloc_base(boost::empty_init_t(),alloc) + { + allocate_space(); + std::copy(rhs.begin(),rhs.end(),this->begin()); + } + +#endif // !BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + // Thes constructors are necessary because of more exact template matches. + multi_array(const multi_array_ref<T,NumDims>& rhs, + const Allocator& alloc = Allocator()) + : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape()), + alloc_base(boost::empty_init_t(),alloc) + { + allocate_space(); + // Warning! storage order may change, hence the following copy technique. + std::copy(rhs.begin(),rhs.end(),this->begin()); + } + + multi_array(const multi_array_ref<T,NumDims>& rhs, + const general_storage_order<NumDims>& so, + const Allocator& alloc = Allocator()) + : super_type(0,so,rhs.index_bases(),rhs.shape()), + alloc_base(boost::empty_init_t(),alloc) + { + allocate_space(); + // Warning! storage order may change, hence the following copy technique. + std::copy(rhs.begin(),rhs.end(),this->begin()); + } + + + multi_array(const detail::multi_array:: + sub_array<T,NumDims>& rhs, + const Allocator& alloc = Allocator()) + : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape()), + alloc_base(boost::empty_init_t(),alloc) + { + allocate_space(); + std::copy(rhs.begin(),rhs.end(),this->begin()); + } + + multi_array(const detail::multi_array:: + sub_array<T,NumDims>& rhs, + const general_storage_order<NumDims>& so, + const Allocator& alloc = Allocator()) + : super_type(0,so,rhs.index_bases(),rhs.shape()), + alloc_base(boost::empty_init_t(),alloc) + { + allocate_space(); + std::copy(rhs.begin(),rhs.end(),this->begin()); + } + + + multi_array(const detail::multi_array:: + multi_array_view<T,NumDims>& rhs, + const Allocator& alloc = Allocator()) + : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape()), + alloc_base(boost::empty_init_t(),alloc) + { + allocate_space(); + std::copy(rhs.begin(),rhs.end(),this->begin()); + } + + multi_array(const detail::multi_array:: + multi_array_view<T,NumDims>& rhs, + const general_storage_order<NumDims>& so, + const Allocator& alloc = Allocator()) + : super_type(0,so,rhs.index_bases(),rhs.shape()), + alloc_base(boost::empty_init_t(),alloc) + { + allocate_space(); + std::copy(rhs.begin(),rhs.end(),this->begin()); + } + + // Since assignment is a deep copy, multi_array_ref + // contains all the necessary code. + template <typename ConstMultiArray> + multi_array& operator=(const ConstMultiArray& other) { + super_type::operator=(other); + return *this; + } + + multi_array& operator=(const multi_array& other) { + if (&other != this) { + super_type::operator=(other); + } + return *this; + } + + + template <typename ExtentList> + multi_array& resize(const ExtentList& extents) { + boost::function_requires< + detail::multi_array::CollectionConcept<ExtentList> >(); + + typedef detail::multi_array::extent_gen<NumDims> gen_type; + gen_type ranges; + + for (int i=0; i != NumDims; ++i) { + typedef typename gen_type::range range_type; + ranges.ranges_[i] = range_type(0,extents[i]); + } + + return this->resize(ranges); + } + + + + multi_array& resize(const detail::multi_array + ::extent_gen<NumDims>& ranges) { + + + // build a multi_array with the specs given + multi_array new_array(ranges,this->storage_order(),allocator()); + + + // build a view of tmp with the minimum extents + + // Get the minimum extents of the arrays. + boost::array<size_type,NumDims> min_extents; + + const size_type& (*min)(const size_type&, const size_type&) = + std::min; + std::transform(new_array.extent_list_.begin(),new_array.extent_list_.end(), + this->extent_list_.begin(), + min_extents.begin(), + min); + + + // typedef boost::array<index,NumDims> index_list; + // Build index_gen objects to create views with the same shape + + // these need to be separate to handle non-zero index bases + typedef detail::multi_array::index_gen<NumDims,NumDims> index_gen; + index_gen old_idxes; + index_gen new_idxes; + + std::transform(new_array.index_base_list_.begin(), + new_array.index_base_list_.end(), + min_extents.begin(),new_idxes.ranges_.begin(), + detail::multi_array::populate_index_ranges()); + + std::transform(this->index_base_list_.begin(), + this->index_base_list_.end(), + min_extents.begin(),old_idxes.ranges_.begin(), + detail::multi_array::populate_index_ranges()); + + // Build same-shape views of the two arrays + typename + multi_array::BOOST_NESTED_TEMPLATE array_view<NumDims>::type view_old = (*this)[old_idxes]; + typename + multi_array::BOOST_NESTED_TEMPLATE array_view<NumDims>::type view_new = new_array[new_idxes]; + + // Set the right portion of the new array + view_new = view_old; + + using std::swap; + // Swap the internals of these arrays. + swap(this->super_type::base_,new_array.super_type::base_); + swap(this->allocator(),new_array.allocator()); + swap(this->storage_,new_array.storage_); + swap(this->extent_list_,new_array.extent_list_); + swap(this->stride_list_,new_array.stride_list_); + swap(this->index_base_list_,new_array.index_base_list_); + swap(this->origin_offset_,new_array.origin_offset_); + swap(this->directional_offset_,new_array.directional_offset_); + swap(this->num_elements_,new_array.num_elements_); + swap(this->base_,new_array.base_); + swap(this->allocated_elements_,new_array.allocated_elements_); + + return *this; + } + + + ~multi_array() { + deallocate_space(); + } + +private: + friend inline bool operator==(const multi_array& a, const multi_array& b) { + return a.base() == b.base(); + } + + friend inline bool operator!=(const multi_array& a, const multi_array& b) { + return !(a == b); + } + + const super_type& base() const { + return *this; + } + + const Allocator& allocator() const { + return alloc_base::get(); + } + + Allocator& allocator() { + return alloc_base::get(); + } + + void allocate_space() { + base_ = allocator().allocate(this->num_elements()); + this->set_base_ptr(base_); + allocated_elements_ = this->num_elements(); + boost::alloc_construct_n(allocator(),base_,allocated_elements_); + } + + void deallocate_space() { + if(base_) { + boost::alloc_destroy_n(allocator(),base_,allocated_elements_); + allocator().deallocate(base_,allocated_elements_); + } + } + + typedef boost::array<size_type,NumDims> size_list; + typedef boost::array<index,NumDims> index_list; + + T* base_; + size_type allocated_elements_; + enum {initial_base_ = 0}; +}; + +} // namespace boost + +#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 406) +# pragma GCC diagnostic pop +#endif + +#endif diff --git a/ThirdParty/boost/multi_array/algorithm.hpp b/ThirdParty/boost/multi_array/algorithm.hpp new file mode 100644 index 0000000000000000000000000000000000000000..01ac70fdb2591f0f697cbf3412a5e5b46ba623eb --- /dev/null +++ b/ThirdParty/boost/multi_array/algorithm.hpp @@ -0,0 +1,103 @@ +#ifndef BOOST_MULTI_ARRAY_ALGORITHM_HPP +#define BOOST_MULTI_ARRAY_ALGORITHM_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 <iterator> + +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 diff --git a/ThirdParty/boost/multi_array/base.hpp b/ThirdParty/boost/multi_array/base.hpp new file mode 100644 index 0000000000000000000000000000000000000000..4e621e15353fa8a588b0d601e8942008a36f3cab --- /dev/null +++ b/ThirdParty/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 BOOST_MULTI_ARRAY_BASE_HPP +#define BOOST_MULTI_ARRAY_BASE_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 diff --git a/ThirdParty/boost/multi_array/collection_concept.hpp b/ThirdParty/boost/multi_array/collection_concept.hpp new file mode 100644 index 0000000000000000000000000000000000000000..bad1d6f0514e5e0df54c4ca2b782a32fd4321269 --- /dev/null +++ b/ThirdParty/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 BOOST_MULTI_ARRAY_COLLECTION_CONCEPT_HPP +#define BOOST_MULTI_ARRAY_COLLECTION_CONCEPT_HPP + +#include "boost/concept_check.hpp" + +namespace boost { +namespace detail { +namespace multi_array { // Old location for this + using boost::CollectionConcept; +} +} + +} +#endif diff --git a/ThirdParty/boost/multi_array/concept_checks.hpp b/ThirdParty/boost/multi_array/concept_checks.hpp new file mode 100644 index 0000000000000000000000000000000000000000..4df71bcd13e61d8f03bf24e6f088ace675167f1e --- /dev/null +++ b/ThirdParty/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_HPP +#define BOOST_MULTI_ARRAY_CONCEPT_CHECKS_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 diff --git a/ThirdParty/boost/multi_array/copy_array.hpp b/ThirdParty/boost/multi_array/copy_array.hpp new file mode 100644 index 0000000000000000000000000000000000000000..a448d58bba4a03c1d6cef2203c5de92f0fd7a8b6 --- /dev/null +++ b/ThirdParty/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 BOOST_MULTI_ARRAY_COPY_ARRAY_HPP +#define BOOST_MULTI_ARRAY_COPY_ARRAY_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 diff --git a/ThirdParty/boost/multi_array/extent_gen.hpp b/ThirdParty/boost/multi_array/extent_gen.hpp new file mode 100644 index 0000000000000000000000000000000000000000..898b11705c5c3b86b9c62f2a7dd0c13446c375bd --- /dev/null +++ b/ThirdParty/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_MULTI_ARRAY_EXTENT_GEN_HPP +#define BOOST_MULTI_ARRAY_EXTENT_GEN_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 diff --git a/ThirdParty/boost/multi_array/extent_range.hpp b/ThirdParty/boost/multi_array/extent_range.hpp new file mode 100644 index 0000000000000000000000000000000000000000..1ee77438ed8e661169ce70a9f263124e0d3e8b27 --- /dev/null +++ b/ThirdParty/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_MULTI_ARRAY_EXTENT_RANGE_HPP +#define BOOST_MULTI_ARRAY_EXTENT_RANGE_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 diff --git a/ThirdParty/boost/multi_array/index_gen.hpp b/ThirdParty/boost/multi_array/index_gen.hpp new file mode 100644 index 0000000000000000000000000000000000000000..a4fdaced7ad8ccd9c5579daebf46ec6427ca3ae9 --- /dev/null +++ b/ThirdParty/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_MULTI_ARRAY_INDEX_GEN_HPP +#define BOOST_MULTI_ARRAY_INDEX_GEN_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 diff --git a/ThirdParty/boost/multi_array/index_range.hpp b/ThirdParty/boost/multi_array/index_range.hpp new file mode 100644 index 0000000000000000000000000000000000000000..fcb7c2e632fbab1a921fd037c924e4c5eff1b393 --- /dev/null +++ b/ThirdParty/boost/multi_array/index_range.hpp @@ -0,0 +1,194 @@ +// 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_INDEX_RANGE_HPP +#define BOOST_MULTI_ARRAY_INDEX_RANGE_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_; } + + size_type size(index idx) const + { + return (start_ == from_start() || finish_ == to_end()) + ? idx : ((finish_ - start_) / 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 diff --git a/ThirdParty/boost/multi_array/iterator.hpp b/ThirdParty/boost/multi_array/iterator.hpp new file mode 100644 index 0000000000000000000000000000000000000000..ec5e61ce6c7b6ebe1499bcd4ef3e93c03334a4b5 --- /dev/null +++ b/ThirdParty/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 BOOST_MULTI_ARRAY_ITERATOR_HPP +#define BOOST_MULTI_ARRAY_ITERATOR_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 diff --git a/ThirdParty/boost/multi_array/multi_array_ref.hpp b/ThirdParty/boost/multi_array/multi_array_ref.hpp new file mode 100644 index 0000000000000000000000000000000000000000..98c10c0f40ed795c842a335ba051818bcb4a1a0b --- /dev/null +++ b/ThirdParty/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_MULTI_ARRAY_REF_HPP +#define BOOST_MULTI_ARRAY_MULTI_ARRAY_REF_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 diff --git a/ThirdParty/boost/multi_array/range_list.hpp b/ThirdParty/boost/multi_array/range_list.hpp new file mode 100644 index 0000000000000000000000000000000000000000..46a65cb15365c5544d547de8fd13afdc5fd470b9 --- /dev/null +++ b/ThirdParty/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 BOOST_MULTI_ARRAY_RANGE_LIST_HPP +#define BOOST_MULTI_ARRAY_RANGE_LIST_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 diff --git a/ThirdParty/boost/multi_array/storage_order.hpp b/ThirdParty/boost/multi_array/storage_order.hpp new file mode 100644 index 0000000000000000000000000000000000000000..5ede677e97101ee3429dbe6eea6a6b4e9356a8d3 --- /dev/null +++ b/ThirdParty/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_MULTI_ARRAY_STORAGE_ORDER_HPP +#define BOOST_MULTI_ARRAY_STORAGE_ORDER_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 diff --git a/ThirdParty/boost/multi_array/subarray.hpp b/ThirdParty/boost/multi_array/subarray.hpp new file mode 100644 index 0000000000000000000000000000000000000000..2cb30d7076c7ffe694beefb8981bddc0b89f278d --- /dev/null +++ b/ThirdParty/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 BOOST_MULTI_ARRAY_SUBARRAY_HPP +#define BOOST_MULTI_ARRAY_SUBARRAY_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 diff --git a/ThirdParty/boost/multi_array/types.hpp b/ThirdParty/boost/multi_array/types.hpp new file mode 100644 index 0000000000000000000000000000000000000000..cdb9e4f9c52c5255cd4b31ccbe4ff93dfcca69b3 --- /dev/null +++ b/ThirdParty/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_HPP +#define BOOST_MULTI_ARRAY_TYPES_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 diff --git a/ThirdParty/boost/multi_array/view.hpp b/ThirdParty/boost/multi_array/view.hpp new file mode 100644 index 0000000000000000000000000000000000000000..e6379118576d44f4d2b38009d071b4a1749eea44 --- /dev/null +++ b/ThirdParty/boost/multi_array/view.hpp @@ -0,0 +1,460 @@ +// 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_HPP +#define BOOST_MULTI_ARRAY_VIEW_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