1 | // Copyright (C) 2020 The Qt Company Ltd. |
---|---|
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 |
3 | |
4 | #ifndef SYNCHRONIZED_H |
5 | #define SYNCHRONIZED_H |
6 | |
7 | #include <QtCore/qmutex.h> |
8 | |
9 | #include <atomic> |
10 | #include <vector> |
11 | |
12 | QT_BEGIN_NAMESPACE |
13 | |
14 | template<typename T> class WriteSynchronizedRef |
15 | { |
16 | Q_DISABLE_COPY_MOVE(WriteSynchronizedRef) |
17 | |
18 | public: |
19 | WriteSynchronizedRef(std::vector<T> &vector) Q_DECL_NOEXCEPT |
20 | : m_vector(vector) |
21 | {} |
22 | |
23 | void emplace_back(T &&value) |
24 | { |
25 | QMutexLocker lock(&m_mutex); |
26 | m_vector.push_back(std::move(value)); |
27 | } |
28 | |
29 | void emplace_back(const T &value) |
30 | { |
31 | QMutexLocker lock(&m_mutex); |
32 | m_vector.emplace_back(value); |
33 | } |
34 | |
35 | void emplace_bulk(std::vector<T> && values) |
36 | { |
37 | QMutexLocker lock(&m_mutex); |
38 | if (!m_vector.empty()) { |
39 | m_vector.insert(m_vector.cend(), std::make_move_iterator(values.begin()), |
40 | std::make_move_iterator(values.end())); |
41 | } else { |
42 | m_vector = std::move(values); |
43 | } |
44 | } |
45 | |
46 | private: |
47 | mutable QMutex m_mutex; |
48 | std::vector<T> &m_vector; |
49 | }; |
50 | |
51 | template<typename T> class ReadSynchronizedRef |
52 | { |
53 | Q_DISABLE_COPY_MOVE(ReadSynchronizedRef) |
54 | |
55 | public: |
56 | ReadSynchronizedRef(const std::vector<T> &v) noexcept |
57 | : m_vector(v) |
58 | {} |
59 | |
60 | size_t size() const |
61 | { |
62 | return m_vector.size(); |
63 | } |
64 | |
65 | bool next(T *value) const |
66 | { |
67 | const auto idx = m_next.fetch_add(i: 1, m: std::memory_order_acquire); |
68 | const bool hasNext = idx < m_vector.size(); |
69 | if (hasNext) |
70 | *value = m_vector[idx]; |
71 | return hasNext; |
72 | } |
73 | |
74 | private: |
75 | const std::vector<T> &m_vector; |
76 | mutable std::atomic<size_t> m_next = 0; |
77 | }; |
78 | |
79 | QT_END_NAMESPACE |
80 | |
81 | #endif |
82 |