135. Compile-Time Fixed Stack

#include <iostream>
#include <string>

template <typename T, int Capacity>
class StaticStack {
private:
    T buffer[Capacity]; // Compile-time fixed array
    int top_index;      // Index of the *current* top element

public:
    // Initialize top_index to -1 (empty state)
    StaticStack() : top_index(-1) {}

    void push(T val) {
        if (top_index >= Capacity - 1) {
            std::cout << "Stack Overflow" << std::endl;
            return;
        }
        buffer[++top_index] = val;
    }

    void pop() {
        if (top_index < 0) {
            std::cout << "Stack Underflow" << std::endl;
            return;
        }
        top_index--;
    }

    T peek() const {
        if (top_index < 0) {
            return T(); // Return default if empty (caller should check)
        }
        return buffer[top_index];
    }

    bool isEmpty() const {
        return top_index < 0;
    }
};

int main() {
    // Instantiate a stack of int with capacity 3
    StaticStack<int, 3> stack;

    int N;
    if (!(std::cin >> N)) return 0;

    for (int i = 0; i < N; ++i) {
        std::string cmd;
        std::cin >> cmd;

        if (cmd == "PUSH") {
            int val;
            std::cin >> val;
            stack.push(val);
        } else if (cmd == "POP") {
            stack.pop();
        } else if (cmd == "PEEK") {
            if (!stack.isEmpty()) {
                std::cout << "Top: " << stack.peek() << std::endl;
            } else {
                 std::cout << "Stack Empty" << std::endl; // Matches logic when main checks empty
            }
        } else if (cmd == "EMPTY") {
            std::cout << "Empty: " << (stack.isEmpty() ? "Yes" : "No") << std::endl;
        }
    }
    return 0;
}

Explanation & Logic Summary: 

Standard C++ containers like std::stack or std::vector use the heap to grow dynamically. In strict embedded environments, we cannot assume heap availability.

  • Class Templates: Allow the stack to store any type (int, float, SensorData).
  • Non-Type Template Parameters: The int Capacity parameter allows passing a size (like 3) at compile time.
  • Effect: StaticStack<int, 3> generates a class with int buffer[3] inside it. The memory is allocated on the stack (or BSS/Data segment if global), ensuring zero fragmentation and predictable RAM usage.

Firmware Relevance & Real-World Context:

  • Communication Buffers: A UART driver might need a small queue for incoming bytes. RingBuffer<uint8_t, 64> is a standard pattern.
  • Menu Systems: Storing the history of nested menu screens (MenuStack<Screen*, 5>) to allow the "Back" button to work.
  • Safety Standards (MISRA): Dynamic memory is often banned (MISRA C++ Rule 18-4-1). Templates provide the flexibility of dynamic structures with the safety of static allocation.

 

 

 

 

Loading...

Input

6 PUSH 10 PUSH 20 PUSH 30 PUSH 40 PEEK POP

Expected Output

Stack Overflow Top: 30