1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
// Copyright (C) by Josh Blum. See LICENSE.txt for licensing information.
#ifndef INCLUDED_GRAS_DETAIL_FACTORY_HPP
#define INCLUDED_GRAS_DETAIL_FACTORY_HPP
#include <PMC/Containers.hpp> //PMCList
namespace gras
{
/***********************************************************************
* Factory entry base class
**********************************************************************/
struct GRAS_API FactoryRegistryEntry
{
FactoryRegistryEntry(void);
virtual ~FactoryRegistryEntry(void);
virtual Element *make(const PMCC &args) = 0;
};
/***********************************************************************
* Templated registration - 0 args
**********************************************************************/
template <typename ReturnType>
struct FactoryRegistryEntryImpl0 : FactoryRegistryEntry
{
typedef ReturnType(*Fcn)(void);
FactoryRegistryEntryImpl0(Fcn fcn):_fcn(fcn){}
Element *make(const PMCC &)
{
return _fcn();
}
Fcn _fcn;
};
template <typename ReturnType>
void Factory::register_make(const std::string &name, ReturnType(*fcn)(void))
{
void *r = new FactoryRegistryEntryImpl0<ReturnType>(fcn);
Factory::_register_make(name, r);
}
/***********************************************************************
* Templated registration - 1 args
**********************************************************************/
template <typename ReturnType, typename Arg0>
struct FactoryRegistryEntryImpl1 : FactoryRegistryEntry
{
typedef ReturnType(*Fcn)(const Arg0 &);
FactoryRegistryEntryImpl1(Fcn fcn):_fcn(fcn){}
Element *make(const PMCC &args)
{
const PMCList &a = args.as<PMCList>();
return _fcn(a[0].safe_as<Arg0>());
}
Fcn _fcn;
};
template <typename ReturnType, typename Arg0>
void Factory::register_make(const std::string &name, ReturnType(*fcn)(const Arg0 &))
{
void *r = new FactoryRegistryEntryImpl1<ReturnType, Arg0>(fcn);
Factory::_register_make(name, r);
}
/***********************************************************************
* Templated registration - 2 args
**********************************************************************/
template <typename ReturnType, typename Arg0, typename Arg1>
struct FactoryRegistryEntryImpl2 : FactoryRegistryEntry
{
typedef ReturnType(*Fcn)(const Arg0 &, const Arg1 &);
FactoryRegistryEntryImpl2(Fcn fcn):_fcn(fcn){}
Element *make(const PMCC &args)
{
const PMCList &a = args.as<PMCList>();
return _fcn(a[0].safe_as<Arg0>(), a[1].safe_as<Arg1>());
}
Fcn _fcn;
};
template <typename ReturnType, typename Arg0, typename Arg1>
void Factory::register_make(const std::string &name, ReturnType(*fcn)(const Arg0 &, const Arg1 &))
{
void *r = new FactoryRegistryEntryImpl2<ReturnType, Arg0, Arg1>(fcn);
Factory::_register_make(name, r);
}
/***********************************************************************
* Templated registration - 3 args
**********************************************************************/
template <typename ReturnType, typename Arg0, typename Arg1, typename Arg2>
struct FactoryRegistryEntryImpl3 : FactoryRegistryEntry
{
typedef ReturnType(*Fcn)(const Arg0 &, const Arg1 &, const Arg2 &);
FactoryRegistryEntryImpl3(Fcn fcn):_fcn(fcn){}
Element *make(const PMCC &args)
{
const PMCList &a = args.as<PMCList>();
return _fcn(a[0].safe_as<Arg0>(), a[1].safe_as<Arg1>(), a[2].safe_as<Arg2>());
}
Fcn _fcn;
};
template <typename ReturnType, typename Arg0, typename Arg1, typename Arg2>
void Factory::register_make(const std::string &name, ReturnType(*fcn)(const Arg0 &, const Arg1 &, const Arg2 &))
{
void *r = new FactoryRegistryEntryImpl3<ReturnType, Arg0, Arg1, Arg2>(fcn);
Factory::_register_make(name, r);
}
/***********************************************************************
* Templated make implementations
**********************************************************************/
inline
Element *Factory::make(const std::string &name)
{
PMCList args(0);
return Factory::_handle_make(name, PMC_M(args));
}
template <typename Arg0>
Element *Factory::make(const std::string &name, const Arg0 &a0)
{
PMCList args(1);
args[0] = PMC_M(a0);
return Factory::_handle_make(name, PMC_M(args));
}
template <typename Arg0, typename Arg1>
Element *Factory::make(const std::string &name, const Arg0 &a0, const Arg1 &a1)
{
PMCList args(2);
args[0] = PMC_M(a0);
args[1] = PMC_M(a1);
return Factory::_handle_make(name, PMC_M(args));
}
template <typename Arg0, typename Arg1, typename Arg2>
Element *Factory::make(const std::string &name, const Arg0 &a0, const Arg1 &a1, const Arg2 &a2)
{
PMCList args(3);
args[0] = PMC_M(a0);
args[1] = PMC_M(a1);
args[2] = PMC_M(a2);
return Factory::_handle_make(name, PMC_M(args));
}
}
#endif /*INCLUDED_GRAS_DETAIL_FACTORY_HPP*/
|