[libc++][format] Finish P0645 Text Formatting.

This adjust the version macro and sets it as completed. All parts of the paper
have been implemented, except for the parts replaced by later papers and
LWG-issues.

Adjusted the synopsis to match the synopsis in the Standard. Not yet
implemented parts of P2216 and P2418 still use the P0645 wording.

Completes:
- P0645 Text Formatting

Depends on D115991

Reviewed By: ldionne, #libc

Differential Revision: https://reviews.llvm.org/D115999
This commit is contained in:
Mark de Wever 2021-12-18 15:03:26 +01:00
parent eadf7268d5
commit 4684857abf
5 changed files with 18 additions and 156 deletions

View File

@ -38,10 +38,13 @@ What's New in Libc++ 14.0.0?
New Features
------------
- There's initial support for the C++20 header ``<format>``. The implementation
is incomplete. Some functions are known to be inefficient; both in memory
usage and performance. The implementation is considered experimental and isn't
considered ABI stable.
- There's support for the C++20 header ``<format>``. Some parts are still
missing, most notably the compile-time format string validation. Some
functions are known to be inefficient, both in memory usage and performance.
The implementation isn't API- or ABI-stable and therefore considered
experimental. (Some not-yet-implemented papers require an API-break.)
Vendors can still disable this header by turning the CMake option
`LIBCXX_ENABLE_INCOMPLETE_FEATURES` off.
- There's a new CMake option ``LIBCXX_ENABLE_UNICODE`` to disable Unicode
support in the ``<format>`` header. This only affects the estimation of the

View File

