Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:57:55

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 // G4AnyMethod
0027 //
0028 // Class description:
0029 //
0030 // The G4AnyMethod class represents any object method.
0031 // The class only holds a member pointer.
0032 
0033 // See http://www.boost.org/libs/any for Documentation.
0034 // Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
0035 //
0036 // Permission to use, copy, modify, and distribute this software for any
0037 // purpose is hereby granted without fee, provided that this copyright and
0038 // permissions notice appear in all copies and derivatives.
0039 //
0040 // This software is provided "as is" without express or implied warranty.
0041 // What:  variant At boost::any
0042 // who:   contributed by Kevlin Henney,
0043 //        with features contributed and bugs found by
0044 //        Ed Brey, Mark Rodgers, Peter Dimov, and James Curran
0045 // when:  July 2001
0046 // --------------------------------------------------------------------
0047 #ifndef G4AnyMethod_hh
0048 #define G4AnyMethod_hh 1
0049 
0050 #include "G4Types.hh"
0051 
0052 #include <functional>
0053 #include <sstream>
0054 #include <type_traits>
0055 
0056 /** Bad Argument exception */
0057 class G4BadArgument : public std::bad_cast
0058 {
0059   public:
0060     G4BadArgument() = default;
0061     const char* what() const throw() override { return "G4BadArgument: failed operator()"; }
0062 };
0063 
0064 class G4AnyMethod
0065 {
0066   public:
0067     G4AnyMethod() = default;
0068 
0069     template<class S, class T>
0070     G4AnyMethod(S (T::*f)())
0071     {
0072       fContent = new FuncRef<S, T>(f);
0073     }
0074 
0075     template<class S, class T, class A0>
0076     G4AnyMethod(S (T::*f)(A0)) : narg(1)
0077     {
0078       fContent = new FuncRef1<S, T, A0>(f);
0079     }
0080 
0081     template<class S, class T, class A0, class A1>
0082     G4AnyMethod(S (T::*f)(A0, A1)) : narg(2)
0083     {
0084       fContent = new FuncRef2<S, T, A0, A1>(f);
0085     }
0086 
0087     G4AnyMethod(const G4AnyMethod& other)
0088       : fContent(other.fContent != nullptr ? other.fContent->Clone() : nullptr), narg(other.narg)
0089     {}
0090 
0091     ~G4AnyMethod() { delete fContent; }
0092 
0093     G4AnyMethod& Swap(G4AnyMethod& rhs)
0094     {
0095       std::swap(fContent, rhs.fContent);
0096       std::swap(narg, rhs.narg);
0097       return *this;
0098     }
0099 
0100     template<class S, class T>
0101     G4AnyMethod& operator=(S (T::*f)())
0102     {
0103       G4AnyMethod(f).Swap(*this);
0104       narg = 0;
0105       return *this;
0106     }
0107 
0108     template<class S, class T, class A0>
0109     G4AnyMethod& operator=(S (T::*f)(A0))
0110     {
0111       G4AnyMethod(f).Swap(*this);
0112       narg = 1;
0113       return *this;
0114     }
0115     template<class S, class T, class A0, class A1>
0116     G4AnyMethod& operator=(S (T::*f)(A0, A1))
0117     {
0118       G4AnyMethod(f).Swap(*this);
0119       narg = 1;
0120       return *this;
0121     }
0122 
0123     G4AnyMethod& operator=(const G4AnyMethod& rhs)
0124     {
0125       G4AnyMethod(rhs).Swap(*this);
0126       narg = rhs.narg;
0127       return *this;
0128     }
0129 
0130     /** Query */
0131 
0132     G4bool Empty() const { return fContent == nullptr; }
0133 
0134     /** call operators */
0135 
0136     void operator()(void* obj) { fContent->operator()(obj); }
0137     void operator()(void* obj, const std::string& a0) { fContent->operator()(obj, a0); }
0138 
0139     /** Number of arguments */
0140 
0141     std::size_t NArg() const { return narg; }
0142 
0143     const std::type_info& ArgType(size_t n = 0) const
0144     {
0145       return fContent != nullptr ? fContent->ArgType(n) : typeid(void);
0146     }
0147 
0148   private:
0149     class Placeholder
0150     {
0151       public:
0152         Placeholder() = default;
0153         virtual ~Placeholder() = default;
0154         virtual Placeholder* Clone() const = 0;
0155         virtual void operator()(void*) = 0;
0156         virtual void operator()(void*, const std::string&) = 0;
0157         virtual const std::type_info& ArgType(size_t) const = 0;
0158     };
0159 
0160     template<class S, class T>
0161     struct FuncRef : public Placeholder
0162     {
0163         FuncRef(S (T::*f)()) : fRef(f) {}
0164 
0165         void operator()(void* obj) override { ((T*)obj->*fRef)(); }
0166         void operator()(void*, const std::string&) override { throw G4BadArgument(); }
0167         Placeholder* Clone() const override { return new FuncRef(fRef); }
0168         const std::type_info& ArgType(std::size_t) const override { return typeid(void); }
0169         S (T::*fRef)();
0170     };
0171 
0172     template<class S, class T, class A0>
0173     struct FuncRef1 : public Placeholder
0174     {
0175         using nakedA0 = std::remove_const_t<std::remove_reference_t<A0>>;
0176 
0177         FuncRef1(S (T::*f)(A0)) : fRef(f) {}
0178 
0179         void operator()(void*) override { throw G4BadArgument(); }
0180         void operator()(void* obj, const std::string& s0) override
0181         {
0182           nakedA0 a0;
0183           std::stringstream strs(s0);
0184           strs >> a0;
0185           ((T*)obj->*fRef)(a0);
0186         }
0187         Placeholder* Clone() const override { return new FuncRef1(fRef); }
0188         const std::type_info& ArgType(size_t) const override { return typeid(A0); }
0189         S (T::*fRef)(A0);
0190     };
0191 
0192     template<class S, class T, class A0, class A1>
0193     struct FuncRef2 : public Placeholder
0194     {
0195         using nakedA0 = std::remove_const_t<std::remove_reference_t<A0>>;
0196         using nakedA1 = std::remove_const_t<std::remove_reference_t<A1>>;
0197 
0198         FuncRef2(S (T::*f)(A0, A1)) : fRef(f) {}
0199 
0200         void operator()(void*) override { throw G4BadArgument(); }
0201         void operator()(void* obj, const std::string& s0) override
0202         {
0203           nakedA0 a0;
0204           nakedA1 a1;
0205           std::stringstream strs(s0);
0206           strs >> a0 >> a1;
0207           ((T*)obj->*fRef)(a0, a1);
0208         }
0209         Placeholder* Clone() const override { return new FuncRef2(fRef); }
0210         const std::type_info& ArgType(size_t i) const override
0211         {
0212           return i == 0 ? typeid(A0) : typeid(A1);
0213         }
0214         S (T::*fRef)(A0, A1);
0215     };
0216 
0217     Placeholder* fContent = nullptr;
0218     std::size_t narg = 0;
0219 };
0220 
0221 #endif