1/* { dg-do run } */ 2/* { dg-options "-fstrict-aliasing" } */ 3 4extern "C" void abort (void); 5namespace sigc { 6 template <class T_type> 7 struct type_trait 8 { 9 typedef T_type& pass; 10 typedef const T_type& take; 11 typedef T_type* pointer; 12 }; 13 template <class T_base, class T_derived> 14 struct is_base_and_derived 15 { 16 struct big { 17 char memory[64]; 18 }; 19 static big is_base_class_(...); 20 static char is_base_class_(typename type_trait<T_base>::pointer); 21 static const bool value = 22 sizeof(is_base_class_(reinterpret_cast<typename type_trait<T_derived>::pointer>(0))) == 23 sizeof(char); 24 }; 25 struct nil; 26 struct functor_base {}; 27 template <class T_functor, bool I_derives_functor_base=is_base_and_derived<functor_base,T_functor>::value> 28 struct functor_trait 29 { 30 }; 31 template <class T_functor> 32 struct functor_trait<T_functor,true> 33 { 34 typedef typename T_functor::result_type result_type; 35 typedef T_functor functor_type; 36 }; 37 template <class T_arg1, class T_return> 38 class pointer_functor1 : public functor_base 39 { 40 typedef T_return (*function_type)(T_arg1); 41 function_type func_ptr_; 42 public: 43 typedef T_return result_type; 44 explicit pointer_functor1(function_type _A_func): func_ptr_(_A_func) {} 45 T_return operator()(typename type_trait<T_arg1>::take _A_a1) const 46 { return func_ptr_(_A_a1); } 47 }; 48 template <class T_arg1, class T_return> 49 inline pointer_functor1<T_arg1, T_return> 50 ptr_fun1(T_return (*_A_func)(T_arg1)) 51 { return pointer_functor1<T_arg1, T_return>(_A_func); } 52 struct adaptor_base : public functor_base {}; 53 template <class T_functor, 54 class T_arg1=void, 55 bool I_derives_adaptor_base=is_base_and_derived<adaptor_base,T_functor>::value> 56 struct deduce_result_type 57 { typedef typename functor_trait<T_functor>::result_type type; }; 58 template <class T_functor> 59 struct adaptor_functor : public adaptor_base 60 { 61 template <class T_arg1=void> 62 struct deduce_result_type 63 { typedef typename sigc::deduce_result_type<T_functor, T_arg1>::type type; }; 64 typedef typename functor_trait<T_functor>::result_type result_type; 65 result_type 66 operator()() const; 67 template <class T_arg1> 68 typename deduce_result_type<T_arg1>::type 69 operator()(T_arg1 _A_arg1) const 70 { return functor_(_A_arg1); } 71 explicit adaptor_functor(const T_functor& _A_functor) 72 : functor_(_A_functor) 73 {} 74 mutable T_functor functor_; 75 }; 76 template <class T_functor> 77 typename adaptor_functor<T_functor>::result_type 78 adaptor_functor<T_functor>::operator()() const 79 { return functor_(); } 80 template <class T_functor, bool I_isadaptor = is_base_and_derived<adaptor_base, T_functor>::value> struct adaptor_trait; 81 template <class T_functor> 82 struct adaptor_trait<T_functor, true> 83 { 84 typedef T_functor adaptor_type; 85 }; 86 template <class T_functor> 87 struct adaptor_trait<T_functor, false> 88 { 89 typedef typename functor_trait<T_functor>::functor_type functor_type; 90 typedef adaptor_functor<functor_type> adaptor_type; 91 }; 92 template <class T_functor> 93 struct adapts : public adaptor_base 94 { 95 typedef typename adaptor_trait<T_functor>::adaptor_type adaptor_type; 96 explicit adapts(const T_functor& _A_functor) 97 : functor_(_A_functor) 98 {} 99 mutable adaptor_type functor_; 100 }; 101 template <class T_type> 102 struct reference_wrapper 103 { 104 }; 105 template <class T_type> 106 struct unwrap_reference 107 { 108 typedef T_type type; 109 }; 110 template <class T_type> 111 class bound_argument 112 { 113 public: 114 bound_argument(const T_type& _A_argument) 115 : visited_(_A_argument) 116 {} 117 inline T_type& invoke() 118 { return visited_; } 119 T_type visited_; 120 }; 121 template <class T_wrapped> 122 class bound_argument< reference_wrapper<T_wrapped> > 123 { 124 }; 125 template <int I_location, class T_functor, class T_type1=nil> 126 struct bind_functor; 127 template <class T_functor, class T_type1> 128 struct bind_functor<-1, T_functor, T_type1> : public adapts<T_functor> 129 { 130 typedef typename adapts<T_functor>::adaptor_type adaptor_type; 131 typedef typename adaptor_type::result_type result_type; 132 result_type 133 operator()() 134 { 135 return this->functor_.template operator()<typename type_trait<typename unwrap_reference<T_type1>::type>::pass> (bound1_.invoke()); 136 } 137 bind_functor(typename type_trait<T_functor>::take _A_func, typename type_trait<T_type1>::take _A_bound1) 138 : adapts<T_functor>(_A_func), bound1_(_A_bound1) 139 {} 140 bound_argument<T_type1> bound1_; 141 }; 142 template <class T_type1, class T_functor> 143 inline bind_functor<-1, T_functor, 144 T_type1> 145 bind(const T_functor& _A_func, T_type1 _A_b1) 146 { return bind_functor<-1, T_functor, 147 T_type1> 148 (_A_func, _A_b1); 149 } 150 namespace internal { 151 struct slot_rep; 152 typedef void* (*hook)(slot_rep *); 153 struct slot_rep 154 { 155 hook call_; 156 }; 157 } 158 class slot_base : public functor_base 159 { 160 public: 161 typedef internal::slot_rep rep_type; 162 explicit slot_base(rep_type* rep) 163 : rep_(rep) 164 { 165 } 166 mutable rep_type *rep_; 167 }; 168 namespace internal { 169 template <class T_functor> 170 struct typed_slot_rep : public slot_rep 171 { 172 typedef typename adaptor_trait<T_functor>::adaptor_type adaptor_type; 173 adaptor_type functor_; 174 inline typed_slot_rep(const T_functor& functor) 175 : functor_(functor) 176 { 177 } 178 }; 179 template<class T_functor> 180 struct slot_call0 181 { 182 static void *call_it(slot_rep* rep) 183 { 184 typedef typed_slot_rep<T_functor> typed_slot; 185 typed_slot *typed_rep = static_cast<typed_slot*>(rep); 186 return (typed_rep->functor_)(); 187 } 188 static hook address() 189 { 190 return &call_it; 191 } 192 }; 193 } 194 195 class slot0 : public slot_base 196 { 197 public: 198 typedef void * (*call_type)(rep_type*); 199 inline void *operator()() const 200 { 201 return slot_base::rep_->call_ (slot_base::rep_); 202 } 203 template <class T_functor> 204 slot0(const T_functor& _A_func) 205 : slot_base(new internal::typed_slot_rep<T_functor>(_A_func)) 206 { 207 slot_base::rep_->call_ = internal::slot_call0<T_functor>::address(); 208 } 209 }; 210} 211struct A 212{ 213 static void *foo (void *p) { return p; } 214 typedef sigc::slot0 C; 215 C bar(); 216}; 217A::C A::bar () 218{ 219 return sigc::bind (sigc::ptr_fun1 (&A::foo), (void*)0); 220} 221int main (void) 222{ 223 A a; 224 if (a.bar ()() != 0) 225 abort (); 226} 227