|
@@ -44,11 +44,15 @@ public:
|
|
size_t amount() const; // amount
|
|
size_t amount() const; // amount
|
|
void push(T element);
|
|
void push(T element);
|
|
std::optional<T> pop();
|
|
std::optional<T> pop();
|
|
|
|
+ std::optional<T> tryPop();
|
|
std::optional<T> peek();
|
|
std::optional<T> peek();
|
|
std::optional<T> exchange(T element);
|
|
std::optional<T> exchange(T element);
|
|
bool wait(const std::optional<std::chrono::milliseconds> &duration = nullopt);
|
|
bool wait(const std::optional<std::chrono::milliseconds> &duration = nullopt);
|
|
|
|
|
|
private:
|
|
private:
|
|
|
|
+ void pushImpl(T element);
|
|
|
|
+ std::optional<T> popImpl();
|
|
|
|
+
|
|
const size_t mLimit;
|
|
const size_t mLimit;
|
|
size_t mAmount;
|
|
size_t mAmount;
|
|
std::queue<T> mQueue;
|
|
std::queue<T> mQueue;
|
|
@@ -99,43 +103,32 @@ template <typename T> size_t Queue<T>::amount() const {
|
|
template <typename T> void Queue<T>::push(T element) {
|
|
template <typename T> void Queue<T>::push(T element) {
|
|
std::unique_lock lock(mMutex);
|
|
std::unique_lock lock(mMutex);
|
|
mPushCondition.wait(lock, [this]() { return !mLimit || mQueue.size() < mLimit || mStopping; });
|
|
mPushCondition.wait(lock, [this]() { return !mLimit || mQueue.size() < mLimit || mStopping; });
|
|
- if (!mStopping) {
|
|
|
|
- mAmount += mAmountFunction(element);
|
|
|
|
- mQueue.emplace(std::move(element));
|
|
|
|
- mPopCondition.notify_one();
|
|
|
|
- }
|
|
|
|
|
|
+ pushImpl(std::move(element));
|
|
}
|
|
}
|
|
|
|
|
|
template <typename T> std::optional<T> Queue<T>::pop() {
|
|
template <typename T> std::optional<T> Queue<T>::pop() {
|
|
std::unique_lock lock(mMutex);
|
|
std::unique_lock lock(mMutex);
|
|
mPopCondition.wait(lock, [this]() { return !mQueue.empty() || mStopping; });
|
|
mPopCondition.wait(lock, [this]() { return !mQueue.empty() || mStopping; });
|
|
- if (!mQueue.empty()) {
|
|
|
|
- mAmount -= mAmountFunction(mQueue.front());
|
|
|
|
- std::optional<T> element{std::move(mQueue.front())};
|
|
|
|
- mQueue.pop();
|
|
|
|
- return element;
|
|
|
|
- } else {
|
|
|
|
- return nullopt;
|
|
|
|
- }
|
|
|
|
|
|
+ return popImpl();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+template <typename T> std::optional<T> Queue<T>::tryPop() {
|
|
|
|
+ std::unique_lock lock(mMutex);
|
|
|
|
+ return popImpl();
|
|
}
|
|
}
|
|
|
|
|
|
template <typename T> std::optional<T> Queue<T>::peek() {
|
|
template <typename T> std::optional<T> Queue<T>::peek() {
|
|
std::unique_lock lock(mMutex);
|
|
std::unique_lock lock(mMutex);
|
|
- if (!mQueue.empty()) {
|
|
|
|
- return std::optional<T>{mQueue.front()};
|
|
|
|
- } else {
|
|
|
|
- return nullopt;
|
|
|
|
- }
|
|
|
|
|
|
+ return !mQueue.empty() ? std::make_optional(mQueue.front()) : nullopt;
|
|
}
|
|
}
|
|
|
|
|
|
template <typename T> std::optional<T> Queue<T>::exchange(T element) {
|
|
template <typename T> std::optional<T> Queue<T>::exchange(T element) {
|
|
std::unique_lock lock(mMutex);
|
|
std::unique_lock lock(mMutex);
|
|
- if (!mQueue.empty()) {
|
|
|
|
- std::swap(mQueue.front(), element);
|
|
|
|
- return std::optional<T>{element};
|
|
|
|
- } else {
|
|
|
|
|
|
+ if (mQueue.empty())
|
|
return nullopt;
|
|
return nullopt;
|
|
- }
|
|
|
|
|
|
+
|
|
|
|
+ std::swap(mQueue.front(), element);
|
|
|
|
+ return std::make_optional(std::move(element));
|
|
}
|
|
}
|
|
|
|
|
|
template <typename T>
|
|
template <typename T>
|
|
@@ -145,7 +138,27 @@ bool Queue<T>::wait(const std::optional<std::chrono::milliseconds> &duration) {
|
|
mPopCondition.wait_for(lock, *duration, [this]() { return !mQueue.empty() || mStopping; });
|
|
mPopCondition.wait_for(lock, *duration, [this]() { return !mQueue.empty() || mStopping; });
|
|
else
|
|
else
|
|
mPopCondition.wait(lock, [this]() { return !mQueue.empty() || mStopping; });
|
|
mPopCondition.wait(lock, [this]() { return !mQueue.empty() || mStopping; });
|
|
- return !mStopping;
|
|
|
|
|
|
+
|
|
|
|
+ return !mQueue.empty();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+template <typename T> void Queue<T>::pushImpl(T element) {
|
|
|
|
+ if (mStopping)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ mAmount += mAmountFunction(element);
|
|
|
|
+ mQueue.emplace(std::move(element));
|
|
|
|
+ mPopCondition.notify_one();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+template <typename T> std::optional<T> Queue<T>::popImpl() {
|
|
|
|
+ if (mQueue.empty())
|
|
|
|
+ return nullopt;
|
|
|
|
+
|
|
|
|
+ mAmount -= mAmountFunction(mQueue.front());
|
|
|
|
+ std::optional<T> element{std::move(mQueue.front())};
|
|
|
|
+ mQueue.pop();
|
|
|
|
+ return element;
|
|
}
|
|
}
|
|
|
|
|
|
} // namespace rtc
|
|
} // namespace rtc
|