diff --git a/include/libimp/detect_plat.h b/include/libimp/detect_plat.h index 12e2e7e..2a68009 100644 --- a/include/libimp/detect_plat.h +++ b/include/libimp/detect_plat.h @@ -44,6 +44,9 @@ # define LIBIMP_CC_MSVC_2019 1920 #elif defined(__GNUC__) # define LIBIMP_CC_GNUC __GNUC__ +# if defined(__clang__) +# define LIBIMP_CC_CLANG +#endif #else # error "This compiler is unsupported." #endif @@ -103,6 +106,7 @@ #endif /// \brief C++ attributes. +/// \see https://en.cppreference.com/w/cpp/language/attributes #if defined(__has_cpp_attribute) # if __has_cpp_attribute(fallthrough) @@ -120,6 +124,9 @@ # if __has_cpp_attribute(nodiscard) # define LIBIMP_NODISCARD [[nodiscard]] # endif +# if __has_cpp_attribute(assume) +# define LIBIMP_ASSUME(...) [[assume(__VA_ARGS__)]] +# endif #endif #if !defined(LIBIMP_FALLTHROUGH) @@ -175,6 +182,21 @@ # endif #endif +#if !defined(LIBIMP_ASSUME) +# if defined(LIBIMP_CC_CLANG) && __has_builtin(__builtin_assume) +/// \see https://clang.llvm.org/docs/LanguageExtensions.html#langext-builtin-assume +# define LIBIMP_ASSUME(...) __builtin_assume(__VA_ARGS__) +# elif defined(LIBIMP_CC_GNUC) && __has_builtin(__builtin_unreachable) +/// \see https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#index-_005f_005fbuiltin_005funreachable +# define LIBIMP_ASSUME(...) do { if (!(__VA_ARGS__)) __builtin_unreachable(); } while (false) +# elif defined(LIBIMP_CC_MSVC) +/// \see https://learn.microsoft.com/en-us/cpp/intrinsics/assume?view=msvc-140 +# define LIBIMP_ASSUME(...) __assume(__VA_ARGS__) +# else +# define LIBIMP_ASSUME(...) +# endif +#endif + /// \see https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_exceptions.html /// https://learn.microsoft.com/en-us/cpp/preprocessor/predefined-macros /// https://stackoverflow.com/questions/6487013/programmatically-determine-whether-exceptions-are-enabled