Skip to content

Commit

Permalink
16MAR-12:47 merged master
Browse files Browse the repository at this point in the history
  • Loading branch information
Vladimir Batov authored and Vladimir Batov committed Mar 16, 2024
1 parent 79984a5 commit 4fb6074
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 31 deletions.
4 changes: 2 additions & 2 deletions include/boost/convert.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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>
Expand Down
50 changes: 21 additions & 29 deletions include/boost/convert/charconv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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[] =
Expand All @@ -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
1 change: 1 addition & 0 deletions makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
17 changes: 17 additions & 0 deletions test/issue-63.cpp
Original file line number Diff line number Diff line change
@@ -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;
}

0 comments on commit 4fb6074

Please sign in to comment.