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