]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/testsuite/experimental/simd/tests/casts.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / experimental / simd / tests / casts.cc
CommitLineData
7adcbafe 1// Copyright (C) 2020-2022 Free Software Foundation, Inc.
02e32295
MK
2//
3// This file is part of the GNU ISO C++ Library. This library is free
4// software; you can redistribute it and/or modify it under the
5// terms of the GNU General Public License as published by the
6// Free Software Foundation; either version 3, or (at your option)
7// any later version.
8//
9// This library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License along
15// with this library; see the file COPYING3. If not see
16// <http://www.gnu.org/licenses/>.
17
aa89c53c 18// expensive: * [1-9] * *
02e32295
MK
19#include "bits/verify.h"
20#include "bits/metahelpers.h"
21#include "bits/conversions.h"
22
23using std::experimental::simd_cast;
24using std::experimental::static_simd_cast;
25
26template <class T, size_t N>
27 struct gen_cast
28 {
29 std::array<T, N> data;
30
31 template <class V>
32 gen_cast(const V& v)
33 {
34 for (size_t i = 0; i < V::size(); ++i)
35 {
36 data[i] = static_cast<T>(v[i]);
37 }
38 }
39
40 template <class I>
41 constexpr T
42 operator()(I)
43 { return data[I::value]; }
44 };
45
46template <class V, class To>
47 struct gen_seq_t
48 {
49 using From = typename V::value_type;
50 const size_t N = cvt_input_data<From, To>.size();
51 size_t offset = 0;
52
53 constexpr void
54 operator++()
55 { offset += V::size(); }
56
57 explicit constexpr operator bool() const
58 { return offset < N; }
59
60 template <class I>
61 constexpr From
62 operator()(I) const
63 {
64 size_t i = I::value + offset;
65 return i < N ? cvt_input_data<From, To>[i] : From(i);
66 }
67 };
68
69template <class To>
70 struct foo
71 {
72 template <class T>
73 auto
74 operator()(const T& v) -> decltype(simd_cast<To>(v));
75 };
76
77template <typename V, typename To>
78 void
79 casts()
80 {
81 using From = typename V::value_type;
82 constexpr auto N = V::size();
83 if constexpr (N <= std::experimental::simd_abi::max_fixed_size<To>)
84 {
85 using W = std::experimental::fixed_size_simd<To, N>;
86
87 if constexpr (std::is_integral_v<From>)
88 {
89 using A = typename V::abi_type;
90 using TU = std::make_unsigned_t<From>;
91 using TS = std::make_signed_t<From>;
92 COMPARE(typeid(static_simd_cast<TU>(V())),
93 typeid(std::experimental::simd<TU, A>));
94 COMPARE(typeid(static_simd_cast<TS>(V())),
95 typeid(std::experimental::simd<TS, A>));
96 }
97
98 using is_simd_cast_allowed
99 = decltype(vir::test::sfinae_is_callable_t<const V&>(foo<To>()));
100
101 COMPARE(is_simd_cast_allowed::value,
102 std::__digits<From>::value <= std::__digits<To>::value
103 && std::__finite_max<From>::value
104 <= std::__finite_max<To>::value
105 && !(std::is_signed<From>::value
106 && std::is_unsigned<To>::value));
107
108 if constexpr (is_simd_cast_allowed::value)
109 {
110 for (gen_seq_t<V, To> gen_seq; gen_seq; ++gen_seq)
111 {
112 const V seq(gen_seq);
113 COMPARE(simd_cast<V>(seq), seq);
114 COMPARE(simd_cast<W>(seq), W(gen_cast<To, N>(seq)))
115 << "seq = " << seq;
116 auto test = simd_cast<To>(seq);
117 // decltype(test) is not W if
118 // a) V::abi_type is not fixed_size and
119 // b.1) V::value_type and To are integral and of equal rank or
120 // b.2) V::value_type and To are equal
121 COMPARE(test, decltype(test)(gen_cast<To, N>(seq)));
122 if (std::is_same<To, From>::value)
123 {
124 COMPARE(typeid(decltype(test)), typeid(V));
125 }
126 }
127 }
128
129 for (gen_seq_t<V, To> gen_seq; gen_seq; ++gen_seq)
130 {
131 const V seq(gen_seq);
132 COMPARE(static_simd_cast<V>(seq), seq);
133 COMPARE(static_simd_cast<W>(seq), W(gen_cast<To, N>(seq))) << '\n'
134 << seq;
135 auto test = static_simd_cast<To>(seq);
136 // decltype(test) is not W if
137 // a) V::abi_type is not fixed_size and
138 // b.1) V::value_type and To are integral and of equal rank or
139 // b.2) V::value_type and To are equal
140 COMPARE(test, decltype(test)(gen_cast<To, N>(seq)));
141 if (std::is_same<To, From>::value)
142 {
143 COMPARE(typeid(decltype(test)), typeid(V));
144 }
145 }
146 }
147 }
148
149template <typename V>
150 void
151 test()
152 {
153 casts<V, long double>();
154 casts<V, double>();
155 casts<V, float>();
156 casts<V, long long>();
157 casts<V, unsigned long long>();
158 casts<V, unsigned long>();
159 casts<V, long>();
160 casts<V, int>();
161 casts<V, unsigned int>();
162 casts<V, short>();
163 casts<V, unsigned short>();
164 casts<V, char>();
165 casts<V, signed char>();
166 casts<V, unsigned char>();
167 casts<V, char32_t>();
168 casts<V, char16_t>();
169 casts<V, wchar_t>();
170 }