9#ifndef XTENSOR_DYNAMIC_VIEW_HPP 
   10#define XTENSOR_DYNAMIC_VIEW_HPP 
   14#include <xtl/xsequence.hpp> 
   16#include "../core/xexpression.hpp" 
   17#include "../core/xiterable.hpp" 
   18#include "../core/xlayout.hpp" 
   19#include "../core/xsemantic.hpp" 
   20#include "../views/xstrided_view_base.hpp" 
   25    template <
class CT, 
class S, layout_type L, 
class FST>
 
   28    template <
class CT, 
class S, layout_type L, 
class FST>
 
   31        using xexpression_type = std::decay_t<CT>;
 
   32        using undecay_expression = CT;
 
   33        using reference = inner_reference_t<undecay_expression>;
 
   34        using const_reference = 
typename xexpression_type::const_reference;
 
   35        using size_type = 
typename xexpression_type::size_type;
 
   36        using shape_type = std::decay_t<S>;
 
   37        using undecay_shape = S;
 
   38        using storage_getter = FST;
 
   39        using inner_storage_type = 
typename storage_getter::type;
 
 
   44    template <
class CT, 
class S, layout_type L, 
class FST>
 
   47        using inner_shape_type = S;
 
   48        using inner_strides_type = inner_shape_type;
 
   49        using inner_backstrides_type = inner_shape_type;
 
   51#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ == 8 
 
   69        template <
class Tag, 
class CT, 
class S, layout_type L, 
class FST>
 
   72        template <
class CT, 
class S, layout_type L, 
class FST>
 
   78        template <
class CT, 
class S, layout_type L, 
class FST>
 
   83        template <
class CT, 
class S, layout_type L, 
class FST>
 
   97    template <
class CT, 
class S, layout_type L = layout_type::dynamic, 
class FST = detail::flat_storage_getter<CT, XTENSOR_DEFAULT_TRAVERSAL>>
 
   98    class xdynamic_view : 
public xview_semantic<xdynamic_view<CT, S, L, FST>>,
 
   99                          public xiterable<xdynamic_view<CT, S, L, FST>>,
 
  100                          public extension::xdynamic_view_base_t<CT, S, L, FST>,
 
  105        using self_type = xdynamic_view<CT, S, L, FST>;
 
  107        using semantic_base = xview_semantic<self_type>;
 
  108        using extension_base = extension::xdynamic_view_base_t<CT, S, L, FST>;
 
  109        using expression_tag = 
typename extension_base::expression_tag;
 
  111        using xexpression_type = 
typename base_type::xexpression_type;
 
  112        using base_type::is_const;
 
  114        using value_type = 
typename base_type::value_type;
 
  115        using reference = 
typename base_type::reference;
 
  116        using const_reference = 
typename base_type::const_reference;
 
  117        using pointer = 
typename base_type::pointer;
 
  118        using const_pointer = 
typename base_type::const_pointer;
 
  119        using size_type = 
typename base_type::size_type;
 
  120        using difference_type = 
typename base_type::difference_type;
 
  122        using inner_storage_type = 
typename base_type::inner_storage_type;
 
  123        using storage_type = 
typename base_type::storage_type;
 
  126        using inner_shape_type = 
typename iterable_base::inner_shape_type;
 
  127        using inner_strides_type = 
typename base_type::inner_strides_type;
 
  128        using inner_backstrides_type = 
typename base_type::inner_backstrides_type;
 
  130        using shape_type = 
typename base_type::shape_type;
 
  131        using strides_type = 
typename base_type::strides_type;
 
  132        using backstrides_type = 
typename base_type::backstrides_type;
 
  134        using stepper = 
typename iterable_base::stepper;
 
  135        using const_stepper = 
typename iterable_base::const_stepper;
 
  137        using base_type::contiguous_layout;
 
  138        using base_type::static_layout;
 
  141        using base_index_type = xindex_type_t<shape_type>;
 
  143        using simd_value_type = 
typename base_type::simd_value_type;
 
  144        using bool_load_type = 
typename base_type::bool_load_type;
 
  146        using strides_vt = 
typename strides_type::value_type;
 
  148        using slice_vector_type = std::vector<slice_type>;
 
  150        template <
class CTA, 
class SA>
 
  154            get_strides_t<S>&& strides,
 
  157            slice_vector_type&& slices,
 
  158            get_strides_t<S>&& adj_strides
 
  165        disable_xexpression<E, self_type>& operator=(
const E& e);
 
  168        using base_type::is_contiguous;
 
  176        const inner_strides_type& strides() 
const noexcept = 
delete;
 
  178        reference operator()();
 
  179        const_reference operator()() 
const;
 
  181        template <
class... Args>
 
  182        reference operator()(Args... args);
 
  184        template <
class... Args>
 
  185        const_reference operator()(Args... args) 
const;
 
  187        template <
class... Args>
 
  188        reference unchecked(Args... args);
 
  190        template <
class... Args>
 
  191        const_reference unchecked(Args... args) 
const;
 
  193        reference flat(size_type index);
 
  194        const_reference flat(size_type index) 
const;
 
  196        using base_type::operator[];
 
  201        using base_type::periodic;
 
  204        reference element(It first, It last);
 
  207        const_reference element(It first, It last) 
const;
 
  209        size_type data_offset() 
const noexcept;
 
  214        value_type* data() 
noexcept = 
delete;
 
  215        const value_type* data() 
const noexcept = 
delete;
 
  222        bool has_linear_assign(
const O& str) 
const noexcept;
 
  225        void fill(
const T& value);
 
  228        stepper stepper_begin(
const ST& 
shape);
 
  233        const_stepper stepper_begin(
const ST& 
shape) 
const;
 
  237        using container_iterator = std::
 
  238            conditional_t<is_const, typename storage_type::const_iterator, typename storage_type::iterator>;
 
  239        using const_container_iterator = 
typename storage_type::const_iterator;
 
  242        using rebind_t = xdynamic_view<E, S, L, typename FST::template rebind_t<E>>;
 
  245        rebind_t<E> build_view(E&& e) 
const;
 
  249        using offset_type = 
typename base_type::offset_type;
 
  251        slice_vector_type m_slices;
 
  252        inner_strides_type m_adj_strides;
 
  254        container_iterator data_xbegin() 
noexcept;
 
  255        const_container_iterator data_xbegin() 
const noexcept;
 
  256        container_iterator data_xend(
layout_type l, size_type offset) 
noexcept;
 
  257        const_container_iterator data_xend(
layout_type l, size_type offset) 
const noexcept;
 
  260        It data_xbegin_impl(It begin) 
const noexcept;
 
  263        It data_xend_impl(It end, 
layout_type l, size_type offset) 
const noexcept;
 
  265        void assign_temporary_impl(temporary_type&& tmp);
 
  267        template <
class T, 
class... Args>
 
  268        offset_type adjust_offset(offset_type offset, T idx, Args... args) 
const noexcept;
 
  269        offset_type adjust_offset(offset_type offset) 
const noexcept;
 
  271        template <
class T, 
class... Args>
 
  273        adjust_offset_impl(offset_type offset, size_type idx_offset, T idx, Args... args) 
const noexcept;
 
  274        offset_type adjust_offset_impl(offset_type offset, size_type idx_offset) 
const noexcept;
 
  277        offset_type adjust_element_offset(offset_type offset, It first, It last) 
const noexcept;
 
  280        friend class xstepper;
 
  281        friend class xview_semantic<self_type>;
 
 
  291    using xdynamic_slice = std::variant<
 
  315    using xdynamic_slice_vector = std::vector<xdynamic_slice<std::ptrdiff_t>>;
 
  318    auto dynamic_view(E&& e, 
const xdynamic_slice_vector& slices);
 
  327        class xfake_slice : 
public xslice<xfake_slice<T>>
 
  332            using self_type = xfake_slice<T>;
 
  334            xfake_slice() = 
default;
 
  336            size_type operator()(size_type ) 
