Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions include/fmt/color.h
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ template <typename Char> inline void reset_color(buffer<Char>& buffer) {
template <typename T> struct styled_arg : view {
const T& value;
text_style style;
styled_arg(const T& v, text_style s) : value(v), style(s) {}
FMT_CONSTEXPR styled_arg(const T& v, text_style s) : value(v), style(s) {}
};

template <typename Char>
Expand Down Expand Up @@ -583,8 +583,8 @@ inline auto format_to(OutputIt out, text_style ts, format_string<T...> fmt,
template <typename T, typename Char>
struct formatter<detail::styled_arg<T>, Char> : formatter<T, Char> {
template <typename FormatContext>
auto format(const detail::styled_arg<T>& arg, FormatContext& ctx) const
-> decltype(ctx.out()) {
FMT_CONSTEXPR auto format(const detail::styled_arg<T>& arg,
FormatContext& ctx) const -> decltype(ctx.out()) {
const auto& ts = arg.style;
auto out = ctx.out();

Expand Down
2 changes: 1 addition & 1 deletion include/fmt/format.h
Original file line number Diff line number Diff line change
Expand Up @@ -3888,7 +3888,7 @@ template <typename OutputIt, typename Char> class generic_context {

constexpr auto out() const -> iterator { return out_; }

void advance_to(iterator it) {
FMT_CONSTEXPR void advance_to(iterator it) {
if (!detail::is_back_insert_iterator<iterator>()) out_ = it;
}

Expand Down
34 changes: 20 additions & 14 deletions include/fmt/ranges.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,12 @@ struct has_member_fn_begin_end_t<T, void_t<decltype(*std::declval<T>().begin()),

// Member function overloads.
template <typename T>
auto range_begin(T&& rng) -> decltype(static_cast<T&&>(rng).begin()) {
FMT_CONSTEXPR auto range_begin(T&& rng)
-> decltype(static_cast<T&&>(rng).begin()) {
return static_cast<T&&>(rng).begin();
}
template <typename T>
auto range_end(T&& rng) -> decltype(static_cast<T&&>(rng).end()) {
FMT_CONSTEXPR auto range_end(T&& rng) -> decltype(static_cast<T&&>(rng).end()) {
return static_cast<T&&>(rng).end();
}

Expand Down Expand Up @@ -460,7 +461,8 @@ struct range_formatter<
}

template <typename R, typename FormatContext>
auto format(R&& range, FormatContext& ctx) const -> decltype(ctx.out()) {
FMT_CONSTEXPR auto format(R&& range, FormatContext& ctx) const
-> decltype(ctx.out()) {
auto out = ctx.out();
auto it = detail::range_begin(range);
auto end = detail::range_end(range);
Expand Down Expand Up @@ -516,7 +518,7 @@ struct formatter<
}

template <typename FormatContext>
auto format(range_type& range, FormatContext& ctx) const
FMT_CONSTEXPR auto format(range_type& range, FormatContext& ctx) const
-> decltype(ctx.out()) {
return range_formatter_.format(range, ctx);
}
Expand Down Expand Up @@ -625,7 +627,7 @@ struct join_view : detail::view {
Sentinel end;
basic_string_view<Char> sep;

join_view(It b, Sentinel e, basic_string_view<Char> s)
FMT_CONSTEXPR join_view(It b, Sentinel e, basic_string_view<Char> s)
: begin(std::move(b)), end(e), sep(s) {}
};

Expand All @@ -652,7 +654,8 @@ struct formatter<join_view<It, Sentinel, Char>, Char> {
}

template <typename FormatContext>
auto format(view& value, FormatContext& ctx) const -> decltype(ctx.out()) {
FMT_CONSTEXPR auto format(view& value, FormatContext& ctx) const
-> decltype(ctx.out()) {
using iter =
conditional_t<std::is_copy_constructible<view>::value, It, It&>;
iter it = value.begin;
Expand All @@ -675,7 +678,7 @@ template <typename Tuple, typename Char> struct tuple_join_view : detail::view {
const Tuple& tuple;
basic_string_view<Char> sep;

tuple_join_view(const Tuple& t, basic_string_view<Char> s)
FMT_CONSTEXPR tuple_join_view(const Tuple& t, basic_string_view<Char> s)
: tuple(t), sep{s} {}
};

Expand All @@ -694,8 +697,9 @@ struct formatter<tuple_join_view<Tuple, Char>, Char,
}

template <typename FormatContext>
auto format(const tuple_join_view<Tuple, Char>& value,
FormatContext& ctx) const -> typename FormatContext::iterator {
FMT_CONSTEXPR auto format(const tuple_join_view<Tuple, Char>& value,
FormatContext& ctx) const ->
typename FormatContext::iterator {
return do_format(value, ctx, std::tuple_size<Tuple>());
}

Expand Down Expand Up @@ -726,15 +730,17 @@ struct formatter<tuple_join_view<Tuple, Char>, Char,
}

template <typename FormatContext>
auto do_format(const tuple_join_view<Tuple, Char>&, FormatContext& ctx,
std::integral_constant<size_t, 0>) const ->
FMT_CONSTEXPR auto do_format(const tuple_join_view<Tuple, Char>&,
FormatContext& ctx,
std::integral_constant<size_t, 0>) const ->
typename FormatContext::iterator {
return ctx.out();
}

template <typename FormatContext, size_t N>
auto do_format(const tuple_join_view<Tuple, Char>& value, FormatContext& ctx,
std::integral_constant<size_t, N>) const ->
FMT_CONSTEXPR auto do_format(const tuple_join_view<Tuple, Char>& value,
FormatContext& ctx,
std::integral_constant<size_t, N>) const ->
typename FormatContext::iterator {
using std::get;
auto out =
Expand Down Expand Up @@ -813,7 +819,7 @@ auto join(It begin, Sentinel end, string_view sep) -> join_view<It, Sentinel> {
* // Output: 01, 02, 03
*/
template <typename Range, FMT_ENABLE_IF(!is_tuple_like<Range>::value)>
auto join(Range&& r, string_view sep)
FMT_CONSTEXPR auto join(Range&& r, string_view sep)
-> join_view<decltype(detail::range_begin(r)),
decltype(detail::range_end(r))> {
return {detail::range_begin(r), detail::range_end(r), sep};
Expand Down
15 changes: 8 additions & 7 deletions include/fmt/std.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,8 @@ void write_escaped_path(basic_memory_buffer<Char>& quoted,
#if defined(__cpp_lib_expected) || FMT_CPP_LIB_VARIANT

template <typename Char, typename OutputIt, typename T, typename FormatContext>
auto write_escaped_alternative(OutputIt out, const T& v, FormatContext& ctx)
-> OutputIt {
FMT_CONSTEXPR auto write_escaped_alternative(OutputIt out, const T& v,
FormatContext& ctx) -> OutputIt {
if constexpr (has_to_string_view<T>::value)
return write_escaped_string<Char>(out, detail::to_string_view(v));
if constexpr (std::is_same_v<T, Char>) return write_escaped_char(out, v);
Expand Down Expand Up @@ -508,7 +508,7 @@ template <typename Char> struct formatter<std::monostate, Char> {
}

template <typename FormatContext>
auto format(const std::monostate&, FormatContext& ctx) const
FMT_CONSTEXPR auto format(const std::monostate&, FormatContext& ctx) const
-> decltype(ctx.out()) {
return detail::write<Char>(ctx.out(), "monostate");
}
Expand All @@ -524,7 +524,7 @@ struct formatter<Variant, Char,
}

template <typename FormatContext>
auto format(const Variant& value, FormatContext& ctx) const
FMT_CONSTEXPR20 auto format(const Variant& value, FormatContext& ctx) const
-> decltype(ctx.out()) {
auto out = ctx.out();

Expand Down Expand Up @@ -635,7 +635,7 @@ struct formatter<
}

template <typename Context>
auto format(const std::exception& ex, Context& ctx) const
FMT_CONSTEXPR auto format(const std::exception& ex, Context& ctx) const
-> decltype(ctx.out()) {
auto out = ctx.out();
#if FMT_USE_RTTI
Expand Down Expand Up @@ -690,11 +690,12 @@ struct formatter<BitRef, Char,
#ifdef __cpp_lib_byte
template <typename Char>
struct formatter<std::byte, Char> : formatter<unsigned, Char> {
static auto format_as(std::byte b) -> unsigned char {
FMT_CONSTEXPR static auto format_as(std::byte b) -> unsigned char {
return static_cast<unsigned char>(b);
}
template <typename Context>
auto format(std::byte b, Context& ctx) const -> decltype(ctx.out()) {
FMT_CONSTEXPR auto format(std::byte b, Context& ctx) const
-> decltype(ctx.out()) {
return formatter<unsigned, Char>::format(format_as(b), ctx);
}
};
Expand Down
17 changes: 16 additions & 1 deletion test/compile-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@

#include "fmt/compile.h"

#include <array>
#include <iterator>
#include <list>
#include <type_traits>
#include <vector>

#include "fmt/chrono.h"
#include "fmt/color.h"
#include "fmt/ranges.h"
#include "fmt/std.h"
#include "gmock/gmock.h"
#include "gtest-extra.h"

Expand Down Expand Up @@ -87,7 +90,6 @@ TEST(compile_test, format_escape) {
EXPECT_EQ("\"abc\" ", fmt::format(FMT_COMPILE("{0:<7?}"), "abc"));
}


TEST(compile_test, format_specs) {
EXPECT_EQ("42", fmt::format(FMT_COMPILE("{:x}"), 0x42));
EXPECT_EQ("1.2 ms ",
Expand Down Expand Up @@ -224,6 +226,19 @@ TEST(compile_test, constexpr_formatted_size) {
FMT_CONSTEXPR20 size_t str_size =
fmt::formatted_size(FMT_COMPILE("{:s}"), "abc");
EXPECT_EQ(str_size, 3);
FMT_CONSTEXPR20 size_t tuple_size = fmt::formatted_size(
FMT_COMPILE("{}"), fmt::join(std::tuple(1, 2, 3), ","));
EXPECT_EQ(tuple_size, 5);
FMT_CONSTEXPR20 size_t array_size = fmt::formatted_size(
FMT_COMPILE("{}"), fmt::join(std::array<int, 3>{1, 2, 3}, ","));
EXPECT_EQ(array_size, 5);
FMT_CONSTEXPR20 size_t styled_size = fmt::formatted_size(
FMT_COMPILE("{}"),
fmt::styled(std::array{1, 2, 3}, fmt::bg(fmt::color::green)));
EXPECT_EQ(styled_size, 32);
FMT_CONSTEXPR20 size_t variant_size = fmt::formatted_size(
FMT_COMPILE("{}"), std::variant<std::monostate, char>{});
EXPECT_EQ(variant_size, 18);
}

TEST(compile_test, static_format) {
Expand Down
Loading