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