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
19 #include "test_macros.h"
22 #error This file requires C++11
25 using std::false_type
;
28 template <typename To
, typename From
>
30 is_non_narrowing(From a
) -> decltype(To
{a
}, true_type())
35 template <typename To
>
37 is_non_narrowing(...) -> false_type
42 template <typename X
, typename T
>
44 _fits_in(T
, true_type
/* non-narrowing*/, ...)
49 template <typename X
, typename T
, typename xl
= std::numeric_limits
<X
>>
51 _fits_in(T v
, false_type
, true_type
/* T signed*/, true_type
/* X signed */)
53 return xl::lowest() <= v
&& v
<= (xl::max
)();
56 template <typename X
, typename T
, typename xl
= std::numeric_limits
<X
>>
58 _fits_in(T v
, false_type
, true_type
/* T signed */, false_type
/* X unsigned*/)
60 return 0 <= v
&& typename
std::make_unsigned
<T
>::type(v
) <= (xl::max
)();
63 template <typename X
, typename T
, typename xl
= std::numeric_limits
<X
>>
65 _fits_in(T v
, false_type
, false_type
/* T unsigned */, ...)
67 return v
<= typename
std::make_unsigned
<X
>::type((xl::max
)());
70 template <typename X
, typename T
>
74 return _fits_in
<X
>(v
, is_non_narrowing
<X
>(v
), std::is_signed
<T
>(),
79 struct to_chars_test_base
81 template <typename T
, size_t N
, typename
... Ts
>
82 void test(T v
, char const (&expect
)[N
], Ts
... args
)
85 std::to_chars_result r
;
87 constexpr size_t len
= N
- 1;
88 static_assert(len
> 0, "expected output won't be empty");
93 r
= to_chars(buf
, buf
+ len
- 1, X(v
), args
...);
94 assert(r
.ptr
== buf
+ len
- 1);
95 assert(r
.ec
== std::errc::value_too_large
);
97 r
= to_chars(buf
, buf
+ sizeof(buf
), X(v
), args
...);
98 assert(r
.ptr
== buf
+ len
);
99 assert(r
.ec
== std::errc
{});
100 assert(memcmp(buf
, expect
, len
) == 0);
103 template <typename
... Ts
>
104 void test_value(X v
, Ts
... args
)
107 std::to_chars_result r
;
109 // Poison the buffer for testing whether a successful std::to_chars
110 // doesn't modify data beyond r.ptr.
111 std::iota(buf
, buf
+ sizeof(buf
), char(1));
112 r
= to_chars(buf
, buf
+ sizeof(buf
), v
, args
...);
113 assert(r
.ec
== std::errc
{});
114 for (size_t i
= r
.ptr
- buf
; i
< sizeof(buf
); ++i
)
115 assert(buf
[i
] == static_cast<char>(i
+ 1));
118 auto a
= fromchars(buf
, r
.ptr
, args
...);
122 r
= to_chars(buf
, ep
, v
, args
...);
124 assert(r
.ec
== std::errc::value_too_large
);
128 static long long fromchars(char const* p
, char const* ep
, int base
, true_type
)
131 auto r
= strtoll(p
, &last
, base
);
137 static unsigned long long fromchars(char const* p
, char const* ep
, int base
, false_type
)
140 auto r
= strtoull(p
, &last
, base
);
146 static auto fromchars(char const* p
, char const* ep
, int base
= 10)
147 -> decltype(fromchars(p
, ep
, base
, std::is_signed
<X
>()))
149 return fromchars(p
, ep
, base
, std::is_signed
<X
>());
155 template <typename X
>
156 struct roundtrip_test_base
158 template <typename T
, typename
... Ts
>
159 void test(T v
, Ts
... args
)
161 using std::from_chars
;
163 std::from_chars_result r2
;
164 std::to_chars_result r
;
169 r
= to_chars(buf
, buf
+ sizeof(buf
), v
, args
...);
170 assert(r
.ec
== std::errc
{});
172 r2
= from_chars(buf
, r
.ptr
, x
, args
...);
173 assert(r2
.ptr
== r
.ptr
);
178 r
= to_chars(buf
, buf
+ sizeof(buf
), v
, args
...);
179 assert(r
.ec
== std::errc
{});
181 r2
= from_chars(buf
, r
.ptr
, x
, args
...);
183 #ifdef TEST_COMPILER_MSVC
184 #pragma warning(push)
185 #pragma warning(disable: 4127) // conditional expression is constant
186 #endif // TEST_COMPILER_MSVC
187 if (std::is_signed
<T
>::value
&& v
< 0 && std::is_unsigned
<X
>::value
)
190 assert(r2
.ptr
== buf
);
191 assert(r2
.ec
== std::errc::invalid_argument
);
196 assert(r2
.ptr
== r
.ptr
);
197 assert(r2
.ec
== std::errc::result_out_of_range
);
199 #ifdef TEST_COMPILER_MSVC
201 #endif // TEST_COMPILER_MSVC
209 template <typename
... T
>
214 template <typename L1
, typename L2
>
217 template <typename
... Xs
, typename
... Ys
>
218 struct type_concat
<type_list
<Xs
...>, type_list
<Ys
...>>
220 using type
= type_list
<Xs
..., Ys
...>;
223 template <typename L1
, typename L2
>
224 using concat_t
= typename type_concat
<L1
, L2
>::type
;
226 template <typename L1
, typename L2
>
227 constexpr auto concat(L1
, L2
) -> concat_t
<L1
, L2
>
232 auto all_signed
= type_list
<char, signed char, short, int, long, long long>();
233 auto all_unsigned
= type_list
<unsigned char, unsigned short, unsigned int,
234 unsigned long, unsigned long long>();
235 auto integrals
= concat(all_signed
, all_unsigned
);
237 template <template <typename
> class Fn
, typename
... Ts
>
239 run(type_list
<Ts
...>)
241 int ls
[sizeof...(Ts
)] = {(Fn
<Ts
>{}(), 0)...};
245 #endif // SUPPORT_CHARCONV_TEST_HELPERS_H