/* Copyright (C) 2021,2022 fef . All rights reserved. */ #pragma once #include #include /** * @brief Get the number of elements in a statically allocated array. * * @param a The array * @returns The number of elements */ #define ARRAY_SIZE(a) ( sizeof(a) / sizeof((a)[0]) ) #define abs(x) ({ \ typeof(x) __x = (x); \ __x < 0 ? -__x : +__x; \ }) #define max(a, b) ({ \ typeof(a) __a = (a); \ typeof(b) __b = (b); \ __a > __b ? __a : __b; \ }) #define min(a, b) ({ \ typeof(a) __a = (a); \ typeof(b) __b = (b); \ __a < __b ? __a : __b; \ }) /** @brief Get type type of a structure member. */ #define __typeof_member(type, member) typeof( ((type *)0)->member ) /** * @brief Cast a pointer to a struct member out to the containing structure. * * @param ptr Pointer to the struct member * @param type Type of the containing structure * @param member Name of the member within the containing structure * @returns Pointer to the containing structure */ #define container_of(ptr, type, member) ({ \ /* implicit type check to avoid obvious mistakes */ \ __typeof_member(type, member) *__membptr = (ptr); \ (type *)( (void *)__membptr - offsetof(type, member) ); \ }) /** @brief Determine whether `ptr` is kinda sus. */ static __always_inline bool sus_nil(const void *ptr) { return ptr < (void *)0x1000; } static __always_inline uintmax_t _align_floor(uintmax_t ptr, usize size) { return ptr - ptr % size; } #define align_floor(ptr, size) ( (typeof(ptr))_align_floor((uintptr_t)(ptr), size) ) static __always_inline uintmax_t _align_ceil(uintmax_t ptr, usize size) { uintmax_t aligned = ptr - ptr % size; if (aligned < ptr) aligned += size; return aligned; } #define align_ceil(ptr, size) ( (typeof(ptr))_align_ceil((uintmax_t)(ptr), size) )