21 #include <system_error>
23 #include "absl/status/statusor.h"
24 #include "absl/strings/charconv.h"
25 #include "absl/strings/escaping.h"
26 #include "absl/strings/str_format.h"
27 #include "absl/strings/string_view.h"
31 #define OPERATION_RESEARCH_STD_TO_CHARS_DOUBLE_SUPPORTED
32 #if defined(__wasm__) || defined(ANDROID) || defined(_MSC_VER)
33 #undef OPERATION_RESEARCH_STD_TO_CHARS_DOUBLE_SUPPORTED
35 #if defined(__APPLE__) || defined(__FreeBSD__)
36 #undef OPERATION_RESEARCH_STD_TO_CHARS_DOUBLE_SUPPORTED
38 #if defined(__GNUC__) && !defined(__llvm__) && __GNUC__ < 11
39 #undef OPERATION_RESEARCH_STD_TO_CHARS_DOUBLE_SUPPORTED
58 using RoundTripDoubleBuffer = std::array<char, 32>;
62 absl::string_view RoundTripDoubleToBuffer(
const double value,
63 RoundTripDoubleBuffer& buffer) {
64 #ifdef OPERATION_RESEARCH_STD_TO_CHARS_DOUBLE_SUPPORTED
66 std::to_chars(buffer.data(), buffer.data() + buffer.size(),
value);
67 CHECK(result.ec == std::errc()) << std::make_error_code(result.ec).message();
68 return absl::string_view(buffer.data(), result.ptr - buffer.data());
76 absl::SNPrintF(buffer.data(), buffer.size(),
"%.*g",
77 std::numeric_limits<double>::max_digits10,
value);
79 CHECK_LT(written, buffer.size());
80 return absl::string_view(buffer.data(), written);
86 #ifdef OPERATION_RESEARCH_STD_TO_CHARS_DOUBLE_SUPPORTED
92 #undef OPERATION_RESEARCH_STD_TO_CHARS_DOUBLE_SUPPORTED
96 RoundTripDoubleBuffer buffer;
97 out << RoundTripDoubleToBuffer(format.value_, buffer);
102 RoundTripDoubleBuffer buffer;
103 return std::string(RoundTripDoubleToBuffer(
value, buffer));
107 const absl::string_view str_value) {
108 const char*
const begin = str_value.data();
109 const char*
const end = begin + str_value.size();
111 const auto result = absl::from_chars(begin,
end, ret);
112 if (result.ec == std::errc()) {
113 if (result.ptr !=
end) {
115 <<
'"' << absl::CEscape(str_value)
116 <<
"\" has unexpected suffix starting at index "
117 << (result.ptr - begin);
122 case std::errc::invalid_argument:
124 <<
'"' << absl::CEscape(str_value) <<
"\" is not a valid double";
125 case std::errc::result_out_of_range:
127 <<
'"' << absl::CEscape(str_value)
128 <<
"\" does not fit in a double precision float";
131 <<
"parsing of \"" << absl::CEscape(str_value)
132 <<
"\" failed with an unexpected error: "
133 << std::make_error_code(result.ec).message();
Collection of objects used to extend the Constraint Solver library.
std::ostream & operator<<(std::ostream &out, const Assignment &assignment)
ABSL_CONST_INIT const bool kStdToCharsDoubleIsSupported
StatusBuilder InternalErrorBuilder()
StatusBuilder InvalidArgumentErrorBuilder()
std::optional< int64_t > end