129 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++1410// XFAIL: target=powerpc{{.*}}le-unknown-linux-gnu11 12// <experimental/simd>13//14// [simd.class]15// template<class U> simd(U&& value) noexcept;16 17#include <algorithm>18#include <experimental/simd>19 20#include "../test_utils.h"21 22namespace ex = std::experimental::parallelism_v2;23 24template <class T, class SimdAbi, std::size_t array_size>25struct BroadCastHelper {26 const std::array<T, array_size>& expected_value;27 28 BroadCastHelper(const std::array<T, array_size>& value) : expected_value(value) {}29 30 template <class U>31 void operator()() const {32 if constexpr (is_non_narrowing_convertible_v<U, T>) {33 ex::simd<T, SimdAbi> simd_broadcast_from_vectorizable_type(static_cast<U>(3));34 assert_simd_values_equal<array_size>(simd_broadcast_from_vectorizable_type, expected_value);35 }36 }37};38 39template <class T, std::size_t>40struct CheckSimdBroadcastCtorFromVectorizedType {41 template <class SimdAbi>42 void operator()() {43 constexpr std::size_t array_size = ex::simd_size_v<T, SimdAbi>;44 std::array<T, array_size> expected_value;45 std::fill(expected_value.begin(), expected_value.end(), 3);46 47 types::for_each(simd_test_types(), BroadCastHelper<T, SimdAbi, array_size>(expected_value));48 }49};50 51template <class T>52class implicit_type {53 T val;54 55public:56 implicit_type(T v) : val(v) {}57 operator T() const { return val; }58};59 60template <class T, std::size_t>61struct CheckSimdBroadcastCtor {62 template <class SimdAbi>63 void operator()() {64 constexpr std::size_t array_size = ex::simd_size_v<T, SimdAbi>;65 std::array<T, array_size> expected_value;66 std::fill(expected_value.begin(), expected_value.end(), 3);67 68 implicit_type<T> implicit_convert_to_3(3);69 ex::simd<T, SimdAbi> simd_broadcast_from_implicit_type(std::move(implicit_convert_to_3));70 assert_simd_values_equal<array_size>(simd_broadcast_from_implicit_type, expected_value);71 72 ex::simd<T, SimdAbi> simd_broadcast_from_int(3);73 assert_simd_values_equal<array_size>(simd_broadcast_from_int, expected_value);74 75 if constexpr (std::is_unsigned_v<T>) {76 ex::simd<T, SimdAbi> simd_broadcast_from_uint(3u);77 assert_simd_values_equal<array_size>(simd_broadcast_from_uint, expected_value);78 }79 }80};81 82template <class T>83class no_implicit_type {84 T val;85 86public:87 no_implicit_type(T v) : val(v) {}88};89 90template <class U, class T, class SimdAbi = ex::simd_abi::compatible<T>, class = void>91struct has_broadcast_ctor : std::false_type {};92 93template <class U, class T, class SimdAbi>94struct has_broadcast_ctor<U, T, SimdAbi, std::void_t<decltype(ex::simd<T, SimdAbi>(std::declval<U>()))>>95 : std::true_type {};96 97template <class T, class SimdAbi>98struct CheckBroadcastCtorTraitsHelper {99 template <class U>100 void operator()() const {101 if constexpr (std::is_same_v<U, int>)102 static_assert(has_broadcast_ctor<U, T, SimdAbi>::value);103 else if constexpr (std::is_same_v<U, unsigned int> && std::is_unsigned_v<T>)104 static_assert(has_broadcast_ctor<U, T, SimdAbi>::value);105 else if constexpr (is_non_narrowing_convertible_v<U, T>)106 static_assert(has_broadcast_ctor<U, T, SimdAbi>::value);107 else108 static_assert(!has_broadcast_ctor<U, T, SimdAbi>::value);109 }110};111 112template <class T, std::size_t>113struct CheckBroadcastCtorTraits {114 template <class SimdAbi>115 void operator()() {116 types::for_each(simd_test_types(), CheckBroadcastCtorTraitsHelper<T, SimdAbi>());117 118 static_assert(!has_broadcast_ctor<no_implicit_type<T>, T, SimdAbi>::value);119 static_assert(has_broadcast_ctor<implicit_type<T>, T, SimdAbi>::value);120 }121};122 123int main(int, char**) {124 test_all_simd_abi<CheckSimdBroadcastCtorFromVectorizedType>();125 test_all_simd_abi<CheckSimdBroadcastCtor>();126 test_all_simd_abi<CheckBroadcastCtorTraits>();127 return 0;128}129