| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921 |
- /***************************************************************************
- * Copyright (c) Johan Mabille, Sylvain Corlay and Wolf Vollprecht *
- * Copyright (c) QuantStack *
- * *
- * Distributed under the terms of the BSD 3-Clause License. *
- * *
- * The full license is in the file LICENSE, distributed with this software. *
- ****************************************************************************/
- #ifndef XTENSOR_STRIDED_VIEW_HPP
- #define XTENSOR_STRIDED_VIEW_HPP
- #include <algorithm>
- #include <cstddef>
- #include <tuple>
- #include <type_traits>
- #include <utility>
- #include <xtl/xsequence.hpp>
- #include <xtl/xvariant.hpp>
- #include "xexpression.hpp"
- #include "xiterable.hpp"
- #include "xlayout.hpp"
- #include "xsemantic.hpp"
- #include "xstorage.hpp"
- #include "xstrided_view_base.hpp"
- #include "xutils.hpp"
- namespace xt
- {
- /***************************
- * xstrided_view extension *
- ***************************/
- namespace extension
- {
- template <class Tag, class CT, class S, layout_type L, class FST>
- struct xstrided_view_base_impl;
- template <class CT, class S, layout_type L, class FST>
- struct xstrided_view_base_impl<xtensor_expression_tag, CT, S, L, FST>
- {
- using type = xtensor_empty_base;
- };
- template <class CT, class S, layout_type L, class FST>
- struct xstrided_view_base : xstrided_view_base_impl<xexpression_tag_t<CT>, CT, S, L, FST>
- {
- };
- template <class CT, class S, layout_type L, class FST>
- using xstrided_view_base_t = typename xstrided_view_base<CT, S, L, FST>::type;
- }
- template <layout_type L1, layout_type L2, class T>
- struct select_iterable_base
- {
- using type = std::conditional_t<L1 == L2 && L1 != layout_type::dynamic, xcontiguous_iterable<T>, xiterable<T>>;
- };
- template <layout_type L1, layout_type L2, class T>
- using select_iterable_base_t = typename select_iterable_base<L1, L2, T>::type;
- template <class CT, class S, layout_type L, class FST>
- class xstrided_view;
- template <class CT, class S, layout_type L, class FST>
- struct xcontainer_inner_types<xstrided_view<CT, S, L, FST>>
- {
- using xexpression_type = std::decay_t<CT>;
- using undecay_expression = CT;
- using reference = inner_reference_t<undecay_expression>;
- using const_reference = typename xexpression_type::const_reference;
- using size_type = typename xexpression_type::size_type;
- using shape_type = std::decay_t<S>;
- using undecay_shape = S;
- using storage_getter = FST;
- using inner_storage_type = typename storage_getter::type;
- using temporary_type = typename detail::xtype_for_shape<
- S>::template type<typename xexpression_type::value_type, xexpression_type::static_layout>;
- using storage_type = std::remove_reference_t<inner_storage_type>;
- static constexpr layout_type layout = L;
- };
- template <class CT, class S, layout_type L, class FST>
- struct xiterable_inner_types<xstrided_view<CT, S, L, FST>>
- {
- using inner_shape_type = std::decay_t<S>;
- using inner_strides_type = get_strides_t<inner_shape_type>;
- using inner_backstrides_type_type = inner_strides_type;
- using const_stepper = std::conditional_t<
- is_indexed_stepper<typename std::decay_t<CT>::stepper>::value,
- xindexed_stepper<const xstrided_view<CT, S, L, FST>, true>,
- xstepper<const xstrided_view<CT, S, L, FST>>>;
- using stepper = std::conditional_t<
- is_indexed_stepper<typename std::decay_t<CT>::stepper>::value,
- xindexed_stepper<xstrided_view<CT, S, L, FST>, false>,
- xstepper<xstrided_view<CT, S, L, FST>>>;
- };
- template <class CT, class S, layout_type L, class FST, class RHS>
- struct can_assign<xstrided_view<CT, S, L, FST>, RHS> : can_assign<CT, RHS>
- {
- };
- /*****************
- * xstrided_view *
- *****************/
- /**
- * @class xstrided_view
- * @brief View of an xexpression using strides
- *
- * The xstrided_view class implements a view utilizing an initial offset
- * and strides.
- *
- * @tparam CT the closure type of the \ref xexpression type underlying this view
- * @tparam L the layout of the strided view
- * @tparam S the strides type of the strided view
- * @tparam FST the flat storage type used for the strided view
- *
- * @sa strided_view, transpose
- */
- template <class CT, class S, layout_type L = layout_type::dynamic, class FST = detail::flat_storage_getter<CT, XTENSOR_DEFAULT_TRAVERSAL>>
- class xstrided_view
- : public xview_semantic<xstrided_view<CT, S, L, FST>>,
- public select_iterable_base_t<L, std::decay_t<CT>::static_layout, xstrided_view<CT, S, L, FST>>,
- private xstrided_view_base<xstrided_view<CT, S, L, FST>>,
- public extension::xstrided_view_base_t<CT, S, L, FST>
- {
- public:
- using self_type = xstrided_view<CT, S, L, FST>;
- using base_type = xstrided_view_base<self_type>;
- using semantic_base = xview_semantic<self_type>;
- using extension_base = extension::xstrided_view_base_t<CT, S, L, FST>;
- using expression_tag = typename extension_base::expression_tag;
- using xexpression_type = typename base_type::xexpression_type;
- using base_type::is_const;
- using value_type = typename base_type::value_type;
- using reference = typename base_type::reference;
- using const_reference = typename base_type::const_reference;
- using pointer = typename base_type::pointer;
- using const_pointer = typename base_type::const_pointer;
- using size_type = typename base_type::size_type;
- using difference_type = typename base_type::difference_type;
- using inner_storage_type = typename base_type::inner_storage_type;
- using storage_type = typename base_type::storage_type;
- using linear_iterator = typename storage_type::iterator;
- using const_linear_iterator = typename storage_type::const_iterator;
- using reverse_linear_iterator = std::reverse_iterator<linear_iterator>;
- using const_reverse_linear_iterator = std::reverse_iterator<const_linear_iterator>;
- using iterable_base = select_iterable_base_t<L, xexpression_type::static_layout, self_type>;
- using inner_shape_type = typename base_type::inner_shape_type;
- using inner_strides_type = typename base_type::inner_strides_type;
- using inner_backstrides_type = typename base_type::inner_backstrides_type;
- using shape_type = typename base_type::shape_type;
- using strides_type = typename base_type::strides_type;
- using backstrides_type = typename base_type::backstrides_type;
- using stepper = typename iterable_base::stepper;
- using const_stepper = typename iterable_base::const_stepper;
- using base_type::contiguous_layout;
- using base_type::static_layout;
- using temporary_type = typename xcontainer_inner_types<self_type>::temporary_type;
- using base_index_type = xindex_type_t<shape_type>;
- using data_alignment = xt_simd::container_alignment_t<storage_type>;
- using simd_type = xt_simd::simd_type<value_type>;
- using simd_value_type = xt_simd::simd_type<value_type>;
- using bool_load_type = typename base_type::bool_load_type;
- template <class CTA, class SA>
- xstrided_view(CTA&& e, SA&& shape, strides_type&& strides, std::size_t offset, layout_type layout) noexcept;
- xstrided_view(const xstrided_view& rhs) = default;
- self_type& operator=(const self_type&);
- template <class E>
- self_type& operator=(const xexpression<E>& e);
- template <class E>
- disable_xexpression<E, self_type>& operator=(const E& e);
- using base_type::backstrides;
- using base_type::dimension;
- using base_type::is_contiguous;
- using base_type::layout;
- using base_type::shape;
- using base_type::size;
- using base_type::strides;
- using base_type::operator();
- using base_type::at;
- using base_type::unchecked;
- using base_type::operator[];
- using base_type::data;
- using base_type::data_offset;
- using base_type::element;
- using base_type::expression;
- using base_type::storage;
- using base_type::broadcast_shape;
- using base_type::has_linear_assign;
- template <class T>
- void fill(const T& value);
- linear_iterator linear_begin();
- linear_iterator linear_end();
- const_linear_iterator linear_begin() const;
- const_linear_iterator linear_end() const;
- const_linear_iterator linear_cbegin() const;
- const_linear_iterator linear_cend() const;
- reverse_linear_iterator linear_rbegin();
- reverse_linear_iterator linear_rend();
- const_reverse_linear_iterator linear_rbegin() const;
- const_reverse_linear_iterator linear_rend() const;
- const_reverse_linear_iterator linear_crbegin() const;
- const_reverse_linear_iterator linear_crend() const;
- template <class ST, class STEP = stepper>
- disable_indexed_stepper_t<STEP> stepper_begin(const ST& shape);
- template <class ST, class STEP = stepper>
- disable_indexed_stepper_t<STEP> stepper_end(const ST& shape, layout_type l);
- template <class ST, class STEP = stepper>
- enable_indexed_stepper_t<STEP> stepper_begin(const ST& shape);
- template <class ST, class STEP = stepper>
- enable_indexed_stepper_t<STEP> stepper_end(const ST& shape, layout_type l);
- template <class ST, class STEP = const_stepper>
- disable_indexed_stepper_t<STEP> stepper_begin(const ST& shape) const;
- template <class ST, class STEP = const_stepper>
- disable_indexed_stepper_t<STEP> stepper_end(const ST& shape, layout_type l) const;
- template <class ST, class STEP = const_stepper>
- enable_indexed_stepper_t<STEP> stepper_begin(const ST& shape) const;
- template <class ST, class STEP = const_stepper>
- enable_indexed_stepper_t<STEP> stepper_end(const ST& shape, layout_type l) const;
- template <class requested_type>
- using simd_return_type = xt_simd::simd_return_type<value_type, requested_type>;
- template <class T, class R>
- using enable_simd_interface = std::enable_if_t<has_simd_interface<T>::value && L != layout_type::dynamic, R>;
- template <class align, class simd, class T = xexpression_type>
- enable_simd_interface<T, void> store_simd(size_type i, const simd& e);
- template <
- class align,
- class requested_type = value_type,
- std::size_t N = xt_simd::simd_traits<requested_type>::size,
- class T = xexpression_type>
- enable_simd_interface<T, simd_return_type<requested_type>> load_simd(size_type i) const;
- reference data_element(size_type i);
- const_reference data_element(size_type i) const;
- reference flat(size_type i);
- const_reference flat(size_type i) const;
- using container_iterator = std::
- conditional_t<is_const, typename storage_type::const_iterator, typename storage_type::iterator>;
- using const_container_iterator = typename storage_type::const_iterator;
- template <class E>
- using rebind_t = xstrided_view<E, S, L, typename FST::template rebind_t<E>>;
- template <class E>
- rebind_t<E> build_view(E&& e) const;
- private:
- container_iterator data_xbegin() noexcept;
- const_container_iterator data_xbegin() const noexcept;
- container_iterator data_xend(layout_type l, size_type offset) noexcept;
- const_container_iterator data_xend(layout_type l, size_type offset) const noexcept;
- template <class It>
- It data_xbegin_impl(It begin) const noexcept;
- template <class It>
- It data_xend_impl(It end, layout_type l, size_type offset) const noexcept;
- void assign_temporary_impl(temporary_type&& tmp);
- using base_type::set_offset;
- template <class C>
- friend class xstepper;
- friend class xview_semantic<self_type>;
- friend class xaccessible<self_type>;
- friend class xconst_accessible<self_type>;
- template <class D>
- friend class xaxis_iterator;
- template <class D>
- friend class xaxis_slice_iterator;
- };
- /**************************
- * xstrided_view builders *
- **************************/
- template <class T>
- using xstrided_slice = xtl::variant<
- T,
- xrange_adaptor<placeholders::xtuph, T, T>,
- xrange_adaptor<T, placeholders::xtuph, T>,
- xrange_adaptor<T, T, placeholders::xtuph>,
- xrange_adaptor<T, placeholders::xtuph, placeholders::xtuph>,
- xrange_adaptor<placeholders::xtuph, T, placeholders::xtuph>,
- xrange_adaptor<placeholders::xtuph, placeholders::xtuph, T>,
- xrange_adaptor<T, T, T>,
- xrange_adaptor<placeholders::xtuph, placeholders::xtuph, placeholders::xtuph>,
- xrange<T>,
- xstepped_range<T>,
- xall_tag,
- xellipsis_tag,
- xnewaxis_tag>;
- /**
- * @typedef xstrided_slice_vector
- * @brief vector of slices used to build a `xstrided_view`
- */
- using xstrided_slice_vector = std::vector<xstrided_slice<std::ptrdiff_t>>;
- template <layout_type L = layout_type::dynamic, class E, class S, class X>
- auto strided_view(E&& e, S&& shape, X&& stride, std::size_t offset = 0, layout_type layout = L) noexcept;
- template <class E>
- auto strided_view(E&& e, const xstrided_slice_vector& slices);
- /********************************
- * xstrided_view implementation *
- ********************************/
- /**
- * @name Constructor
- */
- //@{
- /**
- * Constructs an xstrided_view
- *
- * @param e the underlying xexpression for this view
- * @param shape the shape of the view
- * @param strides the strides of the view
- * @param offset the offset of the first element in the underlying container
- * @param layout the layout of the view
- */
- template <class CT, class S, layout_type L, class FST>
- template <class CTA, class SA>
- inline xstrided_view<CT, S, L, FST>::xstrided_view(
- CTA&& e,
- SA&& shape,
- strides_type&& strides,
- std::size_t offset,
- layout_type layout
- ) noexcept
- : base_type(std::forward<CTA>(e), std::forward<SA>(shape), std::move(strides), offset, layout)
- {
- }
- //@}
- template <class CT, class S, layout_type L, class FST>
- inline auto xstrided_view<CT, S, L, FST>::operator=(const self_type& rhs) -> self_type&
- {
- temporary_type tmp(rhs);
- return this->assign_temporary(std::move(tmp));
- }
- /**
- * @name Extended copy semantic
- */
- //@{
- /**
- * The extended assignment operator.
- */
- template <class CT, class S, layout_type L, class FST>
- template <class E>
- inline auto xstrided_view<CT, S, L, FST>::operator=(const xexpression<E>& e) -> self_type&
- {
- return semantic_base::operator=(e);
- }
- //@}
- template <class CT, class S, layout_type L, class FST>
- template <class E>
- inline auto xstrided_view<CT, S, L, FST>::operator=(const E& e) -> disable_xexpression<E, self_type>&
- {
- this->fill(e);
- return *this;
- }
- namespace xstrided_view_detail
- {
- template <class V, class T>
- inline void run_assign_temporary_impl(V& v, const T& t, std::true_type /* enable strided assign */)
- {
- strided_loop_assigner<true>::run(v, t);
- }
- template <class V, class T>
- inline void
- run_assign_temporary_impl(V& v, const T& t, std::false_type /* fallback to iterator assign */)
- {
- std::copy(t.cbegin(), t.cend(), v.begin());
- }
- }
- template <class CT, class S, layout_type L, class FST>
- inline void xstrided_view<CT, S, L, FST>::assign_temporary_impl(temporary_type&& tmp)
- {
- constexpr bool
- fast_assign = xassign_traits<xstrided_view<CT, S, L, FST>, temporary_type>::simd_strided_assign();
- xstrided_view_detail::run_assign_temporary_impl(*this, tmp, std::integral_constant<bool, fast_assign>{});
- }
- /**
- * @name Data
- */
- //@{
- /**
- * Fills the view with the given value.
- * @param value the value to fill the view with.
- */
- template <class CT, class S, layout_type L, class FST>
- template <class T>
- inline void xstrided_view<CT, S, L, FST>::fill(const T& value)
- {
- if (layout() != layout_type::dynamic)
- {
- std::fill(this->linear_begin(), this->linear_end(), value);
- }
- else
- {
- std::fill(this->begin(), this->end(), value);
- }
- }
- //@}
- template <class CT, class S, layout_type L, class FST>
- inline auto xstrided_view<CT, S, L, FST>::data_element(size_type i) -> reference
- {
- return storage()[i];
- }
- template <class CT, class S, layout_type L, class FST>
- inline auto xstrided_view<CT, S, L, FST>::data_element(size_type i) const -> const_reference
- {
- return storage()[i];
- }
- template <class CT, class S, layout_type L, class FST>
- inline auto xstrided_view<CT, S, L, FST>::flat(size_type i) -> reference
- {
- return storage()[i];
- }
- template <class CT, class S, layout_type L, class FST>
- inline auto xstrided_view<CT, S, L, FST>::flat(size_type i) const -> const_reference
- {
- return storage()[i];
- }
- template <class CT, class S, layout_type L, class FST>
- inline auto xstrided_view<CT, S, L, FST>::linear_begin() -> linear_iterator
- {
- return this->storage().begin() + static_cast<std::ptrdiff_t>(data_offset());
- }
- template <class CT, class S, layout_type L, class FST>
- inline auto xstrided_view<CT, S, L, FST>::linear_end() -> linear_iterator
- {
- return this->storage().begin() + static_cast<std::ptrdiff_t>(data_offset() + size());
- }
- template <class CT, class S, layout_type L, class FST>
- inline auto xstrided_view<CT, S, L, FST>::linear_begin() const -> const_linear_iterator
- {
- return this->linear_cbegin();
- }
- template <class CT, class S, layout_type L, class FST>
- inline auto xstrided_view<CT, S, L, FST>::linear_end() const -> const_linear_iterator
- {
- return this->linear_cend();
- }
- template <class CT, class S, layout_type L, class FST>
- inline auto xstrided_view<CT, S, L, FST>::linear_cbegin() const -> const_linear_iterator
- {
- return this->storage().cbegin() + static_cast<std::ptrdiff_t>(data_offset());
- }
- template <class CT, class S, layout_type L, class FST>
- inline auto xstrided_view<CT, S, L, FST>::linear_cend() const -> const_linear_iterator
- {
- return this->storage().cbegin() + static_cast<std::ptrdiff_t>(data_offset() + size());
- }
- template <class CT, class S, layout_type L, class FST>
- inline auto xstrided_view<CT, S, L, FST>::linear_rbegin() -> reverse_linear_iterator
- {
- return reverse_linear_iterator(this->linear_begin());
- }
- template <class CT, class S, layout_type L, class FST>
- inline auto xstrided_view<CT, S, L, FST>::linear_rend() -> reverse_linear_iterator
- {
- return reverse_linear_iterator(this->linear_end());
- }
- template <class CT, class S, layout_type L, class FST>
- inline auto xstrided_view<CT, S, L, FST>::linear_rbegin() const -> const_reverse_linear_iterator
- {
- return this->linear_crbegin();
- }
- template <class CT, class S, layout_type L, class FST>
- inline auto xstrided_view<CT, S, L, FST>::linear_rend() const -> const_reverse_linear_iterator
- {
- return this->linear_crend();
- }
- template <class CT, class S, layout_type L, class FST>
- inline auto xstrided_view<CT, S, L, FST>::linear_crbegin() const -> const_reverse_linear_iterator
- {
- return const_reverse_linear_iterator(this->linear_cbegin());
- }
- template <class CT, class S, layout_type L, class FST>
- inline auto xstrided_view<CT, S, L, FST>::linear_crend() const -> const_reverse_linear_iterator
- {
- return const_reverse_linear_iterator(this->linear_cend());
- }
- /***************
- * stepper api *
- ***************/
- template <class CT, class S, layout_type L, class FST>
- template <class ST, class STEP>
- inline auto xstrided_view<CT, S, L, FST>::stepper_begin(const ST& shape) -> disable_indexed_stepper_t<STEP>
- {
- size_type offset = shape.size() - dimension();
- return stepper(this, data_xbegin(), offset);
- }
- template <class CT, class S, layout_type L, class FST>
- template <class ST, class STEP>
- inline auto xstrided_view<CT, S, L, FST>::stepper_end(const ST& shape, layout_type l)
- -> disable_indexed_stepper_t<STEP>
- {
- size_type offset = shape.size() - dimension();
- return stepper(this, data_xend(l, offset), offset);
- }
- template <class CT, class S, layout_type L, class FST>
- template <class ST, class STEP>
- inline auto xstrided_view<CT, S, L, FST>::stepper_begin(const ST& shape) -> enable_indexed_stepper_t<STEP>
- {
- size_type offset = shape.size() - dimension();
- return stepper(this, offset);
- }
- template <class CT, class S, layout_type L, class FST>
- template <class ST, class STEP>
- inline auto xstrided_view<CT, S, L, FST>::stepper_end(const ST& shape, layout_type /*l*/)
- -> enable_indexed_stepper_t<STEP>
- {
- size_type offset = shape.size() - dimension();
- return stepper(this, offset, true);
- }
- template <class CT, class S, layout_type L, class FST>
- template <class ST, class STEP>
- inline auto xstrided_view<CT, S, L, FST>::stepper_begin(const ST& shape) const
- -> disable_indexed_stepper_t<STEP>
- {
- size_type offset = shape.size() - dimension();
- return const_stepper(this, data_xbegin(), offset);
- }
- template <class CT, class S, layout_type L, class FST>
- template <class ST, class STEP>
- inline auto xstrided_view<CT, S, L, FST>::stepper_end(const ST& shape, layout_type l) const
- -> disable_indexed_stepper_t<STEP>
- {
- size_type offset = shape.size() - dimension();
- return const_stepper(this, data_xend(l, offset), offset);
- }
- template <class CT, class S, layout_type L, class FST>
- template <class ST, class STEP>
- inline auto xstrided_view<CT, S, L, FST>::stepper_begin(const ST& shape) const
- -> enable_indexed_stepper_t<STEP>
- {
- size_type offset = shape.size() - dimension();
- return const_stepper(this, offset);
- }
- template <class CT, class S, layout_type L, class FST>
- template <class ST, class STEP>
- inline auto xstrided_view<CT, S, L, FST>::stepper_end(const ST& shape, layout_type /*l*/) const
- -> enable_indexed_stepper_t<STEP>
- {
- size_type offset = shape.size() - dimension();
- return const_stepper(this, offset, true);
- }
- template <class CT, class S, layout_type L, class FST>
- template <class It>
- inline It xstrided_view<CT, S, L, FST>::data_xbegin_impl(It begin) const noexcept
- {
- return begin + static_cast<std::ptrdiff_t>(this->data_offset());
- }
- template <class CT, class S, layout_type L, class FST>
- template <class It>
- inline It
- xstrided_view<CT, S, L, FST>::data_xend_impl(It begin, layout_type l, size_type offset) const noexcept
- {
- return strided_data_end(*this, begin + std::ptrdiff_t(this->data_offset()), l, offset);
- }
- template <class CT, class S, layout_type L, class FST>
- inline auto xstrided_view<CT, S, L, FST>::data_xbegin() noexcept -> container_iterator
- {
- return data_xbegin_impl(this->storage().begin());
- }
- template <class CT, class S, layout_type L, class FST>
- inline auto xstrided_view<CT, S, L, FST>::data_xbegin() const noexcept -> const_container_iterator
- {
- return data_xbegin_impl(this->storage().cbegin());
- }
- template <class CT, class S, layout_type L, class FST>
- inline auto xstrided_view<CT, S, L, FST>::data_xend(layout_type l, size_type offset) noexcept
- -> container_iterator
- {
- return data_xend_impl(this->storage().begin(), l, offset);
- }
- template <class CT, class S, layout_type L, class FST>
- inline auto xstrided_view<CT, S, L, FST>::data_xend(layout_type l, size_type offset) const noexcept
- -> const_container_iterator
- {
- return data_xend_impl(this->storage().cbegin(), l, offset);
- }
- template <class CT, class S, layout_type L, class FST>
- template <class alignment, class simd, class T>
- inline auto xstrided_view<CT, S, L, FST>::store_simd(size_type i, const simd& e)
- -> enable_simd_interface<T, void>
- {
- using align_mode = driven_align_mode_t<alignment, data_alignment>;
- xt_simd::store_as(&(storage()[i]), e, align_mode());
- }
- template <class CT, class S, layout_type L, class FST>
- template <class alignment, class requested_type, std::size_t N, class T>
- inline auto xstrided_view<CT, S, L, FST>::load_simd(size_type i) const
- -> enable_simd_interface<T, simd_return_type<requested_type>>
- {
- using align_mode = driven_align_mode_t<alignment, data_alignment>;
- return xt_simd::load_as<requested_type>(&(storage()[i]), align_mode());
- }
- template <class CT, class S, layout_type L, class FST>
- template <class E>
- inline auto xstrided_view<CT, S, L, FST>::build_view(E&& e) const -> rebind_t<E>
- {
- inner_shape_type sh(this->shape());
- inner_strides_type str(this->strides());
- return rebind_t<E>(
- std::forward<E>(e),
- std::move(sh),
- std::move(str),
- base_type::data_offset(),
- this->layout()
- );
- }
- /*****************************************
- * xstrided_view builders implementation *
- *****************************************/
- /**
- * Construct a strided view from an xexpression, shape, strides and offset.
- *
- * @param e xexpression
- * @param shape the shape of the view
- * @param strides the new strides of the view
- * @param offset the offset of the first element in the underlying container
- * @param layout the new layout of the expression
- *
- * @tparam L the static layout type of the view (default: dynamic)
- * @tparam E type of xexpression
- * @tparam S strides type
- * @tparam X strides type
- *
- * @return the view
- */
- template <layout_type L, class E, class S, class X>
- inline auto strided_view(E&& e, S&& shape, X&& strides, std::size_t offset, layout_type layout) noexcept
- {
- using view_type = xstrided_view<xclosure_t<E>, S, L>;
- return view_type(std::forward<E>(e), std::forward<S>(shape), std::forward<X>(strides), offset, layout);
- }
- namespace detail
- {
- struct no_adj_strides_policy
- {
- protected:
- inline void resize(std::size_t)
- {
- }
- inline void set_fake_slice(std::size_t)
- {
- }
- template <class ST, class S>
- bool fill_args(
- const xstrided_slice_vector& /*slices*/,
- std::size_t /*sl_idx*/,
- std::size_t /*i*/,
- std::size_t /*old_shape*/,
- const ST& /*old_stride*/,
- S& /*shape*/,
- get_strides_t<S>& /*strides*/
- )
- {
- return false;
- }
- };
- }
- /**
- * Function to create a dynamic view from
- * an xexpression and an xstrided_slice_vector.
- *
- * @param e xexpression
- * @param slices the slice vector
- *
- * @return initialized strided_view according to slices
- *
- * @code{.cpp}
- * xt::xarray<double> a = {{1, 2, 3}, {4, 5, 6}};
- * xt::xstrided_slice_vector sv({xt::range(0, 1)});
- * sv.push_back(xt::range(0, 3, 2));
- * auto v = xt::strided_view(a, sv);
- * // ==> {{1, 3}}
- * @endcode
- *
- * You can also achieve the same with the following short-hand syntax:
- *
- * @code{.cpp}
- * xt::xarray<double> a = {{1, 2, 3}, {4, 5, 6}};
- * auto v = xt::strided_view(a, {xt::range(0, 1), xt::range(0, 3, 2)});
- * // ==> {{1, 3}}
- * @endcode
- */
- template <class E>
- inline auto strided_view(E&& e, const xstrided_slice_vector& slices)
- {
- detail::strided_view_args<detail::no_adj_strides_policy> args;
- args.fill_args(
- e.shape(),
- detail::get_strides<XTENSOR_DEFAULT_TRAVERSAL>(e),
- detail::get_offset<XTENSOR_DEFAULT_TRAVERSAL>(e),
- e.layout(),
- slices
- );
- using view_type = xstrided_view<xclosure_t<E>, decltype(args.new_shape)>;
- return view_type(
- std::forward<E>(e),
- std::move(args.new_shape),
- std::move(args.new_strides),
- args.new_offset,
- args.new_layout
- );
- }
- namespace detail
- {
- template <typename S>
- struct rebind_shape;
- template <std::size_t... X>
- struct rebind_shape<xt::fixed_shape<X...>>
- {
- using type = xt::fixed_shape<X...>;
- };
- template <class S>
- struct rebind_shape
- {
- using type = rebind_container_t<size_t, S>;
- };
- template <
- class S,
- std::enable_if_t<std::is_signed<get_value_type_t<typename std::decay<S>::type>>::value, bool> = true>
- inline void recalculate_shape_impl(S& shape, size_t size)
- {
- using value_type = get_value_type_t<typename std::decay_t<S>>;
- XTENSOR_ASSERT(std::count(shape.cbegin(), shape.cend(), -1) <= 1);
- auto iter = std::find(shape.begin(), shape.end(), -1);
- if (iter != std::end(shape))
- {
- const auto total = std::accumulate(shape.cbegin(), shape.cend(), -1, std::multiplies<int>{});
- const auto missing_dimension = size / total;
- (*iter) = static_cast<value_type>(missing_dimension);
- }
- }
- template <
- class S,
- std::enable_if_t<!std::is_signed<get_value_type_t<typename std::decay<S>::type>>::value, bool> = true>
- inline void recalculate_shape_impl(S&, size_t)
- {
- }
- template <class S>
- inline auto recalculate_shape(S&& shape, size_t size)
- {
- return recalculate_shape_impl(shape, size);
- }
- }
- template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL, class E, class S>
- inline auto reshape_view(E&& e, S&& shape)
- {
- static_assert(
- L == layout_type::row_major || L == layout_type::column_major,
- "traversal has to be row or column major"
- );
- using shape_type = std::decay_t<decltype(shape)>;
- using unsigned_shape_type = typename detail::rebind_shape<shape_type>::type;
- get_strides_t<unsigned_shape_type> strides;
- detail::recalculate_shape(shape, e.size());
- xt::resize_container(strides, shape.size());
- compute_strides(shape, L, strides);
- constexpr auto computed_layout = std::decay_t<E>::static_layout == L ? L : layout_type::dynamic;
- using view_type = xstrided_view<
- xclosure_t<E>,
- unsigned_shape_type,
- computed_layout,
- detail::flat_adaptor_getter<xclosure_t<E>, L>>;
- return view_type(
- std::forward<E>(e),
- xtl::forward_sequence<unsigned_shape_type, S>(shape),
- std::move(strides),
- 0,
- e.layout()
- );
- }
- /**
- * @deprecated
- * @brief Return a view on a container with a new shape
- *
- * Note: if you resize the underlying container, this view becomes
- * invalidated.
- *
- * @param e xexpression to reshape
- * @param shape new shape
- * @param order traversal order (optional)
- *
- * @return view on xexpression with new shape
- */
- template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL, class E, class S>
- inline auto reshape_view(E&& e, S&& shape, layout_type /*order*/)
- {
- return reshape_view<L>(std::forward<E>(e), std::forward<S>(shape));
- }
- template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL, class E, class I, std::size_t N>
- inline auto reshape_view(E&& e, const I (&shape)[N], layout_type order)
- {
- using shape_type = std::array<std::size_t, N>;
- return reshape_view<L>(std::forward<E>(e), xtl::forward_sequence<shape_type, decltype(shape)>(shape), order);
- }
- template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL, class E, class I, std::size_t N>
- inline auto reshape_view(E&& e, const I (&shape)[N])
- {
- using shape_type = std::array<I, N>;
- return reshape_view<L>(std::forward<E>(e), xtl::forward_sequence<shape_type, decltype(shape)>(shape));
- }
- }
- #endif
|