File indexing completed on 2025-01-18 09:57:56
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 G4AnyType_hh
0048 #define G4AnyType_hh 1
0049
0050 #include "G4UIcommand.hh"
0051
0052 #include <algorithm>
0053 #include <iostream>
0054 #include <sstream>
0055 #include <typeinfo>
0056
0057 class G4String;
0058 namespace CLHEP
0059 {
0060 class Hep3Vector;
0061 }
0062
0063 class G4AnyType
0064 {
0065 public:
0066
0067
0068 G4AnyType() = default;
0069
0070 template<typename ValueType>
0071 G4AnyType(ValueType& value) : fContent(new Ref<ValueType>(value))
0072 {}
0073
0074
0075
0076 G4AnyType(const G4AnyType& other)
0077 : fContent(other.fContent != nullptr ? other.fContent->Clone() : nullptr)
0078 {}
0079
0080
0081
0082 ~G4AnyType() { delete fContent; }
0083
0084
0085
0086 operator bool() { return !Empty(); }
0087
0088
0089
0090 G4AnyType& Swap(G4AnyType& rhs)
0091 {
0092 std::swap(fContent, rhs.fContent);
0093 return *this;
0094 }
0095
0096 template<typename ValueType>
0097 G4AnyType& operator=(const ValueType& rhs)
0098 {
0099 G4AnyType(rhs).Swap(*this);
0100 return *this;
0101 }
0102
0103 G4AnyType& operator=(const G4AnyType& rhs)
0104 {
0105 G4AnyType(rhs).Swap(*this);
0106 return *this;
0107 }
0108
0109
0110
0111 G4bool Empty() const { return fContent == nullptr; }
0112
0113 const std::type_info& TypeInfo() const
0114 {
0115 return fContent != nullptr ? fContent->TypeInfo() : typeid(void);
0116 }
0117
0118
0119
0120 void* Address() const { return fContent != nullptr ? fContent->Address() : nullptr; }
0121
0122
0123
0124 std::string ToString() const { return fContent->ToString(); }
0125
0126 void FromString(const std::string& val) { fContent->FromString(val); }
0127
0128 private:
0129 class Placeholder
0130 {
0131 public:
0132 Placeholder() = default;
0133
0134 virtual ~Placeholder() = default;
0135
0136
0137
0138 virtual const std::type_info& TypeInfo() const = 0;
0139
0140 virtual Placeholder* Clone() const = 0;
0141
0142 virtual void* Address() const = 0;
0143
0144
0145
0146 virtual std::string ToString() const = 0;
0147
0148
0149
0150 virtual void FromString(const std::string& val) = 0;
0151 };
0152
0153 template<typename ValueType>
0154 class Ref : public Placeholder
0155 {
0156 public:
0157
0158
0159 Ref(ValueType& value) : fRef(value) {}
0160
0161
0162
0163 const std::type_info& TypeInfo() const override { return typeid(ValueType); }
0164
0165
0166
0167 Placeholder* Clone() const override { return new Ref(fRef); }
0168
0169
0170
0171 void* Address() const override { return (void*)(&fRef); }
0172
0173
0174
0175 std::string ToString() const override
0176 {
0177 std::stringstream ss;
0178 ss << fRef;
0179 return ss.str();
0180 }
0181
0182
0183
0184 void FromString(const std::string& val) override
0185 {
0186 std::stringstream ss(val);
0187 ss >> fRef;
0188 }
0189
0190 ValueType& fRef;
0191 };
0192
0193
0194
0195 template<typename ValueType>
0196 friend ValueType* any_cast(G4AnyType*);
0197
0198 Placeholder* fContent = nullptr;
0199 };
0200
0201
0202
0203
0204
0205 template<>
0206 inline void G4AnyType::Ref<bool>::FromString(const std::string& val)
0207 {
0208 fRef = G4UIcommand::ConvertToBool(val.c_str());
0209 }
0210
0211 template<>
0212 inline void G4AnyType::Ref<G4String>::FromString(const std::string& val)
0213 {
0214 if (val[0] == '"') {
0215 fRef = val.substr(1, val.size() - 2);
0216 }
0217 else {
0218 fRef = val;
0219 }
0220 }
0221
0222 template<>
0223 inline void G4AnyType::Ref<G4ThreeVector>::FromString(const std::string& val)
0224 {
0225 fRef = G4UIcommand::ConvertTo3Vector(val.c_str());
0226 }
0227
0228
0229
0230
0231
0232 class G4BadAnyCast : public std::bad_cast
0233 {
0234 public:
0235 G4BadAnyCast() = default;
0236
0237 const char* what() const throw() override
0238 {
0239 return "G4BadAnyCast: failed conversion using any_cast";
0240 }
0241 };
0242
0243
0244
0245 template<typename ValueType>
0246 ValueType* any_cast(G4AnyType* operand)
0247 {
0248 return operand && operand->TypeInfo() == typeid(ValueType)
0249 ? &static_cast<G4AnyType::Ref<ValueType>*>(operand->fContent)->fRef
0250 : nullptr;
0251 }
0252
0253 template<typename ValueType>
0254 const ValueType* any_cast(const G4AnyType* operand)
0255 {
0256 return any_cast<ValueType>(const_cast<G4AnyType*>(operand));
0257 }
0258
0259 template<typename ValueType>
0260 ValueType any_cast(const G4AnyType& operand)
0261 {
0262 const ValueType* result = any_cast<ValueType>(&operand);
0263 if (!result) {
0264 throw G4BadAnyCast();
0265 }
0266 return *result;
0267 }
0268
0269 #endif