2 * Copyright (c) 1999-2000, Eric Moon.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions, and the following disclaimer.
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.
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.
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.
35 // Some extra STL-related functors, adaptors, & helper functions.
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.
41 // The additional-argument functors aren't perfected; most notably,
42 // bind2nd() doesn't handle bound methods that take objects by
46 // e.moon 27jul99 begun
48 #ifndef __functional_tools_H__
49 #define __functional_tools_H__
51 #include "cortex_defs.h"
52 __BEGIN_CORTEX_NAMESPACE
54 ///////////////////////////////////////////////////////////////////////////
56 ///////////////////////////////////////////////////////////////////////////
58 // ***** no additional arguments *****
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
: public std::unary_function
<_objectT
*, _retT
> {
64 explicit bound_method_t(
65 // the bound instance on which the method will be called
68 _retT (_subjectT::* __method
)(_objectT
*)) : _m_subject(__subject
), _m_method(__method
) {}
70 _retT
operator()(_objectT
* o
) const {
71 return (_m_subject
.*_m_method
)(o
);
75 _subjectT
& _m_subject
;
76 _retT (_subjectT::* _m_method
)(_objectT
*);
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
: public std::unary_function
<const _objectT
*, _retT
> {
83 explicit bound_const_method_t(
84 // the bound instance on which the method will be called
87 _retT (_subjectT::* __method
)(const _objectT
*)) : _m_subject(__subject
), _m_method(__method
) {}
89 _retT
operator()(const _objectT
* o
) const {
90 return (_m_subject
.*_m_method
)(o
);
94 _subjectT
& _m_subject
;
95 _retT (_subjectT::* _m_method
)(const _objectT
*);
98 template<class _retT
, class _subjectT
, class _objectT
>
99 class bound_method_ref_t
: public std::unary_function
<_objectT
&, _retT
> {
101 explicit bound_method_ref_t(
102 // the bound instance on which the method will be called
103 _subjectT
& __subject
,
105 _retT (_subjectT::* __method
)(_objectT
&)) : _m_subject(__subject
), _m_method(__method
) {}
107 _retT
operator()(_objectT
& o
) const {
108 return (_m_subject
.*_m_method
)(o
);
112 _subjectT
& _m_subject
;
113 _retT (_subjectT::* _m_method
)(_objectT
&);
116 template<class _retT
, class _subjectT
, class _objectT
>
117 class bound_const_method_ref_t
: public std::unary_function
<const _objectT
&, _retT
> {
119 explicit bound_const_method_ref_t(
120 // the bound instance on which the method will be called
121 _subjectT
& __subject
,
123 _retT (_subjectT::* __method
)(const _objectT
&)) : _m_subject(__subject
), _m_method(__method
) {}
125 _retT
operator()(const _objectT
& o
) const {
126 return (_m_subject
.*_m_method
)(o
);
130 _subjectT
& _m_subject
;
131 _retT (_subjectT::* _m_method
)(const _objectT
&);
134 // ***** 1 additional argument *****
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
: public std::binary_function
<_objectT
*,_arg1T
,_retT
> {
141 explicit bound_method1_t(
142 // the bound instance on which the method will be called
143 _subjectT
& __subject
,
145 _retT (_subjectT::* __method
)(_objectT
*, _arg1T
)) : _m_subject(__subject
), _m_method(__method
) {}
147 _retT
operator()(_objectT
* o
, _arg1T arg1
) const {
148 return (_m_subject
.*_m_method
)(o
, arg1
);
152 _subjectT
& _m_subject
;
153 _retT (_subjectT::* _m_method
)(_objectT
*, _arg1T
);
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
: public std::binary_function
<const _objectT
*,_arg1T
,_retT
> {
161 explicit bound_const_method1_t(
162 // the bound instance on which the method will be called
163 _subjectT
& __subject
,
165 _retT (_subjectT::* __method
)(const _objectT
*, _arg1T
)) : _m_subject(__subject
), _m_method(__method
) {}
167 _retT
operator()(const _objectT
* o
, _arg1T arg1
) const{
168 return (_m_subject
.*_m_method
)(o
, arg1
);
172 _subjectT
& _m_subject
;
173 _retT (_subjectT::* _m_method
)(const _objectT
*,_arg1T
);
176 template<class _retT
, class _subjectT
, class _objectT
, class _arg1T
>
177 class bound_method_ref1_t
: public std::binary_function
<_objectT
&,_arg1T
,_retT
> {
179 explicit bound_method_ref1_t(
180 // the bound instance on which the method will be called
181 _subjectT
& __subject
,
183 _retT (_subjectT::* __method
)(_objectT
&,_arg1T
)) : _m_subject(__subject
), _m_method(__method
) {}
185 _retT
operator()(_objectT
& o
, _arg1T arg1
) const {
186 return (_m_subject
.*_m_method
)(o
, arg1
);
190 _subjectT
& _m_subject
;
191 _retT (_subjectT::* _m_method
)(_objectT
&,_arg1T
);
194 template<class _retT
, class _subjectT
, class _objectT
, class _arg1T
>
195 class bound_const_method_ref1_t
: public std::binary_function
<const _objectT
&,_arg1T
,_retT
> {
197 explicit bound_const_method_ref1_t(
198 // the bound instance on which the method will be called
199 _subjectT
& __subject
,
201 _retT (_subjectT::* __method
)(const _objectT
&,_arg1T
)) : _m_subject(__subject
), _m_method(__method
) {}
203 _retT
operator()(const _objectT
& o
, _arg1T arg1
) const {
204 return (_m_subject
.*_m_method
)(o
, arg1
);
208 _subjectT
& _m_subject
;
209 _retT (_subjectT::* _m_method
)(const _objectT
&,_arg1T
);
213 // 27jul99: adaptor functions
215 // ***** 0-argument *****
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
);
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
);
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
);
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
);
241 // ***** 1-argument *****
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
);
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
);
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
);
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
);
267 __END_CORTEX_NAMESPACE
268 #endif /*__functional_tools_H__*/