Skip to content

Commit

Permalink
[libc++][format] Implements formatter thread::id.
Browse files Browse the repository at this point in the history
Since stacktrace header is WIP and it's not sure that will be done
before LLVM17 update the documentation. When the header is implemented
implementing the formatter is trivial, so that can be done quickly
afterwards.

Implements parts of:
 - P2693R1 Formatting thread::id and stacktrace

Reviewed By: #libc, ldionne

Differential Revision: https://reviews.llvm.org/D144331
  • Loading branch information
mordante committed Apr 8, 2023
1 parent f43adc4 commit 88622aa
Show file tree
Hide file tree
Showing 25 changed files with 547 additions and 11 deletions.
2 changes: 2 additions & 0 deletions libcxx/docs/FeatureTestMacroTable.rst
Expand Up @@ -322,6 +322,8 @@ Status
------------------------------------------------- -----------------
``__cpp_lib_expected`` ``202202L``
------------------------------------------------- -----------------
``__cpp_lib_formatters`` *unimplemented*
------------------------------------------------- -----------------
``__cpp_lib_forward_like`` ``202207L``
------------------------------------------------- -----------------
``__cpp_lib_invoke_r`` ``202106L``
Expand Down
1 change: 1 addition & 0 deletions libcxx/docs/ReleaseNotes.rst
Expand Up @@ -39,6 +39,7 @@ Implemented Papers
------------------
- P2520R0 - ``move_iterator<T*>`` should be a random access iterator
- P1328R1 - ``constexpr type_info::operator==()``
- P1413R3 - Formatting ``thread::id`` (the ``stacktrace`` is not done yet)

This comment has been minimized.

Copy link
@tambry

tambry Jul 21, 2023

Contributor

This should be P2693R1! Ditto in libcxx/docs/Status/Cxx23.rst.

This comment has been minimized.

Copy link
@mordante

mordante Jul 22, 2023

Author Member

Thanks! Fixed in 770b020


Improvements and New Features
-----------------------------
Expand Down
3 changes: 3 additions & 0 deletions libcxx/docs/Status/Cxx2b.rst
Expand Up @@ -44,6 +44,9 @@ Paper Status
clang doesn't issue a diagnostic for deprecated using template declarations.
.. [#note-P2520R0] P2520R0: Libc++ implemented this paper as a DR in C++20 as well.
.. [#note-P2711R1] P2711R1: ``join_with_view`` hasn't been done yet since this type isn't implemented yet.
.. [#note-P2693R1] P1413R3: The formatter for ``std::thread::id`` is implemented.
The formatter for ``stacktrace`` is not implemented, since ``stacktrace`` is
not implemented yet.
.. _issues-status-cxx2b:

Expand Down
2 changes: 1 addition & 1 deletion libcxx/docs/Status/Cxx2bPapers.csv
Expand Up @@ -113,7 +113,7 @@
"`P2713R1 <https://wg21.link/P2713R1>`__","LWG", "Escaping improvements in ``std::format``","February 2023","","","|format|"
"`P2675R1 <https://wg21.link/P2675R1>`__","LWG", "``format``'s width estimation is too approximate and not forward compatible","February 2023","","","|format|"
"`P2572R1 <https://wg21.link/P2572R1>`__","LWG", "``std::format`` fill character allowances","February 2023","","","|format|"
"`P2693R1 <https://wg21.link/P2693R1>`__","LWG", "Formatting ``thread::id`` and ``stacktrace``","February 2023","","","|format|"
"`P2693R1 <https://wg21.link/P2693R1>`__","LWG", "Formatting ``thread::id`` and ``stacktrace``","February 2023","|Partial| [#note-P2693R1]_","","|format|"
"`P2679R2 <https://wg21.link/P2679R2>`__","LWG", "Fixing ``std::start_lifetime_as`` for arrays","February 2023","","",""
"`P2674R1 <https://wg21.link/P2674R1>`__","LWG", "A trait for implicit lifetime types","February 2023","","",""
"`P2655R3 <https://wg21.link/P2655R3>`__","LWG", "``common_reference_t`` of ``reference_wrapper`` Should Be a Reference Type","February 2023","","",""
Expand Down
2 changes: 1 addition & 1 deletion libcxx/docs/Status/FormatPaper.csv
Expand Up @@ -40,5 +40,5 @@ Section,Description,Dependencies,Assignee,Status,First released version
`[format.range.fmtstr] <https://wg21.link/format.range.fmtstr>`_,"Formatting for ranges: strings",,Mark de Wever,|In Progress|,
`[format.range.fmtstr] <https://wg21.link/format.range.fmtstr>`_,"Formatting for ranges: strings",,Mark de Wever,|In Progress|,
"`P2693R1 <https://wg21.link/P2693R1>`__","Formatting ``thread::id`` and ``stacktrace``"
`[thread.thread.id] <https://wg21.link/thread.thread.id>`_,"Formatting ``thread::id``",,Mark de Wever,|In Progress|,
`[thread.thread.id] <https://wg21.link/thread.thread.id>`_,"Formatting ``thread::id``",,Mark de Wever,|Complete|,Clang 17
`[stacktrace.format] <https://wg21.link/stacktrace.format>`_,"Formatting ``stacktrace``",A ``<stacktrace>`` implementation,Mark de Wever,,
1 change: 1 addition & 0 deletions libcxx/include/__format/parser_std_format_spec.h
Expand Up @@ -143,6 +143,7 @@ inline constexpr __fields __fields_pointer{.__type_ = true};
# if _LIBCPP_STD_VER >= 23
inline constexpr __fields __fields_tuple{.__use_range_fill_ = true};
inline constexpr __fields __fields_range{.__use_range_fill_ = true};
inline constexpr __fields __fields_fill_align_width{};
# endif

enum class _LIBCPP_ENUM_VIS __alignment : uint8_t {
Expand Down
2 changes: 2 additions & 0 deletions libcxx/include/__threading_support
Expand Up @@ -643,6 +643,8 @@ private:
_LIBCPP_INLINE_VISIBILITY
__thread_id(__libcpp_thread_id __id) : __id_(__id) {}

_LIBCPP_HIDE_FROM_ABI friend __libcpp_thread_id __get_underlying_id(const __thread_id __id) { return __id.__id_; }

friend __thread_id this_thread::get_id() _NOEXCEPT;
friend class _LIBCPP_TYPE_VIS thread;
friend struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>;
Expand Down
49 changes: 49 additions & 0 deletions libcxx/include/thread
Expand Up @@ -64,6 +64,9 @@ template<class charT, class traits>
basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& out, thread::id id);
template<class charT>
struct formatter<thread::id, charT>;
namespace this_thread
{
Expand All @@ -84,11 +87,18 @@ void sleep_for(const chrono::duration<Rep, Period>& rel_time);
*/

#include <__assert> // all public C++ headers provide the assertion handler
#include <__availability>
#include <__chrono/steady_clock.h>
#include <__chrono/time_point.h>
#include <__concepts/arithmetic.h>
#include <__condition_variable/condition_variable.h>
#include <__config>
#include <__exception/terminate.h>
#include <__format/concepts.h>
#include <__format/format_parse_context.h>
#include <__format/formatter.h>
#include <__format/formatter_integral.h>
#include <__format/parser_std_format_spec.h>
#include <__functional/hash.h>
#include <__memory/addressof.h>
#include <__memory/unique_ptr.h>
Expand Down Expand Up @@ -224,6 +234,45 @@ basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id)
{return __os << __id.__id_;}

#if _LIBCPP_STD_VER >= 23
template <__fmt_char_type _CharT>
struct _LIBCPP_TEMPLATE_VIS formatter<__thread_id, _CharT> {
public:
_LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
-> decltype(__parse_ctx.begin()) {
return __parser_.__parse(__parse_ctx, __format_spec::__fields_fill_align_width);
}

_LIBCPP_HIDE_FROM_ABI auto format(__thread_id __id, auto& __ctx) const -> decltype(__ctx.out()) {
// In __threading_support __libcpp_thread_id is either a
// unsigned long long or a pthread_t.
//
// The type of pthread_t is left unspecified in POSIX so it can be any
// type. The most logical types are an integral or pointer.
// On Linux systems pthread_t is an unsigned long long.
// On Apple systems pthread_t is a pointer type.
//
// Note the output should match what the stream operator does. Since
// the ostream operator has been shipped years before this formatter
// was added to the Standard, this formatter does what the stream
// operator does. This may require platform specific changes.

using _Tp = decltype(__get_underlying_id(__id));
using _Cp = conditional_t<integral<_Tp>, _Tp, conditional_t<is_pointer_v<_Tp>, uintptr_t, void>>;
static_assert(!is_same_v<_Cp, void>, "unsupported thread::id type, please file a bug report");

__format_spec::__parsed_specifications<_CharT> __specs = __parser_.__get_parsed_std_specifications(__ctx);
if constexpr (is_pointer_v<_Tp>) {
__specs.__std_.__alternate_form_ = true;
__specs.__std_.__type_ = __format_spec::__type::__hexadecimal_lower_case;
}
return __formatter::__format_integer(reinterpret_cast<_Cp>(__get_underlying_id(__id)), __ctx, __specs);
}

__format_spec::__parser<_CharT> __parser_{.__alignment_ = __format_spec::__alignment::__right};
};
#endif // _LIBCPP_STD_VER >= 23

class _LIBCPP_TYPE_VIS thread
{
__libcpp_thread_t __t_;
Expand Down
4 changes: 4 additions & 0 deletions libcxx/include/version
Expand Up @@ -85,6 +85,7 @@ __cpp_lib_execution 201902L <execution>
__cpp_lib_expected 202202L <expected>
__cpp_lib_filesystem 201703L <filesystem>
__cpp_lib_format 202106L <format>
__cpp_lib_formatters 202302L <stacktrace> <thread>
__cpp_lib_forward_like 202207L <utility>
__cpp_lib_gcd_lcm 201606L <numeric>
__cpp_lib_generic_associative_lookup 201304L <map> <set>
Expand Down Expand Up @@ -397,6 +398,9 @@ __cpp_lib_void_t 201411L <type_traits>
# define __cpp_lib_constexpr_memory 202202L
# define __cpp_lib_constexpr_typeinfo 202106L
# define __cpp_lib_expected 202202L
# if !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
// # define __cpp_lib_formatters 202302L
# endif
# define __cpp_lib_forward_like 202207L
# define __cpp_lib_invoke_r 202106L
# define __cpp_lib_is_scoped_enum 202011L
Expand Down
5 changes: 5 additions & 0 deletions libcxx/test/libcxx/transitive_includes/cxx03.csv
Expand Up @@ -829,6 +829,7 @@ system_error stdexcept
system_error string
system_error type_traits
system_error version
thread array
thread chrono
thread compare
thread cstddef
Expand All @@ -838,11 +839,15 @@ thread ctime
thread functional
thread iosfwd
thread limits
thread locale
thread new
thread ratio
thread string
thread string_view
thread system_error
thread tuple
thread type_traits
thread vector
thread version
tuple compare
tuple cstddef
Expand Down
5 changes: 5 additions & 0 deletions libcxx/test/libcxx/transitive_includes/cxx11.csv
Expand Up @@ -830,6 +830,7 @@ system_error stdexcept
system_error string
system_error type_traits
system_error version
thread array
thread chrono
thread compare
thread cstddef
Expand All @@ -839,11 +840,15 @@ thread ctime
thread functional
thread iosfwd
thread limits
thread locale
thread new
thread ratio
thread string
thread string_view
thread system_error
thread tuple
thread type_traits
thread vector
thread version
tuple compare
tuple cstddef
Expand Down
5 changes: 5 additions & 0 deletions libcxx/test/libcxx/transitive_includes/cxx14.csv
Expand Up @@ -832,6 +832,7 @@ system_error stdexcept
system_error string
system_error type_traits
system_error version
thread array
thread chrono
thread compare
thread cstddef
Expand All @@ -841,11 +842,15 @@ thread ctime
thread functional
thread iosfwd
thread limits
thread locale
thread new
thread ratio
thread string
thread string_view
thread system_error
thread tuple
thread type_traits
thread vector
thread version
tuple compare
tuple cstddef
Expand Down
5 changes: 5 additions & 0 deletions libcxx/test/libcxx/transitive_includes/cxx17.csv
Expand Up @@ -832,6 +832,7 @@ system_error stdexcept
system_error string
system_error type_traits
system_error version
thread array
thread chrono
thread compare
thread cstddef
Expand All @@ -841,11 +842,15 @@ thread ctime
thread functional
thread iosfwd
thread limits
thread locale
thread new
thread ratio
thread string
thread string_view
thread system_error
thread tuple
thread type_traits
thread vector
thread version
tuple compare
tuple cstddef
Expand Down
7 changes: 7 additions & 0 deletions libcxx/test/libcxx/transitive_includes/cxx20.csv
Expand Up @@ -838,19 +838,26 @@ system_error stdexcept
system_error string
system_error type_traits
system_error version
thread array
thread compare
thread cstddef
thread cstdint
thread cstdlib
thread cstring
thread ctime
thread functional
thread iosfwd
thread limits
thread locale
thread new
thread ratio
thread stdexcept
thread string
thread string_view
thread system_error
thread tuple
thread type_traits
thread vector
thread version
tuple compare
tuple cstddef
Expand Down
8 changes: 8 additions & 0 deletions libcxx/test/libcxx/transitive_includes/cxx2b.csv
Expand Up @@ -584,14 +584,22 @@ system_error limits
system_error stdexcept
system_error string
system_error version
thread array
thread compare
thread cstddef
thread cstdint
thread cstdlib
thread ctime
thread iosfwd
thread limits
thread locale
thread ratio
thread stdexcept
thread string
thread string_view
thread system_error
thread tuple
thread vector
thread version
tuple compare
tuple cstddef
Expand Down
Expand Up @@ -17,33 +17,50 @@

// Test the feature test macros defined by <thread>

/* Constant Value
__cpp_lib_jthread 201911L [C++20]
/* Constant Value
__cpp_lib_formatters 202302L [C++2b]
__cpp_lib_jthread 201911L [C++20]
*/

#include <thread>
#include "test_macros.h"

#if TEST_STD_VER < 14

# ifdef __cpp_lib_formatters
# error "__cpp_lib_formatters should not be defined before c++2b"
# endif

# ifdef __cpp_lib_jthread
# error "__cpp_lib_jthread should not be defined before c++20"
# endif

#elif TEST_STD_VER == 14

# ifdef __cpp_lib_formatters
# error "__cpp_lib_formatters should not be defined before c++2b"
# endif

# ifdef __cpp_lib_jthread
# error "__cpp_lib_jthread should not be defined before c++20"
# endif

#elif TEST_STD_VER == 17

# ifdef __cpp_lib_formatters
# error "__cpp_lib_formatters should not be defined before c++2b"
# endif

# ifdef __cpp_lib_jthread
# error "__cpp_lib_jthread should not be defined before c++20"
# endif

#elif TEST_STD_VER == 20

# ifdef __cpp_lib_formatters
# error "__cpp_lib_formatters should not be defined before c++2b"
# endif

# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_jthread
# error "__cpp_lib_jthread should be defined in c++20"
Expand All @@ -59,6 +76,19 @@

#elif TEST_STD_VER > 20

# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_formatters
# error "__cpp_lib_formatters should be defined in c++2b"
# endif
# if __cpp_lib_formatters != 202302L
# error "__cpp_lib_formatters should have the value 202302L in c++2b"
# endif
# else // _LIBCPP_VERSION
# ifdef __cpp_lib_formatters
# error "__cpp_lib_formatters should not be defined because it is unimplemented in libc++!"
# endif
# endif

# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_jthread
# error "__cpp_lib_jthread should be defined in c++2b"
Expand Down

0 comments on commit 88622aa

Please sign in to comment.