stlab 2.3.0
Modern, modular C++ algorithms, data structures, and concurrency primitives
Loading...
Searching...
No Matches
progress.hpp
Go to the documentation of this file.
1/*
2 Copyright 2015 Adobe
3 Distributed under the Boost Software License, Version 1.0.
4 (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5*/
6
7/**************************************************************************************************/
8
9#ifndef STLAB_CONCURRENCY_PROGRESS_HPP
10#define STLAB_CONCURRENCY_PROGRESS_HPP
11
19
20#include <atomic>
21#include <functional>
22#include <memory>
23
24namespace stlab {
25namespace detail {
26
32
33class tracker_server {
34 std::atomic_size_t _task_number = {0};
35 std::atomic_size_t _done_tasks = {0};
36 std::function<void(size_t, size_t)> _signal;
37
38public:
39 tracker_server() = default;
40 tracker_server(std::function<void(size_t, size_t)> f) : _signal(std::move(f)) {}
41
42 void task_done() {
43 ++_done_tasks;
44 if (_signal) {
45 _signal(steps(), completed());
46 }
47 }
48
49 void drop_task() { --_task_number; }
50
51 void add_task() { ++_task_number; }
52
53 size_t steps() const { return _task_number.load(); }
54
55 size_t completed() const { return _done_tasks.load(); }
56};
57
58template <typename F>
59struct tracker_client {
60 F _f;
61 mutable std::weak_ptr<tracker_server> _p;
62
63 tracker_client() = default;
64 tracker_client(const tracker_client& x) : _f(x._f), _p(x._p) {
65 auto p = _p.lock();
66 if (p) p->add_task();
67 }
68
69 tracker_client& operator=(const tracker_client& x) {
70 _f = x._f;
71 _p = x._p;
72 auto p = _p.lock();
73 if (p) p->add_task();
74 return *this;
75 }
76
77 tracker_client(tracker_client&&) = default;
78 tracker_client& operator=(tracker_client&&) = default;
79
80 tracker_client(std::shared_ptr<tracker_server>& p, F&& f) : _f(std::move(f)), _p(p) {
81 p->add_task();
82 }
83
84 ~tracker_client() {
85 auto p = _p.lock();
86 if (p) p->drop_task();
87 }
88
89 template <typename... Args>
90 auto operator()(Args&&... args) const {
91 auto r = _f(args...);
92 auto p = _p.lock();
93 if (p) p->task_done();
94 return r;
95 }
96};
97
99
100} // namespace detail
101
105
107class progress_tracker {
108 std::shared_ptr<detail::tracker_server> _tracker;
109
110public:
111 progress_tracker() : _tracker(std::make_shared<detail::tracker_server>()) {}
112
114 progress_tracker(std::function<void(size_t, size_t)> f) :
115 _tracker(std::make_shared<detail::tracker_server>(std::move(f))) {}
116 progress_tracker(const progress_tracker&) = default;
117 progress_tracker& operator=(const progress_tracker&) = default;
119 progress_tracker& operator=(progress_tracker&&) = default;
120
122 template <typename F>
123 auto operator()(F&& f) {
124 return detail::tracker_client<F>(_tracker, std::forward<F>(f));
125 }
126
128 size_t steps() const { return _tracker->steps(); }
129
131 size_t completed() const { return _tracker->completed(); }
132};
133
135
136} // namespace stlab
137
138#endif
Tracks how many wrapped tasks are in flight and how many have completed.
Definition progress.hpp:107
size_t steps() const
Number of tasks currently registered (in flight or not yet done).
Definition progress.hpp:128
size_t completed() const
Number of wrapped tasks that have finished.
Definition progress.hpp:131
progress_tracker(std::function< void(size_t, size_t)> f)
Constructs a tracker that invokes f(steps(), completed()) when a wrapped task completes.
Definition progress.hpp:114
auto operator()(F &&f)
Returns a wrapper that counts this callable as one step until it returns.
Definition progress.hpp:123
constexpr auto move(T &&t) noexcept -> std::remove_reference_t< T > &&
A standard move implementation but with a compile-time check for const types.
Definition utility.hpp:154
Definition reverse.hpp:28