1 //===----------------------------------------------------------------------===//
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-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef SUPPORT_CHARCONV_TEST_HELPERS_H
10 #define SUPPORT_CHARCONV_TEST_HELPERS_H
18 #include "test_macros.h"
21 #error This file requires C++11
24 using std::false_type
;
27 template <typename To
, typename From
>
29 is_non_narrowing(From a
) -> decltype(To
{a
}, true_type())
34 template <typename To
>
36 is_non_narrowing(...) -> false_type
41 template <typename X
, typename T
>
43 _fits_in(T
, true_type
/* non-narrowing*/, ...)
48 template <typename X
, typename T
, typename xl
= std::numeric_limits
<X
>>
50 _fits_in(T v
, false_type
, true_type
/* T signed*/, true_type
/* X signed */)
52 return xl::lowest() <= v
&& v
<= (xl::max
)();
55 template <typename X
, typename T
, typename xl
= std::numeric_limits
<X
>>
57 _fits_in(T v
, false_type
, true_type
/* T signed */, false_type
/* X unsigned*/)
59 return 0 <= v
&& typename
std::make_unsigned
<T
>::type(v
) <= (xl::max
)();
62 template <typename X
, typename T
, typename xl
= std::numeric_limits
<X
>>
64 _fits_in(T v
, false_type
, false_type
/* T unsigned */, ...)
66 return v
<= typename
std::make_unsigned
<X
>::type((xl::max
)());
69 template <typename X
, typename T
>
73 return _fits_in
<X
>(v
, is_non_narrowing
<X
>(v
), std::is_signed
<T
>(),
78 struct to_chars_test_base
80 template <typename T
, size_t N
, typename
... Ts
>
81 void test(T v
, char const (&expect
)[N
], Ts
... args
)
84 std::to_chars_result r
;
86 constexpr size_t len
= N
- 1;
87 static_assert(len
> 0, "expected output won't be empty");
92 r
= to_chars(buf
, buf
+ len
- 1, X(v
), args
...);
93 assert(r
.ptr
== buf
+ len
- 1);
94 assert(r
.ec
== std::errc::value_too_large
);
96 r
= to_chars(buf
, buf
+ sizeof(buf
), X(v
), args
...);
97 assert(r
.ptr
== buf
+ len
);
98 assert(r
.ec
== std::errc
{});
99 assert(memcmp(buf
, expect
, len
) == 0);
102 template <typename
... Ts
>
103 void test_value(X v
, Ts
... args
)
106 std::to_chars_result r
;
108 r
= to_chars(buf
, buf
+ sizeof(buf
), v
, args
...);
109 assert(r
.ec
== std::errc
{});
112 auto a
= fromchars(buf
, r
.ptr
, args
...);
116 r
= to_chars(buf
, ep
, v
, args
...);
118 assert(r
.ec
== std::errc::value_too_large
);
122 static long long fromchars(char const* p
, char const* ep
, int base
, true_type
)
125 auto r
= strtoll(p
, &last
, base
);
131 static unsigned long long fromchars(char const* p
, char const* ep
, int base
, false_type
)
134 auto r
= strtoull(p
, &last
, base
);
140 static auto fromchars(char const* p
, char const* ep
, int base
= 10)
141 -> decltype(fromchars(p
, ep
, base
, std::is_signed
<X
>()))
143 return fromchars(p
, ep
, base
, std::is_signed
<X
>());
149 template <typename X
>
150 struct roundtrip_test_base
152 template <typename T
, typename
... Ts
>
153 void test(T v
, Ts
... args
)
155 using std::from_chars
;
157 std::from_chars_result r2
;
158 std::to_chars_result r
;
163 r
= to_chars(buf
, buf
+ sizeof(buf
), v
, args
...);
164 assert(r
.ec
== std::errc
{});
166 r2
= from_chars(buf
, r
.ptr
, x
, args
...);
167 assert(r2
.ptr
== r
.ptr
);
172 r
= to_chars(buf
, buf
+ sizeof(buf
), v
, args
...);
173 assert(r
.ec
== std::errc
{});
175 r2
= from_chars(buf
, r
.ptr
, x
, args
...);
177 #ifdef TEST_COMPILER_C1XX
178 #pragma warning(push)
179 #pragma warning(disable: 4127) // conditional expression is constant
180 #endif // TEST_COMPILER_C1XX
181 if (std::is_signed
<T
>::value
&& v
< 0 && std::is_unsigned
<X
>::value
)
184 assert(r2
.ptr
== buf
);
185 assert(r2
.ec
== std::errc::invalid_argument
);
190 assert(r2
.ptr
== r
.ptr
);
191 assert(r2
.ec
== std::errc::result_out_of_range
);
193 #ifdef TEST_COMPILER_C1XX
195 #endif // TEST_COMPILER_C1XX
203 template <typename
... T
>
208 template <typename L1
, typename L2
>
211 template <typename
... Xs
, typename
... Ys
>
212 struct type_concat
<type_list
<Xs
...>, type_list
<Ys
...>>
214 using type
= type_list
<Xs
..., Ys
...>;
217 template <typename L1
, typename L2
>
218 using concat_t
= typename type_concat
<L1
, L2
>::type
;
220 template <typename L1
, typename L2
>
221 constexpr auto concat(L1
, L2
) -> concat_t
<L1
, L2
>
226 auto all_signed
= type_list
<char, signed char, short, int, long, long long>();
227 auto all_unsigned
= type_list
<unsigned char, unsigned short, unsigned int,
228 unsigned long, unsigned long long>();
229 auto integrals
= concat(all_signed
, all_unsigned
);
231 template <template <typename
> class Fn
, typename
... Ts
>
233 run(type_list
<Ts
...>)
235 int ls
[sizeof...(Ts
)] = {(Fn
<Ts
>{}(), 0)...};
239 #endif // SUPPORT_CHARCONV_TEST_HELPERS_H