buffer.hpp 2.54 KB
/*
 * @Author: yangzilong
 * @Date: 2021-11-30 11:09:25
 * @Last Modified by: yangzilong
 * @Last Modified time: Do not edit
 * @Email: yangzilong@objecteye.com
 * @Description:
 */
#pragma once

#include <mutex>
#include <queue>
#include <memory>
#include <condition_variable>


namespace helpers
{
    namespace buffer
    {

        template<typename T>
        class basic_thread_safe_queue
        {
        /**
         * @brief thread safe data buffer.
         * */
        public:
            /* remove copy construct and copy assignment. */
            basic_thread_safe_queue(const basic_thread_safe_queue&) = delete;
            basic_thread_safe_queue& operator=(const basic_thread_safe_queue&) = delete;


            basic_thread_safe_queue()
            {}

            ~basic_thread_safe_queue()
            {}

            bool push(const T &data)
            {
                std::lock_guard<std::mutex> lk(mutex_);
                data_queue_.push(data);
            }

            bool push(T &&data)
            {
                std::lock_guard<std::mutex> lk(mutex_);
                data_queue_.push(std::move(data));
                cv_.notify_one();
            }

            bool try_pop(T &data)
            {
                std::lock_guard<std::mutex> lk(mutex_);
                if (data_queue_.empty())
                    return false;
                data = std::move(data_queue_.front());
                data_queue_.pop();
                return true;
            }

            bool wait_and_pop(T &data)
            {
                std::unique_lock<std::mutex> lk(mutex_);
                cv_.wait(lk, [this] {return !data_queue_.empty()});
                data = data_queue_.front();
                data_queue_.pop();
            }

            std::shared_ptr<T> get()
            {
                std::lock_guard<std::mutex> lk(mutex_);
                if (data_queue_.empty())
                    return std::shared_ptr<T>();
                std::shared_ptr<T> res(std::make_shared<T>(data_queue_.front()));
                data_queue_.pop();
                return res;
            }

            int size() const
            {
                std::lock_guard<std::mutex> lk(mutex_);
                return data_queue_.size();
            }


            int empty() const
            {
                return data_queue_.size() == 0;
            }

        private:
            mutable std::mutex mutex_;
            std::queue<T> data_queue_;
            std::condition_variable cv_;

        };


    }  // namespace buffer
}  // namespace helpers