From 22a1de25022be88a7541232f76150acdd75025b1 Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Mon, 15 Jul 2024 08:26:54 +0800 Subject: [PATCH] remove_const from value_type of Range::value_type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit in general, value_type in a range-alike type should not be qualified with const specifier. the `reference` type does. before this change, when formatting `StringPiece`, fmt 11 does not consider it as a formattable type, as it falls into the string-alike category, but its value_type is `const char` which is different from the `Char` type of the context, which is `char` when formatting using `fmt::format("{}", ipSlashCidr)`. hence we have the build failure like: ``` /usr/include/fmt/base.h: In instantiation of ‘constexpr fmt::v11::detail::value fmt::v11::detail::make_arg(T&) [with bool PACKED = true; Context = fmt::v11::context; T = folly::Range; typename std::enable_if::type = 0]’: /usr/include/fmt/base.h:2002:74: required from ‘constexpr fmt::v11::detail::format_arg_store fmt::v11::make_format_args(T& ...) [with Context = context; T = {folly::Range}; long unsigned int NUM_ARGS = 1; long unsigned int NUM_NAMED_ARGS = 0; long long unsigned int DESC = 15; typename std::enable_if<(NUM_NAMED_ARGS == 0), int>::type = 0]’ 2002 | return {{detail::make_arg( | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ 2003 | args)...}}; | ~~~~~ /usr/include/fmt/format.h:4357:44: required from ‘std::string fmt::v11::format(format_string, T&& ...) [with T = {folly::Range&}; std::string = std::__cxx11::basic_string; format_string = basic_format_string&>]’ 4357 | return vformat(fmt, fmt::make_format_args(args...)); | ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~ /home/kefu/folly/folly/IPAddress.cpp:100:47: required from here 100 | throw IPAddressFormatException(fmt::format( | ~~~~~~~~~~~^ 101 | "Invalid ipSlashCidr specified. Expected IP/CIDR format, got '{}'", | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 102 | ipSlashCidr)); | ~~~~~~~~~~~~ /usr/include/fmt/base.h:1611:17: error: static assertion failed: Mixing character types is disallowed. 1611 | static_assert(formattable_char, "Mixing character types is disallowed."); | ^~~~~~~~~~~~~~~~ /usr/include/fmt/base.h:1611:17: note: ‘formattable_char’ evaluates to false /usr/include/fmt/base.h: In instantiation of ‘constexpr fmt::v11::detail::value fmt::v11::detail::make_arg(T&) [with bool PACKED = true; Context = fmt::v11::context; T = const folly::Range; typename std::enable_if::type = 0]’: /usr/include/fmt/base.h:2002:74: required from ‘constexpr fmt::v11::detail::format_arg_store fmt::v11::make_format_args(T& ...) [with Context = context; T = {const folly::Range}; long unsigned int NUM_ARGS = 1; long unsigned int NUM_NAMED_ARGS = 0; long long unsigned int DESC = 15; typename std::enable_if<(NUM_NAMED_ARGS == 0), int>::type = 0]’ 2002 | return {{detail::make_arg( | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ 2003 | args)...}}; | ~~~~~ /usr/include/fmt/format.h:4357:44: required from ‘std::string fmt::v11::format(format_string, T&& ...) [with T = {const folly::Range&}; std::string = std::__cxx11::basic_string; format_string = basic_format_string&>]’ 4357 | return vformat(fmt, fmt::make_format_args(args...)); | ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~ /home/kefu/folly/folly/IPAddress.cpp:113:22: required from here 113 | fmt::format("Invalid IP address {}", vec.at(0))); | ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /usr/include/fmt/base.h:1611:17: error: static assertion failed: Mixing character types is disallowed. 1611 | static_assert(formattable_char, "Mixing character types is disallowed."); | ^~~~~~~~~~~~~~~~ /usr/include/fmt/base.h:1611:17: note: ‘formattable_char’ evaluates to false ``` in this change, we use the non-const value type, and update the some methods where the `reference` type is supposed to be used. Fixes #2172 Signed-off-by: Kefu Chai --- folly/Range.h | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/folly/Range.h b/folly/Range.h index 1e826c37740..f46d5603f8a 100644 --- a/folly/Range.h +++ b/folly/Range.h @@ -247,8 +247,7 @@ class Range { using size_type = std::size_t; using iterator = Iter; using const_iterator = Iter; - using value_type = typename std::remove_reference< - typename std::iterator_traits::reference>::type; + using value_type = typename std::iterator_traits::value_type; using difference_type = typename std::iterator_traits::difference_type; using reference = typename std::iterator_traits::reference; @@ -592,11 +591,11 @@ class Range { constexpr Iter end() const { return e_; } constexpr Iter cbegin() const { return b_; } constexpr Iter cend() const { return e_; } - value_type& front() { + reference front() { assert(b_ < e_); return *b_; } - value_type& back() { + reference back() { assert(b_ < e_); return *std::prev(e_); } @@ -745,7 +744,8 @@ class Range { return r; } - value_type& operator[](size_t i) { + std::enable_if_t::value, reference> + operator[](size_t i) { assert(i < size()); return b_[i]; } @@ -755,7 +755,8 @@ class Range { return b_[i]; } - value_type& at(size_t i) { + std::enable_if_t::value, reference> + at(size_t i) { if (i >= size()) { throw_exception("index out of range"); }