#include <iostream>
#include <string>
#include <variant>
#include <type_traits>
// 1. Define specific component structs
struct Circle {
float radius;
};
struct Rectangle {
float width;
float height;
};
// 2. Define metadata structure using std::string instead of raw char arrays
struct Metadata {
std::string name;
bool is_active;
};
// 3. Define the main container struct using std::variant for type-safe variants
struct Shape {
int id;
Metadata metadata;
// std::variant handles the type tagging and safety automatically
std::variant<Circle, Rectangle> dimensions;
};
/**
* @brief Safely inspects shape properties using std::visit (compile-time pattern matching).
* @param shape Reference to the Shape object.
*/
void print_shape_properties(const Shape& shape) {
std::cout << "Shape ID: " << shape.id << "\n";
std::cout << "Shape Name: " << shape.metadata.name << "\n";
std::cout << "Status: " << (shape.metadata.is_active ? "Active" : "Inactive") << "\n";
// std::visit inspects whichever type is currently active in the variant
std::visit([](const auto& dim) {
using T = std::decay_t<decltype(dim)>;
if constexpr (std::is_same_v<T, Circle>) {
std::cout << "Type: Circle\n";
std::cout << "Radius: " << dim.radius << "\n";
} else if constexpr (std::is_same_v<T, Rectangle>) {
std::cout << "Type: Rectangle\n";
std::cout << "Width: " << dim.width << ", Height: " << dim.height << "\n";
}
}, shape.dimensions);
std::cout << "------------------------------------\n";
}
int main() {
// Modern design initializer lists
Shape my_circle{
.id = 101,
.metadata = {.name = "Unit Circle", .is_active = true},
.dimensions = Circle{5.5f}
};
Shape my_rectangle{
.id = 102,
.metadata = {.name = "Bounding Box", .is_active = false},
.dimensions = Rectangle{10.0f, 20.0f}
};
print_shape_properties(my_circle);
print_shape_properties(my_rectangle);
}
/*
run:
Shape ID: 101
Shape Name: Unit Circle
Status: Active
Type: Circle
Radius: 5.5
------------------------------------
Shape ID: 102
Shape Name: Bounding Box
Status: Inactive
Type: Rectangle
Width: 10, Height: 20
------------------------------------
*/