1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9// UNSUPPORTED: no-threads
10// UNSUPPORTED: no-localization
11// UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME
12
13// REQUIRES: locale.fr_FR.UTF-8
14
15// TODO FMT This test should not require std::to_chars(floating-point)
16// XFAIL: availability-fp_to_chars-missing
17
18// <thread>
19
20// class thread::id
21
22// template<class charT, class traits>
23// basic_ostream<charT, traits>&
24// operator<<(basic_ostream<charT, traits>& out, thread::id id);
25
26#include <cassert>
27#include <format>
28#include <locale>
29#include <sstream>
30#include <thread>
31
32#include "make_string.h"
33#include "platform_support.h" // locale name macros
34#include "test_macros.h"
35
36template <class CharT>
37static void basic() {
38 std::thread::id id0 = std::this_thread::get_id();
39 std::basic_ostringstream<CharT> os;
40 os << id0;
41
42#if TEST_STD_VER > 20
43 // C++23 added a formatter specialization for thread::id.
44 // This changed the requirement of ostream to have a
45 // [thread.thread.id]/2
46 // The text representation for the character type charT of an object of
47 // type thread::id is an unspecified sequence of charT ...
48 // This definition is used for both streaming and formatting.
49 //
50 // Test whether the output is identical.
51 std::basic_string<CharT> s = std::format(MAKE_STRING_VIEW(CharT, "{}"), id0);
52 assert(s == os.str());
53#endif
54}
55
56template <class CharT>
57static std::basic_string<CharT> format(std::ios_base::fmtflags flags) {
58 std::basic_stringstream<CharT> sstr;
59 sstr.flags(flags);
60 sstr << std::this_thread::get_id();
61 return sstr.str();
62}
63
64template <class CharT>
65static void stream_state() {
66 std::basic_stringstream<CharT> sstr;
67 sstr << std::this_thread::get_id();
68 std::basic_string<CharT> expected = sstr.str();
69
70 // Unaffected by fill, width, and align.
71
72 assert(expected == format<CharT>(std::ios_base::dec | std::ios_base::skipws)); // default flags
73
74 assert(expected == format<CharT>(std::ios_base::oct));
75 assert(expected == format<CharT>(std::ios_base::hex));
76
77 assert(expected == format<CharT>(std::ios_base::scientific));
78 assert(expected == format<CharT>(std::ios_base::fixed));
79
80 assert(expected == format<CharT>(std::ios_base::boolalpha));
81 assert(expected == format<CharT>(std::ios_base::showbase));
82 assert(expected == format<CharT>(std::ios_base::showpoint));
83 assert(expected == format<CharT>(std::ios_base::showpos));
84 assert(expected == format<CharT>(std::ios_base::skipws)); // added for completeness
85 assert(expected == format<CharT>(std::ios_base::unitbuf)); // added for completeness
86 assert(expected == format<CharT>(std::ios_base::uppercase));
87
88 // Test fill, width, and align.
89
90 sstr.str(std::basic_string<CharT>());
91 sstr.fill(CharT('#'));
92 sstr.width(expected.size() + 10); // Make sure fill and align affect the output.
93 sstr.flags(std::ios_base::dec | std::ios_base::skipws | std::ios_base::right);
94 sstr << std::this_thread::get_id();
95 expected = sstr.str();
96
97 sstr.str(std::basic_string<CharT>());
98 sstr.fill(CharT('*'));
99 sstr.width(expected.size());
100 sstr.flags(std::ios_base::dec | std::ios_base::skipws | std::ios_base::right);
101 sstr << std::this_thread::get_id();
102 assert(expected != sstr.str());
103
104 sstr.str(std::basic_string<CharT>());
105 sstr.fill(CharT('#'));
106 sstr.width(expected.size() - 1);
107 sstr.flags(std::ios_base::dec | std::ios_base::skipws | std::ios_base::right);
108 sstr << std::this_thread::get_id();
109 assert(expected != sstr.str());
110
111 sstr.str(std::basic_string<CharT>());
112 sstr.fill(CharT('#'));
113 sstr.width(expected.size());
114 sstr.flags(std::ios_base::dec | std::ios_base::skipws | std::ios_base::left);
115 sstr << std::this_thread::get_id();
116 assert(expected != sstr.str());
117
118 sstr.str(std::basic_string<CharT>());
119 sstr.fill(CharT('#'));
120 sstr.width(expected.size());
121 sstr.flags(std::ios_base::dec | std::ios_base::skipws | std::ios_base::internal);
122 sstr << std::this_thread::get_id();
123 assert(expected == sstr.str()); // internal does *not* affect strings
124
125 // Test the locale's numpunct.
126
127 std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
128 sstr.str(std::basic_string<CharT>());
129 sstr.fill(CharT('#'));
130 sstr.width(expected.size());
131 sstr << std::this_thread::get_id();
132 assert(expected == sstr.str());
133}
134
135template <class CharT>
136static void test() {
137 basic<CharT>();
138 stream_state<CharT>();
139}
140
141int main(int, char**) {
142 test<char>();
143#ifndef TEST_HAS_NO_WIDE_CHARACTERS
144 test<wchar_t>();
145#endif
146
147 return 0;
148}
149

source code of libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/stream.pass.cpp