Files
mr-library/include/mr-X/mr_service.h
MacRsh 8bfc6c9390 feat(service): Added service macro functions.
1.New macros for obtaining the number of variable parameters, adaptive parameter concatenation macros, and separated concatenation macros have been added (in preparation for the device tree).
2025-10-12 22:19:06 +08:00

214 lines
7.7 KiB
C

/**
* @copyright (c) 2024-2025, MacRsh
*
* @license SPDX-License-Identifier: Apache-2.0
*
* @date 2024-09-06 MacRsh First version
*/
#ifndef __MR_SERVICE_H__
#define __MR_SERVICE_H__
#include <libc/mr_compiler.h>
#include <libc/mr_types.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @addtogroup Service
* @{
*/
/**
* @brief This macro function gets the container of a member.
*
* @param _ptr The member pointer.
* @param _type The container type.
* @param _member The member.
* @return The member container.
*/
#define MR_CONTAINER_OF(_ptr, _type, _member) \
((void *)((char *)(_ptr) - (char *)((void *)&(((_type *)0)->_member))))
/**
* @brief This macro function gets the size of an array.
*
* @param _array The array.
* @return The array size.
*/
#define MR_ARRAY_SIZE(_array) (sizeof(_array) / sizeof((_array)[0]))
/**
* @brief This macro function gets the minimum value.
*
* @param _a The first value.
* @param _b The second value.
* @return The minimum value.
*/
#define MR_MIN(_a, _b) (((_a) < (_b)) ? (_a) : (_b))
/**
* @brief This macro function gets the maximum value.
*
* @param _a The first value.
* @param _b The second value.
* @return The maximum value.
*/
#define MR_MAX(_a, _b) (((_a) > (_b)) ? (_a) : (_b))
/**
* @brief This macro function aligns the value up.
*
* @param _x The value.
* @param _ali The alignment.
* @return The aligned value.
*/
#define MR_ALIGN_UP(_x, _ali) (((_x) + (_ali) - 1) & ~((_ali) - 1))
/**
* @brief This macro function aligns the value down.
*
* @param _x The value.
* @param _ali The alignment.
* @return The aligned value.
*/
#define MR_ALIGN_DOWN(_x, _ali) ((_x) & ~((_ali) - 1))
/**
* @brief This macro function makes a local variable.
*
* @param _type The local variable type.
* @param ... The local variable value.
*/
#define MR_MAKE_LOCAL(_type, ...) (&((_type){__VA_ARGS__}))
/**
* @brief This macro function gets the number of arguments.
*
* @param ... The arguments
* @return The number of arguments(0-63).
*/
#define MR_VA_ARGS_NUM(...) \
__MR_VA_ARGS_NUM(, ##__VA_ARGS__, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, \
53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, \
39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, \
25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, \
11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
#define __MR_VA_ARGS_NUM( \
_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, \
_17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, \
_32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, \
_47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, \
_62, _63, _n, ...) \
_n
/**
* @brief This macro function concatenates n strings.
*
* @param ... The strings.
* @return The concatenated string.
*/
#define MR_CAT(...) \
__MR_CAT(MR_CAT_, MR_VA_ARGS_NUM(__VA_ARGS__))(__VA_ARGS__)
#define __MR_CAT_IMPL(_a, ...) _a##__VA_ARGS__
#define __MR_CAT(_a, ...) __MR_CAT_IMPL(_a, __VA_ARGS__)
#define MR_CAT_0(_a, ...)
#define MR_CAT_1(_a, ...) _a
#define MR_CAT_2(_a, ...) __MR_CAT(_a, MR_CAT_1(__VA_ARGS__))
#define MR_CAT_3(_a, ...) __MR_CAT(_a, MR_CAT_2(__VA_ARGS__))
#define MR_CAT_4(_a, ...) __MR_CAT(_a, MR_CAT_3(__VA_ARGS__))
#define MR_CAT_5(_a, ...) __MR_CAT(_a, MR_CAT_4(__VA_ARGS__))
#define MR_CAT_6(_a, ...) __MR_CAT(_a, MR_CAT_5(__VA_ARGS__))
#define MR_CAT_7(_a, ...) __MR_CAT(_a, MR_CAT_6(__VA_ARGS__))
#define MR_CAT_8(_a, ...) __MR_CAT(_a, MR_CAT_7(__VA_ARGS__))
#define MR_CAT_9(_a, ...) __MR_CAT(_a, MR_CAT_8(__VA_ARGS__))
#define MR_CAT_10(_a, ...) __MR_CAT(_a, MR_CAT_9(__VA_ARGS__))
#define MR_CAT_11(_a, ...) __MR_CAT(_a, MR_CAT_10(__VA_ARGS__))
#define MR_CAT_12(_a, ...) __MR_CAT(_a, MR_CAT_11(__VA_ARGS__))
#define MR_CAT_13(_a, ...) __MR_CAT(_a, MR_CAT_12(__VA_ARGS__))
#define MR_CAT_14(_a, ...) __MR_CAT(_a, MR_CAT_13(__VA_ARGS__))
#define MR_CAT_15(_a, ...) __MR_CAT(_a, MR_CAT_14(__VA_ARGS__))
/**
* @brief This macro function concatenates n strings with a separator.
*
* @param _s The separator.
* @param ... The strings.
* @return The concatenated string.
*/
#define MR_CAT_SEP(_s, ...) \
__MR_CAT(MR_CAT_SEP_, MR_VA_ARGS_NUM(__VA_ARGS__))(_s, __VA_ARGS__)
#define MR_CAT_SEP_0(_s, _a, ...)
#define MR_CAT_SEP_1(_s, _a, ...) MR_CAT(_s, _a)
#define MR_CAT_SEP_2(_s, _a, ...) \
MR_CAT(_s, _a, MR_CAT_SEP_1(_s, __VA_ARGS__))
#define MR_CAT_SEP_3(_s, _a, ...) \
MR_CAT(_s, _a, MR_CAT_SEP_2(_s, __VA_ARGS__))
#define MR_CAT_SEP_4(_s, _a, ...) \
MR_CAT(_s, _a, MR_CAT_SEP_3(_s, __VA_ARGS__))
#define MR_CAT_SEP_5(_s, _a, ...) \
MR_CAT(_s, _a, MR_CAT_SEP_4(_s, __VA_ARGS__))
#define MR_CAT_SEP_6(_s, _a, ...) \
MR_CAT(_s, _a, MR_CAT_SEP_5(_s, __VA_ARGS__))
#define MR_CAT_SEP_7(_s, _a, ...) \
MR_CAT(_s, _a, MR_CAT_SEP_6(_s, __VA_ARGS__))
#define MR_CAT_SEP_8(_s, _a, ...) \
MR_CAT(_s, _a, MR_CAT_SEP_7(_s, __VA_ARGS__))
#define MR_CAT_SEP_9(_s, _a, ...) \
MR_CAT(_s, _a, MR_CAT_SEP_8(_s, __VA_ARGS__))
#define MR_CAT_SEP_10(_s, _a, ...) \
MR_CAT(_s, _a, MR_CAT_SEP_9(_s, __VA_ARGS__))
#define MR_CAT_SEP_11(_s, _a, ...) \
MR_CAT(_s, _a, MR_CAT_SEP_10(_s, __VA_ARGS__))
#define MR_CAT_SEP_12(_s, _a, ...) \
MR_CAT(_s, _a, MR_CAT_SEP_11(_s, __VA_ARGS__))
#define MR_CAT_SEP_13(_s, _a, ...) \
MR_CAT(_s, _a, MR_CAT_SEP_12(_s, __VA_ARGS__))
#define MR_CAT_SEP_14(_s, _a, ...) \
MR_CAT(_s, _a, MR_CAT_SEP_13(_s, __VA_ARGS__))
#define MR_CAT_SEP_15(_s, _a, ...) \
MR_CAT(_s, _a, MR_CAT_SEP_14(_s, __VA_ARGS__))
/**
* @brief This function verifies the parity(even).
*
* @param src The source.
* @param size The verify size.
* @return MR_TRUE on even, MR_FALSE on odd.
*/
MR_INLINE mr_bool_t mr_parity_even(const void *src, mr_size_t size) {
const mr_uint8_t bits16[16]
= {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
mr_uint8_t *s, parity;
mr_size_t i;
/* Bitwise parity */
for (s = (mr_uint8_t *)src, parity = 0, i = 0; i < size; ++i) {
parity += bits16[s[i] & (0x0fU)];
parity += bits16[s[i] >> 4];
}
return (parity & 0x01U) == 0;
}
/**
* @brief This function verifies the parity(odd).
*
* @param src The source.
* @param size The verify size.
* @return MR_TRUE on odd, MR_FALSE on even.
*/
MR_INLINE mr_bool_t mr_parity_odd(const void *src, mr_size_t size) {
/* Even parity negation */
return !mr_parity_even(src, size);
}
/** @} */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __MR_SERVICE_H__ */