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) {
50 Printer::print(out, std::declval<T&&>())
51 } -> std::convertible_to<OutIter>;
57#ifndef MIMICPP_CONFIG_USE_FMT
60 #ifndef _LIBCPP_VERSION
65 using std::make_format_args;
67 using std::vformat_to;
75 using std::make_format_args;
77 using std::vformat_to;
79 template <
typename... Args>
83 return format::vformat(
85 std::make_format_args(args...));
88 template <
class OutputIt,
typename... Args>
89 OutputIt format_to(
const OutputIt out,
const StringViewT fmt, Args&&... args)
91 return format::vformat_to(
94 std::make_format_args(args...));
101 template <
typename Char>
102 struct format_context;
104 template <
typename Char>
105 using format_context_t =
typename format_context<Char>::type;
108 struct format_context<char>
110 using type = std::format_context;
114 struct format_context<wchar_t>
116 using type = std::wformat_context;
129 template <
class T,
class Char>
130 concept formattable =
131 std::semiregular<std::formatter<std::remove_cvref_t<T>, Char>>
133 std::formatter<std::remove_cvref_t<T>, Char> formatter,
135 format_context_t<Char> formatContext,
136 std::basic_format_parse_context<Char> parseContext) {
137 { formatter.parse(parseContext) } -> std::same_as<typename std::basic_format_parse_context<Char>::iterator>;
139 std::as_const(formatter).format(t, formatContext)
140 } -> std::same_as<
typename std::remove_reference_t<
decltype(formatContext)>::iterator>;
148 using fmt::format_to;
149 using fmt::formatter;
150 using fmt::make_format_args;
152 using fmt::vformat_to;
156 template <
class T,
class Char>
157 concept formattable = fmt::is_formattable<std::remove_reference_t<T>, Char>::value;
165 :
public formatter<std::string_view, mimicpp::CharT>
176 case ValueCategoryT::lvalue:
178 case ValueCategoryT::rvalue:
180 case ValueCategoryT::any:
184 throw std::invalid_argument{
"Unknown category value."};
187 return formatter<std::string_view, mimicpp::CharT>::format(
195 :
public formatter<std::string_view, mimicpp::CharT>
203 constexpr auto toString = [](
const ConstnessT value) {
206 case ConstnessT::non_const:
208 case ConstnessT::as_const:
210 case ConstnessT::any:
214 throw std::invalid_argument{
"Unknown constness value."};
217 return formatter<std::string_view, mimicpp::CharT>::format(
233namespace mimicpp::detail
244 return Printer::print(
246 std::forward<T>(value));
258 return Printer::print(
260 std::forward<T>(value));
263 template <pr
int_iterator OutIter, std::ranges::forward_range Range>
269 template <pr
int_iterator OutIter, format::detail::formattable<CharT> T>
273 [[maybe_unused]]
const priority_tag<1>)
275 return format::format_to(
278 std::forward<T>(value));
281 template <pr
int_iterator OutIter>
285 [[maybe_unused]]
const priority_tag<0>)
287 return format::format_to(
295 template <pr
int_iterator OutIter,
typename T>
301 requires(
const priority_tag<4> tag) {
302 {
print(out, std::forward<T>(value), tag) } -> std::convertible_to<OutIter>;
304 "The given type is not printable. ");
308 std::forward<T>(value),
312 template <
typename T>
313 StringT operator()(T&& value)
const
318 std::ostreambuf_iterator{stream},
319 std::forward<T>(value));
320 return std::move(stream).str();
324 template <pr
int_iterator OutIter, std::ranges::forward_range Range>
328 const priority_tag<2>)
330 out = format::format_to(
333 auto iter = std::ranges::begin(range);
334 if (
const auto end = std::ranges::end(range);
337 constexpr PrintFn print{};
338 out =
print(std::move(out), *iter++);
340 for (; iter != end; ++iter)
343 format::format_to(std::move(out),
", "),
348 return format::format_to(
354 class Printer<std::source_location>
357 template <pr
int_iterator OutIter>
358 static OutIter
print(OutIter out,
const std::source_location& loc)
360 return format::format_to(
366 loc.function_name());
371 class Printer<std::nullopt_t>
374 template <pr
int_iterator OutIter>
375 static OutIter
print(OutIter out, [[maybe_unused]]
const std::nullopt_t)
377 return format::format_to(
383 template <
typename T>
384 class Printer<std::optional<T>>
387 template <pr
int_iterator OutIter>
388 static OutIter
print(OutIter out,
const std::optional<T>& opt)
390 constexpr PrintFn
print{};
394 out = format::format_to(std::move(out),
"{{ value: ");
395 out =
print(std::move(out), *opt);
396 return format::format_to(std::move(out),
" }}");
398 return print(std::move(out), std::nullopt);
402 template <std::
size_t index, pr
int_iterator OutIter,
typename Tuple>
403 OutIter tuple_element_print(OutIter out, Tuple&& tuple)
405 if constexpr (0u != index)
407 out = format::format_to(std::move(out),
", ");
410 constexpr PrintFn printer{};
413 std::get<index>(std::forward<Tuple>(tuple)));
416 template <
typename T>
418 typename std::tuple_size<T>::type;
419 requires std::convertible_to<typename std::tuple_size<T>::type, std::size_t>;
420 requires 0u <= std::tuple_size_v<T>;
425 template <pr
int_iterator OutIter>
426 static OutIter
print(OutIter out,
const T& tuple)
428 out = format::format_to(std::move(out),
"{{ ");
431 [&]<std::size_t... indices>([[maybe_unused]]
const std::index_sequence<indices...>) {
433 (out = tuple_element_print<indices>(std::move(out), tuple)));
435 std::make_index_sequence<std::tuple_size_v<T>>{});
437 return format::format_to(std::move(out),
" }}");
441 template <
typename T>
442 concept pointer_like = std::is_pointer_v<T>
443 || std::same_as<std::nullptr_t, T>;
445 template <po
inter_like T>
450 template <pr
int_iterator OutIter>
451 static OutIter
print(OutIter out, T ptr)
453 if constexpr (4u <
sizeof(T))
455 return format::format_to(
458 std::bit_cast<std::uintptr_t>(ptr));
462 return format::format_to(
465 std::bit_cast<std::uintptr_t>(ptr));
470 template <
string String>
471 class Printer<String>
474 template <std::common_reference_with<String> T, pr
int_iterator OutIter>
475 static OutIter
print(OutIter out, T&& str)
478 !std::ranges::empty(prefix))
480 out = out = format::format_to(
486 out = format::format_to(std::move(out),
"\"");
491 if constexpr (std::same_as<CharT, string_char_t<String>>)
493 auto view = string_traits<String>::view(str);
494 out = format::format_to(
498 std::ranges::data(view),
499 std::ranges::size(view)});
502 else if constexpr (printer_for<custom::Printer<string_char_t<String>>, OutIter,
string_char_t<String>>)
507 out = printer.print(std::move(out), c);
514 return std::bit_cast<intermediate_t>(c);
517 auto view = string_traits<std::remove_cvref_t<T>>::view(std::forward<T>(str));
518 auto iter = std::ranges::begin(view);
519 if (
const auto end = std::ranges::end(view);
522 out = format::format_to(
527 for (; iter != end; ++iter)
529 out = format::format_to(
537 return format::format_to(std::move(out),
"\"");
590 [[maybe_unused]]
inline constexpr detail::PrintFn
print{};
User may add specializations, which will then be used during print calls.
Definition Printer.hpp:230
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:590
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:313
Definition BoostTest.hpp:20
char CharT
Definition Fwd.hpp:342
ValueCategory
Definition Fwd.hpp:32
std::basic_ostringstream< CharT, CharTraitsT > StringStreamT
Definition Printer.hpp:41
Constness
Definition Fwd.hpp:25
std::basic_string_view< CharT, CharTraitsT > StringViewT
Definition Fwd.hpp:345
std::basic_string< CharT, CharTraitsT > StringT
Definition Fwd.hpp:344
Definition Utility.hpp:33