mimic++ v9.2.1
Loading...
Searching...
No Matches
Format.hpp
Go to the documentation of this file.
1// Copyright Dominic (DNKpp) Koepke 2024 - 2025.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at
4// https://www.boost.org/LICENSE_1_0.txt)
5
6#ifndef MIMICPP_PRINTING_FORMAT_HPP
7#define MIMICPP_PRINTING_FORMAT_HPP
8
9#pragma once
10
11#include "mimic++/Fwd.hpp"
13
14#ifndef MIMICPP_DETAIL_IS_MODULE
15 #include <concepts>
16 #include <sstream>
17 #include <type_traits>
18 #include <utility>
19
20 #ifndef MIMICPP_CONFIG_USE_FMT
21 #include <format>
22 #else
23
24 #if __has_include(<fmt/format.h>)
25 #include <fmt/format.h>
26 #else
27 #error "The fmt formatting backend is explicitly enabled, but the include <fmt/format.h> can not be found."
28 #endif
29
30 #endif
31#endif
32
34{
35 using StringStreamT = std::basic_ostringstream<CharT, CharTraitsT>;
36
37 template <typename T>
38 concept print_iterator = std::output_iterator<T, const CharT&>;
39
40 template <typename Printer, typename OutIter, typename T>
42 && requires(OutIter out) {
43 {
44 Printer::print(out, std::declval<T&>())
45 } -> std::convertible_to<OutIter>;
46 };
47}
48
49#ifndef MIMICPP_CONFIG_USE_FMT
50
52{
53 // use std format
54 #if !MIMICPP_DETAIL_USES_LIBCXX
55
56 using std::format;
57 using std::format_to;
58 using std::formatter;
59 using std::make_format_args;
60 using std::vformat;
61 using std::vformat_to;
62
63 #else
64
65 // libc++ has some serious trouble when using its std::format implementation.
66 // Let's simply redirect any calls to std::vformat instead.
67
68 using std::formatter;
69 using std::make_format_args;
70 using std::vformat;
71 using std::vformat_to;
72
73 template <typename... Args>
74 [[nodiscard]]
75 StringT format(const StringViewT fmt, Args&&... args) // NOLINT(cppcoreguidelines-missing-std-forward)
76 {
77 return format::vformat(
78 fmt,
79 std::make_format_args(args...));
80 }
81
82 template <class OutputIt, typename... Args>
83 OutputIt format_to(const OutputIt out, const StringViewT fmt, Args&&... args) // NOLINT(cppcoreguidelines-missing-std-forward)
84 {
85 return format::vformat_to(
86 std::move(out),
87 fmt,
88 std::make_format_args(args...));
89 }
90
91 #endif
92}
93
94namespace mimicpp::format::detail
95{
96 template <typename Char>
97 struct format_context;
98
99 template <typename Char>
100 using format_context_t = typename format_context<Char>::type;
101
102 template <>
103 struct format_context<char>
104 {
105 using type = std::format_context;
106 };
107
108 template <>
109 struct format_context<wchar_t>
110 {
111 using type = std::wformat_context;
112 };
113
124 template <class T, class Char>
125 concept formattable =
126 std::semiregular<std::formatter<std::remove_cvref_t<T>, Char>>
127 && requires(
128 std::formatter<std::remove_cvref_t<T>, Char> formatter,
129 T t,
130 format_context_t<Char> formatContext,
131 std::basic_format_parse_context<Char> parseContext) {
132 { formatter.parse(parseContext) } -> std::same_as<typename std::basic_format_parse_context<Char>::iterator>;
133 {
134 std::as_const(formatter).format(t, formatContext)
135 } -> std::same_as<typename std::remove_reference_t<decltype(formatContext)>::iterator>;
136 };
137}
138
139 // use fmt format
140#else
141
143{
144 using fmt::format;
145 using fmt::format_to;
146 using fmt::formatter;
147 using fmt::make_format_args;
148 using fmt::vformat;
149 using fmt::vformat_to;
150}
151
152namespace mimicpp::format::detail
153{
154 template <class T, class Char>
155 concept formattable = fmt::is_formattable<std::remove_reference_t<T>, Char>::value;
156}
157
158#endif
159
160#endif
#define MIMICPP_DETAIL_MODULE_EXPORT
Definition Config.hpp:19
Definition Format.hpp:38
Definition Format.hpp:41
Definition Format.hpp:52
Definition Call.hpp:24
std::basic_ostringstream< CharT, CharTraitsT > StringStreamT
Definition Format.hpp:35
std::basic_string_view< CharT, CharTraitsT > StringViewT
Definition Fwd.hpp:392
std::basic_string< CharT, CharTraitsT > StringT
Definition Fwd.hpp:391