Advertisement
Guest User

Untitled

a guest
Apr 21st, 2021
42
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.74 KB | None | 0 0
  1. #ifndef _TSDEQUE_HPP_
  2. #define _TSDEQUE_HPP_
  3.  
  4. // System includes
  5. #include <atomic>
  6. #include <condition_variable>
  7. #include <deque>
  8. #include <exception>
  9. #include <iterator>
  10. #include <mutex>
  11. #include <utility>
  12. #include <vector>
  13.  
  14. // Project includes
  15.  
  16. namespace DataStructures
  17. {
  18.  
  19. template<typename T>
  20. class TSDeque
  21. {
  22.     private:
  23.         std::deque<T> m_Deque;
  24.         std::mutex m_DequeMutex;
  25.         std::condition_variable m_WaitBlock;
  26.         std::mutex m_WaitMutex;
  27.  
  28.         std::atomic<bool> m_DisposeCalled;
  29.     public:
  30.         TSDeque(const TSDeque<T>&) = delete;
  31.         TSDeque& operator=(const TSDeque<T>&) = delete;
  32.  
  33.         TSDeque()
  34.             : m_Deque(),
  35.               m_DequeMutex(),
  36.               m_WaitBlock(),
  37.               m_WaitMutex(),
  38.               m_DisposeCalled(false)
  39.         {
  40.         }
  41.  
  42.         TSDeque(TSDeque<T>&& tsDeque)
  43.             : m_Deque(std::move(tsDeque.m_Deque)),
  44.               m_DisposeCalled(false)
  45.         {
  46.         }
  47.  
  48.         TSDeque& operator=(TSDeque<T>&& tsDeque)
  49.         {
  50.             if (this == &tsDeque)
  51.             {
  52.                 return *this;
  53.             }
  54.  
  55.             std::unique_lock<std::mutex> l_ulockDM(m_DequeMutex, std::defer_lock);
  56.             std::unique_lock<std::mutex> ulockDM(tsDeque.m_DequeMutex, std::defer_lock);
  57.             std::lock(l_ulockDM, ulockDM);
  58.  
  59.             m_Deque(std::move(tsDeque.m_Deque));
  60.  
  61.             return *this;
  62.         }
  63.  
  64.         ~TSDeque()
  65.         {
  66.         }
  67.  
  68.         void Dispose()
  69.         {
  70.             m_DisposeCalled = true;
  71.  
  72.             // Terminate waiting.
  73.             m_WaitBlock.notify_all();
  74.         }
  75.  
  76.         void push_back(const T& value)
  77.         {
  78.             std::scoped_lock<std::mutex> lock(m_DequeMutex);
  79.             m_Deque.emplace_back(std::move(value));
  80.  
  81.             std::unique_lock<std::mutex> ulock(m_WaitMutex);
  82.             m_WaitBlock.notify_one();
  83.         }
  84.  
  85.         void push_back(T&& value)
  86.         {
  87.             std::scoped_lock<std::mutex> lock(m_DequeMutex);
  88.             m_Deque.emplace_back(std::move(value));
  89.  
  90.             std::unique_lock<std::mutex> ulock(m_WaitMutex);
  91.             m_WaitBlock.notify_one();
  92.         }
  93.  
  94.         void push_front(const T& value)
  95.         {
  96.             std::scoped_lock<std::mutex> lock(m_DequeMutex);
  97.             m_Deque.emplace_front(std::move(value));
  98.  
  99.             std::unique_lock<std::mutex> ulock(m_WaitMutex);
  100.             m_WaitBlock.notify_one();
  101.         }
  102.  
  103.         void push_front(T&& value)
  104.         {
  105.             std::scoped_lock<std::mutex> lock(m_DequeMutex);
  106.             m_Deque.emplace_front(std::move(value));
  107.  
  108.             std::unique_lock<std::mutex> ulock(m_WaitMutex);
  109.             m_WaitBlock.notify_one();
  110.         }
  111.  
  112.         T pop_front()
  113.         {
  114.             if (m_DisposeCalled)
  115.             {
  116.                 throw std::runtime_error("Dispose has been called");
  117.             }
  118.             wait();
  119.  
  120.             std::scoped_lock<std::mutex> lock(m_DequeMutex);
  121.             auto item = std::move(m_Deque.front());
  122.             m_Deque.pop_front();
  123.             return item;
  124.         }
  125.  
  126.         T pop_back()
  127.         {
  128.             if (m_DisposeCalled)
  129.             {
  130.                 throw std::runtime_error("Dispose has been called");
  131.             }
  132.             wait();
  133.  
  134.             std::scoped_lock<std::mutex> lock(m_DequeMutex);
  135.             auto item = std::move(m_Deque.back());
  136.             m_Deque.pop_back();
  137.             return item;
  138.         }
  139.  
  140.         std::size_t size()
  141.         {
  142.             std::scoped_lock<std::mutex> lock(m_DequeMutex);
  143.             return m_Deque.size();
  144.         }
  145.  
  146.         bool empty()
  147.         {
  148.             std::scoped_lock<std::mutex> lock(m_DequeMutex);
  149.             return m_Deque.empty();
  150.         }
  151.  
  152.         void wait()
  153.         {
  154.             if (empty() && !m_DisposeCalled)
  155.             {
  156.                 std::unique_lock<std::mutex> ulock(m_WaitMutex);
  157.                 m_WaitBlock.wait(ulock);
  158.             }
  159.         }
  160.  
  161.         void clear()
  162.         {
  163.             std::scoped_lock<std::mutex> lock(m_DequeMutex);
  164.             m_Deque.clear();
  165.         }
  166.  
  167.         template<typename Iter>
  168.         void insert(Iter begin, Iter end)
  169.         {
  170.             std::scoped_lock<std::mutex> lock(m_DequeMutex);
  171.             m_Deque.insert(m_Deque.end(), begin, end);
  172.  
  173.             std::unique_lock<std::mutex> ulock(m_WaitMutex);
  174.             m_WaitBlock.notify_one();
  175.         }
  176.  
  177.         const T& front()
  178.         {
  179.             std::scoped_lock<std::mutex> lock(m_DequeMutex);
  180.             return m_Deque.front();
  181.         }
  182.  
  183.         const T& back()
  184.         {
  185.             std::scoped_lock<std::mutex> lock(m_DequeMutex);
  186.             return m_Deque.back();
  187.         }
  188. };
  189.  
  190. }
  191.  
  192. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement