G4AnyMethod.hh

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 //
00027 // $Id: G4UImessenger.hh,v 1.9 2006-06-29 19:08:19 gunter Exp $
00028 //
00029 // See http://www.boost.org/libs/any for Documentation.
00030 // Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
00031 //
00032 // Permission to use, copy, modify, and distribute this software for any
00033 // purpose is hereby granted without fee, provided that this copyright and
00034 // permissions notice appear in all copies and derivatives.
00035 //
00036 // This software is provided "as is" without express or implied warranty.
00037 // What:  variant At boost::any
00038 // who:   contributed by Kevlin Henney,
00039 //        with features contributed and bugs found by
00040 //        Ed Brey, Mark Rodgers, Peter Dimov, and James Curran
00041 // when:  July 2001
00042 // where: tested with BCC 5.5, MSVC 6.0, and g++ 2.95
00043 
00044 #ifndef G4AnyMethod_h
00045 #define G4AnyMethod_h 1
00046 
00047 
00048 #include <functional>
00049 
00051 class G4BadArgument: public std::bad_cast {
00052 public:
00053   G4BadArgument() {}
00054   virtual const char* what() const throw() {
00055     return "G4BadArgument: failed operator()";
00056   }
00057 };
00058 
00059 template<typename T> struct remove_reference {typedef T type;};
00060 template<typename T> struct remove_reference<T&> {typedef T type;};
00061 template<typename T> struct remove_reference<const T&> {typedef T type;};
00062 
00067 class G4AnyMethod {
00068 public:
00070   G4AnyMethod(): fContent(0), narg(0) {}
00071   template <class S, class T> G4AnyMethod(S (T::*f)()) : narg(0) {
00072     fContent = new FuncRef<S,T>(f);
00073   }
00074   template <class S, class T, class A0> G4AnyMethod(S (T::*f)(A0)) : narg(1) {
00075     fContent = new FuncRef1<S,T,A0>(f);
00076   }
00077   template <class S, class T, class A0, class A1> G4AnyMethod(S (T::*f)(A0,A1)) : narg(2) {
00078     fContent = new FuncRef2<S,T,A0,A1>(f);
00079   }
00080   G4AnyMethod(const G4AnyMethod &other):
00081   fContent(other.fContent ? other.fContent->Clone() : 0),narg(other.narg) {}
00083   ~G4AnyMethod() {
00084     delete fContent;
00085   }
00086   
00087   G4AnyMethod& Swap(G4AnyMethod& rhs) {
00088     std::swap(fContent, rhs.fContent);
00089     std::swap(narg, rhs.narg);
00090     return *this;
00091   }
00093   template <class S, class T>  G4AnyMethod& operator =(S (T::*f)()) {
00094     G4AnyMethod(f).Swap(*this);
00095     narg = 0;
00096     return *this;
00097   }
00098   template <class S, class T, class A0> G4AnyMethod& operator =(S (T::*f)(A0)) {
00099     G4AnyMethod(f).Swap(*this);
00100     narg = 1;
00101     return *this;
00102   }
00103   template <class S, class T, class A0, class A1> G4AnyMethod& operator =(S (T::*f)(A0, A1)) {
00104     G4AnyMethod(f).Swap(*this);
00105     narg = 1;
00106     return *this;
00107   }
00109   G4AnyMethod& operator =(const G4AnyMethod& rhs) {
00110     G4AnyMethod(rhs).Swap(*this);
00111     narg = rhs.narg;
00112     return *this;
00113   }
00115   bool Empty() const {
00116     return !fContent;
00117   }
00119   void operator()(void* obj) {
00120     fContent->operator()(obj);
00121   }
00122   void operator()(void* obj, const std::string& a0) {
00123     fContent->operator()(obj, a0);
00124   }
00126   size_t NArg() const { return narg; }
00127   
00128   const std::type_info& ArgType(size_t n = 0) const {
00129     return fContent ? fContent->ArgType(n) : typeid(void);
00130   }
00131   
00132 private:
00133   class Placeholder {
00134   public:
00135     Placeholder() {}
00136     virtual ~Placeholder() {}
00137     virtual Placeholder* Clone() const = 0;
00138     virtual void operator()(void*) = 0;
00139     virtual void operator()(void*,const std::string&) = 0;
00140     virtual const std::type_info& ArgType(size_t) const = 0;
00141   };
00142   
00143   template <class S, class T> struct FuncRef: public Placeholder {
00144     FuncRef(S (T::*f)()) : fRef(f) {}
00145     
00146     virtual void operator()(void* obj) {
00147       ((T*)obj->*fRef)();
00148     }
00149     virtual void operator()(void*, const std::string&) {
00150       throw G4BadArgument();
00151     }
00152     virtual Placeholder* Clone() const {
00153       return new FuncRef(fRef);
00154     }
00155     virtual const std::type_info& ArgType(size_t) const {
00156       return typeid(void);
00157     }
00158     S (T::*fRef)();
00159   };
00160   
00161   template <class S, class T, class A0> struct FuncRef1: public Placeholder {
00162     typedef typename remove_reference<A0>::type  nakedA0;
00163     
00164     FuncRef1(S (T::*f)(A0)) : fRef(f) {}
00165     
00166     virtual void operator()(void*) {
00167       throw G4BadArgument();
00168     }
00169     virtual void operator()(void* obj, const std::string& s0) {
00170       nakedA0 a0;
00171       std::stringstream strs(s0);
00172       strs >> a0;
00173       ((T*)obj->*fRef)(a0);
00174     }
00175     virtual Placeholder* Clone() const {
00176       return new FuncRef1(fRef);
00177     }
00178     virtual const std::type_info& ArgType(size_t) const {
00179       return typeid(A0);
00180     }
00181     S (T::*fRef)(A0);
00182   };
00183 
00184   template <class S, class T, class A0, class A1> struct FuncRef2: public Placeholder {
00185     typedef typename remove_reference<A0>::type  nakedA0;
00186     typedef typename remove_reference<A1>::type  nakedA1;
00187     
00188     FuncRef2(S (T::*f)(A0, A1)) : fRef(f) {}
00189     
00190     virtual void operator()(void*) {
00191       throw G4BadArgument();
00192     }
00193     virtual void operator()(void* obj, const std::string& s0) {
00194       nakedA0 a0;
00195       nakedA1 a1;
00196       std::stringstream strs(s0);
00197       strs >> a0 >> a1;
00198       ((T*)obj->*fRef)(a0, a1);
00199     }
00200     virtual Placeholder* Clone() const {
00201       return new FuncRef2(fRef);
00202     }
00203     virtual const std::type_info& ArgType(size_t i) const {
00204       return i == 0 ? typeid(A0) : typeid(A1);
00205     }
00206     S (T::*fRef)(A0, A1);
00207   };
00208   
00209   Placeholder* fContent;
00210   size_t narg;
00211 };
00212 
00213 
00214 
00215 
00216 #endif

Generated on Mon May 27 17:47:41 2013 for Geant4 by  doxygen 1.4.7