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()98 int main()
99 {
100   {
101     background_hello bh;
102     thread t(bh);
103   }
104   if (c != 0)
105     __builtin_abort ();
106 }
107