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