Skip to content

Commit

Permalink
Restore constexpr fmt::formatted_size for C++20
Browse files Browse the repository at this point in the history
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
  • Loading branch information
phprus committed Jul 24, 2024
1 parent 52b3208 commit a1804fa
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 15 deletions.
25 changes: 15 additions & 10 deletions include/fmt/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,8 @@ struct is_back_insert_iterator<

// Extracts a reference to the container from *insert_iterator.
template <typename OutputIt>
inline auto get_container(OutputIt it) -> typename OutputIt::container_type& {
FMT_CONSTEXPR20 inline auto get_container(OutputIt it) ->
typename OutputIt::container_type& {
struct accessor : OutputIt {
accessor(OutputIt base) : OutputIt(base) {}
using OutputIt::container;
Expand Down Expand Up @@ -924,7 +925,8 @@ template <typename T> class buffer {
}

/// Appends data to the end of the buffer.
template <typename U> void append(const U* begin, const U* end) {
template <typename U>
FMT_CONSTEXPR void append(const U* begin, const U* end) {
while (begin != end) {
auto count = to_unsigned(end - begin);
try_reserve(size_ + count);
Expand Down Expand Up @@ -1105,7 +1107,7 @@ template <typename T = char> class counting_buffer : public buffer<T> {
public:
FMT_CONSTEXPR counting_buffer() : buffer<T>(grow, data_, 0, buffer_size) {}

auto count() -> size_t { return count_ + this->size(); }
constexpr auto count() const -> size_t { return count_ + this->size(); }
};
} // namespace detail

Expand Down Expand Up @@ -1155,7 +1157,8 @@ template <typename T> class basic_appender {
private:
detail::buffer<T>* buffer_;

friend auto get_container(basic_appender app) -> detail::buffer<T>& {
friend constexpr auto get_container(basic_appender app)
-> detail::buffer<T>& {
return *app.buffer_;
}

Expand All @@ -1170,13 +1173,13 @@ template <typename T> class basic_appender {

FMT_CONSTEXPR basic_appender(detail::buffer<T>& buf) : buffer_(&buf) {}

auto operator=(T c) -> basic_appender& {
FMT_CONSTEXPR auto operator=(T c) -> basic_appender& {
buffer_->push_back(c);
return *this;
}
auto operator*() -> basic_appender& { return *this; }
auto operator++() -> basic_appender& { return *this; }
auto operator++(int) -> basic_appender { return *this; }
FMT_CONSTEXPR auto operator*() -> basic_appender& { return *this; }
FMT_CONSTEXPR auto operator++() -> basic_appender& { return *this; }
FMT_CONSTEXPR auto operator++(int) -> basic_appender { return *this; }
};

using appender = basic_appender<char>;
Expand All @@ -1188,7 +1191,7 @@ struct is_back_insert_iterator<basic_appender<T>> : std::true_type {};
// An optimized version of std::copy with the output value type (T).
template <typename T, typename InputIt, typename OutputIt,
FMT_ENABLE_IF(is_back_insert_iterator<OutputIt>::value)>
auto copy(InputIt begin, InputIt end, OutputIt out) -> OutputIt {
FMT_CONSTEXPR auto copy(InputIt begin, InputIt end, OutputIt out) -> OutputIt {
get_container(out).append(begin, end);
return out;
}
Expand Down Expand Up @@ -2898,7 +2901,9 @@ template <typename Char, typename... Args> class basic_format_string {
}
basic_format_string(runtime_format_string<Char> fmt) : str_(fmt.str) {}

FMT_ALWAYS_INLINE operator basic_string_view<Char>() const { return str_; }
FMT_ALWAYS_INLINE constexpr operator basic_string_view<Char>() const {
return str_;
}
auto get() const -> basic_string_view<Char> { return str_; }
};

Expand Down
3 changes: 2 additions & 1 deletion include/fmt/compile.h
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,8 @@ auto format_to_n(OutputIt out, size_t n, const S& fmt, Args&&... args)

template <typename S, typename... Args,
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
auto formatted_size(const S& fmt, const Args&... args) -> size_t {
FMT_CONSTEXPR20 auto formatted_size(const S& fmt, const Args&... args)
-> size_t {
auto buf = detail::counting_buffer<>();
fmt::format_to(appender(buf), fmt, args...);
return buf.count();
Expand Down
8 changes: 5 additions & 3 deletions include/fmt/format.h
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@ template <typename OutputIt,
#if FMT_CLANG_VERSION >= 307 && !FMT_ICC_VERSION
__attribute__((no_sanitize("undefined")))
#endif
inline auto
FMT_CONSTEXPR20 inline auto
reserve(OutputIt it, size_t n) -> typename OutputIt::value_type* {
auto& c = get_container(it);
size_t size = c.size();
Expand All @@ -531,7 +531,8 @@ reserve(OutputIt it, size_t n) -> typename OutputIt::value_type* {
}

template <typename T>
inline auto reserve(basic_appender<T> it, size_t n) -> basic_appender<T> {
FMT_CONSTEXPR20 inline auto reserve(basic_appender<T> it, size_t n)
-> basic_appender<T> {
buffer<T>& buf = get_container(it);
buf.try_reserve(buf.size() + n);
return it;
Expand All @@ -550,7 +551,8 @@ template <typename T, typename OutputIt>
constexpr auto to_pointer(OutputIt, size_t) -> T* {
return nullptr;
}
template <typename T> auto to_pointer(basic_appender<T> it, size_t n) -> T* {
template <typename T>
FMT_CONSTEXPR20 auto to_pointer(basic_appender<T> it, size_t n) -> T* {
buffer<T>& buf = get_container(it);
auto size = buf.size();
buf.try_reserve(size + n);
Expand Down
2 changes: 1 addition & 1 deletion test/compile-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ TEST(compile_test, format_to_n) {
EXPECT_STREQ("2a", buffer);
}

# if 0
# if FMT_USE_CONSTEVAL
TEST(compile_test, constexpr_formatted_size) {
FMT_CONSTEXPR20 size_t size = fmt::formatted_size(FMT_COMPILE("{}"), 42);
EXPECT_EQ(size, 2);
Expand Down

0 comments on commit a1804fa

Please sign in to comment.