MMgr v1.0.0
Zero-heap memory manager in C11. One borrowed buffer, carved by asserted offset.
Loading...
Searching...
No Matches
mmgr_types.h
1/**
2 * @brief The MMgr scalar types, and the assertions that pin their widths.
3 *
4 * @warning Not standalone: mmgr_config.h must set MMGR_WORD_BITS and MMGR_INDEX_BITS first.
5 */
6#ifndef MMGR_TYPES_H
7#define MMGR_TYPES_H
8
9#include <stddef.h>
10#include <stdint.h>
11
12#include "config/mmgr_compiler_directives.h"
13
14/**
15 * @brief Fixed-width integers under MMgr names.
16 *
17 * @note The assertions further down fail the build if any of them is not the declared width.
18 */
19typedef uint8_t mmgr_u8;
20typedef uint16_t mmgr_u16;
21typedef uint32_t mmgr_u32;
22typedef uint64_t mmgr_u64;
23typedef int8_t mmgr_i8;
24typedef int16_t mmgr_i16;
25typedef int32_t mmgr_i32;
26typedef int64_t mmgr_i64;
27
28/**
29 * @brief Boolean carrier: bool under C++, _Bool otherwise.
30 */
31#ifdef __cplusplus
32typedef bool mmgr_bool;
33#else
34
35typedef _Bool mmgr_bool;
36#endif
37
38/**
39 * @brief The two mmgr_bool values, each cast so it carries the boolean type and not int.
40 */
41#define MMGR_TRUE ((mmgr_bool)1)
42#define MMGR_FALSE ((mmgr_bool)0)
43
44/**
45 * @brief Stops the build when this header is reached without the widths already chosen.
46 *
47 * @note mmgr_config.h sets both, then includes this file.
48 */
49#if !defined(MMGR_WORD_BITS) || !defined(MMGR_INDEX_BITS)
50#error "mmgr_types.h is not a standalone header - include mmgr_config.h, which sets the widths first"
51#endif
52
53/**
54 * @brief The unsigned and signed word types, both MMGR_WORD_BITS wide.
55 *
56 * @note mmgr_word carries every SWAR lane operation; mmgr_iword carries the signed results.
57 * @warning A MMGR_WORD_BITS that is not 16, 32 or 64 raises #error.
58 */
59#if MMGR_WORD_BITS == 64
60
61typedef mmgr_u64 mmgr_word;
62
63typedef mmgr_i64 mmgr_iword;
64#elif MMGR_WORD_BITS == 32
65typedef mmgr_u32 mmgr_word;
66typedef mmgr_i32 mmgr_iword;
67#elif MMGR_WORD_BITS == 16
68typedef mmgr_u16 mmgr_word;
69typedef mmgr_i16 mmgr_iword;
70#else
71#error "MMGR_WORD_BITS must be 16, 32 or 64 - see mmgr_config.h"
72#endif
73
74/**
75 * @brief The index type, MMGR_INDEX_BITS wide, used for every offset and length.
76 *
77 * @note The assertion below pins mmgr_idx no wider than mmgr_word.
78 * @warning A MMGR_INDEX_BITS that is not 16 or 32 raises #error.
79 */
80#if MMGR_INDEX_BITS == 32
81
82typedef mmgr_u32 mmgr_idx;
83#elif MMGR_INDEX_BITS == 16
84typedef mmgr_u16 mmgr_idx;
85#else
86#error "MMGR_INDEX_BITS must be 16 or 32 - see mmgr_config.h"
87#endif
88
89/**
90 * @brief Pins every type above to its declared width, and mmgr_idx inside mmgr_word.
91 *
92 * @note Each compares a declared width against the type's actual size.
93 */
94MMGR_STATIC_ASSERT(sizeof(mmgr_u8) == 1, "mmgr_u8 must be exactly 8 bits: this target has no 8-bit type");
95MMGR_STATIC_ASSERT(sizeof(mmgr_u16) * 8u == 16u, "mmgr_u16 must be exactly 16 bits");
96MMGR_STATIC_ASSERT(sizeof(mmgr_u32) * 8u == 32u, "mmgr_u32 must be exactly 32 bits");
97MMGR_STATIC_ASSERT(sizeof(mmgr_u64) * 8u == 64u, "mmgr_u64 must be exactly 64 bits");
98MMGR_STATIC_ASSERT(sizeof(mmgr_word) * 8u == MMGR_WORD_BITS, "mmgr_word must be exactly MMGR_WORD_BITS wide");
99MMGR_STATIC_ASSERT(sizeof(mmgr_iword) == sizeof(mmgr_word), "the signed word must be the same register as the word");
100MMGR_STATIC_ASSERT(sizeof(mmgr_idx) * 8u == MMGR_INDEX_BITS, "mmgr_idx must be exactly MMGR_INDEX_BITS wide");
101MMGR_STATIC_ASSERT(sizeof(mmgr_idx) <= sizeof(mmgr_word), "an index must fit the register it is carried in");
102
103/**
104 * @brief A one-byte enum used only to prove MMGR_ENUM_PACKED reaches the compiler.
105 *
106 * @note Its range needs a single byte, and so the assertion below fails exactly when packing is ignored.
107 * @warning A failure means MMGR_ENUM_PACKED expanded to nothing; the assertion message states the consequence.
108 */
109typedef enum MMGR_ENUM_PACKED
110{
111 MMGR_ENUM_PROBE_MIN = 0, /**< Low end of the probe range. */
112 MMGR_ENUM_PROBE_MAX = 255, /**< High end, the largest value one byte holds. */
113} MmgrEnumProbe;
114MMGR_STATIC_ASSERT(sizeof(MmgrEnumProbe) == 1,
115 "MMGR_ENUM_PACKED is not honored here, so no enum keeps its declared width and every "
116 "borrow offset computed from a struct containing one is wrong (TI: pass --small_enum)");
117
118#endif