소스 검색

V1.1.4
1、完善了环形队列的迭代器

Apple 2 일 전
부모
커밋
3a9f9c3ff4

+ 1 - 1
External

@@ -1 +1 @@
-Subproject commit d2f5efa0dec7f5174e99644f6bf04300211cee3b
+Subproject commit e23100681be63a9af9cb80d1690db1187743fbfc

+ 3 - 3
demo/DesignerPattern/CMakeLists.txt

@@ -5,7 +5,7 @@ set(this_exe DesignerPattern)
 
 #包含源文件
 file(GLOB LOCAL_SRC
-    # ${CMAKE_SOURCE_DIR}/External/module/Logs/*.cpp
+    ${CMAKE_SOURCE_DIR}/External/module/RingQueue/*.cpp
 
     ${CMAKE_CURRENT_SOURCE_DIR}/*.qrc
     ${CMAKE_CURRENT_SOURCE_DIR}/*.rc
@@ -36,12 +36,12 @@ target_include_directories(${this_exe} PRIVATE
     ${CMAKE_CURRENT_SOURCE_DIR}
     ${CMAKE_SOURCE_DIR}/External/common
     ${CMAKE_SOURCE_DIR}/External/module
-    # ${CMAKE_SOURCE_DIR}/External/module/Logs
+    ${CMAKE_SOURCE_DIR}/External/module/RingQueue
 
     ${CMAKE_CURRENT_SOURCE_DIR}/AbstractFactory
     ${CMAKE_CURRENT_SOURCE_DIR}/Builder
     ${CMAKE_CURRENT_SOURCE_DIR}/Iterator
-    ${CMAKE_CURRENT_SOURCE_DIR}/Iterator/RingQueue
+    # ${CMAKE_CURRENT_SOURCE_DIR}/Iterator/RingQueue
     ${CMAKE_CURRENT_SOURCE_DIR}/Combination
     ${CMAKE_CURRENT_SOURCE_DIR}/CommandModel
 )

+ 40 - 14
demo/DesignerPattern/Iterator/IteratorDemo.cpp

@@ -1,26 +1,52 @@
 #include "IteratorDemo.h"
 
+#include "RingQueue.hpp"
 
 
+struct User_t
+{
+    int id;
+    std::string name;
+};
 
 void testRingQueueManualMutex()
 {
-    RingQueueManualMutex<int> queue(5, -1);
-
-    queue.push(1);
-    queue.push(2);
-    queue.push(3);
-    queue.push(4);
-    queue.push(5);
-    auto old = queue.push(6); // This should remove 1
-    SPDLOG_INFO("Old value removed: {}", old);
-    // for(auto it = queue.begin(); it != queue.end(); ++it)
-    // {
-    //     SPDLOG_INFO("Value: {}", *it);
-    // }
+    RingQueueManualMutex<User_t> queue(5);
+    queue.push({1, "Alice"});
+    queue.push({2, "Bob"});
+    queue.push({3, "Charlie"});
+    queue.push({4, "Diana"});
+    queue.push({5, "Ethan"});
+    
     for(auto it : queue) 
     {
-        SPDLOG_INFO("Value: {}", it);
+        SPDLOG_INFO("Value: id={}, name={}", it.id, it.name);
+    }
+    SPDLOG_INFO("---------------------------------------------");
+    SPDLOG_INFO("倒叙遍历: ");
+    auto it = queue.end();
+    --it;
+    for(; it != queue.begin(); it--)
+    {
+        SPDLOG_INFO("Value: id={}, name={}", it->id, it->name);
     }
+    SPDLOG_INFO("Value: id={}, name={}", it->id, it->name);
     SPDLOG_INFO("RingQueueManualMutex 测试完成");
 }
+
+
+
+void testRingQueue()
+{
+    RingQueue<User_t> queue;
+    queue.push({1, "Alice"});
+    queue.push({2, "Bob"});
+    queue.push({3, "Charlie"});
+
+    // for(const auto& user : queue)
+    // {
+    //     SPDLOG_INFO("User ID: {}, Name: {}", user.id, user.name);
+    // }
+}
+
+

+ 3 - 1
demo/DesignerPattern/Iterator/IteratorDemo.h

@@ -1,11 +1,13 @@
 #ifndef __ITeratorDemo_H__
 #define __ITeratorDemo_H__
 
-#include "RingQueue.hpp"
+
 #include "RingQueueManualMutex.hpp"
 #include "spdlog/spdlog.h"
 
 
 void testRingQueueManualMutex();
 
+void testRingQueue();
+
 #endif // __ITeratorDemo_H__

+ 0 - 647
demo/DesignerPattern/Iterator/RingQueue/RingQueue.hpp

@@ -1,647 +0,0 @@
-#ifndef RINGQUEUE_H
-#define RINGQUEUE_H
-
-#include <cstdlib>
-#include <utility>
-#include <mutex>
-#include <condition_variable>
-#include <atomic>
-
-/**
- * @brief 这里采用零公摊的方式,设置多大的空间,就有多大的空间可以使用
- *        1、m_rear指向最新入队的元素的下一个位置,就是下个将要入队的元素位置
- *        2、m_front指向需要出队的第一个元素
- *        3、环形队列自带互斥锁
- *        
- * 注意:
- *      使用时要注意,不带NoBlock的都是阻塞函数
- *
- * 判断队列满:
- *        m_rear == m_front,并且此时都不等于 -1
- *
- * 判断队列空:
- *        m_rear == m_front,并且都等于 -1
- *
- * 获取队列大小:
- *       基本原则就是m_rear后面跟着的是有效值,m_front后面跟着的是已经出队的大小
- *       m_rear > m_front,返回 m_rear - m_front
- *       m_front > m_rear,返回 m_capacity - (m_front - m_rear)
- *       m_rear == m_front,且不等于-1,返回 m_capacity
- *       m_rear == m_front,且等于-1,返回 0
- * 
- * @tparam T 模版类型
- */
-
-#define _DefaultValue (m_isUseDefaultValue.load() ? m_defaultValue : T{})
-
-template<typename T>
-class RingQueue
-{
-    RingQueue(const RingQueue<T>& queue) = delete;
-    RingQueue<T> operator=(const RingQueue<T>& queue) = delete;
-public:
-    RingQueue();
-    RingQueue(long size);
-    RingQueue(long size, T defaultValue);
-    ~RingQueue();
-
-    /* 入队,默认是阻塞入队,队列满就阻塞住,直到有位置 */
-    void push(const T& value);
-    void push(T&& value);
-    bool push_noBlock(const T& value);
-    bool push_noBlock(T&& value);
-    /* 入队,队列满就出队一个,非阻塞 */
-    T push_pop(const T& value);
-
-    /* 出队,删除队列的首个元素
-     * 注意,如果存储的是指针,需要手动释放该指针指向的内存区域,不然会造成内存泄漏 */
-    void pop();
-
-    /* 获取队列中第一个值),但是不出队
-     * 阻塞的方式获取,如果队列为空,会一直阻塞住,直到获取到数据为止 */
-    T front();
-    /* 非阻塞的方式获取,队列为空返回false */
-    bool front_noBlock(T& t);
-    /* 非阻塞方式获取第一个值,如果对列为空,则会返回设置的默认值 */
-    T front_noBlock();
-
-    /* 获取对立第一个数据,获取完立刻出队
-     * 如果队列为空,会阻塞住,直到有数据为止
-     * 如果删除了拷贝构造函数,使用会报错 */
-    T front_pop();
-    /* 非阻塞方式获取第一个值,并出队 */
-    bool front_pop_noBlock(T& t);
-    /* 非阻塞方式获取第一个值,并出队,如果队列为空,会返回设置的默认值 */
-    T front_pop_noBlock();
-    /* 通过移动语义获取数据,获取完成后队列中的数据只是个空壳了,因此直接就出队了 */
-    bool front_pop_move(T& t);
-    bool front_pop_move_noBlock(T& t);
-    
-    /* 设置队列大小 */
-    void setQueueCapacity(long size);
-    /* 设置默认值,给指针类型使用,如果是非阻塞获取,空的时候可以返回为设置的默认值(如nullptr) */
-    void setDefaultValue(T defaultValue);
-    /* 获取队列大小,队列中有效值的大小 */
-    long QueueSize();
-    /* 获取队列容量 */
-    long QueueCapacity();
-    /* 判断队列是否为空 */
-    bool isEmpty();
-    /* 判断队列是否已满 */
-    bool isFull();
-    /* 清空队列 */
-    void clearQueue();
-    /* 退出所有可能的阻塞函数 */
-    void exit();
-
-private:
-    /* 判断是否空 */
-    inline bool _isEmpty();
-    /* 判断是否满 */
-    inline bool _isFull();
-
-private:
-    std::atomic_bool m_isExit = false;      /* 是否退出,这个标识位是为了退出阻塞住的函数 */
-    std::mutex m_mutex;                     /* 互斥锁 */
-    T m_defaultValue;                       /* 默认值 */
-    std::atomic_bool m_isUseDefaultValue = false; /* 是否使用默认值 */
-    T* m_queue = nullptr;                   /* 队列 */
-    long m_capacity = 0;                        /* 队列容量 */
-    long m_front = -1;                          /* 队头 */
-    long m_rear = -1;                           /* 队尾 */
-    std::condition_variable m_cond_NoFull;      /* 非满条件变量 */
-    std::condition_variable m_cond_NoEmpty;     /* 非空条件变量 */
-
-};
-
-
-/* =====================================================================
- * ***************************** 函数实现 *****************************
- * ===================================================================== */
-
-/* 这个构造函数需要调用 setQueueSize 设置环形队列的大小 */
-template<typename T>
-RingQueue<T>::RingQueue() 
-{
-    
-}
-
-template<typename T>
-RingQueue<T>::RingQueue(long capacity) 
-{
-    m_capacity = capacity;
-    m_queue = new T[m_capacity] {};
-}
-
-/* 添加默认值 */
-template<typename T>
-RingQueue<T>::RingQueue(long capacity, T defaultValue)
-{
-    m_capacity = capacity;
-    m_queue = new T[m_capacity] {};
-    for(long i = 0; i < m_capacity; i++)
-    {
-        m_queue[i] = defaultValue;
-    }
-    m_defaultValue = defaultValue;
-    m_isUseDefaultValue.store(true); // 设置使用默认值
-}
-
-template<typename T>
-RingQueue<T>::~RingQueue()
-{
-    if(m_queue != nullptr)
-    {
-        delete[] m_queue;
-        m_queue = nullptr;
-    }
-}
-
-
-/* 清空队列 */
-template<typename T>
-void RingQueue<T>::clearQueue()
-{
-    std::lock_guard<std::mutex> lock(m_mutex);
-    if(m_queue != nullptr)
-    {
-        delete[] m_queue;
-        m_queue = nullptr;
-    }
-    m_front = -1;
-    m_rear = -1;
-}
-
-
-/*************** 入队 *******************/
-template<typename T>
-void RingQueue<T>::push(const T& value)
-{
-    {
-        std::unique_lock<std::mutex> _lock(m_mutex);
-        m_cond_NoFull.wait(_lock, [this]() {
-            return (!_isFull() || m_isExit);
-        });
-        if(m_isExit)
-        {
-            return;
-        }
-
-        if(m_rear == -1)
-        {
-            m_front = 0;
-            m_rear = 0;
-        }
-
-        m_queue[m_rear] = value;
-        m_rear = (m_rear + 1) % m_capacity;
-    }
-    m_cond_NoEmpty.notify_all();
-}
-
-template<typename T>
-void RingQueue<T>::push(T&& value)
-{
-    {
-        std::unique_lock<std::mutex> lock(m_mutex);
-        m_cond_NoFull.wait(lock, [this](){
-            return (!_isFull() || m_isExit);
-        });
-        if(m_isExit)
-        {
-            return;
-        }
-
-        if(m_rear == -1)
-        {
-            m_front = 0;
-            m_rear = 0;
-        }
-
-        m_queue[m_rear] = std::move(value);
-        m_rear = (m_rear + 1) % m_capacity;
-    }
-
-    m_cond_NoEmpty.notify_all();
-}
-
-/**
- * @brief 非阻塞的方式入队,如果队列已满,直接返回
- * 
- */
- template<typename T>
-bool RingQueue<T>::push_noBlock(const T& value)
-{
-    {
-        // std::unique_lock<std::mutex> lock(m_mutex, std::defer_lock);
-        // if(!lock.try_lock())
-        // {
-        //     return false;
-        // }
-        std::lock_guard<std::mutex> lock(m_mutex);
-        /* 先检查队列是否还有剩余空间 */
-        if(_isFull())
-        {
-            return false;
-        }
-        else if(m_rear == -1)
-        {
-            m_front = 0;
-            m_rear = 0;
-        }
-
-        m_queue[m_rear] = value;
-        m_rear = (m_rear + 1) % m_capacity;
-    }
-    m_cond_NoEmpty.notify_all();
-    return true;
-}
-
-template<typename T>
-bool RingQueue<T>::push_noBlock(T&& value)
-{
-    {
-        // std::unique_lock<std::mutex> lock(m_mutex, std::defer_lock);
-        // if(!lock.try_lock())
-        // {
-        //     return false;
-        // }
-        std::lock_guard<std::mutex> lock(m_mutex);
-        /* 先检查队列是否还有剩余空间 */
-        if(_isFull())
-        {
-            return false;
-        }
-        else if(m_rear == -1)
-        {
-            m_front = 0;
-            m_rear = 0;
-        }
-
-        m_queue[m_rear] = std::move(value);
-        m_rear = (m_rear + 1) % m_capacity;
-    }
-    m_cond_NoEmpty.notify_all();
-    return true;
-}
-
-/* 入队,队列满就出队一个,非阻塞 */
-template<typename T>
-T RingQueue<T>::push_pop(const T& value)
-{
-    T ret = _DefaultValue;
-    {
-        std::unique_lock<std::mutex> lock(m_mutex);
-        /* 如果队列已满,先出队一个元素 */
-        if(_isFull())
-        {
-            ret = std::move(m_queue[m_front]);
-            m_front = (m_front + 1) % m_capacity;
-            if(m_front == m_rear)
-            {
-                m_front = -1;
-                m_rear = -1;
-            }
-        }
-        /* 入队新元素 */
-        if(m_rear == -1)
-        {
-            m_front = 0;
-            m_rear = 0;
-        }
-        m_queue[m_rear] = value;
-        m_rear = (m_rear + 1) % m_capacity;
-    }
-    m_cond_NoEmpty.notify_all();
-    return ret;
-}
-
-
-/**
- * @brief 出队,删除队列的首个元素
- *        注意,如果存储的是指针,需要手动释放该指针指向的内存区域,不然会造成内存泄漏
- * 
- * @tparam T 
- */
-template<typename T>
-void RingQueue<T>::pop()
-{
-    {
-        std::unique_lock<std::mutex> lock(m_mutex);
-        if(_isEmpty())
-        {
-            return;
-        }
-        m_front = (m_front + 1) % m_capacity;
-        if(m_front == m_rear)
-        {
-            m_front = -1;
-            m_rear = -1;
-        }
-    }
-    m_cond_NoFull.notify_all();
-}
-
-
-/* 获取队列中第一个值,但是不出队
- * 阻塞的方式获取,如果队列为空,会一直阻塞住,直到获取到数据为止 */
-template<typename T>
-T RingQueue<T>::front()
-{
-    
-    std::unique_lock<std::mutex> lock(m_mutex);
-    m_cond_NoEmpty.wait(lock, [this](){
-        return (!_isEmpty() || m_isExit);
-    });
-    if(m_isExit)
-    {
-        return _DefaultValue;
-    }
-    return m_queue[m_front];
-    
-}
-
-
-/* 获取队列中第一个值,但是不出队,非阻塞的方式获取 */
-template<typename T>
-bool RingQueue<T>::front_noBlock(T& t)
-{
-    {
-        std::unique_lock<std::mutex> lock(m_mutex);
-        if(_isEmpty())
-        {
-            return false;
-        }
-        t = m_queue[m_front];
-    }
-    return true;
-}
-
-
-/* 非阻塞方式获取第一个值,如果对列为空,则会返回设置的默认值 */
-template<typename T>
-T RingQueue<T>::front_noBlock()
-{
-    std::unique_lock<std::mutex> lock(m_mutex);
-    if(_isEmpty())
-    {
-        return _DefaultValue;
-    }
-    return m_queue[m_front];
-}
-
-/* 获取对立第一个数据,获取完立刻出队
- * 如果队列为空,会阻塞住,直到有数据为止 */
-template<typename T>
-T RingQueue<T>::front_pop()
-{
-    // T ret = _DefaultValue;
-    {
-        std::unique_lock<std::mutex> lock(m_mutex);
-        m_cond_NoEmpty.wait(lock, [this](){
-            return (!_isEmpty() || m_isExit);
-        });
-        /* 是否退出 */
-        if(m_isExit)
-        {
-            return _DefaultValue;
-        }
-        /* 临时记录索引 */
-        long front = m_front;
-        m_front = (m_front + 1) % m_capacity;
-        if(m_front == m_rear)
-        {
-            m_front = -1;
-            m_rear = -1;
-        }
-        m_cond_NoFull.notify_all();
-        return std::move(m_queue[front]);
-    }
-}
-
-/* 非阻塞方式获取第一个值,并出队 */
-template<typename T>
-bool RingQueue<T>::front_pop_noBlock(T& t)
-{
-    {
-        std::unique_lock<std::mutex> lock(m_mutex);
-        if(_isEmpty())
-        {
-            return false;
-        }
-        t = std::move(m_queue[m_front]);
-        m_front = (m_front + 1) % m_capacity;
-        if(m_front == m_rear)
-        {
-            m_front = -1;
-            m_rear = -1;
-        }
-    }
-    m_cond_NoFull.notify_all();
-    return true;
-}
-
-/* 非阻塞方式获取第一个值,并出队 */
-template<typename T>
-T RingQueue<T>::front_pop_noBlock()
-{
-    // T ret = _DefaultValue;
-    {
-        std::unique_lock<std::mutex> lock(m_mutex);
-        // m_cond_NoEmpty.wait(lock, [this](){
-        //     return (!_isEmpty() || m_isExit);
-        // });
-        if(_isEmpty())
-        {
-            return _DefaultValue;
-        }
-        /* 临时记录索引 */
-        long front = m_front;
-        
-        m_front = (m_front + 1) % m_capacity;
-        if(m_front == m_rear)
-        {
-            m_front = -1;
-            m_rear = -1;
-        }
-        m_cond_NoFull.notify_all();
-        return std::move(m_queue[front]);
-    }
-}
-
-/* 通过移动语义获取数据,获取完成后队列中的数据只是个空壳了,因此直接就出队了 */
-template<typename T>
-bool RingQueue<T>::front_pop_move(T& t)
-{
-    std::unique_lock<std::mutex> lock(m_mutex);
-    m_cond_NoEmpty.wait(lock, [this]() {
-        return (!_isEmpty() || m_isExit);
-    });
-    /* 是否退出 */
-    if(m_isExit)
-    {
-        return false;
-    }
-    t = std::move(m_queue[m_front]); // 移动语义获取数据
-    m_front = (m_front + 1) % m_capacity;
-    if(m_front == m_rear)
-    {
-        m_front = -1;
-        m_rear = -1;
-    }
-    
-    m_cond_NoFull.notify_all();
-    return true;
-}
-
-template<typename T>
-bool RingQueue<T>::front_pop_move_noBlock(T& t)
-{
-    std::unique_lock<std::mutex> lock(m_mutex);
-    // m_cond_NoEmpty.wait(lock, [this](){
-    //     return (!_isEmpty() || m_isExit);
-    // });
-    if(_isEmpty())
-    {
-        return false;
-    }
-    t = std::move(m_queue[m_front]); // 移动语义获取数据
-    
-    m_front = (m_front + 1) % m_capacity;
-    if(m_front == m_rear)
-    {
-        m_front = -1;
-        m_rear = -1;
-    }
-    m_cond_NoFull.notify_all();
-
-    return true;
-}
-
-
-/**
- * @brief 设置队列大小
- *        注意:使用这个设置,如果队列中存储的是指针,指针的内存区域需要在调用这个函数之前释放,不然可能会造成
- *              内存泄漏
- * 
- * @tparam T 
- * @param size 
- */
-template<typename T>
-void RingQueue<T>::setQueueCapacity(long size)
-{
-    if(m_queue != nullptr)
-    {
-        delete[] m_queue;
-        m_queue = nullptr;
-    }
-
-    m_capacity = size;
-    m_front = -1;
-    m_rear = -1;
-    m_queue = new T[m_capacity];
-}
-
-
-/* 设置默认值,给指针类型使用,如果是非阻塞获取,空的时候可以返回为设置的默认值(如nullptr) */
-template<typename T>
-void RingQueue<T>::setDefaultValue(T defaultValue)
-{
-    m_defaultValue = defaultValue;
-    m_isUseDefaultValue.store(true); // 设置使用默认值
-}
-
-/* 获取队列中有效值的大小 */
-template<typename T>
-long RingQueue<T>::QueueSize()
-{
-    std::lock_guard<std::mutex> lock(m_mutex);
-    if(m_rear == -1)
-    {
-        return 0;
-    }
-    else if(m_rear > m_front)
-    {
-        return m_rear - m_front;
-    }
-    else if(m_rear < m_front)
-    {
-        return m_capacity - ( m_front - m_rear );
-    }
-    /* 这时候是队列满 */
-    return m_capacity;
-}
-
-/* 获取队列容量 */
-template<typename T>
-long RingQueue<T>::QueueCapacity()
-{
-    std::lock_guard<std::mutex> lock(m_mutex);
-    return m_capacity;
-}
-
-/**
- * @brief 判断队列是否为空
- * 
- * @tparam T 
- * @return true 
- * @return false 
- */
-template<typename T>
-bool RingQueue<T>::isEmpty()
-{
-    std::lock_guard<std::mutex> lock(m_mutex);
-    return _isEmpty();
-}
-
-/**
- * @brief 判断队列是否已满,这里判断依赖入队和出队后的队头和队尾指针的位置
- *        1、队头和队尾指针相等,但是队尾指针不等于-1,表示队列已满
- * 
- * @tparam T 
- * @return true 
- * @return false 
- */
-template<typename T>
-bool RingQueue<T>::isFull()
-{
-    std::lock_guard<std::mutex> lock(m_mutex);
-    return _isFull();
-}
-
-/* 退出所有可能的阻塞函数 */
-template<typename T>
-void RingQueue<T>::exit()
-{
-    m_isExit = true;
-    m_cond_NoFull.notify_all();
-    m_cond_NoEmpty.notify_all();
-}
-
-/* 判断是否空 */
-template<typename T>
-bool RingQueue<T>::_isEmpty()
-{
-    if((m_front == m_rear) && (m_front == -1))
-    {
-        return true;
-    }
-    return false;
-}
-
-/* 判断是否满 */
-template<typename T>
-inline bool RingQueue<T>::_isFull()
-{
-    /* 如果m_rear或者m_front不等于-1,说明此时里面有内容
-     * 同时m_front == m_rear,队列就满了 */
-    if(m_front == m_rear && m_rear != -1)
-    {
-        return true;
-    }
-    return false;
-}
-
-
-
-#endif /* RINGQUEUE_H */

+ 0 - 548
demo/DesignerPattern/Iterator/RingQueue/RingQueueManualMutex.hpp

@@ -1,548 +0,0 @@
-#ifndef _RINGQUEUE_MANUAL_MUTEX_HPP_
-#define _RINGQUEUE_MANUAL_MUTEX_HPP_
-
-/**
- * @brief 这里采用零公摊的方式,设置多大的空间,就有多大的空间可以使用
- *        1、m_rear指向最新入队的元素的下一个位置,就是下个将要入队的元素位置
- *        2、m_front指向需要出队的第一个元素
- *        3、环形队列自带互斥锁,但是不会自动加锁,需要外部手动上锁
- *        
- * 使用说明:
- *      因为是外部手动上锁,所以这里所有的函数都是非阻塞函数
- *          1、入队时如果队列满,则会自动出队一个元素,入读函数的返回值则是出队的元素,
- *             如果队列中是指针,需要手动释放
- *          2、出队时如果队列为空,则会返回默认构建的元素值,尽量设置一个默认元素,会返
- *             回这个默认元素
- *
- * 判断队列满:
- *        m_rear == m_front,并且此时都不等于 -1
- *
- * 判断队列空:
- *        m_rear == m_front,并且都等于 -1
- *
- * 获取队列大小:
- *       基本原则就是m_rear后面跟着的是有效值,m_front后面跟着的是已经出队的大小
- *       m_rear > m_front,返回 m_rear - m_front
- *       m_front > m_rear,返回 m_capacity - (m_front - m_rear)
- *       m_rear == m_front,且不等于-1,返回 m_capacity
- *       m_rear == m_front,且等于-1,返回 0
- * 
- * @tparam T 模版类型
- */
-
-#include <atomic>
-#include <mutex>
-#include <iostream>
-
-#define _DefaultValue (m_isUseDefaultValue.load() ? m_defaultValue : T{})
-
-template<typename T>
-class RingQueueManualMutex
-{
-    RingQueueManualMutex(RingQueueManualMutex<T>&& queue) = delete;
-    RingQueueManualMutex<T>& operator=(RingQueueManualMutex<T>&& queue) = delete;
-
-public:
-    RingQueueManualMutex();
-    RingQueueManualMutex(long size);
-    RingQueueManualMutex(long size, T defaultValue);
-    /* 拷贝和赋值构造函数内部都不会自动上锁,需要在外部手动上锁
-     * 如果存储的是指针,需要在外部手动拷贝,否则拷贝的是指针而已 */
-    RingQueueManualMutex(const RingQueueManualMutex<T>& queue);
-    RingQueueManualMutex<T> operator=(const RingQueueManualMutex<T>& queue);
-
-    ~RingQueueManualMutex();
-
-
-
-    /* 入队 */
-    T push(const T& value);
-    T push(T&& value);
-
-    /* 获取队列中第一个值,但是不出队,
-     * 非阻塞的方式获取,如果队列为空,会返回一个默认值 */
-    T front();
-
-    /* 获取对立第一个数据,获取完立刻出队
-     * 如果删除了拷贝构造函数,使用会报错 */
-    T front_pop();
-
-    /* 获取最后一个值,最后一个值不会出队 */
-    T back();
-    bool back(T& value);
-
-    /* 根据下标获取某个位置的元素,下标0就是下一个要出队的位置
-     * 这里获取元素不会出队 */
-    T operator[](long index);
-    T at(long index) const;
-    
-    /* 设置队列大小 */
-    void setQueueCapacity(long size);
-    /* 设置默认值,给指针类型使用,如果是非阻塞获取,空的时候可以返回为设置的默认值(如nullptr) */
-    void setDefaultValue(T defaultValue);
-    /* 获取队列大小,队列中有效值的大小 */
-    long QueueSize() const;
-    /* 获取队列容量 */
-    long QueueCapacity() const;
-    /* 判断队列是否为空 */
-    bool isEmpty() const;
-    /* 判断队列是否已满 */
-    bool isFull() const;
-    /* 清空队列 */
-    void clearQueue();
-
-public:
-    std::mutex mutex;                       /* 互斥锁 */
-private:
-    /* 判断是否空 */
-    inline bool _isEmpty() const;
-    /* 判断是否满 */
-    inline bool _isFull() const;
-
-private:    
-    T m_defaultValue;                           /* 默认值 */
-    std::atomic_bool m_isUseDefaultValue = false; /* 是否使用默认值 */
-    T* m_queue = nullptr;                       /* 队列 */
-    long m_capacity = 0;                        /* 队列容量 */
-    long m_front = -1;                          /* 队头 */
-    long m_rear = -1;                           /* 队尾 */
-    // std::condition_variable m_cond_NoFull;      /* 非满条件变量 */
-    // std::condition_variable m_cond_NoEmpty;     /* 非空条件变量 */
-
-public:
-    /* 定义迭代器 */
-    class Iterator
-    {
-    public:
-        Iterator(RingQueueManualMutex<T>* queue) : m_ptr(queue), m_index(m_ptr->m_front) {}
-        Iterator(RingQueueManualMutex<T>* queue, long index) : m_ptr(queue), m_index(index) {}
-
-        T& operator*() { 
-            if(m_index == -1)
-            {
-                throw std::out_of_range("Iterator out of range");
-            }
-            return m_ptr->m_queue[m_index]; 
-        }
-        T* operator->() { 
-            if(m_index == -1)
-            {
-                throw std::out_of_range("Iterator out of range");
-            }
-            return &m_ptr->m_queue[m_index]; 
-        }
-
-        Iterator& operator++()
-        {
-            m_index = (m_index + 1) % m_ptr->m_capacity;
-            if(m_index == m_ptr->m_rear)
-            {
-                m_index = -1; // 到达末尾
-            }
-            return *this;
-        }
-
-        bool operator!=(const Iterator& other) const
-        {
-            if(m_ptr != other.m_ptr)
-                return true;
-            if(m_index == other.m_index)
-                return false;
-            return true;
-        }
-        bool operator==(const Iterator& other) const
-        {
-            if(m_ptr != other.m_ptr)
-                return false;
-            if(m_index != other.m_index)
-                return false;
-            return true;
-        }
-
-    private:
-        RingQueueManualMutex<T>* m_ptr = nullptr;
-        long m_index = -1;
-    };
-
-    Iterator begin() { return Iterator(this); }
-    Iterator end() { return Iterator(this, -1); }
-};
-
-
-/* =====================================================================
- * ***************************** 函数实现 *****************************
- * ===================================================================== */
-
-/* 这个构造函数需要调用 setQueueSize 设置环形队列的大小 */
-template<typename T>
-RingQueueManualMutex<T>::RingQueueManualMutex() 
-{
-    
-}
-
-template<typename T>
-RingQueueManualMutex<T>::RingQueueManualMutex(long capacity) 
-{
-    m_capacity = capacity;
-    m_queue = new T[m_capacity] {};
-}
-
-/* 添加默认值 */
-template<typename T>
-RingQueueManualMutex<T>::RingQueueManualMutex(long capacity, T defaultValue)
-{
-    m_capacity = capacity;
-    m_queue = new T[m_capacity] {};
-    for(long i = 0; i < m_capacity; i++)
-    {
-        m_queue[i] = defaultValue;
-    }
-    m_defaultValue = defaultValue;
-    m_isUseDefaultValue.store(true); // 设置使用默认值
-}
-
-
-
-template<typename T>
-RingQueueManualMutex<T>::RingQueueManualMutex(const RingQueueManualMutex<T>& queue)
-{
-    m_capacity = queue.m_capacity;
-    m_front = queue.m_front;
-    m_rear = queue.m_rear;
-    m_defaultValue = queue.m_defaultValue;
-    m_isUseDefaultValue.store(queue.m_isUseDefaultValue.load());
-    
-    if(m_queue != nullptr)
-    {
-        delete[] m_queue;
-        m_queue = nullptr;
-    }
-    
-    if(m_capacity > 0)
-    {
-        m_queue = new T[m_capacity];
-        for(long i = 0; i < m_capacity; i++)
-        {
-            m_queue[i] = queue.m_queue[i];
-        }
-    }
-}
-
-template<typename T>
-RingQueueManualMutex<T> RingQueueManualMutex<T>::operator=(const RingQueueManualMutex<T>& queue)
-{
-    if(this == &queue)
-    {
-        return *this; // 防止自赋值
-    }
-
-    m_capacity = queue.m_capacity;
-    m_front = queue.m_front;
-    m_rear = queue.m_rear;
-    m_defaultValue = queue.m_defaultValue;
-    m_isUseDefaultValue.store(queue.m_isUseDefaultValue.load());
-
-    if(m_queue != nullptr)
-    {
-        delete[] m_queue;
-        m_queue = nullptr;
-    }
-
-    if(m_capacity > 0)
-    {
-        m_queue = new T[m_capacity];
-        for(long i = 0; i < m_capacity; i++)
-        {
-            m_queue[i] = queue.m_queue[i];
-        }
-    }
-
-    return *this;
-}
-
-
-template<typename T>
-RingQueueManualMutex<T>::~RingQueueManualMutex()
-{
-    if(m_queue != nullptr)
-    {
-        delete[] m_queue;
-        m_queue = nullptr;
-    }
-}
-
-
-/*************** 入队 *******************/
-template<typename T>
-T  RingQueueManualMutex<T>::push(const T& value)
-{
-    T ret = _DefaultValue;
-    if(_isFull())
-    {
-        /* 队列已满,先出队一个元素 */
-        ret = std::move(m_queue[m_front]);
-        /* 出队后,前进一个位置 */
-        m_front = (m_front + 1) % m_capacity;
-    }
-    // std::cout << "m_front: " << m_front << "  m_rear: " << m_rear << std::endl;
-    if(m_rear == -1)
-    {
-        m_front = 0;
-        m_rear = 0;
-    }
-    m_queue[m_rear] = value;
-    m_rear = (m_rear + 1) % m_capacity;
-
-    return std::move(ret);
-}
-
-template<typename T>
-T  RingQueueManualMutex<T>::push(T&& value)
-{
-    T ret = _DefaultValue; // 默认值
-    if(_isFull())
-    {
-        /* 队列已满,先出队一个元素 */
-        ret = std::move(m_queue[m_front]);
-        /* 出队后,前进一个位置 */
-        m_front = (m_front + 1) % m_capacity;
-    }
-    if(m_rear == -1)
-    {
-        m_front = 0;
-        m_rear = 0;
-    }
-    m_queue[m_rear] = std::move(value);
-    m_rear = (m_rear + 1) % m_capacity;
-
-    return std::move(ret);
-}
-
-
-/* 获取队列中第一个值,但是不出队
- * 阻塞的方式获取,如果队列为空,会一直阻塞住,直到获取到数据为止 */
-template<typename T>
-T RingQueueManualMutex<T>::front()
-{
-    if(_isEmpty())
-    {
-        return _DefaultValue; // 如果队列为空,返回默认值
-    }
-    return m_queue[m_front];
-}
-
-
-
-/* 获取对立第一个数据,获取完立刻出队 */
-template<typename T>
-T RingQueueManualMutex<T>::front_pop()
-{
-    if(_isEmpty())
-    {
-        return _DefaultValue; // 如果队列为空,返回默认值
-    }
-    // int ret = m_front;
-    T ret = std::move(m_queue[m_front]);
-    /* 临时记录索引 */
-    m_front = (m_front + 1) % m_capacity;
-    if(m_front == m_rear)
-    {
-        m_front = -1;
-        m_rear = -1;
-    }
-
-    return std::move(ret);
-}
-
-/* 获取最后一个值,最后一个值不会出队 */
-template<typename T>
-T RingQueueManualMutex<T>::back()
-{
-    if(_isEmpty())
-    {
-        return _DefaultValue; // 如果队列为空,返回默认值
-    }
-    return m_queue[(m_rear - 1 + m_capacity) % m_capacity];
-}
-
-template<typename T>
-bool RingQueueManualMutex<T>::back(T& value)
-{
-    if(_isEmpty())
-    {
-        return false;
-    }
-    value = m_queue[(m_rear - 1 + m_capacity) % m_capacity];
-    return true;
-}
-
-/* 根据下标获取某个位置的元素,下标0就是下一个要出队的位置
- * 这里获取元素不会出队 */
-template<typename T>
-T RingQueueManualMutex<T>::operator[](long index)
-{
-    if(_isEmpty())
-    {
-        return _DefaultValue; // 如果队列为空,返回默认值
-    }
-    if(index >= QueueSize() || index < -QueueSize())
-    {
-        return _DefaultValue;
-    }
-    if(index < 0)
-    {
-        index += m_capacity; // 处理负数索引
-    }
-    long realIndex = (index + m_front) % m_capacity;
-    
-    return m_queue[realIndex];
-}
-
-
-template<typename T>
-T RingQueueManualMutex<T>::at(long index) const
-{
-    if(_isEmpty())
-    {
-        return _DefaultValue; // 如果队列为空,返回默认值
-    }
-    if(index >= QueueSize() || index < -QueueSize())
-    {
-        return _DefaultValue;
-    }
-    if(index < 0)
-    {
-        index += m_capacity; // 处理负数索引
-    }
-    long realIndex = (index + m_front) % m_capacity;
-    
-    return m_queue[realIndex];
-}
-
-
-/**
- * @brief 设置队列大小
- *        注意:使用这个设置,如果队列中存储的是指针,指针的内存区域需要在调用这个函数之前释放,不然可能会造成
- *              内存泄漏
- * 
- * @tparam T 
- * @param size 
- */
-template<typename T>
-void RingQueueManualMutex<T>::setQueueCapacity(long size)
-{
-    if(m_queue != nullptr)
-    {
-        delete[] m_queue;
-        m_queue = nullptr;
-    }
-
-    m_capacity = size;
-    m_front = -1;
-    m_rear = -1;
-    m_queue = new T[m_capacity];
-}
-
-
-/* 设置默认值,给指针类型使用,如果是非阻塞获取,空的时候可以返回为设置的默认值(如nullptr) */
-template<typename T>
-void RingQueueManualMutex<T>::setDefaultValue(T defaultValue)
-{
-    m_defaultValue = defaultValue;
-    m_isUseDefaultValue.store(true); // 设置使用默认值
-}
-
-/* 获取队列中有效值的大小 */
-template<typename T>
-long RingQueueManualMutex<T>::QueueSize() const
-{
-    if(m_rear == -1)
-    {
-        return 0;
-    }
-    else if(m_rear > m_front)
-    {
-        return m_rear - m_front;
-    }
-    else if(m_rear < m_front)
-    {
-        return m_capacity - ( m_front - m_rear );
-    }
-    /* 这时候是队列满 */
-    return m_capacity;
-}
-
-/* 获取队列容量 */
-template<typename T>
-long RingQueueManualMutex<T>::QueueCapacity() const
-{
-    return m_capacity;
-}
-
-/**
- * @brief 判断队列是否为空
- * 
- * @tparam T 
- * @return true 
- * @return false 
- */
-template<typename T>
-bool RingQueueManualMutex<T>::isEmpty() const
-{
-    return _isEmpty();
-}
-
-/**
- * @brief 判断队列是否已满,这里判断依赖入队和出队后的队头和队尾指针的位置
- *        1、队头和队尾指针相等,但是队尾指针不等于-1,表示队列已满
- * 
- * @tparam T 
- * @return true 
- * @return false 
- */
-template<typename T>
-bool RingQueueManualMutex<T>::isFull() const
-{
-    return _isFull();
-}
-
-/* 清空队列 */
-template<typename T>
-void RingQueueManualMutex<T>::clearQueue()
-{
-    if(m_queue != nullptr)
-    {
-        delete[] m_queue;
-        m_queue = nullptr;
-    }
-    m_front = -1;
-    m_rear = -1;
-}
-
-/* 判断是否空 */
-template<typename T>
-bool RingQueueManualMutex<T>::_isEmpty() const
-{
-    if((m_front == m_rear) && (m_front == -1))
-    {
-        return true;
-    }
-    return false;
-}
-
-/* 判断是否满 */
-template<typename T>
-inline bool RingQueueManualMutex<T>::_isFull() const
-{
-    /* 如果m_rear或者m_front不等于-1,说明此时里面有内容
-     * 同时m_front == m_rear,队列就满了 */
-    if(m_front == m_rear && m_rear != -1)
-    {
-        return true;
-    }
-    return false;
-}
-
-
-
-#endif /* _RINGQUEUE_MANUAL_MUTEX_HPP_ */

+ 2 - 2
demo/DesignerPattern/main.cpp

@@ -50,11 +50,11 @@ int main(int argc, char *argv[])
     // delete translator;
     // delete french;
 
-    // testRingQueueManualMutex();
+    testRingQueueManualMutex();
 
     // testFlyWeight();
 
-    CommandModel::useRemoteControl();
+    // CommandModel::useRemoteControl();
 
     return a.exec();
 }