1 #ifndef SAUCE_INTERNAL_NEW_BINDING_H_
2 #define SAUCE_INTERNAL_NEW_BINDING_H_
4 #include <sauce/injector.h>
5 #include <sauce/memory.h>
6 #include <sauce/named.h>
7 #include <sauce/provider.h>
8 #include <sauce/internal/apply_variadic.h>
9 #include <sauce/internal/binding.h>
10 #include <sauce/internal/key.h>
11 #include <sauce/internal/resolved_binding.h>
12 #include <sauce/internal/self_injector.h>
13 #include <sauce/internal/type_id.h>
18 template<
typename Dependency,
typename Scope,
typename Constructor,
typename Allocator>
26 struct NewBindingFriend {
28 void validateAcyclicHelper(
NewBinding_ const & binding, InjectorPtr injector, TypeIds & ids, std::string name) {
29 binding.template validateAcyclicHelper<T>(injector, ids, name);
33 typename Key<T>::Ptr injectHelper(
NewBinding_ const & binding, InjectorPtr injector, std::string name) {
34 typename Key<T>::Ptr injected;
35 binding.template injectHelper<typename i::Key<T>::Normalized>(injected, injector, name);
40 friend class NewBindingFriend;
42 struct InjectParameters {
45 InjectorPtr & injector;
48 binding(binding), injector(injector) {}
51 template<
typename T,
int i>
53 typedef typename Key<T>::Ptr Type;
55 template<
typename Passed>
56 Type yield(
Passed passed) {
58 InjectorPtr & injector = passed.injector;
59 std::string dependencyName = binding.dynamicDependencyNames[i];
61 return this->NewBindingFriend::template injectHelper<T>(binding, injector, dependencyName);
67 typedef typename Inject::Constructed Impl;
70 typedef sauce::shared_ptr<Impl> ImplPtr;
73 std::vector<std::string> dynamicDependencyNames;
75 struct ValidateAcyclicParameters {
78 InjectorPtr & injector;
82 binding(binding), injector(injector), ids(ids) {}
85 template<
typename T,
int i>
87 template<
typename Passed>
88 void observe(
Passed passed) {
90 InjectorPtr & injector = passed.injector;
91 TypeIds & ids = passed.ids;
92 std::string dependencyName = binding.dynamicDependencyNames[i];
94 this->NewBindingFriend::template validateAcyclicHelper<T>(binding, injector, ids, dependencyName);
99 void validateAcyclic(InjectorPtr injector, TypeIds & ids)
const {
101 observeConstructor<ValidateAcyclicParameters, Constructor, Allocator>(passed);
104 void setDynamicDependencyNames(std::vector<std::string>
const & dynamicDependencyNames) {
105 this->dynamicDependencyNames = dynamicDependencyNames;
106 this->dynamicDependencyNames.resize(Inject::arity(), unnamed());
111 typedef typename ResolvedBinding<Dependency>::BindingPtr BindingPtr;
114 dynamicDependencyNames(Inject::arity(), unnamed()) {}
123 void inject(IfacePtr & injected, BindingPtr binding, InjectorPtr injector)
const {
125 Deleter deleter(sauce::static_pointer_cast<NewBinding_>(binding));
126 ImplPtr impl(applyConstructor<InjectParameters, Constructor, Allocator>(passed), deleter);
128 selfInjector.setSelf(impl);
130 this->
template injectHelper<NormalizedImpl>(impl, injector, this->
getName());
131 injected = sauce::static_pointer_cast<Iface>(impl);
134 void dispose(Iface * iface)
const {
135 typedef typename Allocator::template rebind<Impl>::other ImplAllocator;
136 ImplAllocator allocator;
137 Impl * impl =
static_cast<Impl *
>(iface);
139 allocator.deallocate(impl, 1);
146 namespace i = ::sauce::internal;
150 #endif // SAUCE_INTERNAL_NEW_BINDING_H_