Skip to content

Commit 883ff34

Browse files
authored
Refactor xfunction to use std::apply rather than index_sequence (#2876)
# Checklist - [ ] The title and commit message(s) are descriptive. - [ ] Small commits made to fix your PR have been squashed to avoid history pollution. - [ ] Tests have been added for new features or bug fixes. - [ ] API of new functions and classes are documented. # Description <!--- Give any relevant description here. If your PR fixes an issue, please include "Fixes #ISSUE" (substituting the relevant issue ID). -->
1 parent 9a37673 commit 883ff34

File tree

1 file changed

+74
-107
lines changed

1 file changed

+74
-107
lines changed

include/xtensor/core/xfunction.hpp

Lines changed: 74 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -355,24 +355,6 @@ namespace xt
355355

356356
private:
357357

358-
template <std::size_t... I>
359-
layout_type layout_impl(std::index_sequence<I...>) const noexcept;
360-
361-
template <std::size_t... I, class... Args>
362-
const_reference access_impl(std::index_sequence<I...>, Args... args) const;
363-
364-
template <std::size_t... I, class... Args>
365-
const_reference unchecked_impl(std::index_sequence<I...>, Args... args) const;
366-
367-
template <std::size_t... I, class It>
368-
const_reference element_access_impl(std::index_sequence<I...>, It first, It last) const;
369-
370-
template <std::size_t... I>
371-
const_reference data_element_impl(std::index_sequence<I...>, size_type i) const;
372-
373-
template <class align, class requested_type, std::size_t N, std::size_t... I>
374-
auto load_simd_impl(std::index_sequence<I...>, size_type i) const;
375-
376358
template <class Func, std::size_t... I>
377359
const_stepper build_stepper(Func&& f, std::index_sequence<I...>) const noexcept;
378360

@@ -437,9 +419,6 @@ namespace xt
437419

438420
using data_type = std::tuple<decltype(xt::linear_begin(std::declval<const std::decay_t<CT>>()))...>;
439421

440-
template <std::size_t... I>
441-
reference deref_impl(std::index_sequence<I...>) const;
442-
443422
template <std::size_t... I>
444423
difference_type
445424
tuple_max_diff(std::index_sequence<I...>, const data_type& lhs, const data_type& rhs) const;
@@ -500,12 +479,6 @@ namespace xt
500479

501480
private:
502481

503-
template <std::size_t... I>
504-
reference deref_impl(std::index_sequence<I...>) const;
505-
506-
template <class T, std::size_t... I>
507-
simd_return_type<T> step_simd_impl(std::index_sequence<I...>);
508-
509482
const xfunction_type* p_f;
510483
std::tuple<typename std::decay_t<CT>::const_stepper...> m_st;
511484
};
@@ -593,7 +566,13 @@ namespace xt
593566
template <class F, class... CT>
594567
inline layout_type xfunction<F, CT...>::layout() const noexcept
595568
{
596-
return layout_impl(std::make_index_sequence<sizeof...(CT)>());
569+
return std::apply(
570+
[&](auto&... e)
571+
{
572+
return compute_layout(e.layout()...);
573+
},
574+
m_e
575+
);
597576
}
598577

599578
template <class F, class... CT>
@@ -628,7 +607,16 @@ namespace xt
628607
{
629608
// The static cast prevents the compiler from instantiating the template methods with signed integers,
630609
// leading to warning about signed/unsigned conversions in the deeper layers of the access methods
631-
return access_impl(std::make_index_sequence<sizeof...(CT)>(), static_cast<size_type>(args)...);
610+
611+
return std::apply(
612+
[&](auto&... e)
613+
{
614+
XTENSOR_TRY(check_index(shape(), args...));
615+
XTENSOR_CHECK_DIMENSION(shape(), args...);
616+
return m_f(e(args...)...);
617+
},
618+
m_e
619+
);
632620
}
633621

