-
Notifications
You must be signed in to change notification settings - Fork 38
/
Copy pathbind_by_lambda.hpp
69 lines (59 loc) · 1.98 KB
/
bind_by_lambda.hpp
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
/**
* Copyright Quadrivium LLC
* All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <boost/di/extension/scopes/shared.hpp>
namespace kagome::injector {
/**
* Creates single instance per injector.
*
* `boost::di::bind<T>.to(callable)` is hardcoded to
* `boost::di::scopes::instance` and prevents scope redefinition with
* `.in(scope)`.
*
* `callable` will be called more than once. Caching result with `static` will
* behave like `boost::di::scopes::singleton`.
*
* `BindByLambda` wraps `boost::di::extension::shared` to create single
* instance per injector, and adds `callable` support from
* `boost::di::scopes::instance`.
*/
struct BindByLambda {
template <typename F, typename Provider>
struct ProviderF {
auto get() const {
return f(provider.super());
}
F &f;
const Provider &provider;
};
template <typename T, typename F>
struct scope {
explicit scope(const F &f) : f_{f} {}
template <typename, typename>
using is_referable = std::true_type;
template <typename, typename, typename Provider>
static boost::di::wrappers::shared<boost::di::extension::detail::shared,
T>
try_create(const Provider &provider);
template <typename, typename, typename Provider>
auto create(const Provider &provider) & {
return base_.template create<void, void>(
ProviderF<F, Provider>{f_, provider});
}
template <typename, typename, typename Provider>
auto create(const Provider &provider) && {
return std::move(base_).template create<void, void>(
ProviderF<F, Provider>{f_, provider});
}
boost::di::extension::detail::shared::scope<void, T> base_;
F f_;
};
};
template <typename T, typename F>
auto bind_by_lambda(const F &f) {
return boost::di::core::dependency<BindByLambda, T, F>{f};
}
} // namespace kagome::injector