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 G4AnyType_h
00045 #define G4AnyType_h 1
00046
00047 #include <algorithm>
00048 #include <typeinfo>
00049 #include <iostream>
00050 #include <sstream>
00051
00052 class G4String;
00053 namespace CLHEP {
00054 class Hep3Vector;
00055 }
00056
00061 class G4AnyType {
00062 public:
00064 G4AnyType():
00065 fContent(0) {}
00066
00068 template <typename ValueType> G4AnyType(ValueType &value):
00069 fContent(new Ref<ValueType>(value)) {}
00070
00072 G4AnyType(const G4AnyType &other):
00073 fContent(other.fContent ? other.fContent->Clone() : 0) {}
00074
00076 ~G4AnyType() {
00077 delete fContent;
00078 }
00079
00081 operator bool() {
00082 return !Empty();
00083 }
00085 G4AnyType& Swap(G4AnyType& rhs) {
00086 std::swap(fContent, rhs.fContent);
00087 return *this;
00088 }
00090 template <typename ValueType> G4AnyType& operator =(const ValueType& rhs) {
00091 G4AnyType(rhs).Swap(*this);
00092 return *this;
00093 }
00095 G4AnyType& operator =(const G4AnyType& rhs) {
00096 G4AnyType(rhs).Swap(*this);
00097 return *this;
00098 }
00100 bool Empty() const {
00101 return !fContent;
00102 }
00104 const std::type_info& TypeInfo() const {
00105 return fContent ? fContent->TypeInfo() : typeid(void);
00106 }
00108 void* Address() const {
00109 return fContent ? fContent->Address() : 0;
00110 }
00112 std::string ToString() const {
00113 return fContent->ToString();
00114 }
00116 void FromString(const std::string& val) {
00117 fContent->FromString(val);
00118 }
00119 private:
00123 class Placeholder {
00124 public:
00126 Placeholder() {}
00128 virtual ~Placeholder() {}
00130 virtual const std::type_info& TypeInfo() const = 0;
00132 virtual Placeholder* Clone() const = 0;
00134 virtual void* Address() const = 0;
00136 virtual std::string ToString() const = 0;
00138 virtual void FromString(const std::string& val) = 0;
00139 };
00140
00141 template <typename ValueType> class Ref: public Placeholder {
00142 public:
00144 Ref(ValueType& value): fRef(value) {}
00146 virtual const std::type_info& TypeInfo() const {
00147 return typeid(ValueType);
00148 }
00150 virtual Placeholder* Clone() const {
00151 return new Ref(fRef);
00152 }
00154 virtual void* Address() const {
00155 return (void*) (&fRef);
00156 }
00158 virtual std::string ToString() const {
00159 std::stringstream s;
00160 s << fRef;
00161 return s.str();
00162 }
00164 virtual void FromString(const std::string& val) {
00165 std::stringstream s(val);
00166 s >> fRef;
00167 }
00169 ValueType& fRef;
00170 };
00172 template <typename ValueType> friend ValueType* any_cast(G4AnyType*);
00174 Placeholder* fContent;
00175 };
00176
00181 template<> void G4AnyType::Ref<bool>::FromString(const std::string& val);
00182 template<> void G4AnyType::Ref<G4String>::FromString(const std::string& val);
00183 template<> void G4AnyType::Ref<CLHEP::Hep3Vector>::FromString(const std::string& val);
00184
00189 class G4BadAnyCast: public std::bad_cast {
00190 public:
00192 G4BadAnyCast() {}
00193
00195 virtual const char* what() const throw() {
00196 return "G4BadAnyCast: failed conversion using any_cast";
00197 }
00198 };
00199
00201 template <typename ValueType> ValueType* any_cast(G4AnyType* operand) {
00202 return operand && operand->TypeInfo() == typeid(ValueType)
00203 ? &static_cast<G4AnyType::Ref<ValueType>*>(operand->fContent)->fRef : 0;
00204 }
00206 template <typename ValueType> const ValueType* any_cast(const G4AnyType* operand) {
00207 return any_cast<ValueType>(const_cast<G4AnyType*>(operand));
00208 }
00210 template <typename ValueType> ValueType any_cast(const G4AnyType& operand) {
00211 const ValueType* result = any_cast<ValueType>(&operand);
00212 if (!result) {
00213 throw G4BadAnyCast();
00214 }
00215 return *result;
00216 }
00217
00218 #endif