10#ifndef XTENSOR_VIEW_HPP
11#define XTENSOR_VIEW_HPP
20#include <xtl/xclosure.hpp>
21#include <xtl/xmeta_utils.hpp>
22#include <xtl/xsequence.hpp>
23#include <xtl/xtype_traits.hpp>
25#include "../containers/xarray.hpp"
26#include "../containers/xcontainer.hpp"
27#include "../containers/xtensor.hpp"
28#include "../core/xaccessible.hpp"
29#include "../core/xiterable.hpp"
30#include "../core/xsemantic.hpp"
31#include "../core/xtensor_config.hpp"
32#include "../core/xtensor_forward.hpp"
33#include "../views/xbroadcast.hpp"
34#include "../views/xslice.hpp"
35#include "../views/xview_utils.hpp"
46 template <
class Tag,
class CT,
class... S>
49 template <
class CT,
class... S>
55 template <
class CT,
class... S>
60 template <
class CT,
class... S>
61 using xview_base_t =
typename xview_base<CT, S...>::type;
68 template <
bool is_const,
class CT,
class... S>
71 template <
class ST,
class... S>
78 struct is_xrange : std::false_type
83 struct is_xrange<xrange<T>> : std::true_type
88 struct is_xall_slice : std::false_type
93 struct is_xall_slice<xall<T>> : std::true_type
97 template <layout_type L,
bool val
id,
bool all_seen,
bool range_seen,
class V>
98 struct is_contiguous_view_impl
100 static constexpr bool value =
false;
104 struct static_dimension
106 static constexpr std::ptrdiff_t value = -1;
109 template <
class T, std::
size_t N>
110 struct static_dimension<std::array<T, N>>
112 static constexpr std::ptrdiff_t value =
static_cast<std::ptrdiff_t
>(N);
115 template <
class T, std::
size_t N>
116 struct static_dimension<xt::const_array<T, N>>
118 static constexpr std::ptrdiff_t value =
static_cast<std::ptrdiff_t
>(N);
121 template <std::size_t... I>
122 struct static_dimension<xt::fixed_shape<I...>>
124 static constexpr std::ptrdiff_t value =
sizeof...(I);
129 template <
class CT,
class... S>
130 struct is_xscalar_impl<xview<CT, S...>>
132 static constexpr bool value =
static_cast<std::ptrdiff_t
>(integral_count<S...>()
133 ) == static_dimension<
typename std::decay_t<CT>::shape_type>::value
138 template <
typename S>
139 inline constexpr bool is_strided_slice_impl =
true;
140 template <
typename T>
141 inline constexpr bool is_strided_slice_impl<xkeep_slice<T>> =
false;
142 template <
typename T>
143 inline constexpr bool is_strided_slice_impl<xdrop_slice<T>> =
false;
145 template <
typename S>
146 concept is_strided_slice_concept = is_strided_slice_impl<S>;
148 template <
class... S>
149 constexpr bool is_strided_slice()
151 return (is_strided_slice_concept<std::decay_t<S>> && ...);
155 template <
class E,
class... S>
156 struct is_strided_view
157 : std::integral_constant<bool, data_interface_expression<E> && is_strided_slice<S...>()>
171 template <
bool val
id,
bool all_seen,
bool range_seen,
class V>
174 using slice = xtl::mpl::front_t<V>;
175 static constexpr bool is_range_slice = is_xrange<slice>::value;
176 static constexpr bool is_int_slice = xtl::is_integral<slice>::value;
177 static constexpr bool is_all_slice = is_xall_slice<slice>::value;
178 static constexpr bool have_all_seen = all_seen || is_all_slice;
179 static constexpr bool have_range_seen = is_range_slice;
181 static constexpr bool is_valid = valid
184 : (!range_seen && (is_int_slice || is_range_slice)));
187 have_all_seen, range_seen || is_range_slice,
188 xtl::mpl::pop_front_t < V >> ::value;
191 template <
bool val
id,
bool all_seen,
bool range_seen>
192 struct is_contiguous_view_impl<
layout_type::
row_major, valid, all_seen, range_seen, xtl::mpl::vector<>>
194 static constexpr bool value = valid;
200 template <
bool val
id,
bool int_seen,
bool range_seen,
class V>
203 using slice = xtl::mpl::front_t<V>;
204 static constexpr bool is_range_slice = is_xrange<slice>::value;
205 static constexpr bool is_int_slice = xtl::is_integral<slice>::value;
206 static constexpr bool is_all_slice = is_xall_slice<slice>::value;
208 static constexpr bool have_int_seen = int_seen || is_int_slice;
210 static constexpr bool is_valid = valid
213 : (!range_seen && (is_all_slice || is_range_slice)));
215 have_int_seen, is_range_slice || range_seen,
216 xtl::mpl::pop_front_t < V >> ::value;
219 template <
bool val
id,
bool int_seen,
bool range_seen>
222 static constexpr bool value = valid;
226 template <
class E,
class... S>
227 struct is_contiguous_view
228 : std::integral_constant<
230 data_interface_expression<E>
232 E::static_layout == layout_type::column_major
233 && static_cast<std::size_t>(static_dimension<typename E::shape_type>::value) != sizeof...(S)
235 && is_contiguous_view_impl<E::static_layout, true, false, false, xtl::mpl::vector<S...>>::value>
239 template <layout_type L,
class T, std::ptrdiff_t offset>
240 struct unwrap_offset_container
245 template <
class T, std::ptrdiff_t offset>
248 using type = sequence_view<T, offset, static_dimension<T>::value>;
251 template <
class T, std::ptrdiff_t start, std::ptrdiff_t end, std::ptrdiff_t offset>
254 using type = sequence_view<T, start + offset, end>;
257 template <
class T, std::ptrdiff_t offset>
260 using type = sequence_view<T, 0, static_dimension<T>::value - offset>;
263 template <
class T, std::ptrdiff_t start, std::ptrdiff_t end, std::ptrdiff_t offset>
266 using type = sequence_view<T, start, end - offset>;
269 template <
class E,
class... S>
270 struct get_contigous_shape_type
273 using type = std::conditional_t<
274 std::disjunction<is_xrange<S>...>::value,
275 typename xview_shape_type<
typename E::shape_type, S...>::type,
277 typename unwrap_offset_container<E::static_layout,
typename E::inner_shape_type, integral_count<S...>()>::type>;
281 struct is_sequence_view : std::integral_constant<bool, false>
285 template <
class T, std::ptrdiff_t S, std::ptrdiff_t E>
286 struct is_sequence_view<sequence_view<T, S, E>> : std::integral_constant<bool, true>
291 template <
class E,
class... S>
293 template <
class E,
class... S>
296 template <
class CT,
class... S>
299 using xexpression_type = std::decay_t<CT>;
300 using reference = inner_reference_t<CT>;
301 using const_reference =
typename xexpression_type::const_reference;
302 using size_type =
typename xexpression_type::size_type;
303 using temporary_type = view_temporary_type_t<xexpression_type, S...>;
305 static constexpr layout_type layout = detail::is_contiguous_view<xexpression_type, S...>::value
306 ? xexpression_type::static_layout
309 static constexpr bool is_const = std::is_const<std::remove_reference_t<CT>>::value;
311 using extract_storage_type =
typename std::conditional_t<
313 detail::expr_storage_type<xexpression_type>,
315 using storage_type = std::conditional_t<is_const, const extract_storage_type, extract_storage_type>;
318 template <
class CT,
class... S>
321 using xexpression_type = std::decay_t<CT>;
323 static constexpr bool is_strided_view = detail::is_strided_view<xexpression_type, S...>::value;
324 static constexpr bool is_contiguous_view = detail::is_contiguous_view<xexpression_type, S...>::value;
326 using inner_shape_type = std::conditional_t<
328 typename detail::get_contigous_shape_type<xexpression_type, S...>::type,
329 typename xview_shape_type<
typename xexpression_type::shape_type, S...>::type>;
331 using stepper = std::conditional_t<
336 using const_stepper = std::conditional_t<
356 template <
class CT,
class... S>
357 class xview :
public xview_semantic<xview<CT, S...>>,
358 public std::conditional_t<
359 detail::is_contiguous_view<std::decay_t<CT>, S...>::value,
360 xcontiguous_iterable<xview<CT, S...>>,
361 xiterable<xview<CT, S...>>>,
362 public xaccessible<xview<CT, S...>>,
363 public extension::xview_base_t<CT, S...>
367 using self_type =
xview<CT, S...>;
369 using xexpression_type = std::decay_t<CT>;
370 using semantic_base = xview_semantic<self_type>;
373 using accessible_base = xaccessible<self_type>;
374 using extension_base = extension::xview_base_t<CT, S...>;
375 using expression_tag =
typename extension_base::expression_tag;
377 static constexpr bool is_const = std::is_const<std::remove_reference_t<CT>>::value;
378 using value_type =
typename xexpression_type::value_type;
379 using simd_value_type = xt_simd::simd_type<value_type>;
380 using bool_load_type =
typename xexpression_type::bool_load_type;
381 using reference =
typename inner_types::reference;
382 using const_reference =
typename inner_types::const_reference;
383 using pointer = std::
384 conditional_t<is_const, typename xexpression_type::const_pointer, typename xexpression_type::pointer>;
385 using const_pointer =
typename xexpression_type::const_pointer;
386 using size_type =
typename inner_types::size_type;
387 using difference_type =
typename xexpression_type::difference_type;
389 static constexpr layout_type static_layout = inner_types::layout;
392 static constexpr bool is_strided_view = detail::is_strided_view<xexpression_type, S...>::value;
393 static constexpr bool is_contiguous_view = contiguous_layout;
396 using inner_shape_type =
typename iterable_base::inner_shape_type;
397 using shape_type =
typename xview_shape_type<
typename xexpression_type::shape_type, S...>::type;
399 using xexpression_inner_strides_type =
typename std::conditional_t<
401 detail::expr_inner_strides_type<xexpression_type>,
404 using xexpression_inner_backstrides_type =
typename std::conditional_t<
406 detail::expr_inner_backstrides_type<xexpression_type>,
409 using storage_type =
typename inner_types::storage_type;
411 static constexpr bool has_trivial_strides = is_contiguous_view
412 && !std::disjunction<detail::is_xrange<S>...>::value;
413 using inner_strides_type = std::conditional_t<
415 typename detail::unwrap_offset_container<
416 xexpression_type::static_layout,
417 xexpression_inner_strides_type,
418 integral_count<S...>()>::type,
419 get_strides_t<shape_type>>;
421 using inner_backstrides_type = std::conditional_t<
423 typename detail::unwrap_offset_container<
424 xexpression_type::static_layout,
425 xexpression_inner_backstrides_type,
426 integral_count<S...>()>::type,
427 get_strides_t<shape_type>>;
429 using strides_type = get_strides_t<shape_type>;
430 using backstrides_type = strides_type;
433 using slice_type = std::tuple<S...>;
435 using stepper =
typename iterable_base::stepper;
436 using const_stepper =
typename iterable_base::const_stepper;
438 using linear_iterator = std::conditional_t<
440 std::conditional_t<is_const, typename xexpression_type::const_linear_iterator, typename xexpression_type::linear_iterator>,
441 typename iterable_base::linear_iterator>;
442 using const_linear_iterator = std::conditional_t<
444 typename xexpression_type::const_linear_iterator,
445 typename iterable_base::const_linear_iterator>;
447 using reverse_linear_iterator = std::reverse_iterator<linear_iterator>;
448 using const_reverse_linear_iterator = std::reverse_iterator<const_linear_iterator>;
450 using container_iterator = pointer;
451 using const_container_iterator = const_pointer;
452 static constexpr std::size_t rank = SIZE_MAX;
456 template <
class CTA,
class FSL,
class... SL>
457 explicit xview(CTA&& e, FSL&& first_slice, SL&&...
slices)
noexcept;
460 self_type& operator=(
const xview& rhs);
466 disable_xexpression<E, self_type>& operator=(
const E& e);
468 const inner_shape_type&
shape() const noexcept;
469 const slice_type&
slices() const noexcept;
471 bool is_contiguous() const noexcept;
472 using accessible_base::
shape;
477 template <class... Args>
478 reference operator()(Args... args);
479 template <class... Args>
482 reference element(It first, It last);
484 template <class... Args>
485 const_reference operator()(Args... args) const;
486 template <class... Args>
489 const_reference element(It first, It last) const;
501 stepper stepper_begin(const ST&
shape);
506 const_stepper stepper_begin(const ST&
shape) const;
510 template <class T = xexpression_type>
511 storage_type& storage()
514 template <class T = xexpression_type>
515 const storage_type& storage() const
518 template <class T = xexpression_type>
519 linear_iterator linear_begin()
522 template <class T = xexpression_type>
523 linear_iterator linear_end()
526 template <class T = xexpression_type>
527 const_linear_iterator linear_begin() const
530 template <class T = xexpression_type>
531 const_linear_iterator linear_end() const
534 template <class T = xexpression_type>
535 const_linear_iterator linear_cbegin() const
538 template <class T = xexpression_type>
539 const_linear_iterator linear_cend() const
542 template <class T = xexpression_type>
543 reverse_linear_iterator linear_rbegin()
546 template <class T = xexpression_type>
547 reverse_linear_iterator linear_rend()
550 template <class T = xexpression_type>
551 const_reverse_linear_iterator linear_rbegin() const
554 template <class T = xexpression_type>
555 const_reverse_linear_iterator linear_rend() const
558 template <class T = xexpression_type>
559 const_reverse_linear_iterator linear_crbegin() const
562 template <class T = xexpression_type>
563 const_reverse_linear_iterator linear_crend() const
566 template <class T = xexpression_type>
567 const inner_strides_type& strides() const
570 template <class T = xexpression_type>
571 const inner_strides_type& backstrides() const
574 template <class T = xexpression_type>
575 const_pointer data() const
578 template <class T = xexpression_type>
582 template <class T = xexpression_type>
587 inline It data_xbegin_impl(It begin) const noexcept;
590 inline It data_xend_impl(It begin,
layout_type l, size_type offset) const noexcept;
591 inline container_iterator data_xbegin() noexcept;
592 inline const_container_iterator data_xbegin() const noexcept;
593 inline container_iterator data_xend(
layout_type l, size_type offset) noexcept;
595 inline const_container_iterator data_xend(
layout_type l, size_type offset) const noexcept;
604 template <xscalar_concept ST = self_type>
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&() &&;
616 template <class E, class T = xexpression_type>
617 void assign_to(xexpression<E>& e,
bool force_resize) const
618 requires(data_interface_expression<T> and contiguous_view_concept<E, S...>);
621 using rebind_t =
xview<E, S...>;
624 rebind_t<E> build_view(E&& e) const;
630 template <class requested_type>
631 using simd_return_type = xt_simd::simd_return_type<value_type, requested_type>;
633 template <class align, class simd, class T = xexpression_type>
634 void store_simd(size_type i, const simd& e)
635 requires(has_simd_interface_concept<T> and strided_view_concept<CT, S...>);
639 class requested_type = value_type,
640 std::
size_t N = xt_simd::simd_traits<requested_type>::
size,
641 class T = xexpression_type>
642 simd_return_type<requested_type> load_simd(size_type i) const
643 requires(has_simd_interface_concept<T> and strided_view_concept<CT, S...>);
645 template <class T = xexpression_type>
646 reference data_element(size_type i)
647 requires(has_simd_interface_concept<T> and strided_view_concept<CT, S...>);
649 template <class T = xexpression_type>
650 const_reference data_element(size_type i) const
651 requires(has_simd_interface_concept<T> and strided_view_concept<CT, S...>);
653 template <class T = xexpression_type>
654 reference flat(size_type i)
655 requires(has_simd_interface_concept<T> and strided_view_concept<CT, S...>);
657 template <class T = xexpression_type>
658 const_reference flat(size_type i) const
659 requires(has_simd_interface_concept<T> and strided_view_concept<CT, S...>);
664 template <std::
size_t I>
665 struct lesser_condition
667 static constexpr bool value = (I + newaxis_count_before<S...>(I + 1) <
sizeof...(S));
672 inner_shape_type m_shape;
673 mutable inner_strides_type m_strides;
674 mutable inner_backstrides_type m_backstrides;
675 mutable std::size_t m_data_offset;
676 mutable bool m_strides_computed;
678 template <
class CTA,
class FSL,
class... SL>
679 explicit xview(std::true_type, CTA&& e, FSL&& first_slice, SL&&...
slices)
noexcept;
681 template <
class CTA,
class FSL,
class... SL>
682 explicit xview(std::false_type, CTA&& e, FSL&& first_slice, SL&&...
slices)
noexcept;
684 template <
class... Args>
685 auto make_index_sequence(Args... args)
const noexcept;
687 void compute_strides(std::true_type)
const;
688 void compute_strides(std::false_type)
const;
692 template <
class Arg,
class... Args>
693 reference access(Arg
arg, Args... args);
695 const_reference access()
const;
697 template <
class Arg,
class... Args>
698 const_reference access(Arg
arg, Args... args)
const;
700 template <typename std::decay_t<CT>::size_type... I,
class... Args>
701 reference unchecked_impl(std::index_sequence<I...>, Args... args);
703 template <typename std::decay_t<CT>::size_type... I,
class... Args>
704 const_reference unchecked_impl(std::index_sequence<I...>, Args... args)
const;
706 template <typename std::decay_t<CT>::size_type... I,
class... Args>
707 reference access_impl(std::index_sequence<I...>, Args... args);
709 template <typename std::decay_t<CT>::size_type... I,
class... Args>
710 const_reference access_impl(std::index_sequence<I...>, Args... args)
const;
712 template <typename std::decay_t<CT>::size_type I,
class... Args>
713 size_type index(Args... args)
const;
715 template <typename std::decay_t<CT>::size_type,
class T>
716 size_type sliced_access(const xslice<T>& slice)
const;
718 template <typename std::decay_t<CT>::size_type I,
class T, class Arg, class... Args>
719 size_type sliced_access(const xslice<T>& slice, Arg
arg, Args... args)
const;
721 template <typename std::decay_t<CT>::size_type I,
class T, class... Args>
722 size_type sliced_access(const T&
squeeze, Args...) const
723 requires(!is_xslice<T>::value);
725 using base_index_type = xindex_type_t<typename xexpression_type::shape_type>;
728 base_index_type make_index(It first, It last) const;
730 void assign_temporary_impl(temporary_type&& tmp);
732 template <std::
size_t... I>
733 std::
size_t data_offset_impl(std::index_sequence<I...>) const noexcept;
735 template <std::
size_t... I>
736 auto compute_strides_impl(std::index_sequence<I...>) const noexcept;
738 inner_shape_type compute_shape(std::true_type) const;
739 inner_shape_type compute_shape(std::false_type) const;
741 template <class E, std::
size_t... I>
742 rebind_t<E> build_view_impl(E&& e, std::index_sequence<I...>) const;
744 friend class xview_semantic<
xview<CT, S...>>;
747 template <class E, class... S>
751 auto
row(E&& e, std::ptrdiff_t index);
754 auto
col(E&& e, std::ptrdiff_t index);
763 struct get_stepper_impl
765 using xexpression_type =
typename V::xexpression_type;
766 using type =
typename xexpression_type::stepper;
770 struct get_stepper_impl<const V>
772 using xexpression_type =
typename V::xexpression_type;
773 using type =
typename xexpression_type::const_stepper;
778 using get_stepper =
typename detail::get_stepper_impl<V>::type;
780 template <
bool is_const,
class CT,
class... S>
785 using view_type = std::conditional_t<is_const,
const xview<CT, S...>,
xview<CT, S...>>;
786 using substepper_type = get_stepper<view_type>;
788 using value_type =
typename substepper_type::value_type;
789 using reference =
typename substepper_type::reference;
790 using pointer =
typename substepper_type::pointer;
791 using difference_type =
typename substepper_type::difference_type;
792 using size_type =
typename view_type::size_type;
794 using shape_type =
typename substepper_type::shape_type;
796 xview_stepper() =
default;
805 reference operator*()
const;
807 void step(size_type dim);
808 void step_back(size_type dim);
809 void step(size_type dim, size_type n);
810 void step_back(size_type dim, size_type n);
811 void reset(size_type dim);
812 void reset_back(size_type dim);
819 bool is_newaxis_slice(size_type index)
const noexcept;
823 void common_step_forward(size_type dim, F f);
825 void common_step_backward(size_type dim, F f);
828 void common_step_forward(size_type dim, size_type n, F f);
830 void common_step_backward(size_type dim, size_type n, F f);
833 void common_reset(size_type dim, F f,
bool backwards);
836 substepper_type m_it;
838 std::array<std::size_t,
sizeof...(S)> m_index_keeper;
842 template <
class ST,
class... S>
848 template <
class I, std::size_t L,
class... S>
851 using type = std::array<I, L - integral_count<S...>() + newaxis_count<S...>()>;
854 template <std::size_t... I,
class... S>
857 using type =
typename xview_shape_type<std::array<std::size_t,
sizeof...(I)>, S...>::type;
878 template <
class CT,
class... S>
879 template <
class CTA,
class FSL,
class... SL>
882 std::integral_constant<bool, has_trivial_strides>{},
883 std::forward<CTA>(e),
884 std::forward<FSL>(first_slice),
885 std::forward<SL>(
slices)...
891 template <
class CT,
class... S>
892 template <
class CTA,
class FSL,
class... SL>
894 : m_e(std::forward<CTA>(e))
895 , m_slices(std::forward<FSL>(first_slice), std::forward<SL>(
slices)...)
896 , m_shape(compute_shape(detail::is_sequence_view<inner_shape_type>{}))
897 , m_strides(m_e.strides())
898 , m_backstrides(m_e.backstrides())
899 , m_data_offset(data_offset_impl(std::make_index_sequence<
sizeof...(S)>()))
900 , m_strides_computed(
true)
904 template <
class CT,
class... S>
905 template <
class CTA,
class FSL,
class... SL>
907 : m_e(std::forward<CTA>(e))
908 , m_slices(std::forward<FSL>(first_slice), std::forward<SL>(
slices)...)
909 , m_shape(compute_shape(std::false_type{}))
910 , m_strides_computed(
false)
916 template <
class CT,
class... S>
919 temporary_type tmp(rhs);
930 template <
class CT,
class... S>
934 return semantic_base::operator=(e);
939 template <
class CT,
class... S>
941 inline auto xview<CT, S...>::operator=(
const E& e) -> disable_xexpression<E, self_type>&
954 template <
class CT,
class... S>
963 template <
class CT,
class... S>
972 template <
class CT,
class... S>
975 if constexpr (is_strided_view)
979 return static_layout;
983 bool strides_match = do_strides_match(
shape(), strides(), m_e.layout(),
true);
993 template <
class CT,
class... S>
994 inline bool xview<CT, S...>::is_contiguous() const noexcept
1010 template <
class CT,
class... S>
1016 std::fill(linear_begin(), linear_end(), value);
1020 std::fill(this->begin(), this->end(), value);
1030 template <
class CT,
class... S>
1031 template <
class... Args>
1034 XTENSOR_TRY(check_index(
shape(), args...));
1035 XTENSOR_CHECK_DIMENSION(
shape(), args...);
1038 return access(
static_cast<size_type
>(args)...);
1060 template <
class CT,
class... S>
1061 template <
class... Args>
1064 return unchecked_impl(make_index_sequence(args...),
static_cast<size_type
>(args)...);
1067 template <
class CT,
class... S>
1069 inline auto xview<CT, S...>::element(It first, It last) -> reference
1071 XTENSOR_TRY(check_element_index(
shape(), first, last));
1073 auto index = make_index(first, last);
1074 return m_e.element(index.cbegin(), index.cend());
1083 template <
class CT,
class... S>
1084 template <
class... Args>
1087 XTENSOR_TRY(check_index(
shape(), args...));
1088 XTENSOR_CHECK_DIMENSION(
shape(), args...);
1091 return access(
static_cast<size_type
>(args)...);
1113 template <
class CT,
class... S>
1114 template <
class... Args>
1117 return unchecked_impl(make_index_sequence(args...),
static_cast<size_type
>(args)...);
1120 template <
class CT,
class... S>
1122 inline auto xview<CT, S...>::element(It first, It last)
const -> const_reference
1125 auto index = make_index(first, last);
1126 return m_e.element(index.cbegin(), index.cend());
1132 template <
class CT,
class... S>
1141 template <
class CT,
class... S>
1152 template <
class CT,
class... S>
1154 inline auto xview<CT, S...>::storage() -> storage_type&
1157 return m_e.storage();
1160 template <
class CT,
class... S>
1162 inline auto xview<CT, S...>::storage() const -> const storage_type&
1165 return m_e.storage();
1168 template <
class CT,
class... S>
1170 auto xview<CT, S...>::linear_begin() -> linear_iterator
1171 requires(data_interface_expression<T> and strided_view_concept<CT, S...>)
1176 template <
class CT,
class... S>
1179 requires(data_interface_expression<T> and strided_view_concept<CT, S...>)
1184 template <
class CT,
class... S>
1187 requires(data_interface_expression<T> and strided_view_concept<CT, S...>)
1189 return linear_cbegin();
1192 template <
class CT,
class... S>
1195 requires(data_interface_expression<T> and strided_view_concept<CT, S...>)
1197 return linear_cend();
1200 template <
class CT,
class... S>
1203 requires(data_interface_expression<T> and strided_view_concept<CT, S...>)
1208 template <
class CT,
class... S>
1211 requires(data_interface_expression<T> and strided_view_concept<CT, S...>)
1216 template <
class CT,
class... S>
1219 requires(data_interface_expression<T> and strided_view_concept<CT, S...>)
1221 return reverse_linear_iterator(linear_end());
1224 template <
class CT,
class... S>
1227 requires(data_interface_expression<T> and strided_view_concept<CT, S...>)
1229 return reverse_linear_iterator(linear_begin());
1232 template <
class CT,
class... S>
1235 requires(data_interface_expression<T> and strided_view_concept<CT, S...>)
1237 return linear_crbegin();
1240 template <
class CT,
class... S>
1243 requires(data_interface_expression<T> and strided_view_concept<CT, S...>)
1245 return linear_crend();
1248 template <
class CT,
class... S>
1251 requires(data_interface_expression<T> and strided_view_concept<CT, S...>)
1253 return const_reverse_linear_iterator(linear_end());
1256 template <
class CT,
class... S>
1259 requires(data_interface_expression<T> and strided_view_concept<CT, S...>)
1261 return const_reverse_linear_iterator(linear_begin());
1267 template <
class CT,
class... S>
1269 inline auto xview<CT, S...>::strides() const
1271 if (!m_strides_computed)
1273 compute_strides(std::integral_constant<bool, has_trivial_strides>{});
1274 m_strides_computed =
true;
1279 template <
class CT,
class... S>
1281 inline auto xview<CT, S...>::backstrides() const
1283 if (!m_strides_computed)
1286 m_strides_computed =
true;
1288 return m_backstrides;
1294 template <
class CT,
class... S>
1296 inline auto xview<CT, S...>::data() const -> const_pointer
1302 template <
class CT,
class... S>
1304 inline auto xview<CT, S...>::data() -> pointer
1310 template <
class CT,
class... S>
1311 template <std::size_t... I>
1312 inline std::size_t xview<CT, S...>::data_offset_impl(std::index_sequence<I...>)
const noexcept
1314 auto temp = std::array<std::ptrdiff_t,
sizeof...(S)>(
1315 {(
static_cast<ptrdiff_t
>(xt::value(std::get<I>(m_slices), 0)))...}
1318 std::ptrdiff_t result = 0;
1320 for (; i < std::min(
sizeof...(S), m_e.strides().size()); ++i)
1322 result += temp[i] * m_e.strides()[i - newaxis_count_before<S...>(i)];
1324 for (; i <
sizeof...(S); ++i)
1328 return static_cast<std::size_t
>(result) + m_e.data_offset();
1334 template <
class CT,
class... S>
1339 if (!m_strides_computed)
1341 compute_strides(std::integral_constant<bool, has_trivial_strides>{});
1342 m_strides_computed =
true;
1344 return m_data_offset;
1349 template <
class CT,
class... S>
1350 inline auto xview<CT, S...>::underlying_size(size_type dim)
const -> size_type
1352 return m_e.shape()[dim];
1355 template <
class CT,
class... S>
1356 inline auto xview<CT, S...>::operator&() & -> xtl::xclosure_pointer<self_type&>
1358 return xtl::closure_pointer(*
this);
1361 template <
class CT,
class... S>
1364 return xtl::closure_pointer(*
this);
1367 template <
class CT,
class... S>
1370 return xtl::closure_pointer(std::move(*
this));
1383 template <
class CT,
class... S>
1387 return xt::broadcast_shape(m_shape,
shape);
1395 template <
class CT,
class... S>
1399 if constexpr (is_strided_view)
1401 return str.size() == strides().size() && std::equal(str.cbegin(), str.cend(), strides().begin());
1411 template <
class CT,
class... S>
1413 inline It xview<CT, S...>::data_xbegin_impl(It begin)
const noexcept
1418 template <
class CT,
class... S>
1420 inline It xview<CT, S...>::data_xend_impl(It begin,
layout_type l, size_type offset)
const noexcept
1422 return strided_data_end(*
this, begin, l, offset);
1425 template <
class CT,
class... S>
1428 return data_xbegin_impl(data());
1431 template <
class CT,
class... S>
1434 return data_xbegin_impl(data());
1437 template <
class CT,
class... S>
1440 return data_xend_impl(data() +
data_offset(), l, offset);
1443 template <
class CT,
class... S>
1445 -> const_container_iterator
1447 return data_xend_impl(data() +
data_offset(), l, offset);
1451 template <
class CT,
class... S>
1452 template <
class E,
class T>
1454 requires(data_interface_expression<T> and contiguous_view_concept<E, S...>)
1456 auto& de = e.derived_cast();
1457 de.resize(
shape(), force_resize);
1458 std::copy(data() +
data_offset(), data() +
data_offset() + de.size(), de.template begin<static_layout>());
1461 template <
class CT,
class... S>
1462 template <
class E, std::size_t... I>
1465 return rebind_t<E>(std::forward<E>(e), std::get<I>(m_slices)...);
1468 template <
class CT,
class... S>
1472 return build_view_impl(std::forward<E>(e), std::make_index_sequence<
sizeof...(S)>());
1475 template <
class CT,
class... S>
1476 template <
class align,
class simd,
class T>
1478 requires(has_simd_interface_concept<T> and strided_view_concept<CT, S...>)
1480 return m_e.template store_simd<xt_simd::unaligned_mode>(
data_offset() + i, e);
1483 template <
class CT,
class... S>
1484 template <
class align,
class requested_type, std::
size_t N,
class T>
1486 requires(has_simd_interface_concept<T> and strided_view_concept<CT, S...>)
1488 return m_e.template load_simd<xt_simd::unaligned_mode, requested_type>(
data_offset() + i);
1491 template <
class CT,
class... S>
1494 requires(has_simd_interface_concept<T> and strided_view_concept<CT, S...>)
1499 template <
class CT,
class... S>
1502 requires(has_simd_interface_concept<T> and strided_view_concept<CT, S...>)
1507 template <
class CT,
class... S>
1510 requires(has_simd_interface_concept<T> and strided_view_concept<CT, S...>)
1512 XTENSOR_ASSERT(is_contiguous());
1516 template <
class CT,
class... S>
1519 requires(has_simd_interface_concept<T> and strided_view_concept<CT, S...>)
1521 XTENSOR_ASSERT(is_contiguous());
1525 template <
class CT,
class... S>
1526 template <
class... Args>
1529 return std::make_index_sequence<
1530 (
sizeof...(Args) + integral_count<S...>() > newaxis_count<S...>()
1531 ?
sizeof...(Args) + integral_count<S...>() - newaxis_count<S...>()
1535 template <
class CT,
class... S>
1536 template <std::size_t... I>
1539 std::size_t original_dim = m_e.dimension();
1540 return std::array<std::ptrdiff_t,
sizeof...(I)>(
1541 {(
static_cast<std::ptrdiff_t
>(xt::step_size(std::get<integral_skip<S...>(I)>(m_slices), 1))
1542 * ((integral_skip<S...>(I) - newaxis_count_before<S...>(integral_skip<S...>(I))) < original_dim
1543 ? m_e.strides()[integral_skip<S...>(I) - newaxis_count_before<S...>(integral_skip<S...>(I))]
1548 template <
class CT,
class... S>
1551 m_strides = xtl::make_sequence<inner_strides_type>(this->
dimension(), 0);
1552 m_backstrides = xtl::make_sequence<inner_strides_type>(this->
dimension(), 0);
1554 constexpr std::size_t n_strides =
sizeof...(S) - integral_count<S...>();
1556 auto slice_strides = compute_strides_impl(std::make_index_sequence<n_strides>());
1558 for (std::size_t i = 0; i < n_strides; ++i)
1560 m_strides[i] = slice_strides[i];
1562 detail::adapt_strides(
shape(), m_strides, &m_backstrides, i);
1564 for (std::size_t i = n_strides; i < this->
dimension(); ++i)
1566 m_strides[i] = m_e.strides()[i + integral_count<S...>() - newaxis_count<S...>()];
1567 detail::adapt_strides(
shape(), m_strides, &m_backstrides, i);
1570 m_data_offset = data_offset_impl(std::make_index_sequence<
sizeof...(S)>());
1573 template <
class CT,
class... S>
1578 template <
class CT,
class... S>
1581 return access_impl(make_index_sequence());
1584 template <
class CT,
class... S>
1585 template <
class Arg,
class... Args>
1588 if (
sizeof...(Args) >= this->
dimension())
1590 return access(args...);
1592 return access_impl(make_index_sequence(
arg, args...),
arg, args...);
1595 template <
class CT,
class... S>
1598 return access_impl(make_index_sequence());
1601 template <
class CT,
class... S>
1602 template <
class Arg,
class... Args>
1605 if (
sizeof...(Args) >= this->
dimension())
1607 return access(args...);
1609 return access_impl(make_index_sequence(
arg, args...),
arg, args...);
1612 template <
class CT,
class... S>
1613 template <typename std::decay_t<CT>::size_type... I,
class... Args>
1616 return m_e.unchecked(index<I>(args...)...);
1619 template <
class CT,
class... S>
1620 template <typename std::decay_t<CT>::size_type... I,
class... Args>
1624 return m_e.unchecked(index<I>(args...)...);
1627 template <
class CT,
class... S>
1628 template <typename std::decay_t<CT>::size_type... I,
class... Args>
1631 return m_e(index<I>(args...)...);
1634 template <
class CT,
class... S>
1635 template <typename std::decay_t<CT>::size_type... I,
class... Args>
1638 return m_e(index<I>(args...)...);
1641 template <
class CT,
class... S>
1642 template <typename std::decay_t<CT>::size_type I,
class... Args>
1645 if constexpr (lesser_condition<I>::value)
1647 constexpr size_type slice_index = newaxis_skip<S...>(I);
1648 return sliced_access<slice_index - integral_count_before<S...>(slice_index)>(
1649 std::get<slice_index>(m_slices),
1655 return argument<I - integral_count<S...>() + newaxis_count<S...>()>(args...);
1659 template <
class CT,
class... S>
1660 template <typename std::decay_t<CT>::size_type I,
class T>
1661 inline auto
xview<CT, S...>::sliced_access(const xslice<T>& slice) const -> size_type
1663 return static_cast<size_type
>(slice.derived_cast()(0));
1666 template <
class CT,
class... S>
1667 template <typename std::decay_t<CT>::size_type I,
class T, class Arg, class... Args>
1668 inline auto
xview<CT, S...>::sliced_access(const xslice<T>& slice, Arg arg, Args... args) const -> size_type
1670 using ST =
typename T::size_type;
1671 return static_cast<size_type
>(
1672 slice.derived_cast()(argument<I>(
static_cast<ST
>(arg),
static_cast<ST
>(args)...))
1676 template <
class CT,
class... S>
1677 template <typename std::decay_t<CT>::size_type I,
class T, class... Args>
1678 inline auto
xview<CT, S...>::sliced_access(const T& squeeze, Args...) const -> size_type
1679 requires(!is_xslice<T>::value)
1681 return static_cast<size_type
>(
squeeze);
1684 template <
class CT,
class... S>
1688 auto index = xtl::make_sequence<base_index_type>(m_e.dimension(), 0);
1689 using diff_type =
typename std::iterator_traits<It>::difference_type;
1690 using ivalue_type =
typename base_index_type::value_type;
1691 auto func1 = [&first](
const auto& s)
noexcept
1693 return get_slice_value(s, first);
1695 auto func2 = [](
const auto& s)
noexcept
1697 return xt::value(s, 0);
1700 auto s =
static_cast<diff_type
>(
1701 (std::min)(
static_cast<size_type
>(std::distance(first, last)), this->
dimension())
1703 auto first_copy = last - s;
1704 for (size_type i = 0; i != m_e.dimension(); ++i)
1706 size_type k = newaxis_skip<S...>(i);
1710 std::advance(first,
static_cast<diff_type
>(k - xt::integral_count_before<S...>(i)));
1714 index[i] = k <
sizeof...(S) ? apply<size_type>(k, func1, m_slices)
1715 :
static_cast<ivalue_type
>(*first);
1719 index[i] = k <
sizeof...(S) ? apply<size_type>(k, func2, m_slices) : ivalue_type(0);
1725 template <
class CT,
class... S>
1728 return inner_shape_type(m_e.shape());
1731 template <
class CT,
class... S>
1734 std::size_t dim = m_e.dimension() - integral_count<S...>() + newaxis_count<S...>();
1735 auto shape = xtl::make_sequence<inner_shape_type>(dim, 0);
1736 auto func = [](
const auto& s)
noexcept
1740 for (size_type i = 0; i != dim; ++i)
1742 size_type index = integral_skip<S...>(i);
1743 shape[i] = index <
sizeof...(S) ? apply<size_type>(index, func, m_slices)
1744 : m_e.shape()[index - newaxis_count_before<S...>(index)];
1749 namespace xview_detail
1751 template <
class V,
class T>
1752 inline void run_assign_temporary_impl(V& v,
const T& t, std::true_type )
1754 strided_loop_assigner<true>::run(v, t);
1757 template <
class V,
class T>
1759 run_assign_temporary_impl(V& v,
const T& t, std::false_type )
1761 std::copy(t.cbegin(), t.cend(), v.begin());
1765 template <
class CT,
class... S>
1768 constexpr bool fast_assign = detail::is_strided_view<xexpression_type, S...>::value
1769 && xassign_traits<
xview<CT, S...>, temporary_type>::simd_strided_assign();
1770 xview_detail::run_assign_temporary_impl(*
this, tmp, std::integral_constant<bool, fast_assign>{});
1775 template <
class E,
class... S>
1776 inline std::size_t get_underlying_shape_index(std::size_t I)
1778 return I - newaxis_count_before<get_slice_type<E, S>...>(I);
1781 template <
class... S>
1785 struct check_slice<>
1787 using type = void_t<>;
1790 template <
class S,
class... SL>
1791 struct check_slice<S, SL...>
1793 static_assert(!std::is_same<S, xellipsis_tag>::value,
"ellipsis not supported vith xview");
1794 using type =
typename check_slice<SL...>::type;
1797 template <
class E, std::size_t... I,
class... S>
1798 inline auto make_view_impl(E&& e, std::index_sequence<I...>, S&&... slices)
1801 using view_type = xview<xtl::closure_type_t<E>, get_slice_type<std::decay_t<E>, S>...>;
1804 get_slice_implementation(
1806 std::forward<S>(slices),
1807 get_underlying_shape_index<std::decay_t<E>, S...>(I)
1822 template <
class E,
class... S>
1825 return detail::make_view_impl(
1827 std::make_index_sequence<
sizeof...(S)>(),
1828 std::forward<S>(
slices)...
1839 inline static auto make(E&& e,
const std::ptrdiff_t index)
1841 const auto shape = e.shape();
1842 check_dimension(shape);
1843 return view(e, index,
xt::all());
1849 inline static void check_dimension(
const S& shape)
1851 if (shape.size() != 2)
1854 std::invalid_argument,
1855 "A row can only be accessed on an expression with exact two dimensions"
1860 template <
class T, std::
size_t N>
1861 inline static void check_dimension(
const std::array<T, N>&)
1863 static_assert(N == 2,
"A row can only be accessed on an expression with exact two dimensions");
1872 inline static auto make(E&& e,
const std::ptrdiff_t index)
1874 const auto shape = e.shape();
1875 check_dimension(shape);
1882 inline static void check_dimension(
const S& shape)
1884 if (shape.size() != 2)
1887 std::invalid_argument,
1888 "A column can only be accessed on an expression with exact two dimensions"
1893 template <
class T, std::
size_t N>
1894 inline static void check_dimension(
const std::array<T, N>&)
1896 static_assert(N == 2,
"A column can only be accessed on an expression with exact two dimensions");
1911 inline auto row(E&& e, std::ptrdiff_t index)
1913 return detail::row_impl::make(e, index);
1926 inline auto col(E&& e, std::ptrdiff_t index)
1928 return detail::column_impl::make(e, index);
1935 template <
class CT,
class... S>
1937 inline auto xview<CT, S...>::stepper_begin(
const ST&
shape) -> stepper
1940 if constexpr (is_strided_view)
1942 return stepper(
this, data_xbegin(), offset);
1946 return stepper(
this, m_e.stepper_begin(m_e.shape()), offset);
1950 template <
class CT,
class... S>
1955 if constexpr (is_strided_view)
1957 return stepper(
this, data_xend(l, offset), offset);
1961 return stepper(
this, m_e.stepper_end(m_e.shape(), l), offset,
true, l);
1965 template <
class CT,
class... S>
1970 if constexpr (is_strided_view)
1972 return const_stepper(
this, data_xbegin(), offset);
1976 const xexpression_type& e = m_e;
1977 return const_stepper(
this, e.stepper_begin(m_e.shape()), offset);
1981 template <
class CT,
class... S>
1986 if constexpr (is_strided_view)
1988 return const_stepper(
this, data_xend(l, offset), offset);
1992 const xexpression_type& e = m_e;
1993 return const_stepper(
this, e.stepper_end(m_e.shape(), l), offset,
true, l);
2001 template <
bool is_const,
class CT,
class... S>
2002 inline xview_stepper<is_const, CT, S...>::xview_stepper(
2015 std::fill(m_index_keeper.begin(), m_index_keeper.end(), 0);
2016 auto func = [](
const auto& s)
noexcept
2018 return xt::value(s, 0);
2020 for (size_type i = 0; i <
sizeof...(S); ++i)
2022 if (!is_newaxis_slice(i))
2024 size_type s = apply<size_type>(i, func, p_view->slices());
2025 size_type index = i - newaxis_count_before<S...>(i);
2026 m_it.step(index, s);
2036 template <
bool is_const,
class CT,
class... S>
2037 inline auto xview_stepper<is_const, CT, S...>::operator*() const -> reference
2042 template <
bool is_const,
class CT,
class... S>
2043 inline void xview_stepper<is_const, CT, S...>::step(size_type dim)
2045 auto func = [
this](size_type index, size_type offset)
2047 m_it.step(index, offset);
2049 common_step_forward(dim, func);
2052 template <
bool is_const,
class CT,
class... S>
2053 inline void xview_stepper<is_const, CT, S...>::step_back(size_type dim)
2055 auto func = [
this](size_type index, size_type offset)
2057 m_it.step_back(index, offset);
2059 common_step_backward(dim, func);
2062 template <
bool is_const,
class CT,
class... S>
2063 inline void xview_stepper<is_const, CT, S...>::step(size_type dim, size_type n)
2065 auto func = [
this](size_type index, size_type offset)
2067 m_it.step(index, offset);
2069 common_step_forward(dim, n, func);
2072 template <
bool is_const,
class CT,
class... S>
2073 inline void xview_stepper<is_const, CT, S...>::step_back(size_type dim, size_type n)
2075 auto func = [
this](size_type index, size_type offset)
2077 m_it.step_back(index, offset);
2079 common_step_backward(dim, n, func);
2082 template <
bool is_const,
class CT,
class... S>
2083 inline void xview_stepper<is_const, CT, S...>::reset(size_type dim)
2085 auto func = [
this](size_type index, size_type offset)
2087 m_it.step_back(index, offset);
2089 common_reset(dim, func,
false);
2092 template <
bool is_const,
class CT,
class... S>
2093 inline void xview_stepper<is_const, CT, S...>::reset_back(size_type dim)
2095 auto func = [
this](size_type index, size_type offset)
2097 m_it.step(index, offset);
2099 common_reset(dim, func,
true);
2102 template <
bool is_const,
class CT,
class... S>
2103 inline void xview_stepper<is_const, CT, S...>::to_begin()
2105 std::fill(m_index_keeper.begin(), m_index_keeper.end(), 0);
2109 template <
bool is_const,
class CT,
class... S>
2110 inline void xview_stepper<is_const, CT, S...>::to_end(layout_type l)
2116 template <
bool is_const,
class CT,
class... S>
2117 inline bool xview_stepper<is_const, CT, S...>::is_newaxis_slice(size_type index)
const noexcept
2120 return newaxis_count_before<S...>(index + 1) != newaxis_count_before<S...>(index);
2123 template <
bool is_const,
class CT,
class... S>
2124 inline void xview_stepper<is_const, CT, S...>::to_end_impl(layout_type l)
2126 auto func = [](
const auto& s)
noexcept
2128 return xt::value(s, get_size(s) - 1);
2130 auto size_func = [](
const auto& s)
noexcept
2135 for (size_type i = 0; i <
sizeof...(S); ++i)
2137 if (!is_newaxis_slice(i))
2139 size_type s = apply<size_type>(i, func, p_view->slices());
2140 size_type ix = apply<size_type>(i, size_func, p_view->slices());
2141 m_index_keeper[i] = ix - size_type(1);
2142 size_type index = i - newaxis_count_before<S...>(i);
2143 s = p_view->underlying_size(index) - 1 - s;
2144 m_it.step_back(index, s);
2147 if (l == layout_type::row_major)
2149 for (size_type i =
sizeof...(S); i > 0; --i)
2151 if (!is_newaxis_slice(i - 1))
2153 m_index_keeper[i - 1]++;
2158 else if (l == layout_type::column_major)
2160 for (size_type i = 0; i <
sizeof...(S); ++i)
2162 if (!is_newaxis_slice(i))
2164 m_index_keeper[i]++;
2171 XTENSOR_THROW(std::runtime_error,
"Iteration only allowed in row or column major.");
2175 template <
bool is_const,
class CT,
class... S>
2177 void xview_stepper<is_const, CT, S...>::common_step_forward(size_type dim, F f)
2179 if (dim >= m_offset)
2181 auto func = [&dim,
this](
const auto& s)
noexcept
2183 return step_size(s, this->m_index_keeper[dim]++, 1);
2185 size_type index = integral_skip<S...>(dim);
2186 if (!is_newaxis_slice(index))
2188 size_type step_size = index <
sizeof...(S) ? apply<size_type>(index, func, p_view->slices())
2190 index -= newaxis_count_before<S...>(index);
2191 f(index, step_size);
2196 template <
bool is_const,
class CT,
class... S>
2198 void xview_stepper<is_const, CT, S...>::common_step_forward(size_type dim, size_type n, F f)
2200 if (dim >= m_offset)
2202 auto func = [&dim, &n,
this](
const auto& s)
noexcept
2204 auto st_size = step_size(s, this->m_index_keeper[dim], n);
2205 this->m_index_keeper[dim] += n;
2206 return size_type(st_size);
2209 size_type index = integral_skip<S...>(dim);
2210 if (!is_newaxis_slice(index))
2212 size_type step_size = index <
sizeof...(S) ? apply<size_type>(index, func, p_view->slices())
2214 index -= newaxis_count_before<S...>(index);
2215 f(index, step_size);
2220 template <
bool is_const,
class CT,
class... S>
2222 void xview_stepper<is_const, CT, S...>::common_step_backward(size_type dim, F f)
2224 if (dim >= m_offset)
2226 auto func = [&dim,
this](
const auto& s)
noexcept
2228 this->m_index_keeper[dim]--;
2229 return step_size(s, this->m_index_keeper[dim], 1);
2231 size_type index = integral_skip<S...>(dim);
2232 if (!is_newaxis_slice(index))
2234 size_type step_size = index <
sizeof...(S) ? apply<size_type>(index, func, p_view->slices())
2236 index -= newaxis_count_before<S...>(index);
2237 f(index, step_size);
2242 template <
bool is_const,
class CT,
class... S>
2244 void xview_stepper<is_const, CT, S...>::common_step_backward(size_type dim, size_type n, F f)
2246 if (dim >= m_offset)
2248 auto func = [&dim, &n,
this](
const auto& s)
noexcept
2250 this->m_index_keeper[dim] -= n;
2251 return step_size(s, this->m_index_keeper[dim], n);
2254 size_type index = integral_skip<S...>(dim);
2255 if (!is_newaxis_slice(index))
2257 size_type step_size = index <
sizeof...(S) ? apply<size_type>(index, func, p_view->slices())
2259 index -= newaxis_count_before<S...>(index);
2260 f(index, step_size);
2265 template <
bool is_const,
class CT,
class... S>
2267 void xview_stepper<is_const, CT, S...>::common_reset(size_type dim, F f,
bool backwards)
2269 auto size_func = [](
const auto& s)
noexcept
2273 auto end_func = [](
const auto& s)
noexcept
2275 return xt::value(s, get_size(s) - 1) - xt::value(s, 0);
2278 size_type index = integral_skip<S...>(dim);
2279 if (!is_newaxis_slice(index))
2281 if (dim < m_index_keeper.size())
2283 size_type size = index <
sizeof...(S) ? apply<size_type>(index, size_func, p_view->slices())
2284 : p_view->shape()[dim];
2285 m_index_keeper[dim] = backwards ? size - 1 : 0;
2288 size_type reset_n = index <
sizeof...(S) ? apply<size_type>(index, end_func, p_view->slices())
2289 : p_view->shape()[dim] - 1;
2290 index -= newaxis_count_before<S...>(index);
Fixed shape implementation for compile time defined arrays.
size_type size() const noexcept(noexcept(derived_cast().shape()))
size_type dimension() const noexcept
Base class for xexpressions.
Base class for multidimensional iterable expressions.
derived_type & assign_temporary(temporary_type &&)
Multidimensional view with tensor semantic.
xview(CTA &&e, FSL &&first_slice, SL &&... slices) noexcept
Constructs a view on the specified xexpression.
const slice_type & slices() const noexcept
bool has_linear_assign(const ST &strides) const
reference unchecked(Args... args)
self_type & operator=(const xexpression< E > &e)
The extended assignment operator.
reference operator()(Args... args)
Returns a reference to the element at the specified position in the view.
const inner_shape_type & shape() const noexcept
Returns the shape of the view.
bool broadcast_shape(ST &shape, bool reuse_cache=false) const
xexpression_type & expression() noexcept
std::size_t data_offset() const noexcept
void fill(const T &value)
layout_type layout() const noexcept
auto arg(E &&e) noexcept
Calculates the phase angle (in radians) elementwise for the complex numbers in e.
auto squeeze(E &&e)
Returns a squeeze view of the given expression.
std::size_t compute_strides(const shape_type &shape, layout_type l, strides_type &strides)
Compute the strides given the shape and the layout of an array.
standard mathematical functions for xexpressions
auto all() noexcept
Returns a slice representing a full dimension, to be used as an argument of view function.
auto row(E &&e, std::ptrdiff_t index)
Constructs and returns a row (sliced view) on the specified expression.
auto col(E &&e, std::ptrdiff_t index)
Constructs and returns a column (sliced view) on the specified expression.
auto view(E &&e, S &&... slices)
Constructs and returns a view on the specified xexpression.