10#include <userver/compiler/impl/lifetime.hpp>
11#include <userver/components/component_fwd.hpp>
12#include <userver/utils/assert.hpp>
13#include <userver/utils/move_only_function.hpp>
15USERVER_NAMESPACE_BEGIN
22 virtual ~ScopeBase() =
default;
24 virtual void AfterConstruction() = 0;
27template <
typename Handle>
28class Scope
final :
public ScopeBase {
30 using AfterConstructionCallback =
utils::move_only_function<Handle()>;
32 explicit Scope(AfterConstructionCallback after_construction)
33 : after_construction_(std::move(after_construction))
36 void AfterConstruction()
override { before_destruction_.emplace(after_construction_()); }
39 AfterConstructionCallback after_construction_;
40 std::optional<Handle> before_destruction_;
44class Scope<
void>
final :
public ScopeBase {
46 using AfterConstructionCallback =
utils::move_only_function<
void()>;
48 explicit Scope(AfterConstructionCallback after_construction)
49 : after_construction_(std::move(after_construction))
52 void AfterConstruction()
override { after_construction_(); }
55 AfterConstructionCallback after_construction_;
62using ScopePtr = std::unique_ptr<impl::ScopeBase>;
85class ResourceScopeStorage
final {
87 ResourceScopeStorage() =
default;
89 ResourceScopeStorage(ResourceScopeStorage&& other)
noexcept =
default;
90 ResourceScopeStorage& operator=(ResourceScopeStorage&& other)
noexcept =
default;
104 template <
std::invocable<> AfterConstructionCallback>
105 void Register(AfterConstructionCallback after_construction)
107 using Handle = std::invoke_result_t<AfterConstructionCallback>;
108 auto scope = std::make_unique<impl::Scope<Handle>>(std::move(after_construction));
109 DoRegister(std::move(scope));
119 void DoRegister(impl::ScopePtr resource_scope);
121 std::vector<impl::ScopePtr> registered_scopes_;
122 std::vector<impl::ScopePtr> initialized_scopes_;
123 bool scope_registration_finished_{
false};
129template <
typename Wrapped>
130class WithResourceScopes
final {
134 template <
typename... Args>
136 : wrapped_(resource_scope_storage_, std::forward<Args>(args)...)
141 WithResourceScopes(WithResourceScopes&& other)
noexcept =
default;
142 WithResourceScopes& operator=(WithResourceScopes&& other)
noexcept =
default;
147 Wrapped&
operator*() &
noexcept USERVER_IMPL_LIFETIME_BOUND {
return wrapped_; }
149 const Wrapped&
operator*()
const&
noexcept USERVER_IMPL_LIFETIME_BOUND {
return wrapped_; }
152 Wrapped*
operator->()
noexcept USERVER_IMPL_LIFETIME_BOUND {
return &wrapped_; }
154 const Wrapped*
operator->()
const noexcept USERVER_IMPL_LIFETIME_BOUND {
return &wrapped_; }
157 ResourceScopeStorage resource_scope_storage_;