1 // PR c++/53202 2 // { dg-do run { target c++11 } } 3 4 #include <tuple> 5 6 template<typename Callable> 7 struct Bind_simple 8 { 9 explicit Bind_simpleBind_simple10 Bind_simple(const Callable& callable) 11 : _M_bound(callable) 12 { } 13 14 Bind_simple(const Bind_simple&) = default; 15 Bind_simple(Bind_simple&&) = default; 16 17 auto operator()() -> decltype((*(Callable*)0)()) 18 { 19 return std::get<0>(_M_bound)(); 20 } 21 22 private: 23 24 std::tuple<Callable> _M_bound; 25 }; 26 27 template<typename Callable> 28 Bind_simple<Callable> bind_simple(Callable & callable)29 bind_simple(Callable& callable) 30 { 31 return Bind_simple<Callable>(callable); 32 } 33 34 struct thread 35 { 36 struct ImplBase { }; 37 38 template<typename T> 39 struct Impl : ImplBase { 40 T t; Implthread::Impl41 Impl(T&& t) : t(std::move(t)) { } 42 }; 43 44 template<typename T> threadthread45 thread(T& t) 46 { 47 auto p = make_routine(bind_simple(t)); 48 49 p->t(); 50 51 delete p; 52 } 53 54 template<typename Callable> 55 Impl<Callable>* make_routinethread56 make_routine(Callable&& f) 57 { 58 return new Impl<Callable>(std::forward<Callable>(f)); 59 } 60 }; 61 62 63 int c; 64 class background_hello 65 { 66 public: background_hello()67 background_hello() 68 { 69 __builtin_printf("default ctor called, this=%p\n", this); 70 ++c; 71 } 72 background_hello(const background_hello &)73 background_hello(const background_hello &) 74 { 75 __builtin_printf("copy ctor called\n"); 76 ++c; 77 } 78 background_hello(background_hello &&)79 background_hello(background_hello &&) 80 { 81 __builtin_printf("move ctor called\n"); 82 ++c; 83 } 84 operator()85 void operator ()() const 86 { 87 __builtin_printf("void background_hello::operator()() called, this=%p\n", this); 88 } 89 ~background_hello()90 ~background_hello() 91 { 92 __builtin_printf("destructor called, this=%p\n", this); 93 --c; 94 } 95 96 }; 97 main()98int main() 99 { 100 { 101 background_hello bh; 102 thread t(bh); 103 } 104 if (c != 0) 105 __builtin_abort (); 106 } 107