Skip to content

Commit fd93b63

Browse files
Constexpr formatted_size (fmtlib#3026)
* Constexpr formatted_size * Add C++20 tests for gcc 9 and 10 * Adjust unit test to require __cpp_lib_bit_cast
1 parent 7fb8d33 commit fd93b63

File tree

3 files changed

+17
-13
lines changed

3 files changed

+17
-13
lines changed

include/fmt/compile.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ FMT_BEGIN_NAMESPACE
1414
namespace detail {
1515

1616
template <typename Char, typename InputIt>
17-
inline counting_iterator copy_str(InputIt begin, InputIt end,
17+
FMT_CONSTEXPR inline counting_iterator copy_str(InputIt begin, InputIt end,
1818
counting_iterator it) {
1919
return it + (end - begin);
2020
}
@@ -568,7 +568,7 @@ format_to_n_result<OutputIt> format_to_n(OutputIt out, size_t n,
568568

569569
template <typename S, typename... Args,
570570
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
571-
size_t formatted_size(const S& format_str, const Args&... args) {
571+
FMT_CONSTEXPR20 size_t formatted_size(const S& format_str, const Args&... args) {
572572
return fmt::format_to(detail::counting_iterator(), format_str, args...)
573573
.count();
574574
}

include/fmt/format.h

+8-8
Original file line numberDiff line numberDiff line change
@@ -1231,7 +1231,7 @@ FMT_CONSTEXPR20 auto format_decimal(Char* out, UInt value, int size)
12311231

12321232
template <typename Char, typename UInt, typename Iterator,
12331233
FMT_ENABLE_IF(!std::is_pointer<remove_cvref_t<Iterator>>::value)>
1234-
inline auto format_decimal(Iterator out, UInt value, int size)
1234+
FMT_CONSTEXPR inline auto format_decimal(Iterator out, UInt value, int size)
12351235
-> format_decimal_result<Iterator> {
12361236
// Buffer is large enough to hold all digits (digits10 + 1).
12371237
Char buffer[digits10<UInt>() + 1];
@@ -2137,29 +2137,29 @@ class counting_iterator {
21372137
FMT_UNCHECKED_ITERATOR(counting_iterator);
21382138

21392139
struct value_type {
2140-
template <typename T> void operator=(const T&) {}
2140+
template <typename T> FMT_CONSTEXPR void operator=(const T&) {}
21412141
};
21422142

2143-
counting_iterator() : count_(0) {}
2143+
FMT_CONSTEXPR counting_iterator() : count_(0) {}
21442144

2145-
size_t count() const { return count_; }
2145+
FMT_CONSTEXPR size_t count() const { return count_; }
21462146

2147-
counting_iterator& operator++() {
2147+
FMT_CONSTEXPR counting_iterator& operator++() {
21482148
++count_;
21492149
return *this;
21502150
}
2151-
counting_iterator operator++(int) {
2151+
FMT_CONSTEXPR counting_iterator operator++(int) {
21522152
auto it = *this;
21532153
++*this;
21542154
return it;
21552155
}
21562156

2157-
friend counting_iterator operator+(counting_iterator it, difference_type n) {
2157+
FMT_CONSTEXPR friend counting_iterator operator+(counting_iterator it, difference_type n) {
21582158
it.count_ += static_cast<size_t>(n);
21592159
return it;
21602160
}
21612161

2162-
value_type operator*() const { return {}; }
2162+
FMT_CONSTEXPR value_type operator*() const { return {}; }
21632163
};
21642164

21652165
template <typename Char, typename OutputIt>

test/compile-test.cc

+7-3
Original file line numberDiff line numberDiff line change
@@ -227,10 +227,14 @@ TEST(compile_test, format_to_n) {
227227
EXPECT_STREQ("2a", buffer);
228228
}
229229

230-
TEST(compile_test, formatted_size) {
231-
EXPECT_EQ(2, fmt::formatted_size(FMT_COMPILE("{0}"), 42));
232-
EXPECT_EQ(5, fmt::formatted_size(FMT_COMPILE("{0:<4.2f}"), 42.0));
230+
#ifdef __cpp_lib_bit_cast
231+
TEST(compile_test, constexpr_formatted_size) {
232+
FMT_CONSTEXPR20 size_t s1 = fmt::formatted_size(FMT_COMPILE("{0}"), 42);
233+
EXPECT_EQ(2, s1);
234+
FMT_CONSTEXPR20 size_t s2 = fmt::formatted_size(FMT_COMPILE("{0:<4.2f}"), 42.0);
235+
EXPECT_EQ(5, s2);
233236
}
237+
#endif
234238

235239
TEST(compile_test, text_and_arg) {
236240
EXPECT_EQ(">>>42<<<", fmt::format(FMT_COMPILE(">>>{}<<<"), 42));

0 commit comments

Comments
 (0)