|
1 | 1 | /////////////////////////////////////////////////////////////////// |
2 | | -// Copyright Christopher Kormanyos 1999 - 2024. // |
| 2 | +// Copyright Christopher Kormanyos 1999 - 2025. // |
3 | 3 | // Distributed under the Boost Software License, // |
4 | 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt // |
5 | 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) // |
|
59 | 59 | #endif |
60 | 60 |
|
61 | 61 | #if (defined(_MSC_VER) && (!defined(__GNUC__) && !defined(__clang__))) |
62 | | - #if (_MSC_VER >= 1900) && defined(_HAS_CXX20) && (_HAS_CXX20 != 0) |
| 62 | + #if ((_MSC_VER >= 1900) && (defined(_HAS_CXX20) && (_HAS_CXX20 != 0))) |
63 | 63 | #define WIDE_INTEGER_NODISCARD [[nodiscard]] // NOLINT(cppcoreguidelines-macro-usage) |
64 | 64 | #else |
65 | 65 | #define WIDE_INTEGER_NODISCARD |
|
97 | 97 |
|
98 | 98 | namespace iterator_detail { |
99 | 99 |
|
100 | | - class input_iterator_tag {}; |
101 | | - class output_iterator_tag {}; |
102 | | - class forward_iterator_tag : public input_iterator_tag {}; |
103 | | - class bidirectional_iterator_tag : public forward_iterator_tag {}; |
104 | | - class random_access_iterator_tag : public bidirectional_iterator_tag {}; |
| 100 | + class input_iterator_tag { }; |
| 101 | + class output_iterator_tag { }; |
| 102 | + class forward_iterator_tag : public input_iterator_tag { }; |
| 103 | + class bidirectional_iterator_tag : public forward_iterator_tag { }; |
| 104 | + class random_access_iterator_tag : public bidirectional_iterator_tag { }; |
105 | 105 |
|
106 | 106 | template<typename iterator_type> |
107 | 107 | class iterator_traits |
|
166 | 166 | using reference = typename iterator_traits<iterator_type>::reference; |
167 | 167 | using iterator_category = typename iterator_traits<iterator_type>::iterator_category; |
168 | 168 |
|
169 | | - constexpr reverse_iterator() = default; |
| 169 | + constexpr reverse_iterator() { } // NOLINT(hicpp-use-equals-default,modernize-use-equals-default) |
170 | 170 |
|
171 | 171 | explicit constexpr reverse_iterator(iterator_type x) : current(x) { } |
172 | 172 |
|
|
218 | 218 | // Forward declaration of: |
219 | 219 | // Use a local, constexpr, unsafe implementation of the abs-function. |
220 | 220 | template<typename ArithmeticType> |
221 | | - constexpr auto abs_unsafe(ArithmeticType val) -> ArithmeticType; |
| 221 | + constexpr auto abs_unsafe(const ArithmeticType& val) -> ArithmeticType; |
222 | 222 |
|
223 | 223 | // Use a local, constexpr, unsafe implementation of the fill-function. |
224 | 224 | template<typename DestinationIterator, |
|
261 | 261 | #pragma GCC diagnostic ignored "-Wstringop-overflow" |
262 | 262 | #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" |
263 | 263 | #endif |
| 264 | + |
264 | 265 | *dest++ = static_cast<local_destination_value_type>(*first++); |
| 266 | + |
265 | 267 | #if (defined(__GNUC__) && (__GNUC__ > 9)) |
266 | 268 | #pragma GCC diagnostic pop |
267 | 269 | #pragma GCC diagnostic pop |
|
289 | 291 | template<typename T> |
290 | 292 | constexpr auto swap_unsafe(T& left, T& right) noexcept -> void |
291 | 293 | { |
292 | | - auto tmp = static_cast<T&&>(left); |
| 294 | + T tmp { std::move(static_cast<T&&>(left)) }; |
293 | 295 |
|
294 | | - left = static_cast<T&&>(right); |
295 | | - right = static_cast<T&&>(tmp); |
| 296 | + left = std::move(static_cast<T&&>(right)); |
| 297 | + right = std::move(static_cast<T&&>(tmp)); |
296 | 298 | } |
297 | 299 |
|
298 | 300 | template<typename InputIt, typename UnaryPredicate> |
|
738 | 740 | // Constructors. |
739 | 741 | constexpr dynamic_array() = delete; |
740 | 742 |
|
741 | | - explicit constexpr dynamic_array( size_type count_in, |
742 | | - const_reference value_in = value_type(), |
743 | | - const allocator_type& alloc_in = allocator_type()) |
| 743 | + explicit constexpr dynamic_array(size_type count_in, |
| 744 | + const_reference value_in = value_type(), |
| 745 | + const allocator_type& alloc_in = allocator_type()) |
744 | 746 | : elem_count(count_in) |
745 | 747 | { |
746 | 748 | if(elem_count > static_cast<size_type>(UINT8_C(0))) |
|
779 | 781 |
|
780 | 782 | template<typename input_iterator> |
781 | 783 | constexpr dynamic_array(input_iterator first, |
782 | | - input_iterator last, |
783 | | - const allocator_type& alloc_in = allocator_type()) |
| 784 | + input_iterator last, |
| 785 | + const allocator_type& alloc_in = allocator_type()) |
784 | 786 | : elem_count(static_cast<size_type>(last - first)) |
785 | 787 | { |
786 | 788 | allocator_type my_alloc(alloc_in); |
|
799 | 801 | } |
800 | 802 |
|
801 | 803 | constexpr dynamic_array(std::initializer_list<value_type> lst, |
802 | | - const allocator_type& alloc_in = allocator_type()) |
| 804 | + const allocator_type& alloc_in = allocator_type()) |
803 | 805 | : elem_count(lst.size()) |
804 | 806 | { |
805 | 807 | allocator_type my_alloc(alloc_in); |
|
818 | 820 |
|
819 | 821 | // Move constructor. |
820 | 822 | constexpr dynamic_array(dynamic_array&& other) noexcept : elem_count(other.elem_count), |
821 | | - elems (other.elems) |
| 823 | + elems (other.elems) |
822 | 824 | { |
823 | 825 | other.elem_count = static_cast<size_type>(UINT8_C(0)); |
824 | 826 | other.elems = nullptr; |
|
943 | 945 |
|
944 | 946 | constexpr auto swap(dynamic_array&& other) noexcept -> void |
945 | 947 | { |
946 | | - const auto tmp = std::move(*this); |
| 948 | + dynamic_array tmp { std::move(*this) }; |
947 | 949 |
|
948 | | - *this = std::move(other); |
949 | | - other = std::move(tmp); |
| 950 | + *this = std::move(static_cast<dynamic_array&&>(other)); |
| 951 | + other = std::move(static_cast<dynamic_array&&>(tmp)); |
950 | 952 | } |
951 | 953 |
|
952 | 954 | private: |
|
972 | 974 |
|
973 | 975 | template<typename ValueType, typename AllocatorType> |
974 | 976 | constexpr auto operator<(const dynamic_array<ValueType, AllocatorType>& lhs, |
975 | | - const dynamic_array<ValueType, AllocatorType>& rhs) -> bool |
| 977 | + const dynamic_array<ValueType, AllocatorType>& rhs) -> bool |
976 | 978 | { |
977 | 979 | using size_type = typename dynamic_array<ValueType, AllocatorType>::size_type; |
978 | 980 |
|
|
1106 | 1108 | using size_t = std::uint32_t; |
1107 | 1109 | using ptrdiff_t = std::int32_t; |
1108 | 1110 |
|
1109 | | - static_assert(( (std::numeric_limits<size_t>::digits >= std::numeric_limits<std::uint16_t>::digits) |
1110 | | - && (std::numeric_limits<ptrdiff_t>::digits + 1 >= std::numeric_limits<std::uint16_t>::digits)), |
| 1111 | + static_assert(( (std::numeric_limits<size_t>::digits >= std::numeric_limits<std::uint16_t>::digits) |
| 1112 | + && (std::numeric_limits<ptrdiff_t>::digits + 1 >= std::numeric_limits<std::uint16_t>::digits)), |
1111 | 1113 | "Error: size type and pointer difference type must be at least 16 bits in width (or wider)"); |
1112 | 1114 |
|
1113 | 1115 | template<const size_t Width2> struct verify_power_of_two // NOLINT(altera-struct-pack-align) |
|
2109 | 2111 | static_assert(((sizeof(limb_type) * 2U) == sizeof(double_limb_type)), |
2110 | 2112 | "Error: Please check the characteristics of the template parameters UnsignedShortType and UnsignedLargeType"); |
2111 | 2113 | #else |
2112 | | - static_assert(( ( std::numeric_limits<limb_type>::is_integer) |
2113 | | - && ( std::numeric_limits<double_limb_type>::is_integer) |
2114 | | - && (!std::numeric_limits<limb_type>::is_signed) |
2115 | | - && (!std::numeric_limits<double_limb_type>::is_signed) |
2116 | | - && ((sizeof(limb_type) * 2U) == sizeof(double_limb_type))), |
| 2114 | + static_assert(( ( std::numeric_limits<limb_type>::is_integer) |
| 2115 | + && ( std::numeric_limits<double_limb_type>::is_integer) |
| 2116 | + && (!std::numeric_limits<limb_type>::is_signed) |
| 2117 | + && (!std::numeric_limits<double_limb_type>::is_signed) |
| 2118 | + && ((sizeof(limb_type) * 2U) == sizeof(double_limb_type))), |
2117 | 2119 | "Error: Please check the characteristics of the template parameters UnsignedShortType and UnsignedLargeType"); |
2118 | 2120 | #endif |
2119 | 2121 |
|
|
4963 | 4965 |
|
4964 | 4966 | for(auto t = static_cast<double_limb_type>(u_j_j1 - static_cast<double_limb_type>(q_hat * static_cast<double_limb_type>(vv_at_vj0))); |
4965 | 4967 | ; |
4966 | | - --q_hat, t = static_cast<double_limb_type>(t + vv_at_vj0)) |
| 4968 | + t = static_cast<double_limb_type>(t + vv_at_vj0), --q_hat) |
4967 | 4969 | { |
4968 | 4970 | if( (detail::make_hi<limb_type>(t) != static_cast<limb_type>(UINT8_C(0))) |
4969 | 4971 | || ( static_cast<double_limb_type>(static_cast<double_limb_type>(vv_at_vj0_minus_one) * q_hat) |
|
6608 | 6610 |
|
6609 | 6611 | // Use a local, constexpr, unsafe implementation of the abs-function. |
6610 | 6612 | template<typename ArithmeticType> |
6611 | | - constexpr auto abs_unsafe(ArithmeticType val) -> ArithmeticType |
| 6613 | + constexpr auto abs_unsafe(const ArithmeticType& val) -> ArithmeticType |
6612 | 6614 | { |
6613 | 6615 | if(val > static_cast<int>(INT8_C(0))) |
6614 | 6616 | { |
6615 | 6617 | return val; |
6616 | 6618 | } |
6617 | 6619 | else // NOLINT(llvm-else-after-return,readability-else-after-return) |
6618 | 6620 | { |
6619 | | - ArithmeticType val_unsigned = std::move(val); |
| 6621 | + ArithmeticType val_unsigned { val }; |
6620 | 6622 |
|
6621 | 6623 | val_unsigned.negate(); |
6622 | 6624 |
|
|
6869 | 6871 |
|
6870 | 6872 | template<typename GeneratorType, |
6871 | 6873 | const int GeneratorResultBits = std::numeric_limits<typename GeneratorType::result_type>::digits> |
6872 | | - constexpr auto operator()( GeneratorType& input_generator, |
6873 | | - const param_type& input_params) -> result_type |
| 6874 | + constexpr auto operator()(GeneratorType& input_generator, |
| 6875 | + const param_type& input_params) -> result_type |
6874 | 6876 | { |
6875 | 6877 | return |
6876 | 6878 | generate<GeneratorType, GeneratorResultBits> |
|
6885 | 6887 |
|
6886 | 6888 | template<typename GeneratorType, |
6887 | 6889 | const int GeneratorResultBits = std::numeric_limits<typename GeneratorType::result_type>::digits> |
6888 | | - constexpr auto generate( GeneratorType& input_generator, |
6889 | | - const param_type& input_params) const -> result_type |
| 6890 | + constexpr auto generate(GeneratorType& input_generator, |
| 6891 | + const param_type& input_params) const -> result_type |
6890 | 6892 | { |
6891 | 6893 | // Generate random numbers r, where a <= r <= b. |
6892 | 6894 |
|
|
6994 | 6996 | // This Miller-Rabin primality test is loosely based on |
6995 | 6997 | // an adaptation of some code from Boost.Multiprecision. |
6996 | 6998 | // The Boost.Multiprecision code can be found here: |
6997 | | - // https://www.boost.org/doc/libs/1_76_0/libs/multiprecision/doc/html/boost_multiprecision/tut/primetest.html |
| 6999 | + // https://www.boost.org/doc/libs/1_87_0/libs/multiprecision/doc/html/boost_multiprecision/tut/primetest.html |
6998 | 7000 |
|
6999 | 7001 | // Note: Some comments in this subroutine use the Wolfram Language(TM). |
7000 | 7002 | // These can be exercised at the web links to WolframAlpha(R) provided |
|
7131 | 7133 | } |
7132 | 7134 | } |
7133 | 7135 |
|
7134 | | - const auto nm1 = static_cast<local_wide_integer_type>(np - static_cast<unsigned>(UINT8_C(1))); |
| 7136 | + const local_wide_integer_type nm1 { np - static_cast<unsigned>(UINT8_C(1)) }; |
7135 | 7137 |
|
7136 | 7138 | auto |
7137 | | - isone |
| 7139 | + local_functor_isone |
7138 | 7140 | { |
7139 | 7141 | [](const local_wide_integer_type& t1) |
7140 | 7142 | { |
|
7155 | 7157 |
|
7156 | 7158 | const local_wide_integer_type fn { powm(local_wide_integer_type(static_cast<local_limb_type>(228U)), nm1, np) }; |
7157 | 7159 |
|
7158 | | - if(!isone(fn)) |
| 7160 | + if(!local_functor_isone(fn)) |
7159 | 7161 | { |
7160 | 7162 | return false; |
7161 | 7163 | } |
|
7174 | 7176 | np - unsigned { UINT8_C(2) } |
7175 | 7177 | }; |
7176 | 7178 |
|
7177 | | - local_wide_integer_type x; |
7178 | | - local_wide_integer_type y; |
7179 | | - |
7180 | 7179 | // Assume the test will pass, even though it usually does not pass. |
7181 | | - bool result { true }; |
7182 | | - |
7183 | | - // Loop over the trials to perform the primality testing. |
| 7180 | + bool result_candidate_is_prime { true }; |
7184 | 7181 |
|
7185 | 7182 | std::size_t idx { UINT8_C(0) }; |
7186 | 7183 |
|
7187 | | - do |
7188 | | - { |
7189 | | - x = distribution(generator, params); |
7190 | | - y = powm(x, q, np); |
| 7184 | + using local_double_width_type = typename local_wide_integer_type::double_width_type; |
7191 | 7185 |
|
7192 | | - using local_double_width_type = typename local_wide_integer_type::double_width_type; |
| 7186 | + const local_double_width_type np_dbl { np }; |
7193 | 7187 |
|
7194 | | - const local_double_width_type np_dbl { np }; |
| 7188 | + // Loop over the trials to perform the primality testing. |
| 7189 | + do |
| 7190 | + { |
| 7191 | + local_wide_integer_type y { powm(distribution(generator, params), q, np) }; |
7195 | 7192 |
|
7196 | 7193 | std::size_t jdx { UINT8_C(0) }; |
7197 | 7194 |
|
7198 | 7195 | // Continue while y is not nm1, and while y is not 1, |
7199 | 7196 | // and while the result is true. |
7200 | 7197 |
|
7201 | | - while((y != nm1) && (!isone(y)) && result) // NOLINT(altera-id-dependent-backward-branch) |
| 7198 | + while((y != nm1) && (!local_functor_isone(y)) && result_candidate_is_prime) // NOLINT(altera-id-dependent-backward-branch) |
7202 | 7199 | { |
7203 | 7200 | ++jdx; |
7204 | 7201 |
|
7205 | 7202 | if(jdx == static_cast<std::size_t>(k)) |
7206 | 7203 | { |
7207 | 7204 | // Mark failure if max iterations reached. |
7208 | | - result = false; |
| 7205 | + result_candidate_is_prime = false; |
7209 | 7206 | } |
7210 | 7207 | else |
7211 | 7208 | { |
7212 | 7209 | // Continue with the next value of y. |
7213 | 7210 |
|
7214 | | - // Manually calculate: |
7215 | | - // y = powm(y, 2, np); |
| 7211 | + // Manually calculate: y = powm(y, 2, np); |
7216 | 7212 |
|
7217 | 7213 | local_double_width_type yd { y }; |
7218 | 7214 |
|
|
7224 | 7220 | } |
7225 | 7221 |
|
7226 | 7222 | // Check for (y == 1) after the loop. |
7227 | | - if(isone(y) && (jdx != std::size_t { UINT8_C(0) })) |
| 7223 | + if(local_functor_isone(y) && (jdx != std::size_t { UINT8_C(0) })) |
7228 | 7224 | { |
7229 | 7225 | // Mark failure if (y == 1) and (jdx != 0). |
7230 | | - result = false; |
| 7226 | + result_candidate_is_prime = false; |
7231 | 7227 | } |
7232 | 7228 |
|
7233 | 7229 | ++idx; |
7234 | 7230 | } |
7235 | | - while((idx < number_of_trials) && result); |
| 7231 | + while((idx < number_of_trials) && result_candidate_is_prime); |
7236 | 7232 |
|
7237 | | - return result; |
| 7233 | + return result_candidate_is_prime; |
7238 | 7234 | } |
7239 | 7235 |
|
7240 | 7236 | #if (defined(__cpp_lib_to_chars) && (__cpp_lib_to_chars >= 201611L)) |
7241 | 7237 | template<const size_t Width2, |
7242 | 7238 | typename LimbType, |
7243 | 7239 | typename AllocatorType, |
7244 | 7240 | const bool IsSigned> |
7245 | | - constexpr |
7246 | | - auto to_chars(char* first, |
7247 | | - char* last, |
7248 | | - const uintwide_t<Width2, LimbType, AllocatorType, IsSigned>& x, |
7249 | | - int base) -> std::to_chars_result |
| 7241 | + constexpr auto to_chars(char* first, |
| 7242 | + char* last, |
| 7243 | + const uintwide_t<Width2, LimbType, AllocatorType, IsSigned>& x, |
| 7244 | + int base) -> std::to_chars_result |
7250 | 7245 | { |
7251 | 7246 | using local_wide_integer_type = uintwide_t<Width2, LimbType, AllocatorType, IsSigned>; |
7252 | 7247 |
|
|
7406 | 7401 | typename LimbType, |
7407 | 7402 | typename AllocatorType, |
7408 | 7403 | const bool IsSigned> |
7409 | | - constexpr |
7410 | | - auto from_chars(const char* first, |
7411 | | - const char* last, |
7412 | | - uintwide_t<Width2, LimbType, AllocatorType, IsSigned>& x, |
7413 | | - int base) -> std::from_chars_result |
| 7404 | + constexpr auto from_chars(const char* first, |
| 7405 | + const char* last, |
| 7406 | + uintwide_t<Width2, LimbType, AllocatorType, IsSigned>& x, |
| 7407 | + int base) -> std::from_chars_result |
7414 | 7408 | { |
7415 | 7409 | using local_wide_integer_type = uintwide_t<Width2, LimbType, AllocatorType, IsSigned>; |
7416 | 7410 |
|
|
0 commit comments