@@ -25,18 +25,27 @@ namespace xt
2525
2626#define DEFAULT_STRATEGY_ACCUMULATORS evaluation_strategy::immediate_type
2727
28+ namespace detail
29+ {
30+ template <class V = void >
31+ struct accumulator_identity : xtl::identity
32+ {
33+ using value_type = V;
34+ };
35+ }
2836 /* *************
2937 * accumulate *
3038 **************/
3139
32- template <class ACCUMULATE_FUNC , class INIT_FUNC = xtl::identity >
40+ template <class ACCUMULATE_FUNC , class INIT_FUNC = detail::accumulator_identity< void > >
3341 struct xaccumulator_functor
3442 : public std::tuple<ACCUMULATE_FUNC, INIT_FUNC>
3543 {
3644 using self_type = xaccumulator_functor<ACCUMULATE_FUNC, INIT_FUNC>;
3745 using base_type = std::tuple<ACCUMULATE_FUNC, INIT_FUNC>;
3846 using accumulate_functor_type = ACCUMULATE_FUNC;
3947 using init_functor_type = INIT_FUNC;
48+ using init_value_type = typename init_functor_type::value_type;
4049
4150 xaccumulator_functor ()
4251 : base_type()
@@ -188,9 +197,10 @@ namespace xt
188197 template <class F , class E >
189198 inline auto accumulator_impl (F&& f, E&& e, std::size_t axis, evaluation_strategy::immediate_type)
190199 {
191- using accumulate_functor = std::decay_t <decltype (xt::get<0 >(f))>;
192- using function_return_type = typename accumulate_functor::result_type;
193- using result_type = xaccumulator_return_type_t <std::decay_t <E>, function_return_type>;
200+ using init_type = typename F::init_value_type;
201+ using init_functor_type = typename F::init_functor_type;
202+ using return_type = std::conditional_t <std::is_same<init_type, void >::value, typename std::decay_t <E>::value_type, init_type>;
203+ using result_type = xaccumulator_return_type_t <std::decay_t <E>, return_type>;
194204
195205 if (axis >= e.dimension ())
196206 {
@@ -232,7 +242,8 @@ namespace xt
232242 inner_loop_size = inner_loop_size - inner_stride;
233243
234244 // activate the init loop if we have an init function other than identity
235- if (!std::is_same<std::decay_t <decltype (xt::get<1 >(f))>, xtl::identity>::value)
245+ if (!std::is_same<std::decay_t <typename F::init_functor_type>,
246+ typename detail::accumulator_identity<init_type>>::value)
236247 {
237248 accumulator_init_with_f (xt::get<1 >(f), result, axis);
238249 }
@@ -255,10 +266,10 @@ namespace xt
255266 template <class F , class E >
256267 inline auto accumulator_impl (F&& f, E&& e, evaluation_strategy::immediate_type)
257268 {
258- using accumulate_functor = std::decay_t <decltype (xt::get<0 >(f))>;
259- using T = typename accumulate_functor::result_type;
269+ using init_type = typename F::init_value_type;
270+ using return_type = std::conditional_t <std::is_same<init_type, void >::value, typename std::decay_t <E>::value_type, init_type>;
271+ using result_type = xaccumulator_return_type_t <std::decay_t <E>, return_type>;
260272
261- using result_type = xaccumulator_linear_return_type_t <std::decay_t <E>, T>;
262273 std::size_t sz = e.size ();
263274 auto result = result_type::from_shape ({sz});
264275
0 commit comments