00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
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