const noexcept 
  341            size_type size() const noexcept
 
  346            size_type step_size() const noexcept
 
  351            size_type step_size(std::size_t , std::size_t  = 1) const noexcept
 
  356            size_type revert_index(std::size_t i) 
const noexcept 
  361            bool contains(size_type ) 
const noexcept 
  366            bool operator==(
const self_type& ) 
const noexcept 
  371            bool operator!=(
const self_type& ) 
const noexcept 
  382    template <
class CT, 
class S, layout_type L, 
class FST>
 
  383    template <
class CTA, 
class SA>
 
  384    inline xdynamic_view<CT, S, L, FST>::xdynamic_view(
 
  390        slice_vector_type&& slices,
 
  391        get_strides_t<S>&& adj_strides
 
  393        : base_type(std::forward<CTA>(e), std::forward<SA>(shape), std::move(
strides), offset, layout)
 
  394        , m_slices(std::move(slices))
 
  395        , m_adj_strides(std::move(adj_strides))
 
  399    template <
class CT, 
class S, layout_type L, 
class FST>
 
  401    inline auto xdynamic_view<CT, S, L, FST>::operator=(
const xexpression<E>& e) -> self_type&
 
  403        return semantic_base::operator=(e);
 
  406    template <
class CT, 
class S, layout_type L, 
class FST>
 
  408    inline auto xdynamic_view<CT, S, L, FST>::operator=(
const E& e) -> disable_xexpression<E, self_type>&
 
  410        std::fill(this->begin(), this->end(), e);
 
  414    template <
class CT, 
class S, layout_type L, 
class FST>
 
  415    inline auto xdynamic_view<CT, S, L, FST>::operator()() -> reference
 
  417        return base_type::storage()[data_offset()];
 
  420    template <
class CT, 
class S, layout_type L, 
class FST>
 
  421    inline auto xdynamic_view<CT, S, L, FST>::operator()() const -> const_reference
 
  423        return base_type::storage()[data_offset()];
 
  426    template <
class CT, 
class S, layout_type L, 
class FST>
 
  427    template <
class... Args>
 
  428    inline auto xdynamic_view<CT, S, L, FST>::operator()(Args... args) -> reference
 
  430        XTENSOR_TRY(check_index(base_type::shape(), args...));
 
  431        XTENSOR_CHECK_DIMENSION(base_type::shape(), args...);
 
  432        offset_type offset = base_type::compute_index(args...);
 
  433        offset = adjust_offset(offset, args...);
 
  434        return base_type::storage()[
static_cast<size_type
>(offset)];
 
  437    template <
class CT, 
class S, layout_type L, 
class FST>
 
  438    template <
class... Args>
 
  439    inline auto xdynamic_view<CT, S, L, FST>::operator()(Args... args) 
const -> const_reference
 
  441        XTENSOR_TRY(check_index(base_type::shape(), args...));
 
  442        XTENSOR_CHECK_DIMENSION(base_type::shape(), args...);
 
  443        offset_type offset = base_type::compute_index(args...);
 
  444        offset = adjust_offset(offset, args...);
 
  445        return base_type::storage()[
static_cast<size_type
>(offset)];
 
  448    template <
class CT, 
class S, layout_type L, 
class FST>
 
  450    inline bool xdynamic_view<CT, S, L, FST>::has_linear_assign(
const O&) 
const noexcept 
  455    template <
class CT, 
class S, layout_type L, 
class FST>
 
  456    template <
class... Args>
 
  457    inline auto xdynamic_view<CT, S, L, FST>::unchecked(Args... args) -> reference
 
  459        offset_type offset = base_type::compute_unchecked_index(args...);
 
  460        offset = adjust_offset(args...);
 
  461        return base_type::storage()[
static_cast<size_type
>(offset)];
 
  464    template <
class CT, 
class S, layout_type L, 
class FST>
 
  465    template <
class... Args>
 
  466    inline auto xdynamic_view<CT, S, L, FST>::unchecked(Args... args) 
const -> const_reference
 
  468        offset_type offset = base_type::compute_unchecked_index(args...);
 
  469        offset = adjust_offset(args...);
 
  470        return base_type::storage()[
static_cast<size_type
>(offset)];
 
  473    template <
class CT, 
class S, layout_type L, 
class FST>
 
  474    inline auto xdynamic_view<CT, S, L, FST>::flat(size_type i) -> reference
 
  476        return base_type::storage()[data_offset() + i];
 
  479    template <
class CT, 
class S, layout_type L, 
class FST>
 
  480    inline auto xdynamic_view<CT, S, L, FST>::flat(size_type i) 
const -> const_reference
 
  482        return base_type::storage()[data_offset() + i];
 
  485    template <
class CT, 
class S, layout_type L, 
class FST>
 
  487    inline auto xdynamic_view<CT, S, L, FST>::element(It first, It last) -> reference
 
  489        XTENSOR_TRY(check_element_index(base_type::shape(), first, last));
 
  490        offset_type offset = base_type::compute_element_index(first, last);
 
  491        offset = adjust_element_offset(offset, first, last);
 
  492        return base_type::storage()[
static_cast<size_type
>(offset)];
 
  495    template <
class CT, 
class S, layout_type L, 
class FST>
 
  497    inline auto xdynamic_view<CT, S, L, FST>::element(It first, It last) 
const -> const_reference
 
  499        XTENSOR_TRY(check_element_index(base_type::shape(), first, last));
 
  500        offset_type offset = base_type::compute_element_index(first, last);
 
  501        offset = adjust_element_offset(offset, first, last);
 
  502        return base_type::storage()[
static_cast<size_type
>(offset)];
 
  505    template <
class CT, 
class S, layout_type L, 
class FST>
 
  506    inline auto xdynamic_view<CT, S, L, FST>::data_offset() const noexcept -> size_type
 
  508        size_type offset = base_type::data_offset();
 
  509        size_type sl_offset = std::visit(
 
  512                return sl(size_type(0));
 
  516        return offset + sl_offset * m_adj_strides[0];
 
  519    template <
class CT, 
class S, layout_type L, 
class FST>
 
  521    inline void xdynamic_view<CT, S, L, FST>::fill(
const T& value)
 
  523        return std::fill(this->linear_begin(), this->linear_end(), value);
 
  526    template <
class CT, 
class S, layout_type L, 
class FST>
 
  528    inline auto xdynamic_view<CT, S, L, FST>::stepper_begin(
const ST& shape) -> stepper
 
  530        size_type offset = shape.size() - dimension();
 
  531        return stepper(
this, offset);
 
  534    template <
class CT, 
class S, layout_type L, 
class FST>
 
  536    inline auto xdynamic_view<CT, S, L, FST>::stepper_end(
const ST& shape, 
layout_type ) -> stepper
 
  538        size_type offset = shape.size() - dimension();
 
  539        return stepper(
this, offset, 
true);
 
  542    template <
class CT, 
class S, layout_type L, 
class FST>
 
  544    inline auto xdynamic_view<CT, S, L, FST>::stepper_begin(
const ST& shape) 
const -> const_stepper
 
  546        size_type offset = shape.size() - dimension();
 
  547        return const_stepper(
this, offset);
 
  550    template <
class CT, 
class S, layout_type L, 
class FST>
 
  552    inline auto xdynamic_view<CT, S, L, FST>::stepper_end(
const ST& shape, 
layout_type ) 
const 
  555        size_type offset = shape.size() - dimension();
 
  556        return const_stepper(
this, offset, 
true);
 
  559    template <
class CT, 
class S, layout_type L, 
class FST>
 
  561    inline auto xdynamic_view<CT, S, L, FST>::build_view(E&& e) 
const -> rebind_t<E>
 
  563        inner_shape_type sh(this->shape());
 
  564        inner_strides_type str(base_type::strides());
 
  565        slice_vector_type svt(m_slices);
 
  566        inner_strides_type adj_str(m_adj_strides);
 
  571            base_type::data_offset(),
 
  578    template <
class CT, 
class S, layout_type L, 
class FST>
 
  579    inline auto xdynamic_view<CT, S, L, FST>::data_xbegin() noexcept -> container_iterator
 
  581        return data_xbegin_impl(this->storage().begin());
 
  584    template <
class CT, 
class S, layout_type L, 
class FST>
 
  585    inline auto xdynamic_view<CT, S, L, FST>::data_xbegin() const noexcept -> const_container_iterator
 
  587        return data_xbegin_impl(this->storage().cbegin());
 
  590    template <
class CT, 
class S, layout_type L, 
class FST>
 
  591    inline auto xdynamic_view<CT, S, L, FST>::data_xend(
layout_type l, size_type offset) 
noexcept 
  592        -> container_iterator
 
  594        return data_xend_impl(this->storage().begin(), l, offset);
 
  597    template <
class CT, 
class S, layout_type L, 
class FST>
 
  598    inline auto xdynamic_view<CT, S, L, FST>::data_xend(
layout_type l, size_type offset) 
const noexcept 
  599        -> const_container_iterator
 
  601        return data_xend_impl(this->storage().cbegin(), l, offset);
 
  604    template <
class CT, 
class S, layout_type L, 
class FST>
 
  606    inline It xdynamic_view<CT, S, L, FST>::data_xbegin_impl(It begin) 
const noexcept 
  608        return begin + 
static_cast<std::ptrdiff_t
>(data_offset());
 
  613    template <
class CT, 
class S, layout_type L, 
class FST>
 
  616    xdynamic_view<CT, S, L, FST>::data_xend_impl(It begin, 
layout_type l, size_type offset) 
const noexcept 
  618        return strided_data_end(*
this, begin + std::ptrdiff_t(data_offset()), l, offset);
 
  621    template <
class CT, 
class S, layout_type L, 
class FST>
 
  622    inline void xdynamic_view<CT, S, L, FST>::assign_temporary_impl(
temporary_type&& tmp)
 
  624        std::copy(tmp.cbegin(), tmp.cend(), this->begin());
 
  627    template <
class CT, 
class S, layout_type L, 
class FST>
 
  628    template <
class T, 
class... Args>
 
  630    xdynamic_view<CT, S, L, FST>::adjust_offset(offset_type offset, T idx, Args... args) 
const noexcept 
  633        constexpr size_type nb_args = 
sizeof...(Args) + 1;
 
  634        size_type dim = base_type::dimension();
 
  635        offset_type res = nb_args > dim ? adjust_offset(offset, args...)
 
  636                                        : adjust_offset_impl(offset, dim - nb_args, idx, args...);
 
  640    template <
class CT, 
class S, layout_type L, 
class FST>
 
  641    inline auto xdynamic_view<CT, S, L, FST>::adjust_offset(offset_type offset) 
const noexcept -> offset_type
 
  646    template <
class CT, 
class S, layout_type L, 
class FST>
 
  647    template <
class T, 
class... Args>
 
  649    xdynamic_view<CT, S, L, FST>::adjust_offset_impl(offset_type offset, size_type idx_offset, T idx, Args... args)
 
  650        const noexcept -> offset_type
 
  652        offset_type sl_offset = std::visit(
 
  653            [idx](
const auto& sl)
 
  655                using type = 
typename std::decay_t<
decltype(sl)>::size_type;
 
  656                return sl(type(idx));
 
  660        offset_type res = offset + sl_offset * m_adj_strides[idx_offset];
 
  661        return adjust_offset_impl(res, idx_offset + 1, args...);
 
  664    template <
class CT, 
class S, layout_type L, 
class FST>
 
  665    inline auto xdynamic_view<CT, S, L, FST>::adjust_offset_impl(offset_type offset, size_type) 
const noexcept 
  671    template <
class CT, 
class S, layout_type L, 
class FST>
 
  674    xdynamic_view<CT, S, L, FST>::adjust_element_offset(offset_type offset, It first, It last) 
const noexcept 
  677        auto dst = std::distance(first, last);
 
  678        offset_type dim = 
static_cast<offset_type
>(dimension());
 
  679        offset_type loop_offset = dst < dim ? dim - dst : offset_type(0);
 
  680        offset_type idx_offset = dim < dst ? dst - dim : offset_type(0);
 
  681        offset_type res = offset;
 
  682        for (offset_type i = loop_offset; i < dim; ++i, ++first)
 
  684            offset_type j = 
static_cast<offset_type
>(first[idx_offset]);
 
  685            offset_type sl_offset = std::visit(
 
  688                    return static_cast<offset_type
>(sl(j));
 
  690                m_slices[
static_cast<std::size_t
>(i)]
 
  692            res += sl_offset * m_adj_strides[
static_cast<std::size_t
>(i)];
 
  704        struct adj_strides_policy
 
  706            using slice_vector = V;
 
  707            using strides_type = dynamic_shape<std::ptrdiff_t>;
 
  709            slice_vector new_slices;
 
  710            strides_type new_adj_strides;
 
  714            inline void resize(std::size_t size)
 
  716                new_slices.resize(size);
 
  717                new_adj_strides.resize(size);
 
  720            inline void set_fake_slice(std::size_t idx)
 
  722                new_slices[idx] = xfake_slice<std::ptrdiff_t>();
 
  723                new_adj_strides[idx] = std::ptrdiff_t(0);
 
  726            template <
class ST, 
class S>
 
  728                const xdynamic_slice_vector& slices,
 
  731                std::size_t old_shape,
 
  732                const ST& old_stride,
 
  737                return fill_args_impl<xkeep_slice<std::ptrdiff_t>>(
 
  746                       || fill_args_impl<xdrop_slice<std::ptrdiff_t>>(
 
  757            template <
class SL, 
class ST, 
class S>
 
  759                const xdynamic_slice_vector& slices,
 
  762                std::size_t old_shape,
 
  763                const ST& old_stride,
 
  768                auto* sl = std::get_if<SL>(&slices[sl_idx]);
 
  772                    auto& ns = std::get<SL>(new_slices[i]);
 
  773                    ns.normalize(old_shape);
 
  774                    shape[i] = 
static_cast<std::size_t
>(ns.size());
 
  775                    strides[i] = std::ptrdiff_t(0);
 
  776                    new_adj_strides[i] = 
static_cast<std::ptrdiff_t
>(old_stride);
 
  778                return sl != 
nullptr;
 
  784    inline auto dynamic_view(E&& e, 
const xdynamic_slice_vector& slices)
 
  787        using slice_vector = 
typename view_type::slice_vector_type;
 
  788        using policy = detail::adj_strides_policy<slice_vector>;
 
  789        detail::strided_view_args<policy> args;
 
  792            detail::get_strides<XTENSOR_DEFAULT_TRAVERSAL>(e),
 
  793            detail::get_offset<XTENSOR_DEFAULT_TRAVERSAL>(e),
 
  799            std::move(args.new_shape),
 
  800            std::move(args.new_strides),
 
  803            std::move(args.new_slices),
 
  804            std::move(args.new_adj_strides)
 
Base class for implementation of common expression access methods.
Base class for implementation of common expression constant access methods.
const_reference front() const
size_type size() const noexcept(noexcept(derived_cast().shape()))
size_type dimension() const noexcept
bool in_bounds(Args... args) const
const_reference back() const
const inner_shape_type & shape() const noexcept
Returns the shape of the xtrided_view_base.
layout_type layout() const noexcept
Returns the layout of the xtrided_view_base.
Base class for xexpressions.
Base class for multidimensional iterable expressions.
layout_type layout() const noexcept
xstrided_view_base(CTA &&e, SA &&shape, strides_type &&strides, size_type offset, layout_type layout) noexcept
Constructs an xstrided_view_base.
bool broadcast_shape(O &shape, bool reuse_cache=false) const
const inner_shape_type & shape() const noexcept
storage_type & storage() noexcept
xexpression_type & expression() noexcept
auto strides(const E &e, stride_type type=stride_type::normal) noexcept
Get strides of an object.
standard mathematical functions for xexpressions
xarray_container< uvector< T, A >, L, xt::svector< typename uvector< T, A >::size_type, 4, SA, true > > xarray
Alias template on xarray_container with default parameters for data container type and shape / stride...