1 //===----------------------------------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 // UNSUPPORTED: c++98, c++03, c++11, c++14
11 
12 // See GCC PR63723.
13 // UNSUPPORTED: gcc-4.9
14 
15 // <experimental/simd>
16 //
17 // [simd.class]
18 // template <class G> explicit simd(G&& gen);
19 
20 #include <experimental/simd>
21 #include <cstdint>
22 
23 namespace ex = std::experimental::parallelism_v2;
24 
25 template <class T, class... Args>
26 auto not_supported_simd128_ctor(Args&&... args) -> decltype(
27     ex::fixed_size_simd<T, 16 / sizeof(T)>(std::forward<Args>(args)...),
28     void()) = delete;
29 
30 template <class T>
not_supported_simd128_ctor(...)31 void not_supported_simd128_ctor(...) {}
32 
33 template <class T, class... Args>
supported_simd128_ctor(Args &&...args)34 auto supported_simd128_ctor(Args&&... args) -> decltype(
35     ex::fixed_size_simd<T, 16 / sizeof(T)>(std::forward<Args>(args)...),
36     void()) {}
37 
38 template <class T>
39 void supported_simd128_ctor(...) = delete;
40 
41 struct identity {
42   template <size_t value>
operator ()identity43   int operator()(std::integral_constant<size_t, value>) const {
44     return value;
45   }
46 };
47 
compile_generator()48 void compile_generator() {
49   supported_simd128_ctor<int>(identity());
50   not_supported_simd128_ctor<int>([](int i) { return float(i); });
51   not_supported_simd128_ctor<int>([](intptr_t i) { return (int*)(i); });
52   not_supported_simd128_ctor<int>([](int* i) { return i; });
53 }
54 
55 struct limited_identity {
56   template <size_t value>
57   typename std::conditional<value <= 2, int32_t, int64_t>::type
operator ()limited_identity58   operator()(std::integral_constant<size_t, value>) const {
59     return value;
60   }
61 };
62 
compile_limited_identity()63 void compile_limited_identity() {
64   supported_simd128_ctor<int64_t>(limited_identity());
65   not_supported_simd128_ctor<int32_t>(limited_identity());
66 }
67 
68 template <typename SimdType>
test_generator()69 void test_generator() {
70   {
71     SimdType a([](int i) { return i; });
72     assert(a[0] == 0);
73     assert(a[1] == 1);
74     assert(a[2] == 2);
75     assert(a[3] == 3);
76   }
77   {
78     SimdType a([](int i) { return 2 * i - 1; });
79     assert(a[0] == -1);
80     assert(a[1] == 1);
81     assert(a[2] == 3);
82     assert(a[3] == 5);
83   }
84 }
85 
main()86 int main() {
87   // TODO: adjust the tests when this assertion fails.
88   assert(ex::native_simd<int32_t>::size() >= 4);
89   test_generator<ex::native_simd<int32_t>>();
90   test_generator<ex::fixed_size_simd<int32_t, 4>>();
91 }
92