Update Docs.md

This commit is contained in:
Spencer Conlon 2024-12-24 05:38:34 +00:00
parent 500b070900
commit 806bffe77e

647
Docs.md
View File

@ -0,0 +1,647 @@
# `gcml.h` Documentation
`gcml.h` is a comprehensive C/C++ header file that provides a collection of powerful and versatile macros designed to simplify common programming tasks. These macros enhance code readability, maintainability, and efficiency by encapsulating repetitive patterns and providing utility functions for various operations such as debugging, logging, memory management, and more.
---
## Table of Contents
1. [General Utility Macros](#1-general-utility-macros)
2. [Debugging and Logging Macros](#2-debugging-and-logging-macros)
3. [Assertion Macros](#3-assertion-macros)
4. [Stringification Macros](#4-stringification-macros)
5. [Token Pasting Macros](#5-token-pasting-macros)
6. [Memory Management Macros](#6-memory-management-macros)
7. [Type Casting Macros](#7-type-casting-macros)
8. [Bit Manipulation Macros](#8-bit-manipulation-macros)
9. [Compile-Time Assertion Macro](#9-compile-time-assertion-macro)
10. [Deprecation Warning Macros](#10-deprecation-warning-macros)
11. [Loop Macros](#11-loop-macros)
12. [Swap Macros](#12-swap-macros)
13. [Execute Once Macros](#13-execute-once-macros)
14. [Additional Utility Macros](#14-additional-utility-macros)
15. [Utility Macros](#15-utility-macros)
16. [Best Practices and Considerations](#16-best-practices-and-considerations)
---
## 1. General Utility Macros
### `MIN(a, b)`
**Description:**
Returns the smaller of two values `a` and `b`.
**Usage Example:**
```cpp
int a = 5, b = 10;
int min_val = MIN(a, b); // min_val = 5
```
---
### `MAX(a, b)`
**Description:**
Returns the larger of two values `a` and `b`.
**Usage Example:**
```cpp
int a = 5, b = 10;
int max_val = MAX(a, b); // max_val = 10
```
---
### `ARRAY_SIZE(arr)`
**Description:**
Calculates the number of elements in an array `arr`.
**Usage Example:**
```cpp
int arr[] = {1, 2, 3, 4, 5};
size_t size = ARRAY_SIZE(arr); // size = 5
```
---
### `UNUSED(x)`
**Description:**
Suppresses compiler warnings for unused variables `x`.
**Usage Example:**
```cpp
void func(int used, int unused) {
UNUSED(unused);
// Function implementation
}
```
---
### `ALIGN_UP(x, align)`
**Description:**
Aligns a value `x` upwards to the nearest multiple of `align`.
**Usage Example:**
```cpp
size_t aligned = ALIGN_UP(13, 8); // aligned = 16
```
---
### `ALIGN_DOWN(x, align)`
**Description:**
Aligns a value `x` downwards to the nearest multiple of `align`.
**Usage Example:**
```cpp
size_t aligned = ALIGN_DOWN(13, 8); // aligned = 8
```
---
## 2. Debugging and Logging Macros
### `DEBUG_PRINT(fmt, ...)`
**Description:**
Prints debug messages with file name, line number, and function name. Only active when `DEBUG` is defined.
**Usage Example:**
```cpp
DEBUG_PRINT("Value of x: %d", x);
```
---
### `LOG_INFO(fmt, ...)`
**Description:**
Logs informational messages to `stdout`.
**Usage Example:**
```cpp
LOG_INFO("Application started successfully.");
```
---
### `LOG_WARN(fmt, ...)`
**Description:**
Logs warning messages to `stderr`.
**Usage Example:**
```cpp
LOG_WARN("Low memory detected.");
```
---
### `LOG_ERROR(fmt, ...)`
**Description:**
Logs error messages to `stderr`.
**Usage Example:**
```cpp
LOG_ERROR("Failed to open file: %s", filename);
```
---
### `LOG_FATAL(fmt, ...)`
**Description:**
Logs fatal error messages to `stderr` and exits the program.
**Usage Example:**
```cpp
LOG_FATAL("Unrecoverable error occurred.");
```
---
## 3. Assertion Macros
### `ASSERT(cond, fmt, ...)`
**Description:**
Asserts a condition `cond` and logs an error message if the condition is false. Only active when `NDEBUG` is not defined.
**Usage Example:**
```cpp
ASSERT(ptr != NULL, "Pointer 'ptr' should not be NULL.");
```
---
## 4. Stringification Macros
### `STRINGIFY(x)`
**Description:**
Converts a macro argument `x` to a string literal.
**Usage Example:**
```cpp
#define VERSION 1
const char* version_str = STRINGIFY(VERSION); // "1"
```
---
### `TOSTRING(x)`
**Description:**
Ensures that `x` is expanded before stringification.
**Usage Example:**
```cpp
#define VERSION_MAJOR 2
#define VERSION_MINOR 5
const char* version = TOSTRING(VERSION_MAJOR) "." TOSTRING(VERSION_MINOR); // "2.5"
```
---
## 5. Token Pasting Macros
### `CONCAT(a, b)`
**Description:**
Concatenates two tokens `a` and `b`.
**Usage Example:**
```cpp
int CONCAT(temp, 1) = 10; // Expands to temp1
```
---
### `CONCAT3(a, b, c)`
**Description:**
Concatenates three tokens `a`, `b`, and `c`.
**Usage Example:**
```cpp
int CONCAT3(var, _, 1) = 20; // Expands to var_1
```
---
## 6. Memory Management Macros
### `SAFE_MALLOC(ptr, size)`
**Description:**
Allocates memory of `size` bytes and assigns it to `ptr`. Logs a fatal error and exits if allocation fails.
**Usage Example:**
```cpp
int *array = NULL;
SAFE_MALLOC(array, sizeof(int) * 10);
// Use array...
SAFE_FREE(array);
```
---
### `SAFE_CALLOC(ptr, count, type)`
**Description:**
Allocates zero-initialized memory for `count` elements of type `type` and assigns it to `ptr`. Logs a fatal error and exits if allocation fails.
**Usage Example:**
```cpp
int *array = NULL;
SAFE_CALLOC(array, 10, int);
// Use array...
SAFE_FREE(array);
```
---
### `SAFE_FREE(ptr)`
**Description:**
Frees the memory pointed to by `ptr` and sets `ptr` to `NULL` to prevent dangling pointers.
**Usage Example:**
```cpp
SAFE_FREE(array);
```
---
## 7. Type Casting Macros
### `SAFE_CAST(ptr, type)`
**Description:**
Safely casts a pointer `ptr` to a specified type `type`.
**Usage Example:**
```cpp
void *generic_ptr = malloc(sizeof(int));
int *int_ptr = SAFE_CAST(generic_ptr, int*);
```
---
## 8. Bit Manipulation Macros
### `SET_BIT(x, pos)`
**Description:**
Sets the bit at position `pos` in variable `x`.
**Usage Example:**
```cpp
unsigned int flags = 0;
SET_BIT(flags, 2); // Sets the 3rd bit
```
---
### `CLEAR_BIT(x, pos)`
**Description:**
Clears the bit at position `pos` in variable `x`.
**Usage Example:**
```cpp
CLEAR_BIT(flags, 2); // Clears the 3rd bit
```
---
### `TOGGLE_BIT(x, pos)`
**Description:**
Toggles the bit at position `pos` in variable `x`.
**Usage Example:**
```cpp
TOGGLE_BIT(flags, 1); // Toggles the 2nd bit
```
---
### `CHECK_BIT(x, pos)`
**Description:**
Checks if the bit at position `pos` in variable `x` is set. Returns a non-zero value if set, zero otherwise.
**Usage Example:**
```cpp
if (CHECK_BIT(flags, 1)) {
LOG_INFO("Bit 1 is set.");
}
```
---
## 9. Compile-Time Assertion Macro
### `STATIC_ASSERT(expr, msg)`
**Description:**
Performs a compile-time assertion to ensure that `expr` is true. If not, compilation fails with the message `msg`.
**Usage Example:**
```cpp
STATIC_ASSERT(sizeof(int) == 4, "Integer size is not 4 bytes.");
```
---
## 10. Deprecation Warning Macros
### `DEPRECATED(msg)`
**Description:**
Marks a function or variable as deprecated with a custom message `msg`. This provides a compiler warning when the deprecated entity is used.
**Usage Example:**
```cpp
DEPRECATED("Use new_function() instead.")
void old_function() {
LOG_WARN("This function is deprecated.");
}
```
---
## 11. Loop Macros
### `FOREACH(item, array)`
**Description:**
Iterates over each element in an array `array`, assigning each element's address to `item`.
**Usage Example:**
```cpp
int arr[] = {1, 2, 3, 4, 5};
int *item;
FOREACH(item, arr) {
LOG_INFO("Array element: %d", *item);
}
```
---
### `REPEAT(n, block)`
**Description:**
Repeats a block of code `n` times.
**Usage Example:**
```cpp
REPEAT(3, {
LOG_INFO("Repeating this message.");
});
```
---
## 12. Swap Macros
### `SWAP(a, b)`
**Description:**
Swaps the values of two variables `a` and `b`. Both variables must be of the same type.
**Usage Example:**
```cpp
int a = 10, b = 20;
SWAP(a, b);
// Now a = 20, b = 10
```
---
### `SWAP_INPLACE(a, b)`
**Description:**
Swaps the values of two integer variables `a` and `b` without using a temporary variable. Uses XOR bitwise operations.
**Usage Example:**
```cpp
int x = 5, y = 10;
SWAP_INPLACE(x, y);
// Now x = 10, y = 5
```
*Note:* This macro is limited to integer types and should be used with caution to avoid undefined behavior.
---
## 13. Execute Once Macros
### `DO_ONCE(block)`
**Description:**
Executes a block of code `block` only once, regardless of how many times the macro is called.
**Usage Example:**
```cpp
DO_ONCE({
LOG_INFO("This message is printed only once.");
});
DO_ONCE({
LOG_INFO("This message will not be printed again.");
});
```
---
### `EXECUTE_ONCE(block)`
**Description:**
Creates a `do-while` loop that executes a block of code `block` exactly once.
**Usage Example:**
```cpp
EXECUTE_ONCE({
initialize_system();
});
```
---
## 14. Additional Utility Macros
### `SAFE_REALLOC(ptr, size)`
**Description:**
Reallocates memory for pointer `ptr` to a new size `size` bytes. Logs a fatal error and exits if reallocation fails.
**Usage Example:**
```cpp
int *data = malloc(5 * sizeof(int));
// Initialize data...
// Reallocate to hold more integers
SAFE_REALLOC(data, 10 * sizeof(int));
// Use the reallocated data...
SAFE_FREE(data);
```
---
### `UNUSED_FUNCTION`
**Description:**
Marks a function as unused to suppress compiler warnings about unused functions.
**Usage Example:**
```cpp
UNUSED_FUNCTION void debug_helper() {
DEBUG_PRINT("This is a debug helper function.");
}
```
---
### `TO_STRING(value)`
**Description:**
Converts a value `value` to a string at compile time.
**Usage Example:**
```cpp
#define VERSION_MAJOR 2
#define VERSION_MINOR 5
const char* version = TO_STRING(VERSION_MAJOR) "." TO_STRING(VERSION_MINOR);
// version = "2.5"
```
---
### `UNIQUE_ID(prefix)`
**Description:**
Generates a unique identifier by appending the current line number to a given `prefix`.
**Usage Example:**
```cpp
int UNIQUE_ID(temp_) = 100; // Expands to temp_23 if on line 23
```
---
### `FORCE_CAST(value, type)`
**Description:**
Forces a value `value` to evaluate to a specific type `type` without altering its binary representation.
**Usage Example:**
```cpp
float f = 3.14f;
int i = FORCE_CAST(f, int); // Reinterprets the bits of f as an int
```
*Warning:*
This macro performs a low-level operation and can lead to undefined behavior if misused.
---
### `IS_ALIGNED(ptr, align)`
**Description:**
Checks if a pointer `ptr` is aligned to a specified boundary `align`. Returns a non-zero value if aligned, zero otherwise.
**Usage Example:**
```cpp
int x;
if (IS_ALIGNED(&x, 4)) {
LOG_INFO("Variable x is 4-byte aligned.");
}
```
---
### `COUNT_SET_BITS(x)`
**Description:**
Counts the number of bits set to `1` in the integer `x`.
**Usage Example:**
```cpp
unsigned int flags = 0b1011;
int count = COUNT_SET_BITS(flags); // count = 3
```
---
### `CEIL_DIV(numerator, denominator)`
**Description:**
Calculates the ceiling of the division between two integers `numerator` and `denominator`.
**Usage Example:**
```cpp
int pages = CEIL_DIV(total_items, items_per_page);
```
---
### `CONCAT_WITH_UNDERSCORE(a, b)`
**Description:**
Concatenates two tokens `a` and `b` with an underscore `_` separating them.
**Usage Example:**
```cpp
int CONCAT_WITH_UNDERSCORE(var, 1) = 50; // Expands to var_1
```
---
## 15. Utility Macros
### `OFFSET_OF(type, member)`
**Description:**
Calculates the byte offset of a member `member` within a struct of type `type`.
**Usage Example:**
```cpp
typedef struct {
int id;
char name[50];
} Person;
size_t offset = OFFSET_OF(Person, name); // Offset of 'name' within 'Person'
```
---
### `CONTAINER_OF(ptr, type, member)`
**Description:**
Retrieves the pointer to the containing struct from a member pointer `ptr`. Given the type `type` and member `member`, it calculates the address of the parent struct.
**Usage Example:**
```cpp
typedef struct {
int id;
char name[50];
} Person;
Person person = {1, "Alice"};
int *id_ptr = &person.id;
Person *p = CONTAINER_OF(id_ptr, Person, id);
// p points to 'person'
```