fix: try fix clang libcxx charconv issue.
- add compile checker in cmake to detect charconv support status. - and expose macro for yycc to enable different part of charconv repectively to prevent duplicated defines.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
#include "../../macro/stl_detector.hpp"
|
||||
|
||||
#if defined(YYCC_STL_CLANGSTL)
|
||||
//#if defined(YYCC_STL_CLANGSTL)
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -13,6 +13,7 @@
|
||||
* This polyfill is generated by AI.
|
||||
*/
|
||||
|
||||
#include <charconv>
|
||||
#include <system_error>
|
||||
#include <cctype>
|
||||
#include <climits>
|
||||
@@ -26,6 +27,8 @@
|
||||
|
||||
namespace std {
|
||||
|
||||
#if !defined(YYCC_CHARCONV_HAS_CHARS_FORMAT)
|
||||
|
||||
enum class chars_format : unsigned int {
|
||||
scientific = 1,
|
||||
fixed = 2,
|
||||
@@ -33,6 +36,10 @@ namespace std {
|
||||
general = fixed | scientific // This should be 6 (fixed|scientific)
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(YYCC_CHARCONV_HAS_FROM_CHARS_RESULT)
|
||||
|
||||
struct from_chars_result {
|
||||
const char* ptr;
|
||||
std::errc ec;
|
||||
@@ -41,6 +48,10 @@ namespace std {
|
||||
constexpr explicit operator bool() const noexcept { return ec == std::errc{}; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(YYCC_CHARCONV_HAS_TO_CHARS_RESULT)
|
||||
|
||||
struct to_chars_result {
|
||||
char* ptr;
|
||||
std::errc ec;
|
||||
@@ -49,6 +60,10 @@ namespace std {
|
||||
constexpr explicit operator bool() const noexcept { return ec == std::errc{}; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(YYCC_CHARCONV_HAS_TO_CHARS_INT)
|
||||
|
||||
/// @private
|
||||
enum class __integral_type {
|
||||
u8,
|
||||
@@ -172,16 +187,21 @@ namespace std {
|
||||
// Use snprintf with appropriate format
|
||||
const auto max_buffer_size = static_cast<size_t>(last - first);
|
||||
const char* format_string = __get_int_format<integral_type>(integral_base_type);
|
||||
int written = std::snprintf(first, max_buffer_size, format_string, val);
|
||||
int written = std::snprintf(first, max_buffer_size, format_string, value);
|
||||
if (written < 0 || static_cast<size_t>(written) >= max_buffer_size) {
|
||||
return {last, std::errc::value_too_large};
|
||||
}
|
||||
return {first + written, std::errc{}};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(YYCC_CHARCONV_HAS_TO_CHARS_FLOAT)
|
||||
|
||||
/// @private
|
||||
enum class __float_type {
|
||||
f32, f64,
|
||||
f32,
|
||||
f64,
|
||||
};
|
||||
|
||||
/// @private
|
||||
@@ -195,12 +215,10 @@ namespace std {
|
||||
static_assert(false, "Unsupported floating point type");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// @private
|
||||
enum class __float_fmt_type {
|
||||
general, scientific, fixed, hex
|
||||
};
|
||||
|
||||
enum class __float_fmt_type { general, scientific, fixed, hex };
|
||||
|
||||
/// @private
|
||||
std::optional<__float_fmt_type> __classify_float_fmt(chars_format fmt) {
|
||||
if (fmt == chars_format::general) {
|
||||
@@ -265,7 +283,7 @@ namespace std {
|
||||
const auto float_fmt_type = std::move(opt_float_fmt_type.value());
|
||||
|
||||
const auto max_buffer_size = static_cast<size_t>(last - first);
|
||||
const char *format_string = __get_float_format<float_type>(float_fmt_type);
|
||||
const char* format_string = __get_float_format<float_type>(float_fmt_type);
|
||||
int written = std::snprintf(first, max_buffer_size, format_string, precision, value);
|
||||
if (written < 0 || static_cast<size_t>(written) >= max_buffer_size) {
|
||||
return {last, std::errc::value_too_large};
|
||||
@@ -273,10 +291,12 @@ namespace std {
|
||||
return {first + written, std::errc{}};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(YYCC_CHARCONV_HAS_FROM_CHARS_INT)
|
||||
|
||||
/// @private
|
||||
enum class __strtoi_cluster {
|
||||
tol, toll, toul, toull
|
||||
};
|
||||
enum class __strtoi_cluster { tol, toll, toul, toull };
|
||||
|
||||
/// @private
|
||||
template<typename T>
|
||||
@@ -330,19 +350,19 @@ namespace std {
|
||||
|
||||
errno = 0;
|
||||
char* end_ptr = const_cast<char*>(first);
|
||||
auto rv = __execute_strtoi<strtoi_cluster>(buffer.data(), &end_ptr, base);
|
||||
auto result = __execute_strtoi<strtoi_cluster>(buffer.data(), &end_ptr, base);
|
||||
if (errno == ERANGE) {
|
||||
return {end_ptr, std::errc::result_out_of_range};
|
||||
}
|
||||
|
||||
using strtoi_cluster_rvtype = decltype(rv);
|
||||
using strtoi_cluster_rvtype = decltype(result);
|
||||
// Check if result fits in T
|
||||
if (result < static_cast<strtoi_cluster_rvtype>(std::numeric_limits<T>::min())
|
||||
|| result > static_cast<strtoi_cluster_rvtype>(std::numeric_limits<T>::max())) {
|
||||
return {end_ptr, std::errc::result_out_of_range};
|
||||
}
|
||||
|
||||
if (end_ptr == buffer.data) {
|
||||
if (end_ptr == buffer.data()) {
|
||||
return {first, std::errc::invalid_argument};
|
||||
}
|
||||
|
||||
@@ -355,10 +375,12 @@ namespace std {
|
||||
return {first + (end_ptr - buffer.data()), std::errc{}};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(YYCC_CHARCONV_HAS_FROM_CHARS_FLOAT)
|
||||
|
||||
/// @private
|
||||
enum class __strtof_cluster {
|
||||
tof, tod
|
||||
};
|
||||
enum class __strtof_cluster { tof, tod };
|
||||
|
||||
/// @private
|
||||
template<typename T>
|
||||
@@ -399,12 +421,12 @@ namespace std {
|
||||
|
||||
errno = 0;
|
||||
char* end_ptr = const_cast<char*>(first);
|
||||
auto rv = __execute_strtof<strtof_cluster>(buffer.data(), &end_ptr);
|
||||
auto result = __execute_strtof<strtof_cluster>(buffer.data(), &end_ptr);
|
||||
if (errno == ERANGE) {
|
||||
return {end_ptr, std::errc::result_out_of_range};
|
||||
}
|
||||
|
||||
if (end_ptr == buffer.data) {
|
||||
if (end_ptr == buffer.data()) {
|
||||
return {first, std::errc::invalid_argument};
|
||||
}
|
||||
|
||||
@@ -417,6 +439,8 @@ namespace std {
|
||||
return {first + (end_ptr - buffer.data()), std::errc{}};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace std
|
||||
|
||||
#endif
|
||||
//#endif
|
||||
|
||||
Reference in New Issue
Block a user