diff --git a/libcxx/include/__config b/libcxx/include/__config --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -1430,6 +1430,8 @@ _Pragma("clang attribute pop") \ _Pragma("clang attribute pop") \ _Pragma("clang attribute pop") +# define _LIBCPP_AVAILABILITY_TO_CHARS \ + _LIBCPP_AVAILABILITY_FILESYSTEM #else # define _LIBCPP_AVAILABILITY_SHARED_MUTEX # define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS @@ -1444,6 +1446,7 @@ # define _LIBCPP_AVAILABILITY_FILESYSTEM # define _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH # define _LIBCPP_AVAILABILITY_FILESYSTEM_POP +# define _LIBCPP_AVAILABILITY_TO_CHARS #endif // Define availability that depends on _LIBCPP_NO_EXCEPTIONS. diff --git a/libcxx/include/charconv b/libcxx/include/charconv --- a/libcxx/include/charconv +++ b/libcxx/include/charconv @@ -73,6 +73,7 @@ */ +#include <__config> #include <__errc> #include #include @@ -92,8 +93,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace __itoa { -_LIBCPP_FUNC_VIS char* __u64toa(uint64_t __value, char* __buffer); -_LIBCPP_FUNC_VIS char* __u32toa(uint32_t __value, char* __buffer); +_LIBCPP_AVAILABILITY_TO_CHARS _LIBCPP_FUNC_VIS char* __u64toa(uint64_t __value, char* __buffer); +_LIBCPP_AVAILABILITY_TO_CHARS _LIBCPP_FUNC_VIS char* __u32toa(uint32_t __value, char* __buffer); } #ifndef _LIBCPP_CXX03_LANG @@ -167,6 +168,7 @@ } #endif + _LIBCPP_AVAILABILITY_TO_CHARS static _LIBCPP_INLINE_VISIBILITY char* __convert(_Tp __v, char* __p) { return __u64toa(__v, __p); @@ -189,6 +191,7 @@ } #endif + _LIBCPP_AVAILABILITY_TO_CHARS static _LIBCPP_INLINE_VISIBILITY char* __convert(_Tp __v, char* __p) { return __u32toa(__v, __p); @@ -292,6 +295,7 @@ } template +_LIBCPP_AVAILABILITY_TO_CHARS inline _LIBCPP_INLINE_VISIBILITY to_chars_result __to_chars_itoa(char* __first, char* __last, _Tp __value, true_type) { @@ -306,6 +310,7 @@ } template +_LIBCPP_AVAILABILITY_TO_CHARS inline _LIBCPP_INLINE_VISIBILITY to_chars_result __to_chars_itoa(char* __first, char* __last, _Tp __value, false_type) { @@ -337,6 +342,7 @@ } template +_LIBCPP_AVAILABILITY_TO_CHARS inline _LIBCPP_INLINE_VISIBILITY to_chars_result __to_chars_integral(char* __first, char* __last, _Tp __value, int __base, true_type) @@ -352,6 +358,7 @@ } template +_LIBCPP_AVAILABILITY_TO_CHARS inline _LIBCPP_INLINE_VISIBILITY to_chars_result __to_chars_integral(char* __first, char* __last, _Tp __value, int __base, false_type) @@ -380,6 +387,7 @@ } template ::value, int>::type = 0> +_LIBCPP_AVAILABILITY_TO_CHARS inline _LIBCPP_INLINE_VISIBILITY to_chars_result to_chars(char* __first, char* __last, _Tp __value) { @@ -387,6 +395,7 @@ } template ::value, int>::type = 0> +_LIBCPP_AVAILABILITY_TO_CHARS inline _LIBCPP_INLINE_VISIBILITY to_chars_result to_chars(char* __first, char* __last, _Tp __value, int __base) { diff --git a/libcxx/test/libcxx/utilities/charconv/charconv.to.chars/availability.fail.cpp b/libcxx/test/libcxx/utilities/charconv/charconv.to.chars/availability.fail.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/utilities/charconv/charconv.to.chars/availability.fail.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 +// REQUIRES: availability=macosx10.7 || availability=macosx10.8 || availability=macosx10.9 || availability=macosx10.10 || availability=macosx10.11 || availability=macosx10.12 || availability=macosx10.13 || availability=macosx10.14 + +// Test the availability markup on std::to_chars. + +#include + +int main(int, char**) +{ + char buf[100]; + int int_value = 33; + long long_value = 33; + int base = 2; + std::to_chars(buf, buf + 100, int_value); // expected-error{{is unavailable: introduced in}} + std::to_chars(buf, buf + 100, int_value, base); // expected-error{{is unavailable: introduced in}} + + std::to_chars(buf, buf + 100, long_value); // expected-error{{is unavailable: introduced in}} + std::to_chars(buf, buf + 100, long_value, base); // expected-error{{is unavailable: introduced in}} +} diff --git a/libcxx/test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp b/libcxx/test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp --- a/libcxx/test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp +++ b/libcxx/test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp @@ -10,52 +10,20 @@ // UNSUPPORTED: !libc++ && c++11 // UNSUPPORTED: !libc++ && c++14 -// XFAIL: with_system_cxx_lib=macosx10.14 -// XFAIL: with_system_cxx_lib=macosx10.13 -// XFAIL: with_system_cxx_lib=macosx10.12 -// XFAIL: with_system_cxx_lib=macosx10.11 -// XFAIL: with_system_cxx_lib=macosx10.10 -// XFAIL: with_system_cxx_lib=macosx10.9 -// XFAIL: with_system_cxx_lib=macosx10.8 -// XFAIL: with_system_cxx_lib=macosx10.7 - // // from_chars_result from_chars(const char* first, const char* last, // Integral& value, int base = 10) +#include #include "test_macros.h" #include "charconv_test_helpers.h" template -struct test_basics : roundtrip_test_base +struct test_basics { - using roundtrip_test_base::test; - void operator()() { - test(0); - test(42); - test(32768); - test(0, 10); - test(42, 10); - test(32768, 10); - test(0xf, 16); - test(0xdeadbeaf, 16); - test(0755, 8); - - for (int b = 2; b < 37; ++b) - { - using xl = std::numeric_limits; - - test(1, b); - test(-1, b); - test(xl::lowest(), b); - test((xl::max)(), b); - test((xl::max)() / 2, b); - } - - using std::from_chars; std::from_chars_result r; T x; @@ -65,7 +33,7 @@ // the expected form of the subject sequence is a sequence of // letters and digits representing an integer with the radix // specified by base (C11 7.22.1.4/3) - r = from_chars(s, s + sizeof(s), x); + r = std::from_chars(s, s + sizeof(s), x); assert(r.ec == std::errc{}); assert(r.ptr == s + 3); assert(x == 1); @@ -76,7 +44,7 @@ // The letters from a (or A) through z (or Z) are ascribed the // values 10 through 35; (C11 7.22.1.4/3) - r = from_chars(s, s + sizeof(s), x, 36); + r = std::from_chars(s, s + sizeof(s), x, 36); assert(r.ec == std::errc::result_out_of_range); // The member ptr of the return value points to the first character // not matching the pattern @@ -84,14 +52,14 @@ assert(x == 1); // no "0x" or "0X" prefix shall appear if the value of base is 16 - r = from_chars(s, s + sizeof(s), x, 16); + r = std::from_chars(s, s + sizeof(s), x, 16); assert(r.ec == std::errc{}); assert(r.ptr == s + 1); assert(x == 0); // only letters and digits whose ascribed values are less than that // of base are permitted. (C11 7.22.1.4/3) - r = from_chars(s + 2, s + sizeof(s), x, 12); + r = std::from_chars(s + 2, s + sizeof(s), x, 12); // If the parsed value is not in the range representable by the type // of value, if (!fits_in(1150)) @@ -115,30 +83,10 @@ }; template -struct test_signed : roundtrip_test_base +struct test_signed { - using roundtrip_test_base::test; - void operator()() { - test(-1); - test(-12); - test(-1, 10); - test(-12, 10); - test(-21734634, 10); - test(-2647, 2); - test(-0xcc1, 16); - - for (int b = 2; b < 37; ++b) - { - using xl = std::numeric_limits; - - test(0, b); - test(xl::lowest(), b); - test((xl::max)(), b); - } - - using std::from_chars; std::from_chars_result r; T x; @@ -146,7 +94,7 @@ // If the pattern allows for an optional sign, // but the string has no digit characters following the sign, char s[] = "- 9+12"; - r = from_chars(s, s + sizeof(s), x); + r = std::from_chars(s, s + sizeof(s), x); // no characters match the pattern. assert(r.ptr == s); assert(r.ec == std::errc::invalid_argument); @@ -154,7 +102,7 @@ { char s[] = "9+12"; - r = from_chars(s, s + sizeof(s), x); + r = std::from_chars(s, s + sizeof(s), x); assert(r.ec == std::errc{}); // The member ptr of the return value points to the first character // not matching the pattern, @@ -164,7 +112,7 @@ { char s[] = "12"; - r = from_chars(s, s + 2, x); + r = std::from_chars(s, s + 2, x); assert(r.ec == std::errc{}); // or has the value last if all characters match. assert(r.ptr == s + 2); @@ -175,7 +123,7 @@ // '-' is the only sign that may appear char s[] = "+30"; // If no characters match the pattern, - r = from_chars(s, s + sizeof(s), x); + r = std::from_chars(s, s + sizeof(s), x); // value is unmodified, assert(x == 12); // the member ptr of the return value is first and @@ -191,5 +139,5 @@ run(integrals); run(all_signed); - return 0; + return 0; } diff --git a/libcxx/test/std/utilities/charconv/charconv.from.chars/integral.roundtrip.pass.cpp b/libcxx/test/std/utilities/charconv/charconv.from.chars/integral.roundtrip.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/utilities/charconv/charconv.from.chars/integral.roundtrip.pass.cpp @@ -0,0 +1,96 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 +// UNSUPPORTED: !libc++ && c++11 +// UNSUPPORTED: !libc++ && c++14 + +// The roundtrip test uses to_chars, which requires functions in the dylib +// that were introduced in Mac OS 10.15. +// +// XFAIL: with_system_cxx_lib=macosx10.14 +// XFAIL: with_system_cxx_lib=macosx10.13 +// XFAIL: with_system_cxx_lib=macosx10.12 +// XFAIL: with_system_cxx_lib=macosx10.11 +// XFAIL: with_system_cxx_lib=macosx10.10 +// XFAIL: with_system_cxx_lib=macosx10.9 +// XFAIL: with_system_cxx_lib=macosx10.8 +// XFAIL: with_system_cxx_lib=macosx10.7 + +// + +// from_chars_result from_chars(const char* first, const char* last, +// Integral& value, int base = 10) + +#include +#include "test_macros.h" +#include "charconv_test_helpers.h" + +template +struct test_basics : roundtrip_test_base +{ + using roundtrip_test_base::test; + + void operator()() + { + test(0); + test(42); + test(32768); + test(0, 10); + test(42, 10); + test(32768, 10); + test(0xf, 16); + test(0xdeadbeaf, 16); + test(0755, 8); + + for (int b = 2; b < 37; ++b) + { + using xl = std::numeric_limits; + + test(1, b); + test(-1, b); + test(xl::lowest(), b); + test((xl::max)(), b); + test((xl::max)() / 2, b); + } + } +}; + +template +struct test_signed : roundtrip_test_base +{ + using roundtrip_test_base::test; + + void operator()() + { + test(-1); + test(-12); + test(-1, 10); + test(-12, 10); + test(-21734634, 10); + test(-2647, 2); + test(-0xcc1, 16); + + for (int b = 2; b < 37; ++b) + { + using xl = std::numeric_limits; + + test(0, b); + test(xl::lowest(), b); + test((xl::max)(), b); + } + } +}; + +int main(int, char**) +{ + run(integrals); + run(all_signed); + + return 0; +} diff --git a/libcxx/test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp b/libcxx/test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp --- a/libcxx/test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp +++ b/libcxx/test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp @@ -10,6 +10,8 @@ // UNSUPPORTED: !libc++ && c++11 // UNSUPPORTED: !libc++ && c++14 +// to_chars requires functions in the dylib that were introduced in Mac OS 10.15. +// // XFAIL: with_system_cxx_lib=macosx10.14 // XFAIL: with_system_cxx_lib=macosx10.13 // XFAIL: with_system_cxx_lib=macosx10.12 @@ -24,6 +26,7 @@ // to_chars_result to_chars(char* first, char* last, Integral value, // int base = 10) +#include #include "test_macros.h" #include "charconv_test_helpers.h"