xref: /llvm-project/libcxx/test/std/input.output/syncstream/osyncstream/thread/several_threads.pass.cpp (revision 7cc72a0a2ec22855572d96411febd4f2c4ac5a49)
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: c++03, c++11, c++14, c++17
10 // UNSUPPORTED: no-localization
11 // UNSUPPORTED: no-threads
12 // UNSUPPORTED: libcpp-has-no-experimental-syncstream
13 
14 // <syncstream>
15 
16 // template <class charT, class traits, class Allocator>
17 // class basic_osyncstream;
18 
19 // The test writes all elements in test_strings in a random order in ss. Every
20 // write is done by an osyncstream. This means the output is in random order,
21 // but the words should be written without interleaving. To increment the
22 // change of interleaving words are written one character at a time.
23 
24 #include <cassert>
25 #include <chrono>
26 #include <mutex>
27 #include <sstream>
28 #include <string>
29 #include <syncstream>
30 #include <thread>
31 #include <unordered_set>
32 #include <vector>
33 
34 #include "test_macros.h"
35 
36 static std::ostringstream ss;
37 
38 static std::unordered_multiset<std::string> test_strings = {
39     "C++ ",
40     "is ",
41     "a ",
42     "general-purpose ",
43     "programming ",
44     "language ",
45     "created ",
46     "by ",
47     "Bjarne ",
48     "Stroustrup ",
49     "as ",
50     "an ",
51     "extension ",
52     "of ",
53     "the ",
54     "C ",
55     "programming ",
56     "language, ",
57     "or ",
58     "C ",
59     "with ",
60     "Classes. ",
61     "The ",
62     "language ",
63     "has ",
64     "expanded ",
65     "significantly ",
66     "over ",
67     "time, ",
68     "and ",
69     "modern ",
70     "C++ ",
71     "has ",
72     "object-oriented, ",
73     "generic, ",
74     "and ",
75     "functional ",
76     "features ",
77     "in ",
78     "addition ",
79     "to ",
80     "facilities ",
81     "for ",
82     "low-level ",
83     "memory ",
84     "manipulation. ",
85     "It ",
86     "is ",
87     "almost ",
88     "always ",
89     "implemented ",
90     "as ",
91     "a ",
92     "compiled ",
93     "language, ",
94     "and ",
95     "many ",
96     "vendors ",
97     "provide ",
98     "C++ ",
99     "compilers, ",
100     "including ",
101     "the ",
102     "Free ",
103     "Software ",
104     "Foundation, ",
105     "LLVM, ",
106     "Microsoft, ",
107     "Intel, ",
108     "and ",
109     "IBM, ",
110     "so ",
111     "it ",
112     "is ",
113     "available ",
114     "on ",
115     "many ",
116     "platforms."};
117 
f(std::string text)118 void f(std::string text) {
119   std::osyncstream out(ss);
120   for (char c : text)
121     out << c;
122 }
123 
test()124 void test() {
125   ss = std::basic_ostringstream<char>();
126   std::vector<std::thread> threads;
127   for (std::string const& word : test_strings)
128     threads.push_back(std::thread(f, word));
129 
130   for (auto& thread : threads)
131     thread.join();
132 
133   std::string output = ss.str();
134   for (const std::string& word : test_strings)
135     assert(output.find(word) != std::string::npos);
136 }
137 
main(int,char **)138 int main(int, char**) {
139   // The more we test, the more likely we catch an error
140   for (size_t i = 0; i < 1024; ++i)
141     test();
142 
143   return 0;
144 }
145