From dfffa4dc71e5587809da3c85a6f468073d65ed69 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Sun, 4 Oct 2020 00:00:53 +0300 Subject: [PATCH] utils: big_decimal: work around clang difficulty with boost::cpp_int(string_view) constructor Clang has some difficulty with the boost::cpp_int constructor from string_view. In fact it is a mess of enable_if<>s so a human would have trouble too. Work around it by converting to std::string. This is bad for performance, but this constructor is not going to be fast in any case. Hopefully a fix will arrive in clang or boost. Closes #7389 --- utils/big_decimal.cc | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/utils/big_decimal.cc b/utils/big_decimal.cc index cdbf644761..cd71529e71 100644 --- a/utils/big_decimal.cc +++ b/utils/big_decimal.cc @@ -26,6 +26,21 @@ #include +#ifdef __clang__ + +// Clang or boost have a problem navigating the enable_if maze +// that is cpp_int's constructor. It ends up treating the +// string_view as binary and "0" ends up 48. + +// Work around by casting to string. +using string_view_workaround = std::string; + +#else + +using string_view_workaround = std::string_view; + +#endif + uint64_t from_varint_to_integer(const utils::multiprecision_int& varint) { // The behavior CQL expects on overflow is for values to wrap // around. For cpp_int conversion functions, the behavior is to @@ -70,7 +85,7 @@ big_decimal::big_decimal(sstring_view text) integer.remove_prefix(std::min(integer.find_first_not_of("0"), integer.size() - 1)); try { - _unscaled_value = boost::multiprecision::cpp_int(integer); + _unscaled_value = boost::multiprecision::cpp_int(string_view_workaround(integer)); } catch (...) { throw marshal_exception(format("big_decimal - failed to parse integer value: {}", integer)); }