634622
/**
@@ -643,7 +631,13 @@ namespace xt
643631
template <class F, class... CT>
644632
inline auto xfunction<F, CT...>::flat(size_type index) const -> const_reference
645633
{
646-
return data_element_impl(std::make_index_sequence<sizeof...(CT)>(), index);
634+
return std::apply(
635+
[&](auto&... e)
636+
{
637+
return m_f(e.data_element(index)...);
638+
},
639+
m_e
640+
);
647641
}
648642

649643
/**
@@ -671,7 +665,13 @@ namespace xt
671665
{
672666
// The static cast prevents the compiler from instantiating the template methods with signed integers,
673667
// leading to warning about signed/unsigned conversions in the deeper layers of the access methods
674-
return unchecked_impl(std::make_index_sequence<sizeof...(CT)>(), static_cast<size_type>(args)...);
668+
return std::apply(
669+
[&](const auto&... e)
670+
{
671+
return m_f(e.unchecked(static_cast<size_type>(args)...)...);
672+
},
673+
m_e
674+
);
675675
}
676676

677677
/**
@@ -685,7 +685,14 @@ namespace xt
685685
template <class It>
686686
inline auto xfunction<F, CT...>::element(It first, It last) const -> const_reference
687687
{
688-
return element_access_impl(std::make_index_sequence<sizeof...(CT)>(), first, last);
688+
return std::apply(
689+
[&](auto&... e)
690+
{
691+
XTENSOR_TRY(check_element_index(shape(), first, last));
692+
return m_f(e.element(first, last)...);
693+
},
694+
m_e
695+
);
689696
}
690697

691698
//@}
@@ -819,7 +826,13 @@ namespace xt
819826
template <class F, class... CT>
820827
inline auto xfunction<F, CT...>::data_element(size_type i) const -> const_reference
821828
{
822-
return data_element_impl(std::make_index_sequence<sizeof...(CT)>(), i);
829+
return std::apply(
830+
[&](auto&... e)
831+
{
832+
return m_f(e.data_element(i)...);
833+
},
834+
m_e
835+
);
823836
}
824837

825838
template <class F, class... CT>
@@ -833,7 +846,13 @@ namespace xt
833846
template <class align, class requested_type, std::size_t N>
834847
inline auto xfunction<F, CT...>::load_simd(size_type i) const -> simd_return_type<requested_type>
835848
{
836-
return load_simd_impl<align, requested_type, N>(std::make_index_sequence<sizeof...(CT)>(), i);
849+
return std::apply(
850+
[&](auto&... e)
851+
{
852+
return m_f.simd_apply((e.template load_simd<align, requested_type>(i))...);
853+
},
854+
m_e
855+
);
837856
}
838857

839858
template <class F, class... CT>
@@ -848,55 +867,6 @@ namespace xt
848867
return m_f;
849868
}
850869

851-
template <class F, class... CT>
852-
template <std::size_t... I>
853-
inline layout_type xfunction<F, CT...>::layout_impl(std::index_sequence<I...>) const noexcept
854-
{
855-
return compute_layout(std::get<I>(m_e).layout()...);
856-
}
857-
858-
template <class F, class... CT>
859-
template <std::size_t... I, class... Args>
860-
inline auto xfunction<F, CT...>::access_impl(std::index_sequence<I...>, Args... args) const
861-
-> const_reference
862-
{
863-
XTENSOR_TRY(check_index(shape(), args...));
864-
XTENSOR_CHECK_DIMENSION(shape(), args...);
865-
return m_f(std::get<I>(m_e)(args...)...);
866-
}
867-
868-
template <class F, class... CT>
869-
template <std::size_t... I, class... Args>
870-
inline auto xfunction<F, CT...>::unchecked_impl(std::index_sequence<I...>, Args... args) const
871-
-> const_reference
872-
{
873-
return m_f(std::get<I>(m_e).unchecked(args...)...);
874-
}
875-
876-
template <class F, class... CT>
877-
template <std::size_t... I, class It>
878-
inline auto xfunction<F, CT...>::element_access_impl(std::index_sequence<I...>, It first, It last) const
879-
-> const_reference
880-
{
881-
XTENSOR_TRY(check_element_index(shape(), first, last));
882-
return m_f((std::get<I>(m_e).element(first, last))...);
883-
}
884-
885-
template <class F, class... CT>
886-
template <std::size_t... I>
887-
inline auto xfunction<F, CT...>::data_element_impl(std::index_sequence<I...>, size_type i) const
888-
-> const_reference
889-
{
890-
return m_f((std::get<I>(m_e).data_element(i))...);
891-
}
892-
893-
template <class F, class... CT>
894-
template <class align, class requested_type, std::size_t N, std::size_t... I>
895-
inline auto xfunction<F, CT...>::load_simd_impl(std::index_sequence<I...>, size_type i) const
896-
{
897-
return m_f.simd_apply((std::get<I>(m_e).template load_simd<align, requested_type>(i))...);
898-
}
899-
900870
template <class F, class... CT>
901871
template <class Func, std::size_t... I>
902872
inline auto xfunction<F, CT...>::build_stepper(Func&& f, std::index_sequence<I...>) const noexcept
@@ -987,7 +957,13 @@ namespace xt
987957
template <class F, class... CT>
988958
inline auto xfunction_iterator<F, CT...>::operator*() const -> reference
989959
{
990-
return deref_impl(std::make_index_sequence<sizeof...(CT)>());
960+
return std::apply(
961+
[&](auto&... it)
962+
{
963+
return (p_f->m_f)(*it...);
964+
},
965+
m_it
966+
);
991967
}
992968

993969
template <class F, class... CT>
@@ -1010,13 +986,6 @@ namespace xt
1010986
return std::get<index>(m_it) < std::get<index>(rhs.m_it);
1011987
}
1012988

1013-
template <class F, class... CT>
1014-
template <std::size_t... I>
1015-
inline auto xfunction_iterator<F, CT...>::deref_impl(std::index_sequence<I...>) const -> reference
1016-
{
1017-
return (p_f->m_f)(*std::get<I>(m_it)...);
1018-
}
1019-
1020989
template <class F, class... CT>
1021990
template <std::size_t... I>
1022991
inline auto xfunction_iterator<F, CT...>::tuple_max_diff(
@@ -1140,28 +1109,26 @@ namespace xt
11401109
template <class F, class... CT>
11411110
inline auto xfunction_stepper<F, CT...>::operator*() const -> reference
11421111
{
1143-
return deref_impl(std::make_index_sequence<sizeof...(CT)>());
1144-
}
1145-
1146-
template <class F, class... CT>
1147-
template <std::size_t... I>
1148-
inline auto xfunction_stepper<F, CT...>::deref_impl(std::index_sequence<I...>) const -> reference
1149-
{
1150-
return (p_f->m_f)(*std::get<I>(m_st)...);
1151-
}
1152-
1153-
template <class F, class... CT>
1154-
template <class T, std::size_t... I>
1155-
inline auto xfunction_stepper<F, CT...>::step_simd_impl(std::index_sequence<I...>) -> simd_return_type<T>
1156-
{
1157-
return (p_f->m_f.simd_apply)(std::get<I>(m_st).template step_simd<T>()...);
1112+
return std::apply(
1113+
[&](auto&... e)
1114+
{
1115+
return (p_f->m_f)(*e...);
1116+
},
1117+
m_st
1118+
);
11581119
}
11591120

11601121
template <class F, class... CT>
11611122
template <class T>
11621123
inline auto xfunction_stepper<F, CT...>::step_simd() -> simd_return_type<T>
11631124
{
1164-
return step_simd_impl<T>(std::make_index_sequence<sizeof...(CT)>());
1125+
return std::apply(
1126+
[&](auto&... st)
1127+
{
1128+
return (p_f->m_f.simd_apply)(st.template step_simd<T>()...);
1129+
},
1130+
m_st
1131+
);
11651132
}
11661133

11671134
template <class F, class... CT>

0 commit comments

Comments
 (0)