tmp/tmpo0g1viwr/{from.md → to.md}
RENAMED
|
@@ -5,10 +5,13 @@ namespace std {
|
|
| 5 |
template<class Out, class charT>
|
| 6 |
class basic_format_context {
|
| 7 |
basic_format_args<basic_format_context> args_; // exposition only
|
| 8 |
Out out_; // exposition only
|
| 9 |
|
|
|
|
|
|
|
|
|
|
| 10 |
public:
|
| 11 |
using iterator = Out;
|
| 12 |
using char_type = charT;
|
| 13 |
template<class T> using formatter_type = formatter<T, charT>;
|
| 14 |
|
|
@@ -22,10 +25,14 @@ namespace std {
|
|
| 22 |
```
|
| 23 |
|
| 24 |
An instance of `basic_format_context` holds formatting state consisting
|
| 25 |
of the formatting arguments and the output iterator.
|
| 26 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 27 |
`Out` shall model `output_iterator<const charT&>`.
|
| 28 |
|
| 29 |
`format_context` is an alias for a specialization of
|
| 30 |
`basic_format_context` with an output iterator that appends to `string`,
|
| 31 |
such as `back_insert_iterator<string>`. Similarly, `wformat_context` is
|
|
@@ -72,33 +79,34 @@ template<> struct std::formatter<S> {
|
|
| 72 |
size_t width_arg_id = 0;
|
| 73 |
|
| 74 |
// Parses a width argument id in the format { digit }.
|
| 75 |
constexpr auto parse(format_parse_context& ctx) {
|
| 76 |
auto iter = ctx.begin();
|
|
|
|
| 77 |
auto get_char = [&]() { return iter != ctx.end() ? *iter : 0; };
|
| 78 |
if (get_char() != '{')
|
| 79 |
return iter;
|
| 80 |
++iter;
|
| 81 |
char c = get_char();
|
| 82 |
-
if (!
|
| 83 |
throw format_error("invalid format");
|
| 84 |
width_arg_id = c - '0';
|
| 85 |
ctx.check_arg_id(width_arg_id);
|
| 86 |
return ++iter;
|
| 87 |
}
|
| 88 |
|
| 89 |
// Formats an S with width given by the argument width_arg_id.
|
| 90 |
auto format(S s, format_context& ctx) const {
|
| 91 |
-
int width =
|
| 92 |
if constexpr (!is_integral_v<decltype(value)>)
|
| 93 |
throw format_error("width is not integral");
|
| 94 |
else if (value < 0 || value > numeric_limits<int>::max())
|
| 95 |
throw format_error("invalid width");
|
| 96 |
else
|
| 97 |
return value;
|
| 98 |
-
}
|
| 99 |
-
return format_to(ctx.out(), "{0:x
|
| 100 |
}
|
| 101 |
};
|
| 102 |
|
| 103 |
std::string s = std::format("{0:{1}}", S{42}, 10); // value of s is "xxxxxxxx42"
|
| 104 |
```
|
|
|
|
| 5 |
template<class Out, class charT>
|
| 6 |
class basic_format_context {
|
| 7 |
basic_format_args<basic_format_context> args_; // exposition only
|
| 8 |
Out out_; // exposition only
|
| 9 |
|
| 10 |
+
basic_format_context(const basic_format_context&) = delete;
|
| 11 |
+
basic_format_context& operator=(const basic_format_context&) = delete;
|
| 12 |
+
|
| 13 |
public:
|
| 14 |
using iterator = Out;
|
| 15 |
using char_type = charT;
|
| 16 |
template<class T> using formatter_type = formatter<T, charT>;
|
| 17 |
|
|
|
|
| 25 |
```
|
| 26 |
|
| 27 |
An instance of `basic_format_context` holds formatting state consisting
|
| 28 |
of the formatting arguments and the output iterator.
|
| 29 |
|
| 30 |
+
If a program declares an explicit or partial specialization of
|
| 31 |
+
`basic_format_context`, the program is ill-formed, no diagnostic
|
| 32 |
+
required.
|
| 33 |
+
|
| 34 |
`Out` shall model `output_iterator<const charT&>`.
|
| 35 |
|
| 36 |
`format_context` is an alias for a specialization of
|
| 37 |
`basic_format_context` with an output iterator that appends to `string`,
|
| 38 |
such as `back_insert_iterator<string>`. Similarly, `wformat_context` is
|
|
|
|
| 79 |
size_t width_arg_id = 0;
|
| 80 |
|
| 81 |
// Parses a width argument id in the format { digit }.
|
| 82 |
constexpr auto parse(format_parse_context& ctx) {
|
| 83 |
auto iter = ctx.begin();
|
| 84 |
+
auto is_digit = [](auto c) { return c >= '0' && c <= '9'; };
|
| 85 |
auto get_char = [&]() { return iter != ctx.end() ? *iter : 0; };
|
| 86 |
if (get_char() != '{')
|
| 87 |
return iter;
|
| 88 |
++iter;
|
| 89 |
char c = get_char();
|
| 90 |
+
if (!is_digit(c) || (++iter, get_char()) != '}')
|
| 91 |
throw format_error("invalid format");
|
| 92 |
width_arg_id = c - '0';
|
| 93 |
ctx.check_arg_id(width_arg_id);
|
| 94 |
return ++iter;
|
| 95 |
}
|
| 96 |
|
| 97 |
// Formats an S with width given by the argument width_arg_id.
|
| 98 |
auto format(S s, format_context& ctx) const {
|
| 99 |
+
int width = ctx.arg(width_arg_id).visit([](auto value) -> int {
|
| 100 |
if constexpr (!is_integral_v<decltype(value)>)
|
| 101 |
throw format_error("width is not integral");
|
| 102 |
else if (value < 0 || value > numeric_limits<int>::max())
|
| 103 |
throw format_error("invalid width");
|
| 104 |
else
|
| 105 |
return value;
|
| 106 |
+
});
|
| 107 |
+
return format_to(ctx.out(), "{0:x>{1}}", s.value, width);
|
| 108 |
}
|
| 109 |
};
|
| 110 |
|
| 111 |
std::string s = std::format("{0:{1}}", S{42}, 10); // value of s is "xxxxxxxx42"
|
| 112 |
```
|