27
27
namespace internal {
29
//This should really be an inner class of limit_derived_target, without the T_limit template type,
30
//But the SUN CC 5.7 (not earlier versions) compiler finds it ambiguous when we specify a particular specialization of it.
31
//and does not seem to allow us to tell it explicitly that it's an inner class.
32
template <bool I_derived, class T_type, class T_limit>
35
//Specialization for I_derived = false
36
template <class T_type, class T_limit> struct
37
with_type<false, T_type, T_limit>
39
static void execute_(const T_type&, const T_limit&) {}
42
//Specialization for I_derived = true
43
template <class T_type, class T_limit>
44
struct with_type<true, T_type, T_limit>
46
static void execute_(const T_type& _A_type, const T_limit& _A_action)
47
{ _A_action.action_(_A_type); }
29
51
/// Helper struct for visit_each_type().
30
52
template <class T_target, class T_action>
31
53
struct limit_derived_target
33
55
typedef limit_derived_target<T_target, T_action> T_self;
35
template <bool I_derived, class T_type> struct with_type;
37
template <class T_type> struct with_type<false,T_type>
38
{ static void execute_(const T_type&, const T_self&) {} };
40
template <class T_type> struct with_type<true,T_type>
41
{ static void execute_(const T_type& _A_type, const T_self& _A_action)
42
{ _A_action.action_(_A_type); }
45
58
template <class T_type>
46
59
void operator()(const T_type& _A_type) const
47
{ with_type<is_base_and_derived<T_target,T_type>::value,T_type>::execute_(_A_type,*this); }
61
with_type<is_base_and_derived<T_target, T_type>::value, T_type, T_self>::execute_(_A_type, *this);
49
limit_derived_target(const T_action& _A_action): action_(_A_action) {}
64
limit_derived_target(const T_action& _A_action)
54
/// Helper struct for visit_each_type().
71
// Specialization for T_target pointer types, to provide a slightly different execute_() implementation.
73
template <bool I_derived, class T_type, class T_limit>
74
struct with_type_pointer;
76
//Specialization for I_derived = false
77
template <class T_type, class T_limit>
78
struct with_type_pointer<false, T_type, T_limit>
80
static void execute_(const T_type&, const T_limit&) {}
83
//Specialization for I_derived = true
84
template <class T_type, class T_limit>
85
struct with_type_pointer<true, T_type, T_limit>
87
static void execute_(const T_type& _A_type, const T_limit& _A_action)
88
{ _A_action.action_(&_A_type); }
55
91
template <class T_target, class T_action>
56
92
struct limit_derived_target<T_target*, T_action>
58
94
typedef limit_derived_target<T_target*, T_action> T_self;
60
template <bool I_derived, class T_type> struct with_type;
62
template <class T_type> struct with_type<false,T_type>
63
{ static void execute_(const T_type&, const T_self&) {} };
65
template <class T_type> struct with_type<true,T_type>
66
{ static void execute_(const T_type& _A_type, const T_self& _A_action)
67
{ _A_action.action_(&_A_type); }
70
97
template <class T_type>
71
98
void operator()(const T_type& _A_type) const
72
{ with_type<is_base_and_derived<T_target,T_type>::value,T_type>::execute_(_A_type,*this); }
100
with_type_pointer<is_base_and_derived<T_target, T_type>::value, T_type, T_self>::execute_(_A_type, *this);
74
limit_derived_target(const T_action& _A_action): action_(_A_action) {}
103
limit_derived_target(const T_action& _A_action)
120
151
template <class T_type, class T_action, class T_functor>
121
152
void visit_each_type(const T_action& _A_action, const T_functor& _A_functor)
123
internal::limit_derived_target<T_type,T_action> limited_action(_A_action);
124
visit_each(limited_action,_A_functor);
154
typedef internal::limit_derived_target<T_type, T_action> type_limited_action;
156
type_limited_action limited_action(_A_action);
158
//specifying the types of the template specialization prevents disconnection of bound trackable references (such as with sigc::ref()),
159
//probably because the visit_each<> specializations take various different template types,
160
//in various sequences, and we are probably specifying only a subset of them with this.
162
//But this is required by the AIX (and maybe IRIX MipsPro and Tru64) compilers.
163
//I guess that sigc::ref() therefore does not work on those platforms. murrayc
164
//visit_each<type_limited_action, T_functor>(limited_action, _A_functor);
166
//g++ (even slightly old ones) is our primary platform, so we could use the non-crashing version.
167
//However, the expliict version also fixes a crash in a slightl more common case: http://bugzilla.gnome.org/show_bug.cgi?id=169225
168
//Users (and distributors) of libsigc++ on AIX (and maybe IRIX MipsPro and Tru64) do
169
//need to use the version above instead, to allow compilation.
170
visit_each(limited_action, _A_functor);
127
173
} /* namespace sigc */