10#ifndef XTENSOR_VIEW_HPP 
   11#define XTENSOR_VIEW_HPP 
   20#include <xtl/xclosure.hpp> 
   21#include <xtl/xmeta_utils.hpp> 
   22#include <xtl/xsequence.hpp> 
   23#include <xtl/xtype_traits.hpp> 
   25#include "../containers/xarray.hpp" 
   26#include "../containers/xcontainer.hpp" 
   27#include "../containers/xtensor.hpp" 
   28#include "../core/xaccessible.hpp" 
   29#include "../core/xiterable.hpp" 
   30#include "../core/xsemantic.hpp" 
   31#include "../core/xtensor_config.hpp" 
   32#include "../core/xtensor_forward.hpp" 
   33#include "../views/xbroadcast.hpp" 
   34#include "../views/xslice.hpp" 
   35#include "../views/xview_utils.hpp" 
   46        template <
class Tag, 
class CT, 
class... S>
 
   49        template <
class CT, 
class... S>
 
   55        template <
class CT, 
class... S>
 
   60        template <
class CT, 
class... S>
 
   61        using xview_base_t = 
typename xview_base<CT, S...>::type;
 
   68    template <
bool is_const, 
class CT, 
class... S>
 
   71    template <
class ST, 
class... S>
 
   78        struct is_xrange : std::false_type
 
   83        struct is_xrange<xrange<T>> : std::true_type
 
   88        struct is_xall_slice : std::false_type
 
   93        struct is_xall_slice<xall<T>> : std::true_type
 
   97        template <layout_type L, 
bool val
id, 
bool all_seen, 
bool range_seen, 
class V>
 
   98        struct is_contiguous_view_impl
 
  100            static constexpr bool value = 
false;
 
  104        struct static_dimension
 
  106            static constexpr std::ptrdiff_t value = -1;
 
  109        template <
class T, std::
size_t N>
 
  110        struct static_dimension<std::array<T, N>>
 
  112            static constexpr std::ptrdiff_t value = 
static_cast<std::ptrdiff_t
>(N);
 
  115        template <
class T, std::
size_t N>
 
  116        struct static_dimension<xt::const_array<T, N>>
 
  118            static constexpr std::ptrdiff_t value = 
static_cast<std::ptrdiff_t
>(N);
 
  121        template <std::size_t... I>
 
  122        struct static_dimension<xt::fixed_shape<I...>>
 
  124            static constexpr std::ptrdiff_t value = 
sizeof...(I);
 
  129        template <
class CT, 
class... S>
 
  130        struct is_xscalar_impl<xview<CT, S...>>
 
  132            static constexpr bool value = 
static_cast<std::ptrdiff_t
>(integral_count<S...>()
 
  133                                          ) == static_dimension<
typename std::decay_t<CT>::shape_type>::value
 
  139        struct is_strided_slice_impl : std::true_type
 
  144        struct is_strided_slice_impl<xkeep_slice<T>> : std::false_type
 
  149        struct is_strided_slice_impl<xdrop_slice<T>> : std::false_type
 
  154        template <
class E, 
class... S>
 
  155        struct is_strided_view
 
  156            : std::integral_constant<
 
  158                  std::conjunction<has_data_interface<E>, is_strided_slice_impl<std::decay_t<S>>...>::value>
 
  172        template <
bool val
id, 
bool all_seen, 
bool range_seen, 
class V>
 
  175            using slice = xtl::mpl::front_t<V>;
 
  176            static constexpr bool is_range_slice = is_xrange<slice>::value;
 
  177            static constexpr bool is_int_slice = xtl::is_integral<slice>::value;
 
  178            static constexpr bool is_all_slice = is_xall_slice<slice>::value;
 
  179            static constexpr bool have_all_seen = all_seen || is_all_slice;
 
  180            static constexpr bool have_range_seen = is_range_slice;
 
  182            static constexpr bool is_valid = valid
 
  185                                                     : (!range_seen && (is_int_slice || is_range_slice)));
 
  188                                  have_all_seen, range_seen || is_range_slice,
 
  189                                  xtl::mpl::pop_front_t < V >> ::value;
 
  192        template <
bool val
id, 
bool all_seen, 
bool range_seen>
 
  193        struct is_contiguous_view_impl<
layout_type::
row_major, valid, all_seen, range_seen, xtl::mpl::vector<>>
 
  195            static constexpr bool value = valid;
 
  201        template <
bool val
id, 
bool int_seen, 
bool range_seen, 
class V>
 
  204            using slice = xtl::mpl::front_t<V>;
 
  205            static constexpr bool is_range_slice = is_xrange<slice>::value;
 
  206            static constexpr bool is_int_slice = xtl::is_integral<slice>::value;
 
  207            static constexpr bool is_all_slice = is_xall_slice<slice>::value;
 
  209            static constexpr bool have_int_seen = int_seen || is_int_slice;
 
  211            static constexpr bool is_valid = valid
 
  214                                                     : (!range_seen && (is_all_slice || is_range_slice)));
 
  216                                  have_int_seen, is_range_slice || range_seen,
 
  217                                  xtl::mpl::pop_front_t < V >> ::value;
 
  220        template <
bool val
id, 
bool int_seen, 
bool range_seen>
 
  223            static constexpr bool value = valid;
 
  227        template <
class E, 
class... S>
 
  228        struct is_contiguous_view
 
  229            : std::integral_constant<
 
  231                  has_data_interface<E>::value
 
  233                          E::static_layout == layout_type::column_major
 
  234                          && static_cast<std::size_t>(static_dimension<typename E::shape_type>::value) != sizeof...(S)
 
  236                      && is_contiguous_view_impl<E::static_layout, true, false, false, xtl::mpl::vector<S...>>::value>
 
  240        template <layout_type L, 
class T, std::ptrdiff_t offset>
 
  241        struct unwrap_offset_container
 
  246        template <
class T, std::ptrdiff_t offset>
 
  249            using type = sequence_view<T, offset, static_dimension<T>::value>;
 
  252        template <
class T, std::ptrdiff_t start, std::ptrdiff_t end, std::ptrdiff_t offset>
 
  255            using type = sequence_view<T, start + offset, end>;
 
  258        template <
class T, std::ptrdiff_t offset>
 
  261            using type = sequence_view<T, 0, static_dimension<T>::value - offset>;
 
  264        template <
class T, std::ptrdiff_t start, std::ptrdiff_t end, std::ptrdiff_t offset>
 
  267            using type = sequence_view<T, start, end - offset>;
 
  270        template <
class E, 
class... S>
 
  271        struct get_contigous_shape_type
 
  274            using type = std::conditional_t<
 
  275                std::disjunction<is_xrange<S>...>::value,
 
  276                typename xview_shape_type<
typename E::shape_type, S...>::type,
 
  278                typename unwrap_offset_container<E::static_layout, 
typename E::inner_shape_type, integral_count<S...>()>::type>;
 
  282        struct is_sequence_view : std::integral_constant<bool, false>
 
  286        template <
class T, std::ptrdiff_t S, std::ptrdiff_t E>
 
  287        struct is_sequence_view<sequence_view<T, S, E>> : std::integral_constant<bool, true>
 
  292    template <
class E, 
class... S>
 
  294    template <
class E, 
class... S>
 
  297    template <
class CT, 
class... S>
 
  300        using xexpression_type = std::decay_t<CT>;
 
  301        using reference = inner_reference_t<CT>;
 
  302        using const_reference = 
typename xexpression_type::const_reference;
 
  303        using size_type = 
