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 "xaccessible.hpp"
27#include "xbroadcast.hpp"
28#include "xcontainer.hpp"
29#include "xiterable.hpp"
30#include "xsemantic.hpp"
33#include "xtensor_config.hpp"
34#include "xtensor_forward.hpp"
35#include "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>
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 xtl::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 xtl::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 CT,
class... S>
295 using xexpression_type = std::decay_t<CT>;
297 using const_reference =
typename xexpression_type::const_reference;
298 using size_type =
typename xexpression_type::size_type;
301 static constexpr layout_type layout = detail::is_contiguous_view<xexpression_type,
S...>::value
302 ? xexpression_type::static_layout
305 static constexpr bool is_const = std::is_const<std::remove_reference_t<CT>>::value;
307 using extract_storage_type = xtl::mpl::eval_if_t<
309 detail::expr_storage_type<xexpression_type>,
311 using storage_type = std::conditional_t<is_const, const extract_storage_type, extract_storage_type>;
314 template <
class CT,
class...
S>
317 using xexpression_type = std::decay_t<CT>;
319 static constexpr bool is_strided_view = detail::is_strided_view<xexpression_type,
S...>::value;
320 static constexpr bool is_contiguous_view = detail::is_contiguous_view<xexpression_type,
S...>::value;
322 using inner_shape_type = std::conditional_t<
324 typename detail::get_contigous_shape_type<xexpression_type,
S...>::type,
327 using stepper = std::conditional_t<
332 using const_stepper = std::conditional_t<
352 template <
class CT,
class...
S>
354 public std::conditional_t<
355 detail::is_contiguous_view<std::decay_t<CT>, S...>::value,
356 xcontiguous_iterable<xview<CT, S...>>,
357 xiterable<xview<CT, S...>>>,
359 public extension::xview_base_t<CT, S...>
365 using xexpression_type = std::decay_t<CT>;
370 using extension_base = extension::xview_base_t<
CT,
S...>;
371 using expression_tag =
typename extension_base::expression_tag;
373 static constexpr bool is_const = std::is_const<std::remove_reference_t<CT>>::value;
374 using value_type =
typename xexpression_type::value_type;
375 using simd_value_type = xt_simd::simd_type<value_type>;
376 using bool_load_type =
typename xexpression_type::bool_load_type;
377 using reference =
typename inner_types::reference;
378 using const_reference =
typename inner_types::const_reference;
379 using pointer = std::
380 conditional_t<is_const, typename xexpression_type::const_pointer, typename xexpression_type::pointer>;
381 using const_pointer =
typename xexpression_type::const_pointer;
382 using size_type =
typename inner_types::size_type;
383 using difference_type =
typename xexpression_type::difference_type;
385 static constexpr layout_type static_layout = inner_types::layout;
388 static constexpr bool is_strided_view = detail::is_strided_view<xexpression_type,
S...>::value;
389 static constexpr bool is_contiguous_view = contiguous_layout;
392 using inner_shape_type =
typename iterable_base::inner_shape_type;
393 using shape_type =
typename xview_shape_type<
typename xexpression_type::shape_type,
S...>::type;
395 using xexpression_inner_strides_type = xtl::mpl::eval_if_t<
397 detail::expr_inner_strides_type<xexpression_type>,
400 using xexpression_inner_backstrides_type = xtl::mpl::eval_if_t<
402 detail::expr_inner_backstrides_type<xexpression_type>,
405 using storage_type =
typename inner_types::storage_type;
407 static constexpr bool has_trivial_strides = is_contiguous_view
408 && !xtl::disjunction<detail::is_xrange<S>...>::value;
409 using inner_strides_type = std::conditional_t<
411 typename detail::unwrap_offset_container<
412 xexpression_type::static_layout,
413 xexpression_inner_strides_type,
414 integral_count<
S...>()>::type,
417 using inner_backstrides_type = std::conditional_t<
419 typename detail::unwrap_offset_container<
420 xexpression_type::static_layout,
421 xexpression_inner_backstrides_type,
422 integral_count<
S...>()>::type,
429 using slice_type = std::tuple<
S...>;
431 using stepper =
typename iterable_base::stepper;
432 using const_stepper =
typename iterable_base::const_stepper;
434 using linear_iterator = std::conditional_t<
436 std::conditional_t<is_const, typename xexpression_type::const_linear_iterator, typename xexpression_type::linear_iterator>,
437 typename iterable_base::linear_iterator>;
438 using const_linear_iterator = std::conditional_t<
440 typename xexpression_type::const_linear_iterator,
443 using reverse_linear_iterator = std::reverse_iterator<linear_iterator>;
444 using const_reverse_linear_iterator = std::reverse_iterator<const_linear_iterator>;
446 using container_iterator = pointer;
447 using const_container_iterator = const_pointer;
448 static constexpr std::size_t rank =
SIZE_MAX;
452 template <
class CTA,
class FSL,
class...
SL>
464 const inner_shape_type&
shape()
const noexcept;
465 const slice_type&
slices()
const noexcept;
467 bool is_contiguous()
const noexcept;
471 void fill(
const T& value);
473 template <
class...
Args>
475 template <
class...
Args>
480 template <
class...
Args>
481 const_reference operator()(
Args...
args)
const;
482 template <
class...
Args>
483 const_reference unchecked(
Args...
args)
const;
488 const xexpression_type&
expression()
const noexcept;
496 template <
class ST,
bool Enable = is_str
ided_view>
497 std::enable_if_t<!Enable, stepper> stepper_begin(
const ST&
shape);
498 template <
class ST,
bool Enable = is_str
ided_view>
501 template <
class ST,
bool Enable = is_str
ided_view>
502 std::enable_if_t<!Enable, const_stepper> stepper_begin(
const ST&
shape)
const;
503 template <
class ST,
bool Enable = is_str
ided_view>
504 std::enable_if_t<!Enable, const_stepper> stepper_end(
const ST&
shape,
layout_type l)
const;
506 template <
class ST,
bool Enable = is_str
ided_view>
507 std::enable_if_t<Enable, stepper> stepper_begin(
const ST&
shape);
508 template <
class ST,
bool Enable = is_str
ided_view>
511 template <
class ST,
bool Enable = is_str
ided_view>
512 std::enable_if_t<Enable, const_stepper> stepper_begin(
const ST&
shape)
const;
513 template <
class ST,
bool Enable = is_str
ided_view>
516 template <
class T = xexpression_type>
517 std::enable_if_t<has_data_interface<T>::value, storage_type&> storage();
519 template <
class T = xexpression_type>
520 std::enable_if_t<has_data_interface<T>::value,
const storage_type&> storage()
const;
522 template <
class T = xexpression_type>
523 std::enable_if_t<has_data_interface<T>::value && is_strided_view, linear_iterator> linear_begin();
525 template <
class T = xexpression_type>
526 std::enable_if_t<has_data_interface<T>::value && is_strided_view, linear_iterator> linear_end();
528 template <
class T = xexpression_type>
529 std::enable_if_t<has_data_interface<T>::value && is_strided_view, const_linear_iterator>
530 linear_begin()
const;
532 template <
class T = xexpression_type>
533 std::enable_if_t<has_data_interface<T>::value && is_strided_view, const_linear_iterator>
536 template <
class T = xexpression_type>
537 std::enable_if_t<has_data_interface<T>::value && is_strided_view, const_linear_iterator>
538 linear_cbegin()
const;
540 template <
class T = xexpression_type>
541 std::enable_if_t<has_data_interface<T>::value && is_strided_view, const_linear_iterator>
544 template <
class T = xexpression_type>
545 std::enable_if_t<has_data_interface<T>::value && is_strided_view, reverse_linear_iterator>
548 template <
class T = xexpression_type>
549 std::enable_if_t<has_data_interface<T>::value && is_strided_view, reverse_linear_iterator>
552 template <
class T = xexpression_type>
553 std::enable_if_t<has_data_interface<T>::value && is_strided_view, const_reverse_linear_iterator>
554 linear_rbegin()
const;
556 template <
class T = xexpression_type>
557 std::enable_if_t<has_data_interface<T>::value && is_strided_view, const_reverse_linear_iterator>
560 template <
class T = xexpression_type>
561 std::enable_if_t<has_data_interface<T>::value && is_strided_view, const_reverse_linear_iterator>
562 linear_crbegin()
const;
564 template <
class T = xexpression_type>
565 std::enable_if_t<has_data_interface<T>::value && is_strided_view, const_reverse_linear_iterator>
566 linear_crend()
const;
568 template <
class T = xexpression_type>
569 std::enable_if_t<has_data_interface<T>::value && is_strided_view,
const inner_strides_type&>
572 template <
class T = xexpression_type>
573 std::enable_if_t<has_data_interface<T>::value && is_strided_view,
const inner_strides_type&>
576 template <
class T = xexpression_type>
577 std::enable_if_t<has_data_interface<T>::value && is_strided_view, const_pointer> data()
const;
579 template <
class T = xexpression_type>
580 std::enable_if_t<has_data_interface<T>::value && is_strided_view, pointer> data();
582 template <
class T = xexpression_type>
583 std::enable_if_t<has_data_interface<T>::value && is_strided_view, std::size_t>
584 data_offset()
const noexcept;
587 inline It data_xbegin_impl(
It begin)
const noexcept;
591 inline container_iterator data_xbegin()
noexcept;
592 inline const_container_iterator data_xbegin()
const noexcept;
595 inline const_container_iterator data_xend(
layout_type l, size_type
offset)
const noexcept;
598 template <
class ST = self_type,
class = std::enable_if_t<is_xscalar<std::decay_t<ST>>::value,
int>>
604 template <
class ST = self_type,
class = std::enable_if_t<is_xscalar<std::decay_t<ST>>::value,
int>>
605 operator const_reference()
const
610 size_type underlying_size(size_type
dim)
const;
612 xtl::xclosure_pointer<self_type&> operator&() &;
613 xtl::xclosure_pointer<const self_type&> operator&()
const&;
614 xtl::xclosure_pointer<self_type> operator&() &&;
618 class T = xexpression_type,
619 class = std::enable_if_t<has_data_interface<T>::value && is_contiguous_view,
int>>
632 template <
class requested_type>
633 using simd_return_type = xt_simd::simd_return_type<value_type, requested_type>;
635 template <
class T,
class R>
636 using enable_simd_interface = std::enable_if_t<has_simd_interface<T>::value && is_strided_view,
R>;
638 template <
class align,
class simd,
class T = xexpression_type>
645 class T = xexpression_type>
648 template <
class T = xexpression_type>
651 template <
class T = xexpression_type>
654 template <
class T = xexpression_type>
657 template <
class T = xexpression_type>
663 template <std::
size_t I>
664 struct lesser_condition
666 static constexpr bool value = (I + newaxis_count_before<
S...>(I + 1) <
sizeof...(
S));
671 inner_shape_type m_shape;
672 mutable inner_strides_type m_strides;
673 mutable inner_backstrides_type m_backstrides;
674 mutable std::size_t m_data_offset;
675 mutable bool m_strides_computed;
677 template <
class CTA,
class FSL,
class...
SL>
680 template <
class CTA,
class FSL,
class...
SL>
683 template <
class...
Args>
684 auto make_index_sequence(
Args...
args)
const noexcept;
686 void compute_strides(std::true_type)
const;
691 template <
class Arg,
class...
Args>
694 const_reference access()
const;
696 template <
class Arg,
class...
Args>
697 const_reference access(
Arg arg,
Args...
args)
const;
700 reference unchecked_impl(std::index_sequence<I...>,
Args...
args);
703 const_reference unchecked_impl(std::index_sequence<I...>,
Args...
args)
const;
706 reference access_impl(std::index_sequence<I...>,
Args...
args);
709 const_reference access_impl(std::index_sequence<I...>,
Args...
args)
const;
712 std::enable_if_t<lesser_condition<I>::value, size_type> index(
Args...
args)
const;
715 std::enable_if_t<!lesser_condition<I>::value, size_type> index(
Args...
args)
const;
718 size_type sliced_access(
const xslice<T>& slice)
const;
724 disable_xslice<T, size_type> sliced_access(
const T&
squeeze,
Args...)
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;
748 template <
class E,
class...
S>
749 auto view(E&&
e,
S&&... slices);
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...>>;
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;
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);
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>
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),
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>
918 inline auto xview<CT, S...>::operator=(
const xview& rhs) -> self_type&
920 temporary_type tmp(rhs);
921 return this->assign_temporary(std::move(tmp));
931 template <
class CT,
class... S>
935 return semantic_base::operator=(
e);
940 template <
class CT,
class...
S>
955 template <
class CT,
class... S>
964 template <
class CT,
class...
S>
973 template <
class CT,
class...
S>
976 return xtl::mpl::static_if<is_strided_view>(
981 return static_layout;
988 self(
this)->m_e.layout(),
1002 template <
class CT,
class...
S>
1019 template <
class CT,
class... S>
1023 xtl::mpl::static_if<static_layout != layout_type::dynamic>(
1026 std::fill(
self(
this)->linear_begin(),
self(
this)->linear_end(), value);
1031 std::fill(
self(
this)->begin(),
self(
this)->end(), value);
1042 template <
class CT,
class...
S>
1043 template <
class...
Args>
1046 XTENSOR_TRY(check_index(shape(),
args...));
1047 XTENSOR_CHECK_DIMENSION(shape(),
args...);
1050 return access(
static_cast<size_type
>(
args)...);
1072 template <
class CT,
class...
S>
1073 template <
class...
Args>
1076 return unchecked_impl(make_index_sequence(
args...),
static_cast<size_type
>(
args)...);
1079 template <
class CT,
class...
S>
1083 XTENSOR_TRY(check_element_index(shape(),
first,
last));
1086 return m_e.element(index.cbegin(), index.cend());
1095 template <
class CT,
class... S>
1096 template <
class... Args>
1099 XTENSOR_TRY(check_index(shape(),
args...));
1100 XTENSOR_CHECK_DIMENSION(shape(),
args...);
1103 return access(
static_cast<size_type
>(
args)...);
1125 template <
class CT,
class...
S>
1126 template <
class...
Args>
1129 return unchecked_impl(make_index_sequence(
args...),
static_cast<size_type
>(
args)...);
1132 template <
class CT,
class...
S>
1138 return m_e.element(index.cbegin(), index.cend());
1144 template <
class CT,
class... S>
1153 template <
class CT,
class...
S>
1164 template <
class CT,
class...
S>
1168 return m_e.storage();
1171 template <
class CT,
class...
S>
1176 return m_e.storage();
1179 template <
class CT,
class... S>
1181 auto xview<CT, S...>::linear_begin()
1182 -> std::enable_if_t<has_data_interface<T>::value && is_strided_view, linear_iterator>
1184 return m_e.storage().begin() + data_offset();
1187 template <
class CT,
class... S>
1189 auto xview<CT, S...>::linear_end()
1190 -> std::enable_if_t<has_data_interface<T>::value && is_strided_view, linear_iterator>
1192 return m_e.storage().begin() + data_offset() + this->size();
1195 template <
class CT,
class... S>
1197 auto xview<CT, S...>::linear_begin() const
1198 -> std::enable_if_t<has_data_interface<T>::value && is_strided_view, const_linear_iterator>
1200 return linear_cbegin();
1203 template <
class CT,
class... S>
1205 auto xview<CT, S...>::linear_end() const
1206 -> std::enable_if_t<has_data_interface<T>::value && is_strided_view, const_linear_iterator>
1208 return linear_cend();
1211 template <
class CT,
class... S>
1213 auto xview<CT, S...>::linear_cbegin() const
1214 -> std::enable_if_t<has_data_interface<T>::value && is_strided_view, const_linear_iterator>
1216 return m_e.storage().cbegin() + data_offset();
1219 template <
class CT,
class... S>
1221 auto xview<CT, S...>::linear_cend() const
1222 -> std::enable_if_t<has_data_interface<T>::value && is_strided_view, const_linear_iterator>
1224 return m_e.storage().cbegin() + data_offset() + this->size();
1227 template <
class CT,
class... S>
1229 auto xview<CT, S...>::linear_rbegin()
1230 -> std::enable_if_t<has_data_interface<T>::value && is_strided_view, reverse_linear_iterator>
1232 return reverse_linear_iterator(linear_end());
1235 template <
class CT,
class... S>
1237 auto xview<CT, S...>::linear_rend()
1238 -> std::enable_if_t<has_data_interface<T>::value && is_strided_view, reverse_linear_iterator>
1240 return reverse_linear_iterator(linear_begin());
1243 template <
class CT,
class... S>
1245 auto xview<CT, S...>::linear_rbegin() const
1246 -> std::enable_if_t<has_data_interface<T>::value && is_strided_view, const_reverse_linear_iterator>
1248 return linear_crbegin();
1251 template <
class CT,
class... S>
1253 auto xview<CT, S...>::linear_rend() const
1254 -> std::enable_if_t<has_data_interface<T>::value && is_strided_view, const_reverse_linear_iterator>
1256 return linear_crend();
1259 template <
class CT,
class... S>
1261 auto xview<CT, S...>::linear_crbegin() const
1262 -> std::enable_if_t<has_data_interface<T>::value && is_strided_view, const_reverse_linear_iterator>
1264 return const_reverse_linear_iterator(linear_end());
1267 template <
class CT,
class... S>
1269 auto xview<CT, S...>::linear_crend() const
1270 -> std::enable_if_t<has_data_interface<T>::value && is_strided_view, const_reverse_linear_iterator>
1272 return const_reverse_linear_iterator(linear_begin());
1278 template <
class CT,
class... S>
1283 if (!m_strides_computed)
1286 m_strides_computed =
true;
1291 template <
class CT,
class...
S>
1296 if (!m_strides_computed)
1299 m_strides_computed =
true;
1301 return m_backstrides;
1307 template <
class CT,
class... S>
1315 template <
class CT,
class...
S>
1318 -> std::enable_if_t<has_data_interface<T>::value && is_strided_view, pointer>
1323 template <
class CT,
class... S>
1324 template <std::size_t... I>
1325 inline std::size_t xview<CT, S...>::data_offset_impl(std::index_sequence<I...>)
const noexcept
1327 auto temp = std::array<std::ptrdiff_t,
sizeof...(S)>(
1328 {(
static_cast<ptrdiff_t
>(xt::value(std::get<I>(m_slices), 0)))...}
1331 std::ptrdiff_t result = 0;
1333 for (; i < std::min(
sizeof...(S), m_e.strides().size()); ++i)
1335 result += temp[i] * m_e.strides()[i - newaxis_count_before<S...>(i)];
1337 for (; i <
sizeof...(S); ++i)
1341 return static_cast<std::size_t
>(result) + m_e.data_offset();
1347 template <
class CT,
class... S>
1352 if (!m_strides_computed)
1355 m_strides_computed =
true;
1357 return m_data_offset;
1362 template <
class CT,
class...
S>
1368 template <
class CT,
class... S>
1369 inline auto xview<CT, S...>::operator&() & -> xtl::xclosure_pointer<self_type&>
1371 return xtl::closure_pointer(*
this);
1374 template <
class CT,
class... S>
1375 inline auto xview<CT, S...>::operator&() const& -> xtl::xclosure_pointer<const self_type&>
1377 return xtl::closure_pointer(*
this);
1380 template <
class CT,
class... S>
1381 inline auto xview<CT, S...>::operator&() && -> xtl::xclosure_pointer<self_type>
1383 return xtl::closure_pointer(std::move(*
this));
1396 template <
class CT,
class... S>
1400 return xt::broadcast_shape(m_shape, shape);
1408 template <
class CT,
class...
S>
1412 return xtl::mpl::static_if<is_strided_view>(
1428 template <
class CT,
class...
S>
1432 return begin + data_offset();
1435 template <
class CT,
class... S>
1437 inline It xview<CT, S...>::data_xend_impl(It begin,
layout_type l, size_type offset)
const noexcept
1439 return strided_data_end(*
this, begin, l, offset);
1442 template <
class CT,
class... S>
1443 inline auto xview<CT, S...>::data_xbegin() noexcept -> container_iterator
1445 return data_xbegin_impl(data());
1448 template <
class CT,
class... S>
1449 inline auto xview<CT, S...>::data_xbegin() const noexcept -> const_container_iterator
1451 return data_xbegin_impl(data());
1454 template <
class CT,
class... S>
1455 inline auto xview<CT, S...>::data_xend(
layout_type l, size_type offset)
noexcept -> container_iterator
1457 return data_xend_impl(data() + data_offset(), l, offset);
1460 template <
class CT,
class... S>
1461 inline auto xview<CT, S...>::data_xend(
layout_type l, size_type offset)
const noexcept
1462 -> const_container_iterator
1464 return data_xend_impl(data() + data_offset(), l, offset);
1468 template <
class CT,
class... S>
1469 template <
class E,
class T,
class>
1470 void xview<CT, S...>::assign_to(xexpression<E>& e,
bool force_resize)
const
1472 auto& de = e.derived_cast();
1473 de.resize(shape(), force_resize);
1474 std::copy(data() + data_offset(), data() + data_offset() + de.size(), de.template begin<static_layout>());
1477 template <
class CT,
class... S>
1478 template <
class E, std::size_t... I>
1479 inline auto xview<CT, S...>::build_view_impl(E&& e, std::index_sequence<I...>)
const -> rebind_t<E>
1481 return rebind_t<E>(std::forward<E>(e), std::get<I>(m_slices)...);
1484 template <
class CT,
class... S>
1486 inline auto xview<CT, S...>::build_view(E&& e)
const -> rebind_t<E>
1488 return build_view_impl(std::forward<E>(e), std::make_index_sequence<
sizeof...(S)>());
1491 template <
class CT,
class... S>
1492 template <
class align,
class simd,
class T>
1493 inline auto xview<CT, S...>::store_simd(size_type i,
const simd& e) -> enable_simd_interface<T, void>
1495 return m_e.template store_simd<xt_simd::unaligned_mode>(data_offset() + i, e);
1498 template <
class CT,
class... S>
1499 template <
class align,
class requested_type, std::
size_t N,
class T>
1500 inline auto xview<CT, S...>::load_simd(size_type i)
const
1501 -> enable_simd_interface<T, simd_return_type<requested_type>>
1503 return m_e.template load_simd<xt_simd::unaligned_mode, requested_type>(data_offset() + i);
1506 template <
class CT,
class... S>
1508 inline auto xview<CT, S...>::data_element(size_type i) -> enable_simd_interface<T, reference>
1510 return m_e.data_element(data_offset() + i);
1513 template <
class CT,
class... S>
1515 inline auto xview<CT, S...>::data_element(size_type i)
const -> enable_simd_interface<T, const_reference>
1517 return m_e.data_element(data_offset() + i);
1520 template <
class CT,
class... S>
1522 inline auto xview<CT, S...>::flat(size_type i) -> enable_simd_interface<T, reference>
1524 XTENSOR_ASSERT(is_contiguous());
1525 return m_e.flat(data_offset() + i);
1528 template <
class CT,
class... S>
1530 inline auto xview<CT, S...>::flat(size_type i)
const -> enable_simd_interface<T, const_reference>
1532 XTENSOR_ASSERT(is_contiguous());
1533 return m_e.flat(data_offset() + i);
1536 template <
class CT,
class... S>
1537 template <
class... Args>
1538 inline auto xview<CT, S...>::make_index_sequence(Args...) const noexcept
1540 return std::make_index_sequence<
1541 (
sizeof...(Args) + integral_count<S...>() > newaxis_count<S...>()
1542 ?
sizeof...(Args) + integral_count<S...>() - newaxis_count<S...>()
1546 template <
class CT,
class... S>
1547 template <std::size_t... I>
1548 inline auto xview<CT, S...>::compute_strides_impl(std::index_sequence<I...>)
const noexcept
1550 std::size_t original_dim = m_e.dimension();
1551 return std::array<std::ptrdiff_t,
sizeof...(I)>(
1552 {(
static_cast<std::ptrdiff_t
>(xt::step_size(std::get<integral_skip<S...>(I)>(m_slices), 1))
1553 * ((integral_skip<S...>(I) - newaxis_count_before<S...>(integral_skip<S...>(I))) < original_dim
1554 ? m_e.strides()[integral_skip<S...>(I) - newaxis_count_before<S...>(integral_skip<S...>(I))]
1559 template <
class CT,
class... S>
1560 inline void xview<CT, S...>::compute_strides(std::false_type)
const
1562 m_strides = xtl::make_sequence<inner_strides_type>(this->dimension(), 0);
1563 m_backstrides = xtl::make_sequence<inner_strides_type>(this->dimension(), 0);
1565 constexpr std::size_t n_strides =
sizeof...(S) - integral_count<S...>();
1567 auto slice_strides = compute_strides_impl(std::make_index_sequence<n_strides>());
1569 for (std::size_t i = 0; i < n_strides; ++i)
1571 m_strides[i] = slice_strides[i];
1573 detail::adapt_strides(shape(), m_strides, &m_backstrides, i);
1575 for (std::size_t i = n_strides; i < this->dimension(); ++i)
1577 m_strides[i] = m_e.strides()[i + integral_count<S...>() - newaxis_count<S...>()];
1578 detail::adapt_strides(shape(), m_strides, &m_backstrides, i);
1581 m_data_offset = data_offset_impl(std::make_index_sequence<
sizeof...(S)>());
1584 template <
class CT,
class... S>
1585 inline void xview<CT, S...>::compute_strides(std::true_type)
const
1589 template <
class CT,
class... S>
1590 inline auto xview<CT, S...>::access() -> reference
1592 return access_impl(make_index_sequence());
1595 template <
class CT,
class... S>
1596 template <
class Arg,
class... Args>
1597 inline auto xview<CT, S...>::access(Arg arg, Args... args) -> reference
1599 if (
sizeof...(Args) >= this->dimension())
1601 return access(args...);
1603 return access_impl(make_index_sequence(arg, args...), arg, args...);
1606 template <
class CT,
class... S>
1607 inline auto xview<CT, S...>::access() const -> const_reference
1609 return access_impl(make_index_sequence());
1612 template <
class CT,
class... S>
1613 template <
class Arg,
class... Args>
1614 inline auto xview<CT, S...>::access(Arg arg, Args... args)
const -> const_reference
1616 if (
sizeof...(Args) >= this->dimension())
1618 return access(args...);
1620 return access_impl(make_index_sequence(arg, args...), arg, args...);
1623 template <
class CT,
class... S>
1624 template <typename std::decay_t<CT>::size_type... I,
class... Args>
1625 inline auto xview<CT, S...>::unchecked_impl(std::index_sequence<I...>, Args... args) -> reference
1627 return m_e.unchecked(index<I>(args...)...);
1630 template <
class CT,
class... S>
1631 template <typename std::decay_t<CT>::size_type... I,
class... Args>
1632 inline auto xview<CT, S...>::unchecked_impl(std::index_sequence<I...>, Args... args)
const
1635 return m_e.unchecked(index<I>(args...)...);
1638 template <
class CT,
class... S>
1639 template <typename std::decay_t<CT>::size_type... I,
class... Args>
1640 inline auto xview<CT, S...>::access_impl(std::index_sequence<I...>, Args... args) -> reference
1642 return m_e(index<I>(args...)...);
1645 template <
class CT,
class... S>
1646 template <typename std::decay_t<CT>::size_type... I,
class... Args>
1647 inline auto xview<CT, S...>::access_impl(std::index_sequence<I...>, Args... args)
const -> const_reference
1649 return m_e(index<I>(args...)...);
1652 template <
class CT,
class... S>
1653 template <typename std::decay_t<CT>::size_type I,
class... Args>
1654 inline auto xview<CT, S...>::index(Args... args)
const
1655 -> std::enable_if_t<lesser_condition<I>::value, size_type>
1657 return sliced_access<I - integral_count_before<S...>(I) + newaxis_count_before<S...>(I + 1)>(
1658 std::get<I + newaxis_count_before<S...>(I + 1)>(m_slices),
1663 template <
class CT,
class... S>
1664 template <typename std::decay_t<CT>::size_type I,
class... Args>
1665 inline auto xview<CT, S...>::index(Args... args)
const
1666 -> std::enable_if_t<!lesser_condition<I>::value, size_type>
1668 return argument<I - integral_count<S...>() + newaxis_count<S...>()>(args...);
1671 template <
class CT,
class... S>
1672 template <typename std::decay_t<CT>::size_type I,
class T>
1673 inline auto xview<CT, S...>::sliced_access(const xslice<T>& slice) const -> size_type
1675 return static_cast<size_type
>(slice.derived_cast()(0));
1678 template <
class CT,
class... S>
1679 template <typename std::decay_t<CT>::size_type I,
class T, class Arg, class... Args>
1680 inline auto xview<CT, S...>::sliced_access(const xslice<T>& slice, Arg arg, Args... args) const -> size_type
1682 using ST =
typename T::size_type;
1683 return static_cast<size_type
>(
1684 slice.derived_cast()(argument<I>(
static_cast<ST
>(arg),
static_cast<ST
>(args)...))
1688 template <
class CT,
class... S>
1689 template <typename std::decay_t<CT>::size_type I,
class T, class... Args>
1690 inline auto xview<CT, S...>::sliced_access(const T& squeeze, Args...) const -> disable_xslice<T, size_type>
1692 return static_cast<size_type
>(
squeeze);
1695 template <
class CT,
class... S>
1697 inline auto xview<CT, S...>::make_index(It first, It last)
const -> base_index_type
1699 auto index = xtl::make_sequence<base_index_type>(m_e.dimension(), 0);
1700 using diff_type =
typename std::iterator_traits<It>::difference_type;
1701 using ivalue_type =
typename base_index_type::value_type;
1702 auto func1 = [&first](
const auto& s)
noexcept
1704 return get_slice_value(s, first);
1706 auto func2 = [](
const auto& s)
noexcept
1708 return xt::value(s, 0);
1711 auto s =
static_cast<diff_type
>(
1712 (std::min)(
static_cast<size_type
>(std::distance(first, last)), this->dimension())
1714 auto first_copy = last - s;
1715 for (size_type i = 0; i != m_e.dimension(); ++i)
1717 size_type k = newaxis_skip<S...>(i);
1725 index[i] = k <
sizeof...(S) ? apply<size_type>(k, func1, m_slices)
1726 :
static_cast<ivalue_type
>(*first);
1730 index[i] = k <
sizeof...(S) ? apply<size_type>(k, func2, m_slices) : ivalue_type(0);
1736 template <
class CT,
class... S>
1737 inline auto xview<CT, S...>::compute_shape(std::true_type)
const -> inner_shape_type
1739 return inner_shape_type(m_e.shape());
1742 template <
class CT,
class... S>
1743 inline auto xview<CT, S...>::compute_shape(std::false_type)
const -> inner_shape_type
1745 std::size_t dim = m_e.dimension() - integral_count<S...>() + newaxis_count<S...>();
1746 auto shape = xtl::make_sequence<inner_shape_type>(dim, 0);
1747 auto func = [](
const auto& s)
noexcept
1751 for (size_type i = 0; i != dim; ++i)
1753 size_type index = integral_skip<S...>(i);
1754 shape[i] = index <
sizeof...(S) ? apply<size_type>(index, func, m_slices)
1755 : m_e.shape()[index - newaxis_count_before<S...>(index)];
1760 namespace xview_detail
1762 template <
class V,
class T>
1763 inline void run_assign_temporary_impl(V& v,
const T& t, std::true_type )
1765 strided_loop_assigner<true>::run(v, t);
1768 template <
class V,
class T>
1770 run_assign_temporary_impl(V& v,
const T& t, std::false_type )
1772 std::copy(t.cbegin(), t.cend(), v.begin());
1776 template <
class CT,
class... S>
1777 inline void xview<CT, S...>::assign_temporary_impl(temporary_type&& tmp)
1779 constexpr bool fast_assign = detail::is_strided_view<xexpression_type, S...>::value
1780 && xassign_traits<xview<CT, S...>, temporary_type>::simd_strided_assign();
1781 xview_detail::run_assign_temporary_impl(*
this, tmp, std::integral_constant<bool, fast_assign>{});
1786 template <
class E,
class... S>
1787 inline std::size_t get_underlying_shape_index(std::size_t I)
1789 return I - newaxis_count_before<get_slice_type<E, S>...>(I);
1792 template <
class... S>
1796 struct check_slice<>
1798 using type = void_t<>;
1801 template <
class S,
class... SL>
1802 struct check_slice<S, SL...>
1804 static_assert(!std::is_same<S, xellipsis_tag>::value,
"ellipsis not supported vith xview");
1805 using type =
typename check_slice<SL...>::type;
1808 template <
class E, std::size_t... I,
class... S>
1809 inline auto make_view_impl(E&& e, std::index_sequence<I...>, S&&... slices)
1812 using view_type = xview<xtl::closure_type_t<E>, get_slice_type<std::decay_t<E>, S>...>;
1815 get_slice_implementation(
1817 std::forward<S>(slices),
1818 get_underlying_shape_index<std::decay_t<E>, S...>(I)
1833 template <
class E,
class... S>
1836 return detail::make_view_impl(
1838 std::make_index_sequence<
sizeof...(
S)>(),
1839 std::forward<S>(slices)...
1850 inline static auto make(E&& e,
const std::ptrdiff_t index)
1852 const auto shape = e.shape();
1853 check_dimension(shape);
1860 inline static void check_dimension(
const S& shape)
1862 if (shape.size() != 2)
1865 std::invalid_argument,
1866 "A row can only be accessed on an expression with exact two dimensions"
1871 template <
class T, std::
size_t N>
1872 inline static void check_dimension(
const std::array<T, N>&)
1874 static_assert(N == 2,
"A row can only be accessed on an expression with exact two dimensions");
1883 inline static auto make(E&& e,
const std::ptrdiff_t index)
1885 const auto shape = e.shape();
1886 check_dimension(shape);
1893 inline static void check_dimension(
const S& shape)
1895 if (shape.size() != 2)
1898 std::invalid_argument,
1899 "A column can only be accessed on an expression with exact two dimensions"
1904 template <
class T, std::
size_t N>
1905 inline static void check_dimension(
const std::array<T, N>&)
1907 static_assert(N == 2,
"A column can only be accessed on an expression with exact two dimensions");
1922 inline auto row(E&&
e, std::ptrdiff_t index)
1924 return detail::row_impl::make(
e, index);
1937 inline auto col(E&&
e, std::ptrdiff_t index)
1939 return detail::column_impl::make(
e, index);
1946 template <
class CT,
class... S>
1947 template <
class ST,
bool Enable>
1948 inline auto xview<CT, S...>::stepper_begin(
const ST& shape) -> std::enable_if_t<!Enable, stepper>
1950 size_type offset = shape.size() - this->dimension();
1951 return stepper(
this, m_e.stepper_begin(m_e.shape()), offset);
1954 template <
class CT,
class... S>
1955 template <
class ST,
bool Enable>
1956 inline auto xview<CT, S...>::stepper_end(
const ST& shape,
layout_type l)
1957 -> std::enable_if_t<!Enable, stepper>
1959 size_type offset = shape.size() - this->dimension();
1960 return stepper(
this, m_e.stepper_end(m_e.shape(), l), offset,
true, l);
1963 template <
class CT,
class... S>
1964 template <
class ST,
bool Enable>
1965 inline auto xview<CT, S...>::stepper_begin(
const ST& shape)
const
1966 -> std::enable_if_t<!Enable, const_stepper>
1968 size_type offset = shape.size() - this->dimension();
1969 const xexpression_type& e = m_e;
1970 return const_stepper(
this, e.stepper_begin(m_e.shape()), offset);
1973 template <
class CT,
class... S>
1974 template <
class ST,
bool Enable>
1975 inline auto xview<CT, S...>::stepper_end(
const ST& shape,
layout_type l)
const
1976 -> std::enable_if_t<!Enable, const_stepper>
1978 size_type offset = shape.size() - this->dimension();
1979 const xexpression_type& e = m_e;
1980 return const_stepper(
this, e.stepper_end(m_e.shape(), l), offset,
true, l);
1983 template <
class CT,
class... S>
1984 template <
class ST,
bool Enable>
1985 inline auto xview<CT, S...>::stepper_begin(
const ST& shape) -> std::enable_if_t<Enable, stepper>
1987 size_type offset = shape.size() - this->dimension();
1988 return stepper(
this, data_xbegin(), offset);
1991 template <
class CT,
class... S>
1992 template <
class ST,
bool Enable>
1993 inline auto xview<CT, S...>::stepper_end(
const ST& shape,
layout_type l)
1994 -> std::enable_if_t<Enable, stepper>
1996 size_type offset = shape.size() - this->dimension();
1997 return stepper(
this, data_xend(l, offset), offset);
2000 template <
class CT,
class... S>
2001 template <
class ST,
bool Enable>
2002 inline auto xview<CT, S...>::stepper_begin(
const ST& shape)
const
2003 -> std::enable_if_t<Enable, const_stepper>
2005 size_type offset = shape.size() - this->dimension();
2006 return const_stepper(
this, data_xbegin(), offset);
2009 template <
class CT,
class... S>
2010 template <
class ST,
bool Enable>
2011 inline auto xview<CT, S...>::stepper_end(
const ST& shape,
layout_type l)
const
2012 -> std::enable_if_t<Enable, const_stepper>
2014 size_type offset = shape.size() - this->dimension();
2015 return const_stepper(
this, data_xend(l, offset), offset);
2022 template <
bool is_const,
class CT,
class... S>
2023 inline xview_stepper<is_const, CT, S...>::xview_stepper(
2036 std::fill(m_index_keeper.begin(), m_index_keeper.end(), 0);
2037 auto func = [](
const auto& s)
noexcept
2039 return xt::value(s, 0);
2041 for (size_type i = 0; i <
sizeof...(S); ++i)
2043 if (!is_newaxis_slice(i))
2045 size_type s = apply<size_type>(i, func, p_view->slices());
2046 size_type index = i - newaxis_count_before<S...>(i);
2047 m_it.step(index, s);
2057 template <
bool is_const,
class CT,
class... S>
2058 inline auto xview_stepper<is_const, CT, S...>::operator*() const -> reference
2063 template <
bool is_const,
class CT,
class... S>
2064 inline void xview_stepper<is_const, CT, S...>::step(size_type dim)
2066 auto func = [
this](size_type index, size_type offset)
2068 m_it.step(index, offset);
2070 common_step_forward(dim, func);
2073 template <
bool is_const,
class CT,
class... S>
2074 inline void xview_stepper<is_const, CT, S...>::step_back(size_type dim)
2076 auto func = [
this](size_type index, size_type offset)
2078 m_it.step_back(index, offset);
2080 common_step_backward(dim, func);
2083 template <
bool is_const,
class CT,
class... S>
2084 inline void xview_stepper<is_const, CT, S...>::step(size_type dim, size_type n)
2086 auto func = [
this](size_type index, size_type offset)
2088 m_it.step(index, offset);
2090 common_step_forward(dim, n, func);
2093 template <
bool is_const,
class CT,
class... S>
2094 inline void xview_stepper<is_const, CT, S...>::step_back(size_type dim, size_type n)
2096 auto func = [
this](size_type index, size_type offset)
2098 m_it.step_back(index, offset);
2100 common_step_backward(dim, n, func);
2103 template <
bool is_const,
class CT,
class... S>
2104 inline void xview_stepper<is_const, CT, S...>::reset(size_type dim)
2106 auto func = [
this](size_type index, size_type offset)
2108 m_it.step_back(index, offset);
2110 common_reset(dim, func,
false);
2113 template <
bool is_const,
class CT,
class... S>
2114 inline void xview_stepper<is_const, CT, S...>::reset_back(size_type dim)
2116 auto func = [
this](size_type index, size_type offset)
2118 m_it.step(index, offset);
2120 common_reset(dim, func,
true);
2123 template <
bool is_const,
class CT,
class... S>
2124 inline void xview_stepper<is_const, CT, S...>::to_begin()
2126 std::fill(m_index_keeper.begin(), m_index_keeper.end(), 0);
2130 template <
bool is_const,
class CT,
class... S>
2131 inline void xview_stepper<is_const, CT, S...>::to_end(layout_type l)
2137 template <
bool is_const,
class CT,
class... S>
2138 inline bool xview_stepper<is_const, CT, S...>::is_newaxis_slice(size_type index)
const noexcept
2141 return newaxis_count_before<S...>(index + 1) != newaxis_count_before<S...>(index);
2144 template <
bool is_const,
class CT,
class... S>
2145 inline void xview_stepper<is_const, CT, S...>::to_end_impl(layout_type l)
2147 auto func = [](
const auto& s)
noexcept
2149 return xt::value(s, get_size(s) - 1);
2151 auto size_func = [](
const auto& s)
noexcept
2156 for (size_type i = 0; i <
sizeof...(S); ++i)
2158 if (!is_newaxis_slice(i))
2160 size_type s = apply<size_type>(i, func, p_view->slices());
2161 size_type ix = apply<size_type>(i, size_func, p_view->slices());
2162 m_index_keeper[i] = ix - size_type(1);
2163 size_type index = i - newaxis_count_before<S...>(i);
2164 s = p_view->underlying_size(index) - 1 - s;
2165 m_it.step_back(index, s);
2168 if (l == layout_type::row_major)
2170 for (size_type i =
sizeof...(S); i > 0; --i)
2172 if (!is_newaxis_slice(i - 1))
2174 m_index_keeper[i - 1]++;
2179 else if (l == layout_type::column_major)
2181 for (size_type i = 0; i <
sizeof...(S); ++i)
2183 if (!is_newaxis_slice(i))
2185 m_index_keeper[i]++;
2192 XTENSOR_THROW(std::runtime_error,
"Iteration only allowed in row or column major.");
2196 template <
bool is_const,
class CT,
class... S>
2198 void xview_stepper<is_const, CT, S...>::common_step_forward(size_type dim, F f)
2200 if (dim >= m_offset)
2202 auto func = [&dim,
this](
const auto& s)
noexcept
2204 return step_size(s, this->m_index_keeper[dim]++, 1);
2206 size_type index = integral_skip<S...>(dim);
2207 if (!is_newaxis_slice(index))
2209 size_type step_size = index <
sizeof...(S) ? apply<size_type>(index, func, p_view->slices())
2211 index -= newaxis_count_before<S...>(index);
2212 f(index, step_size);
2217 template <
bool is_const,
class CT,
class... S>
2219 void xview_stepper<is_const, CT, S...>::common_step_forward(size_type dim, size_type n, F f)
2221 if (dim >= m_offset)
2223 auto func = [&dim, &n,
this](
const auto& s)
noexcept
2225 auto st_size = step_size(s, this->m_index_keeper[dim], n);
2226 this->m_index_keeper[dim] += n;
2227 return size_type(st_size);
2230 size_type index = integral_skip<S...>(dim);
2231 if (!is_newaxis_slice(index))
2233 size_type step_size = index <
sizeof...(S) ? apply<size_type>(index, func, p_view->slices())
2235 index -= newaxis_count_before<S...>(index);
2236 f(index, step_size);
2241 template <
bool is_const,
class CT,
class... S>
2243 void xview_stepper<is_const, CT, S...>::common_step_backward(size_type dim, F f)
2245 if (dim >= m_offset)
2247 auto func = [&dim,
this](
const auto& s)
noexcept
2249 this->m_index_keeper[dim]--;
2250 return step_size(s, this->m_index_keeper[dim], 1);
2252 size_type index = integral_skip<S...>(dim);
2253 if (!is_newaxis_slice(index))
2255 size_type step_size = index <
sizeof...(S) ? apply<size_type>(index, func, p_view->slices())
2257 index -= newaxis_count_before<S...>(index);
2258 f(index, step_size);
2263 template <
bool is_const,
class CT,
class... S>
2265 void xview_stepper<is_const, CT, S...>::common_step_backward(size_type dim, size_type n, F f)
2267 if (dim >= m_offset)
2269 auto func = [&dim, &n,
this](
const auto& s)
noexcept
2271 this->m_index_keeper[dim] -= n;
2272 return step_size(s, this->m_index_keeper[dim], n);
2275 size_type index = integral_skip<S...>(dim);
2276 if (!is_newaxis_slice(index))
2278 size_type step_size = index <
sizeof...(S) ? apply<size_type>(index, func, p_view->slices())
2280 index -= newaxis_count_before<S...>(index);
2281 f(index, step_size);
2286 template <
bool is_const,
class CT,
class... S>
2288 void xview_stepper<is_const, CT, S...>::common_reset(size_type dim, F f,
bool backwards)
2290 auto size_func = [](
const auto& s)
noexcept
2294 auto end_func = [](
const auto& s)
noexcept
2296 return xt::value(s, get_size(s) - 1) - xt::value(s, 0);
2299 size_type index = integral_skip<S...>(dim);
2300 if (!is_newaxis_slice(index))
2302 if (dim < m_index_keeper.size())
2304 size_type size = index <
sizeof...(S) ? apply<size_type>(index, size_func, p_view->slices())
2305 : p_view->shape()[dim];
2306 m_index_keeper[dim] = backwards ? size - 1 : 0;
2309 size_type reset_n = index <
sizeof...(S) ? apply<size_type>(index, end_func, p_view->slices())
2310 : p_view->shape()[dim] - 1;
2311 index -= newaxis_count_before<S...>(index);
Fixed shape implementation for compile time defined arrays.
Base class for implementation of common expression access methods.
size_type shape(size_type index) const
Returns the i-th dimension of the expression.
Base class for multidimensional iterable expressions.
Implementation of the xsemantic_base interface for multidimensional views.
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
Returns the slices of the view.
bool has_linear_assign(const ST &strides) const
Checks whether the xview can be linearly assigned to an expression with the specified strides.
const inner_shape_type & shape() const noexcept
Returns the shape of the view.
bool broadcast_shape(ST &shape, bool reuse_cache=false) const
Broadcast the shape of the view to the specified parameter.
xexpression_type & expression() noexcept
Returns a reference to the underlying expression of the view.
void fill(const T &value)
Fills the view with the given value.
layout_type layout() const noexcept
Returns the slices of the view.
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.
auto strides(const E &e, stride_type type=stride_type::normal) noexcept
Get strides of an object.
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.