1 // { dg-lto-do link }
2 // { dg-require-effective-target lto_incremental }
3 // { dg-lto-options { { -std=gnu++14 -flto -g -Wno-return-type } { -std=gnu++14 -flto -g -O2 -fno-inline -flto-partition=max -Wno-return-type } } }
4 // { dg-extra-ld-options "-r -nostdlib" }
5 
6 namespace std {
7 inline namespace __cxx11 {}
8 template <typename _Tp, _Tp> struct integral_constant {
9   static constexpr _Tp value = 0;
10 };
11 template <typename> struct __and_;
12 struct is_member_object_pointer : integral_constant<bool, false> {};
13 template <typename>
14 struct is_member_function_pointer : integral_constant<bool, false> {};
15 template <typename> struct remove_reference { typedef int type; };
16 template <typename> class C;
17 template <bool, int, typename...> struct __result_of_impl;
18 template <typename _Functor, typename... _ArgTypes>
19 struct __result_of_impl<false, 0, _Functor, _ArgTypes...> {
20   typedef decltype(0) type;
21 };
22 template <typename _Functor, typename... _ArgTypes>
23 struct C<_Functor(_ArgTypes...)>
24     : __result_of_impl<is_member_object_pointer::value,
25                        is_member_function_pointer<
26                            typename remove_reference<_Functor>::type>::value,
27                        _Functor> {};
28 template <typename _Tp> using result_of_t = typename C<_Tp>::type;
29 template <typename> void forward() { }
30 template <typename _Tp> _Tp move(_Tp) {}
31 namespace __cxx11 {
32 class basic_string typedef string;
33 }
34 template <typename> struct allocator_traits { typedef decltype(0) pointer; };
35 }
36 struct F : std::allocator_traits<int> {};
37 namespace std {
38 namespace __cxx11 {
39 class basic_string {
40 public:
41   struct _Alloc_hider : F {
42     _Alloc_hider(pointer);
43   } _M_dataplus;
44   basic_string(int) : _M_dataplus(0) {}
45   ~basic_string();
46 };
47 }
48 template <typename> class function;
49 template <typename _Functor> class _Base_manager {
50 protected:
51   static _Functor *_M_get_pointer(int) {}
52 };
53 template <typename, typename> class _Function_handler;
54 template <typename _Res, typename _Functor, typename... _ArgTypes>
55 class _Function_handler<_Res(_ArgTypes...), _Functor>
56     : _Base_manager<_Functor> {
57 public:
58   static _Res _M_invoke(const int &) {
59     (*_Base_manager<_Functor>::_M_get_pointer(0))();
60   }
61 };
62 template <typename, typename> using __check_func_return_type = int;
63 template <typename _Res, typename... _ArgTypes>
64 class function<_Res(_ArgTypes...)> {
65   template <typename> using _Invoke = decltype(0);
66   template <typename _Functor>
67   using _Callable = __and_<__check_func_return_type<_Invoke<_Functor>, _Res>>;
68   template <typename, typename> using _Requires = int;
69 
70 public:
71   template <typename _Functor, typename = _Requires<_Callable<_Functor>, void>>
72   function(_Functor);
73   using _Invoker_type = _Res (*)(const int &);
74   _Invoker_type _M_invoker;
75 };
76 template <typename _Res, typename... _ArgTypes>
77 template <typename _Functor, typename>
78 function<_Res(_ArgTypes...)>::function(_Functor) {
79   _M_invoker = _Function_handler<_Res(), _Functor>::_M_invoke;
80 }
81 class unique_ptr {
82 public:
83   ~unique_ptr();
84 };
85 template <typename _Tp, typename... _Args> _Tp make_unique(_Args... __args) {
86   _Tp(__args...);
87 }
88 }
89 class A {
90 public:
91   template <class T> T as();
92 };
93 class variables_map {
94 public:
95   A operator[](std::basic_string);
96 };
97 class B {
98 public:
99   variables_map configuration();
100   void run(int, int, std::function<void()>);
101 };
102 class H;
103 struct G {
104   enum {} _state;
105 };
106 class D {
107   G _local_state;
108   std::unique_ptr _task;
109   template <typename Func> void schedule(Func func) {
110     struct task_with_state {
111       task_with_state(Func func) : _func(func) {}
112       Func _func;
113     } tws = std::make_unique<task_with_state>(std::move(func));
114   }
115   friend H;
116 };
117 template <typename> using futurize_t = H;
118 class H {
119   D *_promise;
120   template <typename Func> void schedule(Func func) {
121     G __trans_tmp_1;
122     struct task_with_ready_state {
123       task_with_ready_state(Func, G) { };
124     };
125     std::make_unique<task_with_ready_state>(std::move(func), __trans_tmp_1);
126     _promise->schedule(std::move(func));
127   }
128   template <typename Func, typename Param> void then(Func func, Param) {
129     using P = D;
130     P pr;
131     schedule([ pr = std::move(pr), func, param = std::forward<Param> ]{});
132   }
133 
134 public:
135   template <typename Func> futurize_t<std::result_of_t<Func()>> then(Func) {
136     then(0, [] {});
137   }
138 } clients;
139 int main() {
140   B app;
141   app.run(0, 0, [&] {
142     auto config = app.configuration()[0].as<std::string>();
143     clients.then([] {});
144   });
145 
146   return 0;
147 }
148