Ticket #2749: MemberFunctionChecker.hpp

File MemberFunctionChecker.hpp, 3.6 KB (added by anonymous, 14 years ago)

http://groups.google.com/group/comp.lang.c++.moderated/tree/browse_frm/thread/4f7c7a96f9afbe44/c95a7b4c645e449f#doc_e5fbc9305539f699

Line 
1#ifndef MemberFunctionCheckerH
2#define MemberFunctionCheckerH
3/*-------------------------------------------------------------------------------------------------------------------------------------------
4 MemberFunctionChecker.hpp
5 from http://groups.google.com/group/comp.lang.c++.moderated/tree/browse_frm/thread/4f7c7a96f9afbe44/c95a7b4c645e449f#doc_e5fbc9305539f699
6--------------------------------------------------------------------------------------------------------------------------------------------*/
7
8
9namespace MemberFunctionChecker {
10
11 template <typename Type>
12 class has_member {
13 class yes { char m;};
14 class no { yes m[2];};
15 struct BaseMixin { void operator()() {} };
16 struct Base : public Type, public BaseMixin {};
17 template <typename T, T t> class Helper {};
18 template <typename U>
19 static no deduce(U*, Helper<void (BaseMixin::*)(), &U::operator()>* = 0);
20 static yes deduce(...);
21 public:
22 static const bool result = sizeof(yes) == sizeof(deduce((Base*)(0)));
23 };
24
25 namespace details {
26 template <typename type> class void_exp_result {};
27 template <typename type, typename U> U const& operator,(U const&, void_exp_result<type>);
28 template <typename type, typename U> U& operator,(U&, void_exp_result<type>);
29 template <typename src_type, typename dest_type>
30 struct clone_constness {
31 typedef dest_type type;
32 };
33 template <typename src_type, typename dest_type>
34 struct clone_constness<const src_type, dest_type> {
35 typedef const dest_type type;
36 };
37 }
38
39 template <typename type, typename call_details>
40 struct is_call_possible {
41 private:
42 class yes {};
43 class no { yes m[2]; };
44 struct derived : public type {
45 using type::operator();
46 no operator()(...) const;
47 };
48 typedef typename details::clone_constness<type, derived>::type derived_type;
49 template <typename T, typename due_type>
50 struct return_value_check {
51 static yes deduce(due_type);
52 static no deduce(...);
53 };
54 template <typename T>
55 struct return_value_check<T, void> {
56 static yes deduce(details::void_exp_result<type>);
57 static no deduce(...);
58 };
59
60 template <bool has, typename F>
61 struct impl { static const bool value = false; };
62 template <typename arg1, typename r>
63 struct impl<true, r(arg1)> {
64 static const bool value =
65 sizeof(
66 return_value_check<type, r>::deduce((
67 ((derived_type*)0)->operator()(*(arg1*)0),
68 details::void_exp_result<type>()))
69 ) == sizeof(yes);
70 };
71 template <typename arg1, typename arg2, typename r>
72 struct impl<true, r(arg1, arg2)> {
73 static const bool value =
74 sizeof(
75 return_value_check<type, r>::deduce((
76 ((derived_type*)0)->operator()(*(arg1*)0, *(arg2*)0),
77 details::void_exp_result<type>()))
78 ) == sizeof(yes);
79 };
80 template <typename arg1, typename arg2, typename arg3, typename r>
81 struct impl<true, r(arg1, arg2, arg3)> {
82 static const bool value =
83 sizeof(
84 return_value_check<type, r>::deduce(
85 (((derived_type*)0)->operator()(*(arg1*)0, *(arg2*)0, *(arg3*)0),
86 details::void_exp_result<type>()))
87 ) == sizeof(yes);
88 };
89 public:
90 static const bool value = impl<has_member<type>::result, call_details>::value;
91 };
92
93}
94#endif