Skip to content

Commit

Permalink
Cleanup base API
Browse files Browse the repository at this point in the history
  • Loading branch information
vitaut committed Sep 2, 2024
1 parent 9ef160d commit 60740b7
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 32 deletions.
30 changes: 13 additions & 17 deletions include/fmt/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,8 @@ inline FMT_CONSTEXPR20 auto get_container(OutputIt it) ->
}
} // namespace detail

FMT_BEGIN_EXPORT

// Checks whether T is a container with contiguous storage.
template <typename T> struct is_contiguous : std::false_type {};

Expand All @@ -539,7 +541,6 @@ template <typename T> struct is_contiguous : std::false_type {};
* compiled with a different `-std` option than the client code (which is not
* recommended).
*/
FMT_EXPORT
template <typename Char> class basic_string_view {
private:
const Char* data_;
Expand Down Expand Up @@ -633,7 +634,7 @@ template <typename Char> class basic_string_view {
}
};

FMT_EXPORT using string_view = basic_string_view<char>;
using string_view = basic_string_view<char>;

/// Specifies if `T` is a character type. Can be specialized by users.
template <typename T> struct is_char : std::false_type {};
Expand All @@ -657,28 +658,21 @@ using buffered_context =
conditional_t<std::is_same<Char, char>::value, context,
generic_context<basic_appender<Char>, Char>>;

FMT_EXPORT template <typename Context> class basic_format_arg;
FMT_EXPORT template <typename Context> class basic_format_args;
FMT_EXPORT template <typename Context> class dynamic_format_arg_store;
template <typename Context> class basic_format_arg;
template <typename Context> class basic_format_args;
template <typename Context> class dynamic_format_arg_store;

// A separate type would result in shorter symbols but break ABI compatibility
// between clang and gcc on ARM (#1919).
using format_args = basic_format_args<context>;

// A formatter for objects of type T.
FMT_EXPORT
template <typename T, typename Char = char, typename Enable = void>
struct formatter {
// A deleted default constructor indicates a disabled formatter.
formatter() = delete;
};

// Specifies if T has an enabled formatter specialization. A type can be
// formattable even if it doesn't have a formatter e.g. via a conversion.
template <typename T, typename Context>
using has_formatter =
std::is_constructible<typename Context::template formatter_type<T>>;

// This is defined in base.h instead of format.h to avoid injecting in std.
// It is a template to avoid undesirable implicit conversions to std::byte.
#ifdef __cpp_lib_byte
Expand All @@ -688,6 +682,8 @@ inline auto format_as(T b) -> unsigned char {
}
#endif

FMT_END_EXPORT

namespace detail {

// Constructs fmt::basic_string_view<Char> from types implicitly convertible
Expand Down Expand Up @@ -1005,9 +1001,10 @@ template <typename Context> struct arg_mapper {
}

template <typename T, typename U = remove_const_t<T>>
struct formattable : bool_constant<has_const_formatter<U, Context>() ||
(has_formatter<U, Context>::value &&
!std::is_const<T>::value)> {};
struct formattable
: bool_constant<has_const_formatter<U, Context>() ||
(std::is_constructible<formatter<U, char_type>>::value &&
!std::is_const<T>::value)> {};

template <typename T, FMT_ENABLE_IF(formattable<T>::value)>
FMT_MAP_API auto do_map(T& val) -> T& {
Expand Down Expand Up @@ -1790,8 +1787,7 @@ struct compile_string {};
template <typename T, typename Char>
FMT_VISIBILITY("hidden") // Suppress an ld warning on macOS (#3769).
FMT_CONSTEXPR auto invoke_parse(parse_context<Char>& ctx) -> const Char* {
using mapper = arg_mapper<buffered_context<Char>>;
using mapped_type = remove_cvref_t<decltype(mapper::map(std::declval<T&>()))>;
using mapped_type = remove_cvref_t<mapped_t<T, Char>>;
#if defined(__cpp_if_constexpr)
if constexpr (std::is_default_constructible<formatter<mapped_type, Char>>())
return formatter<mapped_type, Char>().parse(ctx);
Expand Down
9 changes: 7 additions & 2 deletions include/fmt/ranges.h
Original file line number Diff line number Diff line change
Expand Up @@ -358,16 +358,21 @@ template <typename T, typename Char> struct is_range {
};

namespace detail {

template <typename T, typename Char>
using has_formatter = std::is_constructible<formatter<T, Char>>;

template <typename Context> struct range_mapper {
using mapper = arg_mapper<Context>;
using char_type = typename Context::char_type;

template <typename T,
FMT_ENABLE_IF(has_formatter<remove_cvref_t<T>, Context>::value)>
FMT_ENABLE_IF(has_formatter<remove_cvref_t<T>, char_type>::value)>
static auto map(T&& value) -> T&& {
return static_cast<T&&>(value);
}
template <typename T,
FMT_ENABLE_IF(!has_formatter<remove_cvref_t<T>, Context>::value)>
FMT_ENABLE_IF(!has_formatter<remove_cvref_t<T>, char_type>::value)>
static auto map(T&& value) -> decltype(mapper::map(static_cast<T&&>(value))) {
return mapper::map(static_cast<T&&>(value));
}
Expand Down
9 changes: 0 additions & 9 deletions test/base-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -604,15 +604,6 @@ template <> struct formatter<enabled_ptr_formatter*> {
};
FMT_END_NAMESPACE

TEST(base_test, has_formatter) {
using fmt::has_formatter;
using context = fmt::format_context;
static_assert(has_formatter<enabled_formatter, context>::value, "");
static_assert(!has_formatter<disabled_formatter, context>::value, "");
static_assert(!has_formatter<disabled_formatter_convertible, context>::value,
"");
}

struct const_formattable {};
struct nonconst_formattable {};

Expand Down
4 changes: 2 additions & 2 deletions test/format-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2022,8 +2022,8 @@ TEST(format_test, named_arg_udl) {
TEST(format_test, enum) { EXPECT_EQ(fmt::format("{}", foo), "0"); }

TEST(format_test, formatter_not_specialized) {
static_assert(!fmt::has_formatter<fmt::formatter<test_enum>,
fmt::format_context>::value,
static_assert(!fmt::is_formattable<fmt::formatter<test_enum>,
fmt::format_context>::value,
"");
}

Expand Down
3 changes: 1 addition & 2 deletions test/ranges-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -363,8 +363,7 @@ TEST(ranges_test, enum_range) {

#if !FMT_MSC_VERSION
TEST(ranges_test, unformattable_range) {
EXPECT_FALSE((fmt::has_formatter<std::vector<unformattable>,
fmt::format_context>::value));
EXPECT_FALSE((fmt::is_formattable<std::vector<unformattable>, char>::value));
}
#endif

Expand Down

0 comments on commit 60740b7

Please sign in to comment.