Skip to content

Commit c009384

Browse files
authored
Merge pull request #2254 from adriendelsalle/fix-reducer-optional-assignment
Fix reducers assignment
2 parents 83f9e3b + 9e70992 commit c009384

9 files changed

Lines changed: 591 additions & 228 deletions

File tree

docs/source/compilers.rst

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,13 @@ Workarounds for this compiler bug arise in various files of the code base.
7070
Everywhere, the handling of `Clang < 3.8` is wrapped with checks for the
7171
``X_OLD_CLANG`` macro.
7272

73-
The support of `Clang < 4.0` is dropped in xtensor 0.22.
73+
**The support of `Clang < 4.0` is dropped in xtensor 0.22.**
74+
75+
Clang-cl and ``std::get``
76+
-------------------------
77+
78+
`Clang-cl` does not allow to call ``std::get`` with ``*this`` as parameter from a class inheriting from std::tuple.
79+
In that case, we explicitly upcast to ``std::tuple``.
7480

7581
GCC < 5.1 and ``std::is_trivially_default_constructible``
7682
---------------------------------------------------------

include/xtensor/xaccumulator.hpp

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -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

include/xtensor/xassign.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,8 @@ namespace xt
342342
template <class T>
343343
static constexpr bool simd_size_impl() { return xt_simd::simd_traits<T>::size > 1 || (is_bool<T>::value && use_xsimd()); }
344344
static constexpr bool simd_size() { return simd_size_impl<e1_value_type>() && simd_size_impl<e2_value_type>(); }
345-
static constexpr bool simd_interface() { return has_simd_interface<E2, requested_value_type>(); }
345+
static constexpr bool simd_interface() { return has_simd_interface<E1, requested_value_type>() &&
346+
has_simd_interface<E2, requested_value_type>(); }
346347

347348
public:
348349

0 commit comments

Comments
 (0)