@@ -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