@@ -14,42 +14,73 @@ namespace sd
14
14
class DependencyInjector
15
15
{
16
16
private:
17
- template <class T > struct Constructor
17
+ template <typename T> struct FunctionTraits ;
18
+
19
+ template <typename R, typename ... Args> struct FunctionTraits <std::function<R(Args...)>>
18
20
{
19
- T ctor;
20
- Constructor (T ctor) : ctor(ctor) {}
21
+ static const size_t nargs = sizeof ...(Args);
22
+
23
+ typedef R result_type;
24
+
25
+ template <size_t i> struct arg
26
+ {
27
+ typedef typename std::tuple_element<i, std::tuple<Args...>>::type type;
28
+ };
21
29
};
22
30
23
31
struct IConstructionInfo
24
32
{
25
33
virtual std::type_index getTypeIndex () const = 0;
26
34
27
- virtual const std::vector<std::type_index> & getParamsTypeIndexes () const = 0;
35
+ virtual const std::vector<std::type_index> getParamsTypeIndexes () const = 0;
28
36
29
37
virtual void *construct (const std::vector<void *> ¶ms) const = 0;
30
38
31
39
virtual ~IConstructionInfo () {}
32
40
};
33
41
34
- template <class Type , class Param1 > class ConstructionInfo final : public IConstructionInfo
42
+ template <typename R, typename ... Args > class ConstructionInfo final : public IConstructionInfo
35
43
{
36
44
private:
37
- std::type_index _typeIndex = typeid (Type);
38
- std::vector<std::type_index> _params;
39
- Type *(*_ctor)(Param1 *);
45
+ using ConstructorTraits = FunctionTraits<std::function<R(Args...)>>;
46
+ std::function<R(Args...)> _constructor;
40
47
41
48
public:
42
- ConstructionInfo (Constructor<Type *(*)(Param1 *)> constructor)
43
- {
44
- _ctor = constructor.ctor ;
45
- _params = {typeid (Param1)};
46
- }
49
+ ConstructionInfo (const std::function<R(Args...)> &constructor) { _constructor = constructor; }
47
50
48
- std::type_index getTypeIndex () const { return _typeIndex ; }
51
+ std::type_index getTypeIndex () const { return typeid ( typename ConstructorTraits::result_type) ; }
49
52
50
- const std::vector<std::type_index> &getParamsTypeIndexes () const { return _params; };
53
+ const std::vector<std::type_index> getParamsTypeIndexes () const
54
+ {
55
+ if constexpr (ConstructorTraits::nargs == 0 )
56
+ {
57
+ return {};
58
+ }
59
+ else if constexpr (ConstructorTraits::nargs == 1 )
60
+ {
61
+ return {typeid (typename ConstructorTraits::template arg<0 >::type)};
62
+ }
63
+ else if constexpr (ConstructorTraits::nargs == 2 )
64
+ {
65
+ return {typeid (typename ConstructorTraits::template arg<0 >::type),
66
+ typeid (typename ConstructorTraits::template arg<1 >::type)};
67
+ }
68
+ };
51
69
52
- void *construct (const std::vector<void *> ¶ms) const { return (*_ctor)((Param1 *)params[0 ]); };
70
+ void *construct (const std::vector<void *> ¶ms) const
71
+ {
72
+ if constexpr (ConstructorTraits::nargs == 0 )
73
+ {
74
+ return _constructor ();
75
+ }
76
+ else if constexpr (ConstructorTraits::nargs == 1 )
77
+ {
78
+ return _constructor ((typename ConstructorTraits::template arg<0 >::type)(params[0 ]));
79
+ }
80
+ else if constexpr (ConstructorTraits::nargs == 2 )
81
+ {
82
+ }
83
+ };
53
84
};
54
85
55
86
private:
@@ -60,12 +91,12 @@ namespace sd
60
91
template <class I , class T > void addSingeleton ()
61
92
{
62
93
// todo check if T inherits from/implements I
63
- auto cons = Constructor{ T::constructor};
64
- auto i = new ConstructionInfo (cons );
65
- _registered.insert ({typeid (I), std::unique_ptr<IConstructionInfo>(i)});
94
+ std::function< decltype (T::constructor)> ff{& T::constructor};
95
+ auto i = new ConstructionInfo (ff );
96
+ _registered.insert ({typeid (I * ), std::unique_ptr<IConstructionInfo>(i)});
66
97
}
67
98
68
- template <class I > I *get () { return (I *)get (typeid (I)); }
99
+ template <class I > I *get () { return (I *)get (typeid (I * )); }
69
100
70
101
void build ()
71
102
{
@@ -113,7 +144,15 @@ namespace sd
113
144
IConstructionInfo *getRegistered (std::type_index index)
114
145
{
115
146
auto pair = _registered.find (index );
116
- return pair != _registered.end () ? pair->second .get () : nullptr ;
147
+ if (pair != _registered.end ())
148
+ {
149
+ auto &ob = pair->second ;
150
+ return ob.get ();
151
+ }
152
+ else
153
+ {
154
+ return nullptr ;
155
+ }
117
156
}
118
157
};
119
158
} // namespace sd
0 commit comments