userver: userver/components/scope.hpp Source File
Loading...
Searching...
No Matches
scope.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/components/scope.hpp
4/// @brief @copybrief components::MakeScope
5
6#include <functional>
7#include <memory>
8#include <optional>
9
10#include <userver/utils/assert.hpp>
11
12USERVER_NAMESPACE_BEGIN
13
14namespace components {
15
16namespace impl {
17class ScopeBase {
18public:
19 virtual ~ScopeBase() = default;
20
21 virtual void AfterConstruction() = 0;
22};
23
24template <typename Handle>
25class Scope final : public ScopeBase {
26public:
27 using AfterConstructionCallback = std::function<Handle()>;
28
29 explicit Scope(AfterConstructionCallback after_construction)
30 : after_construction_(std::move(after_construction))
31 {}
32
33 void AfterConstruction() override { before_destruction_.emplace(after_construction_()); }
34
35private:
36 AfterConstructionCallback after_construction_;
37 std::optional<Handle> before_destruction_;
38};
39
40template <>
41class Scope<void> final : public ScopeBase {
42public:
43 using AfterConstructionCallback = std::function<void()>;
44
45 explicit Scope(AfterConstructionCallback after_construction)
46 : after_construction_(std::move(after_construction))
47 {}
48
49 void AfterConstruction() override { after_construction_(); }
50
51private:
52 AfterConstructionCallback after_construction_;
53};
54
55} // namespace impl
56
57/// @brief An object of ScopePtr defines actions to do after
58/// a component is constructed and just before it is destroyed.
59///
60/// @see @ref components::ComponentContext::RegisterScope
61using ScopePtr = std::unique_ptr<impl::ScopeBase>;
62
63/// @brief Constructs an object of type @ref ScopePtr from
64/// a registration callback. The callback must return an object that undoes
65/// the registration in its destructor.
66///
67/// @see @ref components::ComponentContext::RegisterScope
68template <typename AfterConstructionCallback>
69ScopePtr MakeScope(AfterConstructionCallback after_construction)
70{
71 using Handle = std::invoke_result_t<AfterConstructionCallback>;
72 return std::make_unique<impl::Scope<Handle>>(std::move(after_construction));
73}
74
75} // namespace components
76
77USERVER_NAMESPACE_END