ReactOS 0.4.16-dev-2646-g1219156
cicfifo.h
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Cicero
3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4 * PURPOSE: Cicero FIFO (First-In-First-Out)
5 * COPYRIGHT: Copyright 2026 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
6 */
7
8#pragma once
9
10#include "cicbase.h"
11
12// FIFO (First-In-First-Out) ring buffer
13template <typename T_ITEM>
15{
16protected:
17 T_ITEM* m_pItems;
18 size_t m_cItems;
19 size_t m_iBack;
20 size_t m_iFront;
21 //static_assert(std::is_trivially_copyable<T_ITEM>::value, ""); // FIXME
22
23public:
24 CicFirstInFirstOut(size_t cInitial = 0)
25 : m_pItems(NULL)
26 , m_cItems(0)
27 , m_iBack(0)
28 , m_iFront(0)
29 {
30 if (cInitial)
31 GrowBuffer(cInitial);
32 }
33
35 {
37 }
38
39 size_t GetSize() const
40 {
41 if (m_iBack == m_iFront)
42 return 0;
43 if (m_iBack < m_iFront)
44 return m_iBack + (m_cItems - m_iFront);
45 return m_iBack - m_iFront;
46 }
47
48 // Like push_back
49 BOOL SetData(const T_ITEM* pItem)
50 {
51 if (!m_cItems || GetSize() + 1 >= m_cItems) /* "+1" is for marking */
52 {
53 if (!GrowBuffer(!m_cItems ? 8 : m_cItems))
54 return FALSE;
55 }
56
57 m_pItems[m_iBack] = *pItem;
58
59 if (++m_iBack == m_cItems)
60 m_iBack = 0;
61
62 return TRUE;
63 }
64
65 // Like front and pop_front
66 BOOL GetData(T_ITEM* pItem)
67 {
68 if (m_iFront == m_iBack)
69 return FALSE;
70 *pItem = m_pItems[m_iFront];
71 if (++m_iFront == m_cItems)
72 m_iFront = 0;
73 return TRUE;
74 }
75
76protected:
77 BOOL GrowBuffer(size_t nGrow)
78 {
79 if (nGrow == 0)
80 return TRUE;
81
82 if (!m_pItems)
83 {
84 m_pItems = (T_ITEM*)cicMemAlloc(nGrow * sizeof(T_ITEM));
85 if (m_pItems)
86 m_cItems = nGrow;
87 return !!m_pItems;
88 }
89
90 size_t cNewItems = m_cItems + nGrow;
91 if (cNewItems < m_cItems || cNewItems > ~(size_t)0 / sizeof(T_ITEM))
92 return FALSE;
93
94 T_ITEM* pNewItems = (T_ITEM*)cicMemAlloc(cNewItems * sizeof(T_ITEM));
95 if (!pNewItems)
96 return FALSE;
97
98 if (m_iBack < m_iFront)
99 {
100 size_t cTail = m_cItems - m_iFront;
101 CopyMemory(pNewItems, &m_pItems[m_iFront], cTail * sizeof(T_ITEM));
102 CopyMemory(&pNewItems[cTail], m_pItems, m_iBack * sizeof(T_ITEM));
103 m_iBack = cTail + m_iBack;
104 }
105 else
106 {
107 size_t nCount = m_iBack - m_iFront;
108 CopyMemory(pNewItems, &m_pItems[m_iFront], nCount * sizeof(T_ITEM));
109 m_iBack = nCount;
110 }
111 m_iFront = 0;
112
114 m_pItems = pNewItems;
115 m_cItems = cNewItems;
116 return TRUE;
117 }
118
119private:
122};
static LPVOID cicMemAlloc(SIZE_T size)
Definition: cicbase.h:13
static void cicMemFree(LPVOID ptr)
Definition: cicbase.h:23
size_t m_cItems
Definition: cicfifo.h:18
T_ITEM * m_pItems
Definition: cicfifo.h:17
BOOL GrowBuffer(size_t nGrow)
Definition: cicfifo.h:77
CicFirstInFirstOut(size_t cInitial=0)
Definition: cicfifo.h:24
CicFirstInFirstOut(const CicFirstInFirstOut &)=delete
size_t m_iBack
Definition: cicfifo.h:19
BOOL SetData(const T_ITEM *pItem)
Definition: cicfifo.h:49
size_t GetSize() const
Definition: cicfifo.h:39
size_t m_iFront
Definition: cicfifo.h:20
BOOL GetData(T_ITEM *pItem)
Definition: cicfifo.h:66
CicFirstInFirstOut & operator=(const CicFirstInFirstOut &)=delete
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
#define CopyMemory
Definition: minwinbase.h:29