xref: /haiku/src/apps/cortex/support/functional_tools.h (revision c9afad22682e9f15753db4e9ca8684e2d4a643a9)
1 /*
2  * Copyright (c) 1999-2000, Eric Moon.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions, and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions, and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * 3. The name of the author may not be used to endorse or promote products
17  *    derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21  * OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
23  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
27  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 
32 // functional_tools.h
33 //
34 // PURPOSE
35 //   Some extra STL-related functors, adaptors, & helper functions.
36 //
37 // NOTES
38 //   bound_method() makes it easy to use STL algorithms to apply a given
39 //     method in a given object to a set of instances of another class.
40 //
41 //   The additional-argument functors aren't perfected; most notably,
42 //     bind2nd() doesn't handle bound methods that take objects by
43 //     reference.  +++++
44 //
45 // HISTORY
46 //   e.moon 27jul99		begun
47 
48 #ifndef __functional_tools_H__
49 #define __functional_tools_H__
50 
51 #include "cortex_defs.h"
52 __BEGIN_CORTEX_NAMESPACE
53 
54 ///////////////////////////////////////////////////////////////////////////
55 // bound_method
56 ///////////////////////////////////////////////////////////////////////////
57 
58 // ***** no additional arguments *****
59 
60 // 27jul99: functor adaptor "call a given method of a given object with argument"
61 template<class _retT, class _subjectT, class _objectT>
62 class bound_method_t {
63 public:
64 	explicit bound_method_t(
65 		// the bound instance on which the method will be called
66 		_subjectT& __subject,
67 		// the method
68 		_retT (_subjectT::* __method)(_objectT*)) : _m_subject(__subject), _m_method(__method) {}
69 
70 	_retT operator()(_objectT* o) const {
71 		return (_m_subject.*_m_method)(o);
72 	}
73 
74 private:
75 	_subjectT&						_m_subject;
76 	_retT (_subjectT::*		_m_method)(_objectT*);
77 };
78 
79 // 27jul99: functor adaptor "call a given method of a given object with argument"
80 template<class _retT, class _subjectT, class _objectT>
81 class bound_const_method_t {
82 public:
83 	explicit bound_const_method_t(
84 		// the bound instance on which the method will be called
85 		_subjectT& __subject,
86 		// the method
87 		_retT (_subjectT::* __method)(const _objectT*)) : _m_subject(__subject), _m_method(__method) {}
88 
89 	_retT operator()(const _objectT* o) const {
90 		return (_m_subject.*_m_method)(o);
91 	}
92 
93 private:
94 	_subjectT&						_m_subject;
95 	_retT (_subjectT::*		_m_method)(const _objectT*);
96 };
97 
98 template<class _retT, class _subjectT, class _objectT>
99 class bound_method_ref_t {
100 public:
101 	explicit bound_method_ref_t(
102 		// the bound instance on which the method will be called
103 		_subjectT& __subject,
104 		// the method
105 		_retT (_subjectT::* __method)(_objectT&)) : _m_subject(__subject), _m_method(__method) {}
106 
107 	_retT operator()(_objectT& o) const {
108 		return (_m_subject.*_m_method)(o);
109 	}
110 
111 private:
112 	_subjectT&						_m_subject;
113 	_retT (_subjectT::*		_m_method)(_objectT&);
114 };
115 
116 template<class _retT, class _subjectT, class _objectT>
117 class bound_const_method_ref_t {
118 public:
119 	explicit bound_const_method_ref_t(
120 		// the bound instance on which the method will be called
121 		_subjectT& __subject,
122 		// the method
123 		_retT (_subjectT::* __method)(const _objectT&)) : _m_subject(__subject), _m_method(__method) {}
124 
125 	_retT operator()(const _objectT& o) const {
126 		return (_m_subject.*_m_method)(o);
127 	}
128 
129 private:
130 	_subjectT&						_m_subject;
131 	_retT (_subjectT::*		_m_method)(const _objectT&);
132 };
133 
134 // ***** 1 additional argument *****
135 
136 // 27jul99: functor adaptor "call a given method of a given object with argument"
137 //          + an additional argument
138 template<class _retT, class _subjectT, class _objectT, class _arg1T>
139 class bound_method1_t {
140 public:
141 	explicit bound_method1_t(
142 		// the bound instance on which the method will be called
143 		_subjectT& __subject,
144 		// the method
145 		_retT (_subjectT::* __method)(_objectT*, _arg1T)) : _m_subject(__subject), _m_method(__method) {}
146 
147 	_retT operator()(_objectT* o, _arg1T arg1) const {
148 		return (_m_subject.*_m_method)(o, arg1);
149 	}
150 
151 private:
152 	_subjectT&						_m_subject;
153 	_retT (_subjectT::*		_m_method)(_objectT*, _arg1T);
154 };
155 
156 
157 // 27jul99: functor adaptor "call a given method of a given object with argument"
158 template<class _retT, class _subjectT, class _objectT, class _arg1T>
159 class bound_const_method1_t {
160 public:
161 	explicit bound_const_method1_t(
162 		// the bound instance on which the method will be called
163 		_subjectT& __subject,
164 		// the method
165 		_retT (_subjectT::* __method)(const _objectT*, _arg1T)) : _m_subject(__subject), _m_method(__method) {}
166 
167 	_retT operator()(const _objectT* o, _arg1T arg1) const{
168 		return (_m_subject.*_m_method)(o, arg1);
169 	}
170 
171 private:
172 	_subjectT&						_m_subject;
173 	_retT (_subjectT::*		_m_method)(const _objectT*,_arg1T);
174 };
175 
176 template<class _retT, class _subjectT, class _objectT, class _arg1T>
177 class bound_method_ref1_t {
178 public:
179 	explicit bound_method_ref1_t(
180 		// the bound instance on which the method will be called
181 		_subjectT& __subject,
182 		// the method
183 		_retT (_subjectT::* __method)(_objectT&,_arg1T)) : _m_subject(__subject), _m_method(__method) {}
184 
185 	_retT operator()(_objectT& o, _arg1T arg1) const {
186 		return (_m_subject.*_m_method)(o, arg1);
187 	}
188 
189 private:
190 	_subjectT&						_m_subject;
191 	_retT (_subjectT::*		_m_method)(_objectT&,_arg1T);
192 };
193 
194 template<class _retT, class _subjectT, class _objectT, class _arg1T>
195 class bound_const_method_ref1_t {
196 public:
197 	explicit bound_const_method_ref1_t(
198 		// the bound instance on which the method will be called
199 		_subjectT& __subject,
200 		// the method
201 		_retT (_subjectT::* __method)(const _objectT&,_arg1T)) : _m_subject(__subject), _m_method(__method) {}
202 
203 	_retT operator()(const _objectT& o, _arg1T arg1) const {
204 		return (_m_subject.*_m_method)(o, arg1);
205 	}
206 
207 private:
208 	_subjectT&						_m_subject;
209 	_retT (_subjectT::*		_m_method)(const _objectT&,_arg1T);
210 };
211 
212 
213 // 27jul99: adaptor functions
214 
215 // ***** 0-argument *****
216 
217 template<class _retT, class _subjectT, class _objectT>
218 inline bound_method_t<_retT,_subjectT,_objectT> bound_method(
219 	_subjectT& subject, _retT (_subjectT::* method)(_objectT*)) {
220 	return bound_method_t<_retT,_subjectT,_objectT>(subject, method);
221 }
222 
223 template<class _retT, class _subjectT, class _objectT>
224 inline bound_const_method_t<_retT,_subjectT,_objectT> bound_method(
225 	_subjectT& subject, _retT (_subjectT::* method)(const _objectT*)) {
226 	return bound_const_method_t<_retT,_subjectT,_objectT>(subject, method);
227 }
228 
229 template<class _retT, class _subjectT, class _objectT>
230 inline bound_method_ref_t<_retT,_subjectT,_objectT> bound_method(
231 	_subjectT& subject, _retT (_subjectT::* method)(_objectT&)) {
232 	return bound_method_ref_t<_retT,_subjectT,_objectT>(subject, method);
233 }
234 
235 template<class _retT, class _subjectT, class _objectT>
236 inline bound_const_method_ref_t<_retT,_subjectT,_objectT> bound_method(
237 	_subjectT& subject, _retT (_subjectT::* method)(const _objectT&)) {
238 	return bound_const_method_ref_t<_retT,_subjectT,_objectT>(subject, method);
239 }
240 
241 // ***** 1-argument *****
242 
243 template<class _retT, class _subjectT, class _objectT, class _arg1T>
244 inline bound_method1_t<_retT,_subjectT,_objectT,_arg1T> bound_method(
245 	_subjectT& subject, _retT (_subjectT::* method)(_objectT*,_arg1T)) {
246 	return bound_method1_t<_retT,_subjectT,_objectT,_arg1T>(subject, method);
247 }
248 
249 template<class _retT, class _subjectT, class _objectT, class _arg1T>
250 inline bound_const_method1_t<_retT,_subjectT,_objectT,_arg1T> bound_method(
251 	_subjectT& subject, _retT (_subjectT::* method)(const _objectT*,_arg1T)) {
252 	return bound_const_method1_t<_retT,_subjectT,_objectT,_arg1T>(subject, method);
253 }
254 
255 template<class _retT, class _subjectT, class _objectT, class _arg1T>
256 inline bound_method_ref1_t<_retT,_subjectT,_objectT,_arg1T> bound_method(
257 	_subjectT& subject, _retT (_subjectT::* method)(_objectT&,_arg1T)) {
258 	return bound_method_ref1_t<_retT,_subjectT,_objectT,_arg1T>(subject, method);
259 }
260 
261 template<class _retT, class _subjectT, class _objectT, class _arg1T>
262 inline bound_const_method_ref1_t<_retT,_subjectT,_objectT,_arg1T> bound_method(
263 	_subjectT& subject, _retT (_subjectT::* method)(const _objectT&,_arg1T)) {
264 	return bound_const_method_ref1_t<_retT,_subjectT,_objectT,_arg1T>(subject, method);
265 }
266 
267 __END_CORTEX_NAMESPACE
268 #endif /*__functional_tools_H__*/
269