Geant4  10.03.p01
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros 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 // original usage below in G4AnyMethod (pre C++11) was without namespace std::
63 // so if compiler has them, make them available without the namespace
64 #else
65 // these are the reference "possible implementations" of a C++11 feature
66 // c.f. http://en.cppreference.com/w/cpp/types/remove_reference
67 // but they clash badly with C++11 definitions supplied by the compiler
68 // so use them only if C++11 is not enabled or there is no possibility
69 // of clashing with the ones defined in std:: namespace
70 // (i.e. avoid "using namespace std")
71 template<typename T> struct remove_reference {typedef T type;};
72 template<typename T> struct remove_reference<T&> {typedef T type;};
73 template<typename T> struct remove_reference<const T&> {typedef T type;};
74 #endif
75 
80 class G4AnyMethod {
81 public:
83  G4AnyMethod(): fContent(0), narg(0) {}
84  template <class S, class T> G4AnyMethod(S (T::*f)()) : narg(0) {
85  fContent = new FuncRef<S,T>(f);
86  }
87  template <class S, class T, class A0> G4AnyMethod(S (T::*f)(A0)) : narg(1) {
88  fContent = new FuncRef1<S,T,A0>(f);
89  }
90  template <class S, class T, class A0, class A1> G4AnyMethod(S (T::*f)(A0,A1)) : narg(2) {
91  fContent = new FuncRef2<S,T,A0,A1>(f);
92  }
93  G4AnyMethod(const G4AnyMethod &other):
94  fContent(other.fContent ? other.fContent->Clone() : 0),narg(other.narg) {}
97  delete fContent;
98  }
99 
101  std::swap(fContent, rhs.fContent);
102  std::swap(narg, rhs.narg);
103  return *this;
104  }
106  template <class S, class T> G4AnyMethod& operator =(S (T::*f)()) {
107  G4AnyMethod(f).Swap(*this);
108  narg = 0;
109  return *this;
110  }
111  template <class S, class T, class A0> G4AnyMethod& operator =(S (T::*f)(A0)) {
112  G4AnyMethod(f).Swap(*this);
113  narg = 1;
114  return *this;
115  }
116  template <class S, class T, class A0, class A1> G4AnyMethod& operator =(S (T::*f)(A0, A1)) {
117  G4AnyMethod(f).Swap(*this);
118  narg = 1;
119  return *this;
120  }
123  G4AnyMethod(rhs).Swap(*this);
124  narg = rhs.narg;
125  return *this;
126  }
128  bool Empty() const {
129  return !fContent;
130  }
132  void operator()(void* obj) {
133  fContent->operator()(obj);
134  }
135  void operator()(void* obj, const std::string& a0) {
136  fContent->operator()(obj, a0);
137  }
139  size_t NArg() const { return narg; }
140 
141  const std::type_info& ArgType(size_t n = 0) const {
142  return fContent ? fContent->ArgType(n) : typeid(void);
143  }
144 
145 private:
146  class Placeholder {
147  public:
148  Placeholder() {}
149  virtual ~Placeholder() {}
150  virtual Placeholder* Clone() const = 0;
151  virtual void operator()(void*) = 0;
152  virtual void operator()(void*,const std::string&) = 0;
153  virtual const std::type_info& ArgType(size_t) const = 0;
154  };
155 
156  template <class S, class T> struct FuncRef: public Placeholder {
157  FuncRef(S (T::*f)()) : fRef(f) {}
158 
159  virtual void operator()(void* obj) {
160  ((T*)obj->*fRef)();
161  }
162  virtual void operator()(void*, const std::string&) {
163  throw G4BadArgument();
164  }
165  virtual Placeholder* Clone() const {
166  return new FuncRef(fRef);
167  }
168  virtual const std::type_info& ArgType(size_t) const {
169  return typeid(void);
170  }
171  S (T::*fRef)();
172  };
173 
174  template <class S, class T, class A0> struct FuncRef1: public Placeholder {
175  typedef typename remove_reference<A0>::type nakedA0;
176 
177  FuncRef1(S (T::*f)(A0)) : fRef(f) {}
178 
179  virtual void operator()(void*) {
180  throw G4BadArgument();
181  }
182  virtual void operator()(void* obj, const std::string& s0) {
183  nakedA0 a0;
184  std::stringstream strs(s0);
185  strs >> a0;
186  ((T*)obj->*fRef)(a0);
187  }
188  virtual Placeholder* Clone() const {
189  return new FuncRef1(fRef);
190  }
191  virtual const std::type_info& ArgType(size_t) const {
192  return typeid(A0);
193  }
194  S (T::*fRef)(A0);
195  };
196 
197  template <class S, class T, class A0, class A1> struct FuncRef2: public Placeholder {
198  typedef typename remove_reference<A0>::type nakedA0;
199  typedef typename remove_reference<A1>::type nakedA1;
200 
201  FuncRef2(S (T::*f)(A0, A1)) : fRef(f) {}
202 
203  virtual void operator()(void*) {
204  throw G4BadArgument();
205  }
206  virtual void operator()(void* obj, const std::string& s0) {
207  nakedA0 a0;
208  nakedA1 a1;
209  std::stringstream strs(s0);
210  strs >> a0 >> a1;
211  ((T*)obj->*fRef)(a0, a1);
212  }
213  virtual Placeholder* Clone() const {
214  return new FuncRef2(fRef);
215  }
216  virtual const std::type_info& ArgType(size_t i) const {
217  return i == 0 ? typeid(A0) : typeid(A1);
218  }
219  S (T::*fRef)(A0, A1);
220  };
221 
222  Placeholder* fContent;
223  size_t narg;
224 };
225 
226 
227 
228 
229 #endif
const G4double a0
G4AnyMethod(S(T::*f)(A0))
Definition: G4AnyMethod.hh:87
double S(double temp)
G4AnyMethod(S(T::*f)())
Definition: G4AnyMethod.hh:84
G4AnyMethod(const G4AnyMethod &other)
Definition: G4AnyMethod.hh:93
G4AnyMethod(S(T::*f)(A0, A1))
Definition: G4AnyMethod.hh:90
G4AnyMethod & operator=(S(T::*f)())
Definition: G4AnyMethod.hh:106
bool Empty() const
Definition: G4AnyMethod.hh:128
G4AnyMethod & Swap(G4AnyMethod &rhs)
Definition: G4AnyMethod.hh:100
size_t NArg() const
Definition: G4AnyMethod.hh:139
void operator()(void *obj)
Definition: G4AnyMethod.hh:132
const std::type_info & ArgType(size_t n=0) const
Definition: G4AnyMethod.hh:141
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:135