Skip to content

Commit 9c55a9a

Browse files
committed
ref: improve stack array implementation
- Use TOS instead of stack index - Add tests for overflow and underflow
1 parent 19fc4b4 commit 9c55a9a

File tree

1 file changed

+51
-53
lines changed

1 file changed

+51
-53
lines changed
Lines changed: 51 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,8 @@
1-
/**
2-
* @file
3-
* @brief Implementation of a stack data structure
4-
* @details
5-
* This implementation provides functionalities to push, pop, and view elements
6-
* of the stack. It also includes a self-test method to ensure proper
7-
* functionality.
8-
*/
9-
10-
#include <cassert> /// For assert
11-
#include <iostream> /// For IO operations
12-
#include <stdexcept> /// For std::out_of_range
1+
#include <cassert>
2+
#include <iostream>
3+
#include <memory>
4+
#include <stdexcept>
135

14-
/*
15-
* @namespace
16-
* @brief Data structures
17-
*/
186
namespace data_structures {
197
/**
208
* @brief Class representation of a stack
@@ -23,8 +11,8 @@ namespace data_structures {
2311
template <typename T>
2412
class Stack {
2513
private:
26-
T* stack; ///< Pointer to the stack array
27-
int stackSize; ///< Maximum size of the stack
14+
std::unique_ptr<T[]> stack; ///< Smart pointer to the stack array
15+
int stackSize; ///< Maximum size of the stack
2816
int stackIndex; ///< Index pointing to the top element of the stack
2917

3018
public:
@@ -33,40 +21,32 @@ class Stack {
3321
*
3422
* @param size Maximum size of the stack
3523
*/
36-
Stack(int size) : stackSize(size), stackIndex(0) { stack = new T[size]; }
37-
38-
/**
39-
* @brief Destroys the Stack object
40-
*/
41-
~Stack() { delete[] stack; }
24+
Stack(int size) : stackSize(size), stackIndex(-1), stack(new T[size]) {}
4225

4326
/**
4427
* @brief Checks if the stack is full
4528
*
4629
* @return true if the stack is full, false otherwise
4730
*/
48-
bool full() const { return stackIndex == stackSize; }
31+
bool full() const { return stackIndex == stackSize - 1; }
4932

5033
/**
5134
* @brief Checks if the stack is empty
5235
*
5336
* @return true if the stack is empty, false otherwise
5437
*/
55-
bool empty() const { return stackIndex == 0; }
38+
bool empty() const { return stackIndex == -1; }
5639

5740
/**
5841
* @brief Pushes an element onto the stack
5942
*
6043
* @param element Element to push onto the stack
61-
* @return true if the element was successfully pushed onto the stack, false
62-
* otherwise
6344
*/
64-
bool push(T element) {
45+
void push(T element) {
6546
if (full()) {
66-
return false;
47+
throw std::out_of_range("Stack overflow");
6748
} else {
68-
stack[stackIndex++] = element;
69-
return true;
49+
stack[++stackIndex] = element;
7050
}
7151
}
7252

@@ -78,17 +58,16 @@ class Stack {
7858
*/
7959
T pop() {
8060
if (empty()) {
81-
throw std::out_of_range("Stack is empty");
82-
} else {
83-
return stack[--stackIndex];
61+
throw std::out_of_range("Stack underflow");
8462
}
63+
return stack[stackIndex--];
8564
}
8665

8766
/**
8867
* @brief Displays all elements in the stack
8968
*/
90-
void show() {
91-
for (int i = 0; i < stackIndex; i++) {
69+
void show() const {
70+
for (int i = 0; i <= stackIndex; i++) {
9271
std::cout << stack[i] << "\n";
9372
}
9473
}
@@ -101,10 +80,9 @@ class Stack {
10180
*/
10281
T topmost() const {
10382
if (empty()) {
104-
throw std::out_of_range("Stack is empty");
105-
} else {
106-
return stack[stackIndex - 1];
83+
throw std::out_of_range("Stack underflow");
10784
}
85+
return stack[stackIndex];
10886
}
10987

11088
/**
@@ -115,10 +93,9 @@ class Stack {
11593
*/
11694
T bottom() const {
11795
if (empty()) {
118-
throw std::out_of_range("Stack is empty");
119-
} else {
120-
return stack[0];
96+
throw std::out_of_range("Stack underflow");
12197
}
98+
return stack[0];
12299
}
123100
};
124101
} // namespace data_structures
@@ -130,21 +107,35 @@ class Stack {
130107
static void test() {
131108
data_structures::Stack<int> stack(5);
132109

133-
// Test push, pop, topmost, bottom, full, and empty operations
110+
// Test empty and full operations
134111
assert(stack.empty() == true);
135112
assert(stack.full() == false);
136113

137-
assert(stack.push(10) == true);
138-
assert(stack.push(20) == true);
139-
assert(stack.push(30) == true);
140-
assert(stack.push(40) == true);
141-
assert(stack.push(50) == true);
142-
assert(stack.push(60) == false);
114+
// Test pushing elements and checking topmost
115+
stack.push(10);
116+
assert(stack.topmost() == 10);
143117

118+
stack.push(20);
119+
assert(stack.topmost() == 20);
120+
121+
stack.push(30);
122+
stack.push(40);
123+
stack.push(50);
124+
assert(stack.full() == true);
125+
126+
// Test stack overflow
127+
try {
128+
stack.push(60);
129+
} catch (const std::out_of_range& e) {
130+
assert(std::string(e.what()) == "Stack overflow");
131+
}
132+
133+
// Test popping elements
144134
assert(stack.pop() == 50);
145135
assert(stack.pop() == 40);
146136
assert(stack.pop() == 30);
147137

138+
// Check topmost and bottom elements
148139
assert(stack.topmost() == 20);
149140
assert(stack.bottom() == 10);
150141

@@ -154,17 +145,23 @@ static void test() {
154145
assert(stack.empty() == true);
155146
assert(stack.full() == false);
156147

157-
// Test for exceptions when stack is empty
148+
// Test stack underflow
149+
try {
150+
stack.pop();
151+
} catch (const std::out_of_range& e) {
152+
assert(std::string(e.what()) == "Stack underflow");
153+
}
154+
158155
try {
159156
stack.topmost();
160157
} catch (const std::out_of_range& e) {
161-
assert(std::string(e.what()) == "Stack is empty");
158+
assert(std::string(e.what()) == "Stack underflow");
162159
}
163160

164161
try {
165162
stack.bottom();
166163
} catch (const std::out_of_range& e) {
167-
assert(std::string(e.what()) == "Stack is empty");
164+
assert(std::string(e.what()) == "Stack underflow");
168165
}
169166
}
170167

@@ -174,5 +171,6 @@ static void test() {
174171
*/
175172
int main() {
176173
test(); // run self-test implementations
174+
std::cout << "All tests passed!" << std::endl;
177175
return 0;
178176
}

0 commit comments

Comments
 (0)