From cacc4aa829e7ca91be2831e61a8405f5a779ff6b Mon Sep 17 00:00:00 2001 From: Leonid Yuriev Date: Mon, 14 Sep 2020 16:40:46 +0300 Subject: [PATCH] mdbx++: changes after codereview-1 (part 2 of 2). Change-Id: I8e1ca134bb8c5d447895f116247dfd12fa6871f0 --- mdbx.h | 277 +++++++++---------- mdbx.h++ | 704 +++++++++++++++++++++++++----------------------- src/core.c | 84 +++--- src/defs.h | 14 +- src/internals.h | 14 +- src/mdbx.c++ | 110 ++++---- src/mdbx_chk.c | 6 +- src/osal.c | 8 +- src/osal.h | 4 +- test/keygen.cc | 2 +- test/log.cc | 4 +- test/log.h | 26 +- test/main.cc | 2 +- test/test.cc | 2 +- test/test.h | 2 +- 15 files changed, 631 insertions(+), 628 deletions(-) diff --git a/mdbx.h b/mdbx.h index dfa59fda..5424635f 100644 --- a/mdbx.h +++ b/mdbx.h @@ -226,7 +226,6 @@ typedef mode_t mdbx_mode_t; #define __has_builtin(x) (0) #endif /* __has_builtin */ -#ifndef __pure_function /** Many functions have no effects except the return value and their * return value depends only on the parameters and/or global variables. * Such a function can be subject to common subexpression elimination @@ -235,43 +234,39 @@ typedef mode_t mdbx_mode_t; #if (defined(__GNUC__) || __has_attribute(__pure__)) && \ (!defined(__clang__) /* https://bugs.llvm.org/show_bug.cgi?id=43275 */ \ || !defined(__cplusplus) || !__has_feature(cxx_exceptions)) -#define __pure_function __attribute__((__pure__)) +#define MDBX_PURE_FUNCTION __attribute__((__pure__)) #elif defined(_MSC_VER) && !defined(__clang__) && _MSC_VER >= 1920 -#define __pure_function +#define MDBX_PURE_FUNCTION #elif defined(__cplusplus) && __has_cpp_attribute(gnu::pure) && \ (!defined(__clang__) || !__has_feature(cxx_exceptions)) -#define __pure_function [[gnu::pure]] +#define MDBX_PURE_FUNCTION [[gnu::pure]] #else -#define __pure_function -#endif -#endif /* __pure_function */ +#define MDBX_PURE_FUNCTION +#endif /* MDBX_PURE_FUNCTION */ -#ifndef __nothrow_pure_function -/** Like \ref __pure_function with addition `noexcept` restriction +/** Like \ref MDBX_PURE_FUNCTION with addition `noexcept` restriction * that is compatible to CLANG and proposed [[pure]]. */ #if defined(__GNUC__) || \ (__has_attribute(__pure__) && __has_attribute(__nothrow__)) -#define __nothrow_pure_function __attribute__((__pure__, __nothrow__)) +#define MDBX_NOTHROW_PURE_FUNCTION __attribute__((__pure__, __nothrow__)) #elif defined(_MSC_VER) && !defined(__clang__) && _MSC_VER >= 1920 #if __has_cpp_attribute(pure) -#define __nothrow_pure_function [[pure]] +#define MDBX_NOTHROW_PURE_FUNCTION [[pure]] #else -#define __nothrow_pure_function +#define MDBX_NOTHROW_PURE_FUNCTION #endif #elif defined(__cplusplus) && __has_cpp_attribute(gnu::pure) #if __has_cpp_attribute(gnu::nothrow) -#define __nothrow_pure_function [[gnu::pure, gnu::nothrow]] +#define MDBX_NOTHROW_PURE_FUNCTION [[gnu::pure, gnu::nothrow]] #else -#define __nothrow_pure_function [[gnu::pure]] +#define MDBX_NOTHROW_PURE_FUNCTION [[gnu::pure]] #endif #elif defined(__cplusplus) && __has_cpp_attribute(pure) -#define __nothrow_pure_function [[pure]] +#define MDBX_NOTHROW_PURE_FUNCTION [[pure]] #else -#define __nothrow_pure_function -#endif -#endif /* __nothrow_pure_function */ +#define MDBX_NOTHROW_PURE_FUNCTION +#endif /* MDBX_NOTHROW_PURE_FUNCTION */ -#ifndef __const_function /** Many functions do not examine any values except their arguments, * and have no effects except the return value. Basically this is just * slightly more strict class than the PURE attribute, since function @@ -284,39 +279,36 @@ typedef mode_t mdbx_mode_t; #if (defined(__GNUC__) || __has_attribute(__pure__)) && \ (!defined(__clang__) /* https://bugs.llvm.org/show_bug.cgi?id=43275 */ \ || !defined(__cplusplus) || !__has_feature(cxx_exceptions)) -#define __const_function __attribute__((__const__)) +#define MDBX_CONST_FUNCTION __attribute__((__const__)) #elif defined(_MSC_VER) && !defined(__clang__) && _MSC_VER >= 1920 -#define __const_function __pure_function +#define MDBX_CONST_FUNCTION MDBX_PURE_FUNCTION #elif defined(__cplusplus) && __has_cpp_attribute(gnu::const) && \ (!defined(__clang__) || !__has_feature(cxx_exceptions)) -#define __const_function [[gnu::const]] +#define MDBX_CONST_FUNCTION [[gnu::const]] #else -#define __const_function __pure_function -#endif -#endif /* __const_function */ +#define MDBX_CONST_FUNCTION MDBX_PURE_FUNCTION +#endif /* MDBX_CONST_FUNCTION */ -#ifndef __nothrow_const_function -/** Like \ref __const_function with addition `noexcept` restriction +/** Like \ref MDBX_CONST_FUNCTION with addition `noexcept` restriction * that is compatible to CLANG and future [[const]]. */ #if defined(__GNUC__) || \ (__has_attribute(__const__) && __has_attribute(__nothrow__)) -#define __nothrow_const_function __attribute__((__const__, __nothrow__)) +#define MDBX_NOTHROW_CONST_FUNCTION __attribute__((__const__, __nothrow__)) #elif defined(_MSC_VER) && !defined(__clang__) && _MSC_VER >= 1920 -#define __nothrow_const_function __nothrow_pure_function +#define MDBX_NOTHROW_CONST_FUNCTION MDBX_NOTHROW_PURE_FUNCTION #elif defined(__cplusplus) && __has_cpp_attribute(gnu::const) #if __has_cpp_attribute(gnu::nothrow) -#define __nothrow_pure_function [[gnu::const, gnu::nothrow]] +#define MDBX_NOTHROW_PURE_FUNCTION [[gnu::const, gnu::nothrow]] #else -#define __nothrow_pure_function [[gnu::const]] +#define MDBX_NOTHROW_PURE_FUNCTION [[gnu::const]] #endif #elif defined(__cplusplus) && __has_cpp_attribute(const) -#define __nothrow_const_function [[const]] +#define MDBX_NOTHROW_CONST_FUNCTION [[const]] #else -#define __nothrow_const_function __nothrow_pure_function -#endif -#endif /* __nothrow_pure_function */ +#define MDBX_NOTHROW_CONST_FUNCTION MDBX_NOTHROW_PURE_FUNCTION +#endif /* MDBX_NOTHROW_PURE_FUNCTION */ -#ifndef MDBX_DEPRECATED +#ifndef MDBX_DEPRECATED /* may be predefined to avoid warnings "deprecated" */ #ifdef __deprecated #define MDBX_DEPRECATED __deprecated #elif defined(__GNUC__) || __has_attribute(__deprecated__) @@ -372,97 +364,81 @@ typedef mode_t mdbx_mode_t; #endif #endif /* bool without __cplusplus */ -#if !defined(cxx11_noexcept) -#if defined(__cplusplus) && __cplusplus >= 201103L -#define cxx11_noexcept noexcept -#else -#define cxx11_noexcept -#endif -#endif /* cxx11_noexcept */ - -#if !defined(cxx17_noexcept) #if !defined(__cpp_noexcept_function_type) || \ __cpp_noexcept_function_type < 201510L -#define cxx17_noexcept +#define MDBX_CXX17_NOEXCEPT #else -#define cxx17_noexcept noexcept -#endif -#endif /* cxx17_noexcept */ +#define MDBX_CXX17_NOEXCEPT noexcept +#endif /* MDBX_CXX17_NOEXCEPT */ /* Workaround for old compilers without properly support for constexpr. */ -#if !defined(cxx07_constexpr) #if !defined(__cplusplus) -#define cxx07_constexpr __inline -#define cxx07_constexpr_var const +#define MDBX_CXX01_CONSTEXPR __inline +#define MDBX_CXX01_CONSTEXPR_VAR const #elif !defined(__cpp_constexpr) || __cpp_constexpr < 200704L || \ (defined(__LCC__) && __LCC__ < 124) || \ (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 407) && \ !defined(__clang__) && !defined(__LCC__)) || \ (defined(_MSC_VER) && _MSC_VER < 1910) || \ (defined(__clang__) && __clang_major__ < 4) -#define cxx07_constexpr inline -#define cxx07_constexpr_var const +#define MDBX_CXX01_CONSTEXPR inline +#define MDBX_CXX01_CONSTEXPR_VAR const #else -#define cxx07_constexpr constexpr -#define cxx07_constexpr_var constexpr -#endif -#endif /* cxx07_constexpr */ +#define MDBX_CXX01_CONSTEXPR constexpr +#define MDBX_CXX01_CONSTEXPR_VAR constexpr +#endif /* MDBX_CXX01_CONSTEXPR */ -#if !defined(cxx11_constexpr) #if !defined(__cplusplus) -#define cxx11_constexpr __inline -#define cxx11_constexpr_var const +#define MDBX_CXX11_CONSTEXPR __inline +#define MDBX_CXX11_CONSTEXPR_VAR const #elif !defined(__cpp_constexpr) || __cpp_constexpr < 201304 || \ (defined(__LCC__) && __LCC__ < 124) || \ (defined(__GNUC__) && __GNUC__ < 6 && !defined(__clang__) && \ !defined(__LCC__)) || \ (defined(_MSC_VER) && _MSC_VER < 1910) || \ (defined(__clang__) && __clang_major__ < 5) -#define cxx11_constexpr inline -#define cxx11_constexpr_var const +#define MDBX_CXX11_CONSTEXPR inline +#define MDBX_CXX11_CONSTEXPR_VAR const #else -#define cxx11_constexpr constexpr -#define cxx11_constexpr_var constexpr -#endif -#endif /* cxx11_constexpr */ +#define MDBX_CXX11_CONSTEXPR constexpr +#define MDBX_CXX11_CONSTEXPR_VAR constexpr +#endif /* MDBX_CXX11_CONSTEXPR */ -#if !defined(cxx14_constexpr) #if !defined(__cplusplus) -#define cxx14_constexpr __inline -#define cxx14_constexpr_var const +#define MDBX_CXX14_CONSTEXPR __inline +#define MDBX_CXX14_CONSTEXPR_VAR const #elif defined(__cpp_constexpr) && __cpp_constexpr >= 201304L && \ ((defined(_MSC_VER) && _MSC_VER >= 1910) || \ (defined(__clang__) && __clang_major__ > 4) || \ (defined(__GNUC__) && __GNUC__ > 6) || \ (!defined(__GNUC__) && !defined(__clang__) && !defined(_MSC_VER))) -#define cxx14_constexpr constexpr -#define cxx14_constexpr_var constexpr +#define MDBX_CXX14_CONSTEXPR constexpr +#define MDBX_CXX14_CONSTEXPR_VAR constexpr #else -#define cxx14_constexpr inline -#define cxx14_constexpr_var const -#endif -#endif /* cxx14_constexpr */ +#define MDBX_CXX14_CONSTEXPR inline +#define MDBX_CXX14_CONSTEXPR_VAR const +#endif /* MDBX_CXX14_CONSTEXPR */ -#ifndef __noreturn -#ifdef _Noreturn -#define __noreturn _Noreturn +#if defined(__noreturn) +#define MDBX_NORETURN __noreturn +#elif defined(_Noreturn) +#define MDBX_NORETURN _Noreturn #elif defined(__GNUC__) || __has_attribute(__noreturn__) -#define __noreturn __attribute__((__noreturn__)) +#define MDBX_NORETURN __attribute__((__noreturn__)) #elif defined(_MSC_VER) && !defined(__clang__) -#define __noreturn __declspec(noreturn) +#define MDBX_NORETURN __declspec(noreturn) #else -#define __noreturn -#endif -#endif /* __noreturn */ +#define MDBX_NORETURN +#endif /* MDBX_NORETURN */ -#ifndef mdbx_printf_args +#ifndef MDBX_PRINTF_ARGS #if defined(__GNUC__) || __has_attribute(__format__) -#define mdbx_printf_args(format_index, first_arg) \ +#define MDBX_PRINTF_ARGS(format_index, first_arg) \ __attribute__((__format__(__printf__, format_index, first_arg))) #else -#define mdbx_printf_args(format_index, first_arg) +#define MDBX_PRINTF_ARGS(format_index, first_arg) #endif -#endif /* mdbx_printf_args */ +#endif /* MDBX_PRINTF_ARGS */ #ifndef DEFINE_ENUM_FLAG_OPERATORS #if defined(__cplusplus) @@ -470,19 +446,21 @@ typedef mode_t mdbx_mode_t; /// used to define flags (based on Microsoft's DEFINE_ENUM_FLAG_OPERATORS). #define DEFINE_ENUM_FLAG_OPERATORS(ENUM) \ extern "C++" { \ - cxx07_constexpr ENUM operator|(ENUM a, ENUM b) { \ + MDBX_CXX01_CONSTEXPR ENUM operator|(ENUM a, ENUM b) { \ return ENUM(std::size_t(a) | std::size_t(b)); \ } \ - cxx14_constexpr ENUM &operator|=(ENUM &a, ENUM b) { return a = a | b; } \ - cxx07_constexpr ENUM operator&(ENUM a, ENUM b) { \ + MDBX_CXX14_CONSTEXPR ENUM &operator|=(ENUM &a, ENUM b) { return a = a | b; } \ + MDBX_CXX01_CONSTEXPR ENUM operator&(ENUM a, ENUM b) { \ return ENUM(std::size_t(a) & std::size_t(b)); \ } \ - cxx14_constexpr ENUM &operator&=(ENUM &a, ENUM b) { return a = a & b; } \ - cxx07_constexpr ENUM operator~(ENUM a) { return ENUM(~std::size_t(a)); } \ - cxx07_constexpr ENUM operator^(ENUM a, ENUM b) { \ + MDBX_CXX14_CONSTEXPR ENUM &operator&=(ENUM &a, ENUM b) { return a = a & b; } \ + MDBX_CXX01_CONSTEXPR ENUM operator~(ENUM a) { \ + return ENUM(~std::size_t(a)); \ + } \ + MDBX_CXX01_CONSTEXPR ENUM operator^(ENUM a, ENUM b) { \ return ENUM(std::size_t(a) ^ std::size_t(b)); \ } \ - cxx14_constexpr ENUM &operator^=(ENUM &a, ENUM b) { return a = a ^ b; } \ + MDBX_CXX14_CONSTEXPR ENUM &operator^=(ENUM &a, ENUM b) { return a = a ^ b; } \ } #else /* __cplusplus */ #define DEFINE_ENUM_FLAG_OPERATORS(ENUM) /* nope, C allows these operators */ @@ -792,7 +770,7 @@ DEFINE_ENUM_FLAG_OPERATORS(MDBX_debug_flags_t) * \param [in] msg The assertion message, not including newline. */ typedef void MDBX_debug_func(MDBX_log_level_t loglevel, const char *function, int line, const char *msg, - va_list args) cxx17_noexcept; + va_list args) MDBX_CXX17_NOEXCEPT; /** \brief The "don't change `logger`" value for mdbx_setup_debug() */ #define MDBX_LOGGER_DONTCHANGE ((MDBX_debug_func *)(intptr_t)-1) @@ -812,7 +790,7 @@ LIBMDBX_API int mdbx_setup_debug(MDBX_log_level_t log_level, * \param [in] msg The assertion message, not including newline. */ typedef void MDBX_assert_func(const MDBX_env *env, const char *msg, const char *function, - unsigned line) cxx17_noexcept; + unsigned line) MDBX_CXX17_NOEXCEPT; /** \brief Set or reset the assert() callback of the environment. * @@ -838,7 +816,7 @@ LIBMDBX_API const char *mdbx_dump_val(const MDBX_val *key, char *const buf, const size_t bufsize); /** \brief Panics with message and causes abnormal process termination. */ -LIBMDBX_API void mdbx_panic(const char *fmt, ...) mdbx_printf_args(1, 2); +LIBMDBX_API void mdbx_panic(const char *fmt, ...) MDBX_PRINTF_ARGS(1, 2); /** @} end of logging & debug */ @@ -1715,7 +1693,7 @@ LIBMDBX_API const char *mdbx_strerror(int errnum); * * \returns "error message" The description of the error. */ LIBMDBX_API const char *mdbx_strerror_r(int errnum, char *buf, size_t buflen); -__nothrow_pure_function LIBMDBX_API const char *mdbx_liberr2str(int errnum); +MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API const char *mdbx_liberr2str(int errnum); #if defined(_WIN32) || defined(_WIN64) || defined(DOXYGEN) /** Bit of Windows' madness. The similar to \ref mdbx_strerror() but returns @@ -2430,46 +2408,46 @@ LIBMDBX_API int mdbx_is_readahead_reasonable(size_t volume, /** \brief Returns the minimal database page size in bytes. * \ingroup c_statinfo */ -__nothrow_const_function __inline intptr_t mdbx_limits_pgsize_min(void) { +MDBX_NOTHROW_CONST_FUNCTION __inline intptr_t mdbx_limits_pgsize_min(void) { return MDBX_MIN_PAGESIZE; } /** \brief Returns the maximal database page size in bytes. * \ingroup c_statinfo */ -__nothrow_const_function __inline intptr_t mdbx_limits_pgsize_max(void) { +MDBX_NOTHROW_CONST_FUNCTION __inline intptr_t mdbx_limits_pgsize_max(void) { return MDBX_MAX_PAGESIZE; } /** \brief Returns minimal database size in bytes for given page size, * or -1 if pagesize is invalid. * \ingroup c_statinfo */ -__nothrow_const_function LIBMDBX_API intptr_t +MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API intptr_t mdbx_limits_dbsize_min(intptr_t pagesize); /** \brief Returns maximal database size in bytes for given page size, * or -1 if pagesize is invalid. * \ingroup c_statinfo */ -__nothrow_const_function LIBMDBX_API intptr_t +MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API intptr_t mdbx_limits_dbsize_max(intptr_t pagesize); /** \brief Returns maximal key size in bytes for given page size * and database flags, or -1 if pagesize is invalid. * \ingroup c_statinfo * \see db_flags */ -__nothrow_const_function LIBMDBX_API intptr_t +MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API intptr_t mdbx_limits_keysize_max(intptr_t pagesize, MDBX_db_flags_t flags); /** \brief Returns maximal data size in bytes for given page size * and database flags, or -1 if pagesize is invalid. * \ingroup c_statinfo * \see db_flags */ -__nothrow_const_function LIBMDBX_API intptr_t +MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API intptr_t mdbx_limits_valsize_max(intptr_t pagesize, MDBX_db_flags_t flags); /** \brief Returns maximal write transaction size (i.e. limit for summary volume * of dirty pages) in bytes for given page size, or -1 if pagesize is invalid. * \ingroup c_statinfo */ -__nothrow_const_function LIBMDBX_API intptr_t +MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API intptr_t mdbx_limits_txnsize_max(intptr_t pagesize); /** \brief Set the maximum number of threads/reader slots for the environment. @@ -2552,7 +2530,7 @@ LIBMDBX_API int mdbx_env_get_maxdbs(MDBX_env *env, MDBX_dbi *dbs); * * \returns The maximum size of a key can write, * or -1 if something is wrong. */ -__nothrow_pure_function LIBMDBX_API int +MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int mdbx_env_get_maxkeysize_ex(const MDBX_env *env, MDBX_db_flags_t flags); /** \brief Get the maximum size of data we can write. @@ -2564,13 +2542,13 @@ mdbx_env_get_maxkeysize_ex(const MDBX_env *env, MDBX_db_flags_t flags); * * \returns The maximum size of a data can write, * or -1 if something is wrong. */ -__nothrow_pure_function LIBMDBX_API int +MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int mdbx_env_get_maxvalsize_ex(const MDBX_env *env, MDBX_db_flags_t flags); /** \deprecated Please use \ref mdbx_env_get_maxkeysize_ex() * and/or \ref mdbx_env_get_maxvalsize_ex() * \ingroup c_statinfo */ -__nothrow_pure_function MDBX_DEPRECATED LIBMDBX_API int +MDBX_NOTHROW_PURE_FUNCTION MDBX_DEPRECATED LIBMDBX_API int mdbx_env_get_maxkeysize(const MDBX_env *env); /** \brief Set application information associated with the \ref MDBX_env. @@ -2589,7 +2567,7 @@ LIBMDBX_API int mdbx_env_set_userctx(MDBX_env *env, void *ctx); * * \param [in] env An environment handle returned by \ref mdbx_env_create() * \returns The pointer set by \ref mdbx_env_set_userctx(). */ -__nothrow_pure_function LIBMDBX_API void * +MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API void * mdbx_env_get_userctx(const MDBX_env *env); /** \brief Create a transaction for use with the environment. @@ -2716,7 +2694,8 @@ LIBMDBX_API int mdbx_txn_info(const MDBX_txn *txn, MDBX_txn_info *info, * \ingroup c_transactions * * \param [in] txn A transaction handle returned by \ref mdbx_txn_begin() */ -__nothrow_pure_function LIBMDBX_API MDBX_env *mdbx_txn_env(const MDBX_txn *txn); +MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API MDBX_env * +mdbx_txn_env(const MDBX_txn *txn); /** \brief Return the transaction's flags. * \ingroup c_transactions @@ -2727,7 +2706,7 @@ __nothrow_pure_function LIBMDBX_API MDBX_env *mdbx_txn_env(const MDBX_txn *txn); * * \returns A transaction flags, valid if input is an valid transaction, * otherwise -1. */ -__nothrow_pure_function LIBMDBX_API int mdbx_txn_flags(const MDBX_txn *txn); +MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int mdbx_txn_flags(const MDBX_txn *txn); /** \brief Return the transaction's ID. * \ingroup c_statinfo @@ -2740,7 +2719,8 @@ __nothrow_pure_function LIBMDBX_API int mdbx_txn_flags(const MDBX_txn *txn); * * \returns A transaction ID, valid if input is an active transaction, * otherwise 0. */ -__nothrow_pure_function LIBMDBX_API uint64_t mdbx_txn_id(const MDBX_txn *txn); +MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API uint64_t +mdbx_txn_id(const MDBX_txn *txn); /** \brief Commit all the operations of a transaction into the database. * \ingroup c_transactions @@ -2936,7 +2916,8 @@ LIBMDBX_API int mdbx_canary_get(const MDBX_txn *txn, MDBX_canary *canary); * \ingroup c_crud * \see mdbx_cmp() \see mdbx_get_keycmp() * \see mdbx_get_datacmp \see mdbx_dcmp() */ -typedef int(MDBX_cmp_func)(const MDBX_val *a, const MDBX_val *b) cxx17_noexcept; +typedef int(MDBX_cmp_func)(const MDBX_val *a, + const MDBX_val *b) MDBX_CXX17_NOEXCEPT; /** \brief Open or Create a database in the environment. * \ingroup c_dbi @@ -3063,27 +3044,27 @@ mdbx_dbi_open_ex(MDBX_txn *txn, const char *name, MDBX_db_flags_t flags, * and IEEE754 double values in one index for JSON-numbers with restriction for * integer numbers range corresponding to RFC-7159, i.e. \f$[-2^{53}+1, * 2^{53}-1]\f$. See bottom of page 6 at https://tools.ietf.org/html/rfc7159 */ -__nothrow_const_function LIBMDBX_API uint64_t +MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API uint64_t mdbx_key_from_jsonInteger(const int64_t json_integer); -__nothrow_const_function LIBMDBX_API uint64_t +MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API uint64_t mdbx_key_from_double(const double ieee754_64bit); -__nothrow_pure_function LIBMDBX_API uint64_t +MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API uint64_t mdbx_key_from_ptrdouble(const double *const ieee754_64bit); -__nothrow_const_function LIBMDBX_API uint32_t +MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API uint32_t mdbx_key_from_float(const float ieee754_32bit); -__nothrow_pure_function LIBMDBX_API uint32_t +MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API uint32_t mdbx_key_from_ptrfloat(const float *const ieee754_32bit); -__nothrow_const_function __inline uint64_t +MDBX_NOTHROW_CONST_FUNCTION __inline uint64_t mdbx_key_from_int64(const int64_t i64) { return UINT64_C(0x8000000000000000) + i64; } -__nothrow_const_function __inline uint32_t +MDBX_NOTHROW_CONST_FUNCTION __inline uint32_t mdbx_key_from_int32(const int32_t i32) { return UINT32_C(0x80000000) + i32; } @@ -3092,16 +3073,20 @@ mdbx_key_from_int32(const int32_t i32) { /** \defgroup key2value Key-to-Value functions to avoid custom comparators * \see value2key * @{ */ -__nothrow_pure_function LIBMDBX_API int64_t +MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int64_t mdbx_jsonInteger_from_key(const MDBX_val); -__nothrow_pure_function LIBMDBX_API double mdbx_double_from_key(const MDBX_val); +MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API double +mdbx_double_from_key(const MDBX_val); -__nothrow_pure_function LIBMDBX_API float mdbx_float_from_key(const MDBX_val); +MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API float +mdbx_float_from_key(const MDBX_val); -__nothrow_pure_function LIBMDBX_API int32_t mdbx_int32_from_key(const MDBX_val); +MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int32_t +mdbx_int32_from_key(const MDBX_val); -__nothrow_pure_function LIBMDBX_API int64_t mdbx_int64_from_key(const MDBX_val); +MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int64_t +mdbx_int64_from_key(const MDBX_val); /** @} */ /** \brief Retrieve statistics for a database. @@ -3539,7 +3524,7 @@ LIBMDBX_API int mdbx_cursor_renew(MDBX_txn *txn, MDBX_cursor *cursor); * \ingroup c_cursors * * \param [in] cursor A cursor handle returned by \ref mdbx_cursor_open(). */ -__nothrow_pure_function LIBMDBX_API MDBX_txn * +MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API MDBX_txn * mdbx_cursor_txn(const MDBX_cursor *cursor); /** \brief Return the cursor's database handle. @@ -3712,7 +3697,7 @@ LIBMDBX_API int mdbx_cursor_count(const MDBX_cursor *cursor, size_t *pcount); * positioned * \retval MDBX_RESULT_FALSE A data is available * \retval Otherwise the error code */ -__nothrow_pure_function LIBMDBX_API int +MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int mdbx_cursor_eof(const MDBX_cursor *cursor); /** \brief Determines whether the cursor is pointed to the first key-value pair @@ -3725,7 +3710,7 @@ mdbx_cursor_eof(const MDBX_cursor *cursor); * \retval MDBX_RESULT_TRUE Cursor positioned to the first key-value pair * \retval MDBX_RESULT_FALSE Cursor NOT positioned to the first key-value * pair \retval Otherwise the error code */ -__nothrow_pure_function LIBMDBX_API int +MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int mdbx_cursor_on_first(const MDBX_cursor *cursor); /** \brief Determines whether the cursor is pointed to the last key-value pair @@ -3738,7 +3723,7 @@ mdbx_cursor_on_first(const MDBX_cursor *cursor); * \retval MDBX_RESULT_TRUE Cursor positioned to the last key-value pair * \retval MDBX_RESULT_FALSE Cursor NOT positioned to the last key-value pair * \retval Otherwise the error code */ -__nothrow_pure_function LIBMDBX_API int +MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int mdbx_cursor_on_last(const MDBX_cursor *cursor); /** \addtogroup c_rqest @@ -3878,8 +3863,8 @@ LIBMDBX_API int mdbx_estimate_range(MDBX_txn *txn, MDBX_dbi dbi, * \retval MDBX_RESULT_TRUE Given address is on the dirty page. * \retval MDBX_RESULT_FALSE Given address is NOT on the dirty page. * \retval Otherwise the error code. */ -__nothrow_pure_function LIBMDBX_API int mdbx_is_dirty(const MDBX_txn *txn, - const void *ptr); +MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int mdbx_is_dirty(const MDBX_txn *txn, + const void *ptr); /** \brief Sequence generation for a database. * \ingroup c_crud @@ -3919,14 +3904,14 @@ LIBMDBX_API int mdbx_dbi_sequence(MDBX_txn *txn, MDBX_dbi dbi, uint64_t *result, * \param [in] b The second item to compare. * * \returns < 0 if a < b, 0 if a == b, > 0 if a > b */ -__nothrow_pure_function LIBMDBX_API int mdbx_cmp(const MDBX_txn *txn, - MDBX_dbi dbi, - const MDBX_val *a, - const MDBX_val *b); +MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int mdbx_cmp(const MDBX_txn *txn, + MDBX_dbi dbi, + const MDBX_val *a, + const MDBX_val *b); /** \brief Returns default internal key's comparator for given database flags. * \ingroup c_extra */ -__nothrow_const_function LIBMDBX_API MDBX_cmp_func * +MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API MDBX_cmp_func * mdbx_get_keycmp(MDBX_db_flags_t flags); /** \brief Compare two data items according to a particular database. @@ -3943,14 +3928,14 @@ mdbx_get_keycmp(MDBX_db_flags_t flags); * \param [in] b The second item to compare. * * \returns < 0 if a < b, 0 if a == b, > 0 if a > b */ -__nothrow_pure_function LIBMDBX_API int mdbx_dcmp(const MDBX_txn *txn, - MDBX_dbi dbi, - const MDBX_val *a, - const MDBX_val *b); +MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int mdbx_dcmp(const MDBX_txn *txn, + MDBX_dbi dbi, + const MDBX_val *a, + const MDBX_val *b); /** \brief Returns default internal data's comparator for given database flags * \ingroup c_extra */ -__nothrow_const_function LIBMDBX_API MDBX_cmp_func * +MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API MDBX_cmp_func * mdbx_get_datacmp(MDBX_db_flags_t flags); /** \brief A callback function used to enumerate the reader lock table. @@ -3981,7 +3966,7 @@ mdbx_get_datacmp(MDBX_db_flags_t flags); typedef int(MDBX_reader_list_func)(void *ctx, int num, int slot, mdbx_pid_t pid, mdbx_tid_t thread, uint64_t txnid, uint64_t lag, size_t bytes_used, - size_t bytes_retained) cxx17_noexcept; + size_t bytes_retained) MDBX_CXX17_NOEXCEPT; /** \brief Enumarete the entries in the reader lock table. * \ingroup c_statinfo @@ -4116,7 +4101,7 @@ LIBMDBX_API int mdbx_thread_unregister(const MDBX_env *env); */ typedef int(MDBX_oom_func)(MDBX_env *env, mdbx_pid_t pid, mdbx_tid_t tid, uint64_t txn, unsigned gap, size_t space, - int retry) cxx17_noexcept; + int retry) MDBX_CXX17_NOEXCEPT; /** \brief Set the OOM callback. * \ingroup c_err @@ -4140,7 +4125,7 @@ LIBMDBX_API int mdbx_env_set_oomfunc(MDBX_env *env, MDBX_oom_func *oom_func); * \param [in] env An environment handle returned by \ref mdbx_env_create(). * * \returns A MDBX_oom_func function or NULL if disabled. */ -__nothrow_pure_function LIBMDBX_API MDBX_oom_func * +MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API MDBX_oom_func * mdbx_env_get_oomfunc(const MDBX_env *env); /** \defgroup btree_traversal B-tree Traversal @@ -4178,7 +4163,7 @@ typedef int MDBX_pgvisitor_func( const uint64_t pgno, const unsigned number, void *const ctx, const int deep, const char *const dbi, const size_t page_size, const MDBX_page_type_t type, const MDBX_error_t err, const size_t nentries, const size_t payload_bytes, - const size_t header_bytes, const size_t unused_bytes) cxx17_noexcept; + const size_t header_bytes, const size_t unused_bytes) MDBX_CXX17_NOEXCEPT; /** \brief B-tree traversal function. */ LIBMDBX_API int mdbx_env_pgwalk(MDBX_txn *txn, MDBX_pgvisitor_func *visitor, diff --git a/mdbx.h++ b/mdbx.h++ index 7a28048b..5fb21983 100644 --- a/mdbx.h++ +++ b/mdbx.h++ @@ -31,6 +31,7 @@ #include #endif /* */ +/* Disable min/max macros from C' headers */ #ifndef NOMINMAX #define NOMINMAX #endif @@ -46,9 +47,10 @@ #include // for std::is_pod<>, etc. #include // for std::vector<> as template args -#if defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806L -#include -#endif +// Unused for now +// #if defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806L +// #include +// #endif #if defined(__cpp_lib_memory_resource) && __cpp_lib_memory_resource >= 201603L #include @@ -64,84 +66,77 @@ #include "mdbx.h" -#if !defined(cxx17_constexpr) #if defined(DOXYGEN) || \ defined(__cpp_constexpr) && __cpp_constexpr >= 201603L && \ ((defined(_MSC_VER) && _MSC_VER >= 1915) || \ (defined(__clang__) && __clang_major__ > 5) || \ (defined(__GNUC__) && __GNUC__ > 7) || \ (!defined(__GNUC__) && !defined(__clang__) && !defined(_MSC_VER))) -#define cxx17_constexpr constexpr +#define MDBX_CXX17_CONSTEXPR constexpr #else -#define cxx17_constexpr inline -#endif -#endif /* cxx17_constexpr */ +#define MDBX_CXX17_CONSTEXPR inline +#endif /* MDBX_CXX17_CONSTEXPR */ -#ifndef cxx20_constexpr #if defined(DOXYGEN) || defined(__cpp_lib_is_constant_evaluated) && \ __cpp_lib_is_constant_evaluated >= 201811L && \ defined(__cpp_lib_constexpr_string) && \ __cpp_lib_constexpr_string >= 201907L -#define cxx20_constexpr constexpr +#define MDBX_CXX20_CONSTEXPR constexpr #else -#define cxx20_constexpr inline -#endif -#endif /* cxx20_constexpr */ +#define MDBX_CXX20_CONSTEXPR inline +#endif /* MDBX_CXX20_CONSTEXPR */ -#if !defined(CONSTEXPR_ASSERT) -#if defined NDEBUG -#define CONSTEXPR_ASSERT(expr) void(0) +#if defined(CONSTEXPR_ASSERT) +#define MDBX_CONSTEXPR_ASSERT(expr) CONSTEXPR_ASSERT(expr) +#elif defined NDEBUG +#define MDBX_CONSTEXPR_ASSERT(expr) void(0) #else -#define CONSTEXPR_ASSERT(expr) ((expr) ? void(0) : [] { assert(!#expr); }()) -#endif -#endif /* constexpr_assert */ +#define MDBX_CONSTEXPR_ASSERT(expr) \ + ((expr) ? void(0) : [] { assert(!#expr); }()) +#endif /* MDBX_CONSTEXPR_ASSERT */ -#ifndef mdbx_likely +#ifndef MDBX_LIKELY #if defined(DOXYGEN) || \ (defined(__GNUC__) || __has_builtin(__builtin_expect)) && \ !defined(__COVERITY__) -#define mdbx_likely(cond) __builtin_expect(!!(cond), 1) +#define MDBX_LIKELY(cond) __builtin_expect(!!(cond), 1) #else -#define mdbx_likely(x) (x) +#define MDBX_LIKELY(x) (x) #endif -#endif /* mdbx_likely */ +#endif /* MDBX_LIKELY */ -#ifndef mdbx_unlikely +#ifndef MDBX_UNLIKELY #if defined(DOXYGEN) || \ (defined(__GNUC__) || __has_builtin(__builtin_expect)) && \ !defined(__COVERITY__) -#define mdbx_unlikely(cond) __builtin_expect(!!(cond), 0) +#define MDBX_UNLIKELY(cond) __builtin_expect(!!(cond), 0) #else -#define mdbx_unlikely(x) (x) +#define MDBX_UNLIKELY(x) (x) #endif -#endif /* mdbx_unlikely */ +#endif /* MDBX_UNLIKELY */ -#ifndef cxx17_attribute_fallthrough #if defined(DOXYGEN) || \ (__has_cpp_attribute(fallthrough) && \ (!defined(__clang__) || __clang__ > 4)) || \ __cplusplus >= 201703L -#define cxx17_attribute_fallthrough [[fallthrough]] +#define MDBX_CXX17_FALLTHROUGH [[fallthrough]] #else -#define cxx17_attribute_fallthrough -#endif -#endif /* cxx17_attribute_fallthrough */ +#define MDBX_CXX17_FALLTHROUGH +#endif /* MDBX_CXX17_FALLTHROUGH */ -#ifndef cxx20_attribute_likely #if defined(DOXYGEN) || __has_cpp_attribute(likely) -#define cxx20_attribute_likely [[likely]] +#define MDBX_CXX20_LIKELY [[likely]] #else -#define cxx20_attribute_likely -#endif -#endif /* cxx20_attribute_likely */ +#define MDBX_CXX20_LIKELY +#endif /* MDBX_CXX20_LIKELY */ -#ifndef cxx20_attribute_unlikely +#ifndef MDBX_CXX20_UNLIKELY #if defined(DOXYGEN) || __has_cpp_attribute(unlikely) -#define cxx20_attribute_unlikely [[unlikely]] +#define MDBX_CXX20_UNLIKELY [[unlikely]] #else -#define cxx20_attribute_unlikely +#define MDBX_CXX20_UNLIKELY #endif -#endif /* cxx20_attribute_unlikely */ +#endif /* MDBX_CXX20_UNLIKELY */ #ifdef _MSC_VER #pragma warning(push, 4) @@ -172,15 +167,15 @@ using byte = unsigned char; /// \copydoc MDBX_version_info using version_info = ::MDBX_version_info; /// \brief Returns libmdbx version information. -cxx11_constexpr const version_info &get_version() noexcept; +MDBX_CXX11_CONSTEXPR const version_info &get_version() noexcept; /// \copydoc MDBX_build_info using build_info = ::MDBX_build_info; /// \brief Resutrns libmdbx build information. -cxx11_constexpr const build_info &get_build() noexcept; +MDBX_CXX11_CONSTEXPR const build_info &get_build() noexcept; /// \brief Returns field offset in the container class. template -static cxx11_constexpr ptrdiff_t +static MDBX_CXX11_CONSTEXPR ptrdiff_t offset_of(const MEMBER CONTAINER::*const member) { return static_cast(static_cast( &(static_cast(nullptr)->*member))) - @@ -190,7 +185,7 @@ offset_of(const MEMBER CONTAINER::*const member) { /// \brief Returns const pointer to container class instance /// by const pointer to the member field. template -static cxx11_constexpr const CONTAINER * +static MDBX_CXX11_CONSTEXPR const CONTAINER * owner_of(const MEMBER *ptr, const MEMBER CONTAINER::*member) { return static_cast(static_cast( static_cast(static_cast(ptr)) - @@ -200,14 +195,14 @@ owner_of(const MEMBER *ptr, const MEMBER CONTAINER::*member) { /// \brief Returns non-const pointer to container class instance /// by non-const pointer to the member field. template -static cxx11_constexpr CONTAINER *owner_of(MEMBER *ptr, - const MEMBER CONTAINER::*member) { +static MDBX_CXX11_CONSTEXPR CONTAINER * +owner_of(MEMBER *ptr, const MEMBER CONTAINER::*member) { return static_cast(static_cast( static_cast(static_cast(ptr)) - offset_of(member))); } /// \brief constexpr-compatible strlen(). -static cxx17_constexpr size_t strlen(const char *c_str) noexcept; +static MDBX_CXX17_CONSTEXPR size_t strlen(const char *c_str) noexcept; struct slice; class env; @@ -223,7 +218,7 @@ using legacy_allocator = ::std::string::allocator_type; #if defined(DOXYGEN) || \ defined(__cpp_lib_memory_resource) && __cpp_lib_memory_resource >= 201603L -/// \brief Default polymorphic allocator for modern code +/// \brief Default polymorphic allocator for modern code. using polymorphic_allocator = ::std::pmr::string::allocator_type; #endif /* __cpp_lib_memory_resource >= 201603L */ @@ -267,24 +262,24 @@ class LIBMDBX_API_TYPE error { inline error &operator=(MDBX_error_t error_code) noexcept; public: - cxx11_constexpr error(MDBX_error_t error_code) noexcept; + MDBX_CXX11_CONSTEXPR error(MDBX_error_t error_code) noexcept; error(const error &) = default; error(error &&) = default; error &operator=(const error &) = default; error &operator=(error &&) = default; - cxx11_constexpr friend bool operator==(const error &a, - const error &b) noexcept; - cxx11_constexpr friend bool operator!=(const error &a, - const error &b) noexcept; + MDBX_CXX11_CONSTEXPR friend bool operator==(const error &a, + const error &b) noexcept; + MDBX_CXX11_CONSTEXPR friend bool operator!=(const error &a, + const error &b) noexcept; - cxx11_constexpr bool is_success() const noexcept; - cxx11_constexpr bool is_result_true() const noexcept; - cxx11_constexpr bool is_result_false() const noexcept; - cxx11_constexpr bool is_failure() const noexcept; + MDBX_CXX11_CONSTEXPR bool is_success() const noexcept; + MDBX_CXX11_CONSTEXPR bool is_result_true() const noexcept; + MDBX_CXX11_CONSTEXPR bool is_result_false() const noexcept; + MDBX_CXX11_CONSTEXPR bool is_failure() const noexcept; /// \brief Returns error code. - cxx11_constexpr MDBX_error_t code() const noexcept; + MDBX_CXX11_CONSTEXPR MDBX_error_t code() const noexcept; /// \brief Returns message for MDBX's errors only and "SYSTEM" for others. const char *what() const noexcept; @@ -293,9 +288,10 @@ public: ::std::string message() const; /// \brief Returns true for MDBX's errors. - cxx11_constexpr bool is_mdbx_error() const noexcept; - [[noreturn]] void panic(const char *context_where, - const char *func_who) const noexcept; + MDBX_CXX11_CONSTEXPR bool is_mdbx_error() const noexcept; + /// \brief Panics on unrecoverable errors inside destructors etc. + [[noreturn]] void panic(const char *context_where_when, + const char *func_who_what) const noexcept; [[noreturn]] void throw_exception() const; [[noreturn]] static inline void throw_exception(int error_code); inline void throw_on_failure() const; @@ -391,15 +387,15 @@ MDBX_DECLARE_EXCEPTION(transaction_overlapping); [[noreturn]] LIBMDBX_API void throw_too_small_target_buffer(); [[noreturn]] LIBMDBX_API void throw_max_length_exceeded(); [[noreturn]] LIBMDBX_API void throw_out_range(); -cxx14_constexpr size_t check_length(size_t bytes); +MDBX_CXX14_CONSTEXPR size_t check_length(size_t bytes); //------------------------------------------------------------------------------ /// \brief References a data located outside the slice. /// /// The `slice` is similar in many ways to `std::string_view`, but it -/// implements specific capabilities and manipulates with bytes but not a -/// characters. +/// implements specific capabilities and manipulates with bytes but +/// not a characters. /// /// \copydetails MDBX_val struct LIBMDBX_API_TYPE slice : public ::MDBX_val { @@ -410,38 +406,38 @@ struct LIBMDBX_API_TYPE slice : public ::MDBX_val { enum { max_length = MDBX_MAXDATASIZE }; /// \brief Create an empty slice. - cxx11_constexpr slice() noexcept; + MDBX_CXX11_CONSTEXPR slice() noexcept; /// \brief Create a slice that refers to [0,bytes-1] of memory bytes pointed /// by ptr. - cxx14_constexpr slice(const void *ptr, size_t bytes); + MDBX_CXX14_CONSTEXPR slice(const void *ptr, size_t bytes); /// \brief Create a slice that refers to [begin,end] of memory bytes. - cxx14_constexpr slice(const void *begin, const void *end); + MDBX_CXX14_CONSTEXPR slice(const void *begin, const void *end); /// \brief Create a slice that refers to text[0,strlen(text)-1]. template - cxx14_constexpr slice(const char (&text)[SIZE]) noexcept + MDBX_CXX14_CONSTEXPR slice(const char (&text)[SIZE]) noexcept : slice(text, SIZE - 1) { static_assert(SIZE > 0 && text[SIZE - 1] == '\0', "Must be a null-terminated C-string"); } /// \brief Create a slice that refers to c_str[0,strlen(c_str)-1]. - explicit cxx17_constexpr slice(const char *c_str); + explicit MDBX_CXX17_CONSTEXPR slice(const char *c_str); /// \brief Create a slice that refers to the contents of "str". /* 'explicit' to avoid reference to the temporary std::string instance */ template - explicit cxx20_constexpr slice(const ::std::basic_string &str) + explicit MDBX_CXX20_CONSTEXPR slice(const ::std::basic_string &str) : slice(str.data(), str.length() * sizeof(C)) {} - cxx14_constexpr slice(const MDBX_val &src); - cxx11_constexpr slice(const slice &) noexcept = default; + MDBX_CXX14_CONSTEXPR slice(const MDBX_val &src); + MDBX_CXX11_CONSTEXPR slice(const slice &) noexcept = default; #if defined(DOXYGEN) || \ (defined(__cpp_lib_string_view) && __cpp_lib_string_view >= 201606L) /// \brief Create a slice that refers to the same contents as "sv" template - explicit cxx14_constexpr slice(const ::std::basic_string_view &sv) + explicit MDBX_CXX14_CONSTEXPR slice(const ::std::basic_string_view &sv) : slice(sv.data(), sv.data() + sv.length()) {} #endif /* __cpp_lib_string_view >= 201606L */ @@ -456,11 +452,12 @@ struct LIBMDBX_API_TYPE slice : public ::MDBX_val { #endif /* __cpp_lib_string_view >= 201606L */ template - static cxx14_constexpr slice wrap(const char (&text)[SIZE]) { + static MDBX_CXX14_CONSTEXPR slice wrap(const char (&text)[SIZE]) { return slice(text); } - template cxx14_constexpr static slice wrap(const POD &pod) { + template + MDBX_CXX14_CONSTEXPR static slice wrap(const POD &pod) { static_assert(::std::is_standard_layout::value && !std::is_pointer::value, "Must be a standard layout type!"); @@ -509,14 +506,14 @@ struct LIBMDBX_API_TYPE slice : public ::MDBX_val { template , class A = legacy_allocator> - cxx20_constexpr ::std::basic_string + MDBX_CXX20_CONSTEXPR ::std::basic_string string(const A &allocator = A()) const { static_assert(sizeof(C) == 1, "Must be single byte characters"); return ::std::basic_string(char_ptr(), length(), allocator); } template - cxx20_constexpr operator ::std::basic_string() const { + MDBX_CXX20_CONSTEXPR operator ::std::basic_string() const { return this->string(); } @@ -527,7 +524,8 @@ struct LIBMDBX_API_TYPE slice : public ::MDBX_val { /// \brief Returns the buffer size in bytes needed for hexadecimal data dump /// of slice content. - cxx11_constexpr size_t to_hex_bytes(unsigned wrap_width = 0) const noexcept { + MDBX_CXX11_CONSTEXPR size_t + to_hex_bytes(unsigned wrap_width = 0) const noexcept { const size_t bytes = length() << 1; return wrap_width ? bytes + bytes / wrap_width : bytes; } @@ -540,7 +538,7 @@ struct LIBMDBX_API_TYPE slice : public ::MDBX_val { /// \brief Returns the buffer size in bytes needed for conversion /// hexadecimal dump from slice content to data. - cxx11_constexpr size_t from_hex_bytes() const noexcept { + MDBX_CXX11_CONSTEXPR size_t from_hex_bytes() const noexcept { return length() >> 1; } @@ -551,7 +549,7 @@ struct LIBMDBX_API_TYPE slice : public ::MDBX_val { /// \brief Returns the buffer size in bytes needed for /// [Base58](https://en.wikipedia.org/wiki/Base58) data dump of slice content. - cxx11_constexpr size_t + MDBX_CXX11_CONSTEXPR size_t to_base58_bytes(unsigned wrap_width = 0) const noexcept { const size_t bytes = length() / 8 * 11 + (length() % 8 * 43 + 31) / 32; return wrap_width ? bytes + bytes / wrap_width : bytes; @@ -565,7 +563,7 @@ struct LIBMDBX_API_TYPE slice : public ::MDBX_val { /// vReturns the buffer size in bytes needed for conversion /// [Base58](https://en.wikipedia.org/wiki/Base58) dump to data. - cxx11_constexpr size_t from_base58_bytes() const noexcept { + MDBX_CXX11_CONSTEXPR size_t from_base58_bytes() const noexcept { return length() / 11 * 8 + length() % 11 * 32 / 43; } @@ -576,7 +574,7 @@ struct LIBMDBX_API_TYPE slice : public ::MDBX_val { /// \brief Returns the buffer size in bytes needed for /// [Base64](https://en.wikipedia.org/wiki/Base64) data dump. - cxx11_constexpr size_t + MDBX_CXX11_CONSTEXPR size_t to_base64_bytes(unsigned wrap_width = 0) const noexcept { const size_t bytes = (length() + 2) / 3 * 4; return wrap_width ? bytes + bytes / wrap_width : bytes; @@ -590,7 +588,7 @@ struct LIBMDBX_API_TYPE slice : public ::MDBX_val { /// \brief Returns the buffer size in bytes needed for conversion /// [Base64](https://en.wikipedia.org/wiki/Base64) dump to data. - cxx11_constexpr size_t from_base64_bytes() const noexcept { + MDBX_CXX11_CONSTEXPR size_t from_base64_bytes() const noexcept { return (length() + 3) / 4 * 3; } @@ -635,16 +633,16 @@ struct LIBMDBX_API_TYPE slice : public ::MDBX_val { /// checks that content bytes are printable ASCII-7 characters or a valid UTF8 /// sequences. Otherwise, if if `disable_utf8` is `true` function checks that /// content bytes are printable extended 8-bit ASCII codes. - __nothrow_pure_function bool + MDBX_NOTHROW_PURE_FUNCTION bool is_printable(bool disable_utf8 = false) const noexcept; /// \brief Checks whether the content of the slice is a hexadecimal dump. /// \param [in] ignore_spaces If `true` function will skips spaces surrounding /// (before, between and after) a encoded bytes. However, spaces should not /// break a pair of characters encoding a single byte. - __nothrow_pure_function bool + MDBX_NOTHROW_PURE_FUNCTION bool is_hex(bool ignore_spaces = false) const noexcept; - __nothrow_pure_function bool + MDBX_NOTHROW_PURE_FUNCTION bool /// \brief Checks whether the content of the slice is a /// [Base58](https://en.wikipedia.org/wiki/Base58) dump. @@ -652,7 +650,7 @@ struct LIBMDBX_API_TYPE slice : public ::MDBX_val { /// (before, between and after) a encoded bytes. However, spaces should not /// break a code group of characters. is_base58(bool ignore_spaces = false) const noexcept; - __nothrow_pure_function bool + MDBX_NOTHROW_PURE_FUNCTION bool /// \brief Checks whether the content of the slice is a /// [Base64](https://en.wikipedia.org/wiki/Base64) dump. @@ -665,7 +663,7 @@ struct LIBMDBX_API_TYPE slice : public ::MDBX_val { (defined(__cpp_lib_string_view) && __cpp_lib_string_view >= 201606L) /// \brief Return a string_view that references the same data as this slice. template - cxx11_constexpr explicit + MDBX_CXX11_CONSTEXPR explicit operator ::std::basic_string_view() const noexcept { static_assert(sizeof(C) == 1, "Must be single byte characters"); return ::std::basic_string_view(char_ptr(), length()); @@ -673,7 +671,8 @@ struct LIBMDBX_API_TYPE slice : public ::MDBX_val { /// \brief Return a string_view that references the same data as this slice. template > - cxx11_constexpr ::std::basic_string_view string_view() const noexcept { + MDBX_CXX11_CONSTEXPR ::std::basic_string_view + string_view() const noexcept { static_assert(sizeof(C) == 1, "Must be single byte characters"); return ::std::basic_string_view(char_ptr(), length()); } @@ -692,28 +691,28 @@ struct LIBMDBX_API_TYPE slice : public ::MDBX_val { #endif /* __cpp_lib_string_view >= 201606L */ /// \brief Returns casted to pointer to byte an address of data. - cxx11_constexpr const byte *byte_ptr() const noexcept; + MDBX_CXX11_CONSTEXPR const byte *byte_ptr() const noexcept; /// \brief Returns casted to pointer to char an address of data. - cxx11_constexpr const char *char_ptr() const noexcept; + MDBX_CXX11_CONSTEXPR const char *char_ptr() const noexcept; /// \brief Return a pointer to the beginning of the referenced data. - cxx11_constexpr const void *data() const noexcept; + MDBX_CXX11_CONSTEXPR const void *data() const noexcept; /// \brief Returns the number of bytes. - cxx11_constexpr size_t length() const noexcept; + MDBX_CXX11_CONSTEXPR size_t length() const noexcept; /// \brief Checks whether the slice is empty. - cxx11_constexpr bool empty() const noexcept; + MDBX_CXX11_CONSTEXPR bool empty() const noexcept; /// \brief Checks whether the slice data pointer is nullptr. - cxx11_constexpr bool is_null() const noexcept; + MDBX_CXX11_CONSTEXPR bool is_null() const noexcept; /// \brief Returns the number of bytes. - cxx11_constexpr size_t size() const noexcept; + MDBX_CXX11_CONSTEXPR size_t size() const noexcept; /// \brief Returns true if slice is not empty. - cxx11_constexpr operator bool() const noexcept; + MDBX_CXX11_CONSTEXPR operator bool() const noexcept; /// \brief Depletes content of slice and make it invalid. inline void invalidate() noexcept; @@ -738,11 +737,11 @@ struct LIBMDBX_API_TYPE slice : public ::MDBX_val { inline void safe_remove_suffix(size_t n); /// \brief Checks if the data starts with the given prefix. - __nothrow_pure_function inline bool + MDBX_NOTHROW_PURE_FUNCTION inline bool starts_with(const slice &prefix) const noexcept; /// \brief Checks if the data ends with the given suffix. - __nothrow_pure_function inline bool + MDBX_NOTHROW_PURE_FUNCTION inline bool ends_with(const slice &suffix) const noexcept; /// \brief Returns the nth byte in the referenced data. @@ -781,7 +780,8 @@ struct LIBMDBX_API_TYPE slice : public ::MDBX_val { /// \attention Function implementation and returned hash values may changed /// version to version, and in future the t1ha3 will be used here. Therefore /// values obtained from this function shouldn't be persisted anywhere. - __nothrow_pure_function cxx14_constexpr size_t hash_value() const noexcept; + MDBX_NOTHROW_PURE_FUNCTION MDBX_CXX14_CONSTEXPR size_t + hash_value() const noexcept; /// \brief Three-way fast non-lexicographically length-based comparison. /// \return value: @@ -790,7 +790,7 @@ struct LIBMDBX_API_TYPE slice : public ::MDBX_val { /// > 0 if "a" longer than "b", /// < 0 if "a" length-equal and lexicographically less than "b", /// > 0 if "a" length-equal and lexicographically great than "b". - __nothrow_pure_function static inline intptr_t + MDBX_NOTHROW_PURE_FUNCTION static inline intptr_t compare_fast(const slice &a, const slice &b) noexcept; /// \brief Three-way lexicographically comparison. @@ -798,7 +798,7 @@ struct LIBMDBX_API_TYPE slice : public ::MDBX_val { /// < 0 if "a" < "b", /// == 0 if "a" == "b", /// > 0 if "a" > "b". - __nothrow_pure_function static inline intptr_t + MDBX_NOTHROW_PURE_FUNCTION static inline intptr_t compare_lexicographically(const slice &a, const slice &b) noexcept; friend inline bool operator==(const slice &a, const slice &b) noexcept; friend inline bool operator<(const slice &a, const slice &b) noexcept; @@ -808,16 +808,18 @@ struct LIBMDBX_API_TYPE slice : public ::MDBX_val { friend inline bool operator!=(const slice &a, const slice &b) noexcept; /// \brief Checks the slice is not refers to null address or has zero length. - cxx11_constexpr bool is_valid() const noexcept { + MDBX_CXX11_CONSTEXPR bool is_valid() const noexcept { return !(iov_base == nullptr && iov_len != 0); } /// \brief Build an invalid slice which non-zero length and refers to null /// address. - cxx11_constexpr static slice invalid() noexcept { return slice(size_t(-1)); } + MDBX_CXX11_CONSTEXPR static slice invalid() noexcept { + return slice(size_t(-1)); + } protected: - cxx11_constexpr slice(size_t invalid_lenght) noexcept + MDBX_CXX11_CONSTEXPR slice(size_t invalid_lenght) noexcept : ::MDBX_val({nullptr, invalid_lenght}) {} }; @@ -836,12 +838,12 @@ template class buffer { slice_.iov_base = const_cast(silo_.data()); } - __nothrow_pure_function cxx20_constexpr const byte * + MDBX_NOTHROW_PURE_FUNCTION MDBX_CXX20_CONSTEXPR const byte * silo_begin() const noexcept { return static_cast(static_cast(silo_.data())); } - __nothrow_pure_function cxx20_constexpr const byte * + MDBX_NOTHROW_PURE_FUNCTION MDBX_CXX20_CONSTEXPR const byte * silo_end() const noexcept { return silo_begin() + silo_.capacity(); } @@ -849,7 +851,7 @@ template class buffer { struct data_preserver : public exception_thunk { static int callback(void *context, MDBX_val *target, const void *src, size_t bytes) noexcept; - cxx11_constexpr operator MDBX_preserve_func() const noexcept { + MDBX_CXX11_CONSTEXPR operator MDBX_preserve_func() const noexcept { return callback; } }; @@ -866,82 +868,90 @@ public: }; /// \brief Returns the associated allocator. - cxx20_constexpr allocator_type get_allocator() const { + MDBX_CXX20_CONSTEXPR allocator_type get_allocator() const { return silo_.get_allocator(); } /// \brief Checks whether data chunk stored inside the buffer, otherwise /// buffer just refers to data located outside the buffer. - __nothrow_pure_function cxx20_constexpr bool + MDBX_NOTHROW_PURE_FUNCTION MDBX_CXX20_CONSTEXPR bool is_freestanding() const noexcept { return size_t(byte_ptr() - silo_begin()) < silo_.capacity(); } /// \brief Checks whether the buffer just refers to data located outside /// the buffer, rather than stores it. - __nothrow_pure_function cxx20_constexpr bool is_reference() const noexcept { + MDBX_NOTHROW_PURE_FUNCTION MDBX_CXX20_CONSTEXPR bool + is_reference() const noexcept { return !is_freestanding(); } /// \brief Returns the number of bytes that can be held in currently allocated /// storage. - __nothrow_pure_function cxx20_constexpr size_t capacity() const noexcept { + MDBX_NOTHROW_PURE_FUNCTION MDBX_CXX20_CONSTEXPR size_t + capacity() const noexcept { return is_freestanding() ? silo_.capacity() : 0; } /// \brief Returns the number of bytes that available in currently allocated /// storage ahead of the currently beginning of data. - __nothrow_pure_function cxx20_constexpr size_t headroom() const noexcept { + MDBX_NOTHROW_PURE_FUNCTION MDBX_CXX20_CONSTEXPR size_t + headroom() const noexcept { return is_freestanding() ? slice_.byte_ptr() - silo_begin() : 0; } /// \brief Returns the number of bytes that available in currently allocated /// storage afther of the currently data end. - __nothrow_pure_function cxx20_constexpr size_t tailroom() const noexcept { + MDBX_NOTHROW_PURE_FUNCTION MDBX_CXX20_CONSTEXPR size_t + tailroom() const noexcept { return is_freestanding() ? capacity() - headroom() - slice_.length() : 0; } /// \brief Returns casted to const pointer to byte an address of data. - cxx11_constexpr const byte *byte_ptr() const noexcept { + MDBX_CXX11_CONSTEXPR const byte *byte_ptr() const noexcept { return slice_.byte_ptr(); } /// \brief Returns casted to pointer to byte an address of data. /// \pre REQUIRES: The buffer should store data chunk, but not referenced to /// an external one. - cxx11_constexpr byte *byte_ptr() noexcept { + MDBX_CXX11_CONSTEXPR byte *byte_ptr() noexcept { assert(is_freestanding()); return const_cast(slice_.byte_ptr()); } /// \brief Returns casted to const pointer to char an address of data. - cxx11_constexpr const char *char_ptr() const noexcept { + MDBX_CXX11_CONSTEXPR const char *char_ptr() const noexcept { return slice_.char_ptr(); } /// \brief Returns casted to pointer to char an address of data. /// \pre REQUIRES: The buffer should store data chunk, but not referenced to /// an external one. - cxx11_constexpr char *char_ptr() noexcept { + MDBX_CXX11_CONSTEXPR char *char_ptr() noexcept { assert(is_freestanding()); return const_cast(slice_.char_ptr()); } /// \brief Return a const pointer to the beginning of the referenced data. - cxx11_constexpr const void *data() const noexcept { return slice_.data(); } + MDBX_CXX11_CONSTEXPR const void *data() const noexcept { + return slice_.data(); + } /// \brief Return a pointer to the beginning of the referenced data. /// \pre REQUIRES: The buffer should store data chunk, but not referenced to /// an external one. - cxx11_constexpr void *data() noexcept { + MDBX_CXX11_CONSTEXPR void *data() noexcept { assert(is_freestanding()); return const_cast(slice_.data()); } /// \brief Returns the number of bytes. - __nothrow_pure_function cxx20_constexpr size_t length() const noexcept { - return CONSTEXPR_ASSERT(is_reference() || - slice_.length() + headroom() == silo_.length()), + MDBX_NOTHROW_PURE_FUNCTION MDBX_CXX20_CONSTEXPR size_t + length() const noexcept { + return MDBX_CONSTEXPR_ASSERT(is_reference() || + slice_.length() + headroom() == + silo_.length()), slice_.length(); } @@ -982,32 +992,36 @@ public: : buffer(::mdbx::slice(view), make_reference, allocator) {} #endif /* __cpp_lib_string_view >= 201606L */ - cxx20_constexpr buffer(const ::mdbx::slice &src, - const allocator_type &allocator = allocator_type()) + MDBX_CXX20_CONSTEXPR + buffer(const ::mdbx::slice &src, + const allocator_type &allocator = allocator_type()) : silo_(src.char_ptr(), src.length(), allocator), slice_(silo_) {} - cxx20_constexpr buffer(const buffer &src, - const allocator_type &allocator = allocator_type()) + MDBX_CXX20_CONSTEXPR + buffer(const buffer &src, const allocator_type &allocator = allocator_type()) : buffer(src.slice_, allocator) {} - cxx20_constexpr buffer(const void *ptr, size_t bytes, - const allocator_type &allocator = allocator_type()) + MDBX_CXX20_CONSTEXPR + buffer(const void *ptr, size_t bytes, + const allocator_type &allocator = allocator_type()) : buffer(::mdbx::slice(ptr, bytes), allocator) {} template - cxx20_constexpr buffer(const ::std::basic_string &str, - const allocator_type &allocator = allocator_type()) + MDBX_CXX20_CONSTEXPR + buffer(const ::std::basic_string &str, + const allocator_type &allocator = allocator_type()) : buffer(::mdbx::slice(str), allocator) {} - cxx20_constexpr buffer(const char *c_str, - const allocator_type &allocator = allocator_type()) + MDBX_CXX20_CONSTEXPR + buffer(const char *c_str, const allocator_type &allocator = allocator_type()) : buffer(::mdbx::slice(c_str), allocator) {} #if defined(DOXYGEN) || \ (defined(__cpp_lib_string_view) && __cpp_lib_string_view >= 201606L) template - cxx20_constexpr buffer(const ::std::basic_string_view &view, - const allocator_type &allocator = allocator_type()) + MDBX_CXX20_CONSTEXPR + buffer(const ::std::basic_string_view &view, + const allocator_type &allocator = allocator_type()) : buffer(::mdbx::slice(view), allocator) {} #endif /* __cpp_lib_string_view >= 201606L */ @@ -1024,7 +1038,7 @@ public: const allocator_type &allocator = allocator_type()) : buffer(head_room, src.slice_, tail_room, allocator) {} - cxx20_constexpr + MDBX_CXX20_CONSTEXPR buffer(const allocator_type &allocator = allocator_type()) noexcept : silo_(allocator) {} @@ -1036,9 +1050,11 @@ public: buffer(silo &&str) noexcept : silo_(::std::move(str)), slice_(silo_) {} - cxx11_constexpr const ::mdbx::slice &slice() const noexcept { return slice_; } + MDBX_CXX11_CONSTEXPR const ::mdbx::slice &slice() const noexcept { + return slice_; + } - cxx11_constexpr operator const ::mdbx::slice &() const noexcept { + MDBX_CXX11_CONSTEXPR operator const ::mdbx::slice &() const noexcept { return slice_; } @@ -1284,15 +1300,17 @@ public: } /// \brief Checks whether the string is empty. - __nothrow_pure_function cxx20_constexpr bool empty() const noexcept { + MDBX_NOTHROW_PURE_FUNCTION MDBX_CXX20_CONSTEXPR bool empty() const noexcept { return length() == 0; } /// \brief Checks whether the data pointer of the buffer is nullptr. - cxx11_constexpr bool is_null() const noexcept { return data() == nullptr; } + MDBX_CXX11_CONSTEXPR bool is_null() const noexcept { + return data() == nullptr; + } /// \brief Returns the number of bytes. - __nothrow_pure_function cxx20_constexpr size_t size() const noexcept { + MDBX_NOTHROW_PURE_FUNCTION MDBX_CXX20_CONSTEXPR size_t size() const noexcept { return length(); } @@ -1300,30 +1318,31 @@ public: /// \attention Function implementation and returned hash values may changed /// version to version, and in future the t1ha3 will be used here. Therefore /// values obtained from this function shouldn't be persisted anywhere. - __nothrow_pure_function cxx14_constexpr size_t hash_value() const noexcept { + MDBX_NOTHROW_PURE_FUNCTION MDBX_CXX14_CONSTEXPR size_t + hash_value() const noexcept { return slice_.hash_value(); } template , class A = legacy_allocator> - cxx20_constexpr ::std::basic_string + MDBX_CXX20_CONSTEXPR ::std::basic_string string(const A &allocator = A()) const { return slice_.string(allocator); } template - cxx20_constexpr operator ::std::basic_string() const { + MDBX_CXX20_CONSTEXPR operator ::std::basic_string() const { return this->string(); } /// \brief Checks if the data starts with the given prefix. - __nothrow_pure_function bool + MDBX_NOTHROW_PURE_FUNCTION bool starts_with(const ::mdbx::slice &prefix) const noexcept { return slice_.starts_with(prefix); } /// \brief Checks if the data ends with the given suffix. - __nothrow_pure_function bool + MDBX_NOTHROW_PURE_FUNCTION bool ends_with(const ::mdbx::slice &suffix) const noexcept { return slice_.ends_with(suffix); } @@ -1371,8 +1390,8 @@ public: /// \brief Accesses the specified byte of data chunk with bounds checking. /// \throws std::out_of_range if `n >= size()` byte &at(size_t n) { - if (mdbx_unlikely(n >= size())) - cxx20_attribute_unlikely throw_out_range(); + if (MDBX_UNLIKELY(n >= size())) + MDBX_CXX20_UNLIKELY throw_out_range(); return byte_ptr()[n]; } @@ -1492,7 +1511,7 @@ struct value_result { : value(value), done(done) {} value_result(const value_result &) noexcept = default; value_result &operator=(const value_result &) noexcept = default; - cxx14_constexpr operator bool() const noexcept { + MDBX_CXX14_CONSTEXPR operator bool() const noexcept { assert(!done || bool(value)); return done; } @@ -1506,7 +1525,7 @@ struct pair { : key(key), value(value) {} pair(const pair &) noexcept = default; pair &operator=(const pair &) noexcept = default; - cxx14_constexpr operator bool() const noexcept { + MDBX_CXX14_CONSTEXPR operator bool() const noexcept { assert(bool(key) == bool(value)); return key; } @@ -1520,7 +1539,7 @@ struct pair_result : public pair { : pair(key, value), done(done) {} pair_result(const pair_result &) noexcept = default; pair_result &operator=(const pair_result &) noexcept = default; - cxx14_constexpr operator bool() const noexcept { + MDBX_CXX14_CONSTEXPR operator bool() const noexcept { assert(!done || (bool(key) && bool(value))); return done; } @@ -1627,8 +1646,8 @@ enum class value_mode { /// \see cursor::map() struct LIBMDBX_API_TYPE map_handle { MDBX_dbi dbi{0}; - cxx11_constexpr map_handle() noexcept {} - cxx11_constexpr map_handle(MDBX_dbi dbi) noexcept : dbi(dbi) {} + MDBX_CXX11_CONSTEXPR map_handle() noexcept {} + MDBX_CXX11_CONSTEXPR map_handle(MDBX_dbi dbi) noexcept : dbi(dbi) {} map_handle(const map_handle &) noexcept = default; map_handle &operator=(const map_handle &) noexcept = default; operator bool() const noexcept { return dbi != 0; } @@ -1638,12 +1657,12 @@ struct LIBMDBX_API_TYPE map_handle { struct LIBMDBX_API_TYPE info { map_handle::flags flags; map_handle::state state; - cxx11_constexpr info(map_handle::flags flags, - map_handle::state state) noexcept; + MDBX_CXX11_CONSTEXPR info(map_handle::flags flags, + map_handle::state state) noexcept; info(const info &) noexcept = default; info &operator=(const info &) noexcept = default; - cxx11_constexpr ::mdbx::key_mode key_mode() const noexcept; - cxx11_constexpr ::mdbx::value_mode value_mode() const noexcept; + MDBX_CXX11_CONSTEXPR ::mdbx::key_mode key_mode() const noexcept; + MDBX_CXX11_CONSTEXPR ::mdbx::value_mode value_mode() const noexcept; }; }; @@ -1667,20 +1686,22 @@ class LIBMDBX_API_TYPE env { protected: MDBX_env *handle_{nullptr}; - cxx11_constexpr env(MDBX_env *ptr) noexcept; + MDBX_CXX11_CONSTEXPR env(MDBX_env *ptr) noexcept; public: - cxx11_constexpr env() noexcept = default; + MDBX_CXX11_CONSTEXPR env() noexcept = default; env(const env &) noexcept = default; inline env &operator=(env &&other) noexcept; inline env(env &&other) noexcept; inline ~env() noexcept; - cxx14_constexpr operator bool() const noexcept; - cxx14_constexpr operator const MDBX_env *() const; - cxx14_constexpr operator MDBX_env *(); - friend cxx11_constexpr bool operator==(const env &a, const env &b) noexcept; - friend cxx11_constexpr bool operator!=(const env &a, const env &b) noexcept; + MDBX_CXX14_CONSTEXPR operator bool() const noexcept; + MDBX_CXX14_CONSTEXPR operator const MDBX_env *() const; + MDBX_CXX14_CONSTEXPR operator MDBX_env *(); + friend MDBX_CXX11_CONSTEXPR bool operator==(const env &a, + const env &b) noexcept; + friend MDBX_CXX11_CONSTEXPR bool operator!=(const env &a, + const env &b) noexcept; //---------------------------------------------------------------------------- @@ -1707,8 +1728,8 @@ public: /// \brief Tagged type for output to std::ostream struct size { intptr_t bytes; - cxx11_constexpr size(intptr_t bytes) noexcept : bytes(bytes) {} - cxx11_constexpr operator intptr_t() const noexcept { return bytes; } + MDBX_CXX11_CONSTEXPR size(intptr_t bytes) noexcept : bytes(bytes) {} + MDBX_CXX11_CONSTEXPR operator intptr_t() const noexcept { return bytes; } }; /// \brief The lower bound of database size in bytes. @@ -1771,7 +1792,7 @@ public: bool lifo{false}; /// \copydoc MDBX_COALESCE bool coalesce{false}; - cxx11_constexpr reclaiming_options() noexcept {} + MDBX_CXX11_CONSTEXPR reclaiming_options() noexcept {} reclaiming_options(MDBX_env_flags_t) noexcept; }; @@ -1786,7 +1807,7 @@ public: bool disable_readahead{false}; /// \copydoc MDBX_NOMEMINIT bool disable_clear_memory{false}; - cxx11_constexpr operate_options() noexcept {} + MDBX_CXX11_CONSTEXPR operate_options() noexcept {} operate_options(MDBX_env_flags_t) noexcept; }; @@ -1803,7 +1824,7 @@ public: env::reclaiming_options reclaiming; env::operate_options options; - cxx11_constexpr operate_parameters() noexcept {} + MDBX_CXX11_CONSTEXPR operate_parameters() noexcept {} MDBX_env_flags_t make_flags(bool accede = true, ///< \copydoc MDBX_ACCEDE bool use_subdirectory = false) const; static env::mode mode_from_flags(MDBX_env_flags_t) noexcept; @@ -2077,9 +2098,10 @@ public: ///< the MVCC-snapshot for reuse by completion read ///< transaction. - cxx11_constexpr reader_info(int slot, mdbx_pid_t pid, mdbx_tid_t thread, - uint64_t txnid, uint64_t lag, size_t used, - size_t retained) noexcept; + MDBX_CXX11_CONSTEXPR reader_info(int slot, mdbx_pid_t pid, + mdbx_tid_t thread, uint64_t txnid, + uint64_t lag, size_t used, + size_t retained) noexcept; }; /// \brief Enumerate readers. @@ -2136,11 +2158,11 @@ public: class LIBMDBX_API_TYPE env_managed : public env { using inherited = env; /// delegated constructor for RAII - cxx11_constexpr env_managed(MDBX_env *ptr) noexcept : inherited(ptr) {} + MDBX_CXX11_CONSTEXPR env_managed(MDBX_env *ptr) noexcept : inherited(ptr) {} void setup(unsigned max_maps, unsigned max_readers = 0); public: - cxx11_constexpr env_managed() noexcept = default; + MDBX_CXX11_CONSTEXPR env_managed() noexcept = default; /// \brief Open existing database. env_managed(const path &, const operate_parameters &, bool accede = true); @@ -2190,20 +2212,22 @@ class LIBMDBX_API_TYPE txn { protected: friend class cursor; MDBX_txn *handle_{nullptr}; - cxx11_constexpr txn(MDBX_txn *ptr) noexcept; + MDBX_CXX11_CONSTEXPR txn(MDBX_txn *ptr) noexcept; public: - cxx11_constexpr txn() noexcept = default; + MDBX_CXX11_CONSTEXPR txn() noexcept = default; txn(const txn &) noexcept = default; inline txn &operator=(txn &&other) noexcept; inline txn(txn &&other) noexcept; inline ~txn() noexcept; - cxx14_constexpr operator bool() const noexcept; - cxx14_constexpr operator const MDBX_txn *() const; - cxx14_constexpr operator MDBX_txn *(); - friend cxx11_constexpr bool operator==(const txn &a, const txn &b) noexcept; - friend cxx11_constexpr bool operator!=(const txn &a, const txn &b) noexcept; + MDBX_CXX14_CONSTEXPR operator bool() const noexcept; + MDBX_CXX14_CONSTEXPR operator const MDBX_txn *() const; + MDBX_CXX14_CONSTEXPR operator MDBX_txn *(); + friend MDBX_CXX11_CONSTEXPR bool operator==(const txn &a, + const txn &b) noexcept; + friend MDBX_CXX11_CONSTEXPR bool operator!=(const txn &a, + const txn &b) noexcept; /// \brief Returns the transaction's environment. inline ::mdbx::env env() const noexcept; @@ -2448,10 +2472,10 @@ class LIBMDBX_API_TYPE txn_managed : public txn { friend class env; friend class txn; /// delegated constructor for RAII - cxx11_constexpr txn_managed(MDBX_txn *ptr) noexcept : inherited(ptr) {} + MDBX_CXX11_CONSTEXPR txn_managed(MDBX_txn *ptr) noexcept : inherited(ptr) {} public: - cxx11_constexpr txn_managed() noexcept = default; + MDBX_CXX11_CONSTEXPR txn_managed() noexcept = default; txn_managed(txn_managed &&) = default; txn_managed &operator=(txn_managed &&) = default; txn_managed(const txn_managed &) = delete; @@ -2478,21 +2502,21 @@ public: class LIBMDBX_API_TYPE cursor { protected: MDBX_cursor *handle_{nullptr}; - cxx11_constexpr cursor(MDBX_cursor *ptr) noexcept; + MDBX_CXX11_CONSTEXPR cursor(MDBX_cursor *ptr) noexcept; public: - cxx11_constexpr cursor() noexcept = default; + MDBX_CXX11_CONSTEXPR cursor() noexcept = default; cursor(const cursor &) noexcept = default; inline cursor &operator=(cursor &&other) noexcept; inline cursor(cursor &&other) noexcept; inline ~cursor() noexcept; - cxx14_constexpr operator bool() const noexcept; - cxx14_constexpr operator const MDBX_cursor *() const; - cxx14_constexpr operator MDBX_cursor *(); - friend cxx11_constexpr bool operator==(const cursor &a, - const cursor &b) noexcept; - friend cxx11_constexpr bool operator!=(const cursor &a, - const cursor &b) noexcept; + MDBX_CXX14_CONSTEXPR operator bool() const noexcept; + MDBX_CXX14_CONSTEXPR operator const MDBX_cursor *() const; + MDBX_CXX14_CONSTEXPR operator MDBX_cursor *(); + friend MDBX_CXX11_CONSTEXPR bool operator==(const cursor &a, + const cursor &b) noexcept; + friend MDBX_CXX11_CONSTEXPR bool operator!=(const cursor &a, + const cursor &b) noexcept; enum move_operation { first = MDBX_FIRST, @@ -2615,10 +2639,11 @@ class LIBMDBX_API_TYPE cursor_managed : public cursor { using inherited = cursor; friend class txn; /// delegated constructor for RAII - cxx11_constexpr cursor_managed(MDBX_cursor *ptr) noexcept : inherited(ptr) {} + MDBX_CXX11_CONSTEXPR cursor_managed(MDBX_cursor *ptr) noexcept + : inherited(ptr) {} public: - cxx11_constexpr cursor_managed() noexcept = default; + MDBX_CXX11_CONSTEXPR cursor_managed() noexcept = default; /// Explicitly closes the cursor. void close(); @@ -2672,12 +2697,14 @@ inline ::std::ostream &operator<<(::std::ostream &out, // Inline body of the libmdbx C++ API (preliminary draft) // -cxx11_constexpr const version_info &get_version() noexcept { +MDBX_CXX11_CONSTEXPR const version_info &get_version() noexcept { return ::mdbx_version; } -cxx11_constexpr const build_info &get_build() noexcept { return ::mdbx_build; } +MDBX_CXX11_CONSTEXPR const build_info &get_build() noexcept { + return ::mdbx_build; +} -static cxx17_constexpr size_t strlen(const char *c_str) noexcept { +static MDBX_CXX17_CONSTEXPR size_t strlen(const char *c_str) noexcept { #if defined(__cpp_lib_is_constant_evaluated) && \ __cpp_lib_is_constant_evaluated >= 201811L if (::std::is_constant_evaluated()) { @@ -2694,9 +2721,9 @@ static cxx17_constexpr size_t strlen(const char *c_str) noexcept { #endif } -cxx14_constexpr size_t check_length(size_t bytes) { - if (mdbx_unlikely(bytes > size_t(MDBX_MAXDATASIZE))) - cxx20_attribute_unlikely throw_max_length_exceeded(); +MDBX_CXX14_CONSTEXPR size_t check_length(size_t bytes) { + if (MDBX_UNLIKELY(bytes > size_t(MDBX_MAXDATASIZE))) + MDBX_CXX20_UNLIKELY throw_max_length_exceeded(); return bytes; } @@ -2709,12 +2736,12 @@ inline void exception_thunk::capture() noexcept { inline void exception_thunk::rethrow_captured() const { if (captured_) - cxx20_attribute_unlikely ::std::rethrow_exception(captured_); + MDBX_CXX20_UNLIKELY ::std::rethrow_exception(captured_); } //------------------------------------------------------------------------------ -cxx11_constexpr error::error(MDBX_error_t error_code) noexcept +MDBX_CXX11_CONSTEXPR error::error(MDBX_error_t error_code) noexcept : code_(error_code) {} inline error &error::operator=(MDBX_error_t error_code) noexcept { @@ -2722,33 +2749,33 @@ inline error &error::operator=(MDBX_error_t error_code) noexcept { return *this; } -cxx11_constexpr bool operator==(const error &a, const error &b) noexcept { +MDBX_CXX11_CONSTEXPR bool operator==(const error &a, const error &b) noexcept { return a.code_ == b.code_; } -cxx11_constexpr bool operator!=(const error &a, const error &b) noexcept { +MDBX_CXX11_CONSTEXPR bool operator!=(const error &a, const error &b) noexcept { return !(a == b); } -cxx11_constexpr bool error::is_success() const noexcept { +MDBX_CXX11_CONSTEXPR bool error::is_success() const noexcept { return code_ == MDBX_SUCCESS; } -cxx11_constexpr bool error::is_result_true() const noexcept { +MDBX_CXX11_CONSTEXPR bool error::is_result_true() const noexcept { return code_ == MDBX_RESULT_FALSE; } -cxx11_constexpr bool error::is_result_false() const noexcept { +MDBX_CXX11_CONSTEXPR bool error::is_result_false() const noexcept { return code_ == MDBX_RESULT_TRUE; } -cxx11_constexpr bool error::is_failure() const noexcept { +MDBX_CXX11_CONSTEXPR bool error::is_failure() const noexcept { return code_ != MDBX_SUCCESS && code_ != MDBX_RESULT_TRUE; } -cxx11_constexpr MDBX_error_t error::code() const noexcept { return code_; } +MDBX_CXX11_CONSTEXPR MDBX_error_t error::code() const noexcept { return code_; } -cxx11_constexpr bool error::is_mdbx_error() const noexcept { +MDBX_CXX11_CONSTEXPR bool error::is_mdbx_error() const noexcept { return (code() >= MDBX_FIRST_LMDB_ERRCODE && code() <= MDBX_LAST_LMDB_ERRCODE) || (code() >= MDBX_FIRST_ADDED_ERRCODE && @@ -2761,38 +2788,38 @@ inline void error::throw_exception(int error_code) { } inline void error::throw_on_failure() const { - if (mdbx_unlikely(is_failure())) - cxx20_attribute_unlikely throw_exception(); + if (MDBX_UNLIKELY(is_failure())) + MDBX_CXX20_UNLIKELY throw_exception(); } inline void error::success_or_throw() const { - if (mdbx_unlikely(!is_success())) - cxx20_attribute_unlikely throw_exception(); + if (MDBX_UNLIKELY(!is_success())) + MDBX_CXX20_UNLIKELY throw_exception(); } inline void error::success_or_throw(const exception_thunk &thunk) const { assert(thunk.is_clean() || code() != MDBX_SUCCESS); - if (mdbx_unlikely(!is_success())) { - cxx20_attribute_unlikely if (!thunk.is_clean()) thunk.rethrow_captured(); + if (MDBX_UNLIKELY(!is_success())) { + MDBX_CXX20_UNLIKELY if (!thunk.is_clean()) thunk.rethrow_captured(); else throw_exception(); } } inline void error::panic_on_failure(const char *context_where, const char *func_who) const noexcept { - if (mdbx_unlikely(is_failure())) - cxx20_attribute_unlikely panic(context_where, func_who); + if (MDBX_UNLIKELY(is_failure())) + MDBX_CXX20_UNLIKELY panic(context_where, func_who); } inline void error::success_or_panic(const char *context_where, const char *func_who) const noexcept { - if (mdbx_unlikely(!is_success())) - cxx20_attribute_unlikely panic(context_where, func_who); + if (MDBX_UNLIKELY(!is_success())) + MDBX_CXX20_UNLIKELY panic(context_where, func_who); } inline void error::throw_on_nullptr(const void *ptr, MDBX_error_t error_code) { - if (mdbx_unlikely(ptr == nullptr)) - cxx20_attribute_unlikely error(error_code).throw_exception(); + if (MDBX_UNLIKELY(ptr == nullptr)) + MDBX_CXX20_UNLIKELY error(error_code).throw_exception(); } inline void error::throw_on_failure(int error_code) { @@ -2812,7 +2839,7 @@ inline bool error::boolean_or_throw(int error_code) { case MDBX_RESULT_TRUE: return true; default: - cxx20_attribute_unlikely throw_exception(error_code); + MDBX_CXX20_UNLIKELY throw_exception(error_code); } } @@ -2836,19 +2863,19 @@ inline void error::success_or_panic(int error_code, const char *context_where, //------------------------------------------------------------------------------ -cxx11_constexpr slice::slice() noexcept : ::MDBX_val({nullptr, 0}) {} +MDBX_CXX11_CONSTEXPR slice::slice() noexcept : ::MDBX_val({nullptr, 0}) {} -cxx14_constexpr slice::slice(const void *ptr, size_t bytes) +MDBX_CXX14_CONSTEXPR slice::slice(const void *ptr, size_t bytes) : ::MDBX_val({const_cast(ptr), check_length(bytes)}) {} -cxx14_constexpr slice::slice(const void *begin, const void *end) +MDBX_CXX14_CONSTEXPR slice::slice(const void *begin, const void *end) : slice(begin, static_cast(end) - static_cast(begin)) {} -cxx17_constexpr slice::slice(const char *c_str) +MDBX_CXX17_CONSTEXPR slice::slice(const char *c_str) : slice(c_str, ::mdbx::strlen(c_str)) {} -cxx14_constexpr slice::slice(const MDBX_val &src) +MDBX_CXX14_CONSTEXPR slice::slice(const MDBX_val &src) : slice(src.iov_base, src.iov_len) {} inline slice::slice(MDBX_val &&src) : slice(src) { src.iov_base = nullptr; } @@ -2906,27 +2933,33 @@ inline void slice::swap(slice &other) noexcept { other = temp; } -cxx11_constexpr const mdbx::byte *slice::byte_ptr() const noexcept { +MDBX_CXX11_CONSTEXPR const mdbx::byte *slice::byte_ptr() const noexcept { return static_cast(iov_base); } -cxx11_constexpr const char *slice::char_ptr() const noexcept { +MDBX_CXX11_CONSTEXPR const char *slice::char_ptr() const noexcept { return static_cast(iov_base); } -cxx11_constexpr const void *slice::data() const noexcept { return iov_base; } +MDBX_CXX11_CONSTEXPR const void *slice::data() const noexcept { + return iov_base; +} -cxx11_constexpr size_t slice::length() const noexcept { return iov_len; } +MDBX_CXX11_CONSTEXPR size_t slice::length() const noexcept { return iov_len; } -cxx11_constexpr bool slice::empty() const noexcept { return length() == 0; } +MDBX_CXX11_CONSTEXPR bool slice::empty() const noexcept { + return length() == 0; +} -cxx11_constexpr bool slice::is_null() const noexcept { +MDBX_CXX11_CONSTEXPR bool slice::is_null() const noexcept { return data() == nullptr; } -cxx11_constexpr size_t slice::size() const noexcept { return length(); } +MDBX_CXX11_CONSTEXPR size_t slice::size() const noexcept { return length(); } -cxx11_constexpr slice::operator bool() const noexcept { return !is_null(); } +MDBX_CXX11_CONSTEXPR slice::operator bool() const noexcept { + return !is_null(); +} inline void slice::invalidate() noexcept { iov_base = nullptr; } @@ -2942,8 +2975,8 @@ inline void slice::remove_prefix(size_t n) noexcept { } inline void slice::safe_remove_prefix(size_t n) { - if (mdbx_unlikely(n > size())) - cxx20_attribute_unlikely throw_out_range(); + if (MDBX_UNLIKELY(n > size())) + MDBX_CXX20_UNLIKELY throw_out_range(); remove_prefix(n); } @@ -2953,8 +2986,8 @@ inline void slice::remove_suffix(size_t n) noexcept { } inline void slice::safe_remove_suffix(size_t n) { - if (mdbx_unlikely(n > size())) - cxx20_attribute_unlikely throw_out_range(); + if (MDBX_UNLIKELY(n > size())) + MDBX_CXX20_UNLIKELY throw_out_range(); remove_suffix(n); } @@ -2969,7 +3002,7 @@ inline bool slice::ends_with(const slice &suffix) const noexcept { suffix.length()) == 0; } -__nothrow_pure_function cxx14_constexpr size_t +MDBX_NOTHROW_PURE_FUNCTION MDBX_CXX14_CONSTEXPR size_t slice::hash_value() const noexcept { size_t h = length() * 3977471; for (size_t i = 0; i < length(); ++i) @@ -2983,8 +3016,8 @@ inline byte slice::operator[](size_t n) const noexcept { } inline byte slice::at(size_t n) const { - if (mdbx_unlikely(n >= size())) - cxx20_attribute_unlikely throw_out_range(); + if (MDBX_UNLIKELY(n >= size())) + MDBX_CXX20_UNLIKELY throw_out_range(); return byte_ptr()[n]; } @@ -3004,22 +3037,22 @@ inline slice slice::middle(size_t from, size_t n) const noexcept { } inline slice slice::safe_head(size_t n) const { - if (mdbx_unlikely(n > size())) - cxx20_attribute_unlikely throw_out_range(); + if (MDBX_UNLIKELY(n > size())) + MDBX_CXX20_UNLIKELY throw_out_range(); return head(n); } inline slice slice::safe_tail(size_t n) const { - if (mdbx_unlikely(n > size())) - cxx20_attribute_unlikely throw_out_range(); + if (MDBX_UNLIKELY(n > size())) + MDBX_CXX20_UNLIKELY throw_out_range(); return tail(n); } inline slice slice::safe_middle(size_t from, size_t n) const { - if (mdbx_unlikely(n > max_length)) - cxx20_attribute_unlikely throw_max_length_exceeded(); - if (mdbx_unlikely(from + n > size())) - cxx20_attribute_unlikely throw_out_range(); + if (MDBX_UNLIKELY(n > max_length)) + MDBX_CXX20_UNLIKELY throw_max_length_exceeded(); + if (MDBX_UNLIKELY(from + n > size())) + MDBX_CXX20_UNLIKELY throw_out_range(); return middle(from, n); } @@ -3038,33 +3071,33 @@ inline intptr_t slice::compare_lexicographically(const slice &a, return diff ? diff : intptr_t(a.length() - b.length()); } -__nothrow_pure_function inline bool operator==(const slice &a, - const slice &b) noexcept { +MDBX_NOTHROW_PURE_FUNCTION inline bool operator==(const slice &a, + const slice &b) noexcept { return slice::compare_fast(a, b) == 0; } -__nothrow_pure_function inline bool operator<(const slice &a, - const slice &b) noexcept { +MDBX_NOTHROW_PURE_FUNCTION inline bool operator<(const slice &a, + const slice &b) noexcept { return slice::compare_lexicographically(a, b) < 0; } -__nothrow_pure_function inline bool operator>(const slice &a, - const slice &b) noexcept { +MDBX_NOTHROW_PURE_FUNCTION inline bool operator>(const slice &a, + const slice &b) noexcept { return slice::compare_lexicographically(a, b) > 0; } -__nothrow_pure_function inline bool operator<=(const slice &a, - const slice &b) noexcept { +MDBX_NOTHROW_PURE_FUNCTION inline bool operator<=(const slice &a, + const slice &b) noexcept { return slice::compare_lexicographically(a, b) <= 0; } -__nothrow_pure_function inline bool operator>=(const slice &a, - const slice &b) noexcept { +MDBX_NOTHROW_PURE_FUNCTION inline bool operator>=(const slice &a, + const slice &b) noexcept { return slice::compare_lexicographically(a, b) >= 0; } -__nothrow_pure_function inline bool operator!=(const slice &a, - const slice &b) noexcept { +MDBX_NOTHROW_PURE_FUNCTION inline bool operator!=(const slice &a, + const slice &b) noexcept { return slice::compare_fast(a, b) != 0; } @@ -3072,7 +3105,7 @@ template inline ::mdbx::string slice::hex_encode(bool uppercase, const ALLOCATOR &allocator) const { ::mdbx::string result(allocator); - if (mdbx_likely(length() > 0)) { + if (MDBX_LIKELY(length() > 0)) { result.reserve(to_hex_bytes()); result.resize(to_hex(const_cast(result.data()), result.capacity()) - result.data(), @@ -3085,7 +3118,7 @@ template inline ::mdbx::string slice::hex_decode(const ALLOCATOR &allocator) const { ::mdbx::string result(allocator); - if (mdbx_likely(length() > 0)) { + if (MDBX_LIKELY(length() > 0)) { result.reserve(from_hex_bytes()); result.resize( from_hex(static_cast( @@ -3100,7 +3133,7 @@ template inline ::mdbx::string slice::base58_encode(const ALLOCATOR &allocator) const { ::mdbx::string result(allocator); - if (mdbx_likely(length() > 0)) { + if (MDBX_LIKELY(length() > 0)) { result.reserve(to_base58_bytes()); result.resize( to_base58(const_cast(result.data()), result.capacity()) - @@ -3113,7 +3146,7 @@ template inline ::mdbx::string slice::base58_decode(const ALLOCATOR &allocator) const { ::mdbx::string result(allocator); - if (mdbx_likely(length() > 0)) { + if (MDBX_LIKELY(length() > 0)) { result.reserve(from_base58_bytes()); result.resize( from_base58(static_cast( @@ -3128,7 +3161,7 @@ template inline ::mdbx::string slice::base64_encode(const ALLOCATOR &allocator) const { ::mdbx::string result(allocator); - if (mdbx_likely(length() > 0)) { + if (MDBX_LIKELY(length() > 0)) { result.reserve(to_base64_bytes()); result.resize( to_base64(const_cast(result.data()), result.capacity()) - @@ -3141,7 +3174,7 @@ template inline ::mdbx::string slice::base64_decode(const ALLOCATOR &allocator) const { ::mdbx::string result(allocator); - if (mdbx_likely(length() > 0)) { + if (MDBX_LIKELY(length() > 0)) { result.reserve(from_base64_bytes()); result.resize( from_base64(static_cast( @@ -3154,15 +3187,16 @@ slice::base64_decode(const ALLOCATOR &allocator) const { //------------------------------------------------------------------------------ -cxx11_constexpr map_handle::info::info(map_handle::flags flags, - map_handle::state state) noexcept +MDBX_CXX11_CONSTEXPR map_handle::info::info(map_handle::flags flags, + map_handle::state state) noexcept : flags(flags), state(state) {} -cxx11_constexpr ::mdbx::key_mode map_handle::info::key_mode() const noexcept { +MDBX_CXX11_CONSTEXPR ::mdbx::key_mode +map_handle::info::key_mode() const noexcept { return ::mdbx::key_mode(flags & (MDBX_REVERSEKEY | MDBX_INTEGERKEY)); } -cxx11_constexpr ::mdbx::value_mode +MDBX_CXX11_CONSTEXPR ::mdbx::value_mode map_handle::info::value_mode() const noexcept { return ::mdbx::value_mode(flags & (MDBX_DUPSORT | MDBX_REVERSEDUP | MDBX_DUPFIXED | MDBX_INTEGERDUP)); @@ -3170,7 +3204,7 @@ map_handle::info::value_mode() const noexcept { //------------------------------------------------------------------------------ -cxx11_constexpr env::env(MDBX_env *ptr) noexcept : handle_(ptr) {} +MDBX_CXX11_CONSTEXPR env::env(MDBX_env *ptr) noexcept : handle_(ptr) {} inline env &env::operator=(env &&other) noexcept { handle_ = other.handle_; @@ -3188,19 +3222,19 @@ inline env::~env() noexcept { #endif } -cxx14_constexpr env::operator bool() const noexcept { +MDBX_CXX14_CONSTEXPR env::operator bool() const noexcept { return handle_ != nullptr; } -cxx14_constexpr env::operator const MDBX_env *() const { return handle_; } +MDBX_CXX14_CONSTEXPR env::operator const MDBX_env *() const { return handle_; } -cxx14_constexpr env::operator MDBX_env *() { return handle_; } +MDBX_CXX14_CONSTEXPR env::operator MDBX_env *() { return handle_; } -cxx11_constexpr bool operator==(const env &a, const env &b) noexcept { +MDBX_CXX11_CONSTEXPR bool operator==(const env &a, const env &b) noexcept { return a.handle_ == b.handle_; } -cxx11_constexpr bool operator!=(const env &a, const env &b) noexcept { +MDBX_CXX11_CONSTEXPR bool operator!=(const env &a, const env &b) noexcept { return a.handle_ != b.handle_; } @@ -3235,14 +3269,14 @@ inline size_t env::limits::pagesize_max() noexcept { return MDBX_MAX_PAGESIZE; } inline size_t env::limits::dbsize_min(intptr_t pagesize) { const intptr_t result = mdbx_limits_dbsize_min(pagesize); if (result < 0) - cxx20_attribute_unlikely error::throw_exception(MDBX_EINVAL); + MDBX_CXX20_UNLIKELY error::throw_exception(MDBX_EINVAL); return static_cast(result); } inline size_t env::limits::dbsize_max(intptr_t pagesize) { const intptr_t result = mdbx_limits_dbsize_max(pagesize); if (result < 0) - cxx20_attribute_unlikely error::throw_exception(MDBX_EINVAL); + MDBX_CXX20_UNLIKELY error::throw_exception(MDBX_EINVAL); return static_cast(result); } @@ -3257,7 +3291,7 @@ inline size_t env::limits::key_min(key_mode mode) noexcept { inline size_t env::limits::key_max(intptr_t pagesize, MDBX_db_flags_t flags) { const intptr_t result = mdbx_limits_keysize_max(pagesize, flags); if (result < 0) - cxx20_attribute_unlikely error::throw_exception(MDBX_EINVAL); + MDBX_CXX20_UNLIKELY error::throw_exception(MDBX_EINVAL); return static_cast(result); } @@ -3268,7 +3302,7 @@ inline size_t env::limits::key_max(intptr_t pagesize, key_mode mode) { inline size_t env::limits::key_max(const env &env, MDBX_db_flags_t flags) { const intptr_t result = mdbx_env_get_maxkeysize_ex(env, flags); if (result < 0) - cxx20_attribute_unlikely error::throw_exception(MDBX_EINVAL); + MDBX_CXX20_UNLIKELY error::throw_exception(MDBX_EINVAL); return static_cast(result); } @@ -3287,7 +3321,7 @@ inline size_t env::limits::value_min(value_mode mode) noexcept { inline size_t env::limits::value_max(intptr_t pagesize, MDBX_db_flags_t flags) { const intptr_t result = mdbx_limits_valsize_max(pagesize, flags); if (result < 0) - cxx20_attribute_unlikely error::throw_exception(MDBX_EINVAL); + MDBX_CXX20_UNLIKELY error::throw_exception(MDBX_EINVAL); return static_cast(result); } @@ -3298,7 +3332,7 @@ inline size_t env::limits::value_max(intptr_t pagesize, value_mode mode) { inline size_t env::limits::value_max(const env &env, MDBX_db_flags_t flags) { const intptr_t result = mdbx_env_get_maxvalsize_ex(env, flags); if (result < 0) - cxx20_attribute_unlikely error::throw_exception(MDBX_EINVAL); + MDBX_CXX20_UNLIKELY error::throw_exception(MDBX_EINVAL); return static_cast(result); } @@ -3309,7 +3343,7 @@ inline size_t env::limits::value_max(const env &env, value_mode mode) { inline size_t env::limits::transaction_size_max(intptr_t pagesize) { const intptr_t result = mdbx_limits_txnsize_max(pagesize); if (result < 0) - cxx20_attribute_unlikely error::throw_exception(MDBX_EINVAL); + MDBX_CXX20_UNLIKELY error::throw_exception(MDBX_EINVAL); return static_cast(result); } @@ -3425,7 +3459,7 @@ inline bool env::sync_to_disk(bool force, bool nonblock) { case MDBX_BUSY /* the environment is used by other thread */: return false; default: - cxx20_attribute_unlikely error::throw_exception(err); + MDBX_CXX20_UNLIKELY error::throw_exception(err); } } @@ -3433,10 +3467,10 @@ inline void env::close_map(const map_handle &handle) { error::success_or_throw(::mdbx_dbi_close(*this, handle.dbi)); } -cxx11_constexpr env::reader_info::reader_info(int slot, mdbx_pid_t pid, - mdbx_tid_t thread, uint64_t txnid, - uint64_t lag, size_t used, - size_t retained) noexcept +MDBX_CXX11_CONSTEXPR +env::reader_info::reader_info(int slot, mdbx_pid_t pid, mdbx_tid_t thread, + uint64_t txnid, uint64_t lag, size_t used, + size_t retained) noexcept : slot(slot), pid(pid), thread(thread), transaction_id(txnid), transaction_lag(lag), bytes_used(used), bytes_retained(retained) {} @@ -3457,7 +3491,7 @@ inline int env::enumerate_readers(VISITOR &visitor) { return loop_control::exit_loop; } } - cxx11_constexpr reader_visitor_thunk(VISITOR &visitor) noexcept + MDBX_CXX11_CONSTEXPR reader_visitor_thunk(VISITOR &visitor) noexcept : visitor_(visitor) {} }; reader_visitor_thunk thunk(visitor); @@ -3510,7 +3544,7 @@ inline txn_managed env::try_start_write() { return start_write(true); } //------------------------------------------------------------------------------ -cxx11_constexpr txn::txn(MDBX_txn *ptr) noexcept : handle_(ptr) {} +MDBX_CXX11_CONSTEXPR txn::txn(MDBX_txn *ptr) noexcept : handle_(ptr) {} inline txn &txn::operator=(txn &&other) noexcept { handle_ = other.handle_; @@ -3528,19 +3562,19 @@ inline txn::~txn() noexcept { #endif } -cxx14_constexpr txn::operator bool() const noexcept { +MDBX_CXX14_CONSTEXPR txn::operator bool() const noexcept { return handle_ != nullptr; } -cxx14_constexpr txn::operator const MDBX_txn *() const { return handle_; } +MDBX_CXX14_CONSTEXPR txn::operator const MDBX_txn *() const { return handle_; } -cxx14_constexpr txn::operator MDBX_txn *() { return handle_; } +MDBX_CXX14_CONSTEXPR txn::operator MDBX_txn *() { return handle_; } -cxx11_constexpr bool operator==(const txn &a, const txn &b) noexcept { +MDBX_CXX11_CONSTEXPR bool operator==(const txn &a, const txn &b) noexcept { return a.handle_ == b.handle_; } -cxx11_constexpr bool operator!=(const txn &a, const txn &b) noexcept { +MDBX_CXX11_CONSTEXPR bool operator!=(const txn &a, const txn &b) noexcept { return a.handle_ != b.handle_; } @@ -3548,7 +3582,7 @@ inline bool txn::is_dirty(const void *ptr) const { int err = ::mdbx_is_dirty(handle_, ptr); switch (err) { default: - cxx20_attribute_unlikely error::throw_exception(err); + MDBX_CXX20_UNLIKELY error::throw_exception(err); case MDBX_RESULT_TRUE: return true; case MDBX_RESULT_FALSE: @@ -3727,7 +3761,7 @@ inline slice txn::get(map_handle map, const slice &key, case MDBX_NOTFOUND: return value_at_absence; default: - cxx20_attribute_unlikely error::throw_exception(err); + MDBX_CXX20_UNLIKELY error::throw_exception(err); } } @@ -3741,7 +3775,7 @@ inline slice txn::get(map_handle map, slice key, size_t &values_count, case MDBX_NOTFOUND: return value_at_absence; default: - cxx20_attribute_unlikely error::throw_exception(err); + MDBX_CXX20_UNLIKELY error::throw_exception(err); } } @@ -3767,7 +3801,7 @@ txn::get_equal_or_great(map_handle map, const slice &key, case MDBX_NOTFOUND: return pair_result{key, value_at_absence, false}; default: - cxx20_attribute_unlikely error::throw_exception(err); + MDBX_CXX20_UNLIKELY error::throw_exception(err); } } @@ -3798,7 +3832,7 @@ inline value_result txn::try_insert(map_handle map, const slice &key, case MDBX_KEYEXIST: return value_result{value, false}; default: - cxx20_attribute_unlikely error::throw_exception(err); + MDBX_CXX20_UNLIKELY error::throw_exception(err); } } @@ -3823,7 +3857,7 @@ inline value_result txn::try_insert_reserve(map_handle map, const slice &key, case MDBX_KEYEXIST: return value_result{result, false}; default: - cxx20_attribute_unlikely error::throw_exception(err); + MDBX_CXX20_UNLIKELY error::throw_exception(err); } } @@ -3855,7 +3889,7 @@ inline bool txn::try_update(map_handle map, const slice &key, case MDBX_NOTFOUND: return false; default: - cxx20_attribute_unlikely error::throw_exception(err); + MDBX_CXX20_UNLIKELY error::throw_exception(err); } } @@ -3878,7 +3912,7 @@ inline value_result txn::try_update_reserve(map_handle map, const slice &key, case MDBX_NOTFOUND: return value_result{slice(), false}; default: - cxx20_attribute_unlikely error::throw_exception(err); + MDBX_CXX20_UNLIKELY error::throw_exception(err); } } @@ -3890,7 +3924,7 @@ inline bool txn::erase(map_handle map, const slice &key) { case MDBX_NOTFOUND: return false; default: - cxx20_attribute_unlikely error::throw_exception(err); + MDBX_CXX20_UNLIKELY error::throw_exception(err); } } @@ -3902,7 +3936,7 @@ inline bool txn::erase(map_handle map, const slice &key, const slice &value) { case MDBX_NOTFOUND: return false; default: - cxx20_attribute_unlikely error::throw_exception(err); + MDBX_CXX20_UNLIKELY error::throw_exception(err); } } @@ -3969,13 +4003,13 @@ inline size_t txn::put_multiple(map_handle map, const slice &key, MDBX_put_flags_t(mode) | MDBX_MULTIPLE); switch (err) { case MDBX_SUCCESS: - cxx20_attribute_likely break; + MDBX_CXX20_LIKELY break; case MDBX_KEYEXIST: if (allow_partial) break; mdbx_txn_break(handle_); default: - cxx20_attribute_unlikely error::throw_exception(err); + MDBX_CXX20_UNLIKELY error::throw_exception(err); } return args[1].iov_len /* done item count */; } @@ -4010,7 +4044,7 @@ inline ptrdiff_t txn::estimate_to_last(map_handle map, slice from) const { //------------------------------------------------------------------------------ -cxx11_constexpr cursor::cursor(MDBX_cursor *ptr) noexcept : handle_(ptr) {} +MDBX_CXX11_CONSTEXPR cursor::cursor(MDBX_cursor *ptr) noexcept : handle_(ptr) {} inline cursor &cursor::operator=(cursor &&other) noexcept { handle_ = other.handle_; @@ -4028,19 +4062,23 @@ inline cursor::~cursor() noexcept { #endif } -cxx14_constexpr cursor::operator bool() const noexcept { +MDBX_CXX14_CONSTEXPR cursor::operator bool() const noexcept { return handle_ != nullptr; } -cxx14_constexpr cursor::operator const MDBX_cursor *() const { return handle_; } +MDBX_CXX14_CONSTEXPR cursor::operator const MDBX_cursor *() const { + return handle_; +} -cxx14_constexpr cursor::operator MDBX_cursor *() { return handle_; } +MDBX_CXX14_CONSTEXPR cursor::operator MDBX_cursor *() { return handle_; } -cxx11_constexpr bool operator==(const cursor &a, const cursor &b) noexcept { +MDBX_CXX11_CONSTEXPR bool operator==(const cursor &a, + const cursor &b) noexcept { return a.handle_ == b.handle_; } -cxx11_constexpr bool operator!=(const cursor &a, const cursor &b) noexcept { +MDBX_CXX11_CONSTEXPR bool operator!=(const cursor &a, + const cursor &b) noexcept { return a.handle_ != b.handle_; } @@ -4078,13 +4116,13 @@ inline bool cursor::move(move_operation operation, MDBX_val *key, ::mdbx_cursor_get(handle_, key, value, MDBX_cursor_op(operation)); switch (err) { case MDBX_SUCCESS: - cxx20_attribute_likely return true; + MDBX_CXX20_LIKELY return true; case MDBX_NOTFOUND: if (!throw_notfound) return false; - cxx17_attribute_fallthrough /* fallthrough */; + MDBX_CXX17_FALLTHROUGH /* fallthrough */; default: - cxx20_attribute_unlikely error::throw_exception(err); + MDBX_CXX20_UNLIKELY error::throw_exception(err); } } @@ -4235,7 +4273,7 @@ inline txn cursor::txn() const { inline map_handle cursor::map() const { const MDBX_dbi dbi = ::mdbx_cursor_dbi(handle_); - if (mdbx_unlikely(dbi > MDBX_MAX_DBI)) + if (MDBX_UNLIKELY(dbi > MDBX_MAX_DBI)) error::throw_exception(MDBX_EINVAL); return map_handle(dbi); } @@ -4261,7 +4299,7 @@ inline value_result cursor::try_insert(const slice &key, slice value) { case MDBX_KEYEXIST: return value_result{value, false}; default: - cxx20_attribute_unlikely error::throw_exception(err); + MDBX_CXX20_UNLIKELY error::throw_exception(err); } } @@ -4285,7 +4323,7 @@ inline value_result cursor::try_insert_reserve(const slice &key, case MDBX_KEYEXIST: return value_result{result, false}; default: - cxx20_attribute_unlikely error::throw_exception(err); + MDBX_CXX20_UNLIKELY error::throw_exception(err); } } @@ -4315,7 +4353,7 @@ inline bool cursor::try_update(const slice &key, const slice &value) { case MDBX_NOTFOUND: return false; default: - cxx20_attribute_unlikely error::throw_exception(err); + MDBX_CXX20_UNLIKELY error::throw_exception(err); } } @@ -4337,7 +4375,7 @@ inline value_result cursor::try_update_reserve(const slice &key, case MDBX_NOTFOUND: return value_result{slice(), false}; default: - cxx20_attribute_unlikely error::throw_exception(err); + MDBX_CXX20_UNLIKELY error::throw_exception(err); } } @@ -4346,11 +4384,11 @@ inline bool cursor::erase(bool whole_multivalue) { : MDBX_CURRENT); switch (err) { case MDBX_SUCCESS: - cxx20_attribute_likely return true; + MDBX_CXX20_LIKELY return true; case MDBX_NOTFOUND: return false; default: - cxx20_attribute_unlikely error::throw_exception(err); + MDBX_CXX20_UNLIKELY error::throw_exception(err); } } @@ -4365,7 +4403,7 @@ template inline buffer::buffer(size_t head_room, size_t tail_room, const ALLOCATOR &allocator) : silo_(allocator) { - if (mdbx_unlikely(head_room > max_length || tail_room > max_length || + if (MDBX_UNLIKELY(head_room > max_length || tail_room > max_length || head_room + tail_room > max_length)) throw_max_length_exceeded(); silo_.reserve(head_room + tail_room); @@ -4386,7 +4424,7 @@ template inline buffer::buffer(size_t head_room, const ::mdbx::slice &src, size_t tail_room, const ALLOCATOR &allocator) : silo_(allocator) { - if (mdbx_unlikely(head_room > max_length || tail_room > max_length || + if (MDBX_UNLIKELY(head_room > max_length || tail_room > max_length || head_room + tail_room > max_length - slice_.length())) throw_max_length_exceeded(); silo_.reserve(head_room + src.length() + tail_room); @@ -4400,7 +4438,7 @@ template inline void buffer::reserve(size_t wanna_headroom, size_t wanna_tailroom, size_t shrink_threshold) { - if (mdbx_unlikely( + if (MDBX_UNLIKELY( wanna_headroom > max_length || wanna_tailroom > max_length || wanna_headroom + wanna_tailroom > max_length - slice_.length())) throw_max_length_exceeded(); @@ -4432,7 +4470,7 @@ inline void buffer::reserve(size_t wanna_headroom, template inline buffer &buffer::append(const void *src, size_t bytes) { - if (mdbx_unlikely(tailroom() < check_length(bytes))) + if (MDBX_UNLIKELY(tailroom() < check_length(bytes))) reserve(0, bytes); std::memcpy(static_cast(slice_.iov_base) + size(), src, bytes); slice_.iov_len += bytes; @@ -4442,7 +4480,7 @@ inline buffer &buffer::append(const void *src, template inline buffer &buffer::add_header(const void *src, size_t bytes) { - if (mdbx_unlikely(headroom() < check_length(bytes))) + if (MDBX_UNLIKELY(headroom() < check_length(bytes))) reserve(bytes, 0); slice_.iov_base = std::memcpy(static_cast(slice_.iov_base) - bytes, src, bytes); @@ -4473,7 +4511,7 @@ inline void buffer::swap(buffer &other) && !std::allocator_traits::is_always_equal::value #endif /* __cpp_lib_allocator_traits_is_always_equal */ ) { - if (mdbx_unlikely(silo_.get_allocator() != other.silo_.get_allocator())) + if (MDBX_UNLIKELY(silo_.get_allocator() != other.silo_.get_allocator())) throw std::bad_alloc(); } silo_.swap(other.silo_); diff --git a/src/core.c b/src/core.c index f91d2911..e7d178c3 100644 --- a/src/core.c +++ b/src/core.c @@ -40,7 +40,7 @@ /*------------------------------------------------------------------------------ * Internal inlines */ -__nothrow_const_function static unsigned log2n(size_t value) { +MDBX_NOTHROW_CONST_FUNCTION static unsigned log2n(size_t value) { assert(value > 0 && value < INT32_MAX && is_powerof2(value)); assert((value & -(int32_t)value) == value); #if __GNUC_PREREQ(4, 1) || __has_builtin(__builtin_ctzl) @@ -60,14 +60,14 @@ __nothrow_const_function static unsigned log2n(size_t value) { /*------------------------------------------------------------------------------ * Unaligned access */ -__nothrow_const_function static __maybe_unused __always_inline unsigned +MDBX_NOTHROW_CONST_FUNCTION static __maybe_unused __always_inline unsigned field_alignment(unsigned alignment_baseline, size_t field_offset) { unsigned merge = alignment_baseline | (unsigned)field_offset; return merge & -(int)merge; } /* read-thunk for UB-sanitizer */ -__nothrow_pure_function static __always_inline uint8_t +MDBX_NOTHROW_PURE_FUNCTION static __always_inline uint8_t peek_u8(const uint8_t *const __restrict ptr) { return *ptr; } @@ -78,7 +78,7 @@ static __always_inline void poke_u8(uint8_t *const __restrict ptr, *ptr = v; } -__nothrow_pure_function static __always_inline uint16_t +MDBX_NOTHROW_PURE_FUNCTION static __always_inline uint16_t unaligned_peek_u16(const unsigned expected_alignment, const void *const ptr) { assert((uintptr_t)ptr % expected_alignment == 0); if (MDBX_UNALIGNED_OK || (expected_alignment % sizeof(uint16_t)) == 0) @@ -100,7 +100,7 @@ unaligned_poke_u16(const unsigned expected_alignment, memcpy(ptr, &v, sizeof(v)); } -__nothrow_pure_function static __always_inline uint32_t unaligned_peek_u32( +MDBX_NOTHROW_PURE_FUNCTION static __always_inline uint32_t unaligned_peek_u32( const unsigned expected_alignment, const void *const __restrict ptr) { assert((uintptr_t)ptr % expected_alignment == 0); if (MDBX_UNALIGNED_OK || (expected_alignment % sizeof(uint32_t)) == 0) @@ -132,7 +132,7 @@ unaligned_poke_u32(const unsigned expected_alignment, memcpy(ptr, &v, sizeof(v)); } -__nothrow_pure_function static __always_inline uint64_t unaligned_peek_u64( +MDBX_NOTHROW_PURE_FUNCTION static __always_inline uint64_t unaligned_peek_u64( const unsigned expected_alignment, const void *const __restrict ptr) { assert((uintptr_t)ptr % expected_alignment == 0); if (MDBX_UNALIGNED_OK || (expected_alignment % sizeof(uint64_t)) == 0) @@ -185,7 +185,7 @@ unaligned_poke_u64(const unsigned expected_alignment, unaligned_poke_u64(1, (char *)(ptr) + offsetof(struct, field), value) /* Get the page number pointed to by a branch node */ -__nothrow_pure_function static __always_inline pgno_t +MDBX_NOTHROW_PURE_FUNCTION static __always_inline pgno_t node_pgno(const MDBX_node *const __restrict node) { pgno_t pgno = UNALIGNED_PEEK_32(node, MDBX_node, mn_pgno32); if (sizeof(pgno) > 4) @@ -205,7 +205,7 @@ static __always_inline void node_set_pgno(MDBX_node *const __restrict node, } /* Get the size of the data in a leaf node */ -__nothrow_pure_function static __always_inline size_t +MDBX_NOTHROW_PURE_FUNCTION static __always_inline size_t node_ds(const MDBX_node *const __restrict node) { return UNALIGNED_PEEK_32(node, MDBX_node, mn_dsize); } @@ -218,7 +218,7 @@ static __always_inline void node_set_ds(MDBX_node *const __restrict node, } /* The size of a key in a node */ -__nothrow_pure_function static __always_inline size_t +MDBX_NOTHROW_PURE_FUNCTION static __always_inline size_t node_ks(const MDBX_node *const __restrict node) { return UNALIGNED_PEEK_16(node, MDBX_node, mn_ksize); } @@ -230,7 +230,7 @@ static __always_inline void node_set_ks(MDBX_node *const __restrict node, UNALIGNED_POKE_16(node, MDBX_node, mn_ksize, (uint16_t)size); } -__nothrow_pure_function static __always_inline uint8_t +MDBX_NOTHROW_PURE_FUNCTION static __always_inline uint8_t node_flags(const MDBX_node *const __restrict node) { return UNALIGNED_PEEK_8(node, MDBX_node, mn_flags); } @@ -244,29 +244,29 @@ static __always_inline void node_set_flags(MDBX_node *const __restrict node, #define NODESIZE offsetof(MDBX_node, mn_data) /* Address of the key for the node */ -__nothrow_pure_function static __always_inline void * +MDBX_NOTHROW_PURE_FUNCTION static __always_inline void * node_key(const MDBX_node *const __restrict node) { return (char *)node + NODESIZE; } /* Address of the data for a node */ -__nothrow_pure_function static __always_inline void * +MDBX_NOTHROW_PURE_FUNCTION static __always_inline void * node_data(const MDBX_node *const __restrict node) { return (char *)node_key(node) + node_ks(node); } /* Size of a node in a leaf page with a given key and data. * This is node header plus key plus data size. */ -__nothrow_const_function static __always_inline size_t +MDBX_NOTHROW_CONST_FUNCTION static __always_inline size_t node_size_len(const size_t key_len, const size_t value_len) { return NODESIZE + EVEN(key_len + value_len); } -__nothrow_pure_function static __always_inline size_t +MDBX_NOTHROW_PURE_FUNCTION static __always_inline size_t node_size(const MDBX_val *key, const MDBX_val *value) { return node_size_len(key ? key->iov_len : 0, value ? value->iov_len : 0); } -__nothrow_pure_function static __always_inline pgno_t +MDBX_NOTHROW_PURE_FUNCTION static __always_inline pgno_t peek_pgno(const void *const __restrict ptr) { if (sizeof(pgno_t) == sizeof(uint32_t)) return (pgno_t)unaligned_peek_u32(1, ptr); @@ -289,7 +289,7 @@ static __always_inline void poke_pgno(void *const __restrict ptr, memcpy(ptr, &pgno, sizeof(pgno)); } -__nothrow_pure_function static __always_inline pgno_t +MDBX_NOTHROW_PURE_FUNCTION static __always_inline pgno_t node_largedata_pgno(const MDBX_node *const __restrict node) { assert(node_flags(node) & F_BIGDATA); return peek_pgno(node_data(node)); @@ -411,7 +411,7 @@ __cold intptr_t mdbx_limits_valsize_max(intptr_t pagesize, * size will only include the key and not the data. Sizes are always * rounded up to an even number of bytes, to guarantee 2-byte alignment * of the MDBX_node headers. */ -__nothrow_pure_function static __always_inline size_t +MDBX_NOTHROW_PURE_FUNCTION static __always_inline size_t leaf_size(const MDBX_env *env, const MDBX_val *key, const MDBX_val *data) { size_t node_bytes = node_size(key, data); /* NOTE: The actual limit is LEAF_NODEMAX(env->me_psize), but it reasonable to @@ -454,7 +454,7 @@ leaf_size(const MDBX_env *env, const MDBX_val *key, const MDBX_val *data) { * [in] key The key for the node. * * Returns The number of bytes needed to store the node. */ -__nothrow_pure_function static __always_inline size_t +MDBX_NOTHROW_PURE_FUNCTION static __always_inline size_t branch_size(const MDBX_env *env, const MDBX_val *key) { /* Size of a node in a branch page with a given key. * This is just the node header plus the key, there is no data. */ @@ -470,7 +470,7 @@ branch_size(const MDBX_env *env, const MDBX_val *key) { return node_bytes + sizeof(indx_t); } -__nothrow_const_function static __always_inline uint16_t +MDBX_NOTHROW_CONST_FUNCTION static __always_inline uint16_t flags_db2sub(uint16_t db_flags) { uint16_t sub_flags = db_flags & MDBX_DUPFIXED; @@ -491,84 +491,84 @@ flags_db2sub(uint16_t db_flags) { /*----------------------------------------------------------------------------*/ -__nothrow_pure_function static __always_inline size_t +MDBX_NOTHROW_PURE_FUNCTION static __always_inline size_t pgno2bytes(const MDBX_env *env, pgno_t pgno) { mdbx_assert(env, (1u << env->me_psize2log) == env->me_psize); return ((size_t)pgno) << env->me_psize2log; } -__nothrow_pure_function static __always_inline MDBX_page * +MDBX_NOTHROW_PURE_FUNCTION static __always_inline MDBX_page * pgno2page(const MDBX_env *env, pgno_t pgno) { return (MDBX_page *)(env->me_map + pgno2bytes(env, pgno)); } -__nothrow_pure_function static __always_inline pgno_t +MDBX_NOTHROW_PURE_FUNCTION static __always_inline pgno_t bytes2pgno(const MDBX_env *env, size_t bytes) { mdbx_assert(env, (env->me_psize >> env->me_psize2log) == 1); return (pgno_t)(bytes >> env->me_psize2log); } -__nothrow_pure_function static size_t pgno_align2os_bytes(const MDBX_env *env, - pgno_t pgno) { +MDBX_NOTHROW_PURE_FUNCTION static size_t +pgno_align2os_bytes(const MDBX_env *env, pgno_t pgno) { return ceil_powerof2(pgno2bytes(env, pgno), env->me_os_psize); } -__nothrow_pure_function static pgno_t pgno_align2os_pgno(const MDBX_env *env, - pgno_t pgno) { +MDBX_NOTHROW_PURE_FUNCTION static pgno_t pgno_align2os_pgno(const MDBX_env *env, + pgno_t pgno) { return bytes2pgno(env, pgno_align2os_bytes(env, pgno)); } -__nothrow_pure_function static size_t bytes_align2os_bytes(const MDBX_env *env, - size_t bytes) { +MDBX_NOTHROW_PURE_FUNCTION static size_t +bytes_align2os_bytes(const MDBX_env *env, size_t bytes) { return ceil_powerof2(ceil_powerof2(bytes, env->me_psize), env->me_os_psize); } /* Address of first usable data byte in a page, after the header */ -__nothrow_pure_function static __always_inline void * +MDBX_NOTHROW_PURE_FUNCTION static __always_inline void * page_data(const MDBX_page *mp) { return (char *)mp + PAGEHDRSZ; } -__nothrow_pure_function static __always_inline const MDBX_page * +MDBX_NOTHROW_PURE_FUNCTION static __always_inline const MDBX_page * data_page(const void *data) { return container_of(data, MDBX_page, mp_ptrs); } -__nothrow_pure_function static __always_inline MDBX_meta * +MDBX_NOTHROW_PURE_FUNCTION static __always_inline MDBX_meta * page_meta(MDBX_page *mp) { return (MDBX_meta *)page_data(mp); } /* Number of nodes on a page */ -__nothrow_pure_function static __always_inline unsigned +MDBX_NOTHROW_PURE_FUNCTION static __always_inline unsigned page_numkeys(const MDBX_page *mp) { return mp->mp_lower >> 1; } /* The amount of space remaining in the page */ -__nothrow_pure_function static __always_inline unsigned +MDBX_NOTHROW_PURE_FUNCTION static __always_inline unsigned page_room(const MDBX_page *mp) { return mp->mp_upper - mp->mp_lower; } -__nothrow_pure_function static __always_inline unsigned +MDBX_NOTHROW_PURE_FUNCTION static __always_inline unsigned page_space(const MDBX_env *env) { STATIC_ASSERT(PAGEHDRSZ % 2 == 0); return env->me_psize - PAGEHDRSZ; } -__nothrow_pure_function static __always_inline unsigned +MDBX_NOTHROW_PURE_FUNCTION static __always_inline unsigned page_used(const MDBX_env *env, const MDBX_page *mp) { return page_space(env) - page_room(mp); } /* The percentage of space used in the page, in a percents. */ -__nothrow_pure_function static __maybe_unused __inline double +MDBX_NOTHROW_PURE_FUNCTION static __maybe_unused __inline double page_fill(const MDBX_env *env, const MDBX_page *mp) { return page_used(env, mp) * 100.0 / page_space(env); } -__nothrow_pure_function static __inline bool +MDBX_NOTHROW_PURE_FUNCTION static __inline bool page_fill_enough(const MDBX_page *mp, unsigned spaceleft_threshold, unsigned minkeys_threshold) { return page_room(mp) < spaceleft_threshold && @@ -576,12 +576,12 @@ page_fill_enough(const MDBX_page *mp, unsigned spaceleft_threshold, } /* The number of overflow pages needed to store the given size. */ -__nothrow_pure_function static __always_inline pgno_t +MDBX_NOTHROW_PURE_FUNCTION static __always_inline pgno_t number_of_ovpages(const MDBX_env *env, size_t bytes) { return bytes2pgno(env, PAGEHDRSZ - 1 + bytes) + 1; } -__cold static int mdbx_printf_args(2, 3) +__cold static int MDBX_PRINTF_ARGS(2, 3) bad_page(const MDBX_page *mp, const char *fmt, ...) { if (mdbx_log_enabled(MDBX_LOG_ERROR)) { static const MDBX_page *prev; @@ -601,7 +601,7 @@ __cold static int mdbx_printf_args(2, 3) } /* Address of node i in page p */ -__nothrow_pure_function static __always_inline MDBX_node * +MDBX_NOTHROW_PURE_FUNCTION static __always_inline MDBX_node * page_node(const MDBX_page *mp, unsigned i) { assert((mp->mp_flags & (P_LEAF2 | P_OVERFLOW | P_META)) == 0); assert(page_numkeys(mp) > (unsigned)(i)); @@ -612,7 +612,7 @@ page_node(const MDBX_page *mp, unsigned i) { /* The address of a key in a LEAF2 page. * LEAF2 pages are used for MDBX_DUPFIXED sorted-duplicate sub-DBs. * There are no node headers, keys are stored contiguously. */ -__nothrow_pure_function static __always_inline void * +MDBX_NOTHROW_PURE_FUNCTION static __always_inline void * page_leaf2key(const MDBX_page *mp, unsigned i, size_t keysize) { assert((mp->mp_flags & (P_BRANCH | P_LEAF | P_LEAF2 | P_OVERFLOW | P_META)) == (P_LEAF | P_LEAF2)); @@ -1383,7 +1383,7 @@ static __inline void lcklist_unlock(void) { #endif } -__nothrow_const_function static uint64_t rrxmrrxmsx_0(uint64_t v) { +MDBX_NOTHROW_CONST_FUNCTION static uint64_t rrxmrrxmsx_0(uint64_t v) { /* Pelle Evensen's mixer, https://bit.ly/2HOfynt */ v ^= (v << 39 | v >> 25) ^ (v << 14 | v >> 50); v *= UINT64_C(0xA24BAED4963EE407); diff --git a/src/defs.h b/src/defs.h index 18038339..3f61e6f7 100644 --- a/src/defs.h +++ b/src/defs.h @@ -151,18 +151,6 @@ # endif #endif /* __prefetch */ -#ifndef __noreturn -# ifdef _Noreturn -# define __noreturn _Noreturn -# elif defined(__GNUC__) || __has_attribute(__noreturn__) -# define __noreturn __attribute__((__noreturn__)) -# elif defined(_MSC_VER) -# define __noreturn __declspec(noreturn) -# else -# define __noreturn -# endif -#endif /* __noreturn */ - #ifndef __nothrow # if defined(__cplusplus) # if __cplusplus < 201703L @@ -268,7 +256,7 @@ #endif /* __anonymous_struct_extension__ */ #ifndef __Wpedantic_format_voidptr - static __inline __maybe_unused const void* __pure_function + static __inline __maybe_unused const void* MDBX_PURE_FUNCTION __Wpedantic_format_voidptr(const void* ptr) {return ptr;} # define __Wpedantic_format_voidptr(ARG) __Wpedantic_format_voidptr(ARG) #endif /* __Wpedantic_format_voidptr */ diff --git a/src/internals.h b/src/internals.h index e45902d5..e22c52f8 100644 --- a/src/internals.h +++ b/src/internals.h @@ -1038,9 +1038,9 @@ extern uint8_t mdbx_runtime_flags; extern uint8_t mdbx_loglevel; extern MDBX_debug_func *mdbx_debug_logger; -MDBX_INTERNAL_FUNC void mdbx_printf_args(4, 5) +MDBX_INTERNAL_FUNC void MDBX_PRINTF_ARGS(4, 5) mdbx_debug_log(int level, const char *function, int line, const char *fmt, - ...) mdbx_printf_args(4, 5); + ...) MDBX_PRINTF_ARGS(4, 5); MDBX_INTERNAL_FUNC void mdbx_debug_log_va(int level, const char *function, int line, const char *fmt, va_list args); @@ -1360,30 +1360,30 @@ typedef struct MDBX_node { /* Do not spill pages to disk if txn is getting full, may fail instead */ #define MDBX_NOSPILL 0x8000 -__nothrow_const_function static __maybe_unused __inline pgno_t +MDBX_NOTHROW_CONST_FUNCTION static __maybe_unused __inline pgno_t pgno_add(pgno_t base, pgno_t augend) { assert(base <= MAX_PAGENO); return (augend < MAX_PAGENO - base) ? base + augend : MAX_PAGENO; } -__nothrow_const_function static __maybe_unused __inline pgno_t +MDBX_NOTHROW_CONST_FUNCTION static __maybe_unused __inline pgno_t pgno_sub(pgno_t base, pgno_t subtrahend) { assert(base >= MIN_PAGENO); return (subtrahend < base - MIN_PAGENO) ? base - subtrahend : MIN_PAGENO; } -__nothrow_const_function static __always_inline __maybe_unused bool +MDBX_NOTHROW_CONST_FUNCTION static __always_inline __maybe_unused bool is_powerof2(size_t x) { return (x & (x - 1)) == 0; } -__nothrow_const_function static __always_inline __maybe_unused size_t +MDBX_NOTHROW_CONST_FUNCTION static __always_inline __maybe_unused size_t floor_powerof2(size_t value, size_t granularity) { assert(is_powerof2(granularity)); return value & ~(granularity - 1); } -__nothrow_const_function static __always_inline __maybe_unused size_t +MDBX_NOTHROW_CONST_FUNCTION static __always_inline __maybe_unused size_t ceil_powerof2(size_t value, size_t granularity) { return floor_powerof2(value + granularity - 1, granularity); } diff --git a/src/mdbx.c++ b/src/mdbx.c++ index dd698d16..28401c6c 100644 --- a/src/mdbx.c++ +++ b/src/mdbx.c++ @@ -28,14 +28,6 @@ #include // for isxdigit(), etc #include -#if defined(__has_include) && __has_include() -#include -#endif - -#if defined(__cpp_lib_filesystem) && __cpp_lib_filesystem >= 201703L -#include -#endif /* __cpp_lib_filesystem >= 201703L */ - namespace { #if 0 /* Unused for now */ @@ -72,7 +64,7 @@ class trouble_location { #endif public: - cxx11_constexpr trouble_location(unsigned line, const char *condition, + MDBX_CXX11_CONSTEXPR trouble_location(unsigned line, const char *condition, const char *function, const char *filename) : #if TROUBLE_PROVIDE_LINENO @@ -198,14 +190,14 @@ __cold bug::~bug() noexcept {} #define RAISE_BUG(line, condition, function, file) \ do { \ - static cxx11_constexpr_var trouble_location bug(line, condition, function, \ - file); \ + static MDBX_CXX11_CONSTEXPR_VAR trouble_location bug(line, condition, \ + function, file); \ raise_bug(bug); \ } while (0) #define ENSURE(condition) \ do \ - if (mdbx_unlikely(!(condition))) \ + if (MDBX_UNLIKELY(!(condition))) \ RAISE_BUG(__LINE__, #condition, __func__, __FILE__); \ while (0) @@ -488,9 +480,9 @@ bool slice::is_printable(bool disable_utf8) const noexcept { auto src = byte_ptr(); const auto end = src + length(); - if (mdbx_unlikely(disable_utf8)) { + if (MDBX_UNLIKELY(disable_utf8)) { do - if (mdbx_unlikely((P_ & map[*src]) == 0)) + if (MDBX_UNLIKELY((P_ & map[*src]) == 0)) return false; while (++src < end); return true; @@ -543,7 +535,7 @@ bool slice::is_printable(bool disable_utf8) const noexcept { char *slice::to_hex(char *__restrict dest, size_t dest_size, bool uppercase, unsigned wrap_width) const { - if (mdbx_unlikely(to_hex_bytes(wrap_width) > dest_size)) + if (MDBX_UNLIKELY(to_hex_bytes(wrap_width) > dest_size)) throw_too_small_target_buffer(); auto src = byte_ptr(); @@ -565,22 +557,22 @@ char *slice::to_hex(char *__restrict dest, size_t dest_size, bool uppercase, byte *slice::from_hex(byte *__restrict dest, size_t dest_size, bool ignore_spaces) const { - if (mdbx_unlikely(length() % 2 && !ignore_spaces)) + if (MDBX_UNLIKELY(length() % 2 && !ignore_spaces)) throw std::domain_error( "mdbx::from_hex:: odd length of hexadecimal string"); - if (mdbx_unlikely(from_hex_bytes() > dest_size)) + if (MDBX_UNLIKELY(from_hex_bytes() > dest_size)) throw_too_small_target_buffer(); auto src = byte_ptr(); for (auto left = length(); left > 0;) { - if (mdbx_unlikely(*src <= ' ') && - mdbx_likely(ignore_spaces && isspace(*src))) { + if (MDBX_UNLIKELY(*src <= ' ') && + MDBX_LIKELY(ignore_spaces && isspace(*src))) { ++src; --left; continue; } - if (mdbx_unlikely(left < 1 || !isxdigit(src[0]) || !isxdigit(src[1]))) + if (MDBX_UNLIKELY(left < 1 || !isxdigit(src[0]) || !isxdigit(src[1]))) throw std::domain_error("mdbx::from_hex:: invalid hexadecimal string"); int8_t hi = src[0]; @@ -599,20 +591,20 @@ byte *slice::from_hex(byte *__restrict dest, size_t dest_size, } bool slice::is_hex(bool ignore_spaces) const noexcept { - if (mdbx_unlikely(length() % 2 && !ignore_spaces)) + if (MDBX_UNLIKELY(length() % 2 && !ignore_spaces)) return false; bool got = false; auto src = byte_ptr(); for (auto left = length(); left > 0;) { - if (mdbx_unlikely(*src <= ' ') && - mdbx_likely(ignore_spaces && isspace(*src))) { + if (MDBX_UNLIKELY(*src <= ' ') && + MDBX_LIKELY(ignore_spaces && isspace(*src))) { ++src; --left; continue; } - if (mdbx_unlikely(left < 1 || !isxdigit(src[0]) || !isxdigit(src[1]))) + if (MDBX_UNLIKELY(left < 1 || !isxdigit(src[0]) || !isxdigit(src[1]))) return false; got = true; @@ -669,13 +661,13 @@ static inline char b58_8to11(uint64_t &v) noexcept { char *slice::to_base58(char *__restrict dest, size_t dest_size, unsigned wrap_width) const { - if (mdbx_unlikely(to_base58_bytes(wrap_width) > dest_size)) + if (MDBX_UNLIKELY(to_base58_bytes(wrap_width) > dest_size)) throw_too_small_target_buffer(); auto src = byte_ptr(); size_t left = length(); auto line = dest; - while (mdbx_likely(left > 7)) { + while (MDBX_LIKELY(left > 7)) { left -= 8; uint64_t v; std::memcpy(&v, src, 8); @@ -752,20 +744,20 @@ static inline signed char b58_11to8(uint64_t &v, const byte c) noexcept { byte *slice::from_base58(byte *__restrict dest, size_t dest_size, bool ignore_spaces) const { - if (mdbx_unlikely(from_base58_bytes() > dest_size)) + if (MDBX_UNLIKELY(from_base58_bytes() > dest_size)) throw_too_small_target_buffer(); auto src = byte_ptr(); for (auto left = length(); left > 0;) { - if (mdbx_unlikely(isspace(*src)) && ignore_spaces) { + if (MDBX_UNLIKELY(isspace(*src)) && ignore_spaces) { ++src; --left; continue; } - if (mdbx_likely(left > 10)) { + if (MDBX_LIKELY(left > 10)) { uint64_t v = 0; - if (mdbx_unlikely((b58_11to8(v, src[0]) | b58_11to8(v, src[1]) | + if (MDBX_UNLIKELY((b58_11to8(v, src[0]) | b58_11to8(v, src[1]) | b58_11to8(v, src[2]) | b58_11to8(v, src[3]) | b58_11to8(v, src[4]) | b58_11to8(v, src[5]) | b58_11to8(v, src[6]) | b58_11to8(v, src[7]) | @@ -792,7 +784,7 @@ byte *slice::from_base58(byte *__restrict dest, size_t dest_size, uint64_t v = 1; unsigned parrots = 0; do { - if (mdbx_unlikely(b58_11to8(v, *src++) < 0)) + if (MDBX_UNLIKELY(b58_11to8(v, *src++) < 0)) goto bailout; parrots += 32; } while (--left); @@ -814,15 +806,15 @@ bool slice::is_base58(bool ignore_spaces) const noexcept { bool got = false; auto src = byte_ptr(); for (auto left = length(); left > 0;) { - if (mdbx_unlikely(*src <= ' ') && - mdbx_likely(ignore_spaces && isspace(*src))) { + if (MDBX_UNLIKELY(*src <= ' ') && + MDBX_LIKELY(ignore_spaces && isspace(*src))) { ++src; --left; continue; } - if (mdbx_likely(left > 10)) { - if (mdbx_unlikely((b58_map[src[0]] | b58_map[src[1]] | b58_map[src[2]] | + if (MDBX_LIKELY(left > 10)) { + if (MDBX_UNLIKELY((b58_map[src[0]] | b58_map[src[1]] | b58_map[src[2]] | b58_map[src[3]] | b58_map[src[4]] | b58_map[src[5]] | b58_map[src[6]] | b58_map[src[7]] | b58_map[src[8]] | b58_map[src[9]] | b58_map[src[10]]) < 0)) @@ -838,7 +830,7 @@ bool slice::is_base58(bool ignore_spaces) const noexcept { return false; do - if (mdbx_unlikely(b58_map[*src++] < 0)) + if (MDBX_UNLIKELY(b58_map[*src++] < 0)) return false; while (--left); got = true; @@ -865,7 +857,7 @@ static inline void b64_3to4(const byte x, const byte y, const byte z, char *slice::to_base64(char *__restrict dest, size_t dest_size, unsigned wrap_width) const { - if (mdbx_unlikely(to_base64_bytes(wrap_width) > dest_size)) + if (MDBX_UNLIKELY(to_base64_bytes(wrap_width) > dest_size)) throw_too_small_target_buffer(); auto src = byte_ptr(); @@ -874,7 +866,7 @@ char *slice::to_base64(char *__restrict dest, size_t dest_size, while (true) { switch (left) { default: - cxx20_attribute_likely left -= 3; + MDBX_CXX20_LIKELY left -= 3; b64_3to4(src[0], src[1], src[2], dest); dest += 4; src += 3; @@ -928,27 +920,27 @@ static inline signed char b64_4to3(signed char a, signed char b, signed char c, byte *slice::from_base64(byte *__restrict dest, size_t dest_size, bool ignore_spaces) const { - if (mdbx_unlikely(length() % 4 && !ignore_spaces)) + if (MDBX_UNLIKELY(length() % 4 && !ignore_spaces)) throw std::domain_error("mdbx::from_base64:: odd length of base64 string"); - if (mdbx_unlikely(from_base64_bytes() > dest_size)) + if (MDBX_UNLIKELY(from_base64_bytes() > dest_size)) throw_too_small_target_buffer(); auto src = byte_ptr(); for (auto left = length(); left > 0;) { - if (mdbx_unlikely(*src <= ' ') && - mdbx_likely(ignore_spaces && isspace(*src))) { + if (MDBX_UNLIKELY(*src <= ' ') && + MDBX_LIKELY(ignore_spaces && isspace(*src))) { ++src; --left; continue; } - if (mdbx_unlikely(left < 3)) { + if (MDBX_UNLIKELY(left < 3)) { bailout: throw std::domain_error("mdbx::from_base64:: invalid base64 string"); } const signed char a = b64_map[src[0]], b = b64_map[src[1]], c = b64_map[src[2]], d = b64_map[src[3]]; - if (mdbx_unlikely(b64_4to3(a, b, c, d, dest) < 0)) { + if (MDBX_UNLIKELY(b64_4to3(a, b, c, d, dest) < 0)) { if (left == 4 && (a | b) >= 0 && d == EQ) { if (c >= 0) return dest + 2; @@ -964,24 +956,24 @@ byte *slice::from_base64(byte *__restrict dest, size_t dest_size, } bool slice::is_base64(bool ignore_spaces) const noexcept { - if (mdbx_unlikely(length() % 4 && !ignore_spaces)) + if (MDBX_UNLIKELY(length() % 4 && !ignore_spaces)) return false; bool got = false; auto src = byte_ptr(); for (auto left = length(); left > 0;) { - if (mdbx_unlikely(*src <= ' ') && - mdbx_likely(ignore_spaces && isspace(*src))) { + if (MDBX_UNLIKELY(*src <= ' ') && + MDBX_LIKELY(ignore_spaces && isspace(*src))) { ++src; --left; continue; } - if (mdbx_unlikely(left < 3)) + if (MDBX_UNLIKELY(left < 3)) return false; const signed char a = b64_map[src[0]], b = b64_map[src[1]], c = b64_map[src[2]], d = b64_map[src[3]]; - if (mdbx_unlikely((a | b | c | d) < 0)) { + if (MDBX_UNLIKELY((a | b | c | d) < 0)) { if (left == 4 && (a | b) >= 0 && d == EQ && (c >= 0 || c == d)) return true; return false; @@ -1008,7 +1000,7 @@ size_t env::default_pagesize() noexcept { return ::mdbx_syspagesize(); } static inline MDBX_env_flags_t mode2flags(env::mode mode) { switch (mode) { default: - cxx20_attribute_unlikely throw std::invalid_argument("db::mode is invalid"); + MDBX_CXX20_UNLIKELY throw std::invalid_argument("db::mode is invalid"); case env::mode::readonly: return MDBX_RDONLY; case env::mode::write_file_io: @@ -1043,7 +1035,7 @@ env::operate_parameters::make_flags(bool accede, bool use_subdirectory) const { flags |= MDBX_LIFORECLAIM; switch (durability) { default: - cxx20_attribute_unlikely throw std::invalid_argument( + MDBX_CXX20_UNLIKELY throw std::invalid_argument( "db::durability is invalid"); case env::durability::robust_synchronous: break; @@ -1221,7 +1213,7 @@ txn_managed::~txn_managed() noexcept { void txn_managed::abort() { const error err = static_cast(::mdbx_txn_abort(handle_)); - if (mdbx_unlikely(err.code() != MDBX_SUCCESS)) { + if (MDBX_UNLIKELY(err.code() != MDBX_SUCCESS)) { if (err.code() != MDBX_THREAD_MISMATCH) handle_ = nullptr; err.throw_exception(); @@ -1230,7 +1222,7 @@ void txn_managed::abort() { void txn_managed::commit() { const error err = static_cast(::mdbx_txn_commit(handle_)); - if (mdbx_unlikely(err.code() != MDBX_SUCCESS)) { + if (MDBX_UNLIKELY(err.code() != MDBX_SUCCESS)) { if (err.code() != MDBX_THREAD_MISMATCH) handle_ = nullptr; err.throw_exception(); @@ -1250,9 +1242,9 @@ bool txn::drop_map(const char *name, bool throw_if_absent) { case MDBX_BAD_DBI: if (!throw_if_absent) return false; - cxx17_attribute_fallthrough /* fallthrough */; + MDBX_CXX17_FALLTHROUGH /* fallthrough */; default: - cxx20_attribute_unlikely error::throw_exception(err); + MDBX_CXX20_UNLIKELY error::throw_exception(err); } } @@ -1267,17 +1259,17 @@ bool txn::clear_map(const char *name, bool throw_if_absent) { case MDBX_BAD_DBI: if (!throw_if_absent) return false; - cxx17_attribute_fallthrough /* fallthrough */; + MDBX_CXX17_FALLTHROUGH /* fallthrough */; default: - cxx20_attribute_unlikely error::throw_exception(err); + MDBX_CXX20_UNLIKELY error::throw_exception(err); } } //------------------------------------------------------------------------------ void cursor_managed::close() { - if (mdbx_unlikely(!handle_)) - cxx20_attribute_unlikely error::throw_exception(MDBX_EINVAL); + if (MDBX_UNLIKELY(!handle_)) + MDBX_CXX20_UNLIKELY error::throw_exception(MDBX_EINVAL); ::mdbx_cursor_close(handle_); handle_ = nullptr; } diff --git a/src/mdbx_chk.c b/src/mdbx_chk.c index 67863307..53ce0afb 100644 --- a/src/mdbx_chk.c +++ b/src/mdbx_chk.c @@ -106,7 +106,7 @@ struct problem { struct problem *problems_list; uint64_t total_problems; -static void mdbx_printf_args(1, 2) print(const char *msg, ...) { +static void MDBX_PRINTF_ARGS(1, 2) print(const char *msg, ...) { if (!quiet) { va_list args; @@ -145,7 +145,7 @@ static void va_log(MDBX_log_level_t level, const char *msg, va_list args) { } } -static void mdbx_printf_args(1, 2) error(const char *msg, ...) { +static void MDBX_PRINTF_ARGS(1, 2) error(const char *msg, ...) { va_list args; va_start(args, msg); va_log(MDBX_LOG_ERROR, msg, args); @@ -216,7 +216,7 @@ static walk_dbi_t *pagemap_lookup_dbi(const char *dbi_name, bool silent) { return last = dbi; } -static void mdbx_printf_args(4, 5) +static void MDBX_PRINTF_ARGS(4, 5) problem_add(const char *object, uint64_t entry_number, const char *msg, const char *extra, ...) { diff --git a/src/osal.c b/src/osal.c index 0d302c32..55fd109a 100644 --- a/src/osal.c +++ b/src/osal.c @@ -145,7 +145,7 @@ __extern_C void __assert_fail(const char *assertion, const char *file, #else __nothrow #endif /* __THROW */ - __noreturn; + MDBX_NORETURN; #elif defined(__APPLE__) || defined(__MACH__) __extern_C void __assert_rtn(const char *function, const char *file, int line, @@ -153,7 +153,7 @@ __extern_C void __assert_rtn(const char *function, const char *file, int line, #ifdef __dead2 __dead2 #else - __noreturn + MDBX_NORETURN #endif /* __dead2 */ #ifdef __disable_tail_calls __disable_tail_calls @@ -164,7 +164,7 @@ __extern_C void __assert_rtn(const char *function, const char *file, int line, __assert_rtn(function, file, line, assertion) #elif defined(__sun) || defined(__SVR4) || defined(__svr4__) __extern_C void __assert_c99(const char *assection, const char *file, int line, - const char *function) __noreturn; + const char *function) MDBX_NORETURN; #define __assert_fail(assertion, file, line, function) \ __assert_c99(assertion, file, line, function) #elif defined(__OpenBSD__) @@ -186,7 +186,7 @@ __extern_C void __assert(const char *function, const char *file, int line, #ifdef __dead2 __dead2 #else - __noreturn + MDBX_NORETURN #endif /* __dead2 */ #ifdef __disable_tail_calls __disable_tail_calls diff --git a/src/osal.h b/src/osal.h index 9c2e476b..c26ff04f 100644 --- a/src/osal.h +++ b/src/osal.h @@ -412,7 +412,7 @@ typedef pthread_mutex_t mdbx_fastmutex_t; /* Get the size of a memory page for the system. * This is the basic size that the platform's memory manager uses, and is * fundamental to the use of memory-mapped files. */ -__nothrow_const_function static __maybe_unused __inline size_t +MDBX_NOTHROW_CONST_FUNCTION static __maybe_unused __inline size_t mdbx_syspagesize(void) { #if defined(_WIN32) || defined(_WIN64) SYSTEM_INFO si; @@ -536,7 +536,7 @@ static __maybe_unused __inline void mdbx_memory_barrier(void) { #define mdbx_asprintf asprintf #define mdbx_vasprintf vasprintf #else -MDBX_INTERNAL_FUNC mdbx_printf_args(2, 3) int __maybe_unused +MDBX_INTERNAL_FUNC MDBX_PRINTF_ARGS(2, 3) int __maybe_unused mdbx_asprintf(char **strp, const char *fmt, ...); MDBX_INTERNAL_FUNC int mdbx_vasprintf(char **strp, const char *fmt, va_list ap); #endif diff --git a/test/keygen.cc b/test/keygen.cc index b60f8164..2e8641b7 100644 --- a/test/keygen.cc +++ b/test/keygen.cc @@ -16,7 +16,7 @@ namespace keygen { -static inline __pure_function serial_t mask(unsigned bits) { +static inline MDBX_PURE_FUNCTION serial_t mask(unsigned bits) { assert(bits > 0 && bits <= serial_maxwith); return serial_allones >> (serial_maxwith - bits); } diff --git a/test/log.cc b/test/log.cc index 2d617e42..71e017f4 100644 --- a/test/log.cc +++ b/test/log.cc @@ -31,7 +31,7 @@ const char *test_strerror(int errnum) { return mdbx_strerror_r(errnum, buf, sizeof(buf)); } -__noreturn void failure_perror(const char *what, int errnum) { +MDBX_NORETURN void failure_perror(const char *what, int errnum) { failure("%s failed: %s (%d)\n", what, test_strerror(errnum), errnum); } @@ -39,7 +39,7 @@ __noreturn void failure_perror(const char *what, int errnum) { static void mdbx_logger(MDBX_log_level_t priority, const char *function, int line, const char *msg, - va_list args) cxx17_noexcept { + va_list args) MDBX_CXX17_NOEXCEPT { if (!function) function = "unknown"; diff --git a/test/log.h b/test/log.h index 9fe174fa..ca93196b 100644 --- a/test/log.h +++ b/test/log.h @@ -17,9 +17,9 @@ #include "base.h" #include "chrono.h" -__noreturn void usage(void); -__noreturn void mdbx_printf_args(1, 2) failure(const char *fmt, ...); -__noreturn void failure_perror(const char *what, int errnum); +MDBX_NORETURN void usage(void); +MDBX_NORETURN void MDBX_PRINTF_ARGS(1, 2) failure(const char *fmt, ...); +MDBX_NORETURN void failure_perror(const char *what, int errnum); const char *test_strerror(int errnum); namespace logging { @@ -51,12 +51,12 @@ void setlevel(loglevel priority); void output_nocheckloglevel_ap(const loglevel priority, const char *format, va_list ap); -bool mdbx_printf_args(2, 3) +bool MDBX_PRINTF_ARGS(2, 3) output(const loglevel priority, const char *format, ...); bool feed_ap(const char *format, va_list ap); -bool mdbx_printf_args(1, 2) feed(const char *format, ...); +bool MDBX_PRINTF_ARGS(1, 2) feed(const char *format, ...); -void inline mdbx_printf_args(2, 3) +void inline MDBX_PRINTF_ARGS(2, 3) output_nocheckloglevel(const loglevel priority, const char *format, ...) { va_list ap; va_start(ap, format); @@ -85,13 +85,13 @@ public: } // namespace logging -void mdbx_printf_args(1, 2) log_extra(const char *msg, ...); -void mdbx_printf_args(1, 2) log_trace(const char *msg, ...); -void mdbx_printf_args(1, 2) log_debug(const char *msg, ...); -void mdbx_printf_args(1, 2) log_verbose(const char *msg, ...); -void mdbx_printf_args(1, 2) log_notice(const char *msg, ...); -void mdbx_printf_args(1, 2) log_warning(const char *msg, ...); -void mdbx_printf_args(1, 2) log_error(const char *msg, ...); +void MDBX_PRINTF_ARGS(1, 2) log_extra(const char *msg, ...); +void MDBX_PRINTF_ARGS(1, 2) log_trace(const char *msg, ...); +void MDBX_PRINTF_ARGS(1, 2) log_debug(const char *msg, ...); +void MDBX_PRINTF_ARGS(1, 2) log_verbose(const char *msg, ...); +void MDBX_PRINTF_ARGS(1, 2) log_notice(const char *msg, ...); +void MDBX_PRINTF_ARGS(1, 2) log_warning(const char *msg, ...); +void MDBX_PRINTF_ARGS(1, 2) log_error(const char *msg, ...); void log_trouble(const char *where, const char *what, int errnum); void log_flush(void); diff --git a/test/main.cc b/test/main.cc index cf3c263d..edd64a3e 100644 --- a/test/main.cc +++ b/test/main.cc @@ -19,7 +19,7 @@ #include #endif /* !Windows */ -__noreturn void usage(void) { +MDBX_NORETURN void usage(void) { puts( "usage:\n" " --help or -h Show this text\n" diff --git a/test/test.cc b/test/test.cc index 9ca18357..98715037 100644 --- a/test/test.cc +++ b/test/test.cc @@ -80,7 +80,7 @@ const char *keygencase2str(const keygen_case keycase) { int testcase::oom_callback(MDBX_env *env, mdbx_pid_t pid, mdbx_tid_t tid, uint64_t txn, unsigned gap, size_t space, - int retry) cxx17_noexcept { + int retry) MDBX_CXX17_NOEXCEPT { testcase *self = (testcase *)mdbx_env_get_userctx(env); diff --git a/test/test.h b/test/test.h index 60766940..4515e703 100644 --- a/test/test.h +++ b/test/test.h @@ -168,7 +168,7 @@ protected: static int oom_callback(MDBX_env *env, mdbx_pid_t pid, mdbx_tid_t tid, uint64_t txn, unsigned gap, size_t space, - int retry) cxx17_noexcept; + int retry) MDBX_CXX17_NOEXCEPT; MDBX_env_flags_t actual_env_mode{MDBX_ENV_DEFAULTS}; bool is_nested_txn_available() const {