mirror of
https://github.com/fmtlib/fmt.git
synced 2025-07-30 02:37:36 +02:00
Update <format>
This commit is contained in:
137
include/format
137
include/format
@ -132,15 +132,17 @@ namespace std {
|
|||||||
enum indexing { unknown, manual, automatic }; // exposition only
|
enum indexing { unknown, manual, automatic }; // exposition only
|
||||||
indexing indexing_; // exposition only
|
indexing indexing_; // exposition only
|
||||||
size_t next_arg_id_; // exposition only
|
size_t next_arg_id_; // exposition only
|
||||||
|
size_t num_args_; // exposition only
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit constexpr basic_format_parse_context(basic_string_view<charT> fmt) noexcept;
|
explicit constexpr basic_format_parse_context(basic_string_view<charT> fmt,
|
||||||
|
size_t num_args = 0) noexcept;
|
||||||
basic_format_parse_context(const basic_format_parse_context&) = delete;
|
basic_format_parse_context(const basic_format_parse_context&) = delete;
|
||||||
basic_format_parse_context& operator=(const basic_format_parse_context&) = delete;
|
basic_format_parse_context& operator=(const basic_format_parse_context&) = delete;
|
||||||
|
|
||||||
constexpr const_iterator begin() const noexcept;
|
constexpr const_iterator begin() const noexcept;
|
||||||
constexpr const_iterator end() const noexcept;
|
constexpr const_iterator end() const noexcept;
|
||||||
constexpr void advance_to(iterator it);
|
constexpr void advance_to(const_iterator it);
|
||||||
|
|
||||||
constexpr size_t next_arg_id();
|
constexpr size_t next_arg_id();
|
||||||
constexpr void check_arg_id(size_t id);
|
constexpr void check_arg_id(size_t id);
|
||||||
@ -154,8 +156,10 @@ namespace std {
|
|||||||
|
|
||||||
namespace std {
|
namespace std {
|
||||||
template<class charT>
|
template<class charT>
|
||||||
/* explicit */ constexpr basic_format_parse_context<charT>::basic_format_parse_context(basic_string_view<charT> fmt) noexcept
|
/* explicit */ constexpr basic_format_parse_context<charT>::
|
||||||
: begin_(fmt.begin()), end_(fmt.end()), indexing_(unknown), next_arg_id_(0) {}
|
basic_format_parse_context(basic_string_view<charT> fmt,
|
||||||
|
size_t num_args) noexcept
|
||||||
|
: begin_(fmt.begin()), end_(fmt.end()), indexing_(unknown), next_arg_id_(0), num_args_(num_args) {}
|
||||||
|
|
||||||
template<class charT>
|
template<class charT>
|
||||||
constexpr typename basic_format_parse_context<charT>::const_iterator basic_format_parse_context<charT>::begin() const noexcept { return begin_; }
|
constexpr typename basic_format_parse_context<charT>::const_iterator basic_format_parse_context<charT>::begin() const noexcept { return begin_; }
|
||||||
@ -176,7 +180,10 @@ constexpr size_t basic_format_parse_context<charT>::next_arg_id() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class charT>
|
template<class charT>
|
||||||
constexpr void basic_format_parse_context<charT>::check_arg_id(size_t) {
|
constexpr void basic_format_parse_context<charT>::check_arg_id(size_t id) {
|
||||||
|
// clang doesn't support __builtin_is_constant_evaluated yet
|
||||||
|
//if (!(!__builtin_is_constant_evaluated() || id < num_args_))
|
||||||
|
// throw format_error(invalid index is out of range");
|
||||||
if (indexing_ == automatic)
|
if (indexing_ == automatic)
|
||||||
throw format_error("automatic to manual indexing");
|
throw format_error("automatic to manual indexing");
|
||||||
if (indexing_ == unknown)
|
if (indexing_ == unknown)
|
||||||
@ -186,17 +193,15 @@ constexpr void basic_format_parse_context<charT>::check_arg_id(size_t) {
|
|||||||
|
|
||||||
// http://fmtlib.net/Text%20Formatting.html#format.context
|
// http://fmtlib.net/Text%20Formatting.html#format.context
|
||||||
namespace std {
|
namespace std {
|
||||||
template<class O, class charT> FMT_REQUIRES(OutputIterator<O, const charT&>)
|
template<class Out, class charT>
|
||||||
class basic_format_context {
|
class basic_format_context {
|
||||||
basic_format_args<basic_format_context> args_; // exposition only
|
basic_format_args<basic_format_context> args_; // exposition only
|
||||||
O out_; // exposition only
|
Out out_; // exposition only
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using iterator = O;
|
using iterator = Out;
|
||||||
using char_type = charT;
|
using char_type = charT;
|
||||||
|
template<class T> using formatter_type = formatter<T, charT>;
|
||||||
template<class T>
|
|
||||||
using formatter_type = formatter<T>;
|
|
||||||
|
|
||||||
basic_format_arg<basic_format_context> arg(size_t id) const;
|
basic_format_arg<basic_format_context> arg(size_t id) const;
|
||||||
|
|
||||||
@ -205,7 +210,7 @@ namespace std {
|
|||||||
|
|
||||||
// Implementation details:
|
// Implementation details:
|
||||||
using format_arg = basic_format_arg<basic_format_context>;
|
using format_arg = basic_format_arg<basic_format_context>;
|
||||||
basic_format_context(O out, basic_format_args<basic_format_context> args, fmt::internal::locale_ref)
|
basic_format_context(Out out, basic_format_args<basic_format_context> args, fmt::internal::locale_ref)
|
||||||
: args_(args), out_(out) {}
|
: args_(args), out_(out) {}
|
||||||
fmt::internal::error_handler error_handler() const { return {}; }
|
fmt::internal::error_handler error_handler() const { return {}; }
|
||||||
basic_format_arg<basic_format_context> arg(fmt::basic_string_view<charT>) const {
|
basic_format_arg<basic_format_context> arg(fmt::basic_string_view<charT>) const {
|
||||||
@ -256,52 +261,55 @@ namespace std {
|
|||||||
class handle;
|
class handle;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using char_type = typename Context::char_type; // exposition only
|
using char_type = typename Context::char_type; // exposition only
|
||||||
|
|
||||||
public: // public to workaround a bug in clang
|
|
||||||
variant<monostate, bool, char_type,
|
variant<monostate, bool, char_type,
|
||||||
int, unsigned int, long long int, unsigned long long int,
|
int, unsigned int, long long int, unsigned long long int,
|
||||||
double, long double,
|
double, long double,
|
||||||
const char_type*, basic_string_view<char_type>,
|
const char_type*, basic_string_view<char_type>,
|
||||||
const void*, handle> value; // exposition only
|
const void*, handle> value; // exposition only
|
||||||
|
|
||||||
private:
|
template<typename T,
|
||||||
template<
|
|
||||||
FMT_CONCEPT(Integral) I,
|
|
||||||
typename = enable_if_t<
|
typename = enable_if_t<
|
||||||
std::is_same_v<I, bool> ||
|
std::is_same_v<T, bool> ||
|
||||||
std::is_same_v<I, char_type> ||
|
std::is_same_v<T, char_type> ||
|
||||||
(std::is_same_v<I, char> && std::is_same_v<char_type, wchar_t>) ||
|
(std::is_same_v<T, char> && std::is_same_v<char_type, wchar_t>) ||
|
||||||
detail::is_standard_integer_v<I> ||
|
detail::is_standard_integer_v<T> ||
|
||||||
detail::is_standard_unsigned_integer_v<I> ||
|
detail::is_standard_unsigned_integer_v<T> ||
|
||||||
is_default_constructible_v<typename Context::template formatter_type<I>>
|
is_default_constructible_v<typename Context::template formatter_type<T>>
|
||||||
>>
|
>> explicit basic_format_arg(const T& v) noexcept; // exposition only
|
||||||
explicit basic_format_arg(const I& n) noexcept; // exposition only
|
explicit basic_format_arg(float n) noexcept; // exposition only
|
||||||
explicit basic_format_arg(float n) noexcept; // exposition only
|
explicit basic_format_arg(double n) noexcept; // exposition only
|
||||||
explicit basic_format_arg(double n) noexcept; // exposition only
|
explicit basic_format_arg(long double n) noexcept; // exposition only
|
||||||
explicit basic_format_arg(long double n) noexcept; // exposition only
|
explicit basic_format_arg(const char_type* s); // exposition only
|
||||||
explicit basic_format_arg(const char_type* s) noexcept; // exposition only
|
|
||||||
explicit basic_format_arg(nullptr_t) noexcept; // exposition only
|
|
||||||
|
|
||||||
template<class traits>
|
template<class traits>
|
||||||
explicit basic_format_arg(
|
explicit basic_format_arg(
|
||||||
basic_string_view<char_type, traits> s) noexcept; // exposition only
|
basic_string_view<char_type, traits> s) noexcept; // exposition only
|
||||||
|
|
||||||
template<class traits, class Allocator>
|
template<class traits, class Allocator>
|
||||||
explicit basic_format_arg(
|
explicit basic_format_arg(
|
||||||
const basic_string<char_type, traits, Allocator>& s) noexcept; // exposition only
|
const basic_string<char_type, traits, Allocator>& s) noexcept; // exposition only
|
||||||
|
|
||||||
template<class T, typename = std::enable_if_t<std::is_same_v<T, void>>>
|
explicit basic_format_arg(nullptr_t) noexcept; // exposition only
|
||||||
explicit basic_format_arg(const T* p) noexcept; // exposition only
|
|
||||||
|
|
||||||
//template<class Visitor>
|
template<class T, typename = enable_if_t<is_void_v<T>>>
|
||||||
// friend auto std::visit_format_arg(Visitor&& vis, basic_format_arg<Context> arg);
|
explicit basic_format_arg(const T* p) noexcept; // exposition only
|
||||||
|
|
||||||
|
// Fails due to a bug in clang
|
||||||
|
//template<class Visitor, class Ctx>
|
||||||
|
// friend auto visit_format_arg(Visitor&& vis,
|
||||||
|
// basic_format_arg<Ctx> arg); // exposition only
|
||||||
|
|
||||||
|
friend auto get_value(basic_format_arg arg) {
|
||||||
|
return arg.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename Char> friend struct detail::formatter;
|
||||||
|
|
||||||
template<class Ctx, class... Args>
|
template<class Ctx, class... Args>
|
||||||
friend format_arg_store<Ctx, Args...>
|
friend format_arg_store<Ctx, Args...>
|
||||||
make_format_args(const Args&... args); // exposition only
|
make_format_args(const Args&... args); // exposition only
|
||||||
|
|
||||||
template <typename T, typename Char> friend struct detail::formatter;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
basic_format_arg() noexcept;
|
basic_format_arg() noexcept;
|
||||||
@ -315,22 +323,21 @@ template<class Context>
|
|||||||
basic_format_arg<Context>::basic_format_arg() noexcept {}
|
basic_format_arg<Context>::basic_format_arg() noexcept {}
|
||||||
|
|
||||||
template<class Context>
|
template<class Context>
|
||||||
template<FMT_CONCEPT(Integral) I, typename>
|
template<class T, typename> /* explicit */ basic_format_arg<Context>::basic_format_arg(const T& v) noexcept {
|
||||||
/* explicit */ basic_format_arg<Context>::basic_format_arg(const I& n) noexcept {
|
if constexpr (std::is_same_v<T, bool> || std::is_same_v<T, char_type>)
|
||||||
if constexpr (std::is_same_v<I, bool> || std::is_same_v<I, char_type>)
|
value = v;
|
||||||
value = n;
|
else if constexpr (std::is_same_v<T, char> && std::is_same_v<char_type, wchar_t>)
|
||||||
else if constexpr (std::is_same_v<I, char> && std::is_same_v<char_type, wchar_t>)
|
value = static_cast<wchar_t>(v);
|
||||||
value = static_cast<wchar_t>(n);
|
else if constexpr (detail::is_standard_integer_v<T> && sizeof(T) <= sizeof(int))
|
||||||
else if constexpr (detail::is_standard_integer_v<I> && sizeof(I) <= sizeof(int))
|
value = static_cast<int>(v);
|
||||||
value = static_cast<int>(n);
|
else if constexpr (detail::is_standard_unsigned_integer_v<T> && sizeof(T) <= sizeof(unsigned))
|
||||||
else if constexpr (detail::is_standard_unsigned_integer_v<I> && sizeof(I) <= sizeof(unsigned))
|
value = static_cast<unsigned>(v);
|
||||||
value = static_cast<unsigned>(n);
|
else if constexpr (detail::is_standard_integer_v<T>)
|
||||||
else if constexpr (detail::is_standard_integer_v<I>)
|
value = static_cast<long long int>(v);
|
||||||
value = static_cast<long long int>(n);
|
else if constexpr (detail::is_standard_unsigned_integer_v<T>)
|
||||||
else if constexpr (detail::is_standard_unsigned_integer_v<I>)
|
value = static_cast<unsigned long long int>(v);
|
||||||
value = static_cast<unsigned long long int>(n);
|
else if constexpr (is_default_constructible_v<typename Context::template formatter_type<T>>)
|
||||||
else if constexpr (is_default_constructible_v<typename Context::template formatter_type<I>>)
|
value = handle(v);
|
||||||
value = handle(n);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Context>
|
template<class Context>
|
||||||
@ -346,7 +353,7 @@ template<class Context>
|
|||||||
: value(n) {}
|
: value(n) {}
|
||||||
|
|
||||||
template<class Context>
|
template<class Context>
|
||||||
/* explicit */ basic_format_arg<Context>::basic_format_arg(const typename basic_format_arg<Context>::char_type* s) noexcept
|
/* explicit */ basic_format_arg<Context>::basic_format_arg(const typename basic_format_arg<Context>::char_type* s)
|
||||||
: value(s) {
|
: value(s) {
|
||||||
assert(s != nullptr);
|
assert(s != nullptr);
|
||||||
}
|
}
|
||||||
@ -386,7 +393,7 @@ namespace std {
|
|||||||
|
|
||||||
template<class T> explicit handle(const T& val) noexcept; // exposition only
|
template<class T> explicit handle(const T& val) noexcept; // exposition only
|
||||||
|
|
||||||
friend class basic_format_arg<Context>;
|
friend class basic_format_arg<Context>; // exposition only
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void format(basic_format_parse_context<char_type>&, Context& ctx) const;
|
void format(basic_format_parse_context<char_type>&, Context& ctx) const;
|
||||||
@ -397,10 +404,10 @@ namespace std {
|
|||||||
template<class Context>
|
template<class Context>
|
||||||
template<class T> /* explicit */ basic_format_arg<Context>::handle::handle(const T& val) noexcept
|
template<class T> /* explicit */ basic_format_arg<Context>::handle::handle(const T& val) noexcept
|
||||||
: ptr_(&val), format_([](basic_format_parse_context<char_type>& parse_ctx, Context& format_ctx, const void* ptr) {
|
: ptr_(&val), format_([](basic_format_parse_context<char_type>& parse_ctx, Context& format_ctx, const void* ptr) {
|
||||||
typename Context::template formatter_type<T> f;
|
typename Context::template formatter_type<T> f;
|
||||||
parse_ctx.advance_to(f.parse(parse_ctx));
|
parse_ctx.advance_to(f.parse(parse_ctx));
|
||||||
format_ctx.advance_to(f.format(*static_cast<const T*>(ptr), format_ctx));
|
format_ctx.advance_to(f.format(*static_cast<const T*>(ptr), format_ctx));
|
||||||
}) {}
|
}) {}
|
||||||
|
|
||||||
template<class Context>
|
template<class Context>
|
||||||
void basic_format_arg<Context>::handle::format(basic_format_parse_context<char_type>& parse_ctx, Context& format_ctx) const {
|
void basic_format_arg<Context>::handle::format(basic_format_parse_context<char_type>& parse_ctx, Context& format_ctx) const {
|
||||||
@ -410,7 +417,7 @@ void basic_format_arg<Context>::handle::format(basic_format_parse_context<char_t
|
|||||||
// http://fmtlib.net/Text%20Formatting.html#format.visit
|
// http://fmtlib.net/Text%20Formatting.html#format.visit
|
||||||
template<class Visitor, class Context>
|
template<class Visitor, class Context>
|
||||||
auto visit_format_arg(Visitor&& vis, basic_format_arg<Context> arg) {
|
auto visit_format_arg(Visitor&& vis, basic_format_arg<Context> arg) {
|
||||||
return visit(vis, arg.value);
|
return visit(vis, get_value(arg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -465,7 +472,7 @@ template<class Context /*= format_context*/, class... Args>
|
|||||||
// http://fmtlib.net/Text%20Formatting.html#format.make_wargs
|
// http://fmtlib.net/Text%20Formatting.html#format.make_wargs
|
||||||
template<class... Args>
|
template<class... Args>
|
||||||
format_arg_store<wformat_context, Args...> make_wformat_args(const Args&... args) {
|
format_arg_store<wformat_context, Args...> make_wformat_args(const Args&... args) {
|
||||||
return {basic_format_arg<wformat_context>(args)...};
|
return make_format_args<wformat_context>(args...);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -543,7 +550,7 @@ inline fmt::internal::type get_type(basic_format_arg<Context> arg) {
|
|||||||
return fmt::internal::string_type;
|
return fmt::internal::string_type;
|
||||||
if (std::is_same_v<T, const void*>)
|
if (std::is_same_v<T, const void*>)
|
||||||
return fmt::internal::pointer_type;
|
return fmt::internal::pointer_type;
|
||||||
assert(arg.value.index() == 12);
|
assert(get_value(arg).index() == 12);
|
||||||
return fmt::internal::custom_type;
|
return fmt::internal::custom_type;
|
||||||
}, arg);
|
}, arg);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user