timshen created this revision. timshen added a reviewer: mclow.lists. Herald added subscribers: christof, sanjoy. Herald added a reviewer: EricWF.
- change the uses of abi_for_size to simd_abi::deduce. - remove the const in const_where_expression's template. https://reviews.llvm.org/D44663 Files: libcxx/include/experimental/simd libcxx/test/std/experimental/simd/simd.elementwise/operators.pass.cpp libcxx/test/std/experimental/simd/simd.horizontal/concat.pass.cpp libcxx/test/std/experimental/simd/simd.horizontal/hmax.pass.cpp libcxx/test/std/experimental/simd/simd.horizontal/hmin.pass.cpp libcxx/test/std/experimental/simd/simd.horizontal/split.pass.cpp libcxx/test/std/experimental/simd/simd.traits/abi_for_size.pass.cpp libcxx/test/std/experimental/simd/simd.traits/simd_abi_deduce.pass.cpp libcxx/test/std/experimental/simd/simd.whereexpr/where.pass.cpp
Index: libcxx/test/std/experimental/simd/simd.whereexpr/where.pass.cpp =================================================================== --- libcxx/test/std/experimental/simd/simd.whereexpr/where.pass.cpp +++ libcxx/test/std/experimental/simd/simd.whereexpr/where.pass.cpp @@ -43,25 +43,23 @@ void compile_const_where() { { const native_simd<int> a{}; - static_assert( - std::is_same<decltype(where(a < 2, a)), - const_where_expression<native_simd_mask<int>, - const native_simd<int>>>::value, - ""); + static_assert(std::is_same<decltype(where(a < 2, a)), + const_where_expression<native_simd_mask<int>, + native_simd<int>>>::value, + ""); } { const native_simd_mask<int> a{}; static_assert( - std::is_same< - decltype(where(a, a)), - const_where_expression<native_simd_mask<int>, - const native_simd_mask<int>>>::value, + std::is_same<decltype(where(a, a)), + const_where_expression<native_simd_mask<int>, + native_simd_mask<int>>>::value, ""); } { const bool b = true; static_assert(std::is_same<decltype(where(b, 3)), - const_where_expression<bool, const int>>::value, + const_where_expression<bool, int>>::value, ""); } } Index: libcxx/test/std/experimental/simd/simd.traits/simd_abi_deduce.pass.cpp =================================================================== --- libcxx/test/std/experimental/simd/simd.traits/simd_abi_deduce.pass.cpp +++ libcxx/test/std/experimental/simd/simd.traits/simd_abi_deduce.pass.cpp @@ -20,11 +20,12 @@ using namespace std::experimental::parallelism_v2; -static_assert(std::is_same<typename abi_for_size<int, 4>::type, +static_assert(std::is_same<typename simd_abi::deduce<int, 4>::type, simd_abi::fixed_size<4>>::value, ""); static_assert( - std::is_same<abi_for_size_t<int, 4>, simd_abi::fixed_size<4>>::value, ""); + std::is_same<simd_abi::deduce_t<int, 4>, simd_abi::fixed_size<4>>::value, + ""); int main() {} Index: libcxx/test/std/experimental/simd/simd.horizontal/split.pass.cpp =================================================================== --- libcxx/test/std/experimental/simd/simd.horizontal/split.pass.cpp +++ libcxx/test/std/experimental/simd/simd.horizontal/split.pass.cpp @@ -26,11 +26,11 @@ // const simd_mask<typename V::value_type, Abi>&); // // template <size_t n, class T, class A> -// array<simd<T, rebind_abi_t<T, simd_size_v<T, A> / n, A>>, n> split_by( +// array<simd<T, simd_abi::deduce_t<T, simd_size_v<T, A> / n, A>>, n> split_by( // const simd<T, A>& x); // // template <size_t n, class T, class A> -// array<simd_mask<T, rebind_abi_t<T, simd_size_v<T, A> / n, A>>, n> split_by( +// array<simd_mask<T, simd_abi::deduce_t<T, simd_size_v<T, A> / n, A>>, n> split_by( // const simd_mask<T, A>& x); #include <experimental/simd> @@ -138,11 +138,11 @@ void compile_split_simd_propagate_abi() { using compatible_simd_half = - simd<int, - rebind_abi_t<int, simd<int>::size() / 2, simd_abi::compatible<int>>>; + simd<int, simd_abi::deduce_t<int, simd<int>::size() / 2, + simd_abi::compatible<int>>>; using native_simd_half = - simd<int, rebind_abi_t<int, native_simd<int>::size() / 2, - simd_abi::native<int>>>; + simd<int, simd_abi::deduce_t<int, native_simd<int>::size() / 2, + simd_abi::native<int>>>; static_assert( std::is_same< @@ -169,11 +169,11 @@ void compile_split_simd_mask_propagate_abi() { using compatible_simd_mask_half = - simd_mask<int, rebind_abi_t<int, simd_mask<int>::size() / 2, - simd_abi::compatible<int>>>; + simd_mask<int, simd_abi::deduce_t<int, simd_mask<int>::size() / 2, + simd_abi::compatible<int>>>; using native_simd_mask_half = - simd_mask<int, rebind_abi_t<int, native_simd_mask<int>::size() / 2, - simd_abi::native<int>>>; + simd_mask<int, simd_abi::deduce_t<int, native_simd_mask<int>::size() / 2, + simd_abi::native<int>>>; static_assert(std::is_same<decltype(split<simd_mask<int>::size() / 2, simd_mask<int>::size() / 2>( Index: libcxx/test/std/experimental/simd/simd.horizontal/hmin.pass.cpp =================================================================== --- libcxx/test/std/experimental/simd/simd.horizontal/hmin.pass.cpp +++ libcxx/test/std/experimental/simd/simd.horizontal/hmin.pass.cpp @@ -87,10 +87,12 @@ int main() { test_hmin_simd_power_of_2<fixed_size_simd<int, 4>>(); test_hmin_simd_power_of_2< - simd<int, rebind_abi_t<int, 4, simd_abi::native<int>>>>(); + simd<int, simd_abi::deduce_t<int, 4, simd_abi::native<int>>>>(); test_hmin_simd<fixed_size_simd<int, 5>>(); - test_hmin_simd<simd<int, rebind_abi_t<int, 5, simd_abi::native<int>>>>(); + test_hmin_simd< + simd<int, simd_abi::deduce_t<int, 5, simd_abi::native<int>>>>(); test_hmin_simd<fixed_size_simd<int, 5>>(); - test_hmin_simd<simd<int, rebind_abi_t<int, 5, simd_abi::native<int>>>>(); + test_hmin_simd< + simd<int, simd_abi::deduce_t<int, 5, simd_abi::native<int>>>>(); test_hmin_mask(); } Index: libcxx/test/std/experimental/simd/simd.horizontal/hmax.pass.cpp =================================================================== --- libcxx/test/std/experimental/simd/simd.horizontal/hmax.pass.cpp +++ libcxx/test/std/experimental/simd/simd.horizontal/hmax.pass.cpp @@ -94,8 +94,9 @@ int main() { test_hmax_simd_power_of_2<fixed_size_simd<int, 4>>(); test_hmax_simd_power_of_2< - simd<int, rebind_abi_t<int, 4, simd_abi::native<int>>>>(); + simd<int, simd_abi::deduce_t<int, 4, simd_abi::native<int>>>>(); test_hmax_simd<fixed_size_simd<int, 5>>(); - test_hmax_simd<simd<int, rebind_abi_t<int, 5, simd_abi::native<int>>>>(); + test_hmax_simd< + simd<int, simd_abi::deduce_t<int, 5, simd_abi::native<int>>>>(); test_hmax_mask(); } Index: libcxx/test/std/experimental/simd/simd.horizontal/concat.pass.cpp =================================================================== --- libcxx/test/std/experimental/simd/simd.horizontal/concat.pass.cpp +++ libcxx/test/std/experimental/simd/simd.horizontal/concat.pass.cpp @@ -16,15 +16,15 @@ // concat(const simd<T, Abis>&...); // // template <class T, class Abi, size_t N> -// simd<T, rebind_abi_t<T, N * simd_size_v<T, Abi>, Abi>> +// simd<T, simd_abi::deduce_t<T, N * simd_size_v<T, Abi>, Abi>> // concat(const std::array<simd<T, Abi>, N>& __v); // // template <class T, class... Abis> // simd_mask<T, abi_for_size_t<T, (simd_size_v<T, Abis> + ...)>> // concat(const simd_mask<T, Abis>&...); // // template <class T, class Abi, size_t N> -// simd_mask<T, rebind_abi_t<T, N * simd_size_v<T, Abi>, Abi>> +// simd_mask<T, simd_abi::deduce_t<T, N * simd_size_v<T, Abi>, Abi>> // concat(const std::array<simd_mask<T, Abi>, N>&); #include <experimental/simd> @@ -102,17 +102,18 @@ } void compile_split_propagate_abi() { - static_assert(std::is_same<typename decltype( - concat(simd<int>(), simd<int>()))::abi_type, - rebind_abi_t<int, simd<int>::size() * 2, - simd_abi::compatible<int>>>::value, - ""); + static_assert( + std::is_same<typename decltype( + concat(simd<int>(), simd<int>()))::abi_type, + simd_abi::deduce_t<int, simd<int>::size() * 2, + simd_abi::compatible<int>>>::value, + ""); static_assert( std::is_same<typename decltype(concat(native_simd<int>(), native_simd<int>()))::abi_type, - rebind_abi_t<int, native_simd<int>::size() * 2, - simd_abi::native<int>>>::value, + simd_abi::deduce_t<int, native_simd<int>::size() * 2, + simd_abi::native<int>>>::value, ""); } Index: libcxx/test/std/experimental/simd/simd.elementwise/operators.pass.cpp =================================================================== --- libcxx/test/std/experimental/simd/simd.elementwise/operators.pass.cpp +++ libcxx/test/std/experimental/simd/simd.elementwise/operators.pass.cpp @@ -266,6 +266,6 @@ test_mutating_opreators<native_simd<int>>(); test_mutating_opreators<fixed_size_simd<int, 4>>(); test_relational_operators< - simd<int, rebind_abi_t<int, 9, simd_abi::native<int>>>>(); + simd<int, simd_abi::deduce_t<int, 9, simd_abi::native<int>>>>(); test_relational_operators<fixed_size_simd<int, 9>>(); } Index: libcxx/include/experimental/simd =================================================================== --- libcxx/include/experimental/simd +++ libcxx/include/experimental/simd @@ -1417,6 +1417,21 @@ #endif / sizeof(_Tp)>; +// NOTE: _Abis... is the extension proposed by P0820, allowing the APIs to +// propagate _StorageKind during transforming input type(s) to the output type. +template <class _Tp, size_t _Np, class... _Abis> +struct deduce { + using type = simd_abi::fixed_size<_Np>; +}; + +template <class _Tp, size_t _Np, _StorageKind __kind, int... __old_size> +struct deduce<_Tp, _Np, __simd_abi<__kind, __old_size>...> { + using type = __simd_abi<__kind, _Np>; +}; + +template <class _Tp, size_t _Np, class... _Abis> +using deduce_t = typename deduce<_Tp, _Np, _Abis...>::type; + _LIBCPP_END_NAMESPACE_EXPERIMENTAL_SIMD_ABI _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_SIMD @@ -1484,24 +1499,6 @@ is_simd_flag_type<_Tp>::value; #endif -// NOTE: _Abis... is the extension proposed by P0820, allowing the APIs to -// propagate _StorageKind during transforming input type(s) to the output type. -template <class _Tp, size_t _Np, class... _Abis> -struct abi_for_size { - using type = simd_abi::fixed_size<_Np>; -}; - -template <class _Tp, size_t _Np, _StorageKind __kind, int... __old_size> -struct abi_for_size<_Tp, _Np, __simd_abi<__kind, __old_size>...> { - using type = __simd_abi<__kind, _Np>; -}; - -template <class _Tp, size_t _Np, class... _Abis> -using abi_for_size_t = typename abi_for_size<_Tp, _Np, _Abis...>::type; - -template <class _Tp, size_t _Np, class... _Abis> -using rebind_abi_t = abi_for_size_t<_Tp, _Np, _Abis...>; - template <class _Tp, class _Abi = simd_abi::compatible<_Tp>> struct simd_size; @@ -1662,10 +1659,10 @@ #endif template <size_t... __indices, class _Tp, class _Abi1, class _Abi2> -simd<_Tp, rebind_abi_t<_Tp, sizeof...(__indices), _Abi1, _Abi2>> +simd<_Tp, simd_abi::deduce_t<_Tp, sizeof...(__indices), _Abi1, _Abi2>> __simd_shuffle(const simd<_Tp, _Abi1>& __v, const simd<_Tp, _Abi2>& __u, std::index_sequence<__indices...> = {}) { - simd<_Tp, rebind_abi_t<_Tp, sizeof...(__indices), _Abi1, _Abi2>> __ret; + simd<_Tp, simd_abi::deduce_t<_Tp, sizeof...(__indices), _Abi1, _Abi2>> __ret; size_t __i = 0; for (size_t __index : {__indices...}) { __ret[__i++] = @@ -1675,9 +1672,9 @@ } template <size_t __first_size, class _Tp, class _Abi, size_t... __indices> -tuple< - simd<_Tp, rebind_abi_t<_Tp, __first_size, _Abi>>, - simd<_Tp, rebind_abi_t<_Tp, simd<_Tp, _Abi>::size() - __first_size, _Abi>>> +tuple<simd<_Tp, simd_abi::deduce_t<_Tp, __first_size, _Abi>>, + simd<_Tp, simd_abi::deduce_t<_Tp, simd<_Tp, _Abi>::size() - __first_size, + _Abi>>> __split_to_two(const simd<_Tp, _Abi>& __v, std::index_sequence<__indices...>) { static_assert(__first_size + sizeof...(__indices) == simd<_Tp, _Abi>::size(), ""); @@ -1694,8 +1691,8 @@ } template <size_t __first, size_t... __rest, class _Tp, class _Abi> -tuple<simd<_Tp, rebind_abi_t<_Tp, __first, _Abi>>, - simd<_Tp, rebind_abi_t<_Tp, __rest, _Abi>>...> +tuple<simd<_Tp, simd_abi::deduce_t<_Tp, __first, _Abi>>, + simd<_Tp, simd_abi::deduce_t<_Tp, __rest, _Abi>>...> __split_impl(const simd<_Tp, _Abi>& __v, std::integral_constant<size_t, __first>, std::integral_constant<size_t, __rest>...) { @@ -1710,7 +1707,7 @@ template <size_t... __sizes, class _Tp, class _Abi> typename std::enable_if< __variadic_sum<size_t>(__sizes...) == simd<_Tp, _Abi>::size(), - tuple<simd<_Tp, rebind_abi_t<_Tp, __sizes, _Abi>>...>>::type + tuple<simd<_Tp, simd_abi::deduce_t<_Tp, __sizes, _Abi>>...>>::type split(const simd<_Tp, _Abi>& __v) { return __split_impl(__v, std::integral_constant<size_t, __sizes>()...); } @@ -1729,12 +1726,12 @@ template <size_t __array_size, class _Tp, class _Abi> typename std::enable_if< simd_size<_Tp, _Abi>::value % __array_size == 0, - array<simd<_Tp, rebind_abi_t< + array<simd<_Tp, simd_abi::deduce_t< _Tp, simd_size<_Tp, _Abi>::value / __array_size, _Abi>>, __array_size>>::type split_by(const simd<_Tp, _Abi>& __v) { - array<simd<_Tp, rebind_abi_t<_Tp, simd_size<_Tp, _Abi>::value / __array_size, - _Abi>>, + array<simd<_Tp, simd_abi::deduce_t< + _Tp, simd_size<_Tp, _Abi>::value / __array_size, _Abi>>, __array_size> __ret; __split_by_impl(__v, &__ret, std::make_index_sequence<__array_size>()); @@ -1760,10 +1757,11 @@ } template <class _Tp, class _Abi, class... _Abis> -simd<_Tp, rebind_abi_t<_Tp, - __variadic_sum<size_t>(simd_size<_Tp, _Abi>::value, - simd_size<_Tp, _Abis>::value...), - _Abi, _Abis...>> +simd<_Tp, + simd_abi::deduce_t<_Tp, + __variadic_sum<size_t>(simd_size<_Tp, _Abi>::value, + simd_size<_Tp, _Abis>::value...), + _Abi, _Abis...>> __concat_variadic(const simd<_Tp, _Abi>& __first, const simd<_Tp, _Abis>&... __rest) { return __simd_shuffle( @@ -1773,22 +1771,22 @@ } template <class _Tp, class... _Abis> -simd<_Tp, - rebind_abi_t<_Tp, __variadic_sum<size_t>(simd_size<_Tp, _Abis>::value...), - _Abis...>> +simd<_Tp, simd_abi::deduce_t< + _Tp, __variadic_sum<size_t>(simd_size<_Tp, _Abis>::value...), + _Abis...>> concat(const simd<_Tp, _Abis>&... __vs) { return __concat_variadic(__vs...); } template <class _Tp, class _Abi, size_t _Np, size_t... __indices> -simd<_Tp, rebind_abi_t<_Tp, _Np * simd<_Tp, _Abi>::size(), _Abi>> +simd<_Tp, simd_abi::deduce_t<_Tp, _Np * simd<_Tp, _Abi>::size(), _Abi>> __concat_array(const std::array<simd<_Tp, _Abi>, _Np>& __arr, std::index_sequence<__indices...>) { return concat(__arr[__indices]...); } template <class _Tp, class _Abi, size_t _Np> -simd<_Tp, rebind_abi_t<_Tp, _Np * simd<_Tp, _Abi>::size(), _Abi>> +simd<_Tp, simd_abi::deduce_t<_Tp, _Np * simd<_Tp, _Abi>::size(), _Abi>> concat(const std::array<simd<_Tp, _Abi>, _Np>& __arr) { return __concat_array(__arr, std::make_index_sequence<_Np>()); } @@ -1835,26 +1833,26 @@ template <size_t... __sizes, class _Tp, class _Abi> static typename std::enable_if< __variadic_sum<size_t>(__sizes...) == simd<_Tp, _Abi>::size(), - tuple<simd_mask<_Tp, rebind_abi_t<_Tp, __sizes, _Abi>>...>>::type + tuple<simd_mask<_Tp, simd_abi::deduce_t<_Tp, __sizes, _Abi>>...>>::type __split(const simd_mask<_Tp, _Abi>& __m) { return __split_impl< - tuple<simd_mask<_Tp, rebind_abi_t<_Tp, __sizes, _Abi>>...>>( + tuple<simd_mask<_Tp, simd_abi::deduce_t<_Tp, __sizes, _Abi>>...>>( split<__sizes...>(__m.__s_), std::make_index_sequence<sizeof...(__sizes)>()); } template <size_t __array_size, class _Tp, class _Abi> static typename std::enable_if< simd_size<_Tp, _Abi>::value % __array_size == 0, - array<simd_mask<_Tp, rebind_abi_t< + array<simd_mask<_Tp, simd_abi::deduce_t< _Tp, simd_size<_Tp, _Abi>::value / __array_size, _Abi>>, __array_size>>::type __split_by(const simd_mask<_Tp, _Abi>& __m) { auto __arr = split_by<__array_size>(__m.__s_); - array<simd_mask< - _Tp, rebind_abi_t<_Tp, simd_size<_Tp, _Abi>::value / __array_size, - _Abi>>, + array<simd_mask<_Tp, + simd_abi::deduce_t< + _Tp, simd_size<_Tp, _Abi>::value / __array_size, _Abi>>, __array_size> __ret; for (size_t __i = 0; __i < __ret.size(); __i++) { @@ -1877,16 +1875,16 @@ template <class _Tp, class... _Abis> static simd_mask< - _Tp, - rebind_abi_t<_Tp, __variadic_sum<size_t>(simd_size<_Tp, _Abis>::value...), - _Abis...>> + _Tp, simd_abi::deduce_t< + _Tp, __variadic_sum<size_t>(simd_size<_Tp, _Abis>::value...), + _Abis...>> __concat(const simd_mask<_Tp, _Abis>&... __ms) { return concat(__ms.__s_...); } template <class _Tp, class _Abi, size_t _Np> - static simd_mask<_Tp, - rebind_abi_t<_Tp, _Np * simd_size<_Tp, _Abi>::value, _Abi>> + static simd_mask< + _Tp, simd_abi::deduce_t<_Tp, _Np * simd_size<_Tp, _Abi>::value, _Abi>> __concat(const std::array<simd_mask<_Tp, _Abi>, _Np>& __ms) { std::array<decltype(__ms[0].__s_), _Np> __arr; for (size_t __i = 0; __i < __ms.size(); __i++) { @@ -1942,17 +1940,17 @@ template <size_t... __sizes, class _Tp, class _Abi> typename std::enable_if< __variadic_sum<size_t>(__sizes...) == simd<_Tp, _Abi>::size(), - tuple<simd_mask<_Tp, rebind_abi_t<_Tp, __sizes, _Abi>>...>>::type + tuple<simd_mask<_Tp, simd_abi::deduce_t<_Tp, __sizes, _Abi>>...>>::type split(const simd_mask<_Tp, _Abi>& __m) { return __simd_mask_friend::__split<__sizes...>(__m); } template <size_t __array_size, class _Tp, class _Abi> static typename std::enable_if< simd_size<_Tp, _Abi>::value % __array_size == 0, - array<simd_mask< - _Tp, rebind_abi_t<_Tp, simd_size<_Tp, _Abi>::value / __array_size, - _Abi>>, + array<simd_mask<_Tp, + simd_abi::deduce_t< + _Tp, simd_size<_Tp, _Abi>::value / __array_size, _Abi>>, __array_size>>::type split_by(const simd_mask<_Tp, _Abi>& __m) { return __simd_mask_friend::__split_by<__array_size>(__m); @@ -1971,15 +1969,15 @@ } template <class _Tp, class... _Abis> -simd_mask<_Tp, rebind_abi_t< +simd_mask<_Tp, simd_abi::deduce_t< _Tp, __variadic_sum<size_t>(simd_size<_Tp, _Abis>::value...), _Abis...>> concat(const simd_mask<_Tp, _Abis>&... __ms) { return __simd_mask_friend::__concat(__ms...); } template <class _Tp, class _Abi, size_t _Np> -simd_mask<_Tp, rebind_abi_t<_Tp, _Np * simd_size<_Tp, _Abi>::value, _Abi>> +simd_mask<_Tp, simd_abi::deduce_t<_Tp, _Np * simd_size<_Tp, _Abi>::value, _Abi>> concat(const std::array<simd_mask<_Tp, _Abi>, _Np>& __ms) { return __simd_mask_friend::__concat(__ms); } @@ -2085,15 +2083,17 @@ } template <class _Tp, class _Abi, size_t... __indices> -std::array<simd<_Tp, rebind_abi_t<_Tp, simd<_Tp, _Abi>::size() / 2, _Abi>>, 2> +std::array< + simd<_Tp, simd_abi::deduce_t<_Tp, simd<_Tp, _Abi>::size() / 2, _Abi>>, 2> __deinterleave_impl(const simd<_Tp, _Abi>& __v, std::index_sequence<__indices...>) { return {{__simd_shuffle<(2 * __indices)...>(__v, __v), __simd_shuffle<(2 * __indices + 1)...>(__v, __v)}}; } template <class _Tp, class _Abi> -std::array<simd<_Tp, rebind_abi_t<_Tp, simd<_Tp, _Abi>::size() / 2, _Abi>>, 2> +std::array< + simd<_Tp, simd_abi::deduce_t<_Tp, simd<_Tp, _Abi>::size() / 2, _Abi>>, 2> __deinterleave(const simd<_Tp, _Abi>& __v) { static_assert(simd<_Tp, _Abi>::size() % 2 == 0, ""); return __deinterleave_impl( @@ -2873,40 +2873,37 @@ // [simd.whereexpr] template <class _MaskType, class _ValueType> class const_where_expression { - static_assert( - std::is_arithmetic<typename remove_const<_ValueType>::type>::value || - is_simd<typename remove_const<_ValueType>::type>::value || - is_simd_mask<typename remove_const<_ValueType>::type>::value, - ""); + static_assert(std::is_arithmetic<_ValueType>::value || + is_simd<_ValueType>::value || + is_simd_mask<_ValueType>::value, + ""); - using _Tp = typename __simd_value_type_traits< - typename remove_const<_ValueType>::type>::type; + using _Tp = typename __simd_value_type_traits<_ValueType>::type; - typename std::conditional<std::is_same<bool, _MaskType>::value, bool, - const _MaskType>::type __m_; - _ValueType& __v_; + const _MaskType __m_; + const _ValueType& __v_; - const_where_expression(const _MaskType& __m, _ValueType& __v) + const_where_expression(const _MaskType& __m, const _ValueType& __v) : __m_(__m), __v_(__v) {} const_where_expression(const const_where_expression&) = default; template <class, class> friend class where_expression; template <class _Up, class _Ap> - friend const_where_expression<simd_mask<_Up, _Ap>, const simd<_Up, _Ap>> + friend const_where_expression<simd_mask<_Up, _Ap>, simd<_Up, _Ap>> where(const typename simd<_Up, _Ap>::mask_type& __m, const simd<_Up, _Ap>& __v) noexcept; template <class _Up, class _Ap> - friend const_where_expression<simd_mask<_Up, _Ap>, const simd_mask<_Up, _Ap>> + friend const_where_expression<simd_mask<_Up, _Ap>, simd_mask<_Up, _Ap>> where(const typename __nodeduce<simd_mask<_Up, _Ap>>::type& __m, const simd_mask<_Up, _Ap>& __v) noexcept; template <class _Up, class _Mp> friend typename std::enable_if<std::is_same<_Mp, bool>::value, - const_where_expression<bool, const _Up>>::type + const_where_expression<bool, _Up>>::type where(_Mp __m, const _Up& __v) noexcept; template <class _Mp, class _Vp, class _BinaryOp> @@ -2925,27 +2922,24 @@ public: const_where_expression& operator=(const const_where_expression&) = delete; - typename std::remove_const<_ValueType>::type operator-() const&& { - static_assert(!is_simd_mask<typename remove_const<_ValueType>::type>::value, - "Library extension: operator-() doesn't really make sense " - "when operating on simd_mask<>."); + _ValueType operator-() const&& { return __simd_mask_friend::__simd_select(__v_, _ValueType(0), __m_) - __simd_mask_friend::__simd_select(_ValueType(0), __v_, __m_); } template <class _Up, class _Flags> - typename std::enable_if<std::is_same<_Tp, _Up>::value || - !std::is_same<_Tp, bool>::value>::type + typename std::enable_if<(std::is_same<_Tp, _Up>::value || + !std::is_same<_Tp, bool>::value) && + is_simd_flag_type<_Flags>::value>::type copy_to(_Up* __buffer, _Flags) const&& { __mask_copy_to<__memory_alignment_impl<_ValueType, _Up, _Flags>::value>( __v_, __m_, __buffer); } }; template <class _MaskType, class _ValueType> class where_expression : public const_where_expression<_MaskType, _ValueType> { - using _Tp = typename __simd_value_type_traits< - typename remove_const<_ValueType>::type>::type; + using _Tp = typename __simd_value_type_traits<_ValueType>::type; where_expression(const _MaskType& __m, _ValueType& __v) : const_where_expression<_MaskType, _ValueType>(__m, __v) {} @@ -2967,74 +2961,76 @@ where_expression<bool, _Up>>::type where(_Mp __m, _Up& __v) noexcept; + _ValueType& __ref() { return const_cast<_ValueType&>(this->__v_); } + public: where_expression& operator=(const where_expression&) = delete; template <class _Up> auto operator=(_Up&& __u) - -> decltype(this->__v_ = std::forward<_Up>(__u), void()) { - this->__v_ = __simd_mask_friend::__simd_select( - this->__v_, _ValueType(std::forward<_Up>(__u)), this->__m_); + -> decltype(this->__ref() = std::forward<_Up>(__u), void()) { + this->__ref() = __simd_mask_friend::__simd_select( + this->__ref(), _ValueType(std::forward<_Up>(__u)), this->__m_); } template <class _Up> auto operator+=(_Up&& __u) - -> decltype(this->__v_ + std::forward<_Up>(__u), void()) { - *this = this->__v_ + std::forward<_Up>(__u); + -> decltype(this->__ref() + std::forward<_Up>(__u), void()) { + *this = this->__ref() + std::forward<_Up>(__u); } template <class _Up> auto operator-=(_Up&& __u) - -> decltype(this->__v_ - std::forward<_Up>(__u), void()) { - *this = this->__v_ - std::forward<_Up>(__u); + -> decltype(this->__ref() - std::forward<_Up>(__u), void()) { + *this = this->__ref() - std::forward<_Up>(__u); } template <class _Up> auto operator*=(_Up&& __u) - -> decltype(this->__v_ * std::forward<_Up>(__u), void()) { - *this = this->__v_ * std::forward<_Up>(__u); + -> decltype(this->__ref() * std::forward<_Up>(__u), void()) { + *this = this->__ref() * std::forward<_Up>(__u); } template <class _Up> auto operator/=(_Up&& __u) - -> decltype(this->__v_ / std::forward<_Up>(__u), void()) { - *this = this->__v_ / std::forward<_Up>(__u); + -> decltype(this->__ref() / std::forward<_Up>(__u), void()) { + *this = this->__ref() / std::forward<_Up>(__u); } template <class _Up> auto operator%=(_Up&& __u) - -> decltype(this->__v_ % std::forward<_Up>(__u), void()) { - *this = this->__v_ % std::forward<_Up>(__u); + -> decltype(this->__ref() % std::forward<_Up>(__u), void()) { + *this = this->__ref() % std::forward<_Up>(__u); } template <class _Up> auto operator&=(_Up&& __u) - -> decltype(this->__v_ & std::forward<_Up>(__u), void()) { - *this = this->__v_ & std::forward<_Up>(__u); + -> decltype(this->__ref() & std::forward<_Up>(__u), void()) { + *this = this->__ref() & std::forward<_Up>(__u); } template <class _Up> auto operator|=(_Up&& __u) - -> decltype(this->__v_ | std::forward<_Up>(__u), void()) { - *this = this->__v_ | std::forward<_Up>(__u); + -> decltype(this->__ref() | std::forward<_Up>(__u), void()) { + *this = this->__ref() | std::forward<_Up>(__u); } template <class _Up> auto operator^=(_Up&& __u) - -> decltype(this->__v_ ^ std::forward<_Up>(__u), void()) { - *this = this->__v_ ^ std::forward<_Up>(__u); + -> decltype(this->__ref() ^ std::forward<_Up>(__u), void()) { + *this = this->__ref() ^ std::forward<_Up>(__u); } template <class _Up> auto operator<<=(_Up&& __u) - -> decltype(this->__v_ << std::forward<_Up>(__u), void()) { - *this = this->__v_ << std::forward<_Up>(__u); + -> decltype(this->__ref() << std::forward<_Up>(__u), void()) { + *this = this->__ref() << std::forward<_Up>(__u); } template <class _Up> auto operator>>=(_Up&& __u) - -> decltype(this->__v_ >> std::forward<_Up>(__u), void()) { - *this = this->__v_ >> std::forward<_Up>(__u); + -> decltype(this->__ref() >> std::forward<_Up>(__u), void()) { + *this = this->__ref() >> std::forward<_Up>(__u); } void operator++() { *this += _ValueType(1); } @@ -3050,7 +3046,7 @@ !std::is_same<_Tp, bool>::value>::type copy_from(const _Up* __buffer, _Flags) { __mask_copy_from<__memory_alignment_impl<_ValueType, _Up, _Flags>::value>( - this->__v_, this->__m_, __buffer); + this->__ref(), this->__m_, __buffer); } }; @@ -3062,11 +3058,11 @@ } template <class _Tp, class _Abi> -const_where_expression<simd_mask<_Tp, _Abi>, const simd<_Tp, _Abi>> +const_where_expression<simd_mask<_Tp, _Abi>, simd<_Tp, _Abi>> where(const typename simd<_Tp, _Abi>::mask_type& __m, const simd<_Tp, _Abi>& __v) noexcept { - return const_where_expression<simd_mask<_Tp, _Abi>, const simd<_Tp, _Abi>>( - __m, __v); + return const_where_expression<simd_mask<_Tp, _Abi>, simd<_Tp, _Abi>>(__m, + __v); } template <class _Tp, class _Abi> @@ -3077,11 +3073,11 @@ } template <class _Tp, class _Abi> -const_where_expression<simd_mask<_Tp, _Abi>, const simd_mask<_Tp, _Abi>> +const_where_expression<simd_mask<_Tp, _Abi>, simd_mask<_Tp, _Abi>> where(const typename __nodeduce<simd_mask<_Tp, _Abi>>::type& __m, const simd_mask<_Tp, _Abi>& __v) noexcept { - return const_where_expression<simd_mask<_Tp, _Abi>, - const simd_mask<_Tp, _Abi>>(__m, __v); + return const_where_expression<simd_mask<_Tp, _Abi>, simd_mask<_Tp, _Abi>>( + __m, __v); } template <class _Tp, class _MaskType> @@ -3093,9 +3089,9 @@ template <class _Tp, class _MaskType> typename std::enable_if<std::is_same<_MaskType, bool>::value, - const_where_expression<bool, const _Tp>>::type + const_where_expression<bool, _Tp>>::type where(_MaskType __m, const _Tp& __v) noexcept { - return const_where_expression<bool, const _Tp>(__m, __v); + return const_where_expression<bool, _Tp>(__m, __v); } template <class _MaskType, class _SimdType, class _BinaryOp>
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits