Home | History | Annotate | Download | only in thread.thread.constr
      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 // <thread>
     11 
     12 // class thread
     13 
     14 // template <class F, class ...Args> thread(F&& f, Args&&... args);
     15 
     16 #include <thread>
     17 #include <new>
     18 #include <cstdlib>
     19 #include <cassert>
     20 
     21 unsigned throw_one = 0xFFFF;
     22 
     23 void* operator new(std::size_t s) throw(std::bad_alloc)
     24 {
     25     if (throw_one == 0)
     26         throw std::bad_alloc();
     27     --throw_one;
     28     return std::malloc(s);
     29 }
     30 
     31 void  operator delete(void* p) throw()
     32 {
     33     std::free(p);
     34 }
     35 
     36 bool f_run = false;
     37 
     38 void f()
     39 {
     40     f_run = true;
     41 }
     42 
     43 class G
     44 {
     45     int alive_;
     46 public:
     47     static int n_alive;
     48     static bool op_run;
     49 
     50     G() : alive_(1) {++n_alive;}
     51     G(const G& g) : alive_(g.alive_) {++n_alive;}
     52     ~G() {alive_ = 0; --n_alive;}
     53 
     54     void operator()()
     55     {
     56         assert(alive_ == 1);
     57         assert(n_alive >= 1);
     58         op_run = true;
     59     }
     60 
     61     void operator()(int i, double j)
     62     {
     63         assert(alive_ == 1);
     64         assert(n_alive >= 1);
     65         assert(i == 5);
     66         assert(j == 5.5);
     67         op_run = true;
     68     }
     69 };
     70 
     71 int G::n_alive = 0;
     72 bool G::op_run = false;
     73 
     74 #ifndef _LIBCPP_HAS_NO_VARIADICS
     75 
     76 class MoveOnly
     77 {
     78     MoveOnly(const MoveOnly&);
     79 public:
     80     MoveOnly() {}
     81     MoveOnly(MoveOnly&&) {}
     82 
     83     void operator()(MoveOnly&&)
     84     {
     85     }
     86 };
     87 
     88 #endif
     89 
     90 int main()
     91 {
     92     {
     93         std::thread t(f);
     94         t.join();
     95         assert(f_run == true);
     96     }
     97     f_run = false;
     98     {
     99         try
    100         {
    101             throw_one = 0;
    102             std::thread t(f);
    103             assert(false);
    104         }
    105         catch (...)
    106         {
    107             throw_one = 0xFFFF;
    108             assert(!f_run);
    109         }
    110     }
    111     {
    112         assert(G::n_alive == 0);
    113         assert(!G::op_run);
    114         std::thread t((G()));
    115         t.join();
    116         assert(G::n_alive == 0);
    117         assert(G::op_run);
    118     }
    119     G::op_run = false;
    120     {
    121         try
    122         {
    123             throw_one = 0;
    124             assert(G::n_alive == 0);
    125             assert(!G::op_run);
    126             std::thread t((G()));
    127             assert(false);
    128         }
    129         catch (...)
    130         {
    131             throw_one = 0xFFFF;
    132             assert(G::n_alive == 0);
    133             assert(!G::op_run);
    134         }
    135     }
    136 #ifndef _LIBCPP_HAS_NO_VARIADICS
    137     {
    138         assert(G::n_alive == 0);
    139         assert(!G::op_run);
    140         std::thread t(G(), 5, 5.5);
    141         t.join();
    142         assert(G::n_alive == 0);
    143         assert(G::op_run);
    144     }
    145     {
    146         std::thread t = std::thread(MoveOnly(), MoveOnly());
    147         t.join();
    148     }
    149 #endif  // _LIBCPP_HAS_NO_VARIADICS
    150 }
    151