// // ******************************************************************** // * License and Disclaimer * // * * // * The Geant4 software is copyright of the Copyright Holders of * // * the Geant4 Collaboration. It is provided under the terms and * // * conditions of the Geant4 Software License, included in the file * // * LICENSE and available at http://cern.ch/geant4/license . These * // * include a list of copyright holders. * // * * // * Neither the authors of this software system, nor their employing * // * institutes,nor the agencies providing financial support for this * // * work make any representation or warranty, express or implied, * // * regarding this software system or assume any liability for its * // * use. Please see the license in the file LICENSE and URL above * // * for the full disclaimer and the limitation of liability. * // * * // * This code implementation is the result of the scientific and * // * technical work of the GEANT4 collaboration. * // * By using, copying, modifying or distributing the software (or * // * any work based on the software) you agree to acknowledge its * // * use in resulting scientific publications, and indicate your * // * acceptance of all terms of the Geant4 Software license. * // ******************************************************************** // // Author: Mathieu Karamitros // The code is developed in the framework of the ESA AO7146 // // We would be very happy hearing from you, send us your feedback! :) // // In order for Geant4-DNA to be maintained and still open-source, // article citations are crucial. // If you use Geant4-DNA chemistry and you publish papers about your software, // in addition to the general paper on Geant4-DNA: // // Int. J. Model. Simul. Sci. Comput. 1 (2010) 157–178 // // we would be very happy if you could please also cite the following // reference papers on chemistry: // // J. Comput. Phys. 274 (2014) 841-882 // Prog. Nucl. Sci. Tec. 2 (2011) 503-508 #ifndef G4TRACKSTATE_HH_ #define G4TRACKSTATE_HH_ #include #include "G4memory.hh" //------------------------------------------------------------------------------ class G4VTrackStateID { protected: static int fgLastID; static int Create(); G4VTrackStateID() {} virtual ~G4VTrackStateID() = default; }; //------------------------------------------------------------------------------ template class G4TrackStateID: public G4VTrackStateID { public: static int GetID() { return fID; } private: static const int fID; G4TrackStateID() {} ~G4TrackStateID() override = default; }; template const int G4TrackStateID::fID (G4VTrackStateID::Create()); //------------------------------------------------------------------------------ class G4VTrackState { public: G4VTrackState() = default; virtual ~G4VTrackState() = default; virtual int GetID() = 0; }; //------------------------------------------------------------------------------ using G4VTrackStateHandle = std::shared_ptr; //------------------------------------------------------------------------------ //! template class G4TrackStateDependent; template class G4TrackStateBase : public G4VTrackState { public: ~G4TrackStateBase() override = default; int GetID() override { return G4TrackStateID::GetID(); } static int ID() { return G4TrackStateID::GetID(); } protected: G4TrackStateBase() : G4VTrackState() {} }; //------------------------------------------------------------------------------ template class G4TrackState : public G4TrackStateBase { /* // friend T; // works in c++11 */ friend class G4TrackStateDependent; //! public: virtual ~G4TrackState() = default; static int ID() { return G4TrackStateID::GetID(); } G4TrackState() : G4TrackStateBase() {} }; //------------------------------------------------------------------------------ class G4TrackStateManager { std::map fTrackStates; std::map fMultipleTrackStates; public: void SetTrackState(void* adress, G4VTrackStateHandle state) { fMultipleTrackStates[adress] = std::move(state); } G4VTrackStateHandle GetTrackState(void* adress) const { auto it = fMultipleTrackStates.find(adress); if (it == fMultipleTrackStates.end()) { return G4VTrackStateHandle(); } return it->second; } template G4VTrackStateHandle GetTrackState(T* adress) const { auto it = fMultipleTrackStates.find((void*)adress); if (it == fMultipleTrackStates.end()) { return G4VTrackStateHandle(); } return it->second; } void SetTrackState(G4VTrackStateHandle state) { fTrackStates[state->GetID()] = state; } template G4VTrackStateHandle GetTrackState() const { auto it = fTrackStates.find(G4TrackStateID::GetID()); if (it == fTrackStates.end()) { return G4VTrackStateHandle(); } return it->second; } }; //------------------------------------------------------------------------------ class G4VTrackStateDependent { public: G4VTrackStateDependent() = default; virtual ~G4VTrackStateDependent() = default; virtual void NewTrackState() = 0; virtual void LoadTrackState(G4TrackStateManager&) = 0; virtual void SaveTrackState(G4TrackStateManager&) = 0; virtual G4VTrackStateHandle GetTrackState() const = 0; virtual G4VTrackStateHandle PopTrackState() = 0; virtual void ResetTrackState() = 0; }; #define G4TrackStateHandle(T) G4shared_ptr > template G4shared_ptr ConvertToAbstractTrackState(G4shared_ptr > state) { G4shared_ptr output = G4dynamic_pointer_cast(state); return output; } template G4shared_ptr > ConvertToConcreteTrackState(G4VTrackStateHandle state) { G4shared_ptr > output = G4dynamic_pointer_cast>(state); return output; } //------------------------------------------------------------------------------ //! template class G4TrackStateDependent : public G4VTrackStateDependent { public: using ClassType = T; using StateType = G4TrackState; using StateTypeHandle = std::shared_ptr; ~G4TrackStateDependent() override = default; virtual void SetTrackState(G4shared_ptr state) { fpTrackState = std::move(state); } G4VTrackStateHandle PopTrackState() override { G4VTrackStateHandle output = G4dynamic_pointer_cast(fpTrackState); fpTrackState.reset(); return output; } G4VTrackStateHandle GetTrackState() const override { G4VTrackStateHandle output = G4dynamic_pointer_cast(fpTrackState); return output; } virtual StateTypeHandle GetConcreteTrackState() const { return fpTrackState; } void LoadTrackState(G4TrackStateManager& manager) override { fpTrackState = ConvertToConcreteTrackState(manager.GetTrackState(this)); if (fpTrackState == nullptr) { NewTrackState(); SaveTrackState(manager); } } void SaveTrackState(G4TrackStateManager& manager) override { manager.SetTrackState(this, ConvertToAbstractTrackState(fpTrackState)); } void NewTrackState() override { fpTrackState = StateTypeHandle(new StateType()); } virtual StateTypeHandle CreateTrackState() const { return StateTypeHandle(new StateType()); } void ResetTrackState() override { fpTrackState.reset(); } protected: G4TrackStateDependent() : G4VTrackStateDependent() {} StateTypeHandle fpTrackState; }; //------------------------------------------------------------------------------ #if __cplusplus > 199711L #define RegisterTrackState(CLASS,STATE) \ template<> \ class G4TrackState : public G4TrackStateBase, \ public CLASS::STATE \ { \ friend class G4TrackStateDependent; \ using CLASS::STATE::STATE; \ public: \ typedef CLASS::STATE State; \ G4TrackState() : G4TrackStateBase(), CLASS::STATE(){}\ virtual ~G4TrackState(){}\ virtual int GetID()\ {\ return G4TrackStateID::GetID();\ }\ static int ID()\ {\ return G4TrackStateID::GetID();\ }\ protected:\ }; #else #define RegisterTrackState(CLASS,STATE) \ template<> \ class G4TrackState : public G4TrackStateBase, \ public CLASS::STATE \ { \ friend class G4TrackStateDependent; \ public: \ typedef CLASS::STATE State; \ G4TrackState() : G4TrackStateBase(), CLASS::STATE(){}\ virtual ~G4TrackState(){}\ virtual int GetID()\ {\ return G4TrackStateID::GetID();\ }\ static int ID()\ {\ return G4TrackStateID::GetID();\ }\ protected:\ }; #endif #endif /* G4TRACKSTATE_HH_ */