xref: /llvm-project/libcxx/test/std/thread/thread.stoptoken/stopsource/move.copy.pass.cpp (revision 121ed5c1985356436d0040dbe81bca26992b1fae)
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: c++03, c++11, c++14, c++17
11 // XFAIL: availability-synchronization_library-missing
12 
13 // stop_source& operator=(stop_source&& rhs) noexcept;
14 
15 #include <cassert>
16 #include <concepts>
17 #include <stop_token>
18 #include <type_traits>
19 #include <utility>
20 
21 #include "test_macros.h"
22 
23 static_assert(std::is_nothrow_move_assignable_v<std::stop_source>);
24 
25 int main(int, char**) {
26   // have two different states
27   {
28     std::stop_source ss1;
29     std::stop_source ss2;
30 
31     assert(ss1 != ss2);
32 
33     ss2.request_stop();
34 
35     assert(!ss1.stop_requested());
36     assert(ss2.stop_requested());
37 
38     std::same_as<std::stop_source&> decltype(auto) ref = ss1 = std::move(ss2);
39     assert(&ref == &ss1);
40 
41     assert(ss1.stop_requested());
42     assert(!ss2.stop_possible());
43     assert(!ss2.stop_requested());
44   }
45 
46   // this has no state
47   {
48     std::stop_source ss1{std::nostopstate};
49     std::stop_source ss2;
50 
51     assert(ss1 != ss2);
52 
53     ss2.request_stop();
54 
55     assert(!ss1.stop_requested());
56     assert(!ss1.stop_possible());
57     assert(ss2.stop_requested());
58     assert(ss2.stop_possible());
59 
60     std::same_as<std::stop_source&> decltype(auto) ref = ss1 = std::move(ss2);
61     assert(&ref == &ss1);
62 
63     assert(ss1.stop_requested());
64     assert(ss1.stop_possible());
65     assert(!ss2.stop_requested());
66     assert(!ss2.stop_possible());
67   }
68 
69   // other has no state
70   {
71     std::stop_source ss1;
72     std::stop_source ss2{std::nostopstate};
73 
74     assert(ss1 != ss2);
75 
76     ss1.request_stop();
77 
78     assert(ss1.stop_requested());
79     assert(ss1.stop_possible());
80     assert(!ss2.stop_requested());
81     assert(!ss2.stop_possible());
82 
83     std::same_as<std::stop_source&> decltype(auto) ref = ss1 = std::move(ss2);
84     assert(&ref == &ss1);
85 
86     assert(ss1 == ss2);
87     assert(!ss1.stop_requested());
88     assert(!ss1.stop_possible());
89     assert(!ss2.stop_requested());
90     assert(!ss2.stop_possible());
91   }
92 
93   // both no state
94   {
95     std::stop_source ss1{std::nostopstate};
96     std::stop_source ss2{std::nostopstate};
97 
98     assert(ss1 == ss2);
99 
100     assert(!ss1.stop_requested());
101     assert(!ss1.stop_possible());
102     assert(!ss2.stop_requested());
103     assert(!ss2.stop_possible());
104 
105     std::same_as<std::stop_source&> decltype(auto) ref = ss1 = std::move(ss2);
106     assert(&ref == &ss1);
107 
108     assert(ss1 == ss2);
109     assert(!ss1.stop_requested());
110     assert(!ss1.stop_possible());
111     assert(!ss2.stop_requested());
112     assert(!ss2.stop_possible());
113   }
114 
115   // self assignment
116   {
117     std::stop_source ss;
118     auto& self = ss;
119 
120     assert(!ss.stop_requested());
121 
122     std::same_as<std::stop_source&> decltype(auto) ref = ss = std::move(self);
123     assert(&ref == &ss);
124 
125     assert(!ss.stop_requested());
126 
127     ss.request_stop();
128     assert(ss.stop_requested());
129   }
130 
131   return 0;
132 }
133