typename xexpression_type::size_type;
 
  304        using temporary_type = view_temporary_type_t<xexpression_type, S...>;
 
  306        static constexpr layout_type layout = detail::is_contiguous_view<xexpression_type, S...>::value
 
  307                                                  ? xexpression_type::static_layout
 
  310        static constexpr bool is_const = std::is_const<std::remove_reference_t<CT>>::value;
 
  312        using extract_storage_type = xtl::mpl::eval_if_t<
 
  314            detail::expr_storage_type<xexpression_type>,
 
  316        using storage_type = std::conditional_t<is_const, const extract_storage_type, extract_storage_type>;
 
 
  319    template <
class CT, 
class... S>
 
  322        using xexpression_type = std::decay_t<CT>;
 
  324        static constexpr bool is_strided_view = detail::is_strided_view<xexpression_type, S...>::value;
 
  325        static constexpr bool is_contiguous_view = detail::is_contiguous_view<xexpression_type, S...>::value;
 
  327        using inner_shape_type = std::conditional_t<
 
  329            typename detail::get_contigous_shape_type<xexpression_type, S...>::type,
 
  330            typename xview_shape_type<
typename xexpression_type::shape_type, S...>::type>;
 
  332        using stepper = std::conditional_t<
 
  337        using const_stepper = std::conditional_t<
 
 
  357    template <
class CT, 
class... S>
 
  358    class xview : 
public xview_semantic<xview<CT, S...>>,
 
  359                  public std::conditional_t<
 
  360                      detail::is_contiguous_view<std::decay_t<CT>, S...>::value,
 
  361                      xcontiguous_iterable<xview<CT, S...>>,
 
  362                      xiterable<xview<CT, S...>>>,
 
  363                  public xaccessible<xview<CT, S...>>,
 
  364                  public extension::xview_base_t<CT, S...>
 
  368        using self_type = 
xview<CT, S...>;
 
  370        using xexpression_type = std::decay_t<CT>;
 
  371        using semantic_base = xview_semantic<self_type>;
 
  374        using accessible_base = xaccessible<self_type>;
 
  375        using extension_base = extension::xview_base_t<CT, S...>;
 
  376        using expression_tag = 
typename extension_base::expression_tag;
 
  378        static constexpr bool is_const = std::is_const<std::remove_reference_t<CT>>::value;
 
  379        using value_type = 
typename xexpression_type::value_type;
 
  380        using simd_value_type = xt_simd::simd_type<value_type>;
 
  381        using bool_load_type = 
typename xexpression_type::bool_load_type;
 
  382        using reference = 
typename inner_types::reference;
 
  383        using const_reference = 
typename inner_types::const_reference;
 
  384        using pointer = std::
 
  385            conditional_t<is_const, typename xexpression_type::const_pointer, typename xexpression_type::pointer>;
 
  386        using const_pointer = 
typename xexpression_type::const_pointer;
 
  387        using size_type = 
typename inner_types::size_type;
 
  388        using difference_type = 
typename xexpression_type::difference_type;
 
  390        static constexpr layout_type static_layout = inner_types::layout;
 
  393        static constexpr bool is_strided_view = detail::is_strided_view<xexpression_type, S...>::value;
 
  394        static constexpr bool is_contiguous_view = contiguous_layout;
 
  397        using inner_shape_type = 
typename iterable_base::inner_shape_type;
 
  398        using shape_type = 
typename xview_shape_type<
typename xexpression_type::shape_type, S...>::type;
 
  400        using xexpression_inner_strides_type = xtl::mpl::eval_if_t<
 
  402            detail::expr_inner_strides_type<xexpression_type>,
 
  405        using xexpression_inner_backstrides_type = xtl::mpl::eval_if_t<
 
  407            detail::expr_inner_backstrides_type<xexpression_type>,
 
  410        using storage_type = 
typename inner_types::storage_type;
 
  412        static constexpr bool has_trivial_strides = is_contiguous_view
 
  413                                                    && !std::disjunction<detail::is_xrange<S>...>::value;
 
  414        using inner_strides_type = std::conditional_t<
 
  416            typename detail::unwrap_offset_container<
 
  417                xexpression_type::static_layout,
 
  418                xexpression_inner_strides_type,
 
  419                integral_count<S...>()>::type,
 
  420            get_strides_t<shape_type>>;
 
  422        using inner_backstrides_type = std::conditional_t<
 
  424            typename detail::unwrap_offset_container<
 
  425                xexpression_type::static_layout,
 
  426                xexpression_inner_backstrides_type,
 
  427                integral_count<S...>()>::type,
 
  428            get_strides_t<shape_type>>;
 
  430        using strides_type = get_strides_t<shape_type>;
 
  431        using backstrides_type = strides_type;
 
  434        using slice_type = std::tuple<S...>;
 
  436        using stepper = 
typename iterable_base::stepper;
 
  437        using const_stepper = 
typename iterable_base::const_stepper;
 
  439        using linear_iterator = std::conditional_t<
 
  441            std::conditional_t<is_const, typename xexpression_type::const_linear_iterator, typename xexpression_type::linear_iterator>,
 
  442            typename iterable_base::linear_iterator>;
 
  443        using const_linear_iterator = std::conditional_t<
 
  445            typename xexpression_type::const_linear_iterator,
 
  446            typename iterable_base::const_linear_iterator>;
 
  448        using reverse_linear_iterator = std::reverse_iterator<linear_iterator>;
 
  449        using const_reverse_linear_iterator = std::reverse_iterator<const_linear_iterator>;
 
  451        using container_iterator = pointer;
 
  452        using const_container_iterator = const_pointer;
 
  453        static constexpr std::size_t rank = SIZE_MAX;
 
  457        template <
class CTA, 
class FSL, 
class... SL>
 
  458        explicit xview(CTA&& e, FSL&& first_slice, SL&&... 
slices) 
noexcept;
 
  461        self_type& operator=(
const xview& rhs);
 
  467        disable_xexpression<E, self_type>& operator=(
const E& e);
 
  469        const inner_shape_type& 
shape() const noexcept;
 
  470        const slice_type& 
slices() const noexcept;
 
  472        bool is_contiguous() const noexcept;
 
  473        using accessible_base::
shape;
 
  478        template <class... Args>
 
  479        reference operator()(Args... args);
 
  480        template <class... Args>
 
  481        reference unchecked(Args... args);
 
  483        reference element(It first, It last);
 
  485        template <class... Args>
 
  486        const_reference operator()(Args... args) const;
 
  487        template <class... Args>
 
  488        const_reference unchecked(Args... args) const;
 
  490        const_reference element(It first, It last) const;
 
  502        stepper stepper_begin(const ST& 
shape);
 
  507        const_stepper stepper_begin(const ST& 
shape) const;
 
  511        template <class T = xexpression_type>
 
  512        storage_type& storage()
 
  515        template <class T = xexpression_type>
 
  516        const storage_type& storage() const
 
  519        template <class T = xexpression_type>
 
  520        linear_iterator linear_begin()
 
  523        template <class T = xexpression_type>
 
  524        linear_iterator linear_end()
 
  527        template <class T = xexpression_type>
 
  528        const_linear_iterator linear_begin() const
 
  531        template <class T = xexpression_type>
 
  532        const_linear_iterator linear_end() const
 
  535        template <class T = xexpression_type>
 
  536        const_linear_iterator linear_cbegin() const
 
  539        template <class T = xexpression_type>
 
  540        const_linear_iterator linear_cend() const
 
  543        template <class T = xexpression_type>
 
  544        reverse_linear_iterator linear_rbegin()
 
  547        template <class T = xexpression_type>
 
  548        reverse_linear_iterator linear_rend()
 
  551        template <class T = xexpression_type>
 
  552        const_reverse_linear_iterator linear_rbegin() const
 
  555        template <class T = xexpression_type>
 
  556        const_reverse_linear_iterator linear_rend() const
 
  559        template <class T = xexpression_type>
 
  560        const_reverse_linear_iterator linear_crbegin() const
 
  563        template <class T = xexpression_type>
 
  564        const_reverse_linear_iterator linear_crend() const
 
  567        template <class T = xexpression_type>
 
  568        const inner_strides_type& strides() const
 
  571        template <class T = xexpression_type>
 
  572        const inner_strides_type& backstrides() const
 
  575        template <class T = xexpression_type>
 
  576        const_pointer data() const
 
  579        template <class T = xexpression_type>
 
  583        template <class T = xexpression_type>
 
  588        inline It data_xbegin_impl(It begin) const noexcept;
 
  591        inline It data_xend_impl(It begin, 
layout_type l, size_type offset) const noexcept;
 
  592        inline container_iterator data_xbegin() noexcept;
 
  593        inline const_container_iterator data_xbegin() const noexcept;
 
  594        inline container_iterator data_xend(
layout_type l, size_type offset) noexcept;
 
  596        inline const_container_iterator data_xend(
layout_type l, size_type offset) const noexcept;
 
  605        template <xscalar_concept ST = self_type>
 
  606        operator const_reference()
 const 
  611        size_type underlying_size(size_type dim) 
