00001 /** @file rutz/functors.h template mechanisms for determine parameter 00002 types and return types of functions or general functors */ 00003 00004 /////////////////////////////////////////////////////////////////////// 00005 // 00006 // Copyright (c) 2001-2004 California Institute of Technology 00007 // Copyright (c) 2004-2007 University of Southern California 00008 // Rob Peters <rjpeters at usc dot edu> 00009 // 00010 // created: Fri Sep 7 15:07:16 2001 00011 // commit: $Id: functors.h 8249 2007-04-12 06:03:40Z rjpeters $ 00012 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/rutz/functors.h $ 00013 // 00014 // -------------------------------------------------------------------- 00015 // 00016 // This file is part of GroovX. 00017 // [http://ilab.usc.edu/rjpeters/groovx/] 00018 // 00019 // GroovX is free software; you can redistribute it and/or modify it 00020 // under the terms of the GNU General Public License as published by 00021 // the Free Software Foundation; either version 2 of the License, or 00022 // (at your option) any later version. 00023 // 00024 // GroovX is distributed in the hope that it will be useful, but 00025 // WITHOUT ANY WARRANTY; without even the implied warranty of 00026 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00027 // General Public License for more details. 00028 // 00029 // You should have received a copy of the GNU General Public License 00030 // along with GroovX; if not, write to the Free Software Foundation, 00031 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 00032 // 00033 /////////////////////////////////////////////////////////////////////// 00034 00035 #ifndef GROOVX_RUTZ_FUNCTORS_H_UTC20050626084020_DEFINED 00036 #define GROOVX_RUTZ_FUNCTORS_H_UTC20050626084020_DEFINED 00037 00038 namespace rutz 00039 { 00040 // ####################################################### 00041 // ======================================================= 00042 // 00043 // func_traits 00044 // 00045 // ======================================================= 00046 00047 struct null_t; 00048 00049 /// Holds typedefs for the types of a function's arguments and return value. 00050 template <class R = void, 00051 class A1 = null_t, class A2 = null_t, class A3 = null_t, 00052 class A4 = null_t, class A5 = null_t, class A6 = null_t, 00053 class A7 = null_t, class A8 = null_t> 00054 struct func_args 00055 { 00056 typedef R retn_t; 00057 typedef A1 arg1_t; 00058 typedef A2 arg2_t; 00059 typedef A3 arg3_t; 00060 typedef A4 arg4_t; 00061 typedef A5 arg5_t; 00062 typedef A6 arg6_t; 00063 typedef A7 arg7_t; 00064 typedef A8 arg8_t; 00065 }; 00066 00067 /// A traits class for holding information about functions/functors. 00068 template <class func> 00069 struct func_traits 00070 { 00071 typedef typename func::retn_t retn_t; 00072 }; 00073 00074 // ======================================================= 00075 // 00076 // func_traits specializations for free functions 00077 // 00078 // ======================================================= 00079 00080 /// Specialization for free functions with no arguments. 00081 template <class R> 00082 struct func_traits<R (*)()> 00083 : 00084 public func_args<R> 00085 { 00086 enum { num_args = 0 }; 00087 }; 00088 00089 /// Specialization for free functions with 1 argument. 00090 template <class R, class P1> 00091 struct func_traits<R (*)(P1)> 00092 : 00093 public func_args<R, P1> 00094 { 00095 enum { num_args = 1 }; 00096 }; 00097 00098 /// Specialization for free functions with 2 arguments. 00099 template <class R, class P1, class P2> 00100 struct func_traits<R (*)(P1, P2)> 00101 : 00102 public func_args<R, P1, P2> 00103 { 00104 enum { num_args = 2 }; 00105 }; 00106 00107 /// Specialization for free functions with 3 arguments. 00108 template <class R, class P1, class P2, class P3> 00109 struct func_traits<R (*)(P1, P2, P3)> 00110 : 00111 public func_args<R, P1, P2, P3> 00112 { 00113 enum { num_args = 3 }; 00114 }; 00115 00116 /// Specialization for free functions with 4 arguments. 00117 template <class R, class P1, class P2, class P3, class P4> 00118 struct func_traits<R (*)(P1, P2, P3, P4)> 00119 : 00120 public func_args<R, P1, P2, P3, P4> 00121 { 00122 enum { num_args = 4 }; 00123 }; 00124 00125 /// Specialization for free functions with 5 arguments. 00126 template <class R, class P1, class P2, class P3, class P4, class P5> 00127 struct func_traits<R (*)(P1, P2, P3, P4, P5)> 00128 : 00129 public func_args<R, P1, P2, P3, P4, P5> 00130 { 00131 enum { num_args = 5 }; 00132 }; 00133 00134 /// Specialization for free functions with 6 arguments. 00135 template <class R, class P1, class P2, class P3, class P4, class P5, 00136 class P6> 00137 struct func_traits<R (*)(P1, P2, P3, P4, P5, P6)> 00138 : 00139 public func_args<R, P1, P2, P3, P3, P4, P5, P6> 00140 { 00141 enum { num_args = 6 }; 00142 }; 00143 00144 // ======================================================= 00145 // 00146 // func_traits specializations for member functions 00147 // 00148 // We treat the "this" pointer as an implicit first-argument to the 00149 // function. 00150 // 00151 // ======================================================= 00152 00153 /// Specialization for member functions with "this" plus 0 arguments. 00154 template <class R, class C> 00155 struct func_traits<R (C::*)()> 00156 : 00157 public func_args<R, null_t> 00158 { 00159 enum { num_args = 1 }; 00160 typedef C class_t; 00161 }; 00162 00163 /// Specialization for member functions with "this" plus 0 arguments. 00164 template <class R, class C> 00165 struct func_traits<R (C::*)() const> 00166 : 00167 public func_args<R, null_t> 00168 { 00169 enum { num_args = 1 }; 00170 typedef C class_t; 00171 }; 00172 00173 /// Specialization for member functions with "this" plus 1 argument. 00174 template <class R, class C, class P1> 00175 struct func_traits<R (C::*)(P1)> 00176 : 00177 public func_args<R, null_t, P1> 00178 { 00179 enum { num_args = 2 }; 00180 typedef C class_t; 00181 }; 00182 00183 /// Specialization for member functions with "this" plus 1 argument. 00184 template <class R, class C, class P1> 00185 struct func_traits<R (C::*)(P1) const> 00186 : 00187 public func_args<R, null_t, P1> 00188 { 00189 enum { num_args = 2 }; 00190 typedef C class_t; 00191 }; 00192 00193 /// Specialization for member functions with "this" plus 2 arguments. 00194 template <class R, class C, class P1, class P2> 00195 struct func_traits<R (C::*)(P1, P2)> 00196 : 00197 public func_args<R, null_t, P1, P2> 00198 { 00199 enum { num_args = 3 }; 00200 typedef C class_t; 00201 }; 00202 00203 /// Specialization for member functions with "this" plus 2 arguments. 00204 template <class R, class C, class P1, class P2> 00205 struct func_traits<R (C::*)(P1, P2) const> 00206 : 00207 public func_args<R, null_t, P1, P2> 00208 { 00209 enum { num_args = 3 }; 00210 typedef C class_t; 00211 }; 00212 00213 /// Specialization for member functions with "this" plus 3 arguments. 00214 template <class R, class C, class P1, class P2, class P3> 00215 struct func_traits<R (C::*)(P1, P2, P3)> 00216 : 00217 public func_args<R, null_t, P1, P2, P3> 00218 { 00219 enum { num_args = 4 }; 00220 typedef C class_t; 00221 }; 00222 00223 /// Specialization for member functions with "this" plus 3 arguments. 00224 template <class R, class C, class P1, class P2, class P3> 00225 struct func_traits<R (C::*)(P1, P2, P3) const> 00226 : 00227 public func_args<R, null_t, P1, P2, P3> 00228 { 00229 enum { num_args = 4 }; 00230 typedef C class_t; 00231 }; 00232 00233 /// Specialization for member functions with "this" plus 4 arguments. 00234 template <class R, class C, class P1, class P2, class P3, class P4> 00235 struct func_traits<R (C::*)(P1, P2, P3, P4)> 00236 : 00237 public func_args<R, null_t, P1, P2, P3, P4> 00238 { 00239 enum { num_args = 5 }; 00240 typedef C class_t; 00241 }; 00242 00243 /// Specialization for member functions with "this" plus 4 arguments. 00244 template <class R, class C, class P1, class P2, class P3, class P4> 00245 struct func_traits<R (C::*)(P1, P2, P3, P4) const> 00246 : 00247 public func_args<R, null_t, P1, P2, P3, P4> 00248 { 00249 enum { num_args = 5 }; 00250 typedef C class_t; 00251 }; 00252 00253 /// Specialization for member functions with "this" plus 5 arguments. 00254 template <class R, class C, class P1, class P2, class P3, class P4, 00255 class P5> 00256 struct func_traits<R (C::*)(P1, P2, P3, P4, P5)> 00257 : 00258 public func_args<R, null_t, P1, P2, P3, P4, P5> 00259 { 00260 enum { num_args = 6 }; 00261 typedef C class_t; 00262 }; 00263 00264 /// Specialization for member functions with "this" plus 5 arguments. 00265 template <class R, class C, class P1, class P2, class P3, class P4, 00266 class P5> 00267 struct func_traits<R (C::*)(P1, P2, P3, P4, P5) const> 00268 : 00269 public func_args<R, null_t, P1, P2, P3, P4, P5> 00270 { 00271 enum { num_args = 6 }; 00272 typedef C class_t; 00273 }; 00274 00275 /// Specialization for member functions with "this" plus 6 arguments. 00276 template <class R, class C, class P1, class P2, class P3, class P4, 00277 class P5, class P6> 00278 struct func_traits<R (C::*)(P1, P2, P3, P4, P5, P6)> 00279 : 00280 public func_args<R, null_t, P1, P2, P3, P4, P5, P6> 00281 { 00282 enum { num_args = 7 }; 00283 typedef C class_t; 00284 }; 00285 00286 /// Specialization for member functions with "this" plus 6 arguments. 00287 template <class R, class C, class P1, class P2, class P3, class P4, 00288 class P5, class P6> 00289 struct func_traits<R (C::*)(P1, P2, P3, P4, P5, P6) const> 00290 : 00291 public func_args<R, null_t, P1, P2, P3, P4, P5, P6> 00292 { 00293 enum { num_args = 7 }; 00294 typedef C class_t; 00295 }; 00296 00297 // ####################################################### 00298 // ======================================================= 00299 00300 template <class F> 00301 class mem_functor_base; 00302 00303 /// func_traits specialization for mem_functor_base. 00304 template <class MF> 00305 struct func_traits<mem_functor_base<MF> > : public func_traits<MF> 00306 {}; 00307 00308 /// mem_functor_base adapts a member function to an ordinary operator(). 00309 /** The "this" pointer is passed through the first argument of the 00310 operator() call, via a raw pointer or a smart pointer. */ 00311 00312 template <class mem_func> 00313 class mem_functor_base 00314 : 00315 public func_traits<mem_functor_base<mem_func> > 00316 { 00317 private: 00318 mem_func m_held_func; 00319 00320 public: 00321 typedef typename func_traits<mem_func>::retn_t R; 00322 typedef typename func_traits<mem_func>::class_t C; 00323 00324 mem_functor_base(mem_func f) : m_held_func(f) {} 00325 00326 /// Function-call operator for object + 0 args. 00327 template <class ptr> 00328 R operator()(ptr obj) 00329 { 00330 return ((*obj).*m_held_func)(); 00331 } 00332 00333 /// Function-call operator for object + 1 arg. 00334 template <class ptr, class P1> 00335 R operator()(ptr obj, P1 p1) 00336 { 00337 return ((*obj).*m_held_func)(p1); 00338 } 00339 00340 /// Function-call operator for object + 2 args. 00341 template <class ptr, class P1, class P2> 00342 R operator()(ptr obj, P1 p1, P2 p2) 00343 { 00344 return ((*obj).*m_held_func)(p1, p2); 00345 } 00346 00347 /// Function-call operator for object + 3 args. 00348 template <class ptr, class P1, class P2, class P3> 00349 R operator()(ptr obj, P1 p1, P2 p2, P3 p3) 00350 { 00351 return ((*obj).*m_held_func)(p1, p2, p3); 00352 } 00353 00354 /// Function-call operator for object + 4 args. 00355 template <class ptr, class P1, class P2, class P3, class P4> 00356 R operator()(ptr obj, P1 p1, P2 p2, P3 p3, P4 p4) 00357 { 00358 return ((*obj).*m_held_func)(p1, p2, p3, p4); 00359 } 00360 00361 /// Function-call operator for object + 5 args. 00362 template <class ptr, class P1, class P2, class P3, class P4, 00363 class P5> 00364 R operator()(ptr obj, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) 00365 { 00366 return ((*obj).*m_held_func)(p1, p2, p3, p4, p5); 00367 } 00368 00369 /// Function-call operator for object + 6 args. 00370 template <class ptr, class P1, class P2, class P3, class P4, 00371 class P5, class P6> 00372 R operator()(ptr obj, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) 00373 { 00374 return ((*obj).*m_held_func)(p1, p2, p3, p4, p5, p6); 00375 } 00376 }; 00377 00378 // ####################################################### 00379 // ======================================================= 00380 00381 /// mem_functor extends mem_functor_base smart pointers for "this". 00382 00383 // ======================================================= 00384 00385 template <class mem_func> 00386 struct mem_functor : public mem_functor_base<mem_func> 00387 { 00388 mem_functor(mem_func f) : mem_functor_base<mem_func>(f) {} 00389 00390 // operator()'s inherited from mem_functor_base 00391 }; 00392 00393 /// Factory function to make a mem_functor from any member function. 00394 template <class MF> 00395 inline mem_functor<MF> mem_func(MF mf) 00396 { 00397 return mf; 00398 } 00399 00400 00401 // ####################################################### 00402 // ======================================================= 00403 00404 /// Traits struct for specifying a "functor" type given a function pointer. 00405 template <class fptr> 00406 struct functor_of 00407 { 00408 typedef fptr type; 00409 }; 00410 00411 /// Specialization for zero-arg mem func. 00412 template <class R, class C> 00413 struct functor_of< R (C::*)() > 00414 { 00415 typedef rutz::mem_functor<R (C::*)()> type; 00416 }; 00417 00418 /// Specialization for zero-arg const mem func. 00419 template <class R, class C> 00420 struct functor_of< R (C::*)() const > 00421 { 00422 typedef rutz::mem_functor<R (C::*)() const> type; 00423 }; 00424 00425 /// Specialization for one-arg mem func. 00426 template <class R, class C, class P1> 00427 struct functor_of< R (C::*)(P1) > 00428 { 00429 typedef rutz::mem_functor<R (C::*)(P1)> type; 00430 }; 00431 00432 /// Specialization for one-arg const mem func. 00433 template <class R, class C, class P1> 00434 struct functor_of< R (C::*)(P1) const > 00435 { 00436 typedef rutz::mem_functor<R (C::*)(P1) const> type; 00437 }; 00438 00439 /// Specialization for two-arg mem func. 00440 template <class R, class C, class P1, class P2> 00441 struct functor_of< R (C::*)(P1, P2) > 00442 { 00443 typedef rutz::mem_functor<R (C::*)(P1, P2)> type; 00444 }; 00445 00446 /// Specialization for two-arg const mem func. 00447 template <class R, class C, class P1, class P2> 00448 struct functor_of< R (C::*)(P1, P2) const > 00449 { 00450 typedef rutz::mem_functor<R (C::*)(P1, P2) const> type; 00451 }; 00452 00453 /// Specialization for three-arg mem func. 00454 template <class R, class C, class P1, class P2, class P3> 00455 struct functor_of< R (C::*)(P1, P2, P3) > 00456 { 00457 typedef rutz::mem_functor<R (C::*)(P1, P2, P3)> type; 00458 }; 00459 00460 /// Specialization for three-arg const mem func. 00461 template <class R, class C, class P1, class P2, class P3> 00462 struct functor_of< R (C::*)(P1, P2, P3) const > 00463 { 00464 typedef rutz::mem_functor<R (C::*)(P1, P2, P3) const> type; 00465 }; 00466 00467 /// Specialization for four-arg mem func. 00468 template <class R, class C, class P1, class P2, class P3, class P4> 00469 struct functor_of< R (C::*)(P1, P2, P3, P4) > 00470 { 00471 typedef rutz::mem_functor<R (C::*)(P1, P2, P3, P4)> type; 00472 }; 00473 00474 /// Specialization for four-arg const mem func. 00475 template <class R, class C, class P1, class P2, class P3, class P4> 00476 struct functor_of< R (C::*)(P1, P2, P3, P4) const > 00477 { 00478 typedef rutz::mem_functor<R (C::*)(P1, P2, P3, P4) const> type; 00479 }; 00480 00481 /// Specialization for 5-arg mem func. 00482 template <class R, class C, class P1, class P2, class P3, class P4, 00483 class P5> 00484 struct functor_of< R (C::*)(P1, P2, P3, P4, P5) > 00485 { 00486 typedef rutz::mem_functor<R (C::*)(P1, P2, P3, P4, P5)> type; 00487 }; 00488 00489 /// Specialization for 5-arg const mem func. 00490 template <class R, class C, class P1, class P2, class P3, class P4, 00491 class P5> 00492 struct functor_of< R (C::*)(P1, P2, P3, P4, P5) const > 00493 { 00494 typedef rutz::mem_functor<R (C::*)(P1, P2, P3, P4, P5) const> type; 00495 }; 00496 00497 /// Specialization for 6-arg mem func. 00498 template <class R, class C, class P1, class P2, class P3, class P4, 00499 class P5, class P6> 00500 struct functor_of< R (C::*)(P1, P2, P3, P4, P5, P6) > 00501 { 00502 typedef rutz::mem_functor<R (C::*)(P1, P2, P3, P4, P5, P6)> type; 00503 }; 00504 00505 /// Specialization for 6-arg const mem func. 00506 template <class R, class C, class P1, class P2, class P3, class P4, 00507 class P5, class P6> 00508 struct functor_of< R (C::*)(P1, P2, P3, P4, P5, P6) const > 00509 { 00510 typedef rutz::mem_functor<R (C::*)(P1, P2, P3, P4, P5, P6) const> type; 00511 }; 00512 00513 00514 // ######################################################## 00515 // ======================================================= 00516 00517 /// Factory function for building a "functor" from any function pointer. 00518 template <class fptr> 00519 inline typename functor_of<fptr>::type 00520 build_functor(fptr f) 00521 { 00522 typedef typename functor_of<fptr>::type functor_t; 00523 return functor_t(f); 00524 } 00525 00526 // ####################################################### 00527 // ======================================================= 00528 00529 template <class base_functor, class bound_t> 00530 class bound_first; 00531 00532 /// func_traits specialization for bound_first. 00533 template <class base_functor, class bound_t> 00534 struct func_traits<bound_first<base_functor, bound_t> > 00535 { 00536 enum { num_args = (func_traits<base_functor>::num_args-1) }; 00537 00538 typedef typename func_traits<base_functor>::retn_t retn_t; 00539 typedef typename func_traits<base_functor>::arg2_t arg1_t; 00540 typedef typename func_traits<base_functor>::arg3_t arg2_t; 00541 typedef typename func_traits<base_functor>::arg4_t arg3_t; 00542 typedef typename func_traits<base_functor>::arg5_t arg4_t; 00543 typedef typename func_traits<base_functor>::arg6_t arg5_t; 00544 typedef typename func_traits<base_functor>::arg7_t arg6_t; 00545 typedef typename func_traits<base_functor>::arg8_t arg7_t; 00546 typedef null_t arg8_t; 00547 }; 00548 00549 /// bound_first wraps another functor type with a fixed first argument. 00550 /** bound_first's can be constructed with the factory function 00551 bind_first(). */ 00552 00553 template <class base_functor, class bound_t> 00554 class bound_first 00555 : 00556 public func_traits<bound_first<base_functor, bound_t> > 00557 { 00558 private: 00559 base_functor m_held_func; 00560 bound_t m_bound; 00561 00562 public: 00563 bound_first(base_functor base, bound_t bound) : 00564 m_held_func(base), 00565 m_bound(bound) 00566 {} 00567 00568 bound_first(const bound_first& other) : 00569 m_held_func(other.m_held_func), 00570 m_bound(other.m_bound) 00571 {} 00572 00573 typedef func_traits<bound_first<base_functor, bound_t> > traits; 00574 typedef typename traits::retn_t retn_t; 00575 typedef typename traits::arg1_t arg1_t; 00576 typedef typename traits::arg2_t arg2_t; 00577 typedef typename traits::arg3_t arg3_t; 00578 typedef typename traits::arg4_t arg4_t; 00579 typedef typename traits::arg5_t arg5_t; 00580 typedef typename traits::arg6_t arg6_t; 00581 typedef typename traits::arg7_t arg7_t; 00582 typedef typename traits::arg8_t arg8_t; 00583 00584 // 00585 // All versions of operator() are provided, but only the one that 00586 // involves the correct call to m_held_func() will compile 00587 // successfully 00588 // 00589 00590 retn_t operator()() 00591 { 00592 return m_held_func(m_bound); 00593 } 00594 retn_t operator()(arg1_t p1) 00595 { 00596 return m_held_func(m_bound, p1); 00597 } 00598 retn_t operator()(arg1_t p1, arg2_t p2) 00599 { 00600 return m_held_func(m_bound, p1, p2); 00601 } 00602 retn_t operator()(arg1_t p1, arg2_t p2, arg3_t p3) 00603 { 00604 return m_held_func(m_bound, p1, p2, p3); 00605 } 00606 retn_t operator()(arg1_t p1, arg2_t p2, arg3_t p3, arg4_t p4) 00607 { 00608 return m_held_func(m_bound, p1, p2, p3, p4); 00609 } 00610 retn_t operator()(arg1_t p1, arg2_t p2, arg3_t p3, arg4_t p4, 00611 arg5_t p5) 00612 { 00613 return m_held_func(m_bound, p1, p2, p3, p4, p5); 00614 } 00615 retn_t operator()(arg1_t p1, arg2_t p2, arg3_t p3, arg4_t p4, 00616 arg5_t p5, arg6_t p6) 00617 { 00618 return m_held_func(m_bound, p1, p2, p3, p4, p5, p6); 00619 } 00620 retn_t operator()(arg1_t p1, arg2_t p2, arg3_t p3, arg4_t p4, 00621 arg5_t p5, arg6_t p6, arg7_t p7) 00622 { 00623 return m_held_func(m_bound, p1, p2, p3, p4, p5, p6, p7); 00624 } 00625 00626 private: 00627 bound_first& operator=(const bound_first&); 00628 }; 00629 00630 /// Factory function for creating bound_first functors. 00631 template <class base_functor, class bound_t> 00632 bound_first<base_functor, bound_t> bind_first(base_functor base, 00633 bound_t bound) 00634 { 00635 return bound_first<base_functor, bound_t>(base, bound); 00636 } 00637 00638 00639 // ####################################################### 00640 // ======================================================= 00641 00642 template <class base_functor, class bound_t> 00643 class bound_last; 00644 00645 /// func_traits specialization for bound_last. 00646 template <class base_functor, class bound_t> 00647 struct func_traits<bound_last<base_functor, bound_t> > 00648 { 00649 enum { num_args = (func_traits<base_functor>::num_args-1) }; 00650 00651 typedef typename func_traits<base_functor>::retn_t retn_t; 00652 typedef typename func_traits<base_functor>::arg1_t arg1_t; 00653 typedef typename func_traits<base_functor>::arg2_t arg2_t; 00654 typedef typename func_traits<base_functor>::arg3_t arg3_t; 00655 typedef typename func_traits<base_functor>::arg4_t arg4_t; 00656 typedef typename func_traits<base_functor>::arg5_t arg5_t; 00657 typedef typename func_traits<base_functor>::arg6_t arg6_t; 00658 typedef typename func_traits<base_functor>::arg7_t arg7_t; 00659 typedef typename func_traits<base_functor>::arg8_t arg8_t; 00660 }; 00661 00662 /// bound_last wraps another functor type with a fixed last argument. 00663 /** bound_last objects can be constructed with the factory function 00664 bind_last(). */ 00665 00666 template <class base_functor, class bound_t> 00667 class bound_last 00668 : 00669 public func_traits<bound_last<base_functor, bound_t> > 00670 { 00671 private: 00672 base_functor m_held_func; 00673 bound_t m_bound; 00674 00675 public: 00676 bound_last(base_functor base, bound_t bound) : 00677 m_held_func(base), 00678 m_bound(bound) 00679 {} 00680 00681 bound_last(const bound_last& other) : 00682 m_held_func(other.m_held_func), 00683 m_bound(other.m_bound) 00684 {} 00685 00686 typedef func_traits<bound_last<base_functor, bound_t> > traits; 00687 typedef typename traits::retn_t retn_t; 00688 typedef typename traits::arg1_t arg1_t; 00689 typedef typename traits::arg2_t arg2_t; 00690 typedef typename traits::arg3_t arg3_t; 00691 typedef typename traits::arg4_t arg4_t; 00692 typedef typename traits::arg5_t arg5_t; 00693 typedef typename traits::arg6_t arg6_t; 00694 typedef typename traits::arg7_t arg7_t; 00695 typedef typename traits::arg8_t arg8_t; 00696 00697 // 00698 // Multiple versions of operator() are provided, but only the one 00699 // that involves the correct call to m_held_func() will compile 00700 // successfully 00701 // 00702 00703 retn_t operator()() 00704 { 00705 return m_held_func(m_bound); 00706 } 00707 retn_t operator()(arg1_t p1) 00708 { 00709 return m_held_func(p1, m_bound); 00710 } 00711 retn_t operator()(arg1_t p1, arg2_t p2) 00712 { 00713 return m_held_func(p1, p2, m_bound); 00714 } 00715 retn_t operator()(arg1_t p1, arg2_t p2, arg3_t p3) 00716 { 00717 return m_held_func(p1, p2, p3, m_bound); 00718 } 00719 retn_t operator()(arg1_t p1, arg2_t p2, arg3_t p3, arg4_t p4) 00720 { 00721 return m_held_func(p1, p2, p3, p4, m_bound); 00722 } 00723 retn_t operator()(arg1_t p1, arg2_t p2, arg3_t p3, arg4_t p4, 00724 arg5_t p5) 00725 { 00726 return m_held_func(p1, p2, p3, p4, p5, m_bound); 00727 } 00728 retn_t operator()(arg1_t p1, arg2_t p2, arg3_t p3, arg4_t p4, 00729 arg5_t p5, arg6_t p6) 00730 { 00731 return m_held_func(p1, p2, p3, p4, p5, p6, m_bound); 00732 } 00733 retn_t operator()(arg1_t p1, arg2_t p2, arg3_t p3, arg4_t p4, 00734 arg5_t p5, arg6_t p6, arg7_t p7) 00735 { 00736 return m_held_func(p1, p2, p3, p4, p5, p6, p7, m_bound); 00737 } 00738 00739 private: 00740 bound_last& operator=(const bound_last&); 00741 }; 00742 00743 /// Factory function for creating bound_last functors. 00744 template <class base_functor, class bound_t> 00745 bound_last<base_functor, bound_t> bind_last(base_functor base, 00746 bound_t bound) 00747 { 00748 return bound_last<base_functor, bound_t>(base, bound); 00749 } 00750 00751 } // end namespace rutz 00752 00753 static const char __attribute__((used)) vcid_groovx_rutz_functors_h_utc20050626084020[] = "$Id: functors.h 8249 2007-04-12 06:03:40Z rjpeters $ $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/rutz/functors.h $"; 00754 #endif // !GROOVX_RUTZ_FUNCTORS_H_UTC20050626084020_DEFINED