SolarSystem is a professional C++ data structure library that manages heterogeneous collections through a unified polymorphic interface. Using a Solar System metaphor, each "planet" represents a distinct data structure (Vector, Stack, or Queue), all governed by a central SolarSystem<T> controller.
The library demonstrates modern C++ best practices including RAII ownership, polymorphic dispatch, factory-based creation, template generics, const-correctness, move semantics, and structured exception handling.
The following diagram illustrates the complete system topology. The Star sits at the core as the metadata controller, branching out to three polymorphic planet types through a factory-based creation pipeline. All operations are dispatched polymorphically via BasePlanet<T>.
High-level architecture of the SolarSystem library.
Interactive Architecture Diagram (Mermaid)
graph TB
subgraph Controller["SolarSystem<T> — Orchestrator"]
direction TB
Star["⭐ Star · Control Plane\n─────────────────────\nplanet_count : int\nelement_count : int\nid : int"]
end
subgraph Factory["PlanetFactory<T> · Factory Pattern"]
PF["🏭 create(PlanetType)\n→ unique_ptr<BasePlanet<T>>"]
end
subgraph Planets["vector<unique_ptr<BasePlanet<T>>>"]
direction LR
VP["🔵 VectorPlanet<T>\nstd::vector<T>\nRandom Access\nO(1) push · O(1) pop"]
SP["🟢 StackPlanet<T>\nstd::stack<T>\nLIFO Order\nO(1) push · O(1) pop"]
QP["🟠 QueuePlanet<T>\nstd::queue<T>\nFIFO Order\nO(1) push · O(1) pop"]
end
subgraph Ops["Core Operations"]
direction LR
O1["pushToPlanet · O(1)"]
O2["removePlanet · O(n)"]
O3["gravityPull · O(n×m)"]
O4["resetSystem · O(p)"]
end
Star -->|"owns & tracks"| Planets
PF -->|"make_unique + std::move"| Planets
Ops -->|"polymorphic dispatch"| Planets
classDef starStyle fill:#FFF3B0,stroke:#E6A800,stroke-width:2px,color:#333
classDef vectorStyle fill:#DBEAFE,stroke:#3B82F6,stroke-width:2px,color:#333
classDef stackStyle fill:#D1FAE5,stroke:#10B981,stroke-width:2px,color:#333
classDef queueStyle fill:#FFEDD5,stroke:#F97316,stroke-width:2px,color:#333
classDef factoryStyle fill:#EDE9FE,stroke:#8B5CF6,stroke-width:2px,color:#333
classDef opsStyle fill:#F3F4F6,stroke:#6B7280,stroke-width:1px,color:#333
classDef ctrlStyle fill:#FEF9C3,stroke:#CA8A04,stroke-width:2px,color:#333
class Star starStyle
class VP vectorStyle
class SP stackStyle
class QP queueStyle
class PF factoryStyle
class O1,O2,O3,O4 opsStyle
| Operation | Method | Time | Space |
|---|---|---|---|
| Add planet | addPlanet() |
|
|
| Push element | pushToPlanet() |
|
|
| Pop element | deleteElement() |
||
| Remove planet (Black Hole) | removePlanet() |
||
| Reset system (Supernova) | resetSystem() |
||
| Gravity pull | gravityPull() |
||
| Display all | travelPlanet() |
||
| Element count | getElementCount() |
||
| Planet count | getPlanetCount() |
||
| Validate count | getActualElementCount() |
Where
$p$ = number of planets,$n$ = total elements across the system, and$m$ = maximum elements in a single planet.
The Star struct maintains planet_count and element_count for O(1) system-wide queries.
The Star is an internal struct within SolarSystem<T> that acts as the control plane. It tracks three counters — id, planet_count, and element_count — enabling
VectorPlanet stores elements in a contiguous std::vector<T> with O(1) amortized insertion.
| Property | Value |
|---|---|
| Backing container | std::vector<T> |
| Access pattern | Random access by index |
| Push complexity |
|
| Pop complexity |
|
| Gravity Pull filter | In-place via std::remove_if + erase — |
StackPlanet enforces Last-In-First-Out ordering via std::stack<T>.
| Property | Value |
|---|---|
| Backing container | std::stack<T> |
| Access pattern | LIFO — top element only |
| Push complexity | |
| Pop complexity | |
| Gravity Pull filter | Drain-and-rebuild — |
QueuePlanet enforces First-In-First-Out ordering via std::queue<T>.
| Property | Value |
|---|---|
| Backing container | std::queue<T> |
| Access pattern | FIFO — front element only |
| Push complexity | |
| Pop complexity | |
| Gravity Pull filter | Drain-and-rebuild — |
| Class | Role | Key Feature |
|---|---|---|
SolarSystem<T> |
Top-level orchestrator | Owns all planets via vector<unique_ptr<BasePlanet<T>>>. |
Star (internal struct) |
Metadata controller | Stores planet_count and element_count for |
BasePlanet<T> |
Abstract interface | Pure virtual contract: push, pop, size, display, removeBelow. |
PlanetFactory<T> |
Factory creator | Instantiates the correct derived type from a PlanetType enum. |
The SolarSystem architecture maps directly to a real-world data center. Each abstraction in the codebase has a tangible counterpart:
Mapping SolarSystem components to data center infrastructure.
| SolarSystem Component | Real-World Counterpart | Role |
|---|---|---|
SolarSystem<T> |
Data Center | Central orchestrator that owns and manages all resources. |
Star (internal struct) |
Control Plane / Dashboard | Tracks global metrics ( |
BasePlanet<T> |
Abstract Storage Interface | Polymorphic contract that all storage backends must implement. |
VectorPlanet<T> |
Random-Access Array Store | Indexed storage with |
StackPlanet<T> |
LIFO Message Queue | Last-in-first-out buffer (e.g., undo history, call stack). |
QueuePlanet<T> |
FIFO Task Queue | First-in-first-out pipeline (e.g., job scheduler, event bus). |
PlanetFactory<T> |
Provisioning Service | Factory that spins up new storage instances on demand. |
pushToPlanet() |
Write / Enqueue | Inserts a record into a specific storage backend. |
deleteElement() |
Dequeue / Pop | Removes a single record following the backend's ordering. |
removePlanet() (Black Hole) |
Decommission Server | Destroys a storage node and reclaims all its memory. |
gravityPull() |
Garbage Collection / TTL Sweep | Bulk-removes stale records below a threshold across all nodes. |
resetSystem() (Supernova) |
Full Cluster Teardown | Destroys every node and resets all counters to zero. |
std::unique_ptr |
Exclusive Resource Lock | Guarantees single-owner semantics — automatic deallocation on scope exit. |
SolarSystem/
├── assets/
│ ├── architecture_diagram.png # High-level system architecture
│ ├── star_core.png # Star controller visualization
│ ├── vector_ring.png # VectorPlanet visualization
│ ├── stack_silo.png # StackPlanet visualization
│ ├── queue_belt.png # QueuePlanet visualization
│ └── analogy_visualization.png # Data center analogy diagram
├── include/
│ ├── Planet.hpp # BasePlanet<T>, derived classes, PlanetFactory<T>
│ └── SolarSystem.hpp # SolarSystem<T> class (encapsulated controller)
├── src/
│ ├── main.cpp # Application entry point
│ └── SolarSystem.cpp # Explicit template instantiation
├── tests/
│ └── unit_tests.cpp # Google Test unit tests
├── .github/
│ └── workflows/
│ └── cpp-ci.yml # CI pipeline (build + test on push)
├── CMakeLists.txt # CMake build configuration
├── Doxyfile # Doxygen configuration for API docs
└── README.md
The gravityPull(threshold) operation performs a bulk filter across every planet, removing all elements whose value falls below the threshold. Its cost is
for each planet p_i in planets: // p iterations
for each element e_j in p_i: // m iterations (per planet)
if e_j < threshold:
remove e_j
star.element_count -= total_removed // O(1) counter update
| Metric | Value | Explanation |
|---|---|---|
| Time | Outer loop visits |
|
| Space | Stack/Queue planets require a temporary container to rebuild; VectorPlanet uses in-place erase-remove with |
Implementation details:
-
VectorPlanet uses the erase-remove idiom (
std::remove_if+erase) for in-place filtering — zero temporary allocations. - StackPlanet / QueuePlanet lack iterator access (container adaptors), so elements are drained into a temporary, filtered, and moved back.
- The
star.element_countcounter is decremented by the total removed count in$O(1)$ after the sweep.
#include "SolarSystem.hpp"
int main() {
// Initialize a SolarSystem storing integers
SolarSystem<int> system;
// Add planets via Factory Pattern (no manual new/delete)
system.addPlanet(PlanetType::Stack); // Planet 0: LIFO
system.addPlanet(PlanetType::Vector); // Planet 1: Random-access
system.addPlanet(PlanetType::Queue); // Planet 2: FIFO
// Push elements into the Stack planet
system.pushToPlanet(0, 42);
system.pushToPlanet(0, 17);
system.pushToPlanet(0, 99);
// Display all planets and their contents
system.travelPlanet();
// Gravity Pull: remove all elements < 20
system.gravityPull(20); // 17 is absorbed; 42 and 99 survive
// Supernova: destroy the entire system (RAII — all memory freed)
system.supernova();
// system.getPlanetCount() == 0
// system.getElementCount() == 0
return 0;
}Key point: No
new,delete, or manual memory management appears anywhere.std::unique_ptrdestructors handle deallocation automatically when planets are removed or the system is reset.
This project deliberately avoids legacy C++ memory patterns in favor of modern idioms introduced in C++11/14/17.
The most impactful architectural decision was replacing all manual heap management with RAII smart pointers:
| Legacy Pattern | Modern Replacement | Benefit |
|---|---|---|
new BasePlanet<T>(...) |
std::make_unique<VectorPlanet<T>>() |
Eliminates raw pointer ownership ambiguity. |
Manual delete
|
Automatic unique_ptr destructor |
Guarantees deallocation — even when exceptions are thrown. |
| Raw pointer arrays | std::vector<std::unique_ptr<...>> |
Resizable, bounds-aware, RAII-managed container of owners. |
| Copy-heavy transfers |
std::move() semantics |
Transfers ownership in |
char type flags |
enum class PlanetType |
Compile-time type safety with scoped enumerators. |
C-style casts (int)x
|
static_cast<int>(x) |
Explicit, searchable, and prevents unsafe conversions. |
Every allocation path in SolarSystem follows RAII:
- Planet creation —
PlanetFactory<T>::create()returns aunique_ptr. Ownership transfers to theplanetsvector viastd::move. - Planet destruction (
removePlanet) — Erasing theunique_ptrfrom the vector triggers the destructor chain:unique_ptr→BasePlanet<T>virtual destructor → derived class destructor → internalvector<T>/stack<T>/queue<T>destructor. Zero manual cleanup. - Full reset (
resetSystem) —planets.clear()destroys everyunique_ptrin sequence. After the call, zero heap memory remains allocated for any planet or element.
This design makes memory leaks, double-frees, and dangling pointers structurally impossible under normal execution flow.
Planet names are stored as std::string instead of raw char* arrays. This eliminates buffer overflows, manual strlen/strcpy calls, and provides automatic deallocation when the owning object is destroyed — another RAII guarantee at zero additional cost.
- C++17 compatible compiler (GCC 7+, Clang 5+, MSVC 2017+)
- CMake 3.14+ (GTest is fetched automatically via FetchContent)
# Configure
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
# Build
cmake --build build --config Release
# Run application
./build/SolarSystem
# Run unit tests
cd build && ctest --output-on-failure --verbose# Build application
g++ -std=c++17 -Wall -Wextra -I include -o SolarSystem src/main.cpp src/SolarSystem.cpp
# Run
./SolarSystemThe project includes 22 unit tests covering:
- pushToPlanet — Push to all planet types, boundary conditions, invalid indices.
- removePlanet (Black Hole) — Planet destruction, element count decrements, edge cases.
- gravityPull — Threshold filtering across all planet types, boundary values.
- resetSystem (Supernova) — Full system destruction and RAII verification.
- Element Count Validation — After every operation,
star.element_countis verified against the actual sum of all planet elements.
Full API documentation is auto-generated with Doxygen and deployed to GitHub Pages on every push to main.
Live URL: https://mamitrkr.github.io/SolarSystem/
# Install Doxygen (Ubuntu/Debian)
sudo apt-get install doxygen
# Generate HTML documentation
doxygen Doxyfile
# Open in browser
open docs/html/index.html # macOS
xdg-open docs/html/index.html # Linux
start docs/html/index.html # WindowsThe CI pipeline (.github/workflows/cpp-ci.yml) handles deployment automatically. To enable it:
- Enable GitHub Pages — Go to your repository Settings → Pages.
- Source — Select GitHub Actions as the deployment source.
- Push to
main— Thedocsjob in the workflow will:- Install Doxygen on the CI runner.
- Run
doxygen Doxyfileto generatedocs/html/. - Upload the HTML output as a Pages artifact.
- Deploy it to
https://mamitrkr.github.io/SolarSystem/.
- Add to CV — Use the live URL as a portfolio link in your Erasmus application.
Note: The first deployment may take 1–2 minutes. Subsequent pushes update the site automatically.
This project is licensed under the MIT License.