const;
 
  613        xtl::xclosure_pointer<self_type&> operator&() &;
 
  614        xtl::xclosure_pointer<const self_type&> operator&() const&;
 
  615        xtl::xclosure_pointer<self_type> operator&() &&;
 
  617        template <class E, class T = xexpression_type>
 
  618        void assign_to(xexpression<E>& e, 
bool force_resize) const
 
  619            requires(has_data_interface_concept<T> and contiguous_view_concept<E, S...>);
 
  622        using rebind_t = 
xview<E, S...>;
 
  625        rebind_t<E> build_view(E&& e) const;
 
  631        template <class requested_type>
 
  632        using simd_return_type = xt_simd::simd_return_type<value_type, requested_type>;
 
  634        template <class align, class simd, class T = xexpression_type>
 
  635        void store_simd(size_type i, const simd& e)
 
  636            requires(has_simd_interface_concept<T> and strided_view_concept<CT, S...>);
 
  640            class requested_type = value_type,
 
  641            std::
size_t N = xt_simd::simd_traits<requested_type>::
size,
 
  642            class T = xexpression_type>
 
  643        simd_return_type<requested_type> load_simd(size_type i) const
 
  644            requires(has_simd_interface_concept<T> and strided_view_concept<CT, S...>);
 
  646        template <class T = xexpression_type>
 
  647        reference data_element(size_type i)
 
  648            requires(has_simd_interface_concept<T> and strided_view_concept<CT, S...>);
 
  650        template <class T = xexpression_type>
 
  651        const_reference data_element(size_type i) const
 
  652            requires(has_simd_interface_concept<T> and strided_view_concept<CT, S...>);
 
  654        template <class T = xexpression_type>
 
  655        reference flat(size_type i)
 
  656            requires(has_simd_interface_concept<T> and strided_view_concept<CT, S...>);
 
  658        template <class T = xexpression_type>
 
  659        const_reference flat(size_type i) const
 
  660            requires(has_simd_interface_concept<T> and strided_view_concept<CT, S...>);
 
  665        template <std::
size_t I>
 
  666        struct lesser_condition
 
  668            static constexpr bool value = (I + newaxis_count_before<S...>(I + 1) < 
sizeof...(S));
 
  673        inner_shape_type m_shape;
 
  674        mutable inner_strides_type m_strides;
 
  675        mutable inner_backstrides_type m_backstrides;
 
  676        mutable std::size_t m_data_offset;
 
  677        mutable bool m_strides_computed;
 
  679        template <
class CTA, 
class FSL, 
class... SL>
 
  680        explicit xview(std::true_type, CTA&& e, FSL&& first_slice, SL&&... 
slices) 
noexcept;
 
  682        template <
class CTA, 
class FSL, 
class... SL>
 
  683        explicit xview(std::false_type, CTA&& e, FSL&& first_slice, SL&&... 
slices) 
noexcept;
 
  685        template <
class... Args>
 
  686        auto make_index_sequence(Args... args) 
const noexcept;
 
  688        void compute_strides(std::true_type) 
const;
 
  689        void compute_strides(std::false_type) 
const;
 
  693        template <
class Arg, 
class... Args>
 
  694        reference access(Arg 
arg, Args... args);
 
  696        const_reference access() 
const;
 
  698        template <
class Arg, 
class... Args>
 
  699        const_reference access(Arg 
arg, Args... args) 
const;
 
  701        template <typename std::decay_t<CT>::size_type... I, 
class... Args>
 
  702        reference unchecked_impl(std::index_sequence<I...>, Args... args);
 
  704        template <typename std::decay_t<CT>::size_type... I, 
class... Args>
 
  705        const_reference unchecked_impl(std::index_sequence<I...>, Args... args) 
const;
 
  707        template <typename std::decay_t<CT>::size_type... I, 
class... Args>
 
  708        reference access_impl(std::index_sequence<I...>, Args... args);
 
  710        template <typename std::decay_t<CT>::size_type... I, 
class... Args>
 
  711        const_reference access_impl(std::index_sequence<I...>, Args... args) 
const;
 
  713        template <typename std::decay_t<CT>::size_type I, 
class... Args>
 
  714        size_type index(Args... args) 
const;
 
  716        template <typename std::decay_t<CT>::size_type, 
class T>
 
  717        size_type sliced_access(const xslice<T>& slice) 
const;
 
  719        template <typename std::decay_t<CT>::size_type I, 
class T, class Arg, class... Args>
 
  720        size_type sliced_access(const xslice<T>& slice, Arg 
arg, Args... args) 
const;
 
  722        template <typename std::decay_t<CT>::size_type I, 
class T, class... Args>
 
  723        size_type sliced_access(const T& 
squeeze, Args...) const
 
  724            requires(!is_xslice<T>::value);
 
  726        using base_index_type = xindex_type_t<typename xexpression_type::shape_type>;
 
  729        base_index_type make_index(It first, It last) const;
 
  731        void assign_temporary_impl(temporary_type&& tmp);
 
  733        template <std::
size_t... I>
 
  734        std::
size_t data_offset_impl(std::index_sequence<I...>) const noexcept;
 
  736        template <std::
size_t... I>
 
  737        auto compute_strides_impl(std::index_sequence<I...>) const noexcept;
 
  739        inner_shape_type compute_shape(std::true_type) const;
 
  740        inner_shape_type compute_shape(std::false_type) const;
 
  742        template <class E, std::
size_t... I>
 
  743        rebind_t<E> build_view_impl(E&& e, std::index_sequence<I...>) const;
 
  745        friend class xview_semantic<
xview<CT, S...>>;
 
 
  748    template <class E, class... S>
 
  752    auto 
row(E&& e, std::ptrdiff_t index);
 
  755    auto 
col(E&& e, std::ptrdiff_t index);
 
  764        struct get_stepper_impl
 
  766            using xexpression_type = 
typename V::xexpression_type;
 
  767            using type = 
typename xexpression_type::stepper;
 
  771        struct get_stepper_impl<const V>
 
  773            using xexpression_type = 
typename V::xexpression_type;
 
  774            using type = 
typename xexpression_type::const_stepper;
 
  779    using get_stepper = 
typename detail::get_stepper_impl<V>::type;
 
  781    template <
bool is_const, 
class CT, 
class... S>
 
  786        using view_type = std::conditional_t<is_const, 
