![]() |
pl-nk v0.4.5
Plonk|Plink|Plank are a set of cross-platform C/C++ frameworks for audio software development
|
00001 /* 00002 ------------------------------------------------------------------------------- 00003 This file is part of the Plink, Plonk, Plank libraries 00004 by Martin Robinson 00005 00006 http://code.google.com/p/pl-nk/ 00007 00008 Copyright University of the West of England, Bristol 2011-14 00009 All rights reserved. 00010 00011 Redistribution and use in source and binary forms, with or without 00012 modification, are permitted provided that the following conditions are met: 00013 00014 * Redistributions of source code must retain the above copyright 00015 notice, this list of conditions and the following disclaimer. 00016 * Redistributions in binary form must reproduce the above copyright 00017 notice, this list of conditions and the following disclaimer in the 00018 documentation and/or other materials provided with the distribution. 00019 * Neither the name of University of the West of England, Bristol nor 00020 the names of its contributors may be used to endorse or promote products 00021 derived from this software without specific prior written permission. 00022 00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 00024 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00025 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00026 DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF THE WEST OF ENGLAND, BRISTOL BE 00027 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00028 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 00029 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00030 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00031 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 00032 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00033 00034 This software makes use of third party libraries. For more information see: 00035 doc/license.txt included in the distribution. 00036 ------------------------------------------------------------------------------- 00037 */ 00038 00039 #ifndef PLONK_FUNCTION_H 00040 #define PLONK_FUNCTION_H 00041 00042 #include "../core/plonk_CoreForwardDeclarations.h" 00043 #include "plonk_ContainerForwardDeclarations.h" 00044 00045 #include "../core/plonk_SmartPointer.h" 00046 #include "../core/plonk_WeakPointer.h" 00047 00048 00049 00050 //------------------------------------------------------------------------------ 00051 00052 class FunctionContainerBase : public PlonkBase 00053 { 00054 public: 00055 FunctionContainerBase() throw() { } 00056 virtual ~FunctionContainerBase() { } 00057 }; 00058 00059 //------------------------------------------------------------------------------ 00060 // Functions 00061 // 00062 00063 template<class ReturnType, 00064 class ArgType1, 00065 class ArgType2, 00066 class ArgType3> 00067 class FunctionContainer : public FunctionContainerBase 00068 { 00069 public: 00070 typedef ReturnType Return; 00071 typedef ArgType1 Arg1; 00072 typedef ArgType2 Arg2; 00073 typedef ArgType3 Arg3; 00074 typedef typename TypeUtility<ArgType1>::PassType Arg1PassType; 00075 typedef typename TypeUtility<ArgType2>::PassType Arg2PassType; 00076 typedef typename TypeUtility<ArgType3>::PassType Arg3PassType; 00077 typedef typename TypeUtility<ArgType1>::OriginalType Arg1OriginalType; 00078 typedef typename TypeUtility<ArgType2>::OriginalType Arg2OriginalType; 00079 typedef typename TypeUtility<ArgType3>::OriginalType Arg3OriginalType; 00080 00081 FunctionContainer (Arg1PassType argument1, 00082 Arg2PassType argument2, 00083 Arg3PassType argument3) throw() 00084 : value1 (argument1), 00085 value2 (argument2), 00086 value3 (argument3) 00087 { 00088 } 00089 00090 inline ReturnType operator()() throw() 00091 { 00092 return function (value1, value2, value3); 00093 } 00094 00095 virtual ReturnType function (Arg1PassType argument1, 00096 Arg1PassType argument2, 00097 Arg1PassType argument3) = 0; 00098 00099 static const int argumentCount; 00100 static const bool isProxy; 00101 00102 private: 00103 Arg1OriginalType value1; 00104 Arg2OriginalType value2; 00105 Arg3OriginalType value3; 00106 }; 00107 00108 template<class ReturnType, class ArgType1, class ArgType2, class ArgType3> 00109 const int FunctionContainer<ReturnType, ArgType1, ArgType2, ArgType3>::argumentCount = 3; 00110 00111 template<class ReturnType, class ArgType1, class ArgType2, class ArgType3> 00112 const bool FunctionContainer<ReturnType, ArgType1, ArgType2, ArgType3>::isProxy = false; 00113 00114 00115 //------------------------------------------------------------------------------ 00116 00117 template<class ReturnType> 00118 class FunctionContainer<ReturnType> : public FunctionContainerBase 00119 { 00120 public: 00121 typedef ReturnType Return; 00122 00123 FunctionContainer() throw() { } 00124 inline ReturnType operator()() throw() { return function(); } 00125 virtual ReturnType function() = 0; 00126 00127 static const int argumentCount; 00128 static const bool isProxy; 00129 }; 00130 00131 template<class ReturnType> 00132 const int FunctionContainer<ReturnType>::argumentCount = 0; 00133 00134 template<class ReturnType> 00135 const bool FunctionContainer<ReturnType>::isProxy = false; 00136 00137 00138 //------------------------------------------------------------------------------ 00139 00140 template<class ReturnType, class ArgType1> 00141 class FunctionContainer<ReturnType, ArgType1> : public FunctionContainerBase 00142 { 00143 public: 00144 typedef ReturnType Return; 00145 typedef ArgType1 Arg1; 00146 typedef typename TypeUtility<ArgType1>::PassType Arg1PassType; 00147 typedef typename TypeUtility<ArgType1>::OriginalType Arg1OriginalType; 00148 00149 FunctionContainer (Arg1PassType argument1) throw() 00150 : value1 (argument1) 00151 { 00152 } 00153 00154 inline ReturnType operator()() throw() 00155 { 00156 return function (value1); 00157 } 00158 00159 virtual ReturnType function (Arg1PassType argument1) = 0; 00160 00161 static const int argumentCount; 00162 static const bool isProxy; 00163 00164 private: 00165 Arg1OriginalType value1; 00166 }; 00167 00168 template<class ReturnType, class ArgType1> 00169 const int FunctionContainer<ReturnType, ArgType1>::argumentCount = 1; 00170 00171 template<class ReturnType, class ArgType1> 00172 const bool FunctionContainer<ReturnType, ArgType1>::isProxy = false; 00173 00174 //------------------------------------------------------------------------------ 00175 00176 template<class ReturnType, class ArgType1, class ArgType2> 00177 class FunctionContainer<ReturnType, ArgType1, ArgType2> : public FunctionContainerBase 00178 { 00179 public: 00180 typedef ReturnType Return; 00181 typedef ArgType1 Arg1; 00182 typedef ArgType2 Arg2; 00183 typedef typename TypeUtility<ArgType1>::PassType Arg1PassType; 00184 typedef typename TypeUtility<ArgType2>::PassType Arg2PassType; 00185 typedef typename TypeUtility<ArgType1>::OriginalType Arg1OriginalType; 00186 typedef typename TypeUtility<ArgType2>::OriginalType Arg2OriginalType; 00187 00188 FunctionContainer (Arg1PassType argument1, 00189 Arg2PassType argument2) throw() 00190 : value1 (argument1), 00191 value2 (argument2) 00192 { 00193 } 00194 00195 inline ReturnType operator()() throw() 00196 { 00197 return function (value1, value2); 00198 } 00199 00200 virtual ReturnType function (Arg1PassType argument1, 00201 Arg2PassType argument2) = 0; 00202 00203 static const int argumentCount; 00204 static const bool isProxy; 00205 00206 private: 00207 Arg1OriginalType value1; 00208 Arg2OriginalType value2; 00209 }; 00210 00211 template<class ReturnType, class ArgType1, class ArgType2> 00212 const int FunctionContainer<ReturnType, ArgType1, ArgType2>::argumentCount = 2; 00213 00214 template<class ReturnType, class ArgType1, class ArgType2> 00215 const bool FunctionContainer<ReturnType, ArgType1, ArgType2>::isProxy = false; 00216 00217 00218 //------------------------------------------------------------------------------ 00219 // Function proxies 00220 // 00221 00222 template<class ReturnType, 00223 class ArgType1, 00224 class ArgType2, 00225 class ArgType3> 00226 class FunctionContainerProxy 00227 { 00228 public: 00229 typedef ReturnType Return; 00230 typedef ArgType1 Arg1; 00231 typedef ArgType2 Arg2; 00232 typedef ArgType3 Arg3; 00233 typedef typename TypeUtility<ArgType1>::PassType Arg1PassType; 00234 typedef typename TypeUtility<ArgType2>::PassType Arg2PassType; 00235 typedef typename TypeUtility<ArgType3>::PassType Arg3PassType; 00236 typedef typename TypeUtility<ArgType1>::OriginalType Arg1OriginalType; 00237 typedef typename TypeUtility<ArgType2>::OriginalType Arg2OriginalType; 00238 typedef typename TypeUtility<ArgType3>::OriginalType Arg3OriginalType; 00239 typedef ReturnType (*ProxyFunction) (Arg1PassType, Arg2PassType, Arg3PassType); 00240 00241 FunctionContainerProxy (ProxyFunction proxyFunction, 00242 Arg1PassType argument1, 00243 Arg2PassType argument2, 00244 Arg3PassType argument3) throw() 00245 : function (proxyFunction), 00246 value1 (argument1), 00247 value2 (argument2), 00248 value3 (argument3) 00249 { 00250 } 00251 00252 inline ReturnType operator()() throw() 00253 { 00254 return function (value1, value2, value3); 00255 } 00256 00257 static const int argumentCount; 00258 static const bool isProxy; 00259 00260 private: 00261 ProxyFunction function; 00262 Arg1OriginalType value1; 00263 Arg2OriginalType value2; 00264 Arg3OriginalType value3; 00265 }; 00266 00267 template<class ReturnType, class ArgType1, class ArgType2, class ArgType3> 00268 const int FunctionContainerProxy<ReturnType, ArgType1, ArgType2, ArgType3>::argumentCount = 3; 00269 00270 template<class ReturnType, class ArgType1, class ArgType2, class ArgType3> 00271 const bool FunctionContainerProxy<ReturnType, ArgType1, ArgType2, ArgType3>::isProxy = true; 00272 00273 //------------------------------------------------------------------------------ 00274 00275 template<class ReturnType> 00276 class FunctionContainerProxy<ReturnType> 00277 { 00278 public: 00279 typedef ReturnType (*ProxyFunction) (void); 00280 typedef ReturnType Return; 00281 00282 FunctionContainerProxy (ProxyFunction proxyFunction) throw() 00283 : function (proxyFunction) 00284 { 00285 } 00286 00287 inline ReturnType operator()() throw() { return function(); } 00288 00289 static const int argumentCount; 00290 static const bool isProxy; 00291 00292 private: 00293 ProxyFunction function; 00294 }; 00295 00296 template<class ReturnType> 00297 const int FunctionContainerProxy<ReturnType>::argumentCount = 0; 00298 00299 template<class ReturnType> 00300 const bool FunctionContainerProxy<ReturnType>::isProxy = true; 00301 00302 00303 //------------------------------------------------------------------------------ 00304 00305 template<class ReturnType, class ArgType1> 00306 class FunctionContainerProxy<ReturnType, ArgType1> 00307 { 00308 public: 00309 typedef ReturnType Return; 00310 typedef ArgType1 Arg1; 00311 typedef typename TypeUtility<ArgType1>::PassType Arg1PassType; 00312 typedef typename TypeUtility<ArgType1>::OriginalType Arg1OriginalType; 00313 typedef ReturnType (*ProxyFunction) (Arg1PassType); 00314 00315 FunctionContainerProxy (ProxyFunction proxyFunction, 00316 Arg1PassType argument1) throw() 00317 : function (proxyFunction), 00318 value1 (argument1) 00319 { 00320 } 00321 00322 inline ReturnType operator()() throw() 00323 { 00324 return function (value1); 00325 } 00326 00327 static const int argumentCount; 00328 static const bool isProxy; 00329 00330 private: 00331 ProxyFunction function; 00332 Arg1OriginalType value1; 00333 }; 00334 00335 template<class ReturnType, class ArgType1> 00336 const int FunctionContainerProxy<ReturnType, ArgType1>::argumentCount = 1; 00337 00338 template<class ReturnType, class ArgType1> 00339 const bool FunctionContainerProxy<ReturnType, ArgType1>::isProxy = true; 00340 00341 //------------------------------------------------------------------------------ 00342 00343 template<class ReturnType, class ArgType1, class ArgType2> 00344 class FunctionContainerProxy<ReturnType, ArgType1, ArgType2> 00345 { 00346 public: 00347 typedef ReturnType Return; 00348 typedef ArgType1 Arg1; 00349 typedef ArgType2 Arg2; 00350 typedef typename TypeUtility<ArgType1>::PassType Arg1PassType; 00351 typedef typename TypeUtility<ArgType2>::PassType Arg2PassType; 00352 typedef typename TypeUtility<ArgType1>::OriginalType Arg1OriginalType; 00353 typedef typename TypeUtility<ArgType2>::OriginalType Arg2OriginalType; 00354 typedef ReturnType (*ProxyFunction) (Arg1PassType, Arg2PassType); 00355 00356 FunctionContainerProxy (ProxyFunction proxyFunction, 00357 Arg1PassType argument1, 00358 Arg2PassType argument2) throw() 00359 : function (proxyFunction), 00360 value1 (argument1), 00361 value2 (argument2) 00362 { 00363 } 00364 00365 inline ReturnType operator()() throw() 00366 { 00367 return function (value1, value2); 00368 } 00369 00370 static const int argumentCount; 00371 static const bool isProxy; 00372 00373 private: 00374 ProxyFunction function; 00375 Arg1OriginalType value1; 00376 Arg2OriginalType value2; 00377 }; 00378 00379 template<class ReturnType, class ArgType1, class ArgType2> 00380 const int FunctionContainerProxy<ReturnType, ArgType1, ArgType2>::argumentCount = 2; 00381 00382 template<class ReturnType, class ArgType1, class ArgType2> 00383 const bool FunctionContainerProxy<ReturnType, ArgType1, ArgType2>::isProxy = true; 00384 00385 //------------------------------------------------------------------------------ 00386 // FunctionCallerInternals 00387 // 00388 00389 template<class FunctionType, 00390 class ReturnType, 00391 class ArgType1, 00392 class ArgType2, 00393 class ArgType3> 00394 class FunctionCallerInternal 00395 : public SmartPointer 00396 { 00397 public: 00398 typedef typename TypeUtility<ArgType1>::PassType Arg1PassType; 00399 typedef typename TypeUtility<ArgType2>::PassType Arg2PassType; 00400 typedef typename TypeUtility<ArgType3>::PassType Arg3PassType; 00401 00402 FunctionCallerInternal (Arg1PassType argument1, 00403 Arg2PassType argument2, 00404 Arg3PassType argument3) throw() 00405 : function (argument1, argument2, argument3) 00406 { 00407 } 00408 00409 inline ReturnType call() throw() 00410 { 00411 return function(); 00412 } 00413 00414 private: 00415 FunctionType function; 00416 }; 00417 00418 template<class FunctionType, class ReturnType> 00419 class FunctionCallerInternal<FunctionType, ReturnType> 00420 : public SmartPointer 00421 { 00422 public: 00423 FunctionCallerInternal() throw() 00424 { 00425 } 00426 00427 inline ReturnType call() throw() 00428 { 00429 return function(); 00430 } 00431 00432 private: 00433 FunctionType function; 00434 }; 00435 00436 template<class FunctionType, class ReturnType, class ArgType1> 00437 class FunctionCallerInternal<FunctionType, ReturnType, ArgType1> 00438 : public SmartPointer 00439 { 00440 public: 00441 typedef typename TypeUtility<ArgType1>::PassType Arg1PassType; 00442 00443 FunctionCallerInternal (Arg1PassType argument1) throw() 00444 : function (argument1) 00445 { 00446 } 00447 00448 inline ReturnType call() throw() 00449 { 00450 return function(); 00451 } 00452 00453 private: 00454 FunctionType function; 00455 }; 00456 00457 template<class FunctionType, 00458 class ReturnType, 00459 class ArgType1, 00460 class ArgType2> 00461 class FunctionCallerInternal<FunctionType, ReturnType, ArgType1, ArgType2> 00462 : public SmartPointer 00463 { 00464 public: 00465 typedef typename TypeUtility<ArgType1>::PassType Arg1PassType; 00466 typedef typename TypeUtility<ArgType2>::PassType Arg2PassType; 00467 00468 FunctionCallerInternal (Arg1PassType argument1, 00469 Arg2PassType argument2) throw() 00470 : function (argument1, argument2) 00471 { 00472 } 00473 00474 inline ReturnType call() throw() 00475 { 00476 return function(); 00477 } 00478 00479 private: 00480 FunctionType function; 00481 }; 00482 00483 //------------------------------------------------------------------------------ 00484 // FunctionProxyCallerInternals 00485 // 00486 00487 template<class FunctionType, 00488 class ReturnType, 00489 class ArgType1, 00490 class ArgType2, 00491 class ArgType3> 00492 class FunctionProxyCallerInternal 00493 : public SmartPointer 00494 { 00495 public: 00496 typedef typename TypeUtility<ArgType1>::PassType Arg1PassType; 00497 typedef typename TypeUtility<ArgType2>::PassType Arg2PassType; 00498 typedef typename TypeUtility<ArgType3>::PassType Arg3PassType; 00499 typedef ReturnType (*ProxyFunction) (Arg1PassType, Arg2PassType, Arg3PassType); 00500 00501 FunctionProxyCallerInternal (ProxyFunction proxyFunction, 00502 Arg1PassType argument1, 00503 Arg2PassType argument2, 00504 Arg3PassType argument3) throw() 00505 : function (proxyFunction, argument1, argument2, argument3) 00506 { 00507 } 00508 00509 inline ReturnType call() throw() 00510 { 00511 return function(); 00512 } 00513 00514 private: 00515 FunctionType function; 00516 }; 00517 00518 template<class FunctionType, class ReturnType> 00519 class FunctionProxyCallerInternal<FunctionType, ReturnType> 00520 : public SmartPointer 00521 { 00522 public: 00523 typedef ReturnType (*ProxyFunction) (void); 00524 00525 FunctionProxyCallerInternal (ProxyFunction proxyFunction) throw() 00526 : function (proxyFunction) 00527 { 00528 } 00529 00530 inline ReturnType call() throw() 00531 { 00532 return function(); 00533 } 00534 00535 private: 00536 FunctionType function; 00537 }; 00538 00539 template<class FunctionType, class ReturnType, class ArgType1> 00540 class FunctionProxyCallerInternal<FunctionType, ReturnType, ArgType1> 00541 : public SmartPointer 00542 { 00543 public: 00544 typedef typename TypeUtility<ArgType1>::PassType Arg1PassType; 00545 typedef ReturnType (*ProxyFunction) (Arg1PassType); 00546 00547 FunctionProxyCallerInternal (ProxyFunction proxyFunction, 00548 Arg1PassType argument1) throw() 00549 : function (proxyFunction, argument1) 00550 { 00551 } 00552 00553 inline ReturnType call() throw() 00554 { 00555 return function(); 00556 } 00557 00558 private: 00559 FunctionType function; 00560 }; 00561 00562 template<class FunctionType, 00563 class ReturnType, 00564 class ArgType1, 00565 class ArgType2> 00566 class FunctionProxyCallerInternal<FunctionType, ReturnType, ArgType1, ArgType2> 00567 : public SmartPointer 00568 { 00569 public: 00570 typedef typename TypeUtility<ArgType1>::PassType Arg1PassType; 00571 typedef typename TypeUtility<ArgType2>::PassType Arg2PassType; 00572 typedef ReturnType (*ProxyFunction) (Arg1PassType, Arg2PassType); 00573 00574 FunctionProxyCallerInternal (ProxyFunction proxyFunction, 00575 Arg1PassType argument1, 00576 Arg2PassType argument2) throw() 00577 : function (proxyFunction, argument1, argument2) 00578 { 00579 } 00580 00581 inline ReturnType call() throw() 00582 { 00583 return function(); 00584 } 00585 00586 private: 00587 FunctionType function; 00588 }; 00589 00590 //------------------------------------------------------------------------------ 00591 // FunctionCallerBases 00592 // 00593 00594 template<class FunctionType, 00595 class ReturnType, 00596 class ArgType1, 00597 class ArgType2, 00598 class ArgType3> 00599 class FunctionCallerBase 00600 : public SmartPointerContainer<FunctionCallerInternal<FunctionType, 00601 ReturnType, 00602 ArgType1, 00603 ArgType2, 00604 ArgType3> > 00605 { 00606 public: 00607 typedef FunctionCallerInternal<FunctionType, 00608 ReturnType, 00609 ArgType1, 00610 ArgType2, 00611 ArgType3> Internal; 00612 typedef SmartPointerContainer<Internal> Base; 00613 typedef typename TypeUtility<ArgType1>::PassType Arg1PassType; 00614 typedef typename TypeUtility<ArgType2>::PassType Arg2PassType; 00615 typedef typename TypeUtility<ArgType3>::PassType Arg3PassType; 00616 00617 FunctionCallerBase (Arg1PassType argument1, 00618 Arg2PassType argument2, 00619 Arg3PassType argument3) throw() 00620 : Base (new Internal (argument1, argument2, argument3)) 00621 { 00622 } 00623 00624 inline ReturnType operator()() throw() 00625 { 00626 return this->getInternal()->call(); 00627 } 00628 }; 00629 00630 template<class FunctionType, class ReturnType> 00631 class FunctionCallerBase<FunctionType, ReturnType> 00632 : public SmartPointerContainer<FunctionCallerInternal<FunctionType, 00633 ReturnType> > 00634 { 00635 public: 00636 typedef FunctionCallerInternal<FunctionType, ReturnType> Internal; 00637 typedef SmartPointerContainer<Internal> Base; 00638 00639 FunctionCallerBase() throw() 00640 : Base (new Internal()) 00641 { 00642 } 00643 00644 inline ReturnType operator()() throw() 00645 { 00646 return this->getInternal()->call(); 00647 } 00648 }; 00649 00650 template<class FunctionType, class ReturnType, class ArgType1> 00651 class FunctionCallerBase<FunctionType, ReturnType, ArgType1> 00652 : public SmartPointerContainer<FunctionCallerInternal<FunctionType, 00653 ReturnType, 00654 ArgType1> > 00655 { 00656 public: 00657 typedef FunctionCallerInternal<FunctionType, 00658 ReturnType, 00659 ArgType1> Internal; 00660 typedef SmartPointerContainer<Internal> Base; 00661 typedef typename TypeUtility<ArgType1>::PassType Arg1PassType; 00662 00663 FunctionCallerBase (Arg1PassType argument1) throw() 00664 : Base (new Internal (argument1)) 00665 { 00666 } 00667 00668 inline ReturnType operator()() throw() 00669 { 00670 return this->getInternal()->call(); 00671 } 00672 }; 00673 00674 template<class FunctionType, 00675 class ReturnType, 00676 class ArgType1, 00677 class ArgType2> 00678 class FunctionCallerBase<FunctionType, ReturnType, ArgType1, ArgType2> 00679 : public SmartPointerContainer<FunctionCallerInternal<FunctionType, 00680 ReturnType, 00681 ArgType1, 00682 ArgType2> > 00683 { 00684 public: 00685 typedef FunctionCallerInternal<FunctionType, 00686 ReturnType, 00687 ArgType1, 00688 ArgType2> Internal; 00689 typedef SmartPointerContainer<Internal> Base; 00690 typedef typename TypeUtility<ArgType1>::PassType Arg1PassType; 00691 typedef typename TypeUtility<ArgType2>::PassType Arg2PassType; 00692 00693 FunctionCallerBase (Arg1PassType argument1, 00694 Arg2PassType argument2) throw() 00695 : Base (new Internal (argument1, argument2)) 00696 { 00697 } 00698 00699 inline ReturnType operator()() throw() 00700 { 00701 return this->getInternal()->call(); 00702 } 00703 }; 00704 00705 //------------------------------------------------------------------------------ 00706 // FunctionProxyCallerBases 00707 // 00708 00709 template<class FunctionType, 00710 class ReturnType, 00711 class ArgType1, 00712 class ArgType2, 00713 class ArgType3> 00714 class FunctionProxyCallerBase 00715 : public SmartPointerContainer<FunctionProxyCallerInternal<FunctionType, 00716 ReturnType, 00717 ArgType1, 00718 ArgType2, 00719 ArgType3> > 00720 { 00721 public: 00722 typedef FunctionProxyCallerInternal<FunctionType, 00723 ReturnType, 00724 ArgType1, 00725 ArgType2, 00726 ArgType3> Internal; 00727 typedef SmartPointerContainer<Internal> Base; 00728 typedef typename TypeUtility<ArgType1>::PassType Arg1PassType; 00729 typedef typename TypeUtility<ArgType2>::PassType Arg2PassType; 00730 typedef typename TypeUtility<ArgType3>::PassType Arg3PassType; 00731 typedef ReturnType (*ProxyFunction) (Arg1PassType, Arg2PassType, Arg3PassType); 00732 00733 FunctionProxyCallerBase (ProxyFunction proxyFunction, 00734 Arg1PassType argument1, 00735 Arg2PassType argument2, 00736 Arg3PassType argument3) throw() 00737 : Base (new Internal (proxyFunction, argument1, argument2, argument3)) 00738 { 00739 } 00740 00741 inline ReturnType operator()() throw() 00742 { 00743 return this->getInternal()->call(); 00744 } 00745 }; 00746 00747 template<class FunctionType, class ReturnType> 00748 class FunctionProxyCallerBase<FunctionType, ReturnType> 00749 : public SmartPointerContainer<FunctionProxyCallerInternal<FunctionType, 00750 ReturnType> > 00751 { 00752 public: 00753 typedef ReturnType (*ProxyFunction) (void); 00754 typedef FunctionProxyCallerInternal<FunctionType, ReturnType> Internal; 00755 typedef SmartPointerContainer<Internal> Base; 00756 00757 FunctionProxyCallerBase (ProxyFunction proxyFunction) throw() 00758 : Base (new Internal (proxyFunction)) 00759 { 00760 } 00761 00762 inline ReturnType operator()() throw() 00763 { 00764 return this->getInternal()->call(); 00765 } 00766 }; 00767 00768 template<class FunctionType, class ReturnType, class ArgType1> 00769 class FunctionProxyCallerBase<FunctionType, ReturnType, ArgType1> 00770 : public SmartPointerContainer<FunctionProxyCallerInternal<FunctionType, 00771 ReturnType, 00772 ArgType1> > 00773 { 00774 public: 00775 typedef typename TypeUtility<ArgType1>::PassType Arg1PassType; 00776 typedef ReturnType (*ProxyFunction) (Arg1PassType); 00777 typedef FunctionProxyCallerInternal<FunctionType, 00778 ReturnType, 00779 ArgType1> Internal; 00780 typedef SmartPointerContainer<Internal> Base; 00781 00782 FunctionProxyCallerBase (ProxyFunction proxyFunction, 00783 Arg1PassType argument1) throw() 00784 : Base (new Internal (proxyFunction, argument1)) 00785 { 00786 } 00787 00788 inline ReturnType operator()() throw() 00789 { 00790 return this->getInternal()->call(); 00791 } 00792 }; 00793 00794 template<class FunctionType, 00795 class ReturnType, 00796 class ArgType1, 00797 class ArgType2> 00798 class FunctionProxyCallerBase<FunctionType, ReturnType, ArgType1, ArgType2> 00799 : public SmartPointerContainer<FunctionProxyCallerInternal<FunctionType, 00800 ReturnType, 00801 ArgType1, 00802 ArgType2> > 00803 { 00804 public: 00805 typedef typename TypeUtility<ArgType1>::PassType Arg1PassType; 00806 typedef typename TypeUtility<ArgType2>::PassType Arg2PassType; 00807 typedef ReturnType (*ProxyFunction) (Arg1PassType, Arg2PassType); 00808 typedef FunctionProxyCallerInternal<FunctionType, 00809 ReturnType, 00810 ArgType1, 00811 ArgType2> Internal; 00812 typedef SmartPointerContainer<Internal> Base; 00813 00814 FunctionProxyCallerBase (ProxyFunction proxyFunction, 00815 Arg1PassType argument1, 00816 Arg2PassType argument2) throw() 00817 : Base (new Internal (proxyFunction, argument1, argument2)) 00818 { 00819 } 00820 00821 inline ReturnType operator()() throw() 00822 { 00823 return this->getInternal()->call(); 00824 } 00825 }; 00826 00827 //------------------------------------------------------------------------------ 00828 00829 template<class FunctionType, int argumentCount, bool isProxy> 00830 class FunctionCaller 00831 { 00832 }; 00833 00834 //------------------------------------------------------------------------------ 00835 00836 template<class FunctionType> 00837 class FunctionCaller<FunctionType, 0, false> 00838 : public FunctionCallerBase<FunctionType, typename FunctionType::Return> 00839 { 00840 public: 00841 typedef typename FunctionType::Return ReturnType; 00842 typedef FunctionCallerBase<FunctionType, ReturnType> Base; 00843 00844 FunctionCaller() throw() 00845 { 00846 } 00847 }; 00848 00849 00850 template<class FunctionType> 00851 class FunctionCaller<FunctionType, 1, false> 00852 : public FunctionCallerBase<FunctionType, 00853 typename FunctionType::Return, 00854 typename FunctionType::Arg1> 00855 { 00856 public: 00857 typedef typename FunctionType::Return ReturnType; 00858 typedef typename FunctionType::Arg1 ArgType1; 00859 typedef typename TypeUtility<ArgType1>::PassType Arg1PassType; 00860 00861 typedef FunctionCallerBase<FunctionType, 00862 ReturnType, 00863 ArgType1> Base; 00864 00865 FunctionCaller (Arg1PassType argument1) throw() 00866 : Base (argument1) 00867 { 00868 } 00869 }; 00870 00871 template<class FunctionType> 00872 class FunctionCaller<FunctionType, 2, false> 00873 : public FunctionCallerBase<FunctionType, 00874 typename FunctionType::Return, 00875 typename FunctionType::Arg1, 00876 typename FunctionType::Arg2> 00877 { 00878 public: 00879 typedef typename FunctionType::Return ReturnType; 00880 typedef typename FunctionType::Arg1 ArgType1; 00881 typedef typename FunctionType::Arg2 ArgType2; 00882 typedef typename TypeUtility<ArgType1>::PassType Arg1PassType; 00883 typedef typename TypeUtility<ArgType2>::PassType Arg2PassType; 00884 00885 typedef FunctionCallerBase<FunctionType, 00886 ReturnType, 00887 ArgType1, 00888 ArgType2> Base; 00889 00890 FunctionCaller (Arg1PassType argument1, 00891 Arg2PassType argument2) throw() 00892 : Base (argument1, argument2) 00893 { 00894 } 00895 }; 00896 00897 template<class FunctionType> 00898 class FunctionCaller<FunctionType, 3, false> 00899 : public FunctionCallerBase<FunctionType, 00900 typename FunctionType::Return, 00901 typename FunctionType::Arg1, 00902 typename FunctionType::Arg2, 00903 typename FunctionType::Arg3> 00904 { 00905 public: 00906 typedef typename FunctionType::Return ReturnType; 00907 typedef typename FunctionType::Arg1 ArgType1; 00908 typedef typename FunctionType::Arg2 ArgType2; 00909 typedef typename FunctionType::Arg3 ArgType3; 00910 typedef typename TypeUtility<ArgType1>::PassType Arg1PassType; 00911 typedef typename TypeUtility<ArgType2>::PassType Arg2PassType; 00912 typedef typename TypeUtility<ArgType3>::PassType Arg3PassType; 00913 00914 typedef FunctionCallerBase<FunctionType, 00915 ReturnType, 00916 ArgType1, 00917 ArgType2, 00918 ArgType3> Base; 00919 00920 FunctionCaller (Arg1PassType argument1, 00921 Arg2PassType argument2, 00922 Arg3PassType argument3) throw() 00923 : Base (argument1, argument2, argument3) 00924 { 00925 } 00926 }; 00927 00928 //------------------------------------------------------------------------------ 00929 00930 template<class FunctionType> 00931 class FunctionCaller<FunctionType, 0, true> 00932 : public FunctionProxyCallerBase<FunctionType, typename FunctionType::Return> 00933 { 00934 public: 00935 typedef typename FunctionType::Return ReturnType; 00936 typedef ReturnType (*ProxyFunction) (void); 00937 typedef FunctionProxyCallerBase<FunctionType, ReturnType> Base; 00938 00939 FunctionCaller (ProxyFunction proxyFunction) throw() 00940 : Base (proxyFunction) 00941 { 00942 } 00943 }; 00944 00945 00946 template<class FunctionType> 00947 class FunctionCaller<FunctionType, 1, true> 00948 : public FunctionProxyCallerBase<FunctionType, 00949 typename FunctionType::Return, 00950 typename FunctionType::Arg1> 00951 { 00952 public: 00953 typedef typename FunctionType::Return ReturnType; 00954 typedef typename FunctionType::Arg1 ArgType1; 00955 typedef typename TypeUtility<ArgType1>::PassType Arg1PassType; 00956 00957 typedef ReturnType (*ProxyFunction) (Arg1PassType); 00958 00959 typedef FunctionProxyCallerBase<FunctionType, 00960 ReturnType, 00961 ArgType1> Base; 00962 00963 FunctionCaller (ProxyFunction proxyFunction, 00964 Arg1PassType argument1) throw() 00965 : Base (proxyFunction, argument1) 00966 { 00967 } 00968 }; 00969 00970 template<class FunctionType> 00971 class FunctionCaller<FunctionType, 2, true> 00972 : public FunctionProxyCallerBase<FunctionType, 00973 typename FunctionType::Return, 00974 typename FunctionType::Arg1, 00975 typename FunctionType::Arg2> 00976 { 00977 public: 00978 typedef typename FunctionType::Return ReturnType; 00979 typedef typename FunctionType::Arg1 ArgType1; 00980 typedef typename FunctionType::Arg2 ArgType2; 00981 typedef typename TypeUtility<ArgType1>::PassType Arg1PassType; 00982 typedef typename TypeUtility<ArgType2>::PassType Arg2PassType; 00983 00984 typedef ReturnType (*ProxyFunction) (Arg1PassType, Arg2PassType); 00985 00986 typedef FunctionProxyCallerBase<FunctionType, 00987 ReturnType, 00988 ArgType1, 00989 ArgType2> Base; 00990 00991 FunctionCaller (ProxyFunction proxyFunction, 00992 Arg1PassType argument1, 00993 Arg2PassType argument2) throw() 00994 : Base (proxyFunction, argument1, argument2) 00995 { 00996 } 00997 }; 00998 00999 template<class FunctionType> 01000 class FunctionCaller<FunctionType, 3, true> 01001 : public FunctionProxyCallerBase<FunctionType, 01002 typename FunctionType::Return, 01003 typename FunctionType::Arg1, 01004 typename FunctionType::Arg2, 01005 typename FunctionType::Arg3> 01006 { 01007 public: 01008 typedef typename FunctionType::Return ReturnType; 01009 typedef typename FunctionType::Arg1 ArgType1; 01010 typedef typename FunctionType::Arg2 ArgType2; 01011 typedef typename FunctionType::Arg3 ArgType3; 01012 typedef typename TypeUtility<ArgType1>::PassType Arg1PassType; 01013 typedef typename TypeUtility<ArgType2>::PassType Arg2PassType; 01014 typedef typename TypeUtility<ArgType3>::PassType Arg3PassType; 01015 01016 typedef ReturnType (*ProxyFunction) (Arg1PassType, Arg2PassType, Arg3PassType); 01017 01018 typedef FunctionProxyCallerBase<FunctionType, 01019 ReturnType, 01020 ArgType1, 01021 ArgType2, 01022 ArgType3> Base; 01023 01024 FunctionCaller (ProxyFunction proxyFunction, 01025 Arg1PassType argument1, 01026 Arg2PassType argument2, 01027 Arg3PassType argument3) throw() 01028 : Base (proxyFunction, argument1, argument2, argument3) 01029 { 01030 } 01031 }; 01032 01033 01034 class Function 01035 { 01036 public: 01037 01038 template<class ReturnType, class Arg1CallType> 01039 static inline FunctionCaller<FunctionContainer<ReturnType>, 0, false> 01040 create() throw() 01041 { 01042 typedef FunctionCaller<FunctionContainer<ReturnType>, 1, false> FunctionCallerType; 01043 return FunctionCallerType(); 01044 } 01045 01046 template<class ReturnType, class Arg1CallType> 01047 static inline FunctionCaller<FunctionContainer<ReturnType, 01048 typename TypeUtility<Arg1CallType>::OriginalType>, 1, false> 01049 create (Arg1CallType argument1) throw() 01050 { 01051 typedef typename TypeUtility<Arg1CallType>::OriginalType ArgType1; 01052 01053 typedef FunctionCaller<FunctionContainer<ReturnType, ArgType1>, 1, false> FunctionCallerType; 01054 return FunctionCallerType (argument1); 01055 } 01056 01057 template<class ReturnType, class Arg1CallType, class Arg2CallType> 01058 static inline FunctionCaller<FunctionContainer<ReturnType, 01059 typename TypeUtility<Arg1CallType>::OriginalType, 01060 typename TypeUtility<Arg2CallType>::OriginalType>, 2, false> 01061 create (Arg1CallType argument1, Arg2CallType argument2) throw() 01062 { 01063 typedef typename TypeUtility<Arg1CallType>::OriginalType ArgType1; 01064 typedef typename TypeUtility<Arg2CallType>::OriginalType ArgType2; 01065 01066 typedef FunctionCaller<FunctionContainer<ReturnType, ArgType1, ArgType2>, 2, false> FunctionCallerType; 01067 return FunctionCallerType (argument1, argument2); 01068 } 01069 01070 template<class ReturnType, class Arg1CallType, class Arg2CallType, class Arg3CallType> 01071 static inline FunctionCaller<FunctionContainer<ReturnType, 01072 typename TypeUtility<Arg1CallType>::OriginalType, 01073 typename TypeUtility<Arg2CallType>::OriginalType, 01074 typename TypeUtility<Arg3CallType>::OriginalType>, 3, false> 01075 create (Arg1CallType argument1, Arg2CallType argument2, Arg3CallType argument3) throw() 01076 { 01077 typedef typename TypeUtility<Arg1CallType>::OriginalType ArgType1; 01078 typedef typename TypeUtility<Arg2CallType>::OriginalType ArgType2; 01079 typedef typename TypeUtility<Arg3CallType>::OriginalType ArgType3; 01080 01081 typedef FunctionCaller<FunctionContainer<ReturnType, ArgType1, ArgType2, ArgType3>, 3, false> FunctionCallerType; 01082 return FunctionCallerType (argument1, argument2, argument3); 01083 } 01084 01085 template<class ReturnType> 01086 static inline FunctionCaller<FunctionContainerProxy<ReturnType>, 0, true> 01087 create (ReturnType (*proxyFunction) (void)) throw() 01088 { 01089 typedef FunctionCaller<FunctionContainerProxy<ReturnType>, 0, true> FunctionCallerType; 01090 return FunctionCallerType (proxyFunction); 01091 } 01092 01093 template<class ReturnType, class Arg1CallType> 01094 static inline FunctionCaller<FunctionContainerProxy<ReturnType, 01095 typename TypeUtility<Arg1CallType>::OriginalType>, 1, true> 01096 create (ReturnType (*proxyFunction) (typename TypeUtility<Arg1CallType>::PassType), 01097 Arg1CallType argument1) throw() 01098 { 01099 typedef typename TypeUtility<Arg1CallType>::OriginalType ArgType1; 01100 typedef FunctionCaller<FunctionContainerProxy<ReturnType, ArgType1>, 1, true> FunctionCallerType; 01101 return FunctionCallerType (proxyFunction, argument1); 01102 } 01103 01104 template<class ReturnType, class Arg1CallType, class Arg2CallType> 01105 static inline FunctionCaller<FunctionContainerProxy<ReturnType, 01106 typename TypeUtility<Arg1CallType>::OriginalType, 01107 typename TypeUtility<Arg2CallType>::OriginalType>, 2, true> 01108 create (ReturnType (*proxyFunction) (typename TypeUtility<Arg1CallType>::PassType, 01109 typename TypeUtility<Arg2CallType>::PassType), 01110 Arg1CallType argument1, Arg2CallType argument2) throw() 01111 { 01112 typedef typename TypeUtility<Arg1CallType>::OriginalType ArgType1; 01113 typedef typename TypeUtility<Arg2CallType>::OriginalType ArgType2; 01114 01115 typedef FunctionCaller<FunctionContainerProxy<ReturnType, ArgType1, ArgType2>, 2, true> FunctionCallerType; 01116 return FunctionCallerType (proxyFunction, argument1, argument2); 01117 } 01118 01119 template<class ReturnType, class Arg1CallType, class Arg2CallType, class Arg3CallType> 01120 static inline FunctionCaller<FunctionContainerProxy<ReturnType, 01121 typename TypeUtility<Arg1CallType>::OriginalType, 01122 typename TypeUtility<Arg2CallType>::OriginalType, 01123 typename TypeUtility<Arg3CallType>::OriginalType>, 3, true> 01124 create (ReturnType (*proxyFunction) (typename TypeUtility<Arg1CallType>::PassType, 01125 typename TypeUtility<Arg2CallType>::PassType, 01126 typename TypeUtility<Arg3CallType>::PassType), 01127 Arg1CallType argument1, Arg2CallType argument2, Arg3CallType argument3) throw() 01128 { 01129 typedef typename TypeUtility<Arg1CallType>::OriginalType ArgType1; 01130 typedef typename TypeUtility<Arg2CallType>::OriginalType ArgType2; 01131 typedef typename TypeUtility<Arg3CallType>::OriginalType ArgType3; 01132 01133 typedef FunctionCaller<FunctionContainerProxy<ReturnType, ArgType1, ArgType2, ArgType3>, 3, true> FunctionCallerType; 01134 return FunctionCallerType (proxyFunction, argument1, argument2, argument3); 01135 } 01136 01137 01138 }; 01139 01140 01141 #endif // PLONK_FUNCTION_H