6#ifndef MIMICPP_PRINTER_HPP
7#define MIMICPP_PRINTER_HPP
21#include <source_location>
27#ifndef MIMICPP_CONFIG_USE_FMT
31#if __has_include(<fmt/format.h>)
32#include <fmt/format.h>
34 #error "The fmt formatting backend is explicitly enabled, but the include <fmt/format.h> can not be found."
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::ranges::forward_range Range>
276 template <pr
int_iterator OutIter, format::detail::formattable<CharT> T>
280 [[maybe_unused]]
const priority_tag<1>
283 return format::format_to(
286 std::forward<T>(value));
289 template <pr
int_iterator OutIter>
293 [[maybe_unused]]
const priority_tag<0>
296 return format::format_to(
304 template <pr
int_iterator OutIter,
typename T>
311 requires(
const priority_tag<4> tag)
313 {
print(out, std::forward<T>(value), tag) } -> std::convertible_to<OutIter>;
315 "The given type is not printable. ");
319 std::forward<T>(value),
323 template <
typename T>
324 StringT operator ()(T&& value)
const
329 std::ostreambuf_iterator{stream},
330 std::forward<T>(value));
331 return std::move(stream).str();
335 template <pr
int_iterator OutIter, std::ranges::forward_range Range>
339 const priority_tag<2>
342 out = format::format_to(
345 auto iter = std::ranges::begin(range);
346 if (
const auto end = std::ranges::end(range);
349 constexpr PrintFn
print{};
350 out =
print(std::move(out), *iter++);
352 for (; iter != end; ++iter)
355 format::format_to(std::move(out),
", "),
360 return format::format_to(
366 class Printer<std::source_location>
369 template <pr
int_iterator OutIter>
370 static OutIter
print(OutIter out,
const std::source_location& loc)
372 return format::format_to(
378 loc.function_name());
383 class Printer<std::nullopt_t>
386 template <pr
int_iterator OutIter>
387 static OutIter
print(OutIter out, [[maybe_unused]]
const std::nullopt_t)
389 return format::format_to(
395 template <
typename T>
396 class Printer<std::optional<T>>
399 template <pr
int_iterator OutIter>
400 static OutIter
print(OutIter out,
const std::optional<T>& opt)
402 constexpr PrintFn
print{};
406 out = format::format_to(std::move(out),
"{{ value: ");
407 out =
print(std::move(out), *opt);
408 return format::format_to(std::move(out),
" }}");
410 return print(std::move(out), std::nullopt);
414 template <std::
size_t index, pr
int_iterator OutIter,
typename Tuple>
415 OutIter tuple_element_print(OutIter out, Tuple&& tuple)
417 if constexpr (0u != index)
419 out = format::format_to(std::move(out),
", ");
422 constexpr PrintFn printer{};
425 std::get<index>(std::forward<Tuple>(tuple)));
428 template <
typename T>
431 typename std::tuple_size<T>::type;
432 requires std::convertible_to<typename std::tuple_size<T>::type, std::size_t>;
433 requires 0u <= std::tuple_size_v<T>;
438 template <pr
int_iterator OutIter>
439 static OutIter
print(OutIter out,
const T& tuple)
441 out = format::format_to(std::move(out),
"{{ ");
444 [&]<std::size_t... indices>([[maybe_unused]]
const std::index_sequence<indices...>)
447 (out = tuple_element_print<indices>(std::move(out), tuple)));
449 std::make_index_sequence<std::tuple_size_v<T>>{});
451 return format::format_to(std::move(out),
" }}");
455 template <
typename T>
456 concept pointer_like = std::is_pointer_v<T>
457 || std::same_as<std::nullptr_t, T>;
459 template <po
inter_like T>
460 requires (!string<T>)
464 template <pr
int_iterator OutIter>
465 static OutIter
print(OutIter out, T ptr)
467 return format::format_to(
470 std::bit_cast<std::uintptr_t>(ptr));
474 template <
string String>
475 class Printer<String>
478 template <std::common_reference_with<String> T, pr
int_iterator OutIter>
479 static OutIter
print(OutIter out, T&& str)
482 !std::ranges::empty(prefix))
484 out = out = format::format_to(
490 out = format::format_to(std::move(out),
"\"");
495 if constexpr (std::same_as<CharT, string_char_t<String>>)
497 auto view = string_traits<String>::view(str);
498 out = format::format_to(
502 std::ranges::data(view),
503 std::ranges::size(view)
507 else if constexpr (printer_for<custom::Printer<string_char_t<String>>, OutIter,
string_char_t<String>>)
512 out = printer.print(std::move(out), c);
520 return std::bit_cast<intermediate_t>(c);
524 auto view = string_traits<std::remove_cvref_t<T>>::view(std::forward<T>(str));
525 auto iter = std::ranges::begin(view);
526 if (
const auto end = std::ranges::end(view);
529 out = format::format_to(
534 for (; iter != end; ++iter)
536 out = format::format_to(
544 return format::format_to(std::move(out),
"\"");
597 [[maybe_unused]]
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:597
constexpr StringViewT string_literal_prefix
Primary template, yielding an empty string.
Definition String.hpp:198
typename string_traits< std::remove_cvref_t< T > >::char_t string_char_t
Computes the character type for the given string.
Definition String.hpp:260
typename uint_with_size< byteCount >::type uint_with_size_t
Convenience constant, exposing the value member of the actual type-trait.
Definition Fwd.hpp:162
Definition Matcher.hpp:26
Definition BoostTest.hpp:20
char CharT
Definition Fwd.hpp:205
ValueCategory
Definition Fwd.hpp:195
std::basic_ostringstream< CharT, CharTraitsT > StringStreamT
Definition Printer.hpp:41
Constness
Definition Fwd.hpp:188
std::basic_string_view< CharT, CharTraitsT > StringViewT
Definition Fwd.hpp:208
std::basic_string< CharT, CharTraitsT > StringT
Definition Fwd.hpp:207
Definition Utility.hpp:32