1 //===----------------------------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // UNSUPPORTED: libcpp-has-no-threads 11 12 // <thread> 13 14 // class thread 15 16 // template <class F, class ...Args> thread(F&& f, Args&&... args); 17 18 // UNSUPPORTED: sanitizer-new-delete 19 20 #include <thread> 21 #include <new> 22 #include <cstdlib> 23 #include <cassert> 24 25 #include "test_macros.h" 26 27 unsigned throw_one = 0xFFFF; 28 operator new(std::size_t s)29void* operator new(std::size_t s) throw(std::bad_alloc) 30 { 31 if (throw_one == 0) 32 throw std::bad_alloc(); 33 --throw_one; 34 return std::malloc(s); 35 } 36 operator delete(void * p)37void operator delete(void* p) throw() 38 { 39 std::free(p); 40 } 41 42 bool f_run = false; 43 f()44void f() 45 { 46 f_run = true; 47 } 48 49 class G 50 { 51 int alive_; 52 public: 53 static int n_alive; 54 static bool op_run; 55 G()56 G() : alive_(1) {++n_alive;} G(const G & g)57 G(const G& g) : alive_(g.alive_) {++n_alive;} ~G()58 ~G() {alive_ = 0; --n_alive;} 59 operator ()()60 void operator()() 61 { 62 assert(alive_ == 1); 63 assert(n_alive >= 1); 64 op_run = true; 65 } 66 operator ()(int i,double j)67 void operator()(int i, double j) 68 { 69 assert(alive_ == 1); 70 assert(n_alive >= 1); 71 assert(i == 5); 72 assert(j == 5.5); 73 op_run = true; 74 } 75 }; 76 77 int G::n_alive = 0; 78 bool G::op_run = false; 79 80 #if TEST_STD_VER >= 11 81 82 class MoveOnly 83 { 84 MoveOnly(const MoveOnly&); 85 public: MoveOnly()86 MoveOnly() {} MoveOnly(MoveOnly &&)87 MoveOnly(MoveOnly&&) {} 88 operator ()(MoveOnly &&)89 void operator()(MoveOnly&&) 90 { 91 } 92 }; 93 94 #endif 95 main()96int main() 97 { 98 { 99 std::thread t(f); 100 t.join(); 101 assert(f_run == true); 102 } 103 f_run = false; 104 { 105 try 106 { 107 throw_one = 0; 108 std::thread t(f); 109 assert(false); 110 } 111 catch (...) 112 { 113 throw_one = 0xFFFF; 114 assert(!f_run); 115 } 116 } 117 { 118 assert(G::n_alive == 0); 119 assert(!G::op_run); 120 std::thread t((G())); 121 t.join(); 122 assert(G::n_alive == 0); 123 assert(G::op_run); 124 } 125 G::op_run = false; 126 { 127 try 128 { 129 throw_one = 0; 130 assert(G::n_alive == 0); 131 assert(!G::op_run); 132 std::thread t((G())); 133 assert(false); 134 } 135 catch (...) 136 { 137 throw_one = 0xFFFF; 138 assert(G::n_alive == 0); 139 assert(!G::op_run); 140 } 141 } 142 #if TEST_STD_VER >= 11 143 { 144 assert(G::n_alive == 0); 145 assert(!G::op_run); 146 std::thread t(G(), 5, 5.5); 147 t.join(); 148 assert(G::n_alive == 0); 149 assert(G::op_run); 150 } 151 { 152 std::thread t = std::thread(MoveOnly(), MoveOnly()); 153 t.join(); 154 } 155 #endif 156 } 157