Geant4  10.03.p03
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4AnyMethod.hh
Go to the documentation of this file.
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 // $Id: G4UImessenger.hh,v 1.9 2006-06-29 19:08:19 gunter Exp $
28 //
29 // See http://www.boost.org/libs/any for Documentation.
30 // Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
31 //
32 // Permission to use, copy, modify, and distribute this software for any
33 // purpose is hereby granted without fee, provided that this copyright and
34 // permissions notice appear in all copies and derivatives.
35 //
36 // This software is provided "as is" without express or implied warranty.
37 // What: variant At boost::any
38 // who: contributed by Kevlin Henney,
39 // with features contributed and bugs found by
40 // Ed Brey, Mark Rodgers, Peter Dimov, and James Curran
41 // when: July 2001
42 // where: tested with BCC 5.5, MSVC 6.0, and g++ 2.95
43 
44 #ifndef G4AnyMethod_h
45 #define G4AnyMethod_h 1
46 
47 
48 #include <functional>
49 
51 class G4BadArgument: public std::bad_cast {
52 public:
54  virtual const char* what() const throw() {
55  return "G4BadArgument: failed operator()";
56  }
57 };
58 
59 #if defined(G4USE_STD11) || defined(G4USE_STD14)
60  #include <type_traits>
61  using std::remove_reference;
62  using std::remove_const;
63 // original usage below in G4AnyMethod (pre C++11) was without namespace std::
64 // so if compiler has them, make them available without the namespace
65 #else
66 // these are the reference "possible implementations" of a C++11 feature
67 // c.f. http://en.cppreference.com/w/cpp/types/remove_reference
68 // but they clash badly with C++11 definitions supplied by the compiler
69 // so use them only if C++11 is not enabled or there is no possibility
70 // of clashing with the ones defined in std:: namespace
71 // (i.e. avoid "using namespace std")
72 template<typename T> struct remove_reference {typedef T type;};
73 template<typename T> struct remove_reference<T&> {typedef T type;};
74 template<typename T> struct remove_reference<const T&> {typedef T type;};
75 template<typename T> struct remove_const<const T> {typedef T type;};
76 #endif
77 
82 class G4AnyMethod {
83 public:
85  G4AnyMethod(): fContent(0), narg(0) {}
86  template <class S, class T> G4AnyMethod(S (T::*f)()) : narg(0) {
87  fContent = new FuncRef<S,T>(f);
88  }
89  template <class S, class T, class A0> G4AnyMethod(S (T::*f)(A0)) : narg(1) {
90  fContent = new FuncRef1<S,T,A0>(f);
91  }
92  template <class S, class T, class A0, class A1> G4AnyMethod(S (T::*f)(A0,A1)) : narg(2) {
93  fContent = new FuncRef2<S,T,A0,A1>(f);
94  }
95  G4AnyMethod(const G4AnyMethod &other):
96  fContent(other.fContent ? other.fContent->Clone() : 0),narg(other.narg) {}
99  delete fContent;
100  }
101 
103  std::swap(fContent, rhs.fContent);
104  std::swap(narg, rhs.narg);
105  return *this;
106  }
108  template <class S, class T> G4AnyMethod& operator =(S (T::*f)()) {
109  G4AnyMethod(f).Swap(*this);
110  narg = 0;
111  return *this;
112  }
113  template <class S, class T, class A0> G4AnyMethod& operator =(S (T::*f)(A0)) {
114  G4AnyMethod(f).Swap(*this);
115  narg = 1;
116  return *this;
117  }
118  template <class S, class T, class A0, class A1> G4AnyMethod& operator =(S (T::*f)(A0, A1)) {
119  G4AnyMethod(f).Swap(*this);
120  narg = 1;
121  return *this;
122  }
125  G4AnyMethod(rhs).Swap(*this);
126  narg = rhs.narg;
127  return *this;
128  }
130  bool Empty() const {
131  return !fContent;
132  }
134  void operator()(void* obj) {
135  fContent->operator()(obj);
136  }
137  void operator()(void* obj, const std::string& a0) {
138  fContent->operator()(obj, a0);
139  }
141  size_t NArg() const { return narg; }
142 
143  const std::type_info& ArgType(size_t n = 0) const {
144  return fContent ? fContent->ArgType(n) : typeid(void);
145  }
146 
147 private:
148  class Placeholder {
149  public:
150  Placeholder() {}
151  virtual ~Placeholder() {}
152  virtual Placeholder* Clone() const = 0;
153  virtual void operator()(void*) = 0;
154  virtual void operator()(void*,const std::string&) = 0;
155  virtual const std::type_info& ArgType(size_t) const = 0;
156  };
157 
158  template <class S, class T> struct FuncRef: public Placeholder {
159  FuncRef(S (T::*f)()) : fRef(f) {}
160 
161  virtual void operator()(void* obj) {
162  ((T*)obj->*fRef)();
163  }
164  virtual void operator()(void*, const std::string&) {
165  throw G4BadArgument();
166  }
167  virtual Placeholder* Clone() const {
168  return new FuncRef(fRef);
169  }
170  virtual const std::type_info& ArgType(size_t) const {
171  return typeid(void);
172  }
173  S (T::*fRef)();
174  };
175 
176  template <class S, class T, class A0> struct FuncRef1: public Placeholder {
177  typedef typename remove_const<typename remove_reference<A0>::type>::type nakedA0;
178 
179  FuncRef1(S (T::*f)(A0)) : fRef(f) {}
180 
181  virtual void operator()(void*) {
182  throw G4BadArgument();
183  }
184  virtual void operator()(void* obj, const std::string& s0) {
185  nakedA0 a0;
186  std::stringstream strs(s0);
187  strs >> a0;
188  ((T*)obj->*fRef)(a0);
189  }
190  virtual Placeholder* Clone() const {
191  return new FuncRef1(fRef);
192  }
193  virtual const std::type_info& ArgType(size_t) const {
194  return typeid(A0);
195  }
196  S (T::*fRef)(A0);
197  };
198 
199  template <class S, class T, class A0, class A1> struct FuncRef2: public Placeholder {
200  typedef typename remove_const<typename remove_reference<A0>::type>::type nakedA0;
201  typedef typename remove_const<typename remove_reference<A1>::type>::type nakedA1;
202 
203  FuncRef2(S (T::*f)(A0, A1)) : fRef(f) {}
204 
205  virtual void operator()(void*) {
206  throw G4BadArgument();
207  }
208  virtual void operator()(void* obj, const std::string& s0) {
209  nakedA0 a0;
210  nakedA1 a1;
211  std::stringstream strs(s0);
212  strs >> a0 >> a1;
213  ((T*)obj->*fRef)(a0, a1);
214  }
215  virtual Placeholder* Clone() const {
216  return new FuncRef2(fRef);
217  }
218  virtual const std::type_info& ArgType(size_t i) const {
219  return i == 0 ? typeid(A0) : typeid(A1);
220  }
221  S (T::*fRef)(A0, A1);
222  };
223 
224  Placeholder* fContent;
225  size_t narg;
226 };
227 
228 #endif
const G4double a0
G4AnyMethod(S(T::*f)(A0))
Definition: G4AnyMethod.hh:89
double S(double temp)
G4AnyMethod(S(T::*f)())
Definition: G4AnyMethod.hh:86
G4AnyMethod(const G4AnyMethod &other)
Definition: G4AnyMethod.hh:95
G4AnyMethod(S(T::*f)(A0, A1))
Definition: G4AnyMethod.hh:92
G4AnyMethod & operator=(S(T::*f)())
Definition: G4AnyMethod.hh:108
const G4ThreeVector const G4double const
bool Empty() const
Definition: G4AnyMethod.hh:130
G4AnyMethod & Swap(G4AnyMethod &rhs)
Definition: G4AnyMethod.hh:102
size_t NArg() const
Definition: G4AnyMethod.hh:141
const G4int n
void operator()(void *obj)
Definition: G4AnyMethod.hh:134
const std::type_info & ArgType(size_t n=0) const
Definition: G4AnyMethod.hh:143
virtual const char * what() const
Definition: G4AnyMethod.hh:54
typedef void(XMLCALL *XML_ElementDeclHandler)(void *userData
void operator()(void *obj, const std::string &a0)
Definition: G4AnyMethod.hh:137