File indexing completed on 2025-01-18 09:57:55
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047 #ifndef G4AnyMethod_hh
0048 #define G4AnyMethod_hh 1
0049
0050 #include "G4Types.hh"
0051
0052 #include <functional>
0053 #include <sstream>
0054 #include <type_traits>
0055
0056
0057 class G4BadArgument : public std::bad_cast
0058 {
0059 public:
0060 G4BadArgument() = default;
0061 const char* what() const throw() override { return "G4BadArgument: failed operator()"; }
0062 };
0063
0064 class G4AnyMethod
0065 {
0066 public:
0067 G4AnyMethod() = default;
0068
0069 template<class S, class T>
0070 G4AnyMethod(S (T::*f)())
0071 {
0072 fContent = new FuncRef<S, T>(f);
0073 }
0074
0075 template<class S, class T, class A0>
0076 G4AnyMethod(S (T::*f)(A0)) : narg(1)
0077 {
0078 fContent = new FuncRef1<S, T, A0>(f);
0079 }
0080
0081 template<class S, class T, class A0, class A1>
0082 G4AnyMethod(S (T::*f)(A0, A1)) : narg(2)
0083 {
0084 fContent = new FuncRef2<S, T, A0, A1>(f);
0085 }
0086
0087 G4AnyMethod(const G4AnyMethod& other)
0088 : fContent(other.fContent != nullptr ? other.fContent->Clone() : nullptr), narg(other.narg)
0089 {}
0090
0091 ~G4AnyMethod() { delete fContent; }
0092
0093 G4AnyMethod& Swap(G4AnyMethod& rhs)
0094 {
0095 std::swap(fContent, rhs.fContent);
0096 std::swap(narg, rhs.narg);
0097 return *this;
0098 }
0099
0100 template<class S, class T>
0101 G4AnyMethod& operator=(S (T::*f)())
0102 {
0103 G4AnyMethod(f).Swap(*this);
0104 narg = 0;
0105 return *this;
0106 }
0107
0108 template<class S, class T, class A0>
0109 G4AnyMethod& operator=(S (T::*f)(A0))
0110 {
0111 G4AnyMethod(f).Swap(*this);
0112 narg = 1;
0113 return *this;
0114 }
0115 template<class S, class T, class A0, class A1>
0116 G4AnyMethod& operator=(S (T::*f)(A0, A1))
0117 {
0118 G4AnyMethod(f).Swap(*this);
0119 narg = 1;
0120 return *this;
0121 }
0122
0123 G4AnyMethod& operator=(const G4AnyMethod& rhs)
0124 {
0125 G4AnyMethod(rhs).Swap(*this);
0126 narg = rhs.narg;
0127 return *this;
0128 }
0129
0130
0131
0132 G4bool Empty() const { return fContent == nullptr; }
0133
0134
0135
0136 void operator()(void* obj) { fContent->operator()(obj); }
0137 void operator()(void* obj, const std::string& a0) { fContent->operator()(obj, a0); }
0138
0139
0140
0141 std::size_t NArg() const { return narg; }
0142
0143 const std::type_info& ArgType(size_t n = 0) const
0144 {
0145 return fContent != nullptr ? fContent->ArgType(n) : typeid(void);
0146 }
0147
0148 private:
0149 class Placeholder
0150 {
0151 public:
0152 Placeholder() = default;
0153 virtual ~Placeholder() = default;
0154 virtual Placeholder* Clone() const = 0;
0155 virtual void operator()(void*) = 0;
0156 virtual void operator()(void*, const std::string&) = 0;
0157 virtual const std::type_info& ArgType(size_t) const = 0;
0158 };
0159
0160 template<class S, class T>
0161 struct FuncRef : public Placeholder
0162 {
0163 FuncRef(S (T::*f)()) : fRef(f) {}
0164
0165 void operator()(void* obj) override { ((T*)obj->*fRef)(); }
0166 void operator()(void*, const std::string&) override { throw G4BadArgument(); }
0167 Placeholder* Clone() const override { return new FuncRef(fRef); }
0168 const std::type_info& ArgType(std::size_t) const override { return typeid(void); }
0169 S (T::*fRef)();
0170 };
0171
0172 template<class S, class T, class A0>
0173 struct FuncRef1 : public Placeholder
0174 {
0175 using nakedA0 = std::remove_const_t<std::remove_reference_t<A0>>;
0176
0177 FuncRef1(S (T::*f)(A0)) : fRef(f) {}
0178
0179 void operator()(void*) override { throw G4BadArgument(); }
0180 void operator()(void* obj, const std::string& s0) override
0181 {
0182 nakedA0 a0;
0183 std::stringstream strs(s0);
0184 strs >> a0;
0185 ((T*)obj->*fRef)(a0);
0186 }
0187 Placeholder* Clone() const override { return new FuncRef1(fRef); }
0188 const std::type_info& ArgType(size_t) const override { return typeid(A0); }
0189 S (T::*fRef)(A0);
0190 };
0191
0192 template<class S, class T, class A0, class A1>
0193 struct FuncRef2 : public Placeholder
0194 {
0195 using nakedA0 = std::remove_const_t<std::remove_reference_t<A0>>;
0196 using nakedA1 = std::remove_const_t<std::remove_reference_t<A1>>;
0197
0198 FuncRef2(S (T::*f)(A0, A1)) : fRef(f) {}
0199
0200 void operator()(void*) override { throw G4BadArgument(); }
0201 void operator()(void* obj, const std::string& s0) override
0202 {
0203 nakedA0 a0;
0204 nakedA1 a1;
0205 std::stringstream strs(s0);
0206 strs >> a0 >> a1;
0207 ((T*)obj->*fRef)(a0, a1);
0208 }
0209 Placeholder* Clone() const override { return new FuncRef2(fRef); }
0210 const std::type_info& ArgType(size_t i) const override
0211 {
0212 return i == 0 ? typeid(A0) : typeid(A1);
0213 }
0214 S (T::*fRef)(A0, A1);
0215 };
0216
0217 Placeholder* fContent = nullptr;
0218 std::size_t narg = 0;
0219 };
0220
0221 #endif