GENIEGenerator
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GFluxDriverFactory.h
Go to the documentation of this file.
1 //____________________________________________________________________________
2 /*!
3 
4 \class genie::flux::GFluxDriverFactory
5 
6 \brief A class for generating concrete GFluxI derived classes
7  based on the factory pattern. This code supplies a CPP
8  macro which allows the classes to self-register and thus
9  no modification of this class is needed in order to expand
10  the list of classes it knows about.
11 
12  Implemented as a singleton holding a map between names and
13  pointers-to-functions (that call a class default constructor).
14  The functions pointers must return GFluxI*.
15 
16 \author Robert Hatcher <rhatcher \at fnal.gov>
17  Fermi National Accelerator Laboratory
18 
19 \created
20 
21 \cpright Copyright (c) 2003-2024, The GENIE Collaboration
22  for the full text of the license visit http://copyright.genie-mc.org
23 */
24 //____________________________________________________________________________
25 
26 #ifndef GENIE_FLUX_GFLUXDRIVERFACTORY_H
27 #define GENIE_FLUX_GFLUXDRIVERFACTORY_H
28 
29 #include <string>
30 #include <vector>
31 #include <map>
32 
34 
35 namespace genie {
36 namespace flux {
37 
38 // while most drivers are defined genie::flux::MySpecificDriver
39 // the base interface is only genie::GFluxI
40 
41 // define a type for the pointer to a function that returns a
42 // genie::GFluxI*
43 // i.e. calls the (typically default) ctor for the class.
44 typedef genie::GFluxI* (*GFluxICtorFuncPtr_t)();
45 
47 {
48 public:
49  static GFluxDriverFactory& Instance();
50  // no public ctor for singleton, all user access is through Instance()
51 
52  genie::GFluxI* GetFluxDriver(const std::string&);
53  // instantiate a GFluxI driver by name
54 
55  bool IsKnownFluxDriver(const std::string&);
56  // check if the name is in the list of names
57 
58  const std::vector<std::string>& AvailableFluxDrivers() const;
59  // return a list of available names
60 
61  bool RegisterCreator(std::string name,
62  GFluxICtorFuncPtr_t ctorptr, bool* ptr);
63  // register a new GFluxI type by passing pointer to creator function
64 
65  void PrintConfig() const;
66 
67 private:
69  // the one and only instance
70 
71  std::map<std::string, GFluxICtorFuncPtr_t> fFunctionMap;
72  // mapping between known class names and a registered ctor function
73 
74  std::map<std::string, bool*> fBoolPtrMap;
75 
76  mutable std::vector<std::string> listnames;
77  // copy of list of names, used solely due to AvailableFluxDrivers()
78  // method returning a const reference rather than a vector object.
79  // mutable because AvailableFluxDrivers() is const, but list might
80  // need recreation if new entries have been registered.
81 
82 private:
84  // private ctor, users access class via Instance()
85 
86  virtual ~GFluxDriverFactory();
87 
89  // method private and not implement, declared to prevent copying
90 
91  void operator=(const GFluxDriverFactory&);
92  // method private and not implement, declared to prevent assignment
93 
94  // sub-class Cleaner struct is used to clean up singleton at the end of job.
95  struct Cleaner {
96  void UseMe() { } // Dummy method to quiet compiler
101  } } };
102  friend struct Cleaner;
103 
104 };
105 
106 } // namespace flux
107 } // namespcae genie
108 
109 // Define macro to create a function to call the class' ctor
110 // and then registers this function with the factory instance for later use
111 // Users should have in their MyFluxClass.cc two lines that look like:
112 // #include "GFluxDriverFactory.h"
113 // FLUXDRIVERREG(MyFluxClass) // no semicolon
114 // where "MyFluxClass" is the name of the class (assuming no special namespace)
115 // If the class is defined in a namespace (or two) use:
116 // #include "GFluxDriverFactory.h"
117 // FLUXDRIVERREG3(myspace,myAltFlux,myspace::myAltFlux) // no semicolon
118 // FLUXDRIVERREG4(genie,flux,YAFlux,genie::flux::YAFlux) // no semicolon
119 // and either can then be retrieved from the factory using:
120 // genie::flux::GFluxDriverFactory& factory =
121 // genie::flux::GFluxDriverFactory::Instance();
122 // genie::GFluxI* p = 0;
123 // p = factory.GetFluxDriver("MyFluxClass");
124 // p = factory.GetFluxDriver("myspace::myAltFlux");
125 // p = factory.GetFluxDriver("genie::flux::YAFlux");
126 //
127 // The expanded code looks like:
128 // genie::GFluxI* MyFluxClass_ctor_function () { return new MyFluxClass; }
129 // static bool MyFluxClass_creator_registered =
130 // GFluxDriverFactory::Instance().RegisterCreator("MyFluxClass",
131 // & MyFluxClass_ctor_function );
132 // namespace myspace {
133 // genie::GFluxI* myAltAltFlux_ctor_function () { return new myspace::myAltAltFlux; }
134 // static bool myAltFlux_creator_registered =
135 // GFluxDriverFactory::Instance().RegisterCreator("myspace::myAltAltFlux",
136 // & myspace::myAltAltFlux_ctor_function ); }
137 
138 #define FLUXDRIVERREG( _name ) \
139  genie::GFluxI* _name ## _ctor_function () { return new _name; } \
140  static bool _name ## _creator_registered = \
141  genie::flux::GFluxDriverFactory::Instance().RegisterCreator(# _name, \
142  & _name ## _ctor_function, \
143  & _name ## _creator_registered );
144 
145 #define FLUXDRIVERREG3( _ns, _name, _fqname ) \
146 namespace _ns { \
147  genie::GFluxI* _name ## _ctor_function () { return new _fqname; } \
148  static bool _name ## _creator_registered = \
149  genie::flux::GFluxDriverFactory::Instance().RegisterCreator(# _fqname, \
150  & _fqname ## _ctor_function, \
151  & _fqname ## _creator_registered );}
152 
153 #define FLUXDRIVERREG4( _nsa, _nsb, _name, _fqname ) \
154 namespace _nsa { \
155  namespace _nsb { \
156  genie::GFluxI* _name ## _ctor_function () { return new _fqname; } \
157  static bool _name ## _creator_registered = \
158  genie::flux::GFluxDriverFactory::Instance().RegisterCreator(# _fqname, \
159  & _fqname ## _ctor_function, \
160  & _fqname ## _creator_registered );}}
161 #endif
static GFluxDriverFactory * fgTheInstance
const std::vector< std::string > & AvailableFluxDrivers() const
std::vector< std::string > listnames
A class for generating concrete GFluxI derived classes based on the factory pattern. This code supplies a CPP macro which allows the classes to self-register and thus no modification of this class is needed in order to expand the list of classes it knows about.
static GFluxDriverFactory & Instance()
std::map< std::string, GFluxICtorFuncPtr_t > fFunctionMap
bool RegisterCreator(std::string name, GFluxICtorFuncPtr_t ctorptr, bool *ptr)
std::map< std::string, bool * > fBoolPtrMap
bool IsKnownFluxDriver(const std::string &)
genie::GFluxI *(* GFluxICtorFuncPtr_t)()
void operator=(const GFluxDriverFactory &)
genie::GFluxI * GetFluxDriver(const std::string &)
GENIE Interface for user-defined flux classes.
Definition: GFluxI.h:29