blob: aabf88f51e26e2b42efc59fdf4cec38cc16631a5 [file] [log] [blame]
/* { dg-do run } */
/* { dg-options "-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 ();
}