pl-nk v0.4.5
Plonk|Plink|Plank are a set of cross-platform C/C++ frameworks for audio software development
plonk_Function.h
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
 All Classes Functions Typedefs Enumerations Enumerator Properties