Nix 2.93.3
Lix: A modern, delicious implementation of the Nix package manager; unstable internal interfaces
Loading...
Searching...
No Matches
notifying-counter.hh
Go to the documentation of this file.
1#pragma once
3
4#include <cassert>
5#include <functional>
6#include <memory>
7
8namespace nix {
9
10template<std::integral T>
11class NotifyingCounter
12{
13private:
14 T counter;
15 std::function<void()> notify;
16
17public:
18 class Bump
19 {
20 friend class NotifyingCounter;
21
22 struct SubOnFree
23 {
24 T delta;
25
26 void operator()(NotifyingCounter * c) const
27 {
28 c->add(-delta);
29 }
30 };
31
32 // lightly misuse unique_ptr to get RAII types with destructor callbacks
33 std::unique_ptr<NotifyingCounter<T>, SubOnFree> at;
34
35 Bump(NotifyingCounter<T> & at, T delta) : at(&at, {delta}) {}
36
37 public:
38 Bump() = default;
39 Bump(decltype(nullptr)) {}
40
41 T delta() const
42 {
43 return at ? at.get_deleter().delta : 0;
44 }
45
46 void reset()
47 {
48 at.reset();
49 }
50 };
51
52 explicit NotifyingCounter(std::function<void()> notify, T initial = 0)
53 : counter(initial)
54 , notify(std::move(notify))
55 {
56 assert(this->notify);
57 }
58
59 // bumps hold pointers to this, so we should neither copy nor move.
60 NotifyingCounter(const NotifyingCounter &) = delete;
61 NotifyingCounter & operator=(const NotifyingCounter &) = delete;
63 NotifyingCounter & operator=(NotifyingCounter &&) = delete;
64
65 T get() const
66 {
67 return counter;
68 }
69
70 operator T() const
71 {
72 return counter;
73 }
74
75 void add(T delta)
76 {
77 counter += delta;
78 notify();
79 }
80
81 NotifyingCounter & operator+=(T delta)
82 {
83 add(delta);
84 return *this;
85 }
86
87 NotifyingCounter & operator++(int)
88 {
89 return *this += 1;
90 }
91
92 Bump addTemporarily(T delta)
93 {
94 add(delta);
95 return Bump{*this, delta};
96 }
97};
98
99}
Definition notifying-counter.hh:19
Definition notifying-counter.hh:12