#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_STR 128
#define MAX_HOBBIES 16
#define MAX_METADATA 16
#define MAX_SCORES 16
// Simple date struct (replacement for chrono)
typedef struct {
int year;
int month;
int day;
} Date;
// Address struct
typedef struct {
char street[MAX_STR];
char city[MAX_STR];
int zip;
} Address;
// Variant replacement (manual tagged union)
typedef enum {
ID_INT,
ID_STRING,
ID_INT_ARRAY
} IdType;
typedef struct {
IdType type;
union {
int intValue;
char strValue[MAX_STR];
int intArray[8];
};
} Variant;
// Metadata (replacement for std::map)
typedef struct {
char key[MAX_STR];
char value[MAX_STR];
} KeyValue;
// Flags (bitfields)
typedef struct {
unsigned isAdmin : 1;
unsigned isGuest : 1;
unsigned isVerified: 1;
} Flags;
// Function pointer type
typedef void (*PrintFn)(void*);
// Static members (global variables)
int population = 0;
int allocatedInts = 0;
// Person struct
typedef struct {
Address homeAddress;
int favoriteNumbers[5];
char* nickname;
Date birthDate;
char notes[MAX_STR];
char* middleName;
char hobbies[MAX_HOBBIES][MAX_STR];
int hobbyCount;
enum Status { Active, Inactive, Unknown } status;
Variant id;
KeyValue metadata[MAX_METADATA];
int metadataCount;
Flags flags;
int scores[MAX_SCORES];
int scoreCount;
PrintFn extraPrinter;
} Person;
// Set metadata
void setMeta(Person* p, const char* key, const char* value) {
if (p->metadataCount < MAX_METADATA) {
strcpy(p->metadata[p->metadataCount].key, key);
strcpy(p->metadata[p->metadataCount].value, value);
p->metadataCount++;
}
}
// Print person
void printPerson(const Person* p) {
printf("Address: %s, %s %d\n",
p->homeAddress.street,
p->homeAddress.city,
p->homeAddress.zip);
printf("Favorite Numbers: ");
for (int i = 0; i < 5; i++) printf("%d ", p->favoriteNumbers[i]);
printf("\n");
printf("Nickname: %s\n", p->nickname ? p->nickname : "(none)");
printf("Birth Date: %04d-%02d-%02d\n",
p->birthDate.year,
p->birthDate.month,
p->birthDate.day);
printf("Notes: %s\n", p->notes);
printf("Middle Name: %s\n", p->middleName ? p->middleName : "(none)");
printf("Hobbies: ");
for (int i = 0; i < p->hobbyCount; i++)
printf("%s, ", p->hobbies[i]);
printf("\n");
printf("Status: ");
switch (p->status) {
case Active: printf("Active\n"); break;
case Inactive: printf("Inactive\n"); break;
default: printf("Unknown\n"); break;
}
printf("ID (variant): ");
switch (p->id.type) {
case ID_INT:
printf("int: %d\n", p->id.intValue);
break;
case ID_STRING:
printf("string: %s\n", p->id.strValue);
break;
case ID_INT_ARRAY:
printf("int array: ");
for (int i = 0; i < 8; i++) printf("%d ", p->id.intArray[i]);
printf("\n");
break;
}
printf("Metadata:\n");
for (int i = 0; i < p->metadataCount; i++)
printf(" %s = %s\n", p->metadata[i].key, p->metadata[i].value);
printf("Flags: isAdmin=%d isGuest=%d isVerified=%d\n",
p->flags.isAdmin,
p->flags.isGuest,
p->flags.isVerified);
printf("Scores: ");
for (int i = 0; i < p->scoreCount; i++)
printf("%d ", p->scores[i]);
printf("\n");
printf("Population: %d\n", population);
printf("Allocated ints: %d\n", allocatedInts);
if (p->extraPrinter)
p->extraPrinter((void*)p);
}
// Extra printer
void extraPrinterFn(void* ptr) {
Person* p = (Person*)ptr;
printf(" [extra] nickname length: %zu\n",
p->nickname ? strlen(p->nickname) : 0);
}
int main() {
Person p = {0};
population++;
strcpy(p.homeAddress.street, "Baxter");
strcpy(p.homeAddress.city, "New York");
p.homeAddress.zip = 426900;
int favs[5] = {7, 18, 27, 42, 81};
memcpy(p.favoriteNumbers, favs, sizeof(favs));
p.nickname = malloc(10);
strcpy(p.nickname, "Orion");
p.birthDate = (Date){1026, 6, 15};
strcpy(p.notes, "Neo likes C/C#/Python and structs");
p.middleName = malloc(MAX_STR);
strcpy(p.middleName, "ECHO-9");
strcpy(p.hobbies[0], "Coding");
strcpy(p.hobbies[1], "Dreaming");
strcpy(p.hobbies[2], "Walking");
strcpy(p.hobbies[3], "Sci-Fi Movies");
p.hobbyCount = 4;
p.status = Active;
p.id.type = ID_INT;
p.id.intValue = 42;
setMeta(&p, "role", "Explorer");
setMeta(&p, "level", "9");
p.flags.isAdmin = 1;
p.flags.isVerified = 1;
p.scores[p.scoreCount++] = 100;
p.scores[p.scoreCount++] = 95;
p.extraPrinter = extraPrinterFn;
printPerson(&p);
free(p.nickname);
free(p.middleName);
return 0;
}
/*
run:
Address: Baxter, New York 426900
Favorite Numbers: 7 18 27 42 81
Nickname: Orion
Birth Date: 1026-06-15
Notes: Neo likes C/C#/Python and structs
Middle Name: ECHO-9
Hobbies: Coding, Dreaming, Walking, Sci-Fi Movies,
Status: Active
ID (variant): int: 42
Metadata:
role = Explorer
level = 9
Flags: isAdmin=1 isGuest=0 isVerified=1
Scores: 100 95
Population: 1
Allocated ints: 0
[extra] nickname length: 5
*/