1/* { dg-do compile } */ 2/* { dg-options "-O2" } */ 3namespace sigc { 4 template <class T_type> struct type_trait { 5 typedef T_type& pass; 6 typedef const T_type& take; 7 typedef T_type* pointer; 8 }; 9 template <class T_type> struct type_trait<T_type&> { 10 typedef T_type& pass; 11 }; 12 template<> struct type_trait<void> { 13 typedef void pass; 14 }; 15 template <class T_base, class T_derived> struct is_base_and_derived { 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 = sizeof(is_base_class_(reinterpret_cast<typename type_trait<T_derived>::pointer>(0))) == sizeof(char); 22 }; 23 struct nil; 24 struct functor_base { 25 }; 26 template <class T_functor, bool I_derives_functor_base=is_base_and_derived<functor_base,T_functor>::value> struct functor_trait { 27 typedef typename T_functor::result_type result_type; 28 typedef T_functor functor_type; 29 }; 30 struct adaptor_base : public functor_base { 31 }; 32 template <class T_functor, class T_arg1=void,class T_arg2=void,class T_arg3=void,class T_arg4=void,class T_arg5=void,class T_arg6=void,class T_arg7=void, bool I_derives_adaptor_base=is_base_and_derived<adaptor_base,T_functor>::value> struct deduce_result_type { 33 typedef typename functor_trait<T_functor>::result_type type; 34 }; 35 template <class T_functor> struct adaptor_functor 36 : public adaptor_base { 37 template <class T_arg1=void,class T_arg2=void,class T_arg3=void,class T_arg4=void,class T_arg5=void,class T_arg6=void,class T_arg7=void> struct deduce_result_type { 38 typedef typename sigc::deduce_result_type<T_functor, T_arg1,T_arg2,T_arg3,T_arg4,T_arg5,T_arg6,T_arg7>::type type; 39 }; 40 typedef typename functor_trait<T_functor>::result_type result_type; 41 template <class T_arg1,class T_arg2> typename deduce_result_type<T_arg1,T_arg2>::type operator()(T_arg1 _A_arg1,T_arg2 _A_arg2) const { 42 return functor_(_A_arg1,_A_arg2); 43 } 44 explicit adaptor_functor(const T_functor& _A_functor) : functor_(_A_functor) { 45 } 46 mutable T_functor functor_; 47 }; 48 template <class T_functor, bool I_isadaptor = is_base_and_derived<adaptor_base, T_functor>::value> struct adaptor_trait; 49 template <class T_functor> struct adaptor_trait<T_functor, true> { 50 typedef T_functor adaptor_type; 51 }; 52 template <class T_functor> struct adaptor_trait<T_functor, false> { 53 typedef typename functor_trait<T_functor>::functor_type functor_type; 54 typedef adaptor_functor<functor_type> adaptor_type; 55 }; 56 template <class T_functor> struct adapts 57 : public adaptor_base { 58 typedef typename adaptor_trait<T_functor>::adaptor_type adaptor_type; 59 explicit adapts(const T_functor& _A_functor) : functor_(_A_functor) { 60 } 61 mutable adaptor_type functor_; 62 }; 63 template <class T_type> struct unwrap_reference { 64 typedef T_type type; 65 }; 66 template <class T_type> class bound_argument { 67 public: 68 bound_argument(const T_type& _A_argument) : visited_(_A_argument) { 69 } 70 inline T_type& invoke() { 71 } 72 T_type visited_; 73 }; 74 template <int I_location, class T_functor, class T_type1=nil,class T_type2=nil,class T_type3=nil,class T_type4=nil,class T_type5=nil,class T_type6=nil,class T_type7=nil> struct bind_functor; 75 template <class T_functor, class T_bound> struct bind_functor<0, T_functor, T_bound, nil,nil,nil,nil,nil,nil> : public adapts<T_functor> { 76 typedef typename adapts<T_functor>::adaptor_type adaptor_type; 77 template <class T_arg1=void,class T_arg2=void,class T_arg3=void,class T_arg4=void,class T_arg5=void,class T_arg6=void,class T_arg7=void> struct deduce_result_type { 78 typedef typename adaptor_type::template deduce_result_type<typename type_trait<typename unwrap_reference<T_bound>::type>::pass, typename type_trait<T_arg1>::pass, typename type_trait<T_arg2>::pass, typename type_trait<T_arg3>::pass, typename type_trait<T_arg4>::pass, typename type_trait<T_arg5>::pass, typename type_trait<T_arg6>::pass>::type type; 79 }; 80 typedef typename adaptor_type::result_type result_type; 81 result_type operator()() { 82 return this->functor_.template operator()<typename type_trait<typename unwrap_reference<T_bound>::type>::pass> (bound_.invoke()); 83 } 84 template <class T_arg1> typename deduce_result_type<T_arg1>::type operator()(T_arg1 _A_arg1) { 85 return this->functor_.template operator()<typename type_trait<typename unwrap_reference<T_bound>::type>::pass, typename type_trait<T_arg1>::pass> (bound_.invoke(), _A_arg1); 86 } 87 bind_functor(typename type_trait<T_functor>::take _A_func, typename type_trait<T_bound>::take _A_bound) : adapts<T_functor>(_A_func), bound_(_A_bound) { 88 } 89 bound_argument<T_bound> bound_; 90 }; 91 template <int I_location, class T_bound1, class T_functor> inline bind_functor<I_location, T_functor, T_bound1> bind(const T_functor& _A_func, T_bound1 _A_b1) { 92 return bind_functor<I_location, T_functor, T_bound1>(_A_func, _A_b1); 93 }; 94} 95struct foo { 96 typedef int result_type; 97 int operator()(int i, int j); 98}; 99int main() { 100 sigc::bind<0>(sigc::bind<0>(foo(),7),8)(); 101} 102