Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/intercoms/include/G4AnyMethod.hh

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  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 // G4AnyMethod
 27 //
 28 // Class description:
 29 //
 30 // The G4AnyMethod class represents any object method.
 31 // The class only holds a member pointer.
 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 G4AnyMethod_hh
 48 #define G4AnyMethod_hh 1
 49 
 50 #include "G4Types.hh"
 51 
 52 #include <functional>
 53 #include <sstream>
 54 #include <type_traits>
 55 
 56 /** Bad Argument exception */
 57 class G4BadArgument : public std::bad_cast
 58 {
 59   public:
 60     G4BadArgument() = default;
 61     const char* what() const throw() override { return "G4BadArgument: failed operator()"; }
 62 };
 63 
 64 class G4AnyMethod
 65 {
 66   public:
 67     G4AnyMethod() = default;
 68 
 69     template<class S, class T>
 70     G4AnyMethod(S (T::*f)())
 71     {
 72       fContent = new FuncRef<S, T>(f);
 73     }
 74 
 75     template<class S, class T, class A0>
 76     G4AnyMethod(S (T::*f)(A0)) : narg(1)
 77     {
 78       fContent = new FuncRef1<S, T, A0>(f);
 79     }
 80 
 81     template<class S, class T, class A0, class A1>
 82     G4AnyMethod(S (T::*f)(A0, A1)) : narg(2)
 83     {
 84       fContent = new FuncRef2<S, T, A0, A1>(f);
 85     }
 86 
 87     G4AnyMethod(const G4AnyMethod& other)
 88       : fContent(other.fContent != nullptr ? other.fContent->Clone() : nullptr), narg(other.narg)
 89     {}
 90 
 91     ~G4AnyMethod() { delete fContent; }
 92 
 93     G4AnyMethod& Swap(G4AnyMethod& rhs)
 94     {
 95       std::swap(fContent, rhs.fContent);
 96       std::swap(narg, rhs.narg);
 97       return *this;
 98     }
 99 
100     template<class S, class T>
101     G4AnyMethod& operator=(S (T::*f)())
102     {
103       G4AnyMethod(f).Swap(*this);
104       narg = 0;
105       return *this;
106     }
107 
108     template<class S, class T, class A0>
109     G4AnyMethod& operator=(S (T::*f)(A0))
110     {
111       G4AnyMethod(f).Swap(*this);
112       narg = 1;
113       return *this;
114     }
115     template<class S, class T, class A0, class A1>
116     G4AnyMethod& operator=(S (T::*f)(A0, A1))
117     {
118       G4AnyMethod(f).Swap(*this);
119       narg = 1;
120       return *this;
121     }
122 
123     G4AnyMethod& operator=(const G4AnyMethod& rhs)
124     {
125       G4AnyMethod(rhs).Swap(*this);
126       narg = rhs.narg;
127       return *this;
128     }
129 
130     /** Query */
131 
132     G4bool Empty() const { return fContent == nullptr; }
133 
134     /** call operators */
135 
136     void operator()(void* obj) { fContent->operator()(obj); }
137     void operator()(void* obj, const std::string& a0) { fContent->operator()(obj, a0); }
138 
139     /** Number of arguments */
140 
141     std::size_t NArg() const { return narg; }
142 
143     const std::type_info& ArgType(size_t n = 0) const
144     {
145       return fContent != nullptr ? fContent->ArgType(n) : typeid(void);
146     }
147 
148   private:
149     class Placeholder
150     {
151       public:
152         Placeholder() = default;
153         virtual ~Placeholder() = default;
154         virtual Placeholder* Clone() const = 0;
155         virtual void operator()(void*) = 0;
156         virtual void operator()(void*, const std::string&) = 0;
157         virtual const std::type_info& ArgType(size_t) const = 0;
158     };
159 
160     template<class S, class T>
161     struct FuncRef : public Placeholder
162     {
163         FuncRef(S (T::*f)()) : fRef(f) {}
164 
165         void operator()(void* obj) override { ((T*)obj->*fRef)(); }
166         void operator()(void*, const std::string&) override { throw G4BadArgument(); }
167         Placeholder* Clone() const override { return new FuncRef(fRef); }
168         const std::type_info& ArgType(std::size_t) const override { return typeid(void); }
169         S (T::*fRef)();
170     };
171 
172     template<class S, class T, class A0>
173     struct FuncRef1 : public Placeholder
174     {
175         using nakedA0 = std::remove_const_t<std::remove_reference_t<A0>>;
176 
177         FuncRef1(S (T::*f)(A0)) : fRef(f) {}
178 
179         void operator()(void*) override { throw G4BadArgument(); }
180         void operator()(void* obj, const std::string& s0) override
181         {
182           nakedA0 a0;
183           std::stringstream strs(s0);
184           strs >> a0;
185           ((T*)obj->*fRef)(a0);
186         }
187         Placeholder* Clone() const override { return new FuncRef1(fRef); }
188         const std::type_info& ArgType(size_t) const override { return typeid(A0); }
189         S (T::*fRef)(A0);
190     };
191 
192     template<class S, class T, class A0, class A1>
193     struct FuncRef2 : public Placeholder
194     {
195         using nakedA0 = std::remove_const_t<std::remove_reference_t<A0>>;
196         using nakedA1 = std::remove_const_t<std::remove_reference_t<A1>>;
197 
198         FuncRef2(S (T::*f)(A0, A1)) : fRef(f) {}
199 
200         void operator()(void*) override { throw G4BadArgument(); }
201         void operator()(void* obj, const std::string& s0) override
202         {
203           nakedA0 a0;
204           nakedA1 a1;
205           std::stringstream strs(s0);
206           strs >> a0 >> a1;
207           ((T*)obj->*fRef)(a0, a1);
208         }
209         Placeholder* Clone() const override { return new FuncRef2(fRef); }
210         const std::type_info& ArgType(size_t i) const override
211         {
212           return i == 0 ? typeid(A0) : typeid(A1);
213         }
214         S (T::*fRef)(A0, A1);
215     };
216 
217     Placeholder* fContent = nullptr;
218     std::size_t narg = 0;
219 };
220 
221 #endif
222