diff --git a/.github/workflows/wide_integer_sonar.yml b/.github/workflows/wide_integer_sonar.yml index 4e305f6..d1d1e23 100644 --- a/.github/workflows/wide_integer_sonar.yml +++ b/.github/workflows/wide_integer_sonar.yml @@ -32,7 +32,7 @@ jobs: uses: SonarSource/sonarqube-scan-action/install-build-wrapper@v6.0.0 - name: Run Build Wrapper run: | - build-wrapper-linux-x86-64 --out-dir ${{ runner.workspace }}/build_wrapper_output_directory g++ -finline-functions -m64 -O3 -Werror -Wall -Wextra -Wconversion -Wsign-conversion -std=c++14 -DWIDE_INTEGER_HAS_LIMB_TYPE_UINT64 -DWIDE_INTEGER_HAS_MUL_8_BY_8_UNROLL -I. -I../boost-root -pthread -lpthread test/test.cpp test/test_uintwide_t_boost_backend.cpp test/test_uintwide_t_edge_cases.cpp test/test_uintwide_t_examples.cpp test/test_uintwide_t_float_convert.cpp test/test_uintwide_t_int_convert.cpp test/test_uintwide_t_n_base.cpp test/test_uintwide_t_n_binary_ops_base.cpp test/test_uintwide_t_spot_values.cpp examples/example000_numeric_limits.cpp examples/example000a_builtin_convert.cpp examples/example001_mul_div.cpp examples/example001a_div_mod.cpp examples/example002_shl_shr.cpp examples/example003_sqrt.cpp examples/example003a_cbrt.cpp examples/example004_rootk_pow.cpp examples/example005_powm.cpp examples/example005a_pow_factors_of_p99.cpp examples/example006_gcd.cpp examples/example007_random_generator.cpp examples/example008_miller_rabin_prime.cpp examples/example008a_miller_rabin_prime.cpp examples/example008b_solovay_strassen_prime.cpp examples/example009_timed_mul.cpp examples/example009a_timed_mul_4_by_4.cpp examples/example009b_timed_mul_8_by_8.cpp examples/example010_uint48_t.cpp examples/example011_uint24_t.cpp examples/example012_rsa_crypto.cpp examples/example013_ecdsa_sign_verify.cpp examples/example014_pi_spigot_wide.cpp -o wide_integer.exe + build-wrapper-linux-x86-64 --out-dir ${{ runner.workspace }}/build_wrapper_output_directory g++ -finline-functions -m64 -O3 -Werror -Wall -Wextra -Wpedantic -Wconversion -Wsign-conversion -std=c++14 -DWIDE_INTEGER_HAS_LIMB_TYPE_UINT64 -DWIDE_INTEGER_HAS_MUL_8_BY_8_UNROLL -I. -I../boost-root -pthread -lpthread test/test.cpp test/test_uintwide_t_boost_backend.cpp test/test_uintwide_t_edge_cases.cpp test/test_uintwide_t_examples.cpp test/test_uintwide_t_float_convert.cpp test/test_uintwide_t_int_convert.cpp test/test_uintwide_t_n_base.cpp test/test_uintwide_t_n_binary_ops_base.cpp test/test_uintwide_t_spot_values.cpp examples/example000_numeric_limits.cpp examples/example000a_builtin_convert.cpp examples/example001_mul_div.cpp examples/example001a_div_mod.cpp examples/example002_shl_shr.cpp examples/example003_sqrt.cpp examples/example003a_cbrt.cpp examples/example004_rootk_pow.cpp examples/example005_powm.cpp examples/example005a_pow_factors_of_p99.cpp examples/example006_gcd.cpp examples/example007_random_generator.cpp examples/example008_miller_rabin_prime.cpp examples/example008a_miller_rabin_prime.cpp examples/example008b_solovay_strassen_prime.cpp examples/example009_timed_mul.cpp examples/example009a_timed_mul_4_by_4.cpp examples/example009b_timed_mul_8_by_8.cpp examples/example010_uint48_t.cpp examples/example011_uint24_t.cpp examples/example012_rsa_crypto.cpp examples/example013_ecdsa_sign_verify.cpp examples/example014_pi_spigot_wide.cpp -o wide_integer.exe - name: SonarQube Scan uses: SonarSource/sonarqube-scan-action@v6.0.0 env: diff --git a/math/wide_integer/uintwide_t.h b/math/wide_integer/uintwide_t.h index d7da0a6..7c9a714 100644 --- a/math/wide_integer/uintwide_t.h +++ b/math/wide_integer/uintwide_t.h @@ -718,7 +718,9 @@ while(it != end()) { - *it++ = value_in; + std::allocator_traits::construct(my_alloc, it, value_in); + + ++it; } } } @@ -739,9 +741,9 @@ } } - template - constexpr dynamic_array(input_iterator first, - input_iterator last, + template + constexpr dynamic_array(InputIterator first, + InputIterator last, const allocator_type& alloc_in = allocator_type()) : elem_count(static_cast(last - first)), my_alloc(alloc_in) @@ -784,6 +786,28 @@ other.elems = nullptr; } + // Destructor. + virtual ~dynamic_array() + { + if(!empty()) + { + // The destructors of the elements are called (in unspecified order) + // and the dynamically allocated storage (if any) is deallocated. + + for(auto* itr { begin() }; itr != end(); ++itr) // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) + { + itr->~value_type(); + } + + using local_allocator_traits_type = std::allocator_traits; + + local_allocator_traits_type::deallocate(my_alloc, elems, elem_count); + + elem_count = static_cast(UINT8_C(0)); + elems = nullptr; + } + } + // Assignment operator. constexpr auto operator=(const dynamic_array& other) -> dynamic_array& { @@ -801,9 +825,9 @@ #else other.elems + ::math::wide_integer::detail::min_unsafe #endif - ( - elem_count, other.elem_count - ), + ( + elem_count, other.elem_count + ), elems ); } @@ -834,45 +858,23 @@ return *this; } - // Destructor. - virtual ~dynamic_array() - { - if(!empty()) - { - // The destructors of the elements are called (in unspecified order) - // and the dynamically allocated storage (if any) is deallocated. - - for(auto* itr { begin() }; itr != end(); ++itr) // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) - { - itr->~value_type(); - } - - using local_allocator_traits_type = std::allocator_traits; - - local_allocator_traits_type::deallocate(my_alloc, elems, elem_count); - - elem_count = static_cast(UINT8_C(0)); - elems = nullptr; - } - } - // Iterator members: - WIDE_INTEGER_NODISCARD constexpr auto begin () -> iterator { return elems; } - WIDE_INTEGER_NODISCARD constexpr auto end () -> iterator { return elems + elem_count; } - WIDE_INTEGER_NODISCARD constexpr auto begin () const -> const_iterator { return elems; } - WIDE_INTEGER_NODISCARD constexpr auto end () const -> const_iterator { return elems + elem_count; } - WIDE_INTEGER_NODISCARD constexpr auto cbegin () const -> const_iterator { return elems; } - WIDE_INTEGER_NODISCARD constexpr auto cend () const -> const_iterator { return elems + elem_count; } - WIDE_INTEGER_NODISCARD constexpr auto rbegin () -> reverse_iterator { return reverse_iterator(elems + elem_count); } - WIDE_INTEGER_NODISCARD constexpr auto rend () -> reverse_iterator { return reverse_iterator(elems); } - WIDE_INTEGER_NODISCARD constexpr auto rbegin () const -> const_reverse_iterator { return const_reverse_iterator(elems + elem_count); } - WIDE_INTEGER_NODISCARD constexpr auto rend () const -> const_reverse_iterator { return const_reverse_iterator(elems); } - WIDE_INTEGER_NODISCARD constexpr auto crbegin() const -> const_reverse_iterator { return const_reverse_iterator(elems + elem_count); } - WIDE_INTEGER_NODISCARD constexpr auto crend () const -> const_reverse_iterator { return const_reverse_iterator(elems); } + WIDE_INTEGER_NODISCARD constexpr auto begin () noexcept -> iterator { return elems; } + WIDE_INTEGER_NODISCARD constexpr auto end () noexcept -> iterator { return elems + elem_count; } + WIDE_INTEGER_NODISCARD constexpr auto begin () const noexcept -> const_iterator { return elems; } + WIDE_INTEGER_NODISCARD constexpr auto end () const noexcept -> const_iterator { return elems + elem_count; } + WIDE_INTEGER_NODISCARD constexpr auto cbegin () const noexcept -> const_iterator { return elems; } + WIDE_INTEGER_NODISCARD constexpr auto cend () const noexcept -> const_iterator { return elems + elem_count; } + WIDE_INTEGER_NODISCARD constexpr auto rbegin () noexcept -> reverse_iterator { return reverse_iterator(elems + elem_count); } + WIDE_INTEGER_NODISCARD constexpr auto rend () noexcept -> reverse_iterator { return reverse_iterator(elems); } + WIDE_INTEGER_NODISCARD constexpr auto rbegin () const noexcept -> const_reverse_iterator { return const_reverse_iterator(elems + elem_count); } + WIDE_INTEGER_NODISCARD constexpr auto rend () const noexcept -> const_reverse_iterator { return const_reverse_iterator(elems); } + WIDE_INTEGER_NODISCARD constexpr auto crbegin() const noexcept -> const_reverse_iterator { return const_reverse_iterator(elems + elem_count); } + WIDE_INTEGER_NODISCARD constexpr auto crend () const noexcept -> const_reverse_iterator { return const_reverse_iterator(elems); } // Raw pointer access. - WIDE_INTEGER_NODISCARD constexpr auto data() -> pointer { return elems; } - WIDE_INTEGER_NODISCARD constexpr auto data() const -> const_pointer { return elems; } + WIDE_INTEGER_NODISCARD constexpr auto data() noexcept -> pointer { return elems; } + WIDE_INTEGER_NODISCARD constexpr auto data() const noexcept -> const_pointer { return elems; } // Size and capacity. WIDE_INTEGER_NODISCARD constexpr auto size () const noexcept -> size_type { return elem_count; } @@ -880,17 +882,17 @@ WIDE_INTEGER_NODISCARD constexpr auto empty () const noexcept -> bool { return (elem_count == static_cast(UINT8_C(0))); } // Element access members. - WIDE_INTEGER_NODISCARD constexpr auto operator[](const size_type i) -> reference { return elems[i]; } - WIDE_INTEGER_NODISCARD constexpr auto operator[](const size_type i) const -> const_reference { return elems[i]; } + WIDE_INTEGER_NODISCARD constexpr auto operator[](const size_type i) noexcept -> reference { return elems[i]; } + WIDE_INTEGER_NODISCARD constexpr auto operator[](const size_type i) const noexcept -> const_reference { return elems[i]; } - WIDE_INTEGER_NODISCARD constexpr auto front() -> reference { return elems[static_cast(UINT8_C(0))]; } - WIDE_INTEGER_NODISCARD constexpr auto front() const -> const_reference { return elems[static_cast(UINT8_C(0))]; } + WIDE_INTEGER_NODISCARD constexpr auto front() noexcept -> reference { return elems[static_cast(UINT8_C(0))]; } + WIDE_INTEGER_NODISCARD constexpr auto front() const noexcept -> const_reference { return elems[static_cast(UINT8_C(0))]; } - WIDE_INTEGER_NODISCARD constexpr auto back() -> reference { return ((elem_count > static_cast(UINT8_C(0))) ? elems[static_cast(elem_count - static_cast(UINT8_C(1)))] : elems[static_cast(UINT8_C(0))]); } - WIDE_INTEGER_NODISCARD constexpr auto back() const -> const_reference { return ((elem_count > static_cast(UINT8_C(0))) ? elems[static_cast(elem_count - static_cast(UINT8_C(1)))] : elems[static_cast(UINT8_C(0))]); } + WIDE_INTEGER_NODISCARD constexpr auto back() noexcept -> reference { return ((elem_count > static_cast(UINT8_C(0))) ? elems[static_cast(elem_count - static_cast(UINT8_C(1)))] : elems[static_cast(UINT8_C(0))]); } + WIDE_INTEGER_NODISCARD constexpr auto back() const noexcept -> const_reference { return ((elem_count > static_cast(UINT8_C(0))) ? elems[static_cast(elem_count - static_cast(UINT8_C(1)))] : elems[static_cast(UINT8_C(0))]); } - WIDE_INTEGER_NODISCARD constexpr auto at(const size_type i) -> reference { return ((i < elem_count) ? elems[i] : elems[static_cast(UINT8_C(0))]); } - WIDE_INTEGER_NODISCARD constexpr auto at(const size_type i) const -> const_reference { return ((i < elem_count) ? elems[i] : elems[static_cast(UINT8_C(0))]); } + WIDE_INTEGER_NODISCARD constexpr auto at(const size_type i) noexcept -> reference { return ((i < elem_count) ? elems[i] : elems[static_cast(UINT8_C(0))]); } + WIDE_INTEGER_NODISCARD constexpr auto at(const size_type i) const noexcept -> const_reference { return ((i < elem_count) ? elems[i] : elems[static_cast(UINT8_C(0))]); } // Element manipulation members. constexpr auto fill(const value_type& value_in) -> void @@ -1622,7 +1624,7 @@ const allocator_type& alloc_in = allocator_type()) : base_class_type(static_size(), value_in, alloc_in) { - // This parameter is specifically ignored. + // This parameter is explicitly and purposely ignored. static_cast(size_in); } @@ -1649,7 +1651,12 @@ constexpr auto operator=(const fixed_dynamic_array&) -> fixed_dynamic_array& = default; - constexpr auto operator=(fixed_dynamic_array&&) noexcept -> fixed_dynamic_array& = default; + constexpr auto operator=(fixed_dynamic_array&& other) noexcept -> fixed_dynamic_array& + { + base_class_type::operator=(static_cast(other)); + + return *this; + } }; template