diff --git a/graphs/HungarianAlgorithm/config_macros.hpp b/graphs/HungarianAlgorithm/config_macros.hpp index b0d916f..14a6ba3 100644 --- a/graphs/HungarianAlgorithm/config_macros.hpp +++ b/graphs/HungarianAlgorithm/config_macros.hpp @@ -428,7 +428,7 @@ #endif #if defined(__clang__) -#define CONFIG_CLANG_NONNULL_QUALIFIER _Nonnull +#define CONFIG_CLANG_NONNULL_QUALIFIER _Nonnull #define CONFIG_CLANG_NULLABLE_QUALIFIER _Nullable #else #define CONFIG_CLANG_NONNULL_QUALIFIER @@ -609,11 +609,12 @@ namespace config { template ATTRIBUTE_ALWAYS_INLINE constexpr bool is_gcc_constant_p(ATTRIBUTE_MAYBE_UNUSED T expr) noexcept { +#if CONFIG_HAS_BUILTIN(__builtin_constant_p) #if CONFIG_HAS_INCLUDE() + // not std::is_trivial_v for backward compatibility with old compilers C++ versions static_assert(std::is_trivial::value, "Type passed to the is_gcc_constant_p() should be trivial"); #endif -#if CONFIG_HAS_BUILTIN(__builtin_constant_p) return static_cast(__builtin_constant_p(expr)); #else return false; diff --git a/number_theory/config_macros.hpp b/number_theory/config_macros.hpp index c30bf44..14a6ba3 100644 --- a/number_theory/config_macros.hpp +++ b/number_theory/config_macros.hpp @@ -609,11 +609,12 @@ namespace config { template ATTRIBUTE_ALWAYS_INLINE constexpr bool is_gcc_constant_p(ATTRIBUTE_MAYBE_UNUSED T expr) noexcept { +#if CONFIG_HAS_BUILTIN(__builtin_constant_p) #if CONFIG_HAS_INCLUDE() + // not std::is_trivial_v for backward compatibility with old compilers C++ versions static_assert(std::is_trivial::value, "Type passed to the is_gcc_constant_p() should be trivial"); #endif -#if CONFIG_HAS_BUILTIN(__builtin_constant_p) return static_cast(__builtin_constant_p(expr)); #else return false; diff --git a/number_theory/longint.hpp b/number_theory/longint.hpp index df17998..aaa091f 100644 --- a/number_theory/longint.hpp +++ b/number_theory/longint.hpp @@ -24,17 +24,16 @@ #endif #include "math_functions.hpp" -#if !defined(__GNUG__) -// cppcheck-suppress [preprocessorErrorDirective] -#error "Current implementation works only with GCC" -#endif - #if defined(ENABLE_LONGINT_DEBUG_ASSERTS) && ENABLE_LONGINT_DEBUG_ASSERTS #define LONGINT_DEBUG_ASSERT(expr) assert(expr) #else #define LONGINT_DEBUG_ASSERT(expr) #endif +#if defined(__GNUG__) || defined(__clang__) + +#define HAS_CUSTOM_LONGINT_ALLOCATOR 1 + namespace longint_allocator { // #define DEBUG_LI_ALLOC_PRINTING 1 @@ -271,6 +270,10 @@ ATTRIBUTE_ALLOC_SIZE(1) INLINE_LONGINT_ALLOCATE void* Allocate(std::size_t size) } // namespace longint_allocator +#else +#define HAS_CUSTOM_LONGINT_ALLOCATOR 0 +#endif + namespace longint_detail { struct longint_static_storage; } @@ -780,7 +783,7 @@ struct longint { } } #if defined(INTEGERS_128_BIT_HPP) - [[nodiscard]] ATTRIBUTE_PURE constexpr bool operator==(uint128_t n) const noexcept { + [[nodiscard]] ATTRIBUTE_PURE I128_CONSTEXPR bool operator==(uint128_t n) const noexcept { if ((config::is_constant_evaluated() || config::is_gcc_constant_p(n)) && n == 0) { return iszero(); } @@ -806,7 +809,7 @@ struct longint { return false; } } - [[nodiscard]] ATTRIBUTE_PURE constexpr bool operator==(int128_t n) const noexcept { + [[nodiscard]] ATTRIBUTE_PURE I128_CONSTEXPR bool operator==(int128_t n) const noexcept { if ((config::is_constant_evaluated() || config::is_gcc_constant_p(n)) && n == 0) { return iszero(); } @@ -905,10 +908,10 @@ struct longint { return !(*this == n); } #if defined(INTEGERS_128_BIT_HPP) - [[nodiscard]] ATTRIBUTE_PURE constexpr bool operator!=(uint128_t n) const noexcept { + [[nodiscard]] ATTRIBUTE_PURE I128_CONSTEXPR bool operator!=(uint128_t n) const noexcept { return !(*this == n); } - [[nodiscard]] ATTRIBUTE_PURE constexpr bool operator!=(int128_t n) const noexcept { + [[nodiscard]] ATTRIBUTE_PURE I128_CONSTEXPR bool operator!=(int128_t n) const noexcept { return !(*this == n); } #endif @@ -1173,7 +1176,7 @@ struct longint { return static_cast(size()) <= 4; } [[nodiscard]] - ATTRIBUTE_ALWAYS_INLINE ATTRIBUTE_PURE constexpr uint128_t to_uint128() const noexcept { + ATTRIBUTE_ALWAYS_INLINE ATTRIBUTE_PURE I128_CONSTEXPR uint128_t to_uint128() const noexcept { uint128_t value = 0; static_assert(kNumsBits == 32); switch (usize()) { @@ -1199,7 +1202,7 @@ struct longint { } return value; } - [[nodiscard]] ATTRIBUTE_ALWAYS_INLINE ATTRIBUTE_PURE /* implicit */ constexpr + [[nodiscard]] ATTRIBUTE_ALWAYS_INLINE ATTRIBUTE_PURE /* implicit */ I128_CONSTEXPR operator uint128_t() const noexcept { return to_uint128(); } @@ -1865,7 +1868,11 @@ struct longint { }; private: +#if HAS_CUSTOM_LONGINT_ALLOCATOR + static constexpr bool kUseCustomLongIntAllocator = false; +#else static constexpr bool kUseCustomLongIntAllocator = false; +#endif struct LongIntNaive final { ATTRIBUTE_SIZED_ACCESS(read_only, 1, 2) @@ -1905,7 +1912,9 @@ struct longint { 2 * max_size()); poly_size_type n = 2 * math_functions::nearest_greater_equal_power_of_two(product_size); const bool need_high_precision = n > kFFTPrecisionBorder; - n <<= need_high_precision; + if (need_high_precision) { + n *= 2; + } LONGINT_DEBUG_ASSERT(math_functions::is_power_of_two(n)); ATTRIBUTE_ASSUME(math_functions::is_power_of_two(n)); return {n, need_high_precision}; @@ -2041,7 +2050,10 @@ struct longint { p++; } } - const size_type complex_nums_filled = (2 * k) << need_high_precision; + size_type complex_nums_filled = (2 * k); + if (need_high_precision) { + complex_nums_filled *= 2; + } std::memset(static_cast(p), 0, (n - complex_nums_filled) * sizeof(fft::complex)); } @@ -2099,7 +2111,10 @@ struct longint { p++; } } - const size_type complex_nums_filled = (2 * nums_size) << need_high_precision; + size_type complex_nums_filled = (2 * nums_size); + if (need_high_precision) { + complex_nums_filled *= 2; + } std::memset(static_cast(p), 0, (n - complex_nums_filled) * sizeof(fft::complex)); } }; @@ -2569,7 +2584,7 @@ struct longint { allocate_default_capacity_128(); } } - constexpr void assign_u128_unchecked(uint128_t n) noexcept { + I128_CONSTEXPR void assign_u128_unchecked(uint128_t n) noexcept { size_ = n != 0; nums_[0] = static_cast(n); n >>= 32; @@ -2582,7 +2597,7 @@ struct longint { size_ += n != 0; nums_[3] = static_cast(n); } - constexpr void assign_i128_unchecked(int128_t n) noexcept { + I128_CONSTEXPR void assign_i128_unchecked(int128_t n) noexcept { const std::int32_t sgn = math_functions::sign(n); assign_u128_unchecked(math_functions::uabs(n)); size_ *= sgn; @@ -2720,16 +2735,22 @@ struct longint { } ATTRIBUTE_ALWAYS_INLINE static digit_t* allocate(std::size_t nums) { +#if HAS_CUSTOM_LONGINT_ALLOCATOR if constexpr (kUseCustomLongIntAllocator) { return static_cast(::longint_allocator::Allocate(nums * sizeof(digit_t))); - } else { + } else +#endif + { return static_cast(::operator new(nums * sizeof(digit_t))); } } ATTRIBUTE_ALWAYS_INLINE static void deallocate(digit_t* nums) noexcept { +#if HAS_CUSTOM_LONGINT_ALLOCATOR if constexpr (kUseCustomLongIntAllocator) { ::longint_allocator::Deallocate(static_cast(nums)); - } else { + } else +#endif + { ::operator delete(static_cast(nums)); } } @@ -2930,3 +2951,6 @@ inline void longint::set_str_impl(const unsigned char* str, const std::size_t st } set_ssize_from_size_and_sign(usize_value, sgn); } + +#undef HAS_CUSTOM_LONGINT_ALLOCATOR +#undef LONGINT_DEBUG_ASSERT diff --git a/number_theory/test_long_int.cpp b/number_theory/test_long_int.cpp index cbe1bc2..e599186 100644 --- a/number_theory/test_long_int.cpp +++ b/number_theory/test_long_int.cpp @@ -1691,7 +1691,9 @@ void TestDivMod() { test_tools::log_tests_started(); TestDivModImpl(); TestDivModImpl(); +#if defined(INTEGERS_128_BIT_HPP) && INTEGERS_128_BIT_HPP && (defined(__GNUG__) || defined(__clang__)) TestDivModImpl(); +#endif longint n; longint m; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 91ff0cb..7609765 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -166,30 +166,46 @@ function(configure_gcc_or_clang_gcc_options) ${LOCAL_FN_TEST_CXX_COMPILE_OPTIONS} -Warray-bounds -Warray-bounds-pointer-arithmetic - -Warray-parameter -Wshift-overflow -Wshift-sign-overflow -Wshorten-64-to-32 -Wthread-safety -Wnull-pointer-arithmetic - -Wnull-pointer-subtraction -Wnullable-to-nonnull-conversion -Wsometimes-uninitialized -Wstatic-in-inline -Wformat-pedantic -Wformat-type-confusion -Wfour-char-constants - -Wframe-address -Wgcc-compat -Wgnu -Widiomatic-parentheses -Wimplicit -Wimplicit-fallthrough - -Wincompatible-function-pointer-types-strict -Winconsistent-missing-destructor-override -fcolor-diagnostics -fansi-escape-codes -ftemplate-backtrace-limit=0) + if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 11.0.0) + set(LOCAL_FN_TEST_CXX_COMPILE_OPTIONS + ${LOCAL_FN_TEST_CXX_COMPILE_OPTIONS} + -Wframe-address) + endif() + if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 13.0.0) + set(LOCAL_FN_TEST_CXX_COMPILE_OPTIONS + ${LOCAL_FN_TEST_CXX_COMPILE_OPTIONS} + -Wnull-pointer-subtraction) + endif() + if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 15.0.0) + set(LOCAL_FN_TEST_CXX_COMPILE_OPTIONS + ${LOCAL_FN_TEST_CXX_COMPILE_OPTIONS} + -Warray-parameter) + endif() + if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 16.0.0) + set(LOCAL_FN_TEST_CXX_COMPILE_OPTIONS + ${LOCAL_FN_TEST_CXX_COMPILE_OPTIONS} + -Wincompatible-function-pointer-types-strict) + endif() set(LOCAL_FN_TEST_COMPILE_DEFINITIONS ${LOCAL_FN_TEST_COMPILE_DEFINITIONS} _LIBCPP_ENABLE_ASSERTIONS) @@ -455,7 +471,7 @@ if (NOT USING_MINGW_GCC_32) list(APPEND TestDirectories "number_theory") list(APPEND TestLangVersions "17 20 23 26") list(APPEND TestDependencies "") - if (LINUX) + if (LINUX AND (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU")) list(APPEND TestOptionalDependencies "mpfr") else() list(APPEND TestOptionalDependencies "") @@ -466,7 +482,7 @@ if (NOT USING_MINGW_GCC_32) list(APPEND TestDirectories "number_theory") list(APPEND TestLangVersions "17 20 23 26") list(APPEND TestDependencies "") - if (LINUX) + if (LINUX AND (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU")) list(APPEND TestOptionalDependencies "gmp") else() list(APPEND TestOptionalDependencies "") @@ -477,21 +493,19 @@ if (NOT USING_MINGW_GCC_32) list(APPEND TestDirectories "number_theory") list(APPEND TestLangVersions "17 20 23 26") list(APPEND TestDependencies "") - if (LINUX) + if (LINUX AND (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU")) list(APPEND TestOptionalDependencies "gmp gmpxx") else() list(APPEND TestOptionalDependencies "") endif() list(APPEND TestIsCProject False) - if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU") - list(APPEND TestFilenames "test_long_int.cpp") - list(APPEND TestDirectories "number_theory") - list(APPEND TestLangVersions "17 20 23 26") - list(APPEND TestDependencies "") - list(APPEND TestOptionalDependencies "") - list(APPEND TestIsCProject False) - endif() + list(APPEND TestFilenames "test_long_int.cpp") + list(APPEND TestDirectories "number_theory") + list(APPEND TestLangVersions "17 20 23 26") + list(APPEND TestDependencies "") + list(APPEND TestOptionalDependencies "") + list(APPEND TestIsCProject False) endif() list(APPEND TestFilenames "test_bitmatrix.cpp") diff --git a/tests/build_all_tests.sh b/tests/unix_build_all_tests.sh old mode 100755 new mode 100644 similarity index 100% rename from tests/build_all_tests.sh rename to tests/unix_build_all_tests.sh diff --git a/tests/windows_build_all_tests.bat b/tests/windows_build_all_tests.bat new file mode 100644 index 0000000..8b78059 --- /dev/null +++ b/tests/windows_build_all_tests.bat @@ -0,0 +1,29 @@ +set build_dir=cmake-build-tests-windows-clang-cl + +if not exist ".\%build_dir%" mkdir %build_dir% + +cd ".\%build_dir%" + +if %errorlevel% neq 0 exit /b %errorlevel% + +cmake -G "Visual Studio 17 2022" -A x64 -T ClangCL -S .. -B . +if %errorlevel% neq 0 exit /b %errorlevel% + +msbuild tests.sln -property:Configuration=RelWithDebInfo -noWarn:D9025 -warnaserror -maxcpucount:%NUMBER_OF_PROCESSORS% +if %errorlevel% neq 0 exit /b %errorlevel% + +cd .. + +set build_dir=cmake-build-tests-windows-msvc + +if not exist ".\%build_dir%" mkdir %build_dir% + +cd ".\%build_dir%" + +if %errorlevel% neq 0 exit /b %errorlevel% + +cmake -G "Visual Studio 17 2022" -A x64 -S .. -B . +if %errorlevel% neq 0 exit /b %errorlevel% + +msbuild tests.sln -property:Configuration=RelWithDebInfo -noWarn:D9025 -warnaserror -maxcpucount:%NUMBER_OF_PROCESSORS% +if %errorlevel% neq 0 exit /b %errorlevel% diff --git a/vec_instructs/config_macros.hpp b/vec_instructs/config_macros.hpp index 416efb2..14a6ba3 100644 --- a/vec_instructs/config_macros.hpp +++ b/vec_instructs/config_macros.hpp @@ -292,7 +292,7 @@ #define ATTRIBUTE_COLD #endif -#if CONFIG_GNUC_AT_LEAST(4, 4) || CONFIG_HAS_GCC_ATTRIBUTE(hot) +#if CONFIG_GNUC_AT_LEAST(4, 3) || CONFIG_HAS_GCC_ATTRIBUTE(hot) #define ATTRIBUTE_HOT __attribute__((hot)) #elif (defined(__GNUG__) || defined(__clang__)) && CONFIG_HAS_CPP_ATTRIBUTE(gnu::hot) #define ATTRIBUTE_HOT [[gnu::hot]] @@ -427,6 +427,14 @@ #define ATTRIBUTE_FALLTHROUGH #endif +#if defined(__clang__) +#define CONFIG_CLANG_NONNULL_QUALIFIER _Nonnull +#define CONFIG_CLANG_NULLABLE_QUALIFIER _Nullable +#else +#define CONFIG_CLANG_NONNULL_QUALIFIER +#define CONFIG_CLANG_NULLABLE_QUALIFIER +#endif + // Copypasted from LLVM's int_endianness.h /* ===-- int_endianness.h - configuration header for compiler-rt ------------=== @@ -601,11 +609,12 @@ namespace config { template ATTRIBUTE_ALWAYS_INLINE constexpr bool is_gcc_constant_p(ATTRIBUTE_MAYBE_UNUSED T expr) noexcept { +#if CONFIG_HAS_BUILTIN(__builtin_constant_p) #if CONFIG_HAS_INCLUDE() + // not std::is_trivial_v for backward compatibility with old compilers C++ versions static_assert(std::is_trivial::value, "Type passed to the is_gcc_constant_p() should be trivial"); #endif -#if CONFIG_HAS_BUILTIN(__builtin_constant_p) return static_cast(__builtin_constant_p(expr)); #else return false;