Geant4.10
 All Data Structures 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 
50 /** Bad Argument exception */
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 template<typename T> struct remove_reference {typedef T type;};
60 template<typename T> struct remove_reference<T&> {typedef T type;};
61 template<typename T> struct remove_reference<const T&> {typedef T type;};
62 
63 /**
64  * @class G4AnyMethod G4AnyMothod.hh
65  * This class represents any object method. The class only holds a member pointer.
66  */
67 class G4AnyMethod {
68 public:
69  /** contructor */
70  G4AnyMethod(): fContent(0), narg(0) {}
71  template <class S, class T> G4AnyMethod(S (T::*f)()) : narg(0) {
72  fContent = new FuncRef<S,T>(f);
73  }
74  template <class S, class T, class A0> G4AnyMethod(S (T::*f)(A0)) : narg(1) {
75  fContent = new FuncRef1<S,T,A0>(f);
76  }
77  template <class S, class T, class A0, class A1> G4AnyMethod(S (T::*f)(A0,A1)) : narg(2) {
78  fContent = new FuncRef2<S,T,A0,A1>(f);
79  }
80  G4AnyMethod(const G4AnyMethod &other):
81  fContent(other.fContent ? other.fContent->Clone() : 0),narg(other.narg) {}
82  /** destructor */
84  delete fContent;
85  }
86 
88  std::swap(fContent, rhs.fContent);
89  std::swap(narg, rhs.narg);
90  return *this;
91  }
92  /** Asignment operator */
93  template <class S, class T> G4AnyMethod& operator =(S (T::*f)()) {
94  G4AnyMethod(f).Swap(*this);
95  narg = 0;
96  return *this;
97  }
98  template <class S, class T, class A0> G4AnyMethod& operator =(S (T::*f)(A0)) {
99  G4AnyMethod(f).Swap(*this);
100  narg = 1;
101  return *this;
102  }
103  template <class S, class T, class A0, class A1> G4AnyMethod& operator =(S (T::*f)(A0, A1)) {
104  G4AnyMethod(f).Swap(*this);
105  narg = 1;
106  return *this;
107  }
108  /** Asigment operator */
110  G4AnyMethod(rhs).Swap(*this);
111  narg = rhs.narg;
112  return *this;
113  }
114  /** Query */
115  bool Empty() const {
116  return !fContent;
117  }
118  /** call operator */
119  void operator()(void* obj) {
120  fContent->operator()(obj);
121  }
122  void operator()(void* obj, const std::string& a0) {
123  fContent->operator()(obj, a0);
124  }
125  /** Number of arguments */
126  size_t NArg() const { return narg; }
127 
128  const std::type_info& ArgType(size_t n = 0) const {
129  return fContent ? fContent->ArgType(n) : typeid(void);
130  }
131 
132 private:
133  class Placeholder {
134  public:
135  Placeholder() {}
136  virtual ~Placeholder() {}
137  virtual Placeholder* Clone() const = 0;
138  virtual void operator()(void*) = 0;
139  virtual void operator()(void*,const std::string&) = 0;
140  virtual const std::type_info& ArgType(size_t) const = 0;
141  };
142 
143  template <class S, class T> struct FuncRef: public Placeholder {
144  FuncRef(S (T::*f)()) : fRef(f) {}
145 
146  virtual void operator()(void* obj) {
147  ((T*)obj->*fRef)();
148  }
149  virtual void operator()(void*, const std::string&) {
150  throw G4BadArgument();
151  }
152  virtual Placeholder* Clone() const {
153  return new FuncRef(fRef);
154  }
155  virtual const std::type_info& ArgType(size_t) const {
156  return typeid(void);
157  }
158  S (T::*fRef)();
159  };
160 
161  template <class S, class T, class A0> struct FuncRef1: public Placeholder {
162  typedef typename remove_reference<A0>::type nakedA0;
163 
164  FuncRef1(S (T::*f)(A0)) : fRef(f) {}
165 
166  virtual void operator()(void*) {
167  throw G4BadArgument();
168  }
169  virtual void operator()(void* obj, const std::string& s0) {
170  nakedA0 a0;
171  std::stringstream strs(s0);
172  strs >> a0;
173  ((T*)obj->*fRef)(a0);
174  }
175  virtual Placeholder* Clone() const {
176  return new FuncRef1(fRef);
177  }
178  virtual const std::type_info& ArgType(size_t) const {
179  return typeid(A0);
180  }
181  S (T::*fRef)(A0);
182  };
183 
184  template <class S, class T, class A0, class A1> struct FuncRef2: public Placeholder {
185  typedef typename remove_reference<A0>::type nakedA0;
186  typedef typename remove_reference<A1>::type nakedA1;
187 
188  FuncRef2(S (T::*f)(A0, A1)) : fRef(f) {}
189 
190  virtual void operator()(void*) {
191  throw G4BadArgument();
192  }
193  virtual void operator()(void* obj, const std::string& s0) {
194  nakedA0 a0;
195  nakedA1 a1;
196  std::stringstream strs(s0);
197  strs >> a0 >> a1;
198  ((T*)obj->*fRef)(a0, a1);
199  }
200  virtual Placeholder* Clone() const {
201  return new FuncRef2(fRef);
202  }
203  virtual const std::type_info& ArgType(size_t i) const {
204  return i == 0 ? typeid(A0) : typeid(A1);
205  }
206  S (T::*fRef)(A0, A1);
207  };
208 
209  Placeholder* fContent;
210  size_t narg;
211 };
212 
213 
214 
215 
216 #endif
G4AnyMethod(S(T::*f)(A0))
Definition: G4AnyMethod.hh:74
G4AnyMethod(S(T::*f)())
Definition: G4AnyMethod.hh:71
G4AnyMethod(const G4AnyMethod &other)
Definition: G4AnyMethod.hh:80
G4AnyMethod(S(T::*f)(A0, A1))
Definition: G4AnyMethod.hh:77
typedef void(XMLCALL *XML_ElementDeclHandler)(void *userData
G4AnyMethod & operator=(S(T::*f)())
Definition: G4AnyMethod.hh:93
bool Empty() const
Definition: G4AnyMethod.hh:115
G4AnyMethod & Swap(G4AnyMethod &rhs)
Definition: G4AnyMethod.hh:87
size_t NArg() const
Definition: G4AnyMethod.hh:126
void swap(shared_ptr< P > &, shared_ptr< P > &)
Definition: memory.h:1247
const G4int n
void operator()(void *obj)
Definition: G4AnyMethod.hh:119
const std::type_info & ArgType(size_t n=0) const
Definition: G4AnyMethod.hh:128
virtual const char * what() const
Definition: G4AnyMethod.hh:54
void operator()(void *obj, const std::string &a0)
Definition: G4AnyMethod.hh:122