mirror of
https://github.com/fmtlib/fmt.git
synced 2025-01-27 06:35:37 +00:00
Update <format>
This commit is contained in:
parent
52eb3fe274
commit
a6ad29aa34
137
include/format
137
include/format
@ -132,15 +132,17 @@ namespace std {
|
||||
enum indexing { unknown, manual, automatic }; // exposition only
|
||||
indexing indexing_; // exposition only
|
||||
size_t next_arg_id_; // exposition only
|
||||
size_t num_args_; // exposition only
|
||||
|
||||
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& operator=(const basic_format_parse_context&) = delete;
|
||||
|
||||
constexpr const_iterator begin() 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 void check_arg_id(size_t id);
|
||||
@ -154,8 +156,10 @@ namespace std {
|
||||
|
||||
namespace std {
|
||||
template<class charT>
|
||||
/* explicit */ constexpr basic_format_parse_context<charT>::basic_format_parse_context(basic_string_view<charT> fmt) noexcept
|
||||
: begin_(fmt.begin()), end_(fmt.end()), indexing_(unknown), next_arg_id_(0) {}
|
||||
/* explicit */ constexpr basic_format_parse_context<charT>::
|
||||
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>
|
||||
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>
|
||||
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)
|
||||
throw format_error("automatic to manual indexing");
|
||||
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
|
||||
namespace std {
|
||||
template<class O, class charT> FMT_REQUIRES(OutputIterator<O, const charT&>)
|
||||
template<class Out, class charT>
|
||||
class basic_format_context {
|
||||
basic_format_args<basic_format_context> args_; // exposition only
|
||||
O out_; // exposition only
|
||||
Out out_; // exposition only
|
||||
|
||||
public:
|
||||
using iterator = O;
|
||||
using iterator = Out;
|
||||
using char_type = charT;
|
||||
|
||||
template<class T>
|
||||
using formatter_type = formatter<T>;
|
||||
template<class T> using formatter_type = formatter<T, charT>;
|
||||
|
||||
basic_format_arg<basic_format_context> arg(size_t id) const;
|
||||
|
||||
@ -205,7 +210,7 @@ namespace std {
|
||||
|
||||
// Implementation details:
|
||||
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) {}
|
||||
fmt::internal::error_handler error_handler() const { return {}; }
|
||||
basic_format_arg<basic_format_context> arg(fmt::basic_string_view<charT>) const {
|
||||
@ -256,52 +261,55 @@ namespace std {
|
||||
class handle;
|
||||
|
||||
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,
|
||||
int, unsigned int, long long int, unsigned long long int,
|
||||
double, long double,
|
||||
const char_type*, basic_string_view<char_type>,
|
||||
const void*, handle> value; // exposition only
|
||||
const void*, handle> value; // exposition only
|
||||
|
||||
private:
|
||||
template<
|
||||
FMT_CONCEPT(Integral) I,
|
||||
template<typename T,
|
||||
typename = enable_if_t<
|
||||
std::is_same_v<I, bool> ||
|
||||
std::is_same_v<I, char_type> ||
|
||||
(std::is_same_v<I, char> && std::is_same_v<char_type, wchar_t>) ||
|
||||
detail::is_standard_integer_v<I> ||
|
||||
detail::is_standard_unsigned_integer_v<I> ||
|
||||
is_default_constructible_v<typename Context::template formatter_type<I>>
|
||||
>>
|
||||
explicit basic_format_arg(const I& 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(long double n) noexcept; // exposition only
|
||||
explicit basic_format_arg(const char_type* s) noexcept; // exposition only
|
||||
explicit basic_format_arg(nullptr_t) noexcept; // exposition only
|
||||
std::is_same_v<T, bool> ||
|
||||
std::is_same_v<T, char_type> ||
|
||||
(std::is_same_v<T, char> && std::is_same_v<char_type, wchar_t>) ||
|
||||
detail::is_standard_integer_v<T> ||
|
||||
detail::is_standard_unsigned_integer_v<T> ||
|
||||
is_default_constructible_v<typename Context::template formatter_type<T>>
|
||||
>> explicit basic_format_arg(const T& v) 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(long double n) noexcept; // exposition only
|
||||
explicit basic_format_arg(const char_type* s); // exposition only
|
||||
|
||||
template<class traits>
|
||||
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>
|
||||
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(const T* p) noexcept; // exposition only
|
||||
explicit basic_format_arg(nullptr_t) noexcept; // exposition only
|
||||
|
||||
//template<class Visitor>
|
||||
// friend auto std::visit_format_arg(Visitor&& vis, basic_format_arg<Context> arg);
|
||||
template<class T, typename = enable_if_t<is_void_v<T>>>
|
||||
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>
|
||||
friend format_arg_store<Ctx, Args...>
|
||||
make_format_args(const Args&... args); // exposition only
|
||||
|
||||
template <typename T, typename Char> friend struct detail::formatter;
|
||||
make_format_args(const Args&... args); // exposition only
|
||||
|
||||
public:
|
||||
basic_format_arg() noexcept;
|
||||
@ -315,22 +323,21 @@ template<class Context>
|
||||
basic_format_arg<Context>::basic_format_arg() noexcept {}
|
||||
|
||||
template<class Context>
|
||||
template<FMT_CONCEPT(Integral) I, typename>
|
||||
/* explicit */ basic_format_arg<Context>::basic_format_arg(const I& n) noexcept {
|
||||
if constexpr (std::is_same_v<I, bool> || std::is_same_v<I, char_type>)
|
||||
value = n;
|
||||
else if constexpr (std::is_same_v<I, char> && std::is_same_v<char_type, wchar_t>)
|
||||
value = static_cast<wchar_t>(n);
|
||||
else if constexpr (detail::is_standard_integer_v<I> && sizeof(I) <= sizeof(int))
|
||||
value = static_cast<int>(n);
|
||||
else if constexpr (detail::is_standard_unsigned_integer_v<I> && sizeof(I) <= sizeof(unsigned))
|
||||
value = static_cast<unsigned>(n);
|
||||
else if constexpr (detail::is_standard_integer_v<I>)
|
||||
value = static_cast<long long int>(n);
|
||||
else if constexpr (detail::is_standard_unsigned_integer_v<I>)
|
||||
value = static_cast<unsigned long long int>(n);
|
||||
else if constexpr (is_default_constructible_v<typename Context::template formatter_type<I>>)
|
||||
value = handle(n);
|
||||
template<class T, typename> /* explicit */ basic_format_arg<Context>::basic_format_arg(const T& v) noexcept {
|
||||
if constexpr (std::is_same_v<T, bool> || std::is_same_v<T, char_type>)
|
||||
value = v;
|
||||
else if constexpr (std::is_same_v<T, char> && std::is_same_v<char_type, wchar_t>)
|
||||
value = static_cast<wchar_t>(v);
|
||||
else if constexpr (detail::is_standard_integer_v<T> && sizeof(T) <= sizeof(int))
|
||||
value = static_cast<int>(v);
|
||||
else if constexpr (detail::is_standard_unsigned_integer_v<T> && sizeof(T) <= sizeof(unsigned))
|
||||
value = static_cast<unsigned>(v);
|
||||
else if constexpr (detail::is_standard_integer_v<T>)
|
||||
value = static_cast<long long int>(v);
|
||||
else if constexpr (detail::is_standard_unsigned_integer_v<T>)
|
||||
value = static_cast<unsigned long long int>(v);
|
||||
else if constexpr (is_default_constructible_v<typename Context::template formatter_type<T>>)
|
||||
value = handle(v);
|
||||
}
|
||||
|
||||
template<class Context>
|
||||
@ -346,7 +353,7 @@ template<class Context>
|
||||
: value(n) {}
|
||||
|
||||
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) {
|
||||
assert(s != nullptr);
|
||||
}
|
||||
@ -386,7 +393,7 @@ namespace std {
|
||||
|
||||
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:
|
||||
void format(basic_format_parse_context<char_type>&, Context& ctx) const;
|
||||
@ -397,10 +404,10 @@ namespace std {
|
||||
template<class Context>
|
||||
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) {
|
||||
typename Context::template formatter_type<T> f;
|
||||
parse_ctx.advance_to(f.parse(parse_ctx));
|
||||
format_ctx.advance_to(f.format(*static_cast<const T*>(ptr), format_ctx));
|
||||
}) {}
|
||||
typename Context::template formatter_type<T> f;
|
||||
parse_ctx.advance_to(f.parse(parse_ctx));
|
||||
format_ctx.advance_to(f.format(*static_cast<const T*>(ptr), format_ctx));
|
||||
}) {}
|
||||
|
||||
template<class Context>
|
||||
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
|
||||
template<class Visitor, class Context>
|
||||
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
|
||||
template<class... 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;
|
||||
if (std::is_same_v<T, const void*>)
|
||||
return fmt::internal::pointer_type;
|
||||
assert(arg.value.index() == 12);
|
||||
assert(get_value(arg).index() == 12);
|
||||
return fmt::internal::custom_type;
|
||||
}, arg);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user