|
Boost : |
From: g.peterhoff_at_[hidden]
Date: 2024-01-31 16:37:25
Hello Matt,
Sorry for submitting a bug report this way. (Having problems with my GitHub account at the moment).
Code: Attachment (gcc 13.2 -std=gnu++23 -O3 -Wall -fanalyzer)
Errors (normal)
- Missing sign
- Hex exponent is wrong
- Hex is completely wrong
- Accuracy is not correct
- Error code deviates from the standard
...
The backup functions via (quadmath)snprintf do not work.
Errors (critical)
- If the buffer is too small (e.g. set the array size to 3) there are a lot of buffer overflows. Especially with value ±nan/±inf.
The functions should therefore always be structured in the same way:
Auxiliary function
inline constexpr bool is_valid_range(const char*const first, const char*const last) noexcept
{
return (first!=nullptr && last!=nullptr) ? first < last : false;
}
Pseudocode
to_chars(...) // FP
{
to_chars_result
result{last, std::errc::value_too_large};
if (is_valid_range(first, last)) [[likely]]
{
const size_t
size = size_t(last - first);
if (inf or nan) [[unlikely]]
{
if (size is large enough)
{
copy the string values into the range
result = ...;
Here you could also use #define to specify whether the string values are compatible with the standard or not.
"±inf", "±nan"
or https://develop.charconv.cpp.al/#to_chars_usage_notes_for_to_chars_for_floating_point_types
}
}
else
{
convert, detail::implemantation(first, size, ...)
result = ...;
}
}
return result;
}
to_chars(...) // INT
{
to_chars_result
result{last, std::errc::value_too_large};
if (is_valid_range(first, last)) [[likely]]
{
const size_t
size = size_t(last - first);
convert, detail::implemantation(first, size, ...)
result = ...;
}
return result;
}
This can be achieved with templates and typetraits:
FP
boost::is_floating_point still does not contain any C++23 types.
template <typename Type>
BOOST_NOINLINE typename std::enable_if<std::is_floating_point<Type>::value, to_chars_result>::type
to_chars(char*const first, char*const last, const Type value, const chars_format format, const int precision) noexcept;
template <type name Type>
BOOST_NOINLINE typename std::enable_if<std::is_floating_point<Type>::value, to_chars_result>::type
to_chars(char*const first, char*const last, const Type value, const chars_format format) noexcept;
INT
(boost)is_integer is unfortunately still missing.
template <type name Type>
BOOST_NOINLINE typename std::enable_if<boost::is_integer<Type>::value, to_chars_result>::type
to_chars(char*const first, char*const last, const Type value, const int base = 10) noexcept;
regards
Gero
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk