1// PR tree-optimization/56029
2// { dg-do compile }
3
4template <class T>
5struct DefaultDeleter
6{
7  void operator () (T * ptr) { delete ptr; }
8};
9template <class T, class D>
10struct scoped_ptr_impl
11{
12  scoped_ptr_impl (T * p):data_ (p) {}
13  template <typename U, typename V>
14  scoped_ptr_impl (scoped_ptr_impl <U, V> *other):data_ (other->release (), get_deleter ()) {}
15  ~scoped_ptr_impl () { static_cast <D> (data_) (data_.ptr); }
16  void reset (T * p) { data_.ptr = p; }
17  D get_deleter () {}
18  T *release () { data_.ptr = __null; }
19  struct Data
20  : D
21  {
22    Data (T *) : ptr () {}
23    Data (T *, D) : D (), ptr () {}
24    T *ptr;
25  };
26  Data data_;
27};
28template <class T, class D = DefaultDeleter <T> >
29struct scoped_ptr
30{
31  struct RValue
32  {
33    RValue (scoped_ptr * object):object (object) {}
34    scoped_ptr *object;
35  };
36  scoped_ptr Pass () { return scoped_ptr ((this)); }
37  typedef T element_type;
38  typedef D deleter_type;
39  scoped_ptr () : impl_ (__null) {}
40  scoped_ptr (RValue rvalue) : impl_ (&rvalue.object->impl_) {}
41  void reset (element_type * p) { impl_.reset (p); }
42  scoped_ptr_impl <element_type, deleter_type> impl_;
43};
44template <typename>
45struct Callback;
46struct ClientSocketFactory;
47struct DatagramClientSocket;
48struct DnsSocketPool
49{
50  scoped_ptr <DatagramClientSocket> CreateConnectedSocket ();
51  ClientSocketFactory *socket_factory_;
52};
53int RandInt (int, int);
54struct BindStateBase {};
55struct CallbackBase
56{
57  CallbackBase (BindStateBase *);
58  ~CallbackBase ();
59};
60template <typename, typename, typename>
61struct BindState;
62template <typename R, typename A1, typename A2>
63struct Callback <R (A1, A2)> : CallbackBase
64{
65  template <typename Runnable, typename BindRunType, typename BoundArgsType>
66  Callback (BindState <Runnable, BindRunType, BoundArgsType> *bind_state) : CallbackBase (bind_state) {}
67};
68typedef Callback <int (int, int)>
69RandIntCallback;
70struct ClientSocketFactory
71{
72  virtual DatagramClientSocket *CreateDatagramClientSocket (RandIntCallback) = 0;
73};
74template <typename>
75struct RunnableAdapter;
76template <typename R, typename A1, typename A2>
77struct RunnableAdapter <R (*) (A1, A2)>
78{
79  typedef R (RunType) (A1, A2);
80};
81template <typename T>
82struct FunctorTraits
83{
84  typedef RunnableAdapter <T> RunnableType;
85  typedef typename RunnableType::RunType RunType;
86};
87template <typename T>
88typename FunctorTraits <T>::RunnableType MakeRunnable (T)
89{
90}
91template <int, typename, typename>
92struct Invoker;
93template <typename StorageType, typename R, typename X1, typename X2>
94struct Invoker <0, StorageType, R (X1, X2)>
95{
96  typedef R (UnboundRunType) (X1, X2);
97};
98template <typename Runnable, typename RunType>
99struct BindState <Runnable, RunType, void ()> : BindStateBase
100{
101  typedef Runnable RunnableType;
102  typedef Invoker <0, BindState, RunType> InvokerType;
103  typedef typename InvokerType::UnboundRunType UnboundRunType;
104  BindState (Runnable):runnable_ () {}
105  RunnableType runnable_;
106};
107template <typename Functor>
108Callback <typename BindState <typename FunctorTraits <Functor>::RunnableType, typename FunctorTraits <Functor>::RunType, void ()>::UnboundRunType>
109Bind (Functor functor)
110{
111  typedef typename FunctorTraits <Functor>::RunnableType RunnableType;
112  typedef typename FunctorTraits <Functor>::RunType RunType;
113  typedef BindState <RunnableType, RunType, void ()> BindState;
114  Callback <typename BindState::UnboundRunType> (new BindState (MakeRunnable (functor)));
115}
116struct DatagramClientSocket
117{
118  virtual ~ DatagramClientSocket ();
119};
120scoped_ptr <DatagramClientSocket>
121DnsSocketPool::CreateConnectedSocket ()
122{
123  scoped_ptr <DatagramClientSocket> socket;
124  socket.reset (socket_factory_->CreateDatagramClientSocket (Bind (RandInt)));
125  socket.Pass ();
126}
127