Sauce-0.10.1: sauce/internal/clause.h Source File

Sauce-0.10.1 A C++ Dependency Injection Framework

- Main Page
- Classes
- Files

- File List

clause.h
1 #ifndef SAUCE_CLAUSE_H_
2 #define SAUCE_CLAUSE_H_
3
4 #include <string>
5 #include <vector>
6
7 #include <sauce/exceptions.h>
8 #include <sauce/memory.h>
9 #include <sauce/named.h>
10 #include <sauce/internal/bindings.h>
11 #include <sauce/internal/instance_binding.h>
12 #include <sauce/internal/method_binding.h>
13 #include <sauce/internal/new_binding.h>
14 #include <sauce/internal/opaque_binding.h>
15 #include <sauce/internal/pending_thrower.h>
16 #include <sauce/internal/provider_binding.h>
17
18 namespace sauce {
19 namespace internal {
20
21 class ImplicitBindings;
22
26 class ClauseState {
27 Bindings<ImplicitBindings> & bindings;
28 PendingThrower & pendingThrower;
29 OpaqueBindingPtr pendingBinding;
30 OpaqueBindingPtr providerBinding;
31 std::string dynamicName;
32 std::vector<std::string> dynamicDependencyNames;
33
34 public:
35
36 ClauseState(Bindings<ImplicitBindings> & bindings, PendingThrower & pendingThrower):
37 bindings(bindings),
38 pendingThrower(pendingThrower),
39 pendingBinding(),
40 providerBinding(),
41 dynamicName(unnamed()),
42 dynamicDependencyNames() {
43 pendingThrower.throwAnyPending();
44 }
45
46 virtual ~ClauseState() {
47 if (pendingBinding.get() == NULL) {
48 return;
49 }
50
51 pendingBinding->setName(dynamicName);
52 pendingBinding->setDynamicDependencyNames(dynamicDependencyNames);
53
54 if (pendingBinding.get() != NULL) {
55 bindings.put(pendingBinding);
56 }
57
58 if (providerBinding.get() != NULL) {
59 bindings.put(providerBinding);
60 }
61 }
62
63 void bind(OpaqueBindingPtr pendingBinding) {
64 this->pendingBinding = pendingBinding;
65 }
66
67 void bindProvider(OpaqueBindingPtr providerBinding) {
68 this->providerBinding = providerBinding;
69 }
70
71 void setDynamicName(std::string const name) {
72 this->dynamicName = name;
73 }
74
75 void bindDynamicDependencyName(unsigned int position, std::string const name) {
76 if (dynamicDependencyNames.size() <= position) {
77 dynamicDependencyNames.resize(position + 1, unnamed());
78 }
79 dynamicDependencyNames[position] = name;
80 }
81
82 template<typename Exception>
83 void throwLater() {
84 pendingThrower.template throwLater<Exception>();
85 }
86
87 void clearException() {
88 pendingThrower.clear();
89 }
90 };
91
92 typedef sauce::shared_ptr<ClauseState> ClauseStatePtr;
93
97 template<typename Dependency>
98 class Clause {
99 ClauseStatePtr state;
100
101 protected:
102
103 virtual void onComplete() {
104 throwLater(PartialBindingExceptionFor<Dependency>());
105 }
106
107 Clause():
108 state() {}
109
110 Clause(ClauseStatePtr state):
111 state(state) {
112 throwLater(PartialBindingExceptionFor<Dependency>());
113 }
114
115 ClauseStatePtr getState() {
116 return state;
117 }
118
119 template<typename Next>
120 Next pass(Next next) {
121 next.setState(state);
122 return next;
123 }
124
125 void setDynamicName(std::string const name) {
126 state->setDynamicName(name);
127 }
128
129 template<typename Exception>
130 void throwLater(Exception) {
131 state->template throwLater<Exception>();
132 }
133
134 void bindDynamicDependencyName(unsigned int position, std::string const name) {
135 state->bindDynamicDependencyName(position, name);
136 }
137
138 public:
139
140 virtual ~Clause() {}
141
142 Clause<Dependency> & naming(unsigned int position, std::string const name) {
143 this->bindDynamicDependencyName(position, name);
144 return *this;
145 }
146
147 void setState(ClauseStatePtr state) {
148 this->state = state;
149 getState()->clearException();
150 onComplete();
151 }
152 };
153
154 }
155
156 namespace i = ::sauce::internal;
157
158 }
159
160 #endif // SAUCE_CLAUSE_H_