xref: /haiku/src/apps/cortex/support/functional_tools.h (revision 2600324b57fa31cdea1627d584d314f2a579c4a8)
1 // functional_tools.h
2 //
3 // PURPOSE
4 //   Some extra STL-related functors, adaptors, & helper functions.
5 //
6 // NOTES
7 //   bound_method() makes it easy to use STL algorithms to apply a given
8 //     method in a given object to a set of instances of another class.
9 //
10 //   The additional-argument functors aren't perfected; most notably,
11 //     bind2nd() doesn't handle bound methods that take objects by
12 //     reference.  +++++
13 //
14 // HISTORY
15 //   e.moon 27jul99		begun
16 
17 #ifndef __functional_tools_H__
18 #define __functional_tools_H__
19 
20 #include "cortex_defs.h"
21 __BEGIN_CORTEX_NAMESPACE
22 
23 ///////////////////////////////////////////////////////////////////////////
24 // bound_method
25 ///////////////////////////////////////////////////////////////////////////
26 
27 // ***** no additional arguments *****
28 
29 // 27jul99: functor adaptor "call a given method of a given object with argument"
30 template<class _retT, class _subjectT, class _objectT>
31 class bound_method_t : public std::unary_function<_objectT*, _retT> {
32 public:
33 	explicit bound_method_t(
34 		// the bound instance on which the method will be called
35 		_subjectT& __subject,
36 		// the method
37 		_retT (_subjectT::* __method)(_objectT*)) : _m_subject(__subject), _m_method(__method) {}
38 
39 	_retT operator()(_objectT* o) const {
40 		return (_m_subject.*_m_method)(o);
41 	}
42 
43 private:
44 	_subjectT&						_m_subject;
45 	_retT (_subjectT::*		_m_method)(_objectT*);
46 };
47 
48 // 27jul99: functor adaptor "call a given method of a given object with argument"
49 template<class _retT, class _subjectT, class _objectT>
50 class bound_const_method_t : public std::unary_function<const _objectT*, _retT> {
51 public:
52 	explicit bound_const_method_t(
53 		// the bound instance on which the method will be called
54 		_subjectT& __subject,
55 		// the method
56 		_retT (_subjectT::* __method)(const _objectT*)) : _m_subject(__subject), _m_method(__method) {}
57 
58 	_retT operator()(const _objectT* o) const {
59 		return (_m_subject.*_m_method)(o);
60 	}
61 
62 private:
63 	_subjectT&						_m_subject;
64 	_retT (_subjectT::*		_m_method)(const _objectT*);
65 };
66 
67 template<class _retT, class _subjectT, class _objectT>
68 class bound_method_ref_t : public std::unary_function<_objectT&, _retT> {
69 public:
70 	explicit bound_method_ref_t(
71 		// the bound instance on which the method will be called
72 		_subjectT& __subject,
73 		// the method
74 		_retT (_subjectT::* __method)(_objectT&)) : _m_subject(__subject), _m_method(__method) {}
75 
76 	_retT operator()(_objectT& o) const {
77 		return (_m_subject.*_m_method)(o);
78 	}
79 
80 private:
81 	_subjectT&						_m_subject;
82 	_retT (_subjectT::*		_m_method)(_objectT&);
83 };
84 
85 template<class _retT, class _subjectT, class _objectT>
86 class bound_const_method_ref_t : public std::unary_function<const _objectT&, _retT> {
87 public:
88 	explicit bound_const_method_ref_t(
89 		// the bound instance on which the method will be called
90 		_subjectT& __subject,
91 		// the method
92 		_retT (_subjectT::* __method)(const _objectT&)) : _m_subject(__subject), _m_method(__method) {}
93 
94 	_retT operator()(const _objectT& o) const {
95 		return (_m_subject.*_m_method)(o);
96 	}
97 
98 private:
99 	_subjectT&						_m_subject;
100 	_retT (_subjectT::*		_m_method)(const _objectT&);
101 };
102 
103 // ***** 1 additional argument *****
104 
105 // 27jul99: functor adaptor "call a given method of a given object with argument"
106 //          + an additional argument
107 template<class _retT, class _subjectT, class _objectT, class _arg1T>
108 class bound_method1_t : public std::binary_function<_objectT*,_arg1T,_retT> {
109 public:
110 	explicit bound_method1_t(
111 		// the bound instance on which the method will be called
112 		_subjectT& __subject,
113 		// the method
114 		_retT (_subjectT::* __method)(_objectT*, _arg1T)) : _m_subject(__subject), _m_method(__method) {}
115 
116 	_retT operator()(_objectT* o, _arg1T arg1) const {
117 		return (_m_subject.*_m_method)(o, arg1);
118 	}
119 
120 private:
121 	_subjectT&						_m_subject;
122 	_retT (_subjectT::*		_m_method)(_objectT*, _arg1T);
123 };
124 
125 
126 // 27jul99: functor adaptor "call a given method of a given object with argument"
127 template<class _retT, class _subjectT, class _objectT, class _arg1T>
128 class bound_const_method1_t : public std::binary_function<const _objectT*,_arg1T,_retT> {
129 public:
130 	explicit bound_const_method1_t(
131 		// the bound instance on which the method will be called
132 		_subjectT& __subject,
133 		// the method
134 		_retT (_subjectT::* __method)(const _objectT*, _arg1T)) : _m_subject(__subject), _m_method(__method) {}
135 
136 	_retT operator()(const _objectT* o, _arg1T arg1) const{
137 		return (_m_subject.*_m_method)(o, arg1);
138 	}
139 
140 private:
141 	_subjectT&						_m_subject;
142 	_retT (_subjectT::*		_m_method)(const _objectT*,_arg1T);
143 };
144 
145 template<class _retT, class _subjectT, class _objectT, class _arg1T>
146 class bound_method_ref1_t : public std::binary_function<_objectT&,_arg1T,_retT> {
147 public:
148 	explicit bound_method_ref1_t(
149 		// the bound instance on which the method will be called
150 		_subjectT& __subject,
151 		// the method
152 		_retT (_subjectT::* __method)(_objectT&,_arg1T)) : _m_subject(__subject), _m_method(__method) {}
153 
154 	_retT operator()(_objectT& o, _arg1T arg1) const {
155 		return (_m_subject.*_m_method)(o, arg1);
156 	}
157 
158 private:
159 	_subjectT&						_m_subject;
160 	_retT (_subjectT::*		_m_method)(_objectT&,_arg1T);
161 };
162 
163 template<class _retT, class _subjectT, class _objectT, class _arg1T>
164 class bound_const_method_ref1_t : public std::binary_function<const _objectT&,_arg1T,_retT> {
165 public:
166 	explicit bound_const_method_ref1_t(
167 		// the bound instance on which the method will be called
168 		_subjectT& __subject,
169 		// the method
170 		_retT (_subjectT::* __method)(const _objectT&,_arg1T)) : _m_subject(__subject), _m_method(__method) {}
171 
172 	_retT operator()(const _objectT& o, _arg1T arg1) const {
173 		return (_m_subject.*_m_method)(o, arg1);
174 	}
175 
176 private:
177 	_subjectT&						_m_subject;
178 	_retT (_subjectT::*		_m_method)(const _objectT&,_arg1T);
179 };
180 
181 
182 // 27jul99: adaptor functions
183 
184 // ***** 0-argument *****
185 
186 template<class _retT, class _subjectT, class _objectT>
187 inline bound_method_t<_retT,_subjectT,_objectT> bound_method(
188 	_subjectT& subject, _retT (_subjectT::* method)(_objectT*)) {
189 	return bound_method_t<_retT,_subjectT,_objectT>(subject, method);
190 }
191 
192 template<class _retT, class _subjectT, class _objectT>
193 inline bound_const_method_t<_retT,_subjectT,_objectT> bound_method(
194 	_subjectT& subject, _retT (_subjectT::* method)(const _objectT*)) {
195 	return bound_const_method_t<_retT,_subjectT,_objectT>(subject, method);
196 }
197 
198 template<class _retT, class _subjectT, class _objectT>
199 inline bound_method_ref_t<_retT,_subjectT,_objectT> bound_method(
200 	_subjectT& subject, _retT (_subjectT::* method)(_objectT&)) {
201 	return bound_method_ref_t<_retT,_subjectT,_objectT>(subject, method);
202 }
203 
204 template<class _retT, class _subjectT, class _objectT>
205 inline bound_const_method_ref_t<_retT,_subjectT,_objectT> bound_method(
206 	_subjectT& subject, _retT (_subjectT::* method)(const _objectT&)) {
207 	return bound_const_method_ref_t<_retT,_subjectT,_objectT>(subject, method);
208 }
209 
210 // ***** 1-argument *****
211 
212 template<class _retT, class _subjectT, class _objectT, class _arg1T>
213 inline bound_method1_t<_retT,_subjectT,_objectT,_arg1T> bound_method(
214 	_subjectT& subject, _retT (_subjectT::* method)(_objectT*,_arg1T)) {
215 	return bound_method1_t<_retT,_subjectT,_objectT,_arg1T>(subject, method);
216 }
217 
218 template<class _retT, class _subjectT, class _objectT, class _arg1T>
219 inline bound_const_method1_t<_retT,_subjectT,_objectT,_arg1T> bound_method(
220 	_subjectT& subject, _retT (_subjectT::* method)(const _objectT*,_arg1T)) {
221 	return bound_const_method1_t<_retT,_subjectT,_objectT,_arg1T>(subject, method);
222 }
223 
224 template<class _retT, class _subjectT, class _objectT, class _arg1T>
225 inline bound_method_ref1_t<_retT,_subjectT,_objectT,_arg1T> bound_method(
226 	_subjectT& subject, _retT (_subjectT::* method)(_objectT&,_arg1T)) {
227 	return bound_method_ref1_t<_retT,_subjectT,_objectT,_arg1T>(subject, method);
228 }
229 
230 template<class _retT, class _subjectT, class _objectT, class _arg1T>
231 inline bound_const_method_ref1_t<_retT,_subjectT,_objectT,_arg1T> bound_method(
232 	_subjectT& subject, _retT (_subjectT::* method)(const _objectT&,_arg1T)) {
233 	return bound_const_method_ref1_t<_retT,_subjectT,_objectT,_arg1T>(subject, method);
234 }
235 
236 __END_CORTEX_NAMESPACE
237 #endif /*__functional_tools_H__*/
238