Commit a6ad29aa authored by Victor Zverovich's avatar Victor Zverovich

Update <format>

parent 52eb3fe2
......@@ -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,53 +261,56 @@ 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
template<class Ctx, class... Args>
friend format_arg_store<Ctx, Args...>
make_format_args(const Args&... args); // 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
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);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment