106c3fb27SDimitry Andric // -*- C++ -*- 206c3fb27SDimitry Andric //===----------------------------------------------------------------------===// 306c3fb27SDimitry Andric // 406c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 506c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 606c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 706c3fb27SDimitry Andric // 806c3fb27SDimitry Andric //===----------------------------------------------------------------------===// 906c3fb27SDimitry Andric 1006c3fb27SDimitry Andric #ifndef _LIBCPP___THREAD_FORMATTER_H 1106c3fb27SDimitry Andric #define _LIBCPP___THREAD_FORMATTER_H 1206c3fb27SDimitry Andric 1306c3fb27SDimitry Andric #include <__concepts/arithmetic.h> 1406c3fb27SDimitry Andric #include <__config> 1506c3fb27SDimitry Andric #include <__format/concepts.h> 1606c3fb27SDimitry Andric #include <__format/format_parse_context.h> 1706c3fb27SDimitry Andric #include <__format/formatter.h> 1806c3fb27SDimitry Andric #include <__format/formatter_integral.h> 1906c3fb27SDimitry Andric #include <__format/parser_std_format_spec.h> 2006c3fb27SDimitry Andric #include <__thread/id.h> 2106c3fb27SDimitry Andric #include <__type_traits/conditional.h> 2206c3fb27SDimitry Andric #include <__type_traits/is_pointer.h> 2306c3fb27SDimitry Andric #include <__type_traits/is_same.h> 2406c3fb27SDimitry Andric #include <cstdint> 2506c3fb27SDimitry Andric 2606c3fb27SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 2706c3fb27SDimitry Andric # pragma GCC system_header 2806c3fb27SDimitry Andric #endif 2906c3fb27SDimitry Andric 3006c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 23 3106c3fb27SDimitry Andric 3206c3fb27SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 3306c3fb27SDimitry Andric 3406c3fb27SDimitry Andric # ifndef _LIBCPP_HAS_NO_THREADS 3506c3fb27SDimitry Andric 3606c3fb27SDimitry Andric template <__fmt_char_type _CharT> 3706c3fb27SDimitry Andric struct _LIBCPP_TEMPLATE_VIS formatter<__thread_id, _CharT> { 3806c3fb27SDimitry Andric public: 3906c3fb27SDimitry Andric template <class _ParseContext> 4006c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { 4106c3fb27SDimitry Andric return __parser_.__parse(__ctx, __format_spec::__fields_fill_align_width); 4206c3fb27SDimitry Andric } 4306c3fb27SDimitry Andric 4406c3fb27SDimitry Andric template <class _FormatContext> 4506c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(__thread_id __id, _FormatContext& __ctx) const { 46*0fca6ea1SDimitry Andric // In __thread/support/pthread.h, __libcpp_thread_id is either a 4706c3fb27SDimitry Andric // unsigned long long or a pthread_t. 4806c3fb27SDimitry Andric // 4906c3fb27SDimitry Andric // The type of pthread_t is left unspecified in POSIX so it can be any 5006c3fb27SDimitry Andric // type. The most logical types are an integral or pointer. 5106c3fb27SDimitry Andric // On Linux systems pthread_t is an unsigned long long. 5206c3fb27SDimitry Andric // On Apple systems pthread_t is a pointer type. 5306c3fb27SDimitry Andric // 5406c3fb27SDimitry Andric // Note the output should match what the stream operator does. Since 5506c3fb27SDimitry Andric // the ostream operator has been shipped years before this formatter 5606c3fb27SDimitry Andric // was added to the Standard, this formatter does what the stream 5706c3fb27SDimitry Andric // operator does. This may require platform specific changes. 5806c3fb27SDimitry Andric 5906c3fb27SDimitry Andric using _Tp = decltype(__get_underlying_id(__id)); 6006c3fb27SDimitry Andric using _Cp = conditional_t<integral<_Tp>, _Tp, conditional_t<is_pointer_v<_Tp>, uintptr_t, void>>; 6106c3fb27SDimitry Andric static_assert(!is_same_v<_Cp, void>, "unsupported thread::id type, please file a bug report"); 6206c3fb27SDimitry Andric 6306c3fb27SDimitry Andric __format_spec::__parsed_specifications<_CharT> __specs = __parser_.__get_parsed_std_specifications(__ctx); 6406c3fb27SDimitry Andric if constexpr (is_pointer_v<_Tp>) { 6506c3fb27SDimitry Andric __specs.__std_.__alternate_form_ = true; 6606c3fb27SDimitry Andric __specs.__std_.__type_ = __format_spec::__type::__hexadecimal_lower_case; 6706c3fb27SDimitry Andric } 6806c3fb27SDimitry Andric return __formatter::__format_integer(reinterpret_cast<_Cp>(__get_underlying_id(__id)), __ctx, __specs); 6906c3fb27SDimitry Andric } 7006c3fb27SDimitry Andric 7106c3fb27SDimitry Andric __format_spec::__parser<_CharT> __parser_{.__alignment_ = __format_spec::__alignment::__right}; 7206c3fb27SDimitry Andric }; 7306c3fb27SDimitry Andric 7406c3fb27SDimitry Andric # endif // !_LIBCPP_HAS_NO_THREADS 7506c3fb27SDimitry Andric 7606c3fb27SDimitry Andric _LIBCPP_END_NAMESPACE_STD 7706c3fb27SDimitry Andric 7806c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 23 7906c3fb27SDimitry Andric 8006c3fb27SDimitry Andric #endif // _LIBCPP___THREAD_FORMATTER_H 81