const xview<CT, S...>, 
xview<CT, S...>>;
 
  787        using substepper_type = get_stepper<view_type>;
 
  789        using value_type = 
typename substepper_type::value_type;
 
  790        using reference = 
typename substepper_type::reference;
 
  791        using pointer = 
typename substepper_type::pointer;
 
  792        using difference_type = 
typename substepper_type::difference_type;
 
  793        using size_type = 
typename view_type::size_type;
 
  795        using shape_type = 
typename substepper_type::shape_type;
 
  797        xview_stepper() = 
default;
 
  806        reference operator*() 
const;
 
  808        void step(size_type dim);
 
  809        void step_back(size_type dim);
 
  810        void step(size_type dim, size_type n);
 
  811        void step_back(size_type dim, size_type n);
 
  812        void reset(size_type dim);
 
  813        void reset_back(size_type dim);
 
  820        bool is_newaxis_slice(size_type index) 
const noexcept;
 
  824        void common_step_forward(size_type dim, F f);
 
  826        void common_step_backward(size_type dim, F f);
 
  829        void common_step_forward(size_type dim, size_type n, F f);
 
  831        void common_step_backward(size_type dim, size_type n, F f);
 
  834        void common_reset(size_type dim, F f, 
bool backwards);
 
  837        substepper_type m_it;
 
  839        std::array<std::size_t, 
sizeof...(S)> m_index_keeper;
 
 
  843    template <
class ST, 
class... S>
 
  849    template <
class I, std::size_t L, 
class... S>
 
  852        using type = std::array<I, L - integral_count<S...>() + newaxis_count<S...>()>;
 
 
  855    template <std::size_t... I, 
class... S>
 
  858        using type = 
typename xview_shape_type<std::array<std::size_t, 
sizeof...(I)>, S...>::type;
 
 
  879    template <
class CT, 
class... S>
 
  880    template <
class CTA, 
class FSL, 
class... SL>
 
  883            std::integral_constant<bool, has_trivial_strides>{},
 
  884            std::forward<CTA>(e),
 
  885            std::forward<FSL>(first_slice),
 
  886            std::forward<SL>(
slices)...
 
 
  892    template <
class CT, 
class... S>
 
  893    template <
class CTA, 
class FSL, 
class... SL>
 
  895        : m_e(std::forward<CTA>(e))
 
  896        , m_slices(std::forward<FSL>(first_slice), std::forward<SL>(
slices)...)
 
  897        , m_shape(compute_shape(detail::is_sequence_view<inner_shape_type>{}))
 
  898        , m_strides(m_e.strides())
 
  899        , m_backstrides(m_e.backstrides())
 
  900        , m_data_offset(data_offset_impl(std::make_index_sequence<
sizeof...(S)>()))
 
  901        , m_strides_computed(
true)
 
  905    template <
class CT, 
class... S>
 
  906    template <
class CTA, 
class FSL, 
class... SL>
 
  908        : m_e(std::forward<CTA>(e))
 
  909        , m_slices(std::forward<FSL>(first_slice), std::forward<SL>(
slices)...)
 
  910        , m_shape(compute_shape(std::false_type{}))
 
  911        , m_strides_computed(
false)
 
  917    template <
class CT, 
class... S>
 
  920        temporary_type tmp(rhs);
 
  931    template <
class CT, 
class... S>
 
  935        return semantic_base::operator=(e);
 
 
  940    template <
class CT, 
class... S>
 
  942    inline auto xview<CT, S...>::operator=(
const E& e) -> disable_xexpression<E, self_type>&
 
  955    template <
class CT, 
class... S>
 
  964    template <
class CT, 
class... S>
 
  973    template <
class CT, 
class... S>
 
  976        if constexpr (is_strided_view)
 
  980                return static_layout;
 
  984                bool strides_match = do_strides_match(
shape(), strides(), m_e.layout(), 
true);
 
 
  994    template <
class CT, 
class... S>
 
  995    inline bool xview<CT, S...>::is_contiguous() const noexcept
 
 1011    template <
class CT, 
class... S>
 
 1017            std::fill(linear_begin(), linear_end(), value);
 
 1021            std::fill(this->begin(), this->end(), value);
 
 
 1031    template <
class CT, 
class... S>
 
 1032    template <
class... Args>
 
 1033    inline auto xview<CT, S...>::operator()(Args... args) -> reference
 
 1035        XTENSOR_TRY(check_index(
shape(), args...));
 
 1036        XTENSOR_CHECK_DIMENSION(
shape(), args...);
 
 1039        return access(
static_cast<size_type
>(args)...);
 
 
 1061    template <
class CT, 
class... S>
 
 1062    template <
class... Args>
 
 1063    inline auto xview<CT, S...>::unchecked(Args... args) -> reference
 
 1065        return unchecked_impl(make_index_sequence(args...), 
static_cast<size_type
>(args)...);
 
 
 1068    template <
class CT, 
class... S>
 
 1070    inline auto xview<CT, S...>::element(It first, It last) -> reference
 
 1072        XTENSOR_TRY(check_element_index(
shape(), first, last));
 
 1074        auto index = make_index(first, last);
 
 1075        return m_e.element(index.cbegin(), index.cend());
 
 1084    template <
class CT, 
class... S>
 
 1085    template <
class... Args>
 
 1086    inline auto xview<CT, S...>::operator()(Args... args) 
const -> const_reference
 
 1088        XTENSOR_TRY(check_index(
shape(), args...));
 
 1089        XTENSOR_CHECK_DIMENSION(
shape(), args...);
 
 1092        return access(
static_cast<size_type
>(args)...);
 
 
 1114    template <
class CT, 
class... S>
 
 1115    template <
class... Args>
 
 1116    inline auto xview<CT, S...>::unchecked(Args... args) 
const -> const_reference
 
 1118        return unchecked_impl(make_index_sequence(args...), 
static_cast<size_type
>(args)...);
 
 
 1121    template <
class CT, 
class... S>
 
 1123    inline auto xview<CT, S...>::element(It first, It last) 
const -> const_reference
 
 1126        auto index = make_index(first, last);
 
 1127        return m_e.element(index.cbegin(), index.cend());
 
 1133    template <
class CT, 
class... S>
 
 1142    template <
class CT, 
class... S>
 
 1153    template <
class CT, 
class... S>
 
 1155    inline auto xview<CT, S...>::storage() -> storage_type&
 
 1158        return m_e.storage();
 
 
 1161    template <
class CT, 
class... S>
 
 1163    inline auto xview<CT, S...>::storage() const -> const storage_type&
 
 1166        return m_e.storage();
 
 1169    template <
class CT, 
class... S>
 
 1171    auto xview<CT, S...>::linear_begin() -> linear_iterator
 
 1172        requires(has_data_interface_concept<T> and strided_view_concept<CT, S...>)
 
 1177    template <
class CT, 
class... S>
 
 1180        requires(has_data_interface_concept<T> and strided_view_concept<CT, S...>)
 
 1185    template <
class CT, 
class... S>
 
 1188        requires(has_data_interface_concept<T> and strided_view_concept<CT, S...>)
 
 1190        return linear_cbegin();
 
 1193    template <
class CT, 
class... S>
 
 1196        requires(has_data_interface_concept<T> and strided_view_concept<CT, S...>)
 
 1198        return linear_cend();
 
 1201    template <
class CT, 
class... S>
 
 1204        requires(has_data_interface_concept<T> and strided_view_concept<CT, S...>)
 
 1209    template <
class CT, 
class... S>
 
 1212        requires(has_data_interface_concept<T> and strided_view_concept<CT, S...>)
 
 1217    template <
