Geant4 Cross Reference |
1 // 2 // ******************************************************************** 3 // * License and Disclaimer * 4 // * * 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. * 10 // * * 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitation of liability. * 17 // * * 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************************************** 25 // 26 // G4AnyType 27 // 28 // Class description: 29 // 30 // The class G4AnyType represents any data type. 31 // The class only holds a reference to the type and not the value. 32 33 // See http://www.boost.org/libs/any for Documentation. 34 // Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved. 35 // 36 // Permission to use, copy, modify, and distribute this software for any 37 // purpose is hereby granted without fee, provided that this copyright and 38 // permissions notice appear in all copies and derivatives. 39 // 40 // This software is provided "as is" without express or implied warranty. 41 // What: variant At boost::any 42 // who: contributed by Kevlin Henney, 43 // with features contributed and bugs found by 44 // Ed Brey, Mark Rodgers, Peter Dimov, and James Curran 45 // when: July 2001 46 // -------------------------------------------------------------------- 47 #ifndef G4AnyType_hh 48 #define G4AnyType_hh 1 49 50 #include "G4UIcommand.hh" 51 52 #include <algorithm> 53 #include <iostream> 54 #include <sstream> 55 #include <typeinfo> 56 57 class G4String; 58 namespace CLHEP 59 { 60 class Hep3Vector; 61 } 62 63 class G4AnyType 64 { 65 public: 66 /** Constructors */ 67 68 G4AnyType() = default; 69 70 template<typename ValueType> 71 G4AnyType(ValueType& value) : fContent(new Ref<ValueType>(value)) 72 {} 73 74 /** Copy Constructor */ 75 76 G4AnyType(const G4AnyType& other) 77 : fContent(other.fContent != nullptr ? other.fContent->Clone() : nullptr) 78 {} 79 80 /** Destructor */ 81 82 ~G4AnyType() { delete fContent; } 83 84 /** bool operator */ 85 86 operator bool() { return !Empty(); } 87 88 /** Modifiers */ 89 90 G4AnyType& Swap(G4AnyType& rhs) 91 { 92 std::swap(fContent, rhs.fContent); 93 return *this; 94 } 95 96 template<typename ValueType> 97 G4AnyType& operator=(const ValueType& rhs) 98 { 99 G4AnyType(rhs).Swap(*this); 100 return *this; 101 } 102 103 G4AnyType& operator=(const G4AnyType& rhs) 104 { 105 G4AnyType(rhs).Swap(*this); 106 return *this; 107 } 108 109 /** Queries */ 110 111 G4bool Empty() const { return fContent == nullptr; } 112 113 const std::type_info& TypeInfo() const 114 { 115 return fContent != nullptr ? fContent->TypeInfo() : typeid(void); 116 } 117 118 /** Address */ 119 120 void* Address() const { return fContent != nullptr ? fContent->Address() : nullptr; } 121 122 /** String conversions */ 123 124 std::string ToString() const { return fContent->ToString(); } 125 126 void FromString(const std::string& val) { fContent->FromString(val); } 127 128 private: 129 class Placeholder 130 { 131 public: 132 Placeholder() = default; 133 134 virtual ~Placeholder() = default; 135 136 /** Queries */ 137 138 virtual const std::type_info& TypeInfo() const = 0; 139 140 virtual Placeholder* Clone() const = 0; 141 142 virtual void* Address() const = 0; 143 144 /** ToString */ 145 146 virtual std::string ToString() const = 0; 147 148 /** FromString */ 149 150 virtual void FromString(const std::string& val) = 0; 151 }; 152 153 template<typename ValueType> 154 class Ref : public Placeholder 155 { 156 public: 157 /** Constructor */ 158 159 Ref(ValueType& value) : fRef(value) {} 160 161 /** Query */ 162 163 const std::type_info& TypeInfo() const override { return typeid(ValueType); } 164 165 /** Clone */ 166 167 Placeholder* Clone() const override { return new Ref(fRef); } 168 169 /** Address */ 170 171 void* Address() const override { return (void*)(&fRef); } 172 173 /** ToString */ 174 175 std::string ToString() const override 176 { 177 std::stringstream ss; 178 ss << fRef; 179 return ss.str(); 180 } 181 182 /** FromString */ 183 184 void FromString(const std::string& val) override 185 { 186 std::stringstream ss(val); 187 ss >> fRef; 188 } 189 190 ValueType& fRef; // representation 191 }; 192 193 /** representation */ 194 195 template<typename ValueType> 196 friend ValueType* any_cast(G4AnyType*); 197 198 Placeholder* fContent = nullptr; 199 }; 200 201 // 202 // Specializations 203 // 204 205 template<> 206 inline void G4AnyType::Ref<bool>::FromString(const std::string& val) 207 { 208 fRef = G4UIcommand::ConvertToBool(val.c_str()); 209 } 210 211 template<> 212 inline void G4AnyType::Ref<G4String>::FromString(const std::string& val) 213 { 214 if (val[0] == '"') { 215 fRef = val.substr(1, val.size() - 2); 216 } 217 else { 218 fRef = val; 219 } 220 } 221 222 template<> 223 inline void G4AnyType::Ref<G4ThreeVector>::FromString(const std::string& val) 224 { 225 fRef = G4UIcommand::ConvertTo3Vector(val.c_str()); 226 } 227 228 /** 229 * @class G4BadAnyCast G4AnyType.h Reflex/G4AnyType.h 230 * @author K. Henney 231 */ 232 class G4BadAnyCast : public std::bad_cast 233 { 234 public: 235 G4BadAnyCast() = default; 236 237 const char* what() const throw() override 238 { 239 return "G4BadAnyCast: failed conversion using any_cast"; 240 } 241 }; 242 243 /** value */ 244 245 template<typename ValueType> 246 ValueType* any_cast(G4AnyType* operand) 247 { 248 return operand && operand->TypeInfo() == typeid(ValueType) 249 ? &static_cast<G4AnyType::Ref<ValueType>*>(operand->fContent)->fRef 250 : nullptr; 251 } 252 253 template<typename ValueType> 254 const ValueType* any_cast(const G4AnyType* operand) 255 { 256 return any_cast<ValueType>(const_cast<G4AnyType*>(operand)); 257 } 258 259 template<typename ValueType> 260 ValueType any_cast(const G4AnyType& operand) 261 { 262 const ValueType* result = any_cast<ValueType>(&operand); 263 if (!result) { 264 throw G4BadAnyCast(); 265 } 266 return *result; 267 } 268 269 #endif 270