|
|
|
/* { dg-do run } */ |
|
/* { dg-options "-O -fstrict-aliasing" } */ |
|
|
|
extern "C" void abort (void); |
|
namespace sigc { |
|
template <class T_type> |
|
struct type_trait |
|
{ |
|
typedef T_type& pass; |
|
typedef const T_type& take; |
|
typedef T_type* pointer; |
|
}; |
|
template <class T_base, class T_derived> |
|
struct is_base_and_derived |
|
{ |
|
struct big { |
|
char memory[64]; |
|
}; |
|
static big is_base_class_(...); |
|
static char is_base_class_(typename type_trait<T_base>::pointer); |
|
static const bool value = |
|
sizeof(is_base_class_(reinterpret_cast<typename type_trait<T_derived>::pointer>(0))) == |
|
sizeof(char); |
|
}; |
|
struct nil; |
|
struct functor_base {}; |
|
template <class T_functor, bool I_derives_functor_base=is_base_and_derived<functor_base,T_functor>::value> |
|
struct functor_trait |
|
{ |
|
}; |
|
template <class T_functor> |
|
struct functor_trait<T_functor,true> |
|
{ |
|
typedef typename T_functor::result_type result_type; |
|
typedef T_functor functor_type; |
|
}; |
|
template <class T_arg1, class T_return> |
|
class pointer_functor1 : public functor_base |
|
{ |
|
typedef T_return (*function_type)(T_arg1); |
|
function_type func_ptr_; |
|
public: |
|
typedef T_return result_type; |
|
explicit pointer_functor1(function_type _A_func): func_ptr_(_A_func) {} |
|
T_return operator()(typename type_trait<T_arg1>::take _A_a1) const |
|
{ return func_ptr_(_A_a1); } |
|
}; |
|
template <class T_arg1, class T_return> |
|
inline pointer_functor1<T_arg1, T_return> |
|
ptr_fun1(T_return (*_A_func)(T_arg1)) |
|
{ return pointer_functor1<T_arg1, T_return>(_A_func); } |
|
struct adaptor_base : public functor_base {}; |
|
template <class T_functor, |
|
class T_arg1=void, |
|
bool I_derives_adaptor_base=is_base_and_derived<adaptor_base,T_functor>::value> |
|
struct deduce_result_type |
|
{ typedef typename functor_trait<T_functor>::result_type type; }; |
|
template <class T_functor> |
|
struct adaptor_functor : public adaptor_base |
|
{ |
|
template <class T_arg1=void> |
|
struct deduce_result_type |
|
{ typedef typename sigc::deduce_result_type<T_functor, T_arg1>::type type; }; |
|
typedef typename functor_trait<T_functor>::result_type result_type; |
|
result_type |
|
operator()() const; |
|
template <class T_arg1> |
|
typename deduce_result_type<T_arg1>::type |
|
operator()(T_arg1 _A_arg1) const |
|
{ return functor_(_A_arg1); } |
|
explicit adaptor_functor(const T_functor& _A_functor) |
|
: functor_(_A_functor) |
|
{} |
|
mutable T_functor functor_; |
|
}; |
|
template <class T_functor> |
|
typename adaptor_functor<T_functor>::result_type |
|
adaptor_functor<T_functor>::operator()() const |
|
{ return functor_(); } |
|
template <class T_functor, bool I_isadaptor = is_base_and_derived<adaptor_base, T_functor>::value> struct adaptor_trait; |
|
template <class T_functor> |
|
struct adaptor_trait<T_functor, true> |
|
{ |
|
typedef T_functor adaptor_type; |
|
}; |
|
template <class T_functor> |
|
struct adaptor_trait<T_functor, false> |
|
{ |
|
typedef typename functor_trait<T_functor>::functor_type functor_type; |
|
typedef adaptor_functor<functor_type> adaptor_type; |
|
}; |
|
template <class T_functor> |
|
struct adapts : public adaptor_base |
|
{ |
|
typedef typename adaptor_trait<T_functor>::adaptor_type adaptor_type; |
|
explicit adapts(const T_functor& _A_functor) |
|
: functor_(_A_functor) |
|
{} |
|
mutable adaptor_type functor_; |
|
}; |
|
template <class T_type> |
|
struct reference_wrapper |
|
{ |
|
}; |
|
template <class T_type> |
|
struct unwrap_reference |
|
{ |
|
typedef T_type type; |
|
}; |
|
template <class T_type> |
|
class bound_argument |
|
{ |
|
public: |
|
bound_argument(const T_type& _A_argument) |
|
: visited_(_A_argument) |
|
{} |
|
inline T_type& invoke() |
|
{ return visited_; } |
|
T_type visited_; |
|
}; |
|
template <class T_wrapped> |
|
class bound_argument< reference_wrapper<T_wrapped> > |
|
{ |
|
}; |
|
template <int I_location, class T_functor, class T_type1=nil> |
|
struct bind_functor; |
|
template <class T_functor, class T_type1> |
|
struct bind_functor<-1, T_functor, T_type1> : public adapts<T_functor> |
|
{ |
|
typedef typename adapts<T_functor>::adaptor_type adaptor_type; |
|
typedef typename adaptor_type::result_type result_type; |
|
result_type |
|
operator()() |
|
{ |
|
return this->functor_.template operator()<typename type_trait<typename unwrap_reference<T_type1>::type>::pass> (bound1_.invoke()); |
|
} |
|
bind_functor(typename type_trait<T_functor>::take _A_func, typename type_trait<T_type1>::take _A_bound1) |
|
: adapts<T_functor>(_A_func), bound1_(_A_bound1) |
|
{} |
|
bound_argument<T_type1> bound1_; |
|
}; |
|
template <class T_type1, class T_functor> |
|
inline bind_functor<-1, T_functor, |
|
T_type1> |
|
bind(const T_functor& _A_func, T_type1 _A_b1) |
|
{ return bind_functor<-1, T_functor, |
|
T_type1> |
|
(_A_func, _A_b1); |
|
} |
|
namespace internal { |
|
struct slot_rep; |
|
typedef void* (*hook)(slot_rep *); |
|
struct slot_rep |
|
{ |
|
hook call_; |
|
}; |
|
} |
|
class slot_base : public functor_base |
|
{ |
|
public: |
|
typedef internal::slot_rep rep_type; |
|
explicit slot_base(rep_type* rep) |
|
: rep_(rep) |
|
{ |
|
} |
|
mutable rep_type *rep_; |
|
}; |
|
namespace internal { |
|
template <class T_functor> |
|
struct typed_slot_rep : public slot_rep |
|
{ |
|
typedef typename adaptor_trait<T_functor>::adaptor_type adaptor_type; |
|
adaptor_type functor_; |
|
inline typed_slot_rep(const T_functor& functor) |
|
: functor_(functor) |
|
{ |
|
} |
|
}; |
|
template<class T_functor> |
|
struct slot_call0 |
|
{ |
|
static void *call_it(slot_rep* rep) |
|
{ |
|
typedef typed_slot_rep<T_functor> typed_slot; |
|
typed_slot *typed_rep = static_cast<typed_slot*>(rep); |
|
return (typed_rep->functor_)(); |
|
} |
|
static hook address() |
|
{ |
|
return &call_it; |
|
} |
|
}; |
|
} |
|
|
|
class slot0 : public slot_base |
|
{ |
|
public: |
|
typedef void * (*call_type)(rep_type*); |
|
inline void *operator()() const |
|
{ |
|
return slot_base::rep_->call_ (slot_base::rep_); |
|
} |
|
template <class T_functor> |
|
slot0(const T_functor& _A_func) |
|
: slot_base(new internal::typed_slot_rep<T_functor>(_A_func)) |
|
{ |
|
slot_base::rep_->call_ = internal::slot_call0<T_functor>::address(); |
|
} |
|
}; |
|
} |
|
struct A |
|
{ |
|
static void *foo (void *p) { return p; } |
|
typedef sigc::slot0 C; |
|
C bar(); |
|
}; |
|
A::C A::bar () |
|
{ |
|
return sigc::bind (sigc::ptr_fun1 (&A::foo), (void*)0); |
|
} |
|
int main (void) |
|
{ |
|
A a; |
|
if (a.bar ()() != 0) |
|
abort (); |
|
} |