1 // PR c++/85118
2 // { dg-do compile { target c++14 } }
3 
4 namespace std
5 {
6   template<typename _Tp>
7     struct remove_const
8     { typedef _Tp type; };
9 
10   template<typename _Tp>
11     struct remove_const<_Tp const>
12     { typedef _Tp type; };
13 
14 
15   template<typename _Tp>
16     struct remove_volatile
17     { typedef _Tp type; };
18 
19   template<typename _Tp>
20     struct remove_volatile<_Tp volatile>
21     { typedef _Tp type; };
22 
23 
24   template<typename _Tp>
25     struct remove_cv
26     {
27       typedef typename
28       remove_const<typename remove_volatile<_Tp>::type>::type type;
29     };
30 
31   template<typename _Tp>
32     struct remove_reference
33     { typedef _Tp type; };
34 
35   template<typename _Tp>
36     struct remove_reference<_Tp&>
37     { typedef _Tp type; };
38 
39   template<typename _Tp>
40     struct remove_reference<_Tp&&>
41     { typedef _Tp type; };
42 
43   template<typename _Tp>
44     struct decay
45     {
46       using type = typename remove_reference<typename remove_const<_Tp>::type>::type;
47     };
48 
49   template<typename _Tp>
50     _Tp&&
51     declval() noexcept;
52 
53   template<typename _Tp>
54     constexpr _Tp&&
55     forward(typename std::remove_reference<_Tp>::type& __t) noexcept
56     { return static_cast<_Tp&&>(__t); }
57 
58 
59   template<typename _Arg>
60     struct _Mu
61     {
62       template<typename _CVArg, typename _Tuple>
63          _CVArg&&
64          operator()(_CVArg&& __arg, _Tuple&) const volatile
65          { return std::forward<_CVArg>(__arg); }
66     };
67 
68    template<typename _Functor, typename _Bound_args>
69     struct _Bind
70     {
71       _Functor _M_f;
72       _Bound_args _M_bound_args;
73 
74       template<typename _Args, typename _Result
75          = decltype( std::declval<_Functor&>()(
76                _Mu<_Bound_args>()( std::declval<_Bound_args&>(),
77               std::declval<_Args&>() ) ) )>
78          _Result
79       operator()(_Args&& __args) { return {}; }
80 
81       template<typename _Args, typename _Result
82          = decltype( std::declval<volatile _Functor&>()(
83                _Mu<_Bound_args>()( std::declval<volatile _Bound_args&>(),
84               std::declval<_Args&>() ) ) )>
85          _Result
86          operator()(_Args&& __args) volatile;
87 
88     };
89 
90   template<typename _Func, typename _BoundArgs>
91     _Bind<typename decay<_Func>::type, typename decay<_BoundArgs>::type>
92     bind(_Func&& __f, _BoundArgs&& __args)
93     {
94       return {
95         std::forward<_Func>(__f),
96           std::forward<_BoundArgs>(__args)
97       };
98     }
99 
100 } // namespace std
101 
102 
103 template <typename T>
104 bool isOneOf(const T& )
105 {
106     return false;
107 }
108 
109 template <typename T, typename FirstType, typename... Tail>
110 bool isOneOf(const T& t, const FirstType& firstValue, const Tail&... tail)
111 {
112     return t == firstValue || isOneOf(t, tail...);
113 }
114 
115 int main()
116 {
117     const auto isOneOfHelper = [](auto&&... params)
118     {
119       return isOneOf(std::forward<decltype(params)>(params)...);
120     };
121 
122     auto isO = std::bind(isOneOfHelper, 'o');
123 
124     isO('o');
125 }
126