From 660d8f61e928d30538bbbd05fd68fb6bc33c8d1a Mon Sep 17 00:00:00 2001 From: Vladimir Batov Date: Sat, 16 Mar 2024 12:05:23 +1100 Subject: [PATCH 1/2] 16MAR-12:05 fixed issue #63 --- include/boost/convert.hpp | 4 +-- include/boost/convert/charconv.hpp | 50 +++++++++++++----------------- makefile | 1 + test/issue-63.cpp | 17 ++++++++++ 4 files changed, 41 insertions(+), 31 deletions(-) create mode 100644 test/issue-63.cpp diff --git a/include/boost/convert.hpp b/include/boost/convert.hpp index d3364d5..b022ccb 100644 --- a/include/boost/convert.hpp +++ b/include/boost/convert.hpp @@ -38,10 +38,11 @@ namespace boost namespace cnv { + using char_cptr = char const*; + template 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 diff --git a/include/boost/convert/charconv.hpp b/include/boost/convert/charconv.hpp index f2b5713..715e5e9 100644 --- a/include/boost/convert/charconv.hpp +++ b/include/boost/convert/charconv.hpp @@ -18,56 +18,50 @@ #endif // BOOST_NO_CXX17_IF_CONSTEXPR #include +#include #include #include -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 +/// @brief std::to/from_chars-based extended converter +/// @details Good overall performance and moderate formatting facilities. +struct boost::cnv::charconv : public boost::cnv::cnvbase { using this_type = boost::cnv::charconv; using base_type = boost::cnv::cnvbase; - private: - - friend struct boost::cnv::cnvbase; - template cnv::range to_str(in_type value_in, char* buf) const { - const auto [ptr, ec] = [&]{ - if constexpr (std::is_integral_v) { - return std::to_chars(buf, buf + bufsize_, value_in, static_cast(base_)); - } else { + auto [ptr, err] = [&] + { + if constexpr (std::is_integral_v) + 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(buf, success ? ptr : buf); + return cnv::range(buf, err == std::errc{} ? ptr : buf); } - template void str_to(cnv::range range, optional& result_out) const { out_type result = boost::make_default(); - const auto [ptr, ec] = [&]{ - if constexpr (std::is_integral_v) { - return std::from_chars(&*range.begin(), &*range.end(), result, static_cast(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) + 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 }; return format[int(notation_)]; } - - std::chars_format fmt_ = std::chars_format::fixed; }; #endif // BOOST_CONVERT_CHARCONV_BASED_CONVERTER_HPP diff --git a/makefile b/makefile index f31b1de..e3823ab 100644 --- a/makefile +++ b/makefile @@ -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 diff --git a/test/issue-63.cpp b/test/issue-63.cpp new file mode 100644 index 0000000..e9fc1ff --- /dev/null +++ b/test/issue-63.cpp @@ -0,0 +1,17 @@ +#include +#include +#include + +int main() +{ + auto cnv4 = boost::cnv::charconv(); + std::string PuNum = "2"; + auto optPuNum = boost::convert(PuNum, cnv4); + + if (optPuNum) + std::cout << *optPuNum << "\n"; + else + std::cout << "nullopt\n"; + + return 0; +} From 4fb6074d7b9eb95aeaa7088335a802ef59b588d7 Mon Sep 17 00:00:00 2001 From: Vladimir Batov Date: Sat, 16 Mar 2024 12:47:47 +1100 Subject: [PATCH 2/2] 16MAR-12:47 merged master --- include/boost/convert.hpp | 4 +-- include/boost/convert/charconv.hpp | 50 +++++++++++++----------------- makefile | 1 + test/issue-63.cpp | 17 ++++++++++ 4 files changed, 41 insertions(+), 31 deletions(-) create mode 100644 test/issue-63.cpp diff --git a/include/boost/convert.hpp b/include/boost/convert.hpp index d3364d5..b022ccb 100644 --- a/include/boost/convert.hpp +++ b/include/boost/convert.hpp @@ -38,10 +38,11 @@ namespace boost namespace cnv { + using char_cptr = char const*; + template 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 diff --git a/include/boost/convert/charconv.hpp b/include/boost/convert/charconv.hpp index f2b5713..715e5e9 100644 --- a/include/boost/convert/charconv.hpp +++ b/include/boost/convert/charconv.hpp @@ -18,56 +18,50 @@ #endif // BOOST_NO_CXX17_IF_CONSTEXPR #include +#include #include #include -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 +/// @brief std::to/from_chars-based extended converter +/// @details Good overall performance and moderate formatting facilities. +struct boost::cnv::charconv : public boost::cnv::cnvbase { using this_type = boost::cnv::charconv; using base_type = boost::cnv::cnvbase; - private: - - friend struct boost::cnv::cnvbase; - template cnv::range to_str(in_type value_in, char* buf) const { - const auto [ptr, ec] = [&]{ - if constexpr (std::is_integral_v) { - return std::to_chars(buf, buf + bufsize_, value_in, static_cast(base_)); - } else { + auto [ptr, err] = [&] + { + if constexpr (std::is_integral_v) + 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(buf, success ? ptr : buf); + return cnv::range(buf, err == std::errc{} ? ptr : buf); } - template void str_to(cnv::range range, optional& result_out) const { out_type result = boost::make_default(); - const auto [ptr, ec] = [&]{ - if constexpr (std::is_integral_v) { - return std::from_chars(&*range.begin(), &*range.end(), result, static_cast(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) + 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 }; return format[int(notation_)]; } - - std::chars_format fmt_ = std::chars_format::fixed; }; #endif // BOOST_CONVERT_CHARCONV_BASED_CONVERTER_HPP diff --git a/makefile b/makefile index f31b1de..e3823ab 100644 --- a/makefile +++ b/makefile @@ -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 diff --git a/test/issue-63.cpp b/test/issue-63.cpp new file mode 100644 index 0000000..e9fc1ff --- /dev/null +++ b/test/issue-63.cpp @@ -0,0 +1,17 @@ +#include +#include +#include + +int main() +{ + auto cnv4 = boost::cnv::charconv(); + std::string PuNum = "2"; + auto optPuNum = boost::convert(PuNum, cnv4); + + if (optPuNum) + std::cout << *optPuNum << "\n"; + else + std::cout << "nullopt\n"; + + return 0; +}