From b47beec02f403a4cb633e629da004455eb73412f Mon Sep 17 00:00:00 2001 From: ian Date: Wed, 1 May 2024 17:46:26 -0400 Subject: [PATCH 01/25] Add common Clion generated files to gitignore --- .gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 0a1c458a..18f8df60 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,10 @@ .vs .vscode .cache +.idea scratch build* +cmake-build-* __pycache__ compile_commands.json -CMakeUserPresets.json +CMakeUserPresets.json \ No newline at end of file From 3741c713d01e32d398c04fba355959b4074cb13b Mon Sep 17 00:00:00 2001 From: ian Date: Wed, 1 May 2024 18:44:14 -0400 Subject: [PATCH 02/25] Tell MSVC to report the correct value of __cplusplus instead of 199711L --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1a18fc9e..03a1fb77 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -87,6 +87,7 @@ target_sources( ${target_name} PRIVATE # include include/libassert/assert.hpp + include/libassert/libassert_internal.hpp ) # add /src files to target @@ -115,7 +116,7 @@ target_compile_options( PRIVATE $<$>:-Wall -Wextra -Werror=return-type -Wshadow -Wundef> $<$:-Wuseless-cast -Wnonnull-compare> - $<$:/W4 /WX /permissive-> + $<$:/W4 /WX /permissive- /Zc:__cplusplus> ) # ---- Generate Build Info Headers ---- From 6a313090cc317c68c58af50fff265b491ffed12f Mon Sep 17 00:00:00 2001 From: ian Date: Wed, 1 May 2024 19:17:05 -0400 Subject: [PATCH 03/25] Changed my mind on forcing msvc to properly report. --- include/libassert/libassert_internal.hpp | 131 +++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 include/libassert/libassert_internal.hpp diff --git a/include/libassert/libassert_internal.hpp b/include/libassert/libassert_internal.hpp new file mode 100644 index 00000000..e1460f8e --- /dev/null +++ b/include/libassert/libassert_internal.hpp @@ -0,0 +1,131 @@ +#ifndef LIBASSERT_INTERNAL_HPP +#define LIBASSERT_INTERNAL_HPP + +// Copyright (c) 2021-2024 Jeremy Rifkin under the MIT license +// https://github.com/jeremy-rifkin/libassert + + +#if defined(_MSVC_LANG) && _MSVC_LANG < 201703L + #error "libassert requires C++17 or newer" +#elif !defined(_MSVC_LANG) && __cplusplus < 201703L + #pragma error "libassert requires C++17 or newer" +#endif + +// LIBASSERT_CPP_VER +// +// Macro that checks we have available the macro __cplusplus and assigns its value to LIBASSERT_CPP_VER +#ifndef LIBASSERT_CPLUSPLUS + #if defined(__cplusplus) + #define LIBASSERT_CPLUSPLUS __cplusplus + #else + #error "Libassert requires that __cplusplus is defined!" + #endif // __cplusplus +#endif // LIBASSERT_CPP_VER + + +// LIBASSERT_STRINGIFY +// +// Example usage: +// printf("Line: %s", LIBASSERT_STRINGIFY(__LINE__)); +// +#ifndef LIBASSERT_STRINGIFY + #define LIBASSERT_STRINGIFY(x) LIBASSERT_STRINGIFYIMPL(x) + #define LIBASSERT_STRINGIFYIMPL(x) #x +#endif + + + +#ifndef LIBASSERT_STD_VER + #if LIBASSERT_CPLUSPLUS <= 201703L + #define LIBASSERT_STD_VER 17 + #elif LIBASSERT_CPLUSPLUS <= 202002L + #define LIBASSERT_STD_VER 20 + #elif LIBASSERT_CPLUSPLUS <= 202302L + #define LIBASSERT_STD_VER 23 + #else + // TODO: Once C++26 is fully released we should update this to instead check for its defined value. + // Currently, at this time there is no reliable manner to truely know what the version number for C++26 is. + #define LIBASSERT_STD_VER 26 // If our version number is higher than 202303L assume we are using C++26 + #endif // LIBASSERT_CPLUSPLUS +#endif // LIBASSERT_STD_VER + +// Detect compiler versions. +#if defined(__clang__) && !defined(__ibmxl__) + #define LIBASSERT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__) +#else + #define LIBASSERT_CLANG_VERSION 0 +#endif + +#if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER) +#define LIBASSERT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) +#else +#define LIBASSERT_GCC_VERSION 0 +#endif + +#if defined(__ICL) +#define LIBASSERT_ICC_VERSION __ICL +#elif defined(__INTEL_COMPILER) +#define LIBASSERT_ICC_VERSION __INTEL_COMPILER +#else +#define LIBASSERT_ICC_VERSION 0 +#endif + +#if defined(_MSC_VER) +#define LIBASSERT_MSC_VERSION _MSC_VER +#else +#define LIBASSERT_MSC_VERSION 0 +#endif + + +// Detect standard library versions. +#ifdef _GLIBCXX_RELEASE +#define LIBASSERT_GLIBCXX_RELEASE _GLIBCXX_RELEASE +#else +#define LIBASSERT_GLIBCXX_RELEASE 0 +#endif +#ifdef _LIBCPP_VERSION +#define LIBASSERT_LIBCPP_VERSION _LIBCPP_VERSION +#else +#define LIBASSERT_LIBCPP_VERSION 0 +#endif + +#ifdef _MSVC_LANG +#define LIBASSERT_CPLUSPLUS _MSVC_LANG +#else +#define LIBASSERT_CPLUSPLUS __cplusplus +#endif + + + + +// Detect that we have access to consteval, C++20 constexpr extensions, and std::is_constant_evaluated. +#if !defined(__cpp_lib_is_constant_evaluated) + #define LIBASSERT_USE_CONSTEVAL 0 +#elif LIBASSERT_CPLUSPLUS < 201709L + #define LIBASSERT_USE_CONSTEVAL 0 +#elif LIBASSERT_GLIBCXX_RELEASE && LIBASSERT_GLIBCXX_RELEASE < 10 + #define LIBASSERT_USE_CONSTEVAL 0 +#elif LIBASSERT_LIBCPP_VERSION && LIBASSERT_LIBCPP_VERSION < 10000 + #define LIBASSERT_USE_CONSTEVAL 0 +#elif defined(__apple_build_version__) && __apple_build_version__ < 14000029L + #define LIBASSERT_USE_CONSTEVAL 0 // consteval is broken in Apple clang < 14. +#elif LIBASSERT_MSC_VERSION && LIBASSERT_MSC_VERSION < 1929 + #define LIBASSERT_USE_CONSTEVAL 0 // consteval is broken in MSVC VS2019 < 16.10. +#elif defined(__cpp_consteval) + #define LIBASSERT_USE_CONSTEVAL 1 +#elif LIBASSERT_GCC_VERSION >= 1002 || LIBASSERT_CLANG_VERSION >= 1101 + #define LIBASSERT_USE_CONSTEVAL 1 +#else + #define LIBASSERT_USE_CONSTEVAL 0 +#endif + +#if LIBASSERT_USE_CONSTEVAL + #define LIBASSERT_CONSTEVAL consteval + #define LIBASSERT_CONSTEXPR20 constexpr +#else + #define LIBASSERT_CONSTEVAL + #define LIBASSERT_CONSTEXPR20 +#endif + + +#endif // LIBASSERT_INTERNAL_HPP From 5cb524ceffe59587c84a62d6b8917d24ea0db251 Mon Sep 17 00:00:00 2001 From: ian Date: Wed, 1 May 2024 20:45:08 -0400 Subject: [PATCH 04/25] First revision of compatibility layer --- CMakeLists.txt | 2 +- include/libassert/assert.hpp | 97 +------- include/libassert/libassert_internal.hpp | 298 ++++++++++++++++++++--- 3 files changed, 266 insertions(+), 131 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 03a1fb77..3f7d131b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -116,7 +116,7 @@ target_compile_options( PRIVATE $<$>:-Wall -Wextra -Werror=return-type -Wshadow -Wundef> $<$:-Wuseless-cast -Wnonnull-compare> - $<$:/W4 /WX /permissive- /Zc:__cplusplus> + $<$:/W4 /WX /permissive-> ) # ---- Generate Build Info Headers ---- diff --git a/include/libassert/assert.hpp b/include/libassert/assert.hpp index 8969e3a3..e3a39b3d 100644 --- a/include/libassert/assert.hpp +++ b/include/libassert/assert.hpp @@ -23,13 +23,9 @@ #include #endif -#if defined(_MSVC_LANG) && _MSVC_LANG < 201703L - #error "libassert requires C++17 or newer" -#elif !defined(_MSVC_LANG) && __cplusplus < 201703L - #pragma error "libassert requires C++17 or newer" -#endif +#include "libassert/libassert_internal.hpp" -#if __cplusplus >= 202002L || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L) +#if LIBASSERT_STD_VER >= 20 #include #endif @@ -56,100 +52,11 @@ // Block comments are used to create some visual separation and try to break the library into more manageable parts. // I've tried as much as I can to keep logically connected parts together but there is some bootstrapping necessary. -// ===================================================================================================================== -// || Preprocessor stuff || -// ===================================================================================================================== - -#ifdef _WIN32 -#define LIBASSERT_EXPORT_ATTR __declspec(dllexport) -#define LIBASSERT_IMPORT_ATTR __declspec(dllimport) -#else -#define LIBASSERT_EXPORT_ATTR __attribute__((visibility("default"))) -#define LIBASSERT_IMPORT_ATTR __attribute__((visibility("default"))) -#endif - -#ifdef LIBASSERT_STATIC_DEFINE - #define LIBASSERT_EXPORT - #define LIBASSERT_NO_EXPORT -#else - #ifndef LIBASSERT_EXPORT - #ifdef libassert_lib_EXPORTS - /* We are building this library */ - #define LIBASSERT_EXPORT LIBASSERT_EXPORT_ATTR - #else - /* We are using this library */ - #define LIBASSERT_EXPORT LIBASSERT_IMPORT_ATTR - #endif - #endif -#endif - -#define LIBASSERT_IS_CLANG 0 -#define LIBASSERT_IS_GCC 0 -#define LIBASSERT_IS_MSVC 0 - -#if defined(__clang__) - #undef LIBASSERT_IS_CLANG - #define LIBASSERT_IS_CLANG 1 -#elif defined(__GNUC__) || defined(__GNUG__) - #undef LIBASSERT_IS_GCC - #define LIBASSERT_IS_GCC 1 -#elif defined(_MSC_VER) - #undef LIBASSERT_IS_MSVC - #define LIBASSERT_IS_MSVC 1 - #include // alternative operator tokens are standard but msvc requires the include or /permissive- or /Za -#else - #error "Libassert: Unsupported compiler" -#endif - -#if LIBASSERT_IS_CLANG || LIBASSERT_IS_GCC - #define LIBASSERT_PFUNC __extension__ __PRETTY_FUNCTION__ - #define LIBASSERT_ATTR_COLD [[gnu::cold]] - #define LIBASSERT_ATTR_NOINLINE [[gnu::noinline]] - #define LIBASSERT_UNREACHABLE_CALL __builtin_unreachable() -#else - #define LIBASSERT_PFUNC __FUNCSIG__ - #define LIBASSERT_ATTR_COLD - #define LIBASSERT_ATTR_NOINLINE __declspec(noinline) - #define LIBASSERT_UNREACHABLE_CALL __assume(false) -#endif - -#if LIBASSERT_IS_MSVC - #define LIBASSERT_STRONG_EXPECT(expr, value) (expr) -#elif defined(__clang__) && __clang_major__ >= 11 || __GNUC__ >= 9 - #define LIBASSERT_STRONG_EXPECT(expr, value) __builtin_expect_with_probability((expr), (value), 1) -#else - #define LIBASSERT_STRONG_EXPECT(expr, value) __builtin_expect((expr), (value)) -#endif - -// deal with gcc shenanigans -// at one point their std::string's move assignment was not noexcept even in c++17 -// https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html -#if defined(_GLIBCXX_USE_CXX11_ABI) - // NOLINTNEXTLINE(misc-include-cleaner) - #define LIBASSERT_GCC_ISNT_STUPID _GLIBCXX_USE_CXX11_ABI -#else - // assume others target new abi by default - homework - #define LIBASSERT_GCC_ISNT_STUPID 1 -#endif // always_false is just convenient to use here #define LIBASSERT_PHONY_USE(E) ((void)libassert::detail::always_false) -#if LIBASSERT_IS_MSVC - #pragma warning(push) - // warning C4251: using non-dll-exported type in dll-exported type, firing on std::vector and others for - // some reason - // 4275 is the same thing but for base classes - #pragma warning(disable: 4251; disable: 4275) -#endif -#if LIBASSERT_IS_GCC || __cplusplus >= 2020002L - // __VA_OPT__ needed for GCC, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=44317 - #define LIBASSERT_VA_ARGS(...) __VA_OPT__(,) __VA_ARGS__ -#else - // clang properly eats the comma with ##__VA_ARGS__ - #define LIBASSERT_VA_ARGS(...) , ##__VA_ARGS__ -#endif // ===================================================================================================================== // || Core utilities || diff --git a/include/libassert/libassert_internal.hpp b/include/libassert/libassert_internal.hpp index e1460f8e..5724a1b9 100644 --- a/include/libassert/libassert_internal.hpp +++ b/include/libassert/libassert_internal.hpp @@ -5,23 +5,24 @@ // https://github.com/jeremy-rifkin/libassert + +// ===================================================================================================================== +// || Preprocessor stuff || +// ===================================================================================================================== + +// Validate that we are using a C++17 or newer compiler. #if defined(_MSVC_LANG) && _MSVC_LANG < 201703L #error "libassert requires C++17 or newer" #elif !defined(_MSVC_LANG) && __cplusplus < 201703L #pragma error "libassert requires C++17 or newer" #endif -// LIBASSERT_CPP_VER -// -// Macro that checks we have available the macro __cplusplus and assigns its value to LIBASSERT_CPP_VER -#ifndef LIBASSERT_CPLUSPLUS - #if defined(__cplusplus) - #define LIBASSERT_CPLUSPLUS __cplusplus - #else - #error "Libassert requires that __cplusplus is defined!" - #endif // __cplusplus -#endif // LIBASSERT_CPP_VER - +// Set the C++ version number based on if we are on a dumb compiler like MSVC or not. +#ifdef _MSVC_LANG + #define LIBASSERT_CPLUSPLUS _MSVC_LANG +#else + #define LIBASSERT_CPLUSPLUS __cplusplus +#endif // LIBASSERT_STRINGIFY // @@ -33,8 +34,12 @@ #define LIBASSERT_STRINGIFYIMPL(x) #x #endif - - +// Here we assign the current C++ standard number to LIBASSERT_STD_VER if it is not already defined. +// Currently this check assumes that the base version is C++17 and if the version number is greater than +// 202303L then we assume that we are using C++26. Currently, not every compiler has a defined value for C++26 +// and to some degree even checking for 202302L is not 100% reliable as some compilers have chosen to not actually define +// the version number for C++23 until they are fully compliant. Still this is a rare case and should be fine here. +// TODO: Once C++26 is fully released we should update this so the else instead uses the proper value. #ifndef LIBASSERT_STD_VER #if LIBASSERT_CPLUSPLUS <= 201703L #define LIBASSERT_STD_VER 17 @@ -43,61 +48,141 @@ #elif LIBASSERT_CPLUSPLUS <= 202302L #define LIBASSERT_STD_VER 23 #else - // TODO: Once C++26 is fully released we should update this to instead check for its defined value. - // Currently, at this time there is no reliable manner to truely know what the version number for C++26 is. #define LIBASSERT_STD_VER 26 // If our version number is higher than 202303L assume we are using C++26 #endif // LIBASSERT_CPLUSPLUS #endif // LIBASSERT_STD_VER -// Detect compiler versions. + +/// +/// Detect compiler versions. +/// + + +// Detect Clang compiler. #if defined(__clang__) && !defined(__ibmxl__) + #define LIBASSERT_IS_CLANG 1 #define LIBASSERT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__) #else + #define LIBASSERT_IS_CLANG 0 #define LIBASSERT_CLANG_VERSION 0 #endif -#if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER) -#define LIBASSERT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) -#else -#define LIBASSERT_GCC_VERSION 0 -#endif -#if defined(__ICL) -#define LIBASSERT_ICC_VERSION __ICL -#elif defined(__INTEL_COMPILER) -#define LIBASSERT_ICC_VERSION __INTEL_COMPILER +// Detect GCC compiler. +#if (defined(__GNUC__) || defined(__GNUG__)) && !defined(__clang__) && !defined(__INTEL_COMPILER) + #define LIBASSERT_IS_GCC 1 + #define LIBASSERT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) #else -#define LIBASSERT_ICC_VERSION 0 + #define LIBASSERT_IS_GCC 0 + #define LIBASSERT_GCC_VERSION 0 #endif + +// Detect MSVC compiler. #if defined(_MSC_VER) -#define LIBASSERT_MSC_VERSION _MSC_VER + #define LIBASSERT_IS_MSVC 1 + #define LIBASSERT_MSVC_VERSION _MSC_VER +#include // alternative operator tokens are standard but msvc requires the include or /permissive- or /Za #else -#define LIBASSERT_MSC_VERSION 0 + #define LIBASSERT_IS_MSVC 0 + #define LIBASSERT_MSVC_VERSION 0 #endif -// Detect standard library versions. +/// +/// Detect standard library versions. +/// + +// Detect libstdc++ version. #ifdef _GLIBCXX_RELEASE -#define LIBASSERT_GLIBCXX_RELEASE _GLIBCXX_RELEASE + #define LIBASSERT_GLIBCXX_RELEASE _GLIBCXX_RELEASE #else -#define LIBASSERT_GLIBCXX_RELEASE 0 + #define LIBASSERT_GLIBCXX_RELEASE 0 #endif + + +// Detect libc++ version. #ifdef _LIBCPP_VERSION -#define LIBASSERT_LIBCPP_VERSION _LIBCPP_VERSION + #define LIBASSERT_LIBCPP_VERSION _LIBCPP_VERSION #else -#define LIBASSERT_LIBCPP_VERSION 0 + #define LIBASSERT_LIBCPP_VERSION 0 #endif + +// Detect the version number of __cplusplus. #ifdef _MSVC_LANG -#define LIBASSERT_CPLUSPLUS _MSVC_LANG + #define LIBASSERT_CPLUSPLUS _MSVC_LANG +#else + #define LIBASSERT_CPLUSPLUS __cplusplus +#endif + + +/// +/// Helper macros for compiler attributes. +/// + +// Check if we have __has_cpp_attribute support. +#ifdef __has_cpp_attribute +# define LIBASSERT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) +#else +# define LIBASSERT_HAS_CPP_ATTRIBUTE(x) 0 +#endif + + +/// +/// Compiler attribute support. +/// + +// Check if we have C++20's nodiscard("reason") attribute. +#if LIBASSERT_HAS_CPP_ATTRIBUTE(nodiscard) && LIBASSERT_STD_VER >= 20 + #define LIBASSERT_NODISCARD_MSG(msg) [[nodiscard(msg)]] +#else // Assume we have normal C++17 nodiscard support. + #define LIBASSERT_NODISCARD_MSG(msg) [[nodiscard]] +#endif + + +// Check if we have C++20's likely attribute. +// Clang and GCC's builtin_expect compiler intrinsic appears to work 1:1 with C++20's likely attribute. +#if LIBASSERT_HAS_CPP_ATTRIBUTE(likely) + #define LIBASSERT_LIKELY [[likely]] +#elif defined(__GNUC__) || defined(__clang__) + #define LIBASSERT_LIKELY __builtin_expect(!!(expr), 1) #else -#define LIBASSERT_CPLUSPLUS __cplusplus + #define LIBASSERT_LIKELY #endif +// Check if we have C++20's unlikely attribute. +// Clang and GCC's builtin_expect compiler intrinsic appears to work 1:1 with C++20's unlikely attribute. +#if LIBASSERT_HAS_CPP_ATTRIBUTE(unlikely) + #define LIBASSERT_UNLIKELY [[unlikely]] +#elif defined(__GNUC__) || defined(__clang__) + #define LIBASSERT_UNLIKELY __builtin_expect(!!(expr), 0) +#else + #define LIBASSERT_UNLIKELY +#endif +// Check if we have C++20's no_unique_address attribute. +#if LIBASSERT_HAS_CPP_ATTRIBUTE(no_unique_address) + #define LIBASSERT_NO_UNIQUE_ADDRESS [[no_unique_address]] +#else + #define LIBASSERT_NO_UNIQUE_ADDRESS +#endif + + +// Check if we have C++23's assume attribute. +#if LIBASSERT_HAS_CPP_ATTRIBUTE(assume) + #define LIBASSERT_ASSUME(expr) [[assume(expr)]] +#else + #define LIBASSERT_ASSUME(expr) +#endif + + +/// +/// C++20 feature support. +/// + // Detect that we have access to consteval, C++20 constexpr extensions, and std::is_constant_evaluated. #if !defined(__cpp_lib_is_constant_evaluated) #define LIBASSERT_USE_CONSTEVAL 0 @@ -128,4 +213,147 @@ #endif + +/// +/// C++23 feature support. +/// + +// Permit static constexpr variables in constexpr functions in C++23. +#if defined(__cpp_constexpr) && __cpp_constexpr >= 202211L + #define LIBASSERT_CONSTEXPR23_STATIC_VAR static constexpr +#else + #define LIBASSERT_CONSTEXPR23_STATIC_VAR +#endif + +#ifdef __cpp_if_consteval + #define LIBASSERT_IF_CONSTEVAL if consteval +#else + #define LIBASSERT_IF_CONSTEVAL if constexpr +#endif + + +/// +/// C++20 functionality wrappers. +/// + +#ifdef __has_include + # if __has_include() + # include + # ifdef __cpp_lib_is_constant_evaluated + # include + # define LIBASSERT_HAS_IS_CONSTANT_EVALUATED + # endif + # endif +#endif + +#ifdef __has_builtin + # if __has_builtin(__builtin_is_constant_evaluated) + # define LIBASSERT_HAS_BUILTIN_IS_CONSTANT_EVALUATED + # endif +#endif + +// GCC 9 and later has __builtin_is_constant_evaluated +#if (__GNUC__ >= 9) && !defined(LIBASSERT_HAS_BUILTIN_IS_CONSTANT_EVALUATED) + # define LIBASSERT_HAS_BUILTIN_IS_CONSTANT_EVALUATED +#endif + +// Visual Studio 2019 and later supports __builtin_is_constant_evaluated +#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 192528326) + # define LIBASSERT_HAS_BUILTIN_IS_CONSTANT_EVALUATED +#endif + + +// Add a helper function for support to C++20's std::is_constant_evaluated. +namespace libassert::support +{ + constexpr bool is_constant_evaluated() noexcept + { +#if defined(LIBASSERT_HAS_IS_CONSTANT_EVALUATED) + return std::is_constant_evaluated(); +#elif defined(LIBASSERT_HAS_BUILTIN_IS_CONSTANT_EVALUATED) + return __builtin_is_constant_evaluated(); +#else + return false; +#endif + } +} + + +/// +/// General project macros +/// + + +#ifdef _WIN32 +#define LIBASSERT_EXPORT_ATTR __declspec(dllexport) +#define LIBASSERT_IMPORT_ATTR __declspec(dllimport) +#else +#define LIBASSERT_EXPORT_ATTR __attribute__((visibility("default"))) +#define LIBASSERT_IMPORT_ATTR __attribute__((visibility("default"))) +#endif + +#ifdef LIBASSERT_STATIC_DEFINE + #define LIBASSERT_EXPORT + #define LIBASSERT_NO_EXPORT +#else + #ifndef LIBASSERT_EXPORT + #ifdef libassert_lib_EXPORTS + /* We are building this library */ + #define LIBASSERT_EXPORT LIBASSERT_EXPORT_ATTR + #else + /* We are using this library */ + #define LIBASSERT_EXPORT LIBASSERT_IMPORT_ATTR + #endif + #endif +#endif + +#if LIBASSERT_IS_CLANG || LIBASSERT_IS_GCC + #define LIBASSERT_PFUNC __extension__ __PRETTY_FUNCTION__ + #define LIBASSERT_ATTR_COLD [[gnu::cold]] + #define LIBASSERT_ATTR_NOINLINE [[gnu::noinline]] + #define LIBASSERT_UNREACHABLE_CALL __builtin_unreachable() +#else + #define LIBASSERT_PFUNC __FUNCSIG__ + #define LIBASSERT_ATTR_COLD + #define LIBASSERT_ATTR_NOINLINE __declspec(noinline) + #define LIBASSERT_UNREACHABLE_CALL __assume(false) +#endif + +#if LIBASSERT_IS_MSVC + #define LIBASSERT_STRONG_EXPECT(expr, value) (expr) +#elif defined(__clang__) && __clang_major__ >= 11 || __GNUC__ >= 9 + #define LIBASSERT_STRONG_EXPECT(expr, value) __builtin_expect_with_probability((expr), (value), 1) +#else + #define LIBASSERT_STRONG_EXPECT(expr, value) __builtin_expect((expr), (value)) +#endif + +// deal with gcc shenanigans +// at one point their std::string's move assignment was not noexcept even in c++17 +// https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html +#if defined(_GLIBCXX_USE_CXX11_ABI) + // NOLINTNEXTLINE(misc-include-cleaner) + #define LIBASSERT_GCC_ISNT_STUPID _GLIBCXX_USE_CXX11_ABI +#else + // assume others target new abi by default - homework + #define LIBASSERT_GCC_ISNT_STUPID 1 +#endif + +#if LIBASSERT_IS_MSVC +#pragma warning(push) +// warning C4251: using non-dll-exported type in dll-exported type, firing on std::vector and others for +// some reason +// 4275 is the same thing but for base classes +#pragma warning(disable: 4251; disable: 4275) +#endif + +#if LIBASSERT_IS_GCC || LIBASSERT_STD_VER >= 20 + +// __VA_OPT__ needed for GCC, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=44317 +#define LIBASSERT_VA_ARGS(...) __VA_OPT__(,) __VA_ARGS__ +#else +// clang properly eats the comma with ##__VA_ARGS__ +#define LIBASSERT_VA_ARGS(...) , ##__VA_ARGS__ +#endif + + #endif // LIBASSERT_INTERNAL_HPP From d7818800bbad4598139b8cd61a3dadcda2aaa3e0 Mon Sep 17 00:00:00 2001 From: ian Date: Wed, 1 May 2024 21:04:53 -0400 Subject: [PATCH 05/25] Correct minor oversight & update the documentation and formating --- include/libassert/libassert_internal.hpp | 48 +++++++++++++++--------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/include/libassert/libassert_internal.hpp b/include/libassert/libassert_internal.hpp index 5724a1b9..2a247271 100644 --- a/include/libassert/libassert_internal.hpp +++ b/include/libassert/libassert_internal.hpp @@ -10,6 +10,7 @@ // || Preprocessor stuff || // ===================================================================================================================== + // Validate that we are using a C++17 or newer compiler. #if defined(_MSVC_LANG) && _MSVC_LANG < 201703L #error "libassert requires C++17 or newer" @@ -17,6 +18,7 @@ #pragma error "libassert requires C++17 or newer" #endif + // Set the C++ version number based on if we are on a dumb compiler like MSVC or not. #ifdef _MSVC_LANG #define LIBASSERT_CPLUSPLUS _MSVC_LANG @@ -24,6 +26,7 @@ #define LIBASSERT_CPLUSPLUS __cplusplus #endif + // LIBASSERT_STRINGIFY // // Example usage: @@ -34,6 +37,7 @@ #define LIBASSERT_STRINGIFYIMPL(x) #x #endif + // Here we assign the current C++ standard number to LIBASSERT_STD_VER if it is not already defined. // Currently this check assumes that the base version is C++17 and if the version number is greater than // 202303L then we assume that we are using C++26. Currently, not every compiler has a defined value for C++26 @@ -123,9 +127,9 @@ // Check if we have __has_cpp_attribute support. #ifdef __has_cpp_attribute -# define LIBASSERT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) + #define LIBASSERT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) #else -# define LIBASSERT_HAS_CPP_ATTRIBUTE(x) 0 + #define LIBASSERT_HAS_CPP_ATTRIBUTE(x) 0 #endif @@ -204,6 +208,8 @@ #define LIBASSERT_USE_CONSTEVAL 0 #endif + +// If we have consteval support, define the LIBASSERT_CONSTEVAL macro to use consteval. #if LIBASSERT_USE_CONSTEVAL #define LIBASSERT_CONSTEVAL consteval #define LIBASSERT_CONSTEXPR20 constexpr @@ -222,9 +228,11 @@ #if defined(__cpp_constexpr) && __cpp_constexpr >= 202211L #define LIBASSERT_CONSTEXPR23_STATIC_VAR static constexpr #else - #define LIBASSERT_CONSTEXPR23_STATIC_VAR + #define LIBASSERT_CONSTEXPR23_STATIC_VAR constexpr #endif + +// Permits the use of if consteval in C++23. #ifdef __cpp_if_consteval #define LIBASSERT_IF_CONSTEVAL if consteval #else @@ -236,34 +244,40 @@ /// C++20 functionality wrappers. /// +// Check if we can use std::is_constant_evaluated. #ifdef __has_include - # if __has_include() - # include - # ifdef __cpp_lib_is_constant_evaluated - # include - # define LIBASSERT_HAS_IS_CONSTANT_EVALUATED - # endif - # endif + #if __has_include() + #include + #ifdef __cpp_lib_is_constant_evaluated + #include + #define LIBASSERT_HAS_IS_CONSTANT_EVALUATED + #endif + #endif #endif + +// Check if we have the builtin __builtin_is_constant_evaluated. #ifdef __has_builtin - # if __has_builtin(__builtin_is_constant_evaluated) - # define LIBASSERT_HAS_BUILTIN_IS_CONSTANT_EVALUATED - # endif + #if __has_builtin(__builtin_is_constant_evaluated) + #define LIBASSERT_HAS_BUILTIN_IS_CONSTANT_EVALUATED + #endif #endif -// GCC 9 and later has __builtin_is_constant_evaluated + +// GCC 9.1+ and later has __builtin_is_constant_evaluated #if (__GNUC__ >= 9) && !defined(LIBASSERT_HAS_BUILTIN_IS_CONSTANT_EVALUATED) - # define LIBASSERT_HAS_BUILTIN_IS_CONSTANT_EVALUATED + #define LIBASSERT_HAS_BUILTIN_IS_CONSTANT_EVALUATED #endif -// Visual Studio 2019 and later supports __builtin_is_constant_evaluated + +// Visual Studio 2019 (19.25) and later supports __builtin_is_constant_evaluated #if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 192528326) - # define LIBASSERT_HAS_BUILTIN_IS_CONSTANT_EVALUATED + #define LIBASSERT_HAS_BUILTIN_IS_CONSTANT_EVALUATED #endif // Add a helper function for support to C++20's std::is_constant_evaluated. +// Works with C++17 under GCC 9.1+, Clang 9+, and MSVC 19.25. namespace libassert::support { constexpr bool is_constant_evaluated() noexcept From fad9ebb7486f2b75ad7afc57d051dba49affc45e Mon Sep 17 00:00:00 2001 From: ian Date: Wed, 1 May 2024 21:06:48 -0400 Subject: [PATCH 06/25] Remove accidental macro redefinition --- include/libassert/libassert_internal.hpp | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/include/libassert/libassert_internal.hpp b/include/libassert/libassert_internal.hpp index 2a247271..afc26296 100644 --- a/include/libassert/libassert_internal.hpp +++ b/include/libassert/libassert_internal.hpp @@ -27,17 +27,6 @@ #endif -// LIBASSERT_STRINGIFY -// -// Example usage: -// printf("Line: %s", LIBASSERT_STRINGIFY(__LINE__)); -// -#ifndef LIBASSERT_STRINGIFY - #define LIBASSERT_STRINGIFY(x) LIBASSERT_STRINGIFYIMPL(x) - #define LIBASSERT_STRINGIFYIMPL(x) #x -#endif - - // Here we assign the current C++ standard number to LIBASSERT_STD_VER if it is not already defined. // Currently this check assumes that the base version is C++17 and if the version number is greater than // 202303L then we assume that we are using C++26. Currently, not every compiler has a defined value for C++26 From 0d7a8c3fd11075b7e8009e5bc26329c873c10ec4 Mon Sep 17 00:00:00 2001 From: ian Date: Wed, 1 May 2024 21:09:58 -0400 Subject: [PATCH 07/25] Update the naming convention of attribute wrappers. --- include/libassert/libassert_internal.hpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/include/libassert/libassert_internal.hpp b/include/libassert/libassert_internal.hpp index afc26296..553737be 100644 --- a/include/libassert/libassert_internal.hpp +++ b/include/libassert/libassert_internal.hpp @@ -128,9 +128,9 @@ // Check if we have C++20's nodiscard("reason") attribute. #if LIBASSERT_HAS_CPP_ATTRIBUTE(nodiscard) && LIBASSERT_STD_VER >= 20 - #define LIBASSERT_NODISCARD_MSG(msg) [[nodiscard(msg)]] + #define LIBASSERT_ATTR_NODISCARD_MSG(msg) [[nodiscard(msg)]] #else // Assume we have normal C++17 nodiscard support. - #define LIBASSERT_NODISCARD_MSG(msg) [[nodiscard]] + #define LIBASSERT_ATTR_NODISCARD_MSG(msg) [[nodiscard]] #endif @@ -139,36 +139,36 @@ #if LIBASSERT_HAS_CPP_ATTRIBUTE(likely) #define LIBASSERT_LIKELY [[likely]] #elif defined(__GNUC__) || defined(__clang__) - #define LIBASSERT_LIKELY __builtin_expect(!!(expr), 1) + #define LIBASSERT_ATTR_LIKELY __builtin_expect(!!(expr), 1) #else - #define LIBASSERT_LIKELY + #define LIBASSERT_ATTR_LIKELY #endif // Check if we have C++20's unlikely attribute. // Clang and GCC's builtin_expect compiler intrinsic appears to work 1:1 with C++20's unlikely attribute. #if LIBASSERT_HAS_CPP_ATTRIBUTE(unlikely) - #define LIBASSERT_UNLIKELY [[unlikely]] + #define LIBASSERT_ATTR_UNLIKELY [[unlikely]] #elif defined(__GNUC__) || defined(__clang__) - #define LIBASSERT_UNLIKELY __builtin_expect(!!(expr), 0) + #define LIBASSERT_ATTR_UNLIKELY __builtin_expect(!!(expr), 0) #else - #define LIBASSERT_UNLIKELY + #define LIBASSERT_ATTR_UNLIKELY #endif // Check if we have C++20's no_unique_address attribute. #if LIBASSERT_HAS_CPP_ATTRIBUTE(no_unique_address) - #define LIBASSERT_NO_UNIQUE_ADDRESS [[no_unique_address]] + #define LIBASSERT_ATTR_NO_UNIQUE_ADDRESS [[no_unique_address]] #else - #define LIBASSERT_NO_UNIQUE_ADDRESS + #define LIBASSERT_ATTR_NO_UNIQUE_ADDRESS #endif // Check if we have C++23's assume attribute. #if LIBASSERT_HAS_CPP_ATTRIBUTE(assume) - #define LIBASSERT_ASSUME(expr) [[assume(expr)]] + #define LIBASSERT_ATTR_ASSUME(expr) [[assume(expr)]] #else - #define LIBASSERT_ASSUME(expr) + #define LIBASSERT_ATTR_ASSUME(expr) #endif From a8995436edd151b04d4686182af544450d65eddd Mon Sep 17 00:00:00 2001 From: ian Date: Wed, 1 May 2024 23:58:48 -0400 Subject: [PATCH 08/25] Apply requested changes --- .gitignore | 2 +- CMakeLists.txt | 2 +- include/libassert/assert.hpp | 9 +- .../{libassert_internal.hpp => platform.hpp} | 115 ++++-------------- 4 files changed, 36 insertions(+), 92 deletions(-) rename include/libassert/{libassert_internal.hpp => platform.hpp} (70%) diff --git a/.gitignore b/.gitignore index 18f8df60..52a446c0 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,4 @@ build* cmake-build-* __pycache__ compile_commands.json -CMakeUserPresets.json \ No newline at end of file +CMakeUserPresets.json diff --git a/CMakeLists.txt b/CMakeLists.txt index 3f7d131b..8f5f93ba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -87,7 +87,7 @@ target_sources( ${target_name} PRIVATE # include include/libassert/assert.hpp - include/libassert/libassert_internal.hpp + include/libassert/platform.hpp ) # add /src files to target diff --git a/include/libassert/assert.hpp b/include/libassert/assert.hpp index e3a39b3d..ee7bd443 100644 --- a/include/libassert/assert.hpp +++ b/include/libassert/assert.hpp @@ -23,7 +23,7 @@ #include #endif -#include "libassert/libassert_internal.hpp" +#include "libassert/platform.hpp" #if LIBASSERT_STD_VER >= 20 #include @@ -56,6 +56,13 @@ // always_false is just convenient to use here #define LIBASSERT_PHONY_USE(E) ((void)libassert::detail::always_false) +#if LIBASSERT_IS_MSVC +#pragma warning(push) +// warning C4251: using non-dll-exported type in dll-exported type, firing on std::vector and others for +// some reason +// 4275 is the same thing but for base classes +#pragma warning(disable: 4251; disable: 4275) +#endif // ===================================================================================================================== diff --git a/include/libassert/libassert_internal.hpp b/include/libassert/platform.hpp similarity index 70% rename from include/libassert/libassert_internal.hpp rename to include/libassert/platform.hpp index 553737be..2321e8c5 100644 --- a/include/libassert/libassert_internal.hpp +++ b/include/libassert/platform.hpp @@ -51,7 +51,6 @@ /// -// Detect Clang compiler. #if defined(__clang__) && !defined(__ibmxl__) #define LIBASSERT_IS_CLANG 1 #define LIBASSERT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__) @@ -61,7 +60,6 @@ #endif -// Detect GCC compiler. #if (defined(__GNUC__) || defined(__GNUG__)) && !defined(__clang__) && !defined(__INTEL_COMPILER) #define LIBASSERT_IS_GCC 1 #define LIBASSERT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) @@ -71,11 +69,10 @@ #endif -// Detect MSVC compiler. #if defined(_MSC_VER) #define LIBASSERT_IS_MSVC 1 #define LIBASSERT_MSVC_VERSION _MSC_VER -#include // alternative operator tokens are standard but msvc requires the include or /permissive- or /Za + #include // alternative operator tokens are standard but msvc requires the include or /permissive- or /Za #else #define LIBASSERT_IS_MSVC 0 #define LIBASSERT_MSVC_VERSION 0 @@ -86,7 +83,7 @@ /// Detect standard library versions. /// -// Detect libstdc++ version. +// libstdc++ #ifdef _GLIBCXX_RELEASE #define LIBASSERT_GLIBCXX_RELEASE _GLIBCXX_RELEASE #else @@ -94,7 +91,6 @@ #endif -// Detect libc++ version. #ifdef _LIBCPP_VERSION #define LIBASSERT_LIBCPP_VERSION _LIBCPP_VERSION #else @@ -102,7 +98,6 @@ #endif -// Detect the version number of __cplusplus. #ifdef _MSVC_LANG #define LIBASSERT_CPLUSPLUS _MSVC_LANG #else @@ -114,7 +109,6 @@ /// Helper macros for compiler attributes. /// -// Check if we have __has_cpp_attribute support. #ifdef __has_cpp_attribute #define LIBASSERT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) #else @@ -126,7 +120,6 @@ /// Compiler attribute support. /// -// Check if we have C++20's nodiscard("reason") attribute. #if LIBASSERT_HAS_CPP_ATTRIBUTE(nodiscard) && LIBASSERT_STD_VER >= 20 #define LIBASSERT_ATTR_NODISCARD_MSG(msg) [[nodiscard(msg)]] #else // Assume we have normal C++17 nodiscard support. @@ -134,29 +127,20 @@ #endif -// Check if we have C++20's likely attribute. -// Clang and GCC's builtin_expect compiler intrinsic appears to work 1:1 with C++20's likely attribute. #if LIBASSERT_HAS_CPP_ATTRIBUTE(likely) #define LIBASSERT_LIKELY [[likely]] -#elif defined(__GNUC__) || defined(__clang__) - #define LIBASSERT_ATTR_LIKELY __builtin_expect(!!(expr), 1) #else #define LIBASSERT_ATTR_LIKELY #endif -// Check if we have C++20's unlikely attribute. -// Clang and GCC's builtin_expect compiler intrinsic appears to work 1:1 with C++20's unlikely attribute. #if LIBASSERT_HAS_CPP_ATTRIBUTE(unlikely) #define LIBASSERT_ATTR_UNLIKELY [[unlikely]] -#elif defined(__GNUC__) || defined(__clang__) - #define LIBASSERT_ATTR_UNLIKELY __builtin_expect(!!(expr), 0) #else #define LIBASSERT_ATTR_UNLIKELY #endif -// Check if we have C++20's no_unique_address attribute. #if LIBASSERT_HAS_CPP_ATTRIBUTE(no_unique_address) #define LIBASSERT_ATTR_NO_UNIQUE_ADDRESS [[no_unique_address]] #else @@ -164,48 +148,10 @@ #endif -// Check if we have C++23's assume attribute. -#if LIBASSERT_HAS_CPP_ATTRIBUTE(assume) - #define LIBASSERT_ATTR_ASSUME(expr) [[assume(expr)]] -#else - #define LIBASSERT_ATTR_ASSUME(expr) -#endif - - /// /// C++20 feature support. /// -// Detect that we have access to consteval, C++20 constexpr extensions, and std::is_constant_evaluated. -#if !defined(__cpp_lib_is_constant_evaluated) - #define LIBASSERT_USE_CONSTEVAL 0 -#elif LIBASSERT_CPLUSPLUS < 201709L - #define LIBASSERT_USE_CONSTEVAL 0 -#elif LIBASSERT_GLIBCXX_RELEASE && LIBASSERT_GLIBCXX_RELEASE < 10 - #define LIBASSERT_USE_CONSTEVAL 0 -#elif LIBASSERT_LIBCPP_VERSION && LIBASSERT_LIBCPP_VERSION < 10000 - #define LIBASSERT_USE_CONSTEVAL 0 -#elif defined(__apple_build_version__) && __apple_build_version__ < 14000029L - #define LIBASSERT_USE_CONSTEVAL 0 // consteval is broken in Apple clang < 14. -#elif LIBASSERT_MSC_VERSION && LIBASSERT_MSC_VERSION < 1929 - #define LIBASSERT_USE_CONSTEVAL 0 // consteval is broken in MSVC VS2019 < 16.10. -#elif defined(__cpp_consteval) - #define LIBASSERT_USE_CONSTEVAL 1 -#elif LIBASSERT_GCC_VERSION >= 1002 || LIBASSERT_CLANG_VERSION >= 1101 - #define LIBASSERT_USE_CONSTEVAL 1 -#else - #define LIBASSERT_USE_CONSTEVAL 0 -#endif - - -// If we have consteval support, define the LIBASSERT_CONSTEVAL macro to use consteval. -#if LIBASSERT_USE_CONSTEVAL - #define LIBASSERT_CONSTEVAL consteval - #define LIBASSERT_CONSTEXPR20 constexpr -#else - #define LIBASSERT_CONSTEVAL - #define LIBASSERT_CONSTEXPR20 -#endif @@ -221,7 +167,6 @@ #endif -// Permits the use of if consteval in C++23. #ifdef __cpp_if_consteval #define LIBASSERT_IF_CONSTEVAL if consteval #else @@ -265,34 +210,17 @@ #endif -// Add a helper function for support to C++20's std::is_constant_evaluated. -// Works with C++17 under GCC 9.1+, Clang 9+, and MSVC 19.25. -namespace libassert::support -{ - constexpr bool is_constant_evaluated() noexcept - { -#if defined(LIBASSERT_HAS_IS_CONSTANT_EVALUATED) - return std::is_constant_evaluated(); -#elif defined(LIBASSERT_HAS_BUILTIN_IS_CONSTANT_EVALUATED) - return __builtin_is_constant_evaluated(); -#else - return false; -#endif - } -} - - /// /// General project macros /// #ifdef _WIN32 -#define LIBASSERT_EXPORT_ATTR __declspec(dllexport) -#define LIBASSERT_IMPORT_ATTR __declspec(dllimport) + #define LIBASSERT_EXPORT_ATTR __declspec(dllexport) + #define LIBASSERT_IMPORT_ATTR __declspec(dllimport) #else -#define LIBASSERT_EXPORT_ATTR __attribute__((visibility("default"))) -#define LIBASSERT_IMPORT_ATTR __attribute__((visibility("default"))) + #define LIBASSERT_EXPORT_ATTR __attribute__((visibility("default"))) + #define LIBASSERT_IMPORT_ATTR __attribute__((visibility("default"))) #endif #ifdef LIBASSERT_STATIC_DEFINE @@ -341,22 +269,31 @@ namespace libassert::support #define LIBASSERT_GCC_ISNT_STUPID 1 #endif -#if LIBASSERT_IS_MSVC -#pragma warning(push) -// warning C4251: using non-dll-exported type in dll-exported type, firing on std::vector and others for -// some reason -// 4275 is the same thing but for base classes -#pragma warning(disable: 4251; disable: 4275) -#endif #if LIBASSERT_IS_GCC || LIBASSERT_STD_VER >= 20 + // __VA_OPT__ needed for GCC, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=44317 + #define LIBASSERT_VA_ARGS(...) __VA_OPT__(,) __VA_ARGS__ +#else + // clang properly eats the comma with ##__VA_ARGS__ + #define LIBASSERT_VA_ARGS(...) , ##__VA_ARGS__ +#endif + -// __VA_OPT__ needed for GCC, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=44317 -#define LIBASSERT_VA_ARGS(...) __VA_OPT__(,) __VA_ARGS__ +// Add a helper function for support to C++20's std::is_constant_evaluated. +// Works with C++17 under GCC 9.1+, Clang 9+, and MSVC 19.25. +namespace libassert::support +{ + constexpr bool is_constant_evaluated() noexcept + { +#if defined(LIBASSERT_HAS_IS_CONSTANT_EVALUATED) + return std::is_constant_evaluated(); +#elif defined(LIBASSERT_HAS_BUILTIN_IS_CONSTANT_EVALUATED) + return __builtin_is_constant_evaluated(); #else -// clang properly eats the comma with ##__VA_ARGS__ -#define LIBASSERT_VA_ARGS(...) , ##__VA_ARGS__ + return false; #endif + } +} #endif // LIBASSERT_INTERNAL_HPP From fafc4ff61444142d9569ba75de4dbce5bfbd2f0a Mon Sep 17 00:00:00 2001 From: ian Date: Thu, 2 May 2024 00:17:29 -0400 Subject: [PATCH 09/25] Add a few more items and apply minor reshuffle --- include/libassert/platform.hpp | 36 ++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/include/libassert/platform.hpp b/include/libassert/platform.hpp index 2321e8c5..f3ff4b81 100644 --- a/include/libassert/platform.hpp +++ b/include/libassert/platform.hpp @@ -10,15 +10,6 @@ // || Preprocessor stuff || // ===================================================================================================================== - -// Validate that we are using a C++17 or newer compiler. -#if defined(_MSVC_LANG) && _MSVC_LANG < 201703L - #error "libassert requires C++17 or newer" -#elif !defined(_MSVC_LANG) && __cplusplus < 201703L - #pragma error "libassert requires C++17 or newer" -#endif - - // Set the C++ version number based on if we are on a dumb compiler like MSVC or not. #ifdef _MSVC_LANG #define LIBASSERT_CPLUSPLUS _MSVC_LANG @@ -27,6 +18,12 @@ #endif +// Validate that we are using a C++17 or newer compiler. +#if LIBASSERT_CPLUSPLUS < 201703L + #error "libassert requires C++17 or newer" +#endif + + // Here we assign the current C++ standard number to LIBASSERT_STD_VER if it is not already defined. // Currently this check assumes that the base version is C++17 and if the version number is greater than // 202303L then we assume that we are using C++26. Currently, not every compiler has a defined value for C++26 @@ -152,7 +149,18 @@ /// C++20 feature support. /// +#if defined(__cpp_conditional_explicit) && __cpp_conditional_explicit >= 201806L + #define LIBASSERT_CPP20_EXPLICIT_BOOL(expr) explicit(expr) +#else + #define LIBASSERT_CPP20_EXPLICIT_BOOL(expr) explicit +#endif + +#if LIBASSERT_STD_VER >= 20 + #define LIBASSERT_CPP20_CONSTEXPR constexpr +#else + #define LIBASSERT_CPP20_CONSTEXPR +#endif /// @@ -167,13 +175,21 @@ #endif -#ifdef __cpp_if_consteval +#if defined(__cpp_if_consteval) && __cpp_if_consteval >= 202106L #define LIBASSERT_IF_CONSTEVAL if consteval #else #define LIBASSERT_IF_CONSTEVAL if constexpr #endif +#if LIBASSERT_STD_VER >= 23 + #define LIBASSERT_CONSTEXPR23 constexpr +#else + #define LIBASSERT_CONSTEXPR23 +#endif + + + /// /// C++20 functionality wrappers. /// From 91ef2df5f05a30e8d80067e92c36b655bc8dc513 Mon Sep 17 00:00:00 2001 From: ian Date: Fri, 3 May 2024 20:45:11 -0400 Subject: [PATCH 10/25] Add wrapper for user generated static_assert --- include/libassert/platform.hpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/include/libassert/platform.hpp b/include/libassert/platform.hpp index f3ff4b81..4aeb3375 100644 --- a/include/libassert/platform.hpp +++ b/include/libassert/platform.hpp @@ -295,6 +295,21 @@ #endif +// Wrapper macro to allow support for C++26's user generated static_assert messages. +// The backup message version also allows for the user to provide a backup version that will +// be used if the compiler does not support user generated messages. +// More info on user generated static_assert's +// can be found here: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2741r1.pdf +#if __cpp_static_assert >= 202306L + #define LIBASSERT_USER_STATIC_ASSERT(cond, constant) static_assert(cond, constant) + #define LIBASSERT_USER_STATIC_ASSERT_BACKUP_MSG(cond, msg, constant) static_assert(cond, constant) +#else + #define LIBASSERT_USER_STATIC_ASSERT(cond, constant) static_assert(cond) + #define LIBASSERT_USER_STATIC_ASSERT_BACKUP_MSG(cond, msg, constant) static_assert(cond, msg) +#endif + + + // Add a helper function for support to C++20's std::is_constant_evaluated. // Works with C++17 under GCC 9.1+, Clang 9+, and MSVC 19.25. namespace libassert::support From 438c8aeacb503bb17cd82b5c803bf3b8a62cdf72 Mon Sep 17 00:00:00 2001 From: ian Date: Fri, 3 May 2024 21:03:07 -0400 Subject: [PATCH 11/25] Finalize formatting and wrapping up details --- include/libassert/platform.hpp | 109 ++++++++++++++++++--------------- 1 file changed, 61 insertions(+), 48 deletions(-) diff --git a/include/libassert/platform.hpp b/include/libassert/platform.hpp index 4aeb3375..47b4f298 100644 --- a/include/libassert/platform.hpp +++ b/include/libassert/platform.hpp @@ -1,5 +1,5 @@ -#ifndef LIBASSERT_INTERNAL_HPP -#define LIBASSERT_INTERNAL_HPP +#ifndef LIBASSERT_PLATFORM_HPP +#define LIBASSERT_PLATFORM_HPP // Copyright (c) 2021-2024 Jeremy Rifkin under the MIT license // https://github.com/jeremy-rifkin/libassert @@ -156,6 +156,13 @@ #endif +#if defined(__cpp_consteval) && __cpp_consteval >= 201811L + #define LIBASSERT_CONSTEVAL consteval +#else + #define LIBASSERT_CONSTEVAL constexpr +#endif + + #if LIBASSERT_STD_VER >= 20 #define LIBASSERT_CPP20_CONSTEXPR constexpr #else @@ -188,41 +195,22 @@ #define LIBASSERT_CONSTEXPR23 #endif - - /// -/// C++20 functionality wrappers. -/// - -// Check if we can use std::is_constant_evaluated. -#ifdef __has_include - #if __has_include() - #include - #ifdef __cpp_lib_is_constant_evaluated - #include - #define LIBASSERT_HAS_IS_CONSTANT_EVALUATED - #endif - #endif -#endif - - -// Check if we have the builtin __builtin_is_constant_evaluated. -#ifdef __has_builtin - #if __has_builtin(__builtin_is_constant_evaluated) - #define LIBASSERT_HAS_BUILTIN_IS_CONSTANT_EVALUATED - #endif -#endif - - -// GCC 9.1+ and later has __builtin_is_constant_evaluated -#if (__GNUC__ >= 9) && !defined(LIBASSERT_HAS_BUILTIN_IS_CONSTANT_EVALUATED) - #define LIBASSERT_HAS_BUILTIN_IS_CONSTANT_EVALUATED -#endif +/// C++26 feature support. +/// -// Visual Studio 2019 (19.25) and later supports __builtin_is_constant_evaluated -#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 192528326) - #define LIBASSERT_HAS_BUILTIN_IS_CONSTANT_EVALUATED +// Wrapper macro to allow support for C++26's user generated static_assert messages. +// The backup message version also allows for the user to provide a backup version that will +// be used if the compiler does not support user generated messages. +// More info on user generated static_assert's +// can be found here: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2741r1.pdf +#if defined(__cpp_static_assert) && __cpp_static_assert >= 202306L + #define LIBASSERT_USER_STATIC_ASSERT(cond, constant) static_assert(cond, constant) + #define LIBASSERT_USER_STATIC_ASSERT_BACKUP_MSG(cond, msg, constant) static_assert(cond, constant) +#else + #define LIBASSERT_USER_STATIC_ASSERT(cond, constant) static_assert(cond) + #define LIBASSERT_USER_STATIC_ASSERT_BACKUP_MSG(cond, msg, constant) static_assert(cond, msg) #endif @@ -295,25 +283,50 @@ #endif -// Wrapper macro to allow support for C++26's user generated static_assert messages. -// The backup message version also allows for the user to provide a backup version that will -// be used if the compiler does not support user generated messages. -// More info on user generated static_assert's -// can be found here: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2741r1.pdf -#if __cpp_static_assert >= 202306L - #define LIBASSERT_USER_STATIC_ASSERT(cond, constant) static_assert(cond, constant) - #define LIBASSERT_USER_STATIC_ASSERT_BACKUP_MSG(cond, msg, constant) static_assert(cond, constant) -#else - #define LIBASSERT_USER_STATIC_ASSERT(cond, constant) static_assert(cond) - #define LIBASSERT_USER_STATIC_ASSERT_BACKUP_MSG(cond, msg, constant) static_assert(cond, msg) +/// +/// C++20 functionality wrappers. +/// + +// Check if we can use std::is_constant_evaluated. +#ifdef __has_include + #if __has_include() + #include + #ifdef __cpp_lib_is_constant_evaluated + #include + #define LIBASSERT_HAS_IS_CONSTANT_EVALUATED + #endif + #endif +#endif + + +// Check if we have the builtin __builtin_is_constant_evaluated. +#ifdef __has_builtin + #if __has_builtin(__builtin_is_constant_evaluated) + #define LIBASSERT_HAS_BUILTIN_IS_CONSTANT_EVALUATED + #endif #endif +// GCC 9.1+ and later has __builtin_is_constant_evaluated +#if (__GNUC__ >= 9) && !defined(LIBASSERT_HAS_BUILTIN_IS_CONSTANT_EVALUATED) + #define LIBASSERT_HAS_BUILTIN_IS_CONSTANT_EVALUATED +#endif + + +// Visual Studio 2019 (19.25) and later supports __builtin_is_constant_evaluated +#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 192528326) + #define LIBASSERT_HAS_BUILTIN_IS_CONSTANT_EVALUATED +#endif + -// Add a helper function for support to C++20's std::is_constant_evaluated. -// Works with C++17 under GCC 9.1+, Clang 9+, and MSVC 19.25. namespace libassert::support { + /** + * @brief C++17 implementation of is_constant_evaluated that detects whether the function call occurs within a constant-evaluated context. Returns true if the evaluation of the call occurs within the evaluation of an expression or conversion that is manifestly constant-evaluated; otherwise returns false. + * @return true if the evaluation of the call occurs within the evaluation of an expression or conversion that is manifestly constant-evaluated; otherwise false. + * + * @note Works with C++17 under GCC 9.1+, Clang 9+, and MSVC 19.25. + */ constexpr bool is_constant_evaluated() noexcept { #if defined(LIBASSERT_HAS_IS_CONSTANT_EVALUATED) @@ -327,4 +340,4 @@ namespace libassert::support } -#endif // LIBASSERT_INTERNAL_HPP +#endif // LIBASSERT_PLATFORM_HPP From 0486f55f4de3da72216dee4e1438fb2d34da4253 Mon Sep 17 00:00:00 2001 From: ian Date: Sat, 4 May 2024 02:57:05 -0400 Subject: [PATCH 12/25] First initial wave of adjustments --- CMakeLists.txt | 2 +- include/libassert/assert.hpp | 4 ++-- include/libassert/platform.hpp | 19 +++++++++---------- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8f5f93ba..df5f03ef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -87,7 +87,7 @@ target_sources( ${target_name} PRIVATE # include include/libassert/assert.hpp - include/libassert/platform.hpp + include/libassert/platform.hpp ) # add /src files to target diff --git a/include/libassert/assert.hpp b/include/libassert/assert.hpp index ee7bd443..0c791b54 100644 --- a/include/libassert/assert.hpp +++ b/include/libassert/assert.hpp @@ -57,11 +57,11 @@ #define LIBASSERT_PHONY_USE(E) ((void)libassert::detail::always_false) #if LIBASSERT_IS_MSVC -#pragma warning(push) + #pragma warning(push) // warning C4251: using non-dll-exported type in dll-exported type, firing on std::vector and others for // some reason // 4275 is the same thing but for base classes -#pragma warning(disable: 4251; disable: 4275) + #pragma warning(disable: 4251; disable: 4275) #endif diff --git a/include/libassert/platform.hpp b/include/libassert/platform.hpp index 47b4f298..a158d861 100644 --- a/include/libassert/platform.hpp +++ b/include/libassert/platform.hpp @@ -125,7 +125,7 @@ #if LIBASSERT_HAS_CPP_ATTRIBUTE(likely) - #define LIBASSERT_LIKELY [[likely]] + #define LIBASSERT_ATTR_LIKELY [[likely]] #else #define LIBASSERT_ATTR_LIKELY #endif @@ -327,15 +327,14 @@ namespace libassert::support * * @note Works with C++17 under GCC 9.1+, Clang 9+, and MSVC 19.25. */ - constexpr bool is_constant_evaluated() noexcept - { -#if defined(LIBASSERT_HAS_IS_CONSTANT_EVALUATED) - return std::is_constant_evaluated(); -#elif defined(LIBASSERT_HAS_BUILTIN_IS_CONSTANT_EVALUATED) - return __builtin_is_constant_evaluated(); -#else - return false; -#endif + constexpr bool is_constant_evaluated() noexcept { + #if defined(LIBASSERT_HAS_IS_CONSTANT_EVALUATED) + return std::is_constant_evaluated(); + #elif defined(LIBASSERT_HAS_BUILTIN_IS_CONSTANT_EVALUATED) + return __builtin_is_constant_evaluated(); + #else + return false; + #endif } } From ef3d6d0e45582f95ae1709bca9c0c73efd6a7948 Mon Sep 17 00:00:00 2001 From: ian Date: Sun, 5 May 2024 14:57:08 -0400 Subject: [PATCH 13/25] Add C++20 to the CI --- .github/workflows/build.yml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 941a4dd8..13df6e19 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,6 +13,7 @@ jobs: fail-fast: false matrix: compiler: [g++-10, clang++-14] + cxx-version: [17, 20] target: [Debug, Release] steps: - uses: actions/checkout@v2 @@ -24,7 +25,8 @@ jobs: cd build cmake .. \ -DCMAKE_BUILD_TYPE=${{matrix.target}} \ - -DCMAKE_CXX_COMPILER=${{matrix.compiler}} + -DCMAKE_CXX_COMPILER=${{matrix.compiler}} \ + -DCMAKE_CXX_STANDARD=${{matrix.cxx-version}} make -j build-macos: runs-on: macos-14 @@ -33,6 +35,7 @@ jobs: matrix: compiler: [g++-12, clang++] c_compiler: [g++-12, clang++] + cxx_version: [17, 20] target: [Debug, Release] steps: - uses: actions/checkout@v2 @@ -42,7 +45,8 @@ jobs: cd build cmake .. \ -DCMAKE_BUILD_TYPE=${{matrix.target}} \ - -DCMAKE_CXX_COMPILER=${{matrix.compiler}} + -DCMAKE_CXX_COMPILER=${{matrix.compiler}} \ + -DCMAKE_CXX_STANDARD=${{matrix.cxx_version}} make -j build-windows: runs-on: windows-2022 @@ -50,6 +54,7 @@ jobs: fail-fast: false matrix: compiler: [cl, clang++] + cxx-version: [17, 20] target: [Debug, Release] steps: - uses: actions/checkout@v2 @@ -62,6 +67,7 @@ jobs: cmake .. ` -DCMAKE_BUILD_TYPE=${{matrix.target}} ` -DCMAKE_CXX_COMPILER=${{matrix.compiler}} ` + -DCMAKE_CXX_STANDARD=${{matrix.cxx_version}} ` msbuild .\libassert.sln build-mingw: runs-on: windows-2022 @@ -81,5 +87,6 @@ jobs: cmake .. ` -DCMAKE_BUILD_TYPE=${{matrix.target}} ` -DCMAKE_CXX_COMPILER=${{matrix.compiler}} ` + -DCMAKE_CXX_STANDARD=${{matrix.cxx_version}} ` "-GUnix Makefiles" make -j From 58a3bf149f265624e5d907c898eb83335fac2dd9 Mon Sep 17 00:00:00 2001 From: ian Date: Sun, 5 May 2024 15:06:34 -0400 Subject: [PATCH 14/25] Promote user generated static_asserts to the main header --- include/libassert/assert.hpp | 37 ++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/include/libassert/assert.hpp b/include/libassert/assert.hpp index 0c791b54..584a5620 100644 --- a/include/libassert/assert.hpp +++ b/include/libassert/assert.hpp @@ -1763,8 +1763,45 @@ namespace libassert { #define assert_val(expr, ...) LIBASSERT_INVOKE_VAL(expr, true, true, "assert_val", assertion, , __VA_ARGS__) #endif +// Wrapper macro to allow support for C++26's user generated static_assert messages. +// The backup message version also allows for the user to provide a backup version that will +// be used if the compiler does not support user generated messages. +// More info on user generated static_assert's +// can be found here: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2741r1.pdf +// +// Currently the functionality works as such. If we are in a C++26 environment, the user generated message will be used. +// If we are not in a C++26 environment, then either the static_assert will be used without a message or the backup message. +// TODO: Maybe give these a better name? Ideally one that is shorter and more descriptive? +// TODO: Maybe add a helper to make passing user generated static_assert messages easier? +#if defined(__cpp_static_assert) && __cpp_static_assert >= 202306L + #ifdef LIBASSERT_LOWERCASE + #define libassert_user_static_assert(cond, constant) static_assert(cond, constant) + #define libassert_user_static_assert_backup_msg(cond, msg, constant) static_assert(cond, constant) + #define user_static_assert(cond, constant) static_assert(cond, constant) + #define user_static_assert_backup_msg(cond, msg, constant) static_assert(cond, constant) + #else + #define LIBASSERT_USER_STATIC_ASSERT(cond, constant) static_assert(cond, constant) + #define LIBASSERT_USER_STATIC_ASSERT_BACKUP_MSG(cond, msg, constant) static_assert(cond, constant) + #define USER_STATIC_ASSERT(cond, constant) static_assert(cond, constant) + #define USER_STATIC_ASSERT_BACKUP_MSG(cond, msg, constant) static_assert(cond, constant) + #endif +#else + #ifdef LIBASSERT_LOWERCASE + #define libassert_user_static_assert(cond, constant) static_assert(cond) + #define libassert_user_static_assert_backup_msg(cond, msg, constant) static_assert(cond, msg) + #define user_static_assert(cond, constant) static_assert(cond) + #define user_static_assert_backup_msg(cond, msg, constant) static_assert(cond, msg) + #else + #define LIBASSERT_USER_STATIC_ASSERT(cond, constant) static_assert(cond) + #define LIBASSERT_USER_STATIC_ASSERT_BACKUP_MSG(cond, msg, constant) static_assert(cond, msg) + #define USER_STATIC_ASSERT(cond, constant) static_assert(cond) + #define USER_STATIC_ASSERT_BACKUP_MSG(cond, msg, constant) static_assert(cond, msg) + #endif #endif + +#endif // LIBASSERT_HPP + // Intentionally done outside the include guard. Libc++ leaks `assert` (among other things), so the include for // assert.hpp should go after other includes when using -DLIBASSERT_LOWERCASE. #ifdef LIBASSERT_LOWERCASE From ef9dbbdfcea0b37c6df5283c10d1448bf200ee70 Mon Sep 17 00:00:00 2001 From: ian Date: Sun, 5 May 2024 15:07:14 -0400 Subject: [PATCH 15/25] Bring in final changes to platform header --- include/libassert/platform.hpp | 83 ---------------------------------- 1 file changed, 83 deletions(-) diff --git a/include/libassert/platform.hpp b/include/libassert/platform.hpp index a158d861..81a46bd2 100644 --- a/include/libassert/platform.hpp +++ b/include/libassert/platform.hpp @@ -124,20 +124,6 @@ #endif -#if LIBASSERT_HAS_CPP_ATTRIBUTE(likely) - #define LIBASSERT_ATTR_LIKELY [[likely]] -#else - #define LIBASSERT_ATTR_LIKELY -#endif - - -#if LIBASSERT_HAS_CPP_ATTRIBUTE(unlikely) - #define LIBASSERT_ATTR_UNLIKELY [[unlikely]] -#else - #define LIBASSERT_ATTR_UNLIKELY -#endif - - #if LIBASSERT_HAS_CPP_ATTRIBUTE(no_unique_address) #define LIBASSERT_ATTR_NO_UNIQUE_ADDRESS [[no_unique_address]] #else @@ -145,75 +131,6 @@ #endif -/// -/// C++20 feature support. -/// - -#if defined(__cpp_conditional_explicit) && __cpp_conditional_explicit >= 201806L - #define LIBASSERT_CPP20_EXPLICIT_BOOL(expr) explicit(expr) -#else - #define LIBASSERT_CPP20_EXPLICIT_BOOL(expr) explicit -#endif - - -#if defined(__cpp_consteval) && __cpp_consteval >= 201811L - #define LIBASSERT_CONSTEVAL consteval -#else - #define LIBASSERT_CONSTEVAL constexpr -#endif - - -#if LIBASSERT_STD_VER >= 20 - #define LIBASSERT_CPP20_CONSTEXPR constexpr -#else - #define LIBASSERT_CPP20_CONSTEXPR -#endif - - -/// -/// C++23 feature support. -/// - -// Permit static constexpr variables in constexpr functions in C++23. -#if defined(__cpp_constexpr) && __cpp_constexpr >= 202211L - #define LIBASSERT_CONSTEXPR23_STATIC_VAR static constexpr -#else - #define LIBASSERT_CONSTEXPR23_STATIC_VAR constexpr -#endif - - -#if defined(__cpp_if_consteval) && __cpp_if_consteval >= 202106L - #define LIBASSERT_IF_CONSTEVAL if consteval -#else - #define LIBASSERT_IF_CONSTEVAL if constexpr -#endif - - -#if LIBASSERT_STD_VER >= 23 - #define LIBASSERT_CONSTEXPR23 constexpr -#else - #define LIBASSERT_CONSTEXPR23 -#endif - -/// -/// C++26 feature support. -/// - - -// Wrapper macro to allow support for C++26's user generated static_assert messages. -// The backup message version also allows for the user to provide a backup version that will -// be used if the compiler does not support user generated messages. -// More info on user generated static_assert's -// can be found here: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2741r1.pdf -#if defined(__cpp_static_assert) && __cpp_static_assert >= 202306L - #define LIBASSERT_USER_STATIC_ASSERT(cond, constant) static_assert(cond, constant) - #define LIBASSERT_USER_STATIC_ASSERT_BACKUP_MSG(cond, msg, constant) static_assert(cond, constant) -#else - #define LIBASSERT_USER_STATIC_ASSERT(cond, constant) static_assert(cond) - #define LIBASSERT_USER_STATIC_ASSERT_BACKUP_MSG(cond, msg, constant) static_assert(cond, msg) -#endif - - /// /// General project macros /// From 0b8159645327bdd48d1672267afbbfd1ee470d0c Mon Sep 17 00:00:00 2001 From: ian Date: Sun, 5 May 2024 15:44:59 -0400 Subject: [PATCH 16/25] Fix typo --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 13df6e19..377999ee 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -26,7 +26,7 @@ jobs: cmake .. \ -DCMAKE_BUILD_TYPE=${{matrix.target}} \ -DCMAKE_CXX_COMPILER=${{matrix.compiler}} \ - -DCMAKE_CXX_STANDARD=${{matrix.cxx-version}} + -DCMAKE_CXX_STANDARD=${{matrix.cxx_version}} make -j build-macos: runs-on: macos-14 From 9eb10cd191eca98ec29d6e41aa9910bc75ef06b9 Mon Sep 17 00:00:00 2001 From: ian Date: Sun, 5 May 2024 16:18:28 -0400 Subject: [PATCH 17/25] Remove duplicated macro --- include/libassert/platform.hpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/include/libassert/platform.hpp b/include/libassert/platform.hpp index 81a46bd2..0ca78282 100644 --- a/include/libassert/platform.hpp +++ b/include/libassert/platform.hpp @@ -95,13 +95,6 @@ #endif -#ifdef _MSVC_LANG - #define LIBASSERT_CPLUSPLUS _MSVC_LANG -#else - #define LIBASSERT_CPLUSPLUS __cplusplus -#endif - - /// /// Helper macros for compiler attributes. /// From e4320496678756ca26fad0539635d3228cdf4080 Mon Sep 17 00:00:00 2001 From: ian Date: Sun, 5 May 2024 16:18:56 -0400 Subject: [PATCH 18/25] Fix incorrect formatting --- include/libassert/assert.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/libassert/assert.hpp b/include/libassert/assert.hpp index 584a5620..17bb44f1 100644 --- a/include/libassert/assert.hpp +++ b/include/libassert/assert.hpp @@ -58,9 +58,9 @@ #if LIBASSERT_IS_MSVC #pragma warning(push) -// warning C4251: using non-dll-exported type in dll-exported type, firing on std::vector and others for -// some reason -// 4275 is the same thing but for base classes + // warning C4251: using non-dll-exported type in dll-exported type, firing on std::vector and others for + // some reason + // 4275 is the same thing but for base classes #pragma warning(disable: 4251; disable: 4275) #endif From c47c4f91978f1b5bc950c6eafba2e1c3b095a7df Mon Sep 17 00:00:00 2001 From: ian Date: Sun, 5 May 2024 16:28:37 -0400 Subject: [PATCH 19/25] Add the ability to pass feature flags for the desired std to libassert --- .github/workflows/build.yml | 10 +++++----- CMakeLists.txt | 4 +++- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 377999ee..e47cef65 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,7 +13,7 @@ jobs: fail-fast: false matrix: compiler: [g++-10, clang++-14] - cxx-version: [17, 20] + cxx-version: [cxx_std_17, cxx_std_20] target: [Debug, Release] steps: - uses: actions/checkout@v2 @@ -26,7 +26,7 @@ jobs: cmake .. \ -DCMAKE_BUILD_TYPE=${{matrix.target}} \ -DCMAKE_CXX_COMPILER=${{matrix.compiler}} \ - -DCMAKE_CXX_STANDARD=${{matrix.cxx_version}} + -DLIBASSERT_DESIRED_STD=${{matrix.cxx_version}} make -j build-macos: runs-on: macos-14 @@ -46,7 +46,7 @@ jobs: cmake .. \ -DCMAKE_BUILD_TYPE=${{matrix.target}} \ -DCMAKE_CXX_COMPILER=${{matrix.compiler}} \ - -DCMAKE_CXX_STANDARD=${{matrix.cxx_version}} + -DLIBASSERT_DESIRED_STD=${{matrix.cxx_version}} make -j build-windows: runs-on: windows-2022 @@ -67,7 +67,7 @@ jobs: cmake .. ` -DCMAKE_BUILD_TYPE=${{matrix.target}} ` -DCMAKE_CXX_COMPILER=${{matrix.compiler}} ` - -DCMAKE_CXX_STANDARD=${{matrix.cxx_version}} ` + -DLIBASSERT_DESIRED_STD=${{matrix.cxx_version}} ` msbuild .\libassert.sln build-mingw: runs-on: windows-2022 @@ -87,6 +87,6 @@ jobs: cmake .. ` -DCMAKE_BUILD_TYPE=${{matrix.target}} ` -DCMAKE_CXX_COMPILER=${{matrix.compiler}} ` - -DCMAKE_CXX_STANDARD=${{matrix.cxx_version}} ` + -DLIBASSERT_DESIRED_STD=${{matrix.cxx_version}} ` "-GUnix Makefiles" make -j diff --git a/CMakeLists.txt b/CMakeLists.txt index df5f03ef..6c2a6d61 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,6 +8,8 @@ include(cmake/PreventInSourceBuilds.cmake) # used to support find_package set(package_name "libassert") +set(LIBASSERT_DESIRED_STD "cxx_std_17" CACHE STRING "The C++ standard to use for libassert") + # create base project project( libassert @@ -156,7 +158,7 @@ target_include_directories( # require C++17 support target_compile_features( ${target_name} - PUBLIC cxx_std_17 + PUBLIC ${LIBASSERT_DESIRED_STD} ) if(LIBASSERT_SANITIZER_BUILD) From c229fe13061d6ae523366b2900f1dbd5675012f3 Mon Sep 17 00:00:00 2001 From: ian Date: Sun, 5 May 2024 16:32:50 -0400 Subject: [PATCH 20/25] Update to use option instead --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6c2a6d61..3d899c4b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ include(cmake/PreventInSourceBuilds.cmake) # used to support find_package set(package_name "libassert") -set(LIBASSERT_DESIRED_STD "cxx_std_17" CACHE STRING "The C++ standard to use for libassert") +option(LIBASSERT_DESIRED_STD "The C++ standard to use for libassert" "cxx_std_17") # create base project project( From 6a482eaf248d8a791357954786bd50a78d7a3b6f Mon Sep 17 00:00:00 2001 From: ian Date: Sun, 5 May 2024 17:10:45 -0400 Subject: [PATCH 21/25] Fix cmake commands and set variables for specified std --- .github/workflows/build.yml | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e47cef65..e1f16ab3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,8 +4,6 @@ on: push: pull_request: -# TODO: Check different standards? - jobs: build-linux: runs-on: ubuntu-22.04 @@ -13,7 +11,7 @@ jobs: fail-fast: false matrix: compiler: [g++-10, clang++-14] - cxx-version: [cxx_std_17, cxx_std_20] + cxx_version: [ cxx_std_17, cxx_std_20 ] target: [Debug, Release] steps: - uses: actions/checkout@v2 @@ -26,7 +24,7 @@ jobs: cmake .. \ -DCMAKE_BUILD_TYPE=${{matrix.target}} \ -DCMAKE_CXX_COMPILER=${{matrix.compiler}} \ - -DLIBASSERT_DESIRED_STD=${{matrix.cxx_version}} + -DCOMPILE_FEATURES="${{matrix.cxx_version}}" \ make -j build-macos: runs-on: macos-14 @@ -35,7 +33,7 @@ jobs: matrix: compiler: [g++-12, clang++] c_compiler: [g++-12, clang++] - cxx_version: [17, 20] + cxx_version: [ cxx_std_17, cxx_std_20 ] target: [Debug, Release] steps: - uses: actions/checkout@v2 @@ -46,7 +44,7 @@ jobs: cmake .. \ -DCMAKE_BUILD_TYPE=${{matrix.target}} \ -DCMAKE_CXX_COMPILER=${{matrix.compiler}} \ - -DLIBASSERT_DESIRED_STD=${{matrix.cxx_version}} + -DCOMPILE_FEATURES="${{matrix.cxx_version}}" \ make -j build-windows: runs-on: windows-2022 @@ -54,7 +52,7 @@ jobs: fail-fast: false matrix: compiler: [cl, clang++] - cxx-version: [17, 20] + cxx_version: [ cxx_std_17, cxx_std_20 ] target: [Debug, Release] steps: - uses: actions/checkout@v2 @@ -67,7 +65,7 @@ jobs: cmake .. ` -DCMAKE_BUILD_TYPE=${{matrix.target}} ` -DCMAKE_CXX_COMPILER=${{matrix.compiler}} ` - -DLIBASSERT_DESIRED_STD=${{matrix.cxx_version}} ` + -DCOMPILE_FEATURES="${{matrix.cxx_version}}" ` msbuild .\libassert.sln build-mingw: runs-on: windows-2022 @@ -75,6 +73,7 @@ jobs: fail-fast: false matrix: compiler: [g++] + cxx_version: [ cxx_std_17, cxx_std_20 ] target: [Debug, Release] steps: - uses: actions/checkout@v2 @@ -87,6 +86,6 @@ jobs: cmake .. ` -DCMAKE_BUILD_TYPE=${{matrix.target}} ` -DCMAKE_CXX_COMPILER=${{matrix.compiler}} ` - -DLIBASSERT_DESIRED_STD=${{matrix.cxx_version}} ` + -DCOMPILE_FEATURES="${{matrix.cxx_version}}" ` "-GUnix Makefiles" make -j From ba8204471a3e47b89cebf1f5663a78eff93eb8a4 Mon Sep 17 00:00:00 2001 From: ian Date: Sun, 5 May 2024 17:52:36 -0400 Subject: [PATCH 22/25] Add proper switching between cxx standards --- .github/workflows/build.yml | 8 ++++---- CMakeLists.txt | 20 ++++++++++++++------ 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e1f16ab3..4f0918ab 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,7 +24,7 @@ jobs: cmake .. \ -DCMAKE_BUILD_TYPE=${{matrix.target}} \ -DCMAKE_CXX_COMPILER=${{matrix.compiler}} \ - -DCOMPILE_FEATURES="${{matrix.cxx_version}}" \ + -DLIBASSERT_DESIRED_CXX_STANDARD="${{matrix.cxx_version}}" \ make -j build-macos: runs-on: macos-14 @@ -44,7 +44,7 @@ jobs: cmake .. \ -DCMAKE_BUILD_TYPE=${{matrix.target}} \ -DCMAKE_CXX_COMPILER=${{matrix.compiler}} \ - -DCOMPILE_FEATURES="${{matrix.cxx_version}}" \ + -DLIBASSERT_DESIRED_CXX_STANDARD="${{matrix.cxx_version}}" \ make -j build-windows: runs-on: windows-2022 @@ -65,7 +65,7 @@ jobs: cmake .. ` -DCMAKE_BUILD_TYPE=${{matrix.target}} ` -DCMAKE_CXX_COMPILER=${{matrix.compiler}} ` - -DCOMPILE_FEATURES="${{matrix.cxx_version}}" ` + -DLIBASSERT_DESIRED_CXX_STANDARD="${{matrix.cxx_version}}" ` msbuild .\libassert.sln build-mingw: runs-on: windows-2022 @@ -86,6 +86,6 @@ jobs: cmake .. ` -DCMAKE_BUILD_TYPE=${{matrix.target}} ` -DCMAKE_CXX_COMPILER=${{matrix.compiler}} ` - -DCOMPILE_FEATURES="${{matrix.cxx_version}}" ` + -DLIBASSERT_DESIRED_CXX_STANDARD="${{matrix.cxx_version}}" ` "-GUnix Makefiles" make -j diff --git a/CMakeLists.txt b/CMakeLists.txt index 3d899c4b..42a56961 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,6 @@ include(cmake/PreventInSourceBuilds.cmake) # used to support find_package set(package_name "libassert") -option(LIBASSERT_DESIRED_STD "The C++ standard to use for libassert" "cxx_std_17") # create base project project( @@ -155,11 +154,20 @@ target_include_directories( "$" ) -# require C++17 support -target_compile_features( - ${target_name} - PUBLIC ${LIBASSERT_DESIRED_STD} -) +# If the user has not defined a C++ standard, default to C++17 +if (NOT DEFINED LIBASSERT_DESIRED_CXX_STANDARD) + target_compile_features( + ${target_name} + PUBLIC cxx_std_17 + ) + message(STATUS "libassert: Using cxx_std_17 for target ${target_name}") +else() + target_compile_features( + ${target_name} + PUBLIC ${LIBASSERT_DESIRED_CXX_STANDARD} + ) + message(STATUS "libassert: Using ${LIBASSERT_DESIRED_CXX_STANDARD} for target ${target_name}") +endif() if(LIBASSERT_SANITIZER_BUILD) add_compile_options(-fsanitize=address) From 0a13f971b4a353f3a3767192d245bfb8a9fbf3a0 Mon Sep 17 00:00:00 2001 From: ian Date: Sun, 5 May 2024 17:58:25 -0400 Subject: [PATCH 23/25] Fix accidental chaining of make command --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4f0918ab..942c9bfa 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,7 +24,7 @@ jobs: cmake .. \ -DCMAKE_BUILD_TYPE=${{matrix.target}} \ -DCMAKE_CXX_COMPILER=${{matrix.compiler}} \ - -DLIBASSERT_DESIRED_CXX_STANDARD="${{matrix.cxx_version}}" \ + -DLIBASSERT_DESIRED_CXX_STANDARD="${{matrix.cxx_version}}" make -j build-macos: runs-on: macos-14 @@ -44,7 +44,7 @@ jobs: cmake .. \ -DCMAKE_BUILD_TYPE=${{matrix.target}} \ -DCMAKE_CXX_COMPILER=${{matrix.compiler}} \ - -DLIBASSERT_DESIRED_CXX_STANDARD="${{matrix.cxx_version}}" \ + -DLIBASSERT_DESIRED_CXX_STANDARD="${{matrix.cxx_version}}" make -j build-windows: runs-on: windows-2022 From d8545adbe7078481e78bfd31a5afbf68ead6689a Mon Sep 17 00:00:00 2001 From: Jeremy Rifkin <51220084+jeremy-rifkin@users.noreply.github.com> Date: Mon, 6 May 2024 19:31:06 -0500 Subject: [PATCH 24/25] Quick formatting/style fix --- include/libassert/platform.hpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/include/libassert/platform.hpp b/include/libassert/platform.hpp index 0ca78282..24b06afd 100644 --- a/include/libassert/platform.hpp +++ b/include/libassert/platform.hpp @@ -229,14 +229,8 @@ #endif -namespace libassert::support -{ - /** - * @brief C++17 implementation of is_constant_evaluated that detects whether the function call occurs within a constant-evaluated context. Returns true if the evaluation of the call occurs within the evaluation of an expression or conversion that is manifestly constant-evaluated; otherwise returns false. - * @return true if the evaluation of the call occurs within the evaluation of an expression or conversion that is manifestly constant-evaluated; otherwise false. - * - * @note Works with C++17 under GCC 9.1+, Clang 9+, and MSVC 19.25. - */ +namespace libassert::support { + // Note: Works with >C++20 and with C++17 for GCC 9.1+, Clang 9+, and MSVC 19.25+. constexpr bool is_constant_evaluated() noexcept { #if defined(LIBASSERT_HAS_IS_CONSTANT_EVALUATED) return std::is_constant_evaluated(); From cd729415a3d72be1961a3b5c2b3eac15ebf77d3d Mon Sep 17 00:00:00 2001 From: Jeremy Rifkin <51220084+jeremy-rifkin@users.noreply.github.com> Date: Mon, 6 May 2024 19:31:38 -0500 Subject: [PATCH 25/25] Oops --- include/libassert/platform.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/libassert/platform.hpp b/include/libassert/platform.hpp index 24b06afd..45d75dfb 100644 --- a/include/libassert/platform.hpp +++ b/include/libassert/platform.hpp @@ -230,7 +230,7 @@ namespace libassert::support { - // Note: Works with >C++20 and with C++17 for GCC 9.1+, Clang 9+, and MSVC 19.25+. + // Note: Works with >=C++20 and with C++17 for GCC 9.1+, Clang 9+, and MSVC 19.25+. constexpr bool is_constant_evaluated() noexcept { #if defined(LIBASSERT_HAS_IS_CONSTANT_EVALUATED) return std::is_constant_evaluated();