1 /*========================== begin_copyright_notice ============================
2 
3 Copyright (C) 2019-2021 Intel Corporation
4 
5 SPDX-License-Identifier: MIT
6 
7 ============================= end_copyright_notice ===========================*/
8 
9 #pragma once
10 
11 #include "Array.h"
12 
13 namespace iSTD
14 {
15 
16 /*****************************************************************************\
17 Struct: IsLinearStackTypeSupported
18 \*****************************************************************************/
19 template<typename T>
20 struct IsLinearStackTypeSupported                    { enum { value = false }; };
21 
22 template<>
23 struct IsLinearStackTypeSupported<bool>              { enum { value = true }; };
24 
25 template<>
26 struct IsLinearStackTypeSupported<char>              { enum { value = true }; };
27 
28 template<>
29 struct IsLinearStackTypeSupported<unsigned char>     { enum { value = true }; };
30 
31 template<>
32 struct IsLinearStackTypeSupported<int>               { enum { value = true }; };
33 
34 template<>
35 struct IsLinearStackTypeSupported<unsigned int>      { enum { value = true }; };
36 
37 #ifndef __LP64__ // u/long on linux64 platform is 64-bit type and collides with U/INT64
38 template<>
39 struct IsLinearStackTypeSupported<long>              { enum { value = true }; };
40 
41 template<>
42 struct IsLinearStackTypeSupported<unsigned long>     { enum { value = true }; };
43 #endif
44 
45 template<>
46 struct IsLinearStackTypeSupported<float>             { enum { value = true }; };
47 
48 template<>
49 struct IsLinearStackTypeSupported<INT64>             { enum { value = true }; };
50 
51 template<>
52 struct IsLinearStackTypeSupported<UINT64>            { enum { value = true }; };
53 
54 template<typename T>
55 struct IsLinearStackTypeSupported<T*>                { enum { value = true }; };
56 
57 /*****************************************************************************\
58 Template Parameters
59 \*****************************************************************************/
60 #define LinearStackTemplateList   class Type, class CAllocatorType
61 #define CLinearStackType          CLinearStack<Type,CAllocatorType>
62 
63 /*****************************************************************************\
64 
65 Class:
66     CLinearStack
67 
68 Description:
69     Implements an array-based stack
70 
71 \*****************************************************************************/
72 template<LinearStackTemplateList>
73 class CLinearStack : public CObject<CAllocatorType>
74 {
75 public:
76 
77     CLinearStack( const DWORD size );
78     virtual ~CLinearStack( void );
79 
80     bool    IsEmpty( void ) const;
81     DWORD   GetCount( void ) const;
82 
83     bool    Push( const Type element );
84     Type    Pop( void );
85     Type    Top( void ) const;
86 
87     void    Reset( void );
88 
89     void    DebugPrint( void ) const;
90 
91 protected:
92 
93     CDynamicArray<Type,CAllocatorType> m_ElementArray;
94     DWORD   m_Count;
95 };
96 
97 /*****************************************************************************\
98 
99 Function:
100     CLinearStack Constructor
101 
102 Description:
103     Initializes internal data
104 
105 Input:
106     const DWORD size - initial size of the stack
107 
108 Output:
109     none
110 
111 \*****************************************************************************/
112 template<LinearStackTemplateList>
113 CLinearStackType::CLinearStack( const DWORD size )
114     : CObject<CAllocatorType>(),
115     m_ElementArray( size )
116 {
117     m_Count = 0;
118 }
119 
120 /*****************************************************************************\
121 
122 Function:
123     CLinearStack Destructor
124 
125 Description:
126     Deletes internal data
127 
128 Input:
129     none
130 
131 Output:
132     none
133 
134 \*****************************************************************************/
135 template<LinearStackTemplateList>
136 CLinearStackType::~CLinearStack( void )
137 {
138 }
139 
140 /*****************************************************************************\
141 
142 Function:
143     CLinearStack::IsEmpty
144 
145 Description:
146     Returns if the stack is empty
147 
148 Input:
149     none
150 
151 Output:
152     bool - true or false
153 
154 \*****************************************************************************/
155 template<LinearStackTemplateList>
156 bool CLinearStackType::IsEmpty( void ) const
157 {
158     return m_Count == 0;
159 }
160 
161 /*****************************************************************************\
162 
163 Function:
164     CLinearStack::GetCount
165 
166 Description:
167     Returns the number of elements in the stack
168 
169 Input:
170     none
171 
172 Output:
173     DWORD - number of elements
174 
175 \*****************************************************************************/
176 template<LinearStackTemplateList>
177 DWORD CLinearStackType::GetCount( void ) const
178 {
179     return m_Count;
180 }
181 
182 /*****************************************************************************\
183 
184 Function:
185     CLinearStack::Push
186 
187 Description:
188     Pushes an element on the stack
189 
190 Input:
191     const Type element
192 
193 Output:
194     bool - success or fail
195 
196 \*****************************************************************************/
197 template<LinearStackTemplateList>
198 bool CLinearStackType::Push( const Type element )
199 {
200     // Add element to the end of list
201     return m_ElementArray.SetElement( m_Count++, element );
202 }
203 
204 /*****************************************************************************\
205 
206 Function:
207     CLinearStack::Pop
208 
209 Description:
210     Pops an element off the stack
211 
212 Input:
213     none
214 
215 Output:
216     Type - element
217 
218 \*****************************************************************************/
219 template<LinearStackTemplateList>
220 Type CLinearStackType::Pop( void )
221 {
222     Type element = (Type)0;
223 
224     if( IsEmpty() )
225     {
226         ASSERT(0);
227     }
228     else
229     {
230         // Get the last element on the list and
231         // remove the last element
232         element = m_ElementArray.GetElement( --m_Count );
233     }
234 
235     return element;
236 }
237 
238 /*****************************************************************************\
239 
240 Function:
241     CLinearStack::Top
242 
243 Description:
244     Returns the top element of the stack
245 
246 Input:
247     none
248 
249 Output:
250     Type - element
251 
252 \*****************************************************************************/
253 template<LinearStackTemplateList>
254 Type CLinearStackType::Top( void ) const
255 {
256     Type element = (Type)0;
257 
258     if( IsEmpty() )
259     {
260         ASSERT(0);
261     }
262     else
263     {
264         // Get the last element on the list
265         element = m_ElementArray.GetElement( m_Count-1 );
266     }
267 
268     return element;
269 }
270 
271 /*****************************************************************************\
272 
273 Function:
274     CLinearStack::Reset
275 
276 Description:
277     Resets the stack
278 
279 Input:
280     none
281 
282 Output:
283     none
284 
285 \*****************************************************************************/
286 template<LinearStackTemplateList>
287 void CLinearStackType::Reset( void )
288 {
289     m_Count = 0;
290 }
291 
292 /*****************************************************************************\
293 
294 Function:
295     CLinearStack::DebugPrint
296 
297 Description:
298     Prints the stack to std output for debug only
299 
300 Input:
301     none
302 
303 Output:
304     none
305 
306 \*****************************************************************************/
307 template<LinearStackTemplateList>
308 void CLinearStackType::DebugPrint( void ) const
309 {
310 #ifdef _DEBUG
311     m_ElementArray.DebugPrint();
312 #endif
313 }
314 
315 } // iSTD
316