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 // 27 // GEANT4 Class file 28 // 29 // File name: G4PhysicsConstructorRegistry.cc 30 // 31 // Author W. Pokorski 21.09.2012 32 // ------------------------------------------------------------------- 33 34 #include "G4ios.hh" 35 #include <iomanip> 36 37 // force REFERENCE macros _not_ to be expanded here 38 // but wherever the class is used (w/ that .hh use) 39 #define G4PhysicsConstructorRegistry_cc 1 40 41 #include "G4PhysicsConstructorRegistry.hh" 42 43 #include "G4VPhysicsConstructor.hh" 44 #include "G4PhysicsConstructorFactory.hh" 45 46 G4ThreadLocal G4PhysicsConstructorRegistry* G4PhysicsConstructorRegistry::theInstance = nullptr; 47 48 G4PhysicsConstructorRegistry* G4PhysicsConstructorRegistry::Instance() 49 { 50 if (nullptr == theInstance) { 51 static G4ThreadLocalSingleton<G4PhysicsConstructorRegistry> inst; 52 theInstance = inst.Instance(); 53 } 54 return theInstance; 55 } 56 57 G4PhysicsConstructorRegistry::G4PhysicsConstructorRegistry() 58 {} 59 60 G4PhysicsConstructorRegistry::~G4PhysicsConstructorRegistry() 61 { 62 Clean(); 63 } 64 65 void G4PhysicsConstructorRegistry::Clean() 66 { 67 for (auto const & ptr : physConstr) { delete ptr; } 68 physConstr.clear(); 69 } 70 71 void G4PhysicsConstructorRegistry::Register(G4VPhysicsConstructor* p) 72 { 73 if (nullptr == p) { return; } 74 for (auto const & ptr : physConstr) { if (p == ptr) { return; } } 75 physConstr.push_back(p); 76 } 77 78 void G4PhysicsConstructorRegistry::DeRegister(G4VPhysicsConstructor* p) 79 { 80 if (nullptr == p || physConstr.empty()) { return; } 81 std::size_t n = physConstr.size(); 82 for (std::size_t i=0; i<n; ++i) { 83 if ( physConstr[i] == p ) { 84 physConstr[i] = nullptr; 85 return; 86 } 87 } 88 } 89 90 void G4PhysicsConstructorRegistry::AddFactory(G4String name, G4VBasePhysConstrFactory* factory) 91 { 92 factories[name] = factory; 93 } 94 95 G4VPhysicsConstructor* G4PhysicsConstructorRegistry::GetPhysicsConstructor(const G4String& name) 96 { 97 // check if factory exists... 98 // 99 if (factories.find(name)!=factories.end()) 100 { 101 // we could store the list of called factories in some vector and 102 // before returning we can could first check if this physics constructor was already instantiated 103 // if yes, we can throw an exception saying that this physics can been already registered 104 105 return factories[name]->Instantiate(); 106 } 107 else 108 { 109 G4ExceptionDescription ED; 110 ED << "The factory for the physics constructor ["<< name << "] does not exist!" << G4endl; 111 G4Exception("G4PhysicsConstructorRegistry::GetPhysicsConstructor", "PhysicsList001", FatalException, ED); 112 return nullptr; 113 } 114 } 115 116 G4bool G4PhysicsConstructorRegistry::IsKnownPhysicsConstructor(const G4String& name) 117 { 118 return ( factories.find(name) != factories.end() ); 119 } 120 121 122 std::vector<G4String> G4PhysicsConstructorRegistry::AvailablePhysicsConstructors() const 123 { 124 std::vector<G4String> avail; 125 std::map<G4String,G4VBasePhysConstrFactory*>::const_iterator itr; 126 for ( itr = factories.begin(); itr != factories.end(); ++itr ) { 127 avail.push_back(itr->first); 128 } 129 130 return avail; 131 } 132 133 void G4PhysicsConstructorRegistry::PrintAvailablePhysicsConstructors() const 134 { 135 std::vector<G4String> avail = AvailablePhysicsConstructors(); 136 G4cout << "G4VPhysicsConstructors in G4PhysicsConstructorRegistry are:" 137 << G4endl; 138 if ( avail.empty() ) G4cout << "... no registered processes" << G4endl; 139 else { 140 std::size_t n = avail.size(); 141 for (std::size_t i=0; i<n; ++i ) { 142 G4cout << " [" << std::setw(3) << i << "] " 143 << " \"" << avail[i] << "\"" << G4endl; 144 } 145 } 146 } 147 148 // External reference to phy ctor factories for running with 'static' 149 // libraries to pull the references of the declared factories into the 150 // same compilation unit as the registry itself. 151 // No harm having them in the non-static case. 152 // 153 // Ideally we'd do the G4_REFERENCE_PHYSCONSTR_FACTORY() macros 154 // here, but this introduces a circular dependence between the 155 // ctor_phys_factory library and the other ctor_phys_* libraries 156 // when creating granular libraries. 157 // Instead we'll make the references in the location(s) where the 158 // G4PhysicsConstructorRegistry is _used_ : 159 // 160 //#include "G4RegisterPhysicsConstructors.icc" 161