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
12QT_BEGIN_NAMESPACE
13
14template<typename T> class WriteSynchronizedRef
15{
16 Q_DISABLE_COPY_MOVE(WriteSynchronizedRef)
17
18public:
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
46private:
47 mutable QMutex m_mutex;
48 std::vector<T> &m_vector;
49};
50
51template<typename T> class ReadSynchronizedRef
52{
53 Q_DISABLE_COPY_MOVE(ReadSynchronizedRef)
54
55public:
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
74private:
75 const std::vector<T> &m_vector;
76 mutable std::atomic<size_t> m_next = 0;
77};
78
79QT_END_NAMESPACE
80
81#endif
82

source code of qttools/src/linguist/lupdate/synchronized.h