2
0
mirror of https://github.com/boostorg/convert.git synced 2026-01-19 04:02:18 +00:00

Sync from upstream.

This commit is contained in:
Rene Rivera
2024-03-23 07:57:27 -05:00
4 changed files with 41 additions and 31 deletions

View File

@@ -38,10 +38,11 @@ namespace boost
namespace cnv
{
using char_cptr = char const*;
template<typename, typename, typename> struct reference;
struct by_default;
}
/// @brief Boost.Convert main deployment interface
/// @param[in] value_in Value of the TypeIn type to be converted to the TypeOut type
/// @param[in] converter Converter to be used for conversion
@@ -63,7 +64,6 @@ namespace boost
boost::unwrap_ref(converter)(value_in, result);
return result;
}
namespace cnv { namespace detail
{
template<typename TypeOut, typename TypeIn, typename Converter =boost::cnv::by_default>

View File

@@ -18,56 +18,50 @@
#endif // BOOST_NO_CXX17_IF_CONSTEXPR
#include <boost/convert/base.hpp>
#include <boost/make_default.hpp>
#include <charconv>
#include <type_traits>
namespace boost { namespace cnv { struct charconv; }}
namespace boost::cnv { struct charconv; }
/// @brief std::to/from_chars-based extended converter
/// @details The converter offers good overall performance and moderate formatting facilities.
struct boost::cnv::charconv : boost::cnv::cnvbase<boost::cnv::charconv>
/// @brief std::to/from_chars-based extended converter
/// @details Good overall performance and moderate formatting facilities.
struct boost::cnv::charconv : public boost::cnv::cnvbase<boost::cnv::charconv>
{
using this_type = boost::cnv::charconv;
using base_type = boost::cnv::cnvbase<this_type>;
private:
friend struct boost::cnv::cnvbase<this_type>;
template<typename in_type>
cnv::range<char*>
to_str(in_type value_in, char* buf) const
{
const auto [ptr, ec] = [&]{
if constexpr (std::is_integral_v<in_type>) {
return std::to_chars(buf, buf + bufsize_, value_in, static_cast<int>(base_));
} else {
auto [ptr, err] = [&]
{
if constexpr (std::is_integral_v<in_type>)
return std::to_chars(buf, buf + bufsize_, value_in, int(base_));
else
return std::to_chars(buf, buf + bufsize_, value_in, chars_format(), precision_);
}
}();
bool success = ec == std::errc{};
return cnv::range<char*>(buf, success ? ptr : buf);
return cnv::range<char*>(buf, err == std::errc{} ? ptr : buf);
}
template<typename string_type, typename out_type>
void
str_to(cnv::range<string_type> range, optional<out_type>& result_out) const
{
out_type result = boost::make_default<out_type>();
const auto [ptr, ec] = [&]{
if constexpr (std::is_integral_v<out_type>) {
return std::from_chars(&*range.begin(), &*range.end(), result, static_cast<int>(base_));
} else {
return std::from_chars(&*range.begin(), &*range.end(), result, chars_format());
}
}();
auto [ptr, err] = [&]
{
char_cptr beg = &*range.begin();
char_cptr end = beg + range.size();
if (ec == std::errc{})
if constexpr (std::is_integral_v<out_type>)
return std::from_chars(beg, end, result, int(base_));
else
return std::from_chars(beg, end, result, chars_format());
}();
if (err == std::errc{})
result_out = result;
}
std::chars_format chars_format() const
{
static constexpr std::chars_format format[] =
@@ -78,8 +72,6 @@ struct boost::cnv::charconv : boost::cnv::cnvbase<boost::cnv::charconv>
};
return format[int(notation_)];
}
std::chars_format fmt_ = std::chars_format::fixed;
};
#endif // BOOST_CONVERT_CHARCONV_BASED_CONVERTER_HPP

View File

@@ -18,6 +18,7 @@ target_13 = convert-test-has-member test/has_member.cpp
target_14 = convert-test-performance test/performance.cpp
target_15 = convert-test-performance-spirit test/performance_spirit.cpp
target_16 = convert-test-charconv-converter test/charconv_converter.cpp
target_17 = convert-test-63 test/issue-63.cpp
target_21 = convert-example-algorithms example/algorithms.cpp
target_22 = convert-example-default_converter example/default_converter.cpp

17
test/issue-63.cpp Normal file
View File

@@ -0,0 +1,17 @@
#include <boost/convert.hpp>
#include <boost/convert/charconv.hpp>
#include <iostream>
int main()
{
auto cnv4 = boost::cnv::charconv();
std::string PuNum = "2";
auto optPuNum = boost::convert<size_t>(PuNum, cnv4);
if (optPuNum)
std::cout << *optPuNum << "\n";
else
std::cout << "nullopt\n";
return 0;
}