<charconv> support

<charconv>

The following functions analogous to those from <charconv> are provided:

std::from_chars has an open issue with LWG here: https://cplusplus.github.io/LWG/lwg-active.html#3081. The standard for <charconv> does not distinguish between underflow and overflow like strtod does. boost::decimal::from_chars modifies value in order to communicate this to the user in a divergence from the standard. This behavior is the same as that of boost::charconv::from_chars_erange.

chars_format

namespace boost {
namespace decimal {

enum class chars_format : unsigned
{
    scientific = 1 << 0,
    fixed = 1 << 1,
    hex = 1 << 2,
    general = fixed | scientific
};

} //namespace decimal
} //namespace boost

from_chars_result

namespace boost {
namespace decimal {

struct from_chars_result
{
    const char* ptr;
    std::errc ptr;

    friend constexpr auto operator==(const from_chars_result& lhs, const from_chars_result& rhs) noexcept = default;

    constexpr explicit operator bool() const noexcept { return ec == std::errc{}; }
}

} //namespace decimal
} //namespace boost

to_chars_result

namespace boost {
namespace decimal {

struct to_chars_result
{
    char* ptr;
    std::errc ptr;

    friend constexpr auto operator==(const to_chars_result& lhs, const to_chars_result& rhs) noexcept = default;

    constexpr explicit operator bool() const noexcept { return ec == std::errc{}; }
}

} //namespace decimal
} //namespace boost

from_chars

namespace boost {
namespace decimal {

template <typename DecimalType>
constexpr boost::decimal::from_chars_result from_chars(const char* first, const char* last, DecimalType& value, boost::decimal::chars_format fmt = boost::decimal::chars_format::general) noexcept

#ifdef BOOST_DECIMAL_HAS_STD_STRING_VIEW

template <typename DecimalType>
constexpr boost::decimal::from_chars_result from_chars(std::string_view str, DecimalType& value, boost::decimal::chars_format fmt = boost::decimal::chars_format::general) noexcept

#else

template <typename DecimalType>
constexpr boost::decimal::from_chars_result from_chars(const std::string& str, DecimalType& value, boost::decimal::chars_format fmt = boost::decimal::chars_format::general) noexcept

#endif

#ifdef BOOST_DECIMAL_HAS_STD_CHARCONV

template <typename DecimalType>
constexpr std::from_chars_result from_chars(const char* first, const char* last, DecimalType& value, std::chars_format fmt) noexcept

#endif // BOOST_DECIMAL_HAS_STD_CHARCONV

} //namespace decimal
} //namespace boost
If std::chars_format is used the function will return a std::from_chars_result and if boost::decimal::chars_format is used OR no format is specified then a boost::decimal::from_chars_result will be returned.

to_chars

#include <boost/decimal/charconv.hpp>

namespace boost {
namespace decimal {

template <typename DecimalType>
BOOST_DECIMAL_CONSTEXPR to_chars_result to_chars(char* first, char* last, DecimalType value) noexcept;

template <typename DecimalType>
BOOST_DECIMAL_CONSTEXPR to_chars_result to_chars(char* first, char* last, DecimalType value, chars_format fmt) noexcept;

template <typename DecimalType>
BOOST_DECIMAL_CONSTEXPR to_chars_result to_chars(char* first, char* last, DecimalType value, chars_format fmt, int precision) noexcept;

#ifdef BOOST_DECIMAL_HAS_STD_CHARCONV

template <typename DecimalType>
BOOST_DECIMAL_CONSTEXPR std::to_chars_result to_chars(char* first, char* last, DecimalType value, std::chars_format fmt) noexcept;

template <typename DecimalType>
BOOST_DECIMAL_CONSTEXPR std::to_chars_result to_chars(char* first, char* last, DecimalType value, std::chars_format fmt, int precision) noexcept;

#endif // BOOST_DECIMAL_HAS_STD_CHARCONV

} //namespace decimal
} //namespace boost

All to_chars functions ignore the effects of cohorts, and instead output normalized values.

BOOST_DECIMAL_CONSTEXPR is defined if:
  • _MSC_FULL_VER >= 192528326

  • __GNUC__ >= 9

  • Compiler has: __builtin_is_constant_evaluated()

  • C++20 support with: std::is_constant_evaluated()

Same as from_chars, boost::decimal::to_chars will return a std::to_chars_result if std::chars_format is used to specify the format; otherwise it returns a boost::decimal::to_chars_result.

The library offers an additional feature for sizing buffers without specified precision and in general format

limits

#include <boost/decimal/charconv.hpp>

namespace boost {
namespace decimal {

template <typename T>
struct limits
{
    static constexpr int max_chars;
}

} //namespace decimal
} //namespace boost

The member can then be used to size buffers such as:

#include <boost/decimal.hpp>
#include <iostream>

int main()
{
    using namespace boost::decimal;

    decimal32_t val {5, -1};

    char buffer[limits<T>::max_chars];

    auto r_to = to_chars(buffer, buffer + sizeof(buffer), val);
    *r_to.ptr = '\0';

    std::cout << buffer << std::endl;

    return 0;
}