]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/experimental/simd/tests/bits/conversions.h
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / experimental / simd / tests / bits / conversions.h
1 // Copyright (C) 2020-2024 Free Software Foundation, Inc.
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
18 #ifndef SIMD_TESTS_BITS_CONVERSIONS_H_
19 #define SIMD_TESTS_BITS_CONVERSIONS_H_
20 #include <array>
21
22 // is_conversion_undefined
23 /* implementation-defined
24 * ======================
25 * §4.7 p3 (integral conversions)
26 * If the destination type is signed, the value is unchanged if it can be
27 * represented in the destination type (and bit-field width); otherwise, the
28 * value is implementation-defined.
29 *
30 * undefined
31 * =========
32 * §4.9/1 (floating-point conversions)
33 * If the source value is neither exactly represented in the destination type
34 * nor between two adjacent destination values the result is undefined.
35 *
36 * §4.10/1 (floating-integral conversions)
37 * floating point type can be converted to integer type.
38 * The behavior is undefined if the truncated value cannot be
39 * represented in the destination type.
40 *
41 * §4.10/2
42 * integer can be converted to floating point type.
43 * If the value being converted is outside the range of values that can be
44 * represented, the behavior is undefined.
45 */
46 template <typename To, typename From>
47 constexpr bool
48 is_conversion_undefined_impl(From x, std::true_type)
49 {
50 return x > static_cast<long double>(std::__finite_max_v<To>)
51 || x < static_cast<long double>(std::__finite_min_v<To>);
52 }
53
54 template <typename To, typename From>
55 constexpr bool
56 is_conversion_undefined_impl(From, std::false_type)
57 { return false; }
58
59 template <typename To, typename From>
60 constexpr bool
61 is_conversion_undefined(From x)
62 {
63 static_assert(std::is_arithmetic<From>::value,
64 "this overload is only meant for builtin arithmetic types");
65 return is_conversion_undefined_impl<To, From>(
66 x, std::integral_constant<
67 bool, std::is_floating_point<From>::value
68 && (std::is_integral<To>::value
69 || (std::is_floating_point<To>::value
70 && sizeof(From) > sizeof(To)))>());
71 }
72
73 static_assert(is_conversion_undefined<uint>(float(0x100000000LL)),
74 "testing my expectations of is_conversion_undefined");
75 static_assert(!is_conversion_undefined<float>(0x100000000LL),
76 "testing my expectations of is_conversion_undefined");
77
78 template <typename To, typename T, typename A>
79 inline std::experimental::simd_mask<T, A>
80 is_conversion_undefined(const std::experimental::simd<T, A>& x)
81 {
82 std::experimental::simd_mask<T, A> k = false;
83 for (std::size_t i = 0; i < x.size(); ++i)
84 k[i] = is_conversion_undefined(x[i]);
85 return k;
86 }
87
88 template <class T>
89 constexpr T
90 genHalfBits()
91 {
92 if constexpr (std::is_floating_point_v<T>)
93 return 0;
94 else
95 return std::__finite_max_v<T> >> (std::__digits_v<T> / 2);
96 }
97
98 template <class U, class T, class UU>
99 constexpr U
100 avoid_ub(UU x)
101 { return is_conversion_undefined<T>(U(x)) ? U(0) : U(x); }
102
103 template <class U, class T, class UU>
104 constexpr U
105 avoid_ub2(UU x)
106 { return is_conversion_undefined<U>(x) ? U(0) : avoid_ub<U, T>(x); }
107
108 // conversion test input data
109 template <class U, class T>
110 static const std::array<U, 53> cvt_input_data = {{
111 avoid_ub<U, T>(0xc0000080U),
112 avoid_ub<U, T>(0xc0000081U),
113 avoid_ub<U, T>(0xc0000082U),
114 avoid_ub<U, T>(0xc0000084U),
115 avoid_ub<U, T>(0xc0000088U),
116 avoid_ub<U, T>(0xc0000090U),
117 avoid_ub<U, T>(0xc00000A0U),
118 avoid_ub<U, T>(0xc00000C0U),
119 avoid_ub<U, T>(0xc000017fU),
120 avoid_ub<U, T>(0xc0000180U),
121 avoid_ub<U, T>(0x100000001LL),
122 avoid_ub<U, T>(0x100000011LL),
123 avoid_ub<U, T>(0x100000111LL),
124 avoid_ub<U, T>(0x100001111LL),
125 avoid_ub<U, T>(0x100011111LL),
126 avoid_ub<U, T>(0x100111111LL),
127 avoid_ub<U, T>(0x101111111LL),
128 avoid_ub<U, T>(-0x100000001LL),
129 avoid_ub<U, T>(-0x100000011LL),
130 avoid_ub<U, T>(-0x100000111LL),
131 avoid_ub<U, T>(-0x100001111LL),
132 avoid_ub<U, T>(-0x100011111LL),
133 avoid_ub<U, T>(-0x100111111LL),
134 avoid_ub<U, T>(-0x101111111LL),
135 avoid_ub<U, T>(std::__norm_min_v<U>),
136 avoid_ub<U, T>(std::__norm_min_v<U> + 1),
137 avoid_ub<U, T>(std::__finite_min_v<U>),
138 avoid_ub<U, T>(std::__finite_min_v<U> + 1),
139 avoid_ub<U, T>(-1),
140 avoid_ub<U, T>(-10),
141 avoid_ub<U, T>(-100),
142 avoid_ub<U, T>(-1000),
143 avoid_ub<U, T>(-10000),
144 avoid_ub<U, T>(0),
145 avoid_ub<U, T>(1),
146 avoid_ub<U, T>(genHalfBits<U>() - 1),
147 avoid_ub<U, T>(genHalfBits<U>()),
148 avoid_ub<U, T>(genHalfBits<U>() + 1),
149 avoid_ub<U, T>(std::__finite_max_v<U> - 1),
150 avoid_ub<U, T>(std::__finite_max_v<U>),
151 avoid_ub<U, T>(std::__finite_max_v<U> - 0xff),
152 avoid_ub<U, T>(std::__finite_max_v<U> - 0xff),
153 avoid_ub<U, T>(std::__finite_max_v<U> - 0x55),
154 avoid_ub<U, T>(-(std::__finite_min_v<U> + 1)),
155 avoid_ub<U, T>(-std::__finite_max_v<U>),
156 avoid_ub<U, T>(std::__finite_max_v<U> / std::pow(2., sizeof(T) * 6 - 1)),
157 avoid_ub2<U, T>(-std::__finite_max_v<U> / std::pow(2., sizeof(T) * 6 - 1)),
158 avoid_ub<U, T>(std::__finite_max_v<U> / std::pow(2., sizeof(T) * 4 - 1)),
159 avoid_ub2<U, T>(-std::__finite_max_v<U> / std::pow(2., sizeof(T) * 4 - 1)),
160 avoid_ub<U, T>(std::__finite_max_v<U> / std::pow(2., sizeof(T) * 2 - 1)),
161 avoid_ub2<U, T>(-std::__finite_max_v<U> / std::pow(2., sizeof(T) * 2 - 1)),
162 avoid_ub<U, T>(std::__finite_max_v<T> - 1),
163 avoid_ub<U, T>(std::__finite_max_v<T> * 0.75),
164 }};
165
166 template <class T, class U>
167 struct cvt_inputs
168 {
169 static constexpr size_t
170 size()
171 { return cvt_input_data<U, T>.size(); }
172
173 U
174 operator[](size_t i) const
175 { return cvt_input_data<U, T>[i]; }
176 };
177 #endif // SIMD_TESTS_BITS_CONVERSIONS_H_