class CT, 
class... S>
 
 1220        requires(has_data_interface_concept<T> and strided_view_concept<CT, S...>)
 
 1222        return reverse_linear_iterator(linear_end());
 
 1225    template <
class CT, 
class... S>
 
 1228        requires(has_data_interface_concept<T> and strided_view_concept<CT, S...>)
 
 1230        return reverse_linear_iterator(linear_begin());
 
 1233    template <
class CT, 
class... S>
 
 1236        requires(has_data_interface_concept<T> and strided_view_concept<CT, S...>)
 
 1238        return linear_crbegin();
 
 1241    template <
class CT, 
class... S>
 
 1244        requires(has_data_interface_concept<T> and strided_view_concept<CT, S...>)
 
 1246        return linear_crend();
 
 1249    template <
class CT, 
class... S>
 
 1252        requires(has_data_interface_concept<T> and strided_view_concept<CT, S...>)
 
 1254        return const_reverse_linear_iterator(linear_end());
 
 1257    template <
class CT, 
class... S>
 
 1260        requires(has_data_interface_concept<T> and strided_view_concept<CT, S...>)
 
 1262        return const_reverse_linear_iterator(linear_begin());
 
 1268    template <
class CT, 
class... S>
 
 1270    inline auto xview<CT, S...>::strides() const
 
 1272            if (!m_strides_computed)
 
 1274                compute_strides(std::integral_constant<bool, has_trivial_strides>{});
 
 1275                m_strides_computed = 
true;
 
 
 1280    template <
class CT, 
class... S>
 
 1282    inline auto xview<CT, S...>::backstrides() const
 
 1284            if (!m_strides_computed)
 
 1287                m_strides_computed = 
true;
 
 1289            return m_backstrides;
 
 1295    template <
class CT, 
class... S>
 
 1297    inline auto xview<CT, S...>::data() const -> const_pointer
 
 
 1303    template <
class CT, 
class... S>
 
 1305    inline auto xview<CT, S...>::data() -> pointer
 
 1311    template <
class CT, 
class... S>
 
 1312    template <std::size_t... I>
 
 1313    inline std::size_t xview<CT, S...>::data_offset_impl(std::index_sequence<I...>) 
const noexcept 
 1315        auto temp = std::array<std::ptrdiff_t, 
sizeof...(S)>(
 
 1316            {(
static_cast<ptrdiff_t
>(xt::value(std::get<I>(m_slices), 0)))...}
 
 1319        std::ptrdiff_t result = 0;
 
 1321        for (; i < std::min(
sizeof...(S), m_e.strides().size()); ++i)
 
 1323            result += temp[i] * m_e.strides()[i - newaxis_count_before<S...>(i)];
 
 1325        for (; i < 
sizeof...(S); ++i)
 
 1329        return static_cast<std::size_t
>(result) + m_e.data_offset();
 
 1335    template <
class CT, 
class... S>
 
 1340        if (!m_strides_computed)
 
 1342            compute_strides(std::integral_constant<bool, has_trivial_strides>{});
 
 1343            m_strides_computed = 
true;
 
 1345        return m_data_offset;
 
 
 1350    template <
class CT, 
class... S>
 
 1351    inline auto xview<CT, S...>::underlying_size(size_type dim) 
const -> size_type
 
 1353        return m_e.shape()[dim];
 
 1356    template <
class CT, 
class... S>
 
 1357    inline auto xview<CT, S...>::operator&() & -> xtl::xclosure_pointer<self_type&>
 
 1359        return xtl::closure_pointer(*
this);
 
 1362    template <
class CT, 
class... S>
 
 1365        return xtl::closure_pointer(*
this);
 
 1368    template <
class CT, 
class... S>
 
 1371        return xtl::closure_pointer(std::move(*
this));
 
 1384    template <
class CT, 
class... S>
 
 1388        return xt::broadcast_shape(m_shape, 
shape);
 
 
 1396    template <
class CT, 
class... S>
 
 1400        if constexpr (is_strided_view)
 
 1402            return str.size() == strides().size() && std::equal(str.cbegin(), str.cend(), strides().begin());
 
 
 1412    template <
class CT, 
class... S>
 
 1414    inline It xview<CT, S...>::data_xbegin_impl(It begin) 
const noexcept 
 1419    template <
class CT, 
class... S>
 
 1421    inline It xview<CT, S...>::data_xend_impl(It begin, 
layout_type l, size_type offset) 
const noexcept 
 1423        return strided_data_end(*
this, begin, l, offset);
 
 1426    template <
class CT, 
class... S>
 
 1429        return data_xbegin_impl(data());
 
 1432    template <
class CT, 
class... S>
 
 1435        return data_xbegin_impl(data());
 
 1438    template <
class CT, 
class... S>
 
 1441        return data_xend_impl(data() + 
data_offset(), l, offset);
 
 1444    template <
class CT, 
class... S>
 
 1446        -> const_container_iterator
 
 1448        return data_xend_impl(data() + 
data_offset(), l, offset);
 
 1452    template <
class CT, 
class... S>
 
 1453    template <
class E, 
class T>
 
 1455        requires(has_data_interface_concept<T> and contiguous_view_concept<E, S...>)
 
 1457        auto& de = e.derived_cast();
 
 1458        de.resize(
shape(), force_resize);
 
 1459        std::copy(data() + 
data_offset(), data() + 
data_offset() + de.size(), de.template begin<static_layout>());
 
 1462    template <
class CT, 
class... S>
 
 1463    template <
class E, std::size_t... I>
 
 1466        return rebind_t<E>(std::forward<E>(e), std::get<I>(m_slices)...);
 
 1469    template <
class CT, 
class... S>
 
 1473        return build_view_impl(std::forward<E>(e), std::make_index_sequence<
sizeof...(S)>());
 
 1476    template <
class CT, 
class... S>
 
 1477    template <
class align, 
class simd, 
class T>
 
 1479        requires(has_simd_interface_concept<T> and strided_view_concept<CT, S...>)
 
 1481        return m_e.template store_simd<xt_simd::unaligned_mode>(
data_offset() + i, e);
 
 1484    template <
class CT, 
class... S>
 
 1485    template <
class align, 
class requested_type, std::
size_t N, 
class T>
 
 1487        requires(has_simd_interface_concept<T> and strided_view_concept<CT, S...>)
 
 1489        return m_e.template load_simd<xt_simd::unaligned_mode, requested_type>(
data_offset() + i);
 
 1492    template <
class CT, 
class... S>
 
 1495        requires(has_simd_interface_concept<T> and strided_view_concept<CT, S...>)
 
 1500    template <
class CT, 
class... S>
 
 1503        requires(has_simd_interface_concept<T> and strided_view_concept<CT, S...>)
 
 1508    template <
class CT, 
class... S>
 
 1511        requires(has_simd_interface_concept<T> and strided_view_concept<CT, S...>)
 
 1513        XTENSOR_ASSERT(is_contiguous());
 
 1517    template <
class CT, 
class... S>
 
 1520        requires(has_simd_interface_concept<T> and strided_view_concept<CT, S...>)
 
 1522        XTENSOR_ASSERT(is_contiguous());
 
 1526    template <
class CT, 
class... S>
 
 1527    template <
class... Args>
 
 1530        return std::make_index_sequence<
 
 1531            (
sizeof...(Args) + integral_count<S...>() > newaxis_count<S...>()
 
 1532                 ? 
sizeof...(Args) + integral_count<S...>() - newaxis_count<S...>()
 
 1536    template <
class CT, 
class... S>
 
 1537    template <std::size_t... I>
 
 1540        std::size_t original_dim = m_e.dimension();
 
 1541        return std::array<std::ptrdiff_t, 
sizeof...(I)>(
 
 1542            {(
static_cast<std::ptrdiff_t
>(xt::step_size(std::get<integral_skip<S...>(I)>(m_slices), 1))
 
 1543              * ((integral_skip<S...>(I) - newaxis_count_before<S...>(integral_skip<S...>(I))) < original_dim
 
 1544                     ? m_e.strides()[integral_skip<S...>(I) - newaxis_count_before<S...>(integral_skip<S...>(I))]
 
 1549    template <
class CT, 
class... S>
 
 1552        m_strides = xtl::make_sequence<inner_strides_type>(this->
dimension(), 0);
 
 1553        m_backstrides = xtl::make_sequence<inner_strides_type>(this->
dimension(), 0);
 
 1555        constexpr std::size_t n_strides = 
sizeof...(S) - integral_count<S...>();
 
 1557        auto slice_strides = compute_strides_impl(std::make_index_sequence<n_strides>());
 
 1559        for (std::size_t i = 0; i < n_strides; ++i)
 
 1561            m_strides[i] = slice_strides[i];
 
 1563            detail::adapt_strides(
shape(), m_strides, &m_backstrides, i);
 
 1565        for (std::size_t i = n_strides; i < this->
dimension(); ++i)
 
 1567            m_strides[i] = m_e.strides()[i + integral_count<S...>() - newaxis_count<S...>()];
 
 1568            detail::adapt_strides(
shape(), m_strides, &m_backstrides, i);
 
 1571        m_data_offset = data_offset_impl(std::make_index_sequence<
sizeof...(S)>());
 
 1574    template <
class CT, 
class... S>
 
 1579    template <
class CT, 
class... S>
 
 1582        return access_impl(make_index_sequence());
 
 1585    template <
class CT, 
class... S>
 
 1586    template <
class Arg, 
class... Args>
 
 1589        if (
sizeof...(Args) >= this->
dimension())
 
 1591            return access(args...);
 
 1593        return access_impl(make_index_sequence(
arg, args...), 
arg, args...);
 
 1596    template <
class CT, 
class... S>
 
 1599        return access_impl(make_index_sequence());
 
 1602    template <
class CT, 
class... S>
 
 1603    template <
class Arg, 
class... Args>
 
 1606        if (
sizeof...(Args) >= this->
dimension())
 
 1608            return access(args...);
 
 1610        return access_impl(make_index_sequence(
arg, args...), 
arg, args...);
 
 1613    template <
class CT, 
class... S>
 
 1614    template <typename std::decay_t<CT>::size_type... I, 
class... Args>
 
 1617        return m_e.unchecked(index<I>(args...)...);
 
 1620    template <
class CT, 
class... S>
 
 1621    template <typename std::decay_t<CT>::size_type... I, 
class... Args>
 
 1625        return m_e.unchecked(index<I>(args...)...);
 
 1628    template <
class CT, 
class... S>
 
 1629    template <typename std::decay_t<CT>::size_type... I, 
class... Args>
 
 1632        return m_e(index<I>(args...)...);
 
 1635    template <
class CT, 
class... S>
 
 1636    template <typename std::decay_t<CT>::size_type... I, 
class... Args>
 
 1639        return m_e(index<I>(args...)...);
 
 1642    template <
class CT, 
class... S>
 
 1643    template <typename std::decay_t<CT>::size_type I, 
class... Args>
 
 1646        if constexpr (lesser_condition<I>::value)
 
 1648            return sliced_access<I - integral_count_before<S...>(I) + newaxis_count_before<S...>(I + 1)>(
 
 1649                std::get<I + newaxis_count_before<S...>(I + 1)>(m_slices),
 
 1655            return argument<I - integral_count<S...>() + newaxis_count<S...>()>(args...);
 
 1659    template <
class CT, 
class... S>
 
 1660    template <typename std::decay_t<CT>::size_type I, 
class T>
 
 1661    inline auto 
xview<CT, S...>::sliced_access(const xslice<T>& slice) const -> size_type
 
 1663        return static_cast<size_type
>(slice.derived_cast()(0));
 
 1666    template <
class CT, 
class... S>
 
 1667    template <typename std::decay_t<CT>::size_type I, 
class T, class Arg, class... Args>
 
 1668    inline auto 
xview<CT, S...>::sliced_access(const xslice<T>& slice, Arg arg, Args... args) const -> size_type
 
 1670        using ST = 
typename T::size_type;
 
 1671        return static_cast<size_type
>(
 
 1672            slice.derived_cast()(argument<I>(
static_cast<ST
>(arg), 
static_cast<ST
>(args)...))
 
 1676    template <
class CT, 
class... S>
 
 1677    template <typename std::decay_t<CT>::size_type I, 
class T, class... Args>
 
 1678    inline auto 
xview<CT, S...>::sliced_access(const T& squeeze, Args...) const -> size_type
 
 1679        requires(!is_xslice<T>::value)
 
 1681        return static_cast<size_type
>(
squeeze);
 
 1684    template <
class CT, 
class... S>
 
 1688        auto index = xtl::make_sequence<base_index_type>(m_e.dimension(), 0);
 
 1689        using diff_type = 
typename std::iterator_traits<It>::difference_type;
 
 1690        using ivalue_type = 
typename base_index_type::value_type;
 
 1691        auto func1 = [&first](
const auto& s) 
noexcept 
 1693            return get_slice_value(s, first);
 
 1695        auto func2 = [](
const auto& s) 
noexcept 
 1697            return xt::value(s, 0);
 
 1700        auto s = 
static_cast<diff_type
>(
 
 1701            (std::min)(
static_cast<size_type
>(std::distance(first, last)), this->
dimension())
 
 1703        auto first_copy = last - s;
 
 1704        for (size_type i = 0; i != m_e.dimension(); ++i)
 
 1706            size_type k = newaxis_skip<S...>(i);
 
 1710            std::advance(first, 
static_cast<diff_type
>(k - xt::integral_count_before<S...>(i)));
 
 1714                index[i] = k < 
sizeof...(S) ? apply<size_type>(k, func1, m_slices)
 
 1715                                            : 
static_cast<ivalue_type
>(*first);
 
 1719                index[i] = k < 
sizeof...(S) ? apply<size_type>(k, func2, m_slices) : ivalue_type(0);
 
 1725    template <
class CT, 
class... S>
 
 1728        return inner_shape_type(m_e.shape());
 
 1731    template <
class CT, 
class... S>
 
 1734        std::size_t dim = m_e.dimension() - integral_count<S...>() + newaxis_count<S...>();
 
 1735        auto shape = xtl::make_sequence<inner_shape_type>(dim, 0);
 
 1736        auto func = [](
const auto& s) 
noexcept 
 1740        for (size_type i = 0; i != dim; ++i)
 
 1742            size_type index = integral_skip<S...>(i);
 
 1743            shape[i] = index < 
sizeof...(S) ? apply<size_type>(index, func, m_slices)
 
 1744                                            : m_e.shape()[index - newaxis_count_before<S...>(index)];
 
 1749    namespace xview_detail
 
 1751        template <
class V, 
class T>
 
 1752        inline void run_assign_temporary_impl(V& v, 
const T& t, std::true_type )
 
 1754            strided_loop_assigner<true>::run(v, t);
 
 1757        template <
class V, 
class T>
 
 1759        run_assign_temporary_impl(V& v, 
const T& t, std::false_type )
 
 1761            std::copy(t.cbegin(), t.cend(), v.begin());
 
 1765    template <
class CT, 
class... S>
 
 1768        constexpr bool fast_assign = detail::is_strided_view<xexpression_type, S...>::value
 
 1769                                     && xassign_traits<
xview<CT, S...>, temporary_type>::simd_strided_assign();
 
 1770        xview_detail::run_assign_temporary_impl(*
this, tmp, std::integral_constant<bool, fast_assign>{});
 
 1775        template <
class E, 
class... S>
 
 1776        inline std::size_t get_underlying_shape_index(std::size_t I)
 
 1778            return I - newaxis_count_before<get_slice_type<E, S>...>(I);
 
 1781        template <
class... S>
 
 1785        struct check_slice<>
 
 1787            using type = void_t<>;
 
 1790        template <
class S, 
class... SL>
 
 1791        struct check_slice<S, SL...>
 
 1793            static_assert(!std::is_same<S, xellipsis_tag>::value, 
"ellipsis not supported vith xview");
 
 1794            using type = 
typename check_slice<SL...>::type;
 
 1797        template <
class E, std::size_t... I, 
class... S>
 
 1798        inline auto make_view_impl(E&& e, std::index_sequence<I...>, S&&... slices)
 
 1801            using view_type = xview<xtl::closure_type_t<E>, get_slice_type<std::decay_t<E>, S>...>;
 
 1804                get_slice_implementation(
 
 1806                    std::forward<S>(slices),
 
 1807                    get_underlying_shape_index<std::decay_t<E>, S...>(I)
 
 1822    template <
class E, 
class... S>
 
 1825        return detail::make_view_impl(
 
 1827            std::make_index_sequence<
sizeof...(S)>(),
 
 1828            std::forward<S>(
slices)...
 
 
 1839            inline static auto make(E&& e, 
const std::ptrdiff_t index)
 
 1841                const auto shape = e.shape();
 
 1842                check_dimension(shape);
 
 1843                return view(e, index, 
xt::all());
 
 1849            inline static void check_dimension(
const S& shape)
 
 1851                if (shape.size() != 2)
 
 1854                        std::invalid_argument,
 
 1855                        "A row can only be accessed on an expression with exact two dimensions" 
 1860            template <
class T, std::
size_t N>
 
 1861            inline static void check_dimension(
const std::array<T, N>&)
 
 1863                static_assert(N == 2, 
"A row can only be accessed on an expression with exact two dimensions");
 
 1872            inline static auto make(E&& e, 
const std::ptrdiff_t index)
 
 1874                const auto shape = e.shape();
 
 1875                check_dimension(shape);
 
 1882            inline static void check_dimension(
const S& shape)
 
 1884                if (shape.size() != 2)
 
 1887                        std::invalid_argument,
 
 1888                        "A column can only be accessed on an expression with exact two dimensions" 
 1893            template <
class T, std::
size_t N>
 
 1894            inline static void check_dimension(
const std::array<T, N>&)
 
 1896                static_assert(N == 2, 
"A column can only be accessed on an expression with exact two dimensions");
 
 1911    inline auto row(E&& e, std::ptrdiff_t index)
 
 1913        return detail::row_impl::make(e, index);
 
 
 1926    inline auto col(E&& e, std::ptrdiff_t index)
 
 1928        return detail::column_impl::make(e, index);
 
 
 1935    template <
class CT, 
class... S>
 
 1937    inline auto xview<CT, S...>::stepper_begin(
const ST& 
shape) -> stepper
 
 1940        if constexpr (is_strided_view)
 
 1942            return stepper(
this, data_xbegin(), offset);
 
 1946            return stepper(
this, m_e.stepper_begin(m_e.shape()), offset);
 
 1950    template <
class CT, 
class... S>
 
 1955        if constexpr (is_strided_view)
 
 1957            return stepper(
this, data_xend(l, offset), offset);
 
 1961            return stepper(
this, m_e.stepper_end(m_e.shape(), l), offset, 
true, l);
 
 1965    template <
class CT, 
class... S>
 
 1970        if constexpr (is_strided_view)
 
 1972            return const_stepper(
this, data_xbegin(), offset);
 
 1976            const xexpression_type& e = m_e;
 
 1977            return const_stepper(
this, e.stepper_begin(m_e.shape()), offset);
 
 1981    template <
class CT, 
class... S>
 
 1986        if constexpr (is_strided_view)
 
 1988            return const_stepper(
this, data_xend(l, offset), offset);
 
 1992            const xexpression_type& e = m_e;
 
 1993            return const_stepper(
this, e.stepper_end(m_e.shape(), l), offset, 
true, l);
 
 2001    template <
bool is_const, 
class CT, 
class... S>
 
 2002    inline xview_stepper<is_const, CT, S...>::xview_stepper(
 
 2015            std::fill(m_index_keeper.begin(), m_index_keeper.end(), 0);
 
 2016            auto func = [](
const auto& s) 
noexcept 
 2018                return xt::value(s, 0);
 
 2020            for (size_type i = 0; i < 
sizeof...(S); ++i)
 
 2022                if (!is_newaxis_slice(i))
 
 2024                    size_type s = apply<size_type>(i, func, p_view->slices());
 
 2025                    size_type index = i - newaxis_count_before<S...>(i);
 
 2026                    m_it.step(index, s);
 
 2036    template <
bool is_const, 
class CT, 
class... S>
 
 2037    inline auto xview_stepper<is_const, CT, S...>::operator*() const -> reference
 
 2042    template <
bool is_const, 
class CT, 
class... S>
 
 2043    inline void xview_stepper<is_const, CT, S...>::step(size_type dim)
 
 2045        auto func = [
this](size_type index, size_type offset)
 
 2047            m_it.step(index, offset);
 
 2049        common_step_forward(dim, func);
 
 2052    template <
bool is_const, 
class CT, 
class... S>
 
 2053    inline void xview_stepper<is_const, CT, S...>::step_back(size_type dim)
 
 2055        auto func = [
this](size_type index, size_type offset)
 
 2057            m_it.step_back(index, offset);
 
 2059        common_step_backward(dim, func);
 
 2062    template <
bool is_const, 
class CT, 
class... S>
 
 2063    inline void xview_stepper<is_const, CT, S...>::step(size_type dim, size_type n)
 
 2065        auto func = [
this](size_type index, size_type offset)
 
 2067            m_it.step(index, offset);
 
 2069        common_step_forward(dim, n, func);
 
 2072    template <
bool is_const, 
class CT, 
class... S>
 
 2073    inline void xview_stepper<is_const, CT, S...>::step_back(size_type dim, size_type n)
 
 2075        auto func = [
this](size_type index, size_type offset)
 
 2077            m_it.step_back(index, offset);
 
 2079        common_step_backward(dim, n, func);
 
 2082    template <
bool is_const, 
class CT, 
class... S>
 
 2083    inline void xview_stepper<is_const, CT, S...>::reset(size_type dim)
 
 2085        auto func = [
this](size_type index, size_type offset)
 
 2087            m_it.step_back(index, offset);
 
 2089        common_reset(dim, func, 
false);
 
 2092    template <
bool is_const, 
class CT, 
class... S>
 
 2093    inline void xview_stepper<is_const, CT, S...>::reset_back(size_type dim)
 
 2095        auto func = [
this](size_type index, size_type offset)
 
 2097            m_it.step(index, offset);
 
 2099        common_reset(dim, func, 
true);
 
 2102    template <
bool is_const, 
class CT, 
class... S>
 
 2103    inline void xview_stepper<is_const, CT, S...>::to_begin()
 
 2105        std::fill(m_index_keeper.begin(), m_index_keeper.end(), 0);
 
 2109    template <
bool is_const, 
class CT, 
class... S>
 
 2110    inline void xview_stepper<is_const, CT, S...>::to_end(layout_type l)
 
 2116    template <
bool is_const, 
class CT, 
class... S>
 
 2117    inline bool xview_stepper<is_const, CT, S...>::is_newaxis_slice(size_type index) 
const noexcept 
 2120        return newaxis_count_before<S...>(index + 1) != newaxis_count_before<S...>(index);
 
 2123    template <
bool is_const, 
class CT, 
class... S>
 
 2124    inline void xview_stepper<is_const, CT, S...>::to_end_impl(layout_type l)
 
 2126        auto func = [](
const auto& s) 
noexcept 
 2128            return xt::value(s, get_size(s) - 1);
 
 2130        auto size_func = [](
const auto& s) 
noexcept 
 2135        for (size_type i = 0; i < 
sizeof...(S); ++i)
 
 2137            if (!is_newaxis_slice(i))
 
 2139                size_type s = apply<size_type>(i, func, p_view->slices());
 
 2140                size_type ix = apply<size_type>(i, size_func, p_view->slices());
 
 2141                m_index_keeper[i] = ix - size_type(1);
 
 2142                size_type index = i - newaxis_count_before<S...>(i);
 
 2143                s = p_view->underlying_size(index) - 1 - s;
 
 2144                m_it.step_back(index, s);
 
 2147        if (l == layout_type::row_major)
 
 2149            for (size_type i = 
sizeof...(S); i > 0; --i)
 
 2151                if (!is_newaxis_slice(i - 1))
 
 2153                    m_index_keeper[i - 1]++;
 
 2158        else if (l == layout_type::column_major)
 
 2160            for (size_type i = 0; i < 
sizeof...(S); ++i)
 
 2162                if (!is_newaxis_slice(i))
 
 2164                    m_index_keeper[i]++;
 
 2171            XTENSOR_THROW(std::runtime_error, 
"Iteration only allowed in row or column major.");
 
 2175    template <
bool is_const, 
class CT, 
class... S>
 
 2177    void xview_stepper<is_const, CT, S...>::common_step_forward(size_type dim, F f)
 
 2179        if (dim >= m_offset)
 
 2181            auto func = [&dim, 
this](
const auto& s) 
noexcept 
 2183                return step_size(s, this->m_index_keeper[dim]++, 1);
 
 2185            size_type index = integral_skip<S...>(dim);
 
 2186            if (!is_newaxis_slice(index))
 
 2188                size_type step_size = index < 
sizeof...(S) ? apply<size_type>(index, func, p_view->slices())
 
 2190                index -= newaxis_count_before<S...>(index);
 
 2191                f(index, step_size);
 
 2196    template <
bool is_const, 
class CT, 
class... S>
 
 2198    void xview_stepper<is_const, CT, S...>::common_step_forward(size_type dim, size_type n, F f)
 
 2200        if (dim >= m_offset)
 
 2202            auto func = [&dim, &n, 
this](
const auto& s) 
noexcept 
 2204                auto st_size = step_size(s, this->m_index_keeper[dim], n);
 
 2205                this->m_index_keeper[dim] += n;
 
 2206                return size_type(st_size);
 
 2209            size_type index = integral_skip<S...>(dim);
 
 2210            if (!is_newaxis_slice(index))
 
 2212                size_type step_size = index < 
sizeof...(S) ? apply<size_type>(index, func, p_view->slices())
 
 2214                index -= newaxis_count_before<S...>(index);
 
 2215                f(index, step_size);
 
 2220    template <
bool is_const, 
class CT, 
class... S>
 
 2222    void xview_stepper<is_const, CT, S...>::common_step_backward(size_type dim, F f)
 
 2224        if (dim >= m_offset)
 
 2226            auto func = [&dim, 
this](
const auto& s) 
noexcept 
 2228                this->m_index_keeper[dim]--;
 
 2229                return step_size(s, this->m_index_keeper[dim], 1);
 
 2231            size_type index = integral_skip<S...>(dim);
 
 2232            if (!is_newaxis_slice(index))
 
 2234                size_type step_size = index < 
sizeof...(S) ? apply<size_type>(index, func, p_view->slices())
 
 2236                index -= newaxis_count_before<S...>(index);
 
 2237                f(index, step_size);
 
 2242    template <
bool is_const, 
class CT, 
class... S>
 
 2244    void xview_stepper<is_const, CT, S...>::common_step_backward(size_type dim, size_type n, F f)
 
 2246        if (dim >= m_offset)
 
 2248            auto func = [&dim, &n, 
this](
const auto& s) 
noexcept 
 2250                this->m_index_keeper[dim] -= n;
 
 2251                return step_size(s, this->m_index_keeper[dim], n);
 
 2254            size_type index = integral_skip<S...>(dim);
 
 2255            if (!is_newaxis_slice(index))
 
 2257                size_type step_size = index < 
sizeof...(S) ? apply<size_type>(index, func, p_view->slices())
 
 2259                index -= newaxis_count_before<S...>(index);
 
 2260                f(index, step_size);
 
 2265    template <
bool is_const, 
class CT, 
class... S>
 
 2267    void xview_stepper<is_const, CT, S...>::common_reset(size_type dim, F f, 
bool backwards)
 
 2269        auto size_func = [](
const auto& s) 
noexcept 
 2273        auto end_func = [](
const auto& s) 
noexcept 
 2275            return xt::value(s, get_size(s) - 1) - xt::value(s, 0);
 
 2278        size_type index = integral_skip<S...>(dim);
 
 2279        if (!is_newaxis_slice(index))
 
 2281            if (dim < m_index_keeper.size())
 
 2283                size_type size = index < 
sizeof...(S) ? apply<size_type>(index, size_func, p_view->slices())
 
 2284                                                      : p_view->shape()[dim];
 
 2285                m_index_keeper[dim] = backwards ? size - 1 : 0;
 
 2288            size_type reset_n = index < 
sizeof...(S) ? apply<size_type>(index, end_func, p_view->slices())
 
 2289                                                     : p_view->shape()[dim] - 1;
 
 2290            index -= newaxis_count_before<S...>(index);
 
Fixed shape implementation for compile time defined arrays.
size_type size() const noexcept(noexcept(derived_cast().shape()))
size_type dimension() const noexcept
Base class for xexpressions.
Base class for multidimensional iterable expressions.
derived_type & assign_temporary(temporary_type &&)
Multidimensional view with tensor semantic.
xview(CTA &&e, FSL &&first_slice, SL &&... slices) noexcept
Constructs a view on the specified xexpression.
const slice_type & slices() const noexcept
bool has_linear_assign(const ST &strides) const
const inner_shape_type & shape() const noexcept
Returns the shape of the view.
bool broadcast_shape(ST &shape, bool reuse_cache=false) const
xexpression_type & expression() noexcept
void fill(const T &value)
std::size_t data_offset() const noexcept
layout_type layout() const noexcept
auto arg(E &&e) noexcept
Calculates the phase angle (in radians) elementwise for the complex numbers in e.
auto squeeze(E &&e)
Returns a squeeze view of the given expression.
std::size_t compute_strides(const shape_type &shape, layout_type l, strides_type &strides)
Compute the strides given the shape and the layout of an array.
standard mathematical functions for xexpressions
auto all() noexcept
Returns a slice representing a full dimension, to be used as an argument of view function.
auto row(E &&e, std::ptrdiff_t index)
Constructs and returns a row (sliced view) on the specified expression.
auto col(E &&e, std::ptrdiff_t index)
Constructs and returns a column (sliced view) on the specified expression.
auto view(E &&e, S &&... slices)
Constructs and returns a view on the specified xexpression.