6#ifndef MIMICPP_PRINTER_HPP
7#define MIMICPP_PRINTER_HPP
20#include <source_location>
26#ifndef MIMICPP_CONFIG_USE_FMT
30#if __has_include(<fmt/format.h>)
31#include <fmt/format.h>
33 #error "The fmt formatting backend is explicitly enabled, but the include <fmt/format.h> can not be found."
40 using StringViewT = std::basic_string_view<CharT, CharTraitsT>;
46 template <
typename Pr
inter,
typename OutIter,
typename T>
48 &&
requires(OutIter out)
51 Printer::print(out, std::declval<T&&>())
52 } -> std::convertible_to<OutIter>;
58#ifndef MIMICPP_CONFIG_USE_FMT
61#ifndef _LIBCPP_VERSION
67 using std::vformat_to;
68 using std::make_format_args;
77 using std::vformat_to;
78 using std::make_format_args;
80 template <
typename... Args>
84 return format::vformat(
86 std::make_format_args(args...));
89 template <
class OutputIt,
typename... Args>
90 OutputIt format_to(
const OutputIt out,
const StringViewT fmt, Args&&... args)
92 return format::vformat_to(
95 std::make_format_args(args...));
102 template <
typename Char>
103 struct format_context;
105 template <
typename Char>
106 using format_context_t =
typename format_context<Char>::type;
109 struct format_context<char>
111 using type = std::format_context;
115 struct format_context<wchar_t>
117 using type = std::wformat_context;
130 template <
class T,
class Char>
131 concept formattable =
132 std::semiregular<std::formatter<std::remove_cvref_t<T>, Char>>
134 std::formatter<std::remove_cvref_t<T>, Char> formatter,
136 format_context_t<Char> formatContext,
137 std::basic_format_parse_context<Char> parseContext
140 { formatter.parse(parseContext) } -> std::same_as<typename std::basic_format_parse_context<Char>::iterator>;
142 std::as_const(formatter).format(t, formatContext)
143 } -> std::same_as<
typename std::remove_reference_t<
decltype(formatContext)>::iterator>;
150 using fmt::formatter;
152 using fmt::format_to;
154 using fmt::vformat_to;
155 using fmt::make_format_args;
159 template <
class T,
class Char>
160 concept formattable = fmt::is_formattable<std::remove_reference_t<T>, Char>::value;
168 :
public formatter<std::string_view, mimicpp::CharT>
181 case ValueCategoryT::lvalue:
return "lvalue";
182 case ValueCategoryT::rvalue:
return "rvalue";
183 case ValueCategoryT::any:
return "any";
186 throw std::invalid_argument{
"Unknown category value."};
189 return formatter<std::string_view, mimicpp::CharT>::format(
197 :
public formatter<std::string_view, mimicpp::CharT>
206 constexpr auto toString = [](
const ConstnessT value)
210 case ConstnessT::non_const:
return "mutable";
211 case ConstnessT::as_const:
return "const";
212 case ConstnessT::any:
return "any";
215 throw std::invalid_argument{
"Unknown constness value."};
218 return formatter<std::string_view, mimicpp::CharT>::format(
234namespace mimicpp::detail
246 return Printer::print(
248 std::forward<T>(value));
264 return Printer::print(
266 std::forward<T>(value));
269 template <pr
int_iterator OutIter, std::convertible_to<StringViewT> String>
273 [[maybe_unused]]
const priority_tag<3>
276 return format::format_to(
279 static_cast<StringViewT>(std::forward<String>(str)));
282 template <pr
int_iterator OutIter, std::ranges::forward_range Range>
289 template <pr
int_iterator OutIter, format::detail::formattable<CharT> T>
293 [[maybe_unused]]
const priority_tag<1>
296 return format::format_to(
299 std::forward<T>(value));
302 template <pr
int_iterator OutIter>
306 [[maybe_unused]]
const priority_tag<0>
309 return format::format_to(
317 template <pr
int_iterator OutIter,
typename T>
324 requires(
const priority_tag<6> tag)
326 {
print(out, std::forward<T>(value), tag) } -> std::convertible_to<OutIter>;
328 "The given type is not printable. ");
332 std::forward<T>(value),
336 template <
typename T>
337 StringT operator ()(T&& value)
const
342 std::ostreambuf_iterator{stream},
343 std::forward<T>(value));
344 return std::move(stream).str();
348 template <pr
int_iterator OutIter, std::ranges::forward_range Range>
352 const priority_tag<2>
355 out = format::format_to(
358 auto iter = std::ranges::begin(range);
359 if (
const auto end = std::ranges::end(range);
362 constexpr PrintFn
print{};
363 out =
print(std::move(out), *iter++);
365 for (; iter != end; ++iter)
368 format::format_to(std::move(out),
", "),
373 return format::format_to(
379 class Printer<std::source_location>
382 template <pr
int_iterator OutIter>
383 static OutIter
print(OutIter out,
const std::source_location& loc)
385 return format::format_to(
391 loc.function_name());
395 template <
typename Char>
397 struct character_literal_printer;
400 struct character_literal_printer<char>
402 template <pr
int_iterator OutIter>
403 static OutIter
print(OutIter out)
noexcept
411 struct character_literal_printer<wchar_t>
413 template <pr
int_iterator OutIter>
414 static OutIter
print(OutIter out)
416 return format::format_to(std::move(out),
"L");
421 struct character_literal_printer<char8_t>
423 template <pr
int_iterator OutIter>
424 static OutIter
print(OutIter out)
426 return format::format_to(std::move(out),
"u8");
431 struct character_literal_printer<char16_t>
433 template <pr
int_iterator OutIter>
434 static OutIter
print(OutIter out)
436 return format::format_to(std::move(out),
"u");
441 struct character_literal_printer<char32_t>
443 template <pr
int_iterator OutIter>
444 static OutIter
print(OutIter out)
446 return format::format_to(std::move(out),
"U");
450 template <
string String>
451 requires (!std::same_as<CharT, string_char_t<String>>)
452 class Printer<String>
455 template <std::common_reference_with<String> T, pr
int_iterator OutIter>
456 static OutIter
print(OutIter out, T&& str)
458 using intermediate_t = std::uint32_t;
461 out = character_literal_printer<string_char_t<String>>
::print(std::move(out));
462 out = format::format_to(std::move(out),
"\"");
464 auto view = string_traits<std::remove_cvref_t<T>>::view(std::forward<T>(str));
465 auto iter = std::ranges::begin(view);
466 if (
const auto end = std::ranges::end(view);
469 out = format::format_to(
472 static_cast<intermediate_t
>(*iter++));
474 for (; iter != end; ++iter)
476 out = format::format_to(
479 static_cast<intermediate_t
>(*iter));
483 return format::format_to(std::move(out),
"\"");
537 inline constexpr detail::PrintFn
print{};
User may add specializations, which will then be used during print calls.
Definition Printer.hpp:231
Definition Printer.hpp:44
Definition Printer.hpp:47
constexpr detail::PrintFn print
Functional object, converting the given object to its textual representation.
Definition Printer.hpp:537
constexpr bool is_character_v
Convenience boolean-constant to the result of is_character trait.
Definition String.hpp:54
typename string_traits< std::remove_cvref_t< T > >::char_t string_char_t
Computes the character type for the given string.
Definition String.hpp:144
Definition Matcher.hpp:26
Definition BoostTest.hpp:20
char CharT
Definition Fwd.hpp:110
ValueCategory
Definition Fwd.hpp:100
std::basic_ostringstream< CharT, CharTraitsT > StringStreamT
Definition Printer.hpp:41
Constness
Definition Fwd.hpp:93
std::basic_string_view< CharT, CharTraitsT > StringViewT
Definition Printer.hpp:40
std::basic_string< CharT, CharTraitsT > StringT
Definition Fwd.hpp:112
Definition Utility.hpp:32