@ -41,6 +41,7 @@ Paper Status
.. note::
.. [#note-P0600] P0600: The missing bits in P0600 are in |sect|\ [mem.res.class] and |sect|\ [mem.poly.allocator.class].
.. [#note-P0645] P0645: The paper is implemented but still marked as an incomplete feature. Not yet implemented LWG-issues will cause API and ABI breakage.
.. [#note-P0966] P0966: It was previously erroneously marked as complete in version 8.0. See `bug 45368 <https://llvm.org/PR45368>`__.
.. [#note-P0619] P0619: Only sections D.8, D.9, D.10 and D.13 are implemented. Sections D.4, D.7, D.11, D.12, and D.14 remain undone.
.. [#note-P0883] P0883: shared_ptr and floating-point changes weren't applied as they themselves aren't implemented yet.

View File

@ -103,7 +103,7 @@
"`P0466R5 <https://wg21.link/P0466R5>`__","LWG","Layout-compatibility and Pointer-interconvertibility Traits","Cologne","",""
"`P0553R4 <https://wg21.link/P0553R4>`__","LWG","Bit operations","Cologne","|Complete|","9.0"
"`P0631R8 <https://wg21.link/P0631R8>`__","LWG","Math Constants","Cologne","|Complete|","11.0"
"`P0645R10 <https://wg21.link/P0645R10>`__","LWG","Text Formatting","Cologne","|In Progress|",""
"`P0645R10 <https://wg21.link/P0645R10>`__","LWG","Text Formatting","Cologne","|Complete| [#note-P0645]_","14.0"
"`P0660R10 <https://wg21.link/P0660R10>`__","LWG","Stop Token and Joining Thread, Rev 10","Cologne","",""
"`P0784R7 <https://wg21.link/P0784R7>`__","CWG","More constexpr containers","Cologne","|Complete|","12.0"
"`P0980R1 <https://wg21.link/P0980R1>`__","LWG","Making std::string constexpr","Cologne","",""

1 Paper # Group Paper Name Meeting Status First released version
103 `P0466R5 <https://wg21.link/P0466R5>`__ LWG Layout-compatibility and Pointer-interconvertibility Traits Cologne
104 `P0553R4 <https://wg21.link/P0553R4>`__ LWG Bit operations Cologne |Complete| 9.0
105 `P0631R8 <https://wg21.link/P0631R8>`__ LWG Math Constants Cologne |Complete| 11.0
106 `P0645R10 <https://wg21.link/P0645R10>`__ LWG Text Formatting Cologne |In Progress| |Complete| [#note-P0645]_ 14.0
107 `P0660R10 <https://wg21.link/P0660R10>`__ LWG Stop Token and Joining Thread, Rev 10 Cologne
108 `P0784R7 <https://wg21.link/P0784R7>`__ CWG More constexpr containers Cologne |Complete| 12.0
109 `P0980R1 <https://wg21.link/P0980R1>`__ LWG Making std::string constexpr Cologne

View File

@ -1,5 +1,5 @@
Number,Name,Assignee,Patch,Status,First released version
`P0645 <https://wg21.link/P0645>`_,"Text Formatting",Mark de Wever,,|Partial|,
`P0645 <https://wg21.link/P0645>`_,"Text Formatting",Mark de Wever,,|Complete|,Clang 14
`P1652 <https://wg21.link/P1652>`_,"Printf corner cases in std::format",Mark de Wever,"`D103433 <https://reviews.llvm.org/D103433>`__, `D114001 <https://reviews.llvm.org/D114001>`__",|Review|,
`P1892 <https://wg21.link/P1892>`_,"Extended locale-specific presentation specifiers for std::format",Mark de Wever,`D103368 <https://reviews.llvm.org/D103368>`__,|Complete|,Clang 14
`P1868 <https://wg21.link/P1868>`_,"width: clarifying units of width and precision in std::format (Implements the unicode support.)",Mark de Wever,"`D103413 <https://reviews.llvm.org/D103413>`__ `D103425 <https://reviews.llvm.org/D103425>`__ `D103670 <https://reviews.llvm.org/D103670>`__",|Complete|,Clang 14

1 Number Name Assignee Patch Status First released version
2 `P0645 <https://wg21.link/P0645>`_ Text Formatting Mark de Wever |Partial| |Complete| Clang 14
3 `P1652 <https://wg21.link/P1652>`_ Printf corner cases in std::format Mark de Wever `D103433 <https://reviews.llvm.org/D103433>`__, `D114001 <https://reviews.llvm.org/D114001>`__ |Review|
4 `P1892 <https://wg21.link/P1892>`_ Extended locale-specific presentation specifiers for std::format Mark de Wever `D103368 <https://reviews.llvm.org/D103368>`__ |Complete| Clang 14
5 `P1868 <https://wg21.link/P1868>`_ width: clarifying units of width and precision in std::format (Implements the unicode support.) Mark de Wever `D103413 <https://reviews.llvm.org/D103413>`__ `D103425 <https://reviews.llvm.org/D103425>`__ `D103670 <https://reviews.llvm.org/D103670>`__ |Complete| Clang 14

View File

@ -14,43 +14,15 @@
namespace std {
// [format.context], class template basic_format_context
template<class Out, class charT>
class basic_format_context {
basic_format_args<basic_format_context> args_; // exposition only
Out out_; // exposition only
public:
using iterator = Out;
using char_type = charT;
template<class T> using formatter_type = formatter<T, charT>;
basic_format_arg<basic_format_context> arg(size_t id) const;
std::locale locale();
iterator out();
void advance_to(iterator it);
};
template<class Out, class charT> class basic_format_context;
using format_context = basic_format_context<unspecified, char>;
using wformat_context = basic_format_context<unspecified, wchar_t>;
// [format.args], class template basic_format_args
template<class Context>
class basic_format_args {
size_t size_; // exposition only
const basic_format_arg<Context>* data_; // exposition only
public:
basic_format_args() noexcept;
template<class... Args>
basic_format_args(const format-arg-store<Context, Args...>& store) noexcept;
basic_format_arg<Context> get(size_t i) const noexcept;
};
template<class Context> class basic_format_args;
using format_args = basic_format_args<format_context>;
using wformat_args = basic_format_args<wformat_context>;
// [format.functions], formatting functions
template<class... Args>
string format(string_view fmt, const Args&... args);
@ -90,8 +62,7 @@ namespace std {
Out out;
iter_difference_t<Out> size;
};
template<class Out, class... Args>
template<class Out, class... Args>
format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
string_view fmt, const Args&... args);
template<class Out, class... Args>
@ -116,99 +87,22 @@ namespace std {
size_t formatted_size(const locale& loc, wstring_view fmt, const Args&... args);
// [format.formatter], formatter
template<> struct formatter<char, char>;
template<> struct formatter<char, wchar_t>;
template<> struct formatter<wchar_t, wchar_t>;
template<> struct formatter<charT*, charT>;
template<> struct formatter<const charT*, charT>;
template<size_t N> struct formatter<const charT[N], charT>;
template<class traits, class Allocator>
struct formatter<basic_string<charT, traits, Allocator>, charT>;
template<class traits>
struct formatter<basic_string_view<charT, traits>, charT>;
template<class T, class charT = char> struct formatter;
// [format.parse.ctx], class template basic_format_parse_context
template<class charT>
class basic_format_parse_context {
public:
using char_type = charT;
using const_iterator = typename basic_string_view<charT>::const_iterator;
using iterator = const_iterator;
private:
iterator begin_; // exposition only
iterator end_; // exposition only
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:
constexpr explicit 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(const_iterator it);
constexpr size_t next_arg_id();
constexpr void check_arg_id(size_t id);
};
template<class charT> class basic_format_parse_context;
using format_parse_context = basic_format_parse_context<char>;
using wformat_parse_context = basic_format_parse_context<wchar_t>;
// [format.arguments], arguments
// [format.arg], class template basic_format_arg
template<class Context>
class basic_format_arg {
public:
class handle;
private:
using char_type = typename Context::char_type; // exposition only
variant<monostate, bool, char_type,
int, unsigned int, long long int, unsigned long long int,
float, double, long double,
const char_type*, basic_string_view<char_type>,
const void*, handle> value; // exposition only
template<class 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
template<class traits, class Allocator>
explicit basic_format_arg(
const basic_string<char_type, traits, Allocator>& s) noexcept; // exposition only
explicit basic_format_arg(nullptr_t) noexcept; // exposition only
template<class T>
explicit basic_format_arg(const T* p) noexcept; // exposition only
public:
basic_format_arg() noexcept;
explicit operator bool() const noexcept;
};
template<class Context> class basic_format_arg;
template<class Visitor, class Context>
see below visit_format_arg(Visitor&& vis, basic_format_arg<Context> arg);
// [format.arg.store], class template format-arg-store
template<class Context, class... Args>
struct format-arg-store { // exposition only
array<basic_format_arg<Context>, sizeof...(Args)> args;
};
template<class Context, class... Args> struct format-arg-store; // exposition only
template<class Context = format_context, class... Args>
format-arg-store<Context, Args...>
@ -218,43 +112,7 @@ namespace std {
make_wformat_args(const Args&... args);
// [format.error], class format_error
class format_error : public runtime_error {
public:
explicit format_error(const string& what_arg);
explicit format_error(const char* what_arg);
};
// [format.parse.ctx], class template basic_format_parse_context
template<class charT>
class basic_format_parse_context {
public:
using char_type = charT;
using const_iterator = typename basic_string_view<charT>::const_iterator;
using iterator = const_iterator;
private:
iterator begin_; // exposition only
iterator end_; // exposition only
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:
constexpr explicit 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(const_iterator it);
constexpr size_t next_arg_id();
constexpr void check_arg_id(size_t id);
};
using format_parse_context = basic_format_parse_context<char>;
using wformat_parse_context = basic_format_parse_context<wchar_t>;
class format_error;
}
*/