1 // { dg-do run { target c++11 } }
2 // 2005-01-15 Douglas Gregor <dgregor@cs.indiana.edu>
3 //
4 // Copyright (C) 2005-2019 Free Software Foundation, Inc.
5 //
6 // This file is part of the GNU ISO C++ Library.  This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 3, or (at your option)
10 // any later version.
11 //
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License along
18 // with this library; see the file COPYING3.  If not see
19 // <http://www.gnu.org/licenses/>.
20 
21 // 20.7.15 polymorphic function object wrapper
22 #include <functional>
23 #include <testsuite_hooks.h>
24 #include <testsuite_tr1.h>
25 
26 template<typename T>
27   const T&
as_const(T & t)28   as_const(T& t)
29   { return t; }
30 
31 // Check that f's target is a reference_wrapper bound to obj.
32 template<typename Function, typename T>
33   bool
wraps(Function & f,T & obj)34   wraps(Function& f, T& obj)
35   {
36     using ref_wrapper_type = std::reference_wrapper<T>;
37     auto* p = f.template target<ref_wrapper_type>();
38     return std::addressof(p->get()) == std::addressof(obj);
39   }
40 
41 // Put reference_wrappers to member pointers
test08()42 void test08()
43 {
44   using std::function;
45   using std::ref;
46   using std::cref;
47   using std::reference_wrapper;
48   using __gnu_test::X;
49 
50   int X::* X_bar = &X::bar;
51   int (X::* X_foo)() = &X::foo;
52   int (X::* X_foo_c)() const = &X::foo_c;
53   int (X::* X_foo_v)() volatile = &X::foo_v;
54   int (X::* X_foo_cv)() const volatile = &X::foo_cv;
55 
56   X x;
57   x.bar = 17;
58 
59   function<int(X&)> frm(ref(X_bar));
60   VERIFY( frm );
61   VERIFY( frm(x) == 17 );
62   VERIFY( typeid(ref(X_bar)) == frm.target_type() );
63   VERIFY( wraps(frm, X_bar) );
64 
65   function<int(X&)> fr(ref(X_foo));
66   VERIFY( fr );
67   VERIFY( fr(x) == 1 );
68   VERIFY( typeid(ref(X_foo)) == fr.target_type() );
69   VERIFY( wraps(fr, X_foo) );
70 
71   function<int(const X&)> frc(ref(X_foo_c));
72   VERIFY( frc );
73   VERIFY( frc(x) == 2 );
74   VERIFY( typeid(ref(X_foo_c)) == frc.target_type() );
75   VERIFY( wraps(frc, X_foo_c) );
76 
77   function<int(volatile X&)> frv(ref(X_foo_v));
78   VERIFY( frv );
79   VERIFY( frv(x) == 3 );
80   VERIFY( typeid(ref(X_foo_v)) == frv.target_type() );
81   VERIFY( wraps(frv, X_foo_v) );
82 
83   function<int(const volatile X&)> frcv(ref(X_foo_cv));
84   VERIFY( frcv );
85   VERIFY( frcv(x) == 4 );
86   VERIFY( typeid(ref(X_foo_cv)) == frcv.target_type() );
87   VERIFY( wraps(frcv, X_foo_cv) );
88 
89   function<int(X*)> grm(ref(X_bar));
90   VERIFY( grm );
91   VERIFY( grm(&x) == 17 );
92   VERIFY( typeid(ref(X_bar)) == grm.target_type() );
93   VERIFY( wraps(grm, X_bar) );
94 
95   function<int(X*)> gr(ref(X_foo));
96   VERIFY( gr );
97   VERIFY( gr(&x) == 1 );
98   VERIFY( typeid(ref(X_foo)) == gr.target_type() );
99   VERIFY( wraps(gr, X_foo) );
100 
101   function<int(const X*)> grc(ref(X_foo_c));
102   VERIFY( grc );
103   VERIFY( grc(&x) == 2 );
104   VERIFY( typeid(ref(X_foo_c)) == grc.target_type() );
105   VERIFY( wraps(grc, X_foo_c) );
106 
107   function<int(volatile X*)> grv(ref(X_foo_v));
108   VERIFY( grv );
109   VERIFY( grv(&x) == 3 );
110   VERIFY( typeid(ref(X_foo_v)) == grv.target_type() );
111   VERIFY( wraps(grv, X_foo_v) );
112 
113   function<int(const volatile X*)> grcv(ref(X_foo_cv));
114   VERIFY( grcv );
115   VERIFY( grcv(&x) == 4 );
116   VERIFY( typeid(ref(X_foo_cv)) == grcv.target_type() );
117   VERIFY( wraps(grcv, X_foo_cv) );
118 
119   function<int(X&)> hrm(cref(X_bar));
120   VERIFY( hrm );
121   VERIFY( hrm(x) == 17 );
122   VERIFY( typeid(cref(X_bar)) == hrm.target_type() );
123   VERIFY( wraps(hrm, as_const(X_bar)) );
124 
125   function<int(X&)> hr(cref(X_foo));
126   VERIFY( hr );
127   VERIFY( hr(x) == 1 );
128   VERIFY( typeid(cref(X_foo)) == hr.target_type() );
129   VERIFY( wraps(hr, as_const(X_foo)) );
130 
131   function<int(const X&)> hrc(cref(X_foo_c));
132   VERIFY( hrc );
133   VERIFY( hrc(x) == 2 );
134   VERIFY( typeid(cref(X_foo_c)) == hrc.target_type() );
135   VERIFY( wraps(hrc, as_const(X_foo_c)) );
136 
137   function<int(volatile X&)> hrv(cref(X_foo_v));
138   VERIFY( hrv );
139   VERIFY( hrv(x) == 3 );
140   VERIFY( typeid(cref(X_foo_v)) == hrv.target_type() );
141   VERIFY( wraps(hrv, as_const(X_foo_v)) );
142 
143   function<int(const volatile X&)> hrcv(cref(X_foo_cv));
144   VERIFY( hrcv );
145   VERIFY( hrcv(x) == 4 );
146   VERIFY( typeid(cref(X_foo_cv)) == hrcv.target_type() );
147   VERIFY( wraps(hrcv, as_const(X_foo_cv)) );
148 }
149 
main()150 int main()
151 {
152   test08();
153   return 0;
154 }
155