|
2 | 2 | #define COMPILER_HPP_ |
3 | 3 |
|
4 | 4 | /// @file |
5 | | -/// Contains compiler specific attributes and macros. These should be the only MACROS in the system due to how the attributes are different on |
| 5 | +/// @brief Contains compiler specific attributes and macros. These should be the only MACROS in the system due to how the attributes are different on |
6 | 6 | /// different compilers. |
7 | 7 |
|
| 8 | +#if defined(__GNUC__) or defined(__clang__) |
| 9 | +/// @brief Defines a compiler-specific attribute |
8 | 10 | #define ATTRIBUTE(x) __attribute__(x) |
| 11 | +#endif |
| 12 | + |
| 13 | +/// @def LINKER_SECTION |
| 14 | +/// @brief Places a variable or function in a specific linker section |
| 15 | + |
| 16 | +/// @def NAKED |
| 17 | +/// @brief Marks a function as naked, meaning it has no prologue/epilogue |
| 18 | + |
| 19 | +/// @def USED |
| 20 | +/// @brief Marks a variable or function as used, preventing the compiler from optimizing it away |
| 21 | + |
| 22 | +/// @def ALWAYS_INLINE |
| 23 | +/// @brief Marks a function as always inline, preventing the compiler from generating a separate function call |
| 24 | + |
| 25 | +/// @def ISR |
| 26 | +/// @brief Marks a function as an interrupt service routine. This applies several attributes to ensure the functions are used and do not have a |
| 27 | +/// prologue/epilogue. |
| 28 | + |
9 | 29 | #if defined(UNITTEST) |
| 30 | + |
| 31 | +// Unit Testing on GCC/Clang typically will not need or want the on-target attributes defined as |
| 32 | +// they interfere with the normal operation of the unit tests. |
| 33 | + |
10 | 34 | #define LINKER_SECTION(x) |
11 | 35 | #define NAKED |
12 | 36 | #define USED __attribute__((used)) |
13 | 37 | #define ALWAYS_INLINE |
14 | 38 | #define ISR |
15 | 39 | #elif (defined(__GNUC__) or defined(__clang__)) and defined(__arm__) |
| 40 | + |
| 41 | +// On GCC/Clang for ARM, define the attributes for the target |
| 42 | + |
16 | 43 | #define LINKER_SECTION(x) ATTRIBUTE((used, section(x))) |
17 | 44 | #define NAKED ATTRIBUTE((used, naked)) |
18 | 45 | #define USED ATTRIBUTE((used)) |
|
35 | 62 | #define PRIz "zu" |
36 | 63 | #endif |
37 | 64 |
|
38 | | -// clang-format off |
39 | | -inline size_t operator""_Z( unsigned long long int value) { |
40 | | - return size_t(value); |
| 65 | +/// @brief User-defined literal for size_t |
| 66 | +inline size_t operator""_Z(unsigned long long int value) { |
| 67 | + return static_cast<size_t>(value); |
41 | 68 | } |
42 | | -// clang-format on |
43 | 69 |
|
44 | | -/// On 32 bit system the precision type that is passed around on the stack is a float, on 64 bit systems it is a double. |
45 | 70 | #if defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ == 8 |
| 71 | +/// On 64 bit system the precision type that is passed around on the stack is a double. |
46 | 72 | using precision = double; |
47 | | -#else |
| 73 | +#else // 32 bit systems |
| 74 | +/// On 32 bit system the precision type that is passed around on the stack is a float. |
48 | 75 | using precision = float; |
49 | 76 | #endif |
50 | 77 |
|
51 | 78 | /// A concept that requires the type to implement all the comparison operators |
52 | 79 | template <typename TYPE> |
53 | | -concept Comparible = requires(std::remove_reference_t<TYPE> const& t, std::remove_reference_t<TYPE> const& u) { |
| 80 | +concept Comparable = requires(std::remove_reference_t<TYPE> const& t, std::remove_reference_t<TYPE> const& u) { |
54 | 81 | { t < u } -> std::convertible_to<bool>; |
55 | 82 | { t <= u } -> std::convertible_to<bool>; |
56 | 83 | { t > u } -> std::convertible_to<bool>; |
|
0 commit comments