Project 12.09 Section 12 ⚡ Embedded Relevance: Critical Templates ArrayStack Zero-Heap Type-Safe AUTOSAR Compliant

12.09 Generic Bounded LIFO Structures with Zero Runtime Heap Allocation

Executive Summary: Implementing a generic templated array stack. We explore type-safe compile-time instantiations, bounded memory guarantees, and why templated bounded arrays represent the gold standard container in safety-critical embedded systems.

💻 1. Annotated Source Code

#ifndef STACK_H
#define STACK_H

template <typename T>
class Stack {
	public:
		virtual void push(const T& newEntry) = 0;
		virtual T pop() = 0;
		virtual T peek() const = 0;
		virtual bool isEmpty() const = 0;
		virtual void makeEmpty() = 0;

		virtual ~Stack() {}
};

#endif 
#ifndef ARRAY_STACK_H
#define ARRAY_STACK_H

#include "Stack.h"
#include <iostream>
using namespace std;

template <typename T>
class ArrayStack : public Stack<T> { 
	public:
		ArrayStack(int s = 16) : MAX_SIZE(s) {
			top = -1;
			mArray = new T[MAX_SIZE];
		}//end ctor

		~ArrayStack() override {
			delete[] mArray;
		}

		void push(const T& newEntry) override {
			if (top < MAX_SIZE - 1) {
				top++;
				mArray[top] = newEntry;
			}
			else {
				cout << "Error: Stack is full!  Cannot push." << endl;
			}
		}//end push

		T pop() override {
			if (!isEmpty()) {
				return mArray[top--];
			}
			else {
				cout<<"You can't pop from an empty stack!"<<endl;
				return T();
			}
		}//end pop

		T peek() const override {
			if (!isEmpty()) {
				return mArray[top];
			}
			else {
				cout << "The stack is empty." << endl;
				return T();
			}
		}//end peek

		bool isEmpty() const override {
			return top == -1;
		}//end isEmpty

		void makeEmpty() override {
			top = -1;
		}

	private:
		T* mArray;
		const int MAX_SIZE;
		int top;
};



#endif
#include <iostream>
#include <string>
#include "ArrayStack.h"
using namespace std;

int main() {
	ArrayStack<string> words;

	words.push("apple");
	words.push("banana");
	words.push("cherry");

	while (!words.isEmpty()) {
		cout << words.pop() << endl;
	}

	cout << endl << endl;
	cout << "Now let's try integers!" << endl;

	ArrayStack<int> nums;
	nums.push(10);
	nums.push(20);
	nums.push(30);

	while (!nums.isEmpty()) {
		cout << nums.pop() << endl;
	}

	cout << endl << endl;
	cout << "Testing ArrayStack with doubles..." << endl;
	
	ArrayStack<double> decimals;
	decimals.push(3.14);
	decimals.push(2.718);
	decimals.push(1.618);

	cout << "Top of decimal stack: " << decimals.peek() << endl;

	while (!decimals.isEmpty()) {
		cout << decimals.pop() << endl;
	}


	return 0;
}

📐 2. Architecture & UML Class Model

📐 TemplatedArrayStack Pure Interface Implementation Architecture
+ Public - Private # Protected
<<interface>> StackInterface<T> Abstract Stack Contract
(none / stateless)
+push(newEntry: const T&) : bool[pure virtual =0]
+pop() : bool[pure virtual =0]
+peek() : T const[pure virtual =0]
+isEmpty() : bool const[pure virtual =0]
+~StackInterface()[virtual]
<<template class>> TemplatedArrayStack<T> Concrete Array Implementation
-items[CAPACITY] : T
-top : int32_t = -1
+TemplatedArrayStack()
+push(newEntry: const T&) : bool[override]
+pop() : bool[override]
+peek() : T const[override]
+isEmpty() : bool const[override]
🔗 Architectural Relationships & Hierarchy
TemplatedArrayStack<T> - - ▷ implements interface - - ▷ StackInterface<T>

📚 3. Core C++ Concepts Deep-Dive

1. Generic Template Containers

Combining templates with static arrays provides type safety for arbitrary data payloads while avoiding void* casts.

⚡ 4. Embedded Systems & Hardware Reality

1. Safety-Critical Compliance (AUTOSAR / MISRA)

Templated bounded array stacks allocate storage at compile time, guaranteeing zero dynamic memory operations after system initialization.

💡 5. Production-Ready Embedded Refactoring

💡 Production-Ready Refactor
#include <array>
#include <optional>

template <typename T, size_t MaxCapacity>
class EmbeddedStack {
public:
    bool push(const T& item) {
        if (top_ >= MaxCapacity) return false;
        data_[top_++] = item;
        return true;
    }
    std::optional<T> pop() {
        if (top_ == 0) return std::nullopt;
        return data_[--top_];
    }
private:
    std::array<T, MaxCapacity> data_;
    size_t top_ = 0;
};

📝 Knowledge Verification Quiz

Test your understanding of the C++ concepts and embedded microcontroller trade-offs covered in this guide. Click any option for instant feedback.

Q1. Why is a templated bounded array stack considered the gold standard in AUTOSAR C++ embedded software?
A It combines strong compile-time type safety with guaranteed fixed SRAM allocation and zero heap fragmentation.
B It can grow infinitely.
C It automatically creates threads.
D It bypasses all memory checks.
Detailed Explanation: It provides full generic type safety while bounding memory consumption strictly at compile time.