From d6ef61adc05edd059a1a4a779803eb92673a7d6b Mon Sep 17 00:00:00 2001 From: Christopher Kormanyos Date: Sat, 27 Jan 2024 12:08:32 +0100 Subject: [PATCH 1/4] Update and sync --- .github/workflows/codeql.yml | 4 +- .github/workflows/real-time-cpp-examples.yml | 12 +- .github/workflows/real-time-cpp-snippets.yml | 8 +- .github/workflows/real-time-cpp-sonar.yml | 4 +- .github/workflows/real-time-cpp.yml | 44 +- ref_app/src/math/wide_integer/uintwide_t.h | 1067 ++++++++--------- ref_app/src/mcal/mcal_reg_access_static.h | 3 +- ref_app/src/util/STL/charconv | 12 +- .../atmega2560/make/atmega2560_flags.gmk | 6 +- .../atmega4809/make/atmega4809_flags.gmk | 6 +- ref_app/target/micros/avr/make/avr_flags.gmk | 6 +- .../v850es_fx2/make/v850es_fx2_flags.gmk | 4 +- .../v850es_fx2/startup/crt0_init_ram.cpp | 14 +- 13 files changed, 583 insertions(+), 607 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 2b2464b5f..806bf6dc9 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -1,5 +1,5 @@ # ------------------------------------------------------------------------------ -# Copyright Christopher Kormanyos 2022. +# Copyright Christopher Kormanyos 2022 - 2024. # Distributed under the Boost Software License, # Version 1.0. (See accompanying file LICENSE_1_0.txt # or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -29,7 +29,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Configure (cpp) if: ${{ matrix.language == 'cpp' }} diff --git a/.github/workflows/real-time-cpp-examples.yml b/.github/workflows/real-time-cpp-examples.yml index 75d34823e..f31e134a4 100644 --- a/.github/workflows/real-time-cpp-examples.yml +++ b/.github/workflows/real-time-cpp-examples.yml @@ -1,5 +1,5 @@ ############################################################################## -# Copyright Christopher Kormanyos 2023. +# Copyright Christopher Kormanyos 2023 - 2024. # Distributed under the Boost Software License, # Version 1.0. (See accompanying file LICENSE_1_0.txt # or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -23,7 +23,7 @@ jobs: matrix: example: [ chapter02_02, chapter02_06 ] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: '0' - name: update-tools @@ -44,7 +44,7 @@ jobs: matrix: example: [ chapter02_03, chapter02_03a, chapter03_02, chapter04_04, chapter04_04a, chapter06_01, chapter06_14, chapter09_07, chapter09_08, chapter09_08a, chapter10_08, chapter10_08a, chapter11_07, chapter12_04, chapter16_08, chapter17_03, chapter17_03a ] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: '0' - name: update-tools @@ -65,7 +65,7 @@ jobs: matrix: example: [ chapter10_09 ] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: '0' - name: update-tools @@ -83,7 +83,7 @@ jobs: matrix: example: [ chapter02_03, chapter02_03a, chapter03_02, chapter04_04, chapter04_04a, chapter06_01, chapter06_14, chapter09_07, chapter09_08, chapter09_08a, chapter10_08, chapter10_08a, chapter10_09, chapter11_07, chapter12_04, chapter17_03, chapter17_03a ] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: '0' - uses: ilammy/msvc-dev-cmd@v1 @@ -102,7 +102,7 @@ jobs: matrix: example: [ chapter16_08 ] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: clone-boost-develop working-directory: ${{ runner.workspace }} run: | diff --git a/.github/workflows/real-time-cpp-snippets.yml b/.github/workflows/real-time-cpp-snippets.yml index 508aed02e..76cf26c4e 100644 --- a/.github/workflows/real-time-cpp-snippets.yml +++ b/.github/workflows/real-time-cpp-snippets.yml @@ -1,5 +1,5 @@ ############################################################################## -# Copyright Christopher Kormanyos 2023. +# Copyright Christopher Kormanyos 2023 - 2024. # Distributed under the Boost Software License, # Version 1.0. (See accompanying file LICENSE_1_0.txt # or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -24,7 +24,7 @@ jobs: chapter: [ appendix0a, chapter01, chapter03, chapter04, chapter05, chapter07, chapter08, chapter09, chapter12, chapter16, chapter17 ] compiler: [ g++, clang++ ] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: '0' - name: host-snippets-all @@ -43,7 +43,7 @@ jobs: chapter: [ chapter06 ] compiler: [ g++, clang++ ] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: '0' - name: clone-submods-bootstrap-headers-boost-develop @@ -77,7 +77,7 @@ jobs: chapter: [ chapter10 ] compiler: [ g++, clang++ ] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: '0' - name: clone-submods-bootstrap-headers-boost-develop diff --git a/.github/workflows/real-time-cpp-sonar.yml b/.github/workflows/real-time-cpp-sonar.yml index 5bbb685d2..059681f01 100644 --- a/.github/workflows/real-time-cpp-sonar.yml +++ b/.github/workflows/real-time-cpp-sonar.yml @@ -1,5 +1,5 @@ # ------------------------------------------------------------------------------ -# Copyright Christopher Kormanyos 2022 - 2023. +# Copyright Christopher Kormanyos 2022 - 2024. # Distributed under the Boost Software License, # Version 1.0. (See accompanying file LICENSE_1_0.txt # or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -21,7 +21,7 @@ jobs: SONAR_SERVER_URL: "https://sonarcloud.io" BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up JDK 17 diff --git a/.github/workflows/real-time-cpp.yml b/.github/workflows/real-time-cpp.yml index 80a77705e..25b38e298 100644 --- a/.github/workflows/real-time-cpp.yml +++ b/.github/workflows/real-time-cpp.yml @@ -1,5 +1,5 @@ ############################################################################## -# Copyright Christopher Kormanyos 2021 - 2023. +# Copyright Christopher Kormanyos 2021 - 2024. # Distributed under the Boost Software License, # Version 1.0. (See accompanying file LICENSE_1_0.txt # or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -24,7 +24,7 @@ jobs: standard: [ c++14 ] compiler: [ g++, clang++ ] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: '0' - name: update-tools @@ -51,7 +51,7 @@ jobs: matrix: suite: [ avr, atmega2560 ] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: '0' - name: update-tools @@ -71,7 +71,7 @@ jobs: matrix: suite: [ avr, atmega2560 ] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: '0' - name: update-tools @@ -91,7 +91,7 @@ jobs: matrix: suite: [ avr, atmega2560 ] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: '0' - name: clone-osx-cross-homebrew-avr @@ -135,7 +135,7 @@ jobs: matrix: suite: [ am335x, bcm2835_raspi_b, lpc11c24, nxp_imxrt1062, stm32f100, stm32f407, stm32f429, stm32f446, stm32h7a3, stm32l100c, stm32l152 ] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: '0' - name: update-tools @@ -155,7 +155,7 @@ jobs: matrix: suite: [ am335x, bcm2835_raspi_b, lpc11c24, nxp_imxrt1062, stm32f100, stm32f407, stm32f429, stm32f446, stm32h7a3, stm32l100c, stm32l152 ] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: '0' - name: update-tools @@ -175,7 +175,7 @@ jobs: matrix: suite: [ am335x, bcm2835_raspi_b, lpc11c24, nxp_imxrt1062, stm32f100, stm32f407, stm32f429, stm32f446, stm32h7a3, stm32l100c, stm32l152 ] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: '0' - name: wget-macos-gnu-arm-toolchain @@ -215,7 +215,7 @@ jobs: matrix: suite: [ riscvfe310 ] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: '0' - name: update-tools @@ -232,7 +232,7 @@ jobs: target-x86_64: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: '0' - name: build-target-x86_64-w64-mingw32 @@ -244,7 +244,7 @@ jobs: target-host-cmake: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: '0' - name: build-target-host @@ -266,7 +266,7 @@ jobs: matrix: suite: [ Debug, Release ] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: '0' - uses: ilammy/msvc-dev-cmd@v1 @@ -288,7 +288,7 @@ jobs: compiler: [ g++, clang++ ] standard: [ c++14, c++17, c++2a ] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: '0' - name: clone-submods-bootstrap-headers-boost-develop @@ -316,7 +316,7 @@ jobs: compiler: [ g++-8, g++-9, clang++-8, clang++-9 ] standard: [ c++14, c++17 ] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: '0' - name: update-tools @@ -346,7 +346,7 @@ jobs: compiler: [ g++-10, clang++-10 ] standard: [ c++14, c++17, c++20 ] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: '0' - name: update-tools @@ -373,7 +373,7 @@ jobs: compiler: [ g++, clang++ ] standard: [ c++14, c++17, c++2a ] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: '0' - name: clone-submods-bootstrap-headers-boost-develop @@ -400,7 +400,7 @@ jobs: matrix: standard: [ c++14 ] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: '0' - name: update-tools @@ -418,7 +418,7 @@ jobs: matrix: standard: [ c++14, c++17, c++2a ] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: '0' - name: update-tools @@ -443,7 +443,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: '0' - name: update-tools @@ -466,7 +466,7 @@ jobs: compiler: [ g++, clang++ ] standard: [ c++20 ] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: '0' - name: benchmark_single-cnl @@ -483,7 +483,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: '0' - name: update-tools @@ -520,7 +520,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: '0' - name: update-tools diff --git a/ref_app/src/math/wide_integer/uintwide_t.h b/ref_app/src/math/wide_integer/uintwide_t.h index 1422ddc5b..92e9f42bc 100644 --- a/ref_app/src/math/wide_integer/uintwide_t.h +++ b/ref_app/src/math/wide_integer/uintwide_t.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 1999 - 2023. // +// Copyright Christopher Kormanyos 1999 - 2024. // // Distributed under the Boost Software License, // // Version 1.0. (See accompanying file LICENSE_1_0.txt // // or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -59,76 +59,18 @@ #if (defined(_MSC_VER) && (!defined(__GNUC__) && !defined(__clang__))) #if (_MSC_VER >= 1900) && defined(_HAS_CXX20) && (_HAS_CXX20 != 0) - #define WIDE_INTEGER_NODISCARD [[nodiscard]] // NOLINT(cppcoreguidelines-macro-usage) + #define WIDE_INTEGER_NODISCARD [[nodiscard]] // NOLINT(cppcoreguidelines-macro-usage) #else #define WIDE_INTEGER_NODISCARD #endif #else - #if (defined(__cplusplus) && (__cplusplus >= 201402L)) - #if defined(__AVR__) && (!defined(__GNUC__) || (defined(__GNUC__) && (__cplusplus >= 202002L))) - #define WIDE_INTEGER_NODISCARD [[nodiscard]] // NOLINT(cppcoreguidelines-macro-usage) - #elif (defined(__cpp_lib_constexpr_algorithms) && (__cpp_lib_constexpr_algorithms >= 201806)) - #if defined(__clang__) - #if (__clang_major__ > 9) - #define WIDE_INTEGER_NODISCARD [[nodiscard]] // NOLINT(cppcoreguidelines-macro-usage) - #else - #define WIDE_INTEGER_NODISCARD - #endif - #else - #define WIDE_INTEGER_NODISCARD [[nodiscard]] // NOLINT(cppcoreguidelines-macro-usage) - #endif - #elif (defined(__clang__) && (__clang_major__ >= 10)) && (defined(__cplusplus) && (__cplusplus > 201703L)) - #if defined(__x86_64__) - #define WIDE_INTEGER_NODISCARD [[nodiscard]] // NOLINT(cppcoreguidelines-macro-usage) - #else - #define WIDE_INTEGER_NODISCARD - #endif - #else - #define WIDE_INTEGER_NODISCARD - #endif + #if ((defined(__cplusplus) && (__cplusplus >= 201703L)) && (defined(__has_cpp_attribute) && (__has_cpp_attribute(nodiscard) >= 201603L))) + #define WIDE_INTEGER_NODISCARD [[nodiscard]] // NOLINT(cppcoreguidelines-macro-usage) #else #define WIDE_INTEGER_NODISCARD #endif #endif - // 201703L - - #if defined(_MSVC_LANG) - #if (_MSVC_LANG >= 201402L) - #define WIDE_INTEGER_CONSTEXPR constexpr // NOLINT(cppcoreguidelines-macro-usage) - #define WIDE_INTEGER_CONSTEXPR_IS_COMPILE_TIME_CONST 1 // NOLINT(cppcoreguidelines-macro-usage) - #else - #define WIDE_INTEGER_CONSTEXPR // NOLINT(cppcoreguidelines-macro-usage) - #define WIDE_INTEGER_CONSTEXPR_IS_COMPILE_TIME_CONST 0 // NOLINT(cppcoreguidelines-macro-usage) - #endif - #else - #if (defined(__AVR__) && (defined(__GNUC__) && (__GNUC__ < 10))) - #define WIDE_INTEGER_CONSTEXPR // NOLINT(cppcoreguidelines-macro-usage) - #define WIDE_INTEGER_CONSTEXPR_IS_COMPILE_TIME_CONST 0 // NOLINT(cppcoreguidelines-macro-usage) - #elif (defined(__MINGW32__) && (defined(__GNUC__) && (__GNUC__ < 9))) - #define WIDE_INTEGER_CONSTEXPR // NOLINT(cppcoreguidelines-macro-usage) - #define WIDE_INTEGER_CONSTEXPR_IS_COMPILE_TIME_CONST 0 // NOLINT(cppcoreguidelines-macro-usage) - #else - #if (__cplusplus >= 201402L) - #define WIDE_INTEGER_CONSTEXPR constexpr // NOLINT(cppcoreguidelines-macro-usage) - #define WIDE_INTEGER_CONSTEXPR_IS_COMPILE_TIME_CONST 1 // NOLINT(cppcoreguidelines-macro-usage) - #else - #define WIDE_INTEGER_CONSTEXPR // NOLINT(cppcoreguidelines-macro-usage) - #define WIDE_INTEGER_CONSTEXPR_IS_COMPILE_TIME_CONST 0 // NOLINT(cppcoreguidelines-macro-usage) - #endif - #endif - #endif - - #if defined(WIDE_INTEGER_DISABLE_WIDE_INTEGER_CONSTEXPR) - #undef WIDE_INTEGER_CONSTEXPR - #define WIDE_INTEGER_CONSTEXPR - #undef WIDE_INTEGER_CONSTEXPR_IS_COMPILE_TIME_CONST - #define WIDE_INTEGER_CONSTEXPR_IS_COMPILE_TIME_CONST 0 - #if !defined(WIDE_INTEGER_DISABLE_TRIVIAL_COPY_AND_STD_LAYOUT_CHECKS) - #define WIDE_INTEGER_DISABLE_TRIVIAL_COPY_AND_STD_LAYOUT_CHECKS - #endif - #endif - #if defined(WIDE_INTEGER_NAMESPACE_BEGIN) || defined(WIDE_INTEGER_NAMESPACE_END) #error internal pre-processor macro already defined #endif @@ -272,12 +214,10 @@ } // namespace iterator_detail + // Forward declaration of: // Use a local, constexpr, unsafe implementation of the abs-function. template - constexpr auto abs_unsafe(ArithmeticType val) -> ArithmeticType - { - return ((val > static_cast(INT8_C(0))) ? val : -val); - } + constexpr auto abs_unsafe(ArithmeticType val) -> ArithmeticType; // Use a local, constexpr, unsafe implementation of the fill-function. template - constexpr auto do_distance(It first, It last, detail::iterator_detail::random_access_iterator_tag) -> typename detail::iterator_detail::iterator_traits::difference_type // NOLINT(hicpp-named-parameter,readability-named-parameter) + constexpr auto do_distance_unsafe(It first, It last, detail::iterator_detail::random_access_iterator_tag) -> typename detail::iterator_detail::iterator_traits::difference_type // NOLINT(hicpp-named-parameter,readability-named-parameter) { using local_difference_type = typename detail::iterator_detail::iterator_traits::difference_type; @@ -434,7 +374,7 @@ using local_iterator_category_type = typename iterator_detail::iterator_traits::iterator_category; return - distance_detail::do_distance + distance_detail::do_distance_unsafe ( first, last, @@ -792,9 +732,9 @@ #endif // Constructors. - constexpr dynamic_array() : elem_count(static_cast(UINT8_C(0))) { } + constexpr dynamic_array() = delete; - explicit WIDE_INTEGER_CONSTEXPR dynamic_array( size_type count_in, + explicit constexpr dynamic_array( size_type count_in, const_reference value_in = value_type(), const allocator_type& alloc_in = allocator_type()) : elem_count(count_in) @@ -816,7 +756,7 @@ } } - WIDE_INTEGER_CONSTEXPR dynamic_array(const dynamic_array& other) + constexpr dynamic_array(const dynamic_array& other) : elem_count(other.size()) { allocator_type my_alloc; @@ -834,7 +774,7 @@ } template - WIDE_INTEGER_CONSTEXPR dynamic_array(input_iterator first, + constexpr dynamic_array(input_iterator first, input_iterator last, const allocator_type& alloc_in = allocator_type()) : elem_count(static_cast(last - first)) @@ -854,7 +794,7 @@ } - WIDE_INTEGER_CONSTEXPR dynamic_array(std::initializer_list lst, + constexpr dynamic_array(std::initializer_list lst, const allocator_type& alloc_in = allocator_type()) : elem_count(lst.size()) { @@ -873,7 +813,7 @@ } // Move constructor. - WIDE_INTEGER_CONSTEXPR dynamic_array(dynamic_array&& other) noexcept : elem_count(other.elem_count), + constexpr dynamic_array(dynamic_array&& other) noexcept : elem_count(other.elem_count), elems (other.elems) { other.elem_count = static_cast(UINT8_C(0)); @@ -881,7 +821,7 @@ } // Destructor. - //WIDE_INTEGER_CONSTEXPR + //constexpr virtual ~dynamic_array() { if(!empty()) @@ -905,7 +845,7 @@ } // Assignment operator. - WIDE_INTEGER_CONSTEXPR auto operator=(const dynamic_array& other) -> dynamic_array& + constexpr auto operator=(const dynamic_array& other) -> dynamic_array& { if(this != &other) { @@ -924,7 +864,7 @@ } // Move assignment operator. - WIDE_INTEGER_CONSTEXPR auto operator=(dynamic_array&& other) noexcept -> dynamic_array& + constexpr auto operator=(dynamic_array&& other) noexcept -> dynamic_array& { #if defined(WIDE_INTEGER_NAMESPACE) WIDE_INTEGER_NAMESPACE::math::wide_integer::detail::swap_unsafe(elem_count, other.elem_count); @@ -938,22 +878,22 @@ } // Iterator members: - WIDE_INTEGER_CONSTEXPR auto begin () -> iterator { return elems; } - WIDE_INTEGER_CONSTEXPR auto end () -> iterator { return elems + elem_count; } - WIDE_INTEGER_CONSTEXPR auto begin () const -> const_iterator { return elems; } - WIDE_INTEGER_CONSTEXPR auto end () const -> const_iterator { return elems + elem_count; } - WIDE_INTEGER_CONSTEXPR auto cbegin () const -> const_iterator { return elems; } - WIDE_INTEGER_CONSTEXPR auto cend () const -> const_iterator { return elems + elem_count; } - WIDE_INTEGER_CONSTEXPR auto rbegin () -> reverse_iterator { return reverse_iterator(elems + elem_count); } - WIDE_INTEGER_CONSTEXPR auto rend () -> reverse_iterator { return reverse_iterator(elems); } - WIDE_INTEGER_CONSTEXPR auto rbegin () const -> const_reverse_iterator { return const_reverse_iterator(elems + elem_count); } - WIDE_INTEGER_CONSTEXPR auto rend () const -> const_reverse_iterator { return const_reverse_iterator(elems); } - WIDE_INTEGER_CONSTEXPR auto crbegin() const -> const_reverse_iterator { return const_reverse_iterator(elems + elem_count); } - WIDE_INTEGER_CONSTEXPR auto crend () const -> const_reverse_iterator { return const_reverse_iterator(elems); } + constexpr auto begin () -> iterator { return elems; } + constexpr auto end () -> iterator { return elems + elem_count; } + constexpr auto begin () const -> const_iterator { return elems; } + constexpr auto end () const -> const_iterator { return elems + elem_count; } + constexpr auto cbegin () const -> const_iterator { return elems; } + constexpr auto cend () const -> const_iterator { return elems + elem_count; } + constexpr auto rbegin () -> reverse_iterator { return reverse_iterator(elems + elem_count); } + constexpr auto rend () -> reverse_iterator { return reverse_iterator(elems); } + constexpr auto rbegin () const -> const_reverse_iterator { return const_reverse_iterator(elems + elem_count); } + constexpr auto rend () const -> const_reverse_iterator { return const_reverse_iterator(elems); } + constexpr auto crbegin() const -> const_reverse_iterator { return const_reverse_iterator(elems + elem_count); } + constexpr auto crend () const -> const_reverse_iterator { return const_reverse_iterator(elems); } // Raw pointer access. - WIDE_INTEGER_CONSTEXPR auto data() -> pointer { return elems; } - WIDE_INTEGER_CONSTEXPR auto data() const -> const_pointer { return elems; } + constexpr auto data() -> pointer { return elems; } + constexpr auto data() const -> const_pointer { return elems; } // Size and capacity. constexpr auto size () const -> size_type { return elem_count; } @@ -961,20 +901,20 @@ constexpr auto empty () const -> bool { return (elem_count == static_cast(UINT8_C(0))); } // Element access members. - WIDE_INTEGER_CONSTEXPR auto operator[](const size_type i) -> reference { return elems[i]; } - WIDE_INTEGER_CONSTEXPR auto operator[](const size_type i) const -> const_reference { return elems[i]; } + constexpr auto operator[](const size_type i) -> reference { return elems[i]; } + constexpr auto operator[](const size_type i) const -> const_reference { return elems[i]; } - WIDE_INTEGER_CONSTEXPR auto front() -> reference { return elems[static_cast(UINT8_C(0))]; } - WIDE_INTEGER_CONSTEXPR auto front() const -> const_reference { return elems[static_cast(UINT8_C(0))]; } + constexpr auto front() -> reference { return elems[static_cast(UINT8_C(0))]; } + constexpr auto front() const -> const_reference { return elems[static_cast(UINT8_C(0))]; } - WIDE_INTEGER_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_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))]); } + 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))]); } + 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_CONSTEXPR auto at(const size_type i) -> reference { return ((i < elem_count) ? elems[i] : elems[static_cast(UINT8_C(0))]); } - WIDE_INTEGER_CONSTEXPR auto at(const size_type i) const -> const_reference { return ((i < elem_count) ? elems[i] : elems[static_cast(UINT8_C(0))]); } + constexpr auto at(const size_type i) -> reference { return ((i < elem_count) ? elems[i] : elems[static_cast(UINT8_C(0))]); } + constexpr auto at(const size_type i) const -> const_reference { return ((i < elem_count) ? elems[i] : elems[static_cast(UINT8_C(0))]); } // Element manipulation members. - WIDE_INTEGER_CONSTEXPR auto fill(const value_type& value_in) -> void + constexpr auto fill(const value_type& value_in) -> void { #if defined(WIDE_INTEGER_NAMESPACE) WIDE_INTEGER_NAMESPACE::math::wide_integer::detail::fill_unsafe(begin(), begin() + elem_count, value_in); @@ -983,7 +923,7 @@ #endif } - WIDE_INTEGER_CONSTEXPR auto swap(dynamic_array& other) noexcept -> void + constexpr auto swap(dynamic_array& other) noexcept -> void { if(this != &other) { @@ -997,7 +937,7 @@ } } - WIDE_INTEGER_CONSTEXPR auto swap(dynamic_array&& other) noexcept -> void + constexpr auto swap(dynamic_array&& other) noexcept -> void { const auto tmp = std::move(*this); @@ -1027,7 +967,7 @@ } template - WIDE_INTEGER_CONSTEXPR auto operator<(const dynamic_array& lhs, + constexpr auto operator<(const dynamic_array& lhs, const dynamic_array& rhs) -> bool { using size_type = typename dynamic_array::size_type; @@ -1065,36 +1005,36 @@ } template - WIDE_INTEGER_CONSTEXPR auto operator!=(const dynamic_array& lhs, - const dynamic_array& rhs) -> bool + constexpr auto operator!=(const dynamic_array& lhs, + const dynamic_array& rhs) -> bool { return (!(lhs == rhs)); } template - WIDE_INTEGER_CONSTEXPR auto operator>(const dynamic_array& lhs, - const dynamic_array& rhs) -> bool + constexpr auto operator>(const dynamic_array& lhs, + const dynamic_array& rhs) -> bool { return (rhs < lhs); } template - WIDE_INTEGER_CONSTEXPR auto operator>=(const dynamic_array& lhs, - const dynamic_array& rhs) -> bool + constexpr auto operator>=(const dynamic_array& lhs, + const dynamic_array& rhs) -> bool { return (!(lhs < rhs)); } template - WIDE_INTEGER_CONSTEXPR auto operator<=(const dynamic_array& lhs, - const dynamic_array& rhs) -> bool + constexpr auto operator<=(const dynamic_array& lhs, + const dynamic_array& rhs) -> bool { return (!(rhs < lhs)); } template - WIDE_INTEGER_CONSTEXPR auto swap(dynamic_array& x, - dynamic_array& y) noexcept -> void + constexpr auto swap(dynamic_array& x, + dynamic_array& y) noexcept -> void { x.swap(y); } @@ -1226,17 +1166,17 @@ #if !defined(WIDE_INTEGER_DISABLE_FLOAT_INTEROP) namespace my_own { - template WIDE_INTEGER_CONSTEXPR auto frexp (FloatingPointType x, int* expptr) -> std::enable_if_t<(std::is_floating_point::value && std::numeric_limits::is_iec559 ), FloatingPointType>; - template WIDE_INTEGER_CONSTEXPR auto frexp (FloatingPointType x, int* expptr) -> std::enable_if_t<(std::is_floating_point::value && (!std::numeric_limits::is_iec559)), FloatingPointType>; - template WIDE_INTEGER_CONSTEXPR auto (isfinite)(FloatingPointType x) -> std::enable_if_t<(std::is_floating_point::value && std::numeric_limits::is_iec559 ), bool>; - template WIDE_INTEGER_CONSTEXPR auto (isfinite)(FloatingPointType x) -> std::enable_if_t<(std::is_floating_point::value && (!std::numeric_limits::is_iec559)), bool>; + template constexpr auto frexp (FloatingPointType x, int* expptr) -> std::enable_if_t<(std::is_floating_point::value && std::numeric_limits::is_iec559 ), FloatingPointType>; + template constexpr auto frexp (FloatingPointType x, int* expptr) -> std::enable_if_t<(std::is_floating_point::value && (!std::numeric_limits::is_iec559)), FloatingPointType>; + template constexpr auto (isfinite)(FloatingPointType x) -> std::enable_if_t<(std::is_floating_point::value && std::numeric_limits::is_iec559 ), bool>; + template constexpr auto (isfinite)(FloatingPointType x) -> std::enable_if_t<(std::is_floating_point::value && (!std::numeric_limits::is_iec559)), bool>; } // namespace my_own #endif template - WIDE_INTEGER_CONSTEXPR + constexpr auto import_export_helper( ForwardIterator in, OutputIterator out, const signed_fast_type total_bits_to_use, // NOLINT(bugprone-easily-swappable-parameters) @@ -1354,10 +1294,10 @@ uintwide_t>; template - WIDE_INTEGER_CONSTEXPR auto operator%(const uintwide_t& u, const IntegralType& v) -> std::enable_if_t<( std::is_integral ::value - && std::is_unsigned ::value - && (std::numeric_limits::digits <= std::numeric_limits::digits)), - typename uintwide_t::limb_type>; + constexpr auto operator%(const uintwide_t& u, const IntegralType& v) -> std::enable_if_t<( std::is_integral ::value + && std::is_unsigned ::value + && (std::numeric_limits::digits <= std::numeric_limits::digits)), + typename uintwide_t::limb_type>; template constexpr auto operator%(const uintwide_t& u, const IntegralType& v) -> std::enable_if_t<( std::is_integral ::value @@ -1472,20 +1412,20 @@ typename LimbType, typename AllocatorType, const bool IsSigned> - WIDE_INTEGER_CONSTEXPR auto swap(uintwide_t& x, - uintwide_t& y) noexcept -> void; + constexpr auto swap(uintwide_t& x, + uintwide_t& y) noexcept -> void; template - WIDE_INTEGER_CONSTEXPR auto lsb(const uintwide_t& x) -> unsigned_fast_type; + constexpr auto lsb(const uintwide_t& x) -> unsigned_fast_type; template - WIDE_INTEGER_CONSTEXPR auto msb(const uintwide_t& x) -> unsigned_fast_type; + constexpr auto msb(const uintwide_t& x) -> unsigned_fast_type; template - WIDE_INTEGER_CONSTEXPR auto sqrt(const uintwide_t& m) -> uintwide_t; + constexpr auto sqrt(const uintwide_t& m) -> uintwide_t; template - WIDE_INTEGER_CONSTEXPR auto cbrt(const uintwide_t& m) -> uintwide_t; + constexpr auto cbrt(const uintwide_t& m) -> uintwide_t; template - WIDE_INTEGER_CONSTEXPR auto rootk(const uintwide_t& m, const std::uint_fast8_t k) -> uintwide_t; // NOLINT(readability-avoid-const-params-in-decls) + constexpr auto rootk(const uintwide_t& m, const std::uint_fast8_t k) -> uintwide_t; // NOLINT(readability-avoid-const-params-in-decls) template - WIDE_INTEGER_CONSTEXPR auto pow(const uintwide_t& b, const OtherUnsignedIntegralTypeP& p) -> uintwide_t; + constexpr auto pow(const uintwide_t& b, const OtherUnsignedIntegralTypeP& p) -> uintwide_t; template - WIDE_INTEGER_CONSTEXPR auto powm(const uintwide_t& b, - const OtherUnsignedIntegralTypeP& p, - const OtherUnsignedIntegralTypeM& m) -> uintwide_t; + constexpr auto powm(const uintwide_t& b, + const OtherUnsignedIntegralTypeP& p, + const OtherUnsignedIntegralTypeM& m) -> uintwide_t; template - WIDE_INTEGER_CONSTEXPR auto gcd(const uintwide_t& a, - const uintwide_t& b) -> uintwide_t; + constexpr auto gcd(const uintwide_t& a, + const uintwide_t& b) -> uintwide_t; template - WIDE_INTEGER_CONSTEXPR auto gcd(const UnsignedShortType& u, const UnsignedShortType& v) -> std::enable_if_t<( (std::is_integral::value) - && (std::is_unsigned::value)), UnsignedShortType>; + constexpr auto gcd(const UnsignedShortType& u, const UnsignedShortType& v) -> std::enable_if_t<( (std::is_integral::value) + && (std::is_unsigned::value)), UnsignedShortType>; template - WIDE_INTEGER_CONSTEXPR auto lcm(const uintwide_t& a, - const uintwide_t& b) -> uintwide_t; + constexpr auto lcm(const uintwide_t& a, + const uintwide_t& b) -> uintwide_t; template - WIDE_INTEGER_CONSTEXPR auto lcm(const UnsignedShortType& a, const UnsignedShortType& b) -> std::enable_if_t<( (std::is_integral::value) - && (std::is_unsigned::value)), UnsignedShortType>; + constexpr auto lcm(const UnsignedShortType& a, const UnsignedShortType& b) -> std::enable_if_t<( (std::is_integral::value) + && (std::is_unsigned::value)), UnsignedShortType>; template - WIDE_INTEGER_CONSTEXPR - auto divmod(const uintwide_t& a, - const uintwide_t& b, - std::enable_if_t<((!IsSignedLeft) && (!IsSignedRight)), int>* p_nullparam = nullptr) -> std::pair, uintwide_t>; + constexpr auto divmod(const uintwide_t& a, + const uintwide_t& b, + std::enable_if_t<((!IsSignedLeft) && (!IsSignedRight)), int>* p_nullparam = nullptr) -> std::pair, uintwide_t>; template - WIDE_INTEGER_CONSTEXPR - auto divmod(const uintwide_t& a, - const uintwide_t& b, - std::enable_if_t<(IsSignedLeft || IsSignedRight), int>* p_nullparam = nullptr) -> std::pair, uintwide_t>; + constexpr auto divmod(const uintwide_t& a, + const uintwide_t& b, + std::enable_if_t<(IsSignedLeft || IsSignedRight), int>* p_nullparam = nullptr) -> std::pair, uintwide_t>; template + constexpr auto to_chars(char* first, char* last, const uintwide_t& x, int base = static_cast(INT8_C(10))) -> std::to_chars_result; + + template + constexpr + auto from_chars(const char* first, + const char* last, + uintwide_t& x, + int base = static_cast(INT8_C(10))) -> std::from_chars_result; #endif #if !defined(WIDE_INTEGER_DISABLE_TO_STRING) @@ -1631,7 +1580,7 @@ typename LimbType, typename AllocatorType, std::enable_if_t::value_type>::digits == std::numeric_limits::digits> const* = nullptr> - WIDE_INTEGER_CONSTEXPR + constexpr auto import_bits(uintwide_t& val, ForwardIterator first, ForwardIterator last, @@ -1643,7 +1592,7 @@ typename LimbType, typename AllocatorType, std::enable_if_t::value_type>::digits == std::numeric_limits::digits)> const* = nullptr> - WIDE_INTEGER_CONSTEXPR + constexpr auto import_bits(uintwide_t& val, ForwardIterator first, ForwardIterator last, @@ -1656,7 +1605,7 @@ typename AllocatorType, const bool IsSigned, std::enable_if_t::value_type>::digits == std::numeric_limits::digits> const* = nullptr> - WIDE_INTEGER_CONSTEXPR + constexpr auto export_bits(const uintwide_t& val, OutputIterator out, unsigned chunk_size, @@ -1668,7 +1617,7 @@ typename AllocatorType, const bool IsSigned, std::enable_if_t::value_type>::digits == std::numeric_limits::digits)> const* = nullptr> - WIDE_INTEGER_CONSTEXPR + constexpr auto export_bits(const uintwide_t& val, OutputIterator out, unsigned chunk_size, @@ -1712,7 +1661,7 @@ template - class fixed_dynamic_array final : public detail::dynamic_array + class fixed_dynamic_array final : public detail::dynamic_array // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions) { private: using base_class_type = detail::dynamic_array; @@ -1720,9 +1669,9 @@ public: static constexpr auto static_size() -> typename base_class_type::size_type { return MySize; } - explicit WIDE_INTEGER_CONSTEXPR fixed_dynamic_array(const typename base_class_type::size_type size_in = MySize, - const typename base_class_type::value_type& value_in = typename base_class_type::value_type(), - const typename base_class_type::allocator_type& alloc_in = typename base_class_type::allocator_type()) + explicit constexpr fixed_dynamic_array(const typename base_class_type::size_type size_in = MySize, + const typename base_class_type::value_type& value_in = typename base_class_type::value_type(), + const typename base_class_type::allocator_type& alloc_in = typename base_class_type::allocator_type()) : base_class_type(MySize, typename base_class_type::value_type(), alloc_in) { detail::fill_unsafe(base_class_type::begin(), @@ -1734,7 +1683,7 @@ constexpr fixed_dynamic_array(fixed_dynamic_array&& other_array) noexcept = default; - WIDE_INTEGER_CONSTEXPR fixed_dynamic_array(std::initializer_list lst) + constexpr fixed_dynamic_array(std::initializer_list lst) : base_class_type(MySize) { detail::copy_unsafe(lst.begin(), @@ -1742,12 +1691,9 @@ base_class_type::begin()); } - WIDE_INTEGER_CONSTEXPR auto operator=(const fixed_dynamic_array& other_array) -> fixed_dynamic_array& = default; + constexpr auto operator=(const fixed_dynamic_array& other_array) -> fixed_dynamic_array& = default; - WIDE_INTEGER_CONSTEXPR auto operator=(fixed_dynamic_array&& other_array) noexcept -> fixed_dynamic_array& = default; - - //WIDE_INTEGER_CONSTEXPR - ~fixed_dynamic_array() override = default; + constexpr auto operator=(fixed_dynamic_array&& other_array) noexcept -> fixed_dynamic_array& = default; }; struct allocator_dummy_unsafe @@ -1772,9 +1718,9 @@ constexpr fixed_static_array() = default; - explicit WIDE_INTEGER_CONSTEXPR fixed_static_array(const size_type size_in, - const value_type& value_in = value_type(), - allocator_type alloc_in = allocator_type()) + explicit constexpr fixed_static_array(const size_type size_in, + const value_type& value_in = value_type(), + allocator_type alloc_in = allocator_type()) { static_cast(alloc_in); @@ -1792,10 +1738,10 @@ } } - WIDE_INTEGER_CONSTEXPR fixed_static_array(const fixed_static_array&) = default; - WIDE_INTEGER_CONSTEXPR fixed_static_array(fixed_static_array&&) noexcept = default; + constexpr fixed_static_array(const fixed_static_array&) = default; + constexpr fixed_static_array(fixed_static_array&&) noexcept = default; - WIDE_INTEGER_CONSTEXPR fixed_static_array(std::initializer_list lst) + constexpr fixed_static_array(std::initializer_list lst) { const auto size_to_copy = (detail::min_unsafe)(static_cast(lst.size()), MySize); @@ -1818,14 +1764,14 @@ } } - //WIDE_INTEGER_CONSTEXPR + //constexpr ~fixed_static_array() = default; - WIDE_INTEGER_CONSTEXPR auto operator=(const fixed_static_array& other_array) -> fixed_static_array& = default; - WIDE_INTEGER_CONSTEXPR auto operator=(fixed_static_array&& other_array) noexcept -> fixed_static_array& = default; + constexpr auto operator=(const fixed_static_array& other_array) -> fixed_static_array& = default; + constexpr auto operator=(fixed_static_array&& other_array) noexcept -> fixed_static_array& = default; - WIDE_INTEGER_CONSTEXPR auto operator[](const size_type i) -> typename base_class_type::reference { return base_class_type::operator[](static_cast(i)); } - WIDE_INTEGER_CONSTEXPR auto operator[](const size_type i) const -> typename base_class_type::const_reference { return base_class_type::operator[](static_cast(i)); } + constexpr auto operator[](const size_type i) -> typename base_class_type::reference { return base_class_type::operator[](static_cast(i)); } + constexpr auto operator[](const size_type i) const -> typename base_class_type::const_reference { return base_class_type::operator[](static_cast(i)); } }; template struct verify_power_of_two_times_granularity_one_sixty_fourth // NOLINT(altera-struct-pack-align) @@ -1887,11 +1833,7 @@ template - #if !defined(WIDE_INTEGER_DISABLE_WIDE_INTEGER_CONSTEXPR) constexpr auto advance_and_point(InputIterator it, IntegralType n) -> InputIterator - #else - WIDE_INTEGER_CONSTEXPR auto advance_and_point(InputIterator it, IntegralType n) -> InputIterator - #endif { using local_signed_integral_type = std::conditional_t::value, @@ -1900,15 +1842,7 @@ using local_difference_type = typename detail::iterator_detail::iterator_traits::difference_type; - #if !defined(WIDE_INTEGER_DISABLE_WIDE_INTEGER_CONSTEXPR) return it + static_cast(static_cast(n)); - #else - auto my_it = it; - - std::advance(my_it, static_cast(static_cast(n))); - - return my_it; - #endif } template native_float_parts& // NOLINT(cert-oop54-cpp) + constexpr auto operator=(const native_float_parts& other) noexcept -> native_float_parts& // NOLINT(cert-oop54-cpp) { if(this != &other) { @@ -2110,7 +2045,7 @@ return *this; } - WIDE_INTEGER_CONSTEXPR auto operator=(native_float_parts&& other) noexcept -> native_float_parts& + constexpr auto operator=(native_float_parts&& other) noexcept -> native_float_parts& { my_mantissa_part = other.my_mantissa_part; my_exponent_part = other.my_exponent_part; @@ -2118,10 +2053,8 @@ return *this; } - WIDE_INTEGER_NODISCARD WIDE_INTEGER_CONSTEXPR auto get_mantissa() const -> unsigned long long { return my_mantissa_part; } // NOLINT(google-runtime-int) - WIDE_INTEGER_NODISCARD WIDE_INTEGER_CONSTEXPR auto get_exponent() const -> int { return my_exponent_part; } - - WIDE_INTEGER_CONSTEXPR native_float_parts() = delete; + WIDE_INTEGER_NODISCARD constexpr auto get_mantissa() const -> unsigned long long { return my_mantissa_part; } // NOLINT(google-runtime-int) + WIDE_INTEGER_NODISCARD constexpr auto get_exponent() const -> int { return my_exponent_part; } private: unsigned long long my_mantissa_part { }; // NOLINT(readability-identifier-naming,google-runtime-int) @@ -2147,7 +2080,7 @@ typename LimbType, typename AllocatorType, const bool IsSigned> - class uintwide_t + class uintwide_t // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions) { public: template - WIDE_INTEGER_CONSTEXPR + constexpr uintwide_t(const UnsignedIntegralType v, // NOLINT(google-explicit-constructor,hicpp-explicit-conversions) std::enable_if_t<( std::is_integral ::value && std::is_unsigned ::value @@ -2249,10 +2182,10 @@ // are wider than limb_type, and do not have exactly the // same width as limb_type. template - WIDE_INTEGER_CONSTEXPR uintwide_t(const UnsignedIntegralType v, // NOLINT(google-explicit-constructor,hicpp-explicit-conversions) - std::enable_if_t<( std::is_integral ::value - && std::is_unsigned ::value - && (std::numeric_limits::digits > std::numeric_limits::digits))>* p_nullparam = nullptr) + constexpr uintwide_t(const UnsignedIntegralType v, // NOLINT(google-explicit-constructor,hicpp-explicit-conversions) + std::enable_if_t<( std::is_integral ::value + && std::is_unsigned ::value + && (std::numeric_limits::digits > std::numeric_limits::digits))>* p_nullparam = nullptr) { static_cast(p_nullparam == nullptr); @@ -2282,9 +2215,9 @@ // Constructors from built-in signed integral types. template - WIDE_INTEGER_CONSTEXPR uintwide_t(const SignedIntegralType v, // NOLINT(google-explicit-constructor,hicpp-explicit-conversions) - std::enable_if_t<( std::is_integral::value - && std::is_signed ::value)>* p_nullparam = nullptr) + constexpr uintwide_t(const SignedIntegralType v, // NOLINT(google-explicit-constructor,hicpp-explicit-conversions) + std::enable_if_t<( std::is_integral::value + && std::is_signed ::value)>* p_nullparam = nullptr) : values(number_of_limbs) { static_cast(p_nullparam == nullptr); @@ -2307,7 +2240,7 @@ #if !defined(WIDE_INTEGER_DISABLE_FLOAT_INTEROP) template::value)> const* = nullptr> - WIDE_INTEGER_CONSTEXPR uintwide_t(const FloatingPointType f) // NOLINT(google-explicit-constructor,hicpp-explicit-conversions) + constexpr uintwide_t(const FloatingPointType f) // NOLINT(google-explicit-constructor,hicpp-explicit-conversions) { using local_builtin_float_type = FloatingPointType; @@ -2381,7 +2314,7 @@ template const* = nullptr> - explicit WIDE_INTEGER_CONSTEXPR uintwide_t(const uintwide_t& v) + explicit constexpr uintwide_t(const uintwide_t& v) { using other_wide_integer_type = uintwide_t; @@ -2412,7 +2345,7 @@ template OtherWidth2)> const* = nullptr> - explicit WIDE_INTEGER_CONSTEXPR uintwide_t(const uintwide_t& v) + explicit constexpr uintwide_t(const uintwide_t& v) { using other_wide_integer_type = uintwide_t; @@ -2441,7 +2374,7 @@ } // Constructor from a constant character string. - WIDE_INTEGER_CONSTEXPR uintwide_t(const char* str_input) // NOLINT(google-explicit-constructor,hicpp-explicit-conversions) + constexpr uintwide_t(const char* str_input) // NOLINT(google-explicit-constructor,hicpp-explicit-conversions) : values { static_cast(number_of_limbs), @@ -2449,14 +2382,14 @@ typename representation_type::allocator_type() } { - if(!rd_string(str_input)) + if(!rd_string(str_input, (std::numeric_limits::max)(), 0)) { static_cast(operator=((std::numeric_limits::max)())); } } // Move constructor. - constexpr uintwide_t(uintwide_t&&) noexcept = default; + constexpr uintwide_t(uintwide_t&&) noexcept = default; // LCOV_EXCL_LINE // Move-like constructor from the other signed-ness type. // This constructor is non-explicit because it is a trivial conversion. @@ -2465,17 +2398,13 @@ constexpr uintwide_t(uintwide_t&& other) // NOLINT(google-explicit-constructor,hicpp-explicit-conversions) : values(static_cast(other.values)) { } - // Default destructor. - //WIDE_INTEGER_CONSTEXPR - ~uintwide_t() = default; - // Assignment operator. - WIDE_INTEGER_CONSTEXPR auto operator=(const uintwide_t&) -> uintwide_t& = default; + constexpr auto operator=(const uintwide_t&) -> uintwide_t& = default; // LCOV_EXCL_LINE // Assignment operator from the other signed-ness type. template const* = nullptr> - WIDE_INTEGER_CONSTEXPR auto operator=(const uintwide_t& other) -> uintwide_t& + constexpr auto operator=(const uintwide_t& other) -> uintwide_t& { values = other.values; @@ -2483,12 +2412,12 @@ } // Trivial move assignment operator. - WIDE_INTEGER_CONSTEXPR auto operator=(uintwide_t&& other) noexcept -> uintwide_t& = default; + constexpr auto operator=(uintwide_t&& other) noexcept -> uintwide_t& = default; // LCOV_EXCL_LINE // Trivial move assignment operator from the other signed-ness type. template const* = nullptr> - WIDE_INTEGER_CONSTEXPR auto operator=(uintwide_t&& other) -> uintwide_t& + constexpr auto operator=(uintwide_t&& other) -> uintwide_t& { values = static_cast(other.values); @@ -2522,7 +2451,7 @@ // and/or possibly having a different signed-ness, but having the same limb type. template - WIDE_INTEGER_CONSTEXPR operator uintwide_t() const // NOLINT(hicpp-explicit-conversions,google-explicit-constructor) + constexpr operator uintwide_t() const // NOLINT(hicpp-explicit-conversions,google-explicit-constructor) { const auto this_is_neg = is_neg(*this); @@ -2535,24 +2464,13 @@ : static_cast(other_wide_integer_type::number_of_limbs) ); - other_wide_integer_type other; + other_wide_integer_type other { }; if(!this_is_neg) { detail::copy_unsafe(crepresentation().cbegin(), detail::advance_and_point(crepresentation().cbegin(), sz), other.values.begin()); - - // TBD: Can proper/better template specialization remove the need for if constexpr here? - #if ( (defined(_MSC_VER) && ((_MSC_VER >= 1900) && defined(_HAS_CXX17) && (_HAS_CXX17 != 0))) \ - || (defined(__cplusplus) && ((__cplusplus >= 201703L) || defined(__cpp_if_constexpr)))) - if constexpr(Width2 < OtherWidth2) - #else - if(Width2 < OtherWidth2) - #endif - { - detail::fill_unsafe(detail::advance_and_point(other.values.begin(), sz), other.values.end(), static_cast(UINT8_C(0))); - } } else { @@ -2564,17 +2482,6 @@ detail::advance_and_point(uv.crepresentation().cbegin(), sz), other.values.begin()); - // TBD: Can proper/better template specialization remove the need for if constexpr here? - #if ( (defined(_MSC_VER) && ((_MSC_VER >= 1900) && defined(_HAS_CXX17) && (_HAS_CXX17 != 0))) \ - || (defined(__cplusplus) && ((__cplusplus >= 201703L) || defined(__cpp_if_constexpr)))) - if constexpr(Width2 < OtherWidth2) - #else - if(Width2 < OtherWidth2) - #endif - { - detail::fill_unsafe(detail::advance_and_point(other.values.begin(), sz), other.values.end(), static_cast(UINT8_C(0))); - } - other.negate(); } @@ -2582,15 +2489,15 @@ } // Provide a user interface to the internal data representation. - WIDE_INTEGER_CONSTEXPR auto representation() -> representation_type& { return values; } - WIDE_INTEGER_NODISCARD WIDE_INTEGER_CONSTEXPR auto representation() const -> const representation_type& { return values; } - WIDE_INTEGER_NODISCARD WIDE_INTEGER_CONSTEXPR auto crepresentation() const -> const representation_type& { return values; } + constexpr auto representation() -> representation_type& { return values; } + WIDE_INTEGER_NODISCARD constexpr auto representation() const -> const representation_type& { return values; } + WIDE_INTEGER_NODISCARD constexpr auto crepresentation() const -> const representation_type& { return values; } // Unary operators: not, plus and minus. - WIDE_INTEGER_CONSTEXPR auto operator+() const -> const uintwide_t& { return *this; } - WIDE_INTEGER_CONSTEXPR auto operator-() const -> uintwide_t { uintwide_t tmp(*this); tmp.negate(); return tmp; } + constexpr auto operator+() const -> const uintwide_t& { return *this; } + constexpr auto operator-() const -> uintwide_t { uintwide_t tmp(*this); tmp.negate(); return tmp; } - WIDE_INTEGER_CONSTEXPR auto operator+=(const uintwide_t& other) -> uintwide_t& + constexpr auto operator+=(const uintwide_t& other) -> uintwide_t& { if(this == &other) { @@ -2620,7 +2527,7 @@ return *this; } - WIDE_INTEGER_CONSTEXPR auto operator-=(const uintwide_t& other) -> uintwide_t& + constexpr auto operator-=(const uintwide_t& other) -> uintwide_t& { if(this == &other) { @@ -2641,7 +2548,7 @@ return *this; } - WIDE_INTEGER_CONSTEXPR auto operator*=(const uintwide_t& other) -> uintwide_t& + constexpr auto operator*=(const uintwide_t& other) -> uintwide_t& { if(this == &other) { @@ -2657,7 +2564,7 @@ return *this; } - WIDE_INTEGER_CONSTEXPR auto mul_by_limb(const limb_type v) -> uintwide_t& + constexpr auto mul_by_limb(const limb_type v) -> uintwide_t& { if(v == static_cast(UINT8_C(0))) { @@ -2674,7 +2581,7 @@ return *this; } - WIDE_INTEGER_CONSTEXPR auto operator/=(const uintwide_t& other) -> uintwide_t& + constexpr auto operator/=(const uintwide_t& other) -> uintwide_t& { if(this == &other) { @@ -2684,7 +2591,7 @@ } else if(other.is_zero()) { - *this = limits_helper_max(IsSigned); + static_cast(operator=(limits_helper_max())); } else { @@ -2718,7 +2625,7 @@ return *this; } - WIDE_INTEGER_CONSTEXPR auto operator%=(const uintwide_t& other) -> uintwide_t& + constexpr auto operator%=(const uintwide_t& other) -> uintwide_t& { if(this == &other) { @@ -2763,14 +2670,14 @@ } // Operators pre-increment and pre-decrement. - WIDE_INTEGER_CONSTEXPR auto operator++() -> uintwide_t& { preincrement(); return *this; } - WIDE_INTEGER_CONSTEXPR auto operator--() -> uintwide_t& { predecrement(); return *this; } + constexpr auto operator++() -> uintwide_t& { preincrement(); return *this; } + constexpr auto operator--() -> uintwide_t& { predecrement(); return *this; } // Operators post-increment and post-decrement. - WIDE_INTEGER_CONSTEXPR auto operator++(int) -> uintwide_t { const uintwide_t w(*this); preincrement(); return w; } - WIDE_INTEGER_CONSTEXPR auto operator--(int) -> uintwide_t { const uintwide_t w(*this); predecrement(); return w; } + constexpr auto operator++(int) -> uintwide_t { const uintwide_t w(*this); preincrement(); return w; } + constexpr auto operator--(int) -> uintwide_t { const uintwide_t w(*this); predecrement(); return w; } - WIDE_INTEGER_CONSTEXPR auto operator~() -> uintwide_t& + constexpr auto operator~() -> uintwide_t& { // Perform bitwise NOT. bitwise_not(); @@ -2778,25 +2685,23 @@ return *this; } - WIDE_INTEGER_CONSTEXPR auto operator|=(const uintwide_t& other) -> uintwide_t& // LCOV_EXCL_LINE + constexpr auto operator|=(const uintwide_t& other) -> uintwide_t& // LCOV_EXCL_LINE { if(this != &other) // LCOV_EXCL_LINE { - auto bi = other.values.cbegin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto) + auto itr_b = other.values.cbegin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto) // Perform bitwise OR. - for(auto& a : values) + for(auto itr_a = values.begin(); itr_a != values.end(); ++itr_a, ++itr_b) // NOLINT(altera-id-dependent-backward-branch,llvm-qualified-auto,readability-qualified-auto) { - a = static_cast(a | *bi); - - ++bi; + *itr_a = static_cast(*itr_a | *itr_b); } } return *this; // LCOV_EXCL_LINE } - WIDE_INTEGER_CONSTEXPR auto operator^=(const uintwide_t& other) -> uintwide_t& // LCOV_EXCL_LINE + constexpr auto operator^=(const uintwide_t& other) -> uintwide_t& // LCOV_EXCL_LINE { if(this == &other) // LCOV_EXCL_LINE { @@ -2804,32 +2709,28 @@ } else { - auto bi = other.values.cbegin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto) + auto itr_b = other.values.cbegin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto) // Perform bitwise XOR. - for(auto& a : values) + for(auto itr_a = values.begin(); itr_a != values.end(); ++itr_a, ++itr_b) // NOLINT(altera-id-dependent-backward-branch,llvm-qualified-auto,readability-qualified-auto) { - a = static_cast(a ^ *bi); - - ++bi; + *itr_a = static_cast(*itr_a ^ *itr_b); } } return *this; // LCOV_EXCL_LINE } - WIDE_INTEGER_CONSTEXPR auto operator&=(const uintwide_t& other) -> uintwide_t& + constexpr auto operator&=(const uintwide_t& other) -> uintwide_t& { if(this != &other) // LCOV_EXCL_LINE { - auto bi = other.values.cbegin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto) + auto itr_b = other.values.cbegin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto) // Perform bitwise AND. - for(auto& a : values) + for(auto itr_a = values.begin(); itr_a != values.end(); ++itr_a, ++itr_b) // NOLINT(altera-id-dependent-backward-branch,llvm-qualified-auto,readability-qualified-auto) { - a = static_cast(a & *bi); - - ++bi; + *itr_a = static_cast(*itr_a & *itr_b); } } @@ -2837,8 +2738,8 @@ } template - WIDE_INTEGER_CONSTEXPR auto operator<<=(const SignedIntegralType n) -> std::enable_if_t<( std::is_integral::value - && std::is_signed ::value), uintwide_t>& + constexpr auto operator<<=(const SignedIntegralType n) -> std::enable_if_t<( std::is_integral::value + && std::is_signed ::value), uintwide_t>& { // Implement left-shift operator for signed integral argument. if(n < static_cast(0)) @@ -2867,8 +2768,8 @@ } template - WIDE_INTEGER_CONSTEXPR auto operator<<=(const UnsignedIntegralType n) -> std::enable_if_t<( std::is_integral::value - && (!std::is_signed ::value)), uintwide_t>& + constexpr auto operator<<=(const UnsignedIntegralType n) -> std::enable_if_t<( std::is_integral::value + && (!std::is_signed ::value)), uintwide_t>& { // Implement left-shift operator for unsigned integral argument. if(n != static_cast(0)) @@ -2890,8 +2791,8 @@ } template - WIDE_INTEGER_CONSTEXPR auto operator>>=(const SignedIntegralType n) -> std::enable_if_t<( std::is_integral::value - && std::is_signed ::value), uintwide_t>& + constexpr auto operator>>=(const SignedIntegralType n) -> std::enable_if_t<( std::is_integral::value + && std::is_signed ::value), uintwide_t>& { // Implement right-shift operator for signed integral argument. if(n < static_cast(0)) @@ -2923,8 +2824,8 @@ } template - WIDE_INTEGER_CONSTEXPR auto operator>>=(const UnsignedIntegralType n) -> std::enable_if_t<( std::is_integral::value - && (!std::is_signed ::value)), uintwide_t>& + constexpr auto operator>>=(const UnsignedIntegralType n) -> std::enable_if_t<( std::is_integral::value + && (!std::is_signed ::value)), uintwide_t>& { // Implement right-shift operator for unsigned integral argument. if(n != static_cast(0)) @@ -2957,99 +2858,71 @@ constexpr auto operator>=(const uintwide_t& other) const -> bool { return (compare(other) >= static_cast( 0)); } // Helper functions for supporting std::numeric_limits<>. - static constexpr auto limits_helper_max(bool is_signed) -> uintwide_t + template + static constexpr auto limits_helper_max() -> std::enable_if_t<(!OtherIsSigned), uintwide_t> { - return - (!is_signed) - ? from_rep - ( - representation_type - ( - number_of_limbs, (std::numeric_limits::max)() - ) - ) - : from_rep - ( - representation_type - ( - number_of_limbs, (std::numeric_limits::max)() // LCOV_EXCL_LINE - ) - ) - ^ - ( - uintwide_t(static_cast(UINT8_C(1))) - << static_cast(my_width2 - static_cast(UINT8_C(1))) - ) - ; + uintwide_t result_max { }; + + detail::fill_unsafe(result_max.values.begin(), result_max.values.end(), (std::numeric_limits::max)()); + + return result_max; } - static constexpr auto limits_helper_min(bool is_signed) -> uintwide_t + template + static constexpr auto limits_helper_max() -> std::enable_if_t { - return - (!is_signed) - ? from_rep - ( - representation_type - ( - number_of_limbs, static_cast(UINT8_C(0)) - ) - ) - : from_rep - ( - representation_type - ( - number_of_limbs, static_cast(UINT8_C(0)) // LCOV_EXCL_LINE - ) - ) - | - ( - uintwide_t(static_cast(UINT8_C(1))) - << static_cast(my_width2 - static_cast(UINT8_C(1))) - ) - ; + uintwide_t result_max { }; + + detail::fill_unsafe(result_max.values.begin(), result_max.values.end(), (std::numeric_limits::max)()); + + constexpr auto high_bit_limb = + static_cast + ( + static_cast(UINT8_C(1)) << static_cast(std::numeric_limits::digits - static_cast(INT8_C(1))) + ); + + result_max.values.back() ^= high_bit_limb; + + return result_max; } - static constexpr auto limits_helper_lowest(bool is_signed) -> uintwide_t + template + static constexpr auto limits_helper_min() -> std::enable_if_t<(!OtherIsSigned), uintwide_t> { - return - (!is_signed) - ? from_rep - ( - representation_type - ( - number_of_limbs, static_cast(UINT8_C(0)) - ) - ) - : from_rep - ( - representation_type - ( - number_of_limbs, static_cast(UINT8_C(0)) - ) - ) - | - ( - uintwide_t(static_cast(UINT8_C(1))) - << static_cast(my_width2 - static_cast(UINT8_C(1))) - ) - ; + return uintwide_t { }; + } + + template + static constexpr auto limits_helper_min() -> std::enable_if_t + { + uintwide_t result_min { }; + + constexpr auto high_bit_limb = + static_cast + ( + static_cast(UINT8_C(1)) << static_cast(std::numeric_limits::digits - static_cast(INT8_C(1))) + ); + + result_min.values.back() |= high_bit_limb; + + return result_min; } // Write string function. template - WIDE_INTEGER_CONSTEXPR auto wr_string( OutputStrIterator str_result, // NOLINT(readability-function-cognitive-complexity) - const std::uint_fast8_t base_rep = static_cast(UINT8_C(0x10)), - const bool show_base = true, - const bool show_pos = false, - const bool is_uppercase = true, - unsigned_fast_type field_width = static_cast(UINT8_C(0)), - const char fill_char_str = '0') const -> bool + constexpr auto wr_string( OutputStrIterator str_result, // NOLINT(readability-function-cognitive-complexity) + const std::uint_fast8_t base_rep = static_cast(UINT8_C(0x10)), + const bool show_base = true, + const bool show_pos = false, + const bool is_uppercase = true, + unsigned_fast_type field_width = static_cast(UINT8_C(0)), + const char fill_char_str = '0') const -> bool { auto wr_string_is_ok = true; if(base_rep == static_cast(UINT8_C(8))) { - uintwide_t t(*this); + uintwide_t t(*this); const auto mask = static_cast(static_cast(0x7U)); @@ -3078,17 +2951,15 @@ } else { - uintwide_t tu(t); - - while(!tu.is_zero()) // NOLINT(altera-id-dependent-backward-branch) + while(!t.is_zero()) // NOLINT(altera-id-dependent-backward-branch) { - auto c = static_cast(*tu.values.cbegin() & mask); + auto c = static_cast(*t.values.cbegin() & mask); if(c <= static_cast(INT8_C(8))) { c = static_cast(c + static_cast(INT8_C(0x30))); } str_temp[static_cast(--pos)] = c; - tu >>= static_cast(UINT8_C(3)); + t >>= static_cast(UINT8_C(3)); } } @@ -3261,7 +3132,7 @@ template const* = nullptr> - WIDE_INTEGER_NODISCARD WIDE_INTEGER_CONSTEXPR auto compare(const uintwide_t& other) const -> std::int_fast8_t + WIDE_INTEGER_NODISCARD constexpr auto compare(const uintwide_t& other) const -> std::int_fast8_t { return compare_ranges(values.cbegin(), other.values.cbegin(), @@ -3270,7 +3141,7 @@ template const* = nullptr> - WIDE_INTEGER_NODISCARD WIDE_INTEGER_CONSTEXPR auto compare(const uintwide_t& other) const -> std::int_fast8_t + WIDE_INTEGER_NODISCARD constexpr auto compare(const uintwide_t& other) const -> std::int_fast8_t { auto n_result = std::int_fast8_t { }; @@ -3300,7 +3171,7 @@ // this is known to be used in the coverage tests. // LCOV_EXCL_START - WIDE_INTEGER_CONSTEXPR auto negate() -> void + constexpr auto negate() -> void { bitwise_not(); @@ -3308,9 +3179,9 @@ } // LCOV_EXCL_STOP - WIDE_INTEGER_CONSTEXPR auto eval_divide_by_single_limb(const limb_type short_denominator, - const unsigned_fast_type u_offset, - uintwide_t* remainder) -> void + constexpr auto eval_divide_by_single_limb(const limb_type short_denominator, + const unsigned_fast_type u_offset, + uintwide_t* remainder) -> void { // The denominator has one single limb. // Use a one-dimensional division algorithm. @@ -3365,7 +3236,7 @@ } } - WIDE_INTEGER_NODISCARD WIDE_INTEGER_CONSTEXPR auto is_zero() const -> bool + WIDE_INTEGER_NODISCARD constexpr auto is_zero() const -> bool { auto it = values.cbegin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto) @@ -3393,7 +3264,7 @@ return (static_cast(static_cast(a.values.back() >> static_cast(std::numeric_limits::limb_type>::digits - 1)) & 1U) != 0U); } - static WIDE_INTEGER_CONSTEXPR auto from_rep(const representation_type& other_rep) -> uintwide_t + static constexpr auto from_rep(const representation_type& other_rep) -> uintwide_t { uintwide_t result { }; @@ -3429,7 +3300,7 @@ return result; } - static WIDE_INTEGER_CONSTEXPR auto from_rep(representation_type&& other_rep) noexcept -> uintwide_t + static constexpr auto from_rep(representation_type&& other_rep) noexcept -> uintwide_t { uintwide_t result { }; @@ -3540,30 +3411,50 @@ typename OtherAllocatorType, const bool OtherIsSignedLeft, const bool OtherIsSignedRight> - friend WIDE_INTEGER_CONSTEXPR auto divmod(const uintwide_t& a, // NOLINT(readability-redundant-declaration) - const uintwide_t& b, - std::enable_if_t<((!OtherIsSignedLeft) && (!OtherIsSignedRight)), int>* p_nullparam) -> std::pair, uintwide_t>; + friend constexpr auto divmod(const uintwide_t& a, // NOLINT(readability-redundant-declaration) + const uintwide_t& b, + std::enable_if_t<((!OtherIsSignedLeft) && (!OtherIsSignedRight)), int>* p_nullparam) -> std::pair, uintwide_t>; + + template + friend constexpr auto divmod(const uintwide_t& a, // NOLINT(readability-redundant-declaration) + const uintwide_t& b, + std::enable_if_t<((!OtherIsSignedLeft) && (!OtherIsSignedRight)), int>* p_nullparam) -> std::pair, uintwide_t>; template - friend WIDE_INTEGER_CONSTEXPR auto divmod(const uintwide_t& a, // NOLINT(readability-redundant-declaration) - const uintwide_t& b, - std::enable_if_t<(OtherIsSignedLeft || OtherIsSignedRight), int>* p_nullparam) -> std::pair, uintwide_t>; + friend constexpr auto divmod(const uintwide_t& a, // NOLINT(readability-redundant-declaration) + const uintwide_t& b, + std::enable_if_t<(OtherIsSignedLeft || OtherIsSignedRight), int>* p_nullparam) -> std::pair, uintwide_t>; + + #if (defined(__cpp_lib_to_chars) && (__cpp_lib_to_chars >= 201611L)) + template + friend constexpr auto from_chars(const char* first, // NOLINT(readability-redundant-declaration) + const char* last, + uintwide_t& x, + int base) -> std::from_chars_result; + #endif explicit constexpr uintwide_t(const representation_type& other_rep) : values(static_cast(other_rep)) { } - explicit constexpr uintwide_t(representation_type&& other_rep) + explicit constexpr uintwide_t(representation_type&& other_rep) noexcept : values(static_cast(other_rep)) { } template const* = nullptr> - static WIDE_INTEGER_CONSTEXPR auto extract_hex_digits(uintwide_t& tu, - char* pstr, - const bool is_uppercase) -> unsigned_fast_type + static constexpr auto extract_hex_digits(uintwide_t& tu, + char* pstr, + const bool is_uppercase) -> unsigned_fast_type { constexpr auto mask = static_cast(UINT8_C(0xF)); @@ -3588,9 +3479,9 @@ template - static WIDE_INTEGER_CONSTEXPR auto compare_ranges( InputIteratorLeftType a, - InputIteratorRightType b, - const unsigned_fast_type count) -> std::int_fast8_t + static constexpr auto compare_ranges( InputIteratorLeftType a, + InputIteratorRightType b, + const unsigned_fast_type count) -> std::int_fast8_t { auto n_return = static_cast(INT8_C(0)); @@ -3637,7 +3528,7 @@ / std::numeric_limits::digits); template - static WIDE_INTEGER_CONSTEXPR auto extract(InputIteratorLeft p_limb, unsigned_fast_type limb_count) -> local_unknown_builtin_integral_type + static constexpr auto extract(InputIteratorLeft p_limb, unsigned_fast_type limb_count) -> local_unknown_builtin_integral_type { using local_limb_type = typename detail::iterator_detail::iterator_traits::value_type; using left_difference_type = typename detail::iterator_detail::iterator_traits::difference_type; @@ -3672,7 +3563,7 @@ // Implement a function that extracts any built-in signed or unsigned integral type. template::value>> - WIDE_INTEGER_NODISCARD WIDE_INTEGER_CONSTEXPR auto extract_builtin_integral_type() const -> UnknownBuiltInIntegralType + WIDE_INTEGER_NODISCARD constexpr auto extract_builtin_integral_type() const -> UnknownBuiltInIntegralType { using local_unknown_integral_type = UnknownBuiltInIntegralType; using digits_ratio_type = digits_ratio; @@ -3691,7 +3582,7 @@ // Implement a function that extracts any built-in floating-point type. template::value>> - WIDE_INTEGER_NODISCARD WIDE_INTEGER_CONSTEXPR auto extract_builtin_floating_point_type() const -> FloatingPointType + WIDE_INTEGER_NODISCARD constexpr auto extract_builtin_floating_point_type() const -> FloatingPointType { using local_unsigned_wide_integer_type = uintwide_t; using local_builtin_float_type = FloatingPointType; @@ -3745,9 +3636,9 @@ #endif template - static WIDE_INTEGER_CONSTEXPR auto eval_mul_unary( uintwide_t& u, - const uintwide_t& v, - std::enable_if_t<((OtherWidth2 / std::numeric_limits::digits) < number_of_limbs_karatsuba_threshold)>* p_nullparam = nullptr) -> void + static constexpr auto eval_mul_unary( uintwide_t& u, + const uintwide_t& v, + std::enable_if_t<((OtherWidth2 / std::numeric_limits::digits) < number_of_limbs_karatsuba_threshold)>* p_nullparam = nullptr) -> void { static_cast(p_nullparam == nullptr); @@ -3778,9 +3669,9 @@ } template - static WIDE_INTEGER_CONSTEXPR auto eval_mul_unary( uintwide_t& u, - const uintwide_t& v, - std::enable_if_t<((OtherWidth2 / std::numeric_limits::digits) >= number_of_limbs_karatsuba_threshold)>* p_nullparam = nullptr) -> void + static constexpr auto eval_mul_unary( uintwide_t& u, + const uintwide_t& v, + std::enable_if_t<((OtherWidth2 / std::numeric_limits::digits) >= number_of_limbs_karatsuba_threshold)>* p_nullparam = nullptr) -> void { static_cast(p_nullparam == nullptr); @@ -3828,11 +3719,11 @@ template - static WIDE_INTEGER_CONSTEXPR auto eval_add_n( ResultIterator r, - InputIteratorLeft u, - InputIteratorRight v, - const unsigned_fast_type count, - const limb_type carry_in = static_cast(UINT8_C(0))) -> limb_type + static constexpr auto eval_add_n( ResultIterator r, + InputIteratorLeft u, + InputIteratorRight v, + const unsigned_fast_type count, + const limb_type carry_in = static_cast(UINT8_C(0))) -> limb_type { auto carry_out = static_cast(carry_in); @@ -3870,11 +3761,11 @@ template - static WIDE_INTEGER_CONSTEXPR auto eval_subtract_n( ResultIterator r, - InputIteratorLeft u, - InputIteratorRight v, - const unsigned_fast_type count, - const bool has_borrow_in = false) -> bool + static constexpr auto eval_subtract_n( ResultIterator r, + InputIteratorLeft u, + InputIteratorRight v, + const unsigned_fast_type count, + const bool has_borrow_in = false) -> bool { auto has_borrow_out = static_cast @@ -3925,10 +3816,10 @@ typename InputIteratorRight, const size_t RePhraseWidth2 = Width2, std::enable_if_t<(uintwide_t::number_of_limbs == 4U)> const* = nullptr> - static WIDE_INTEGER_CONSTEXPR auto eval_multiply_n_by_n_to_lo_part( ResultIterator r, - InputIteratorLeft a, - InputIteratorRight b, - const unsigned_fast_type count) -> void + static constexpr auto eval_multiply_n_by_n_to_lo_part( ResultIterator r, + InputIteratorLeft a, + InputIteratorRight b, + const unsigned_fast_type count) -> void { static_cast(count); @@ -4068,10 +3959,10 @@ typename InputIteratorRight, const size_t RePhraseWidth2 = Width2, std::enable_if_t<(uintwide_t::number_of_limbs == static_cast(UINT32_C(8)))> const* = nullptr> - static WIDE_INTEGER_CONSTEXPR auto eval_multiply_n_by_n_to_lo_part( ResultIterator r, - InputIteratorLeft a, - InputIteratorRight b, - const unsigned_fast_type count) -> void + static constexpr auto eval_multiply_n_by_n_to_lo_part( ResultIterator r, + InputIteratorLeft a, + InputIteratorRight b, + const unsigned_fast_type count) -> void { static_cast(count); @@ -4370,10 +4261,10 @@ && (uintwide_t::number_of_limbs != static_cast(UINT32_C(8))) #endif )> const* = nullptr> - static WIDE_INTEGER_CONSTEXPR auto eval_multiply_n_by_n_to_lo_part( ResultIterator r, - InputIteratorLeft a, - InputIteratorRight b, - const unsigned_fast_type count) -> void + static constexpr auto eval_multiply_n_by_n_to_lo_part( ResultIterator r, + InputIteratorLeft a, + InputIteratorRight b, + const unsigned_fast_type count) -> void { static_assert ( @@ -4469,10 +4360,10 @@ template - static WIDE_INTEGER_CONSTEXPR auto eval_multiply_n_by_n_to_2n( ResultIterator r, - InputIteratorLeft a, - InputIteratorRight b, - const unsigned_fast_type count) -> void + static constexpr auto eval_multiply_n_by_n_to_2n( ResultIterator r, + InputIteratorLeft a, + InputIteratorRight b, + const unsigned_fast_type count) -> void { static_assert ( @@ -4523,10 +4414,10 @@ template - static WIDE_INTEGER_CONSTEXPR auto eval_multiply_1d( ResultIterator r, - InputIteratorLeft a, - const typename detail::iterator_detail::iterator_traits::value_type b, - const unsigned_fast_type count) -> limb_type + static constexpr auto eval_multiply_1d( ResultIterator r, + InputIteratorLeft a, + const typename detail::iterator_detail::iterator_traits::value_type b, + const unsigned_fast_type count) -> limb_type { using local_limb_type = typename detail::iterator_detail::iterator_traits::value_type; using left_value_type = typename detail::iterator_detail::iterator_traits::value_type; @@ -4586,14 +4477,14 @@ ); *r++ = static_cast(carry); - carry = detail::make_hi(carry); + carry = static_cast(detail::make_hi(carry)); } #if defined(WIDE_INTEGER_HAS_CLZ_LIMB_OPTIMIZATIONS) for( ; i < count; ++i) { *r++ = static_cast(carry); - carry = detail::make_hi(static_cast(UINT8_C(0))); + carry = static_cast(UINT8_C(0)); } #endif } @@ -4602,7 +4493,7 @@ } template - static WIDE_INTEGER_CONSTEXPR + static constexpr auto eval_multiply_kara_propagate_carry( InputIteratorLeft t, const unsigned_fast_type n, const typename detail::iterator_detail::iterator_traits::value_type carry) -> void @@ -4633,7 +4524,7 @@ } template - static WIDE_INTEGER_CONSTEXPR + static constexpr auto eval_multiply_kara_propagate_borrow( InputIteratorLeft t, const unsigned_fast_type n, const bool has_borrow) -> void @@ -4671,7 +4562,7 @@ typename InputIteratorLeft, typename InputIteratorRight, typename InputIteratorTemp> - static WIDE_INTEGER_CONSTEXPR + static constexpr auto eval_multiply_kara_n_by_n_to_2n( ResultIterator r, // NOLINT(misc-no-recursion) const InputIteratorLeft a, const InputIteratorRight b, @@ -4816,8 +4707,7 @@ } } - WIDE_INTEGER_CONSTEXPR auto eval_divide_knuth(const uintwide_t& other, - uintwide_t* remainder = nullptr) -> void + constexpr auto eval_divide_knuth(const uintwide_t& other, uintwide_t* remainder = nullptr) -> void { // Use Knuth's long division algorithm. // The loop-ordering of indices in Knuth's original @@ -4854,7 +4744,7 @@ { // The denominator is zero. Set the maximum value and return. // This also catches (0 / 0) and sets the maximum value for it. - static_cast(operator=(limits_helper_max(IsSigned))); // LCOV_EXCL_LINE + static_cast(operator=(limits_helper_max())); // LCOV_EXCL_LINE if(remainder != nullptr) // LCOV_EXCL_LINE { @@ -4907,11 +4797,11 @@ } template - WIDE_INTEGER_CONSTEXPR auto eval_divide_knuth_core(const unsigned_fast_type u_offset, // NOLINT(readability-function-cognitive-complexity) - const unsigned_fast_type v_offset, - const uintwide_t& other, - uintwide_t* remainder, - std::enable_if_t<(RePhraseWidth2 > static_cast(std::numeric_limits::digits)), int>* p_nullparam = nullptr) -> void + constexpr auto eval_divide_knuth_core(const unsigned_fast_type u_offset, // NOLINT(readability-function-cognitive-complexity) + const unsigned_fast_type v_offset, + const uintwide_t& other, + uintwide_t* remainder, + std::enable_if_t<(RePhraseWidth2 > static_cast(std::numeric_limits::digits)), int>* p_nullparam = nullptr) -> void { static_cast(p_nullparam); @@ -5165,11 +5055,11 @@ } template - WIDE_INTEGER_CONSTEXPR auto eval_divide_knuth_core(const unsigned_fast_type u_offset, - const unsigned_fast_type v_offset, - const uintwide_t& other, - uintwide_t* remainder, - std::enable_if_t<(RePhraseWidth2 <= static_cast(std::numeric_limits::digits)), int>* p_nullparam = nullptr) -> void + constexpr auto eval_divide_knuth_core(const unsigned_fast_type u_offset, + const unsigned_fast_type v_offset, + const uintwide_t& other, + uintwide_t* remainder, + std::enable_if_t<(RePhraseWidth2 <= static_cast(std::numeric_limits::digits)), int>* p_nullparam = nullptr) -> void { static_cast(p_nullparam); @@ -5199,7 +5089,7 @@ } template - WIDE_INTEGER_CONSTEXPR auto shl(IntegralType n) -> void + constexpr auto shl(IntegralType n) -> void { const auto offset = (detail::min_unsafe)(static_cast(static_cast(n) / static_cast(std::numeric_limits::digits)), @@ -5251,7 +5141,7 @@ } template - WIDE_INTEGER_CONSTEXPR auto shr(IntegralType n) -> void + constexpr auto shr(IntegralType n) -> void { const auto offset = (detail::min_unsafe)(static_cast(static_cast(n) / static_cast(std::numeric_limits::digits)), @@ -5317,13 +5207,15 @@ } // Read string function. - WIDE_INTEGER_CONSTEXPR auto rd_string(const char* str_input) -> bool // NOLINT(readability-function-cognitive-complexity) + constexpr auto rd_string(const char* str_input, const unsigned_fast_type count, const int base_hint) -> bool // NOLINT(readability-function-cognitive-complexity,bugprone-easily-swappable-parameters) { detail::fill_unsafe(values.begin(), values.end(), static_cast(UINT8_C(0))); - const auto str_length = detail::strlen_unsafe(str_input); - - auto base = static_cast(UINT8_C(10)); + const auto str_length = + static_cast + ( + (count == (std::numeric_limits::max)()) ? detail::strlen_unsafe(str_input) : count + ); auto pos = static_cast(UINT8_C(0)); @@ -5345,33 +5237,41 @@ ++pos; } - // Perform a dynamic detection of the base. - if(str_length > static_cast(static_cast(pos) + static_cast(UINT8_C(0)))) + // Set the base if the client has supplied a non-zero base-hint. + auto base = static_cast(base_hint); + + if(base == static_cast(UINT8_C(0))) { - const auto might_be_oct_or_hex = ((str_input[static_cast(static_cast(pos) + static_cast(UINT8_C(0)))] == '0') && (str_length > static_cast(static_cast(pos) + static_cast(UINT8_C(0))))); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) + base = static_cast(UINT8_C(10)); - if(might_be_oct_or_hex) + // Perform a dynamic detection of the base. + if(str_length > static_cast(static_cast(pos) + static_cast(UINT8_C(0)))) { - if((str_input[static_cast(static_cast(pos) + static_cast(UINT8_C(1)))] >= '0') && (str_input[static_cast(static_cast(pos) + static_cast(UINT8_C(1)))] <= '8')) // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) + const auto might_be_oct_or_hex = ((str_input[static_cast(static_cast(pos) + static_cast(UINT8_C(0)))] == '0') && (str_length > static_cast(static_cast(pos) + static_cast(UINT8_C(0))))); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) + + if(might_be_oct_or_hex) { - // The input format is octal. - base = static_cast(UINT8_C(8)); + if((str_input[static_cast(static_cast(pos) + static_cast(UINT8_C(1)))] >= '0') && (str_input[static_cast(static_cast(pos) + static_cast(UINT8_C(1)))] <= '8')) // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) + { + // The input format is octal. + base = static_cast(UINT8_C(8)); + + pos = static_cast(static_cast(pos) + static_cast(UINT8_C(1))); + } + else if((str_input[static_cast(static_cast(pos) + static_cast(UINT8_C(1)))] == 'x') || (str_input[static_cast(static_cast(pos) + static_cast(UINT8_C(1)))] == 'X')) // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) + { + // The input format is hexadecimal. + base = static_cast(UINT8_C(16)); - pos = static_cast(static_cast(pos) + static_cast(UINT8_C(1))); + pos = static_cast(static_cast(pos) + static_cast(UINT8_C(2))); + } } - else if((str_input[static_cast(static_cast(pos) + static_cast(UINT8_C(1)))] == 'x') || (str_input[static_cast(static_cast(pos) + static_cast(UINT8_C(1)))] == 'X')) // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) + else if((str_input[static_cast(static_cast(pos) + static_cast(UINT8_C(0)))] >= '0') && (str_input[static_cast(static_cast(pos) + static_cast(UINT8_C(0)))] <= '9')) // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) { - // The input format is hexadecimal. - base = static_cast(UINT8_C(16)); - - pos = static_cast(static_cast(pos) + static_cast(UINT8_C(2))); + // The input format is decimal. + ; } } - else if((str_input[static_cast(static_cast(pos) + static_cast(UINT8_C(0)))] >= '0') && (str_input[static_cast(static_cast(pos) + static_cast(UINT8_C(0)))] <= '9')) // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) - { - // The input format is decimal. - ; - } } auto char_is_valid = true; @@ -5445,7 +5345,7 @@ return char_is_valid; } - WIDE_INTEGER_CONSTEXPR auto bitwise_not() -> void // LCOV_EXCL_LINE + constexpr auto bitwise_not() -> void // LCOV_EXCL_LINE { for(auto it = values.begin(); it != values.end(); ++it) // NOLINT(llvm-qualified-auto,readability-qualified-auto,altera-id-dependent-backward-branch) { @@ -5453,7 +5353,7 @@ } } // LCOV_EXCL_LINE - WIDE_INTEGER_CONSTEXPR auto preincrement() -> void + constexpr auto preincrement() -> void { // Implement self-increment. @@ -5466,7 +5366,7 @@ while((*it++ == static_cast(UINT8_C(0))) && (it != values.end())); // NOLINT(altera-id-dependent-backward-branch) } - WIDE_INTEGER_CONSTEXPR auto predecrement() -> void + constexpr auto predecrement() -> void { // Implement self-decrement. @@ -5581,9 +5481,9 @@ static constexpr int max_exponent = digits; static constexpr int max_exponent10 = static_cast((static_cast(max_exponent) * UINTMAX_C(75257499)) / UINTMAX_C(250000000)); - static constexpr auto (max) () -> local_wide_integer_type { return local_wide_integer_type::limits_helper_max (IsSigned); } - static constexpr auto (min) () -> local_wide_integer_type { return local_wide_integer_type::limits_helper_min (IsSigned); } - static constexpr auto lowest() -> local_wide_integer_type { return local_wide_integer_type::limits_helper_lowest(IsSigned); } + static constexpr auto (max) () -> local_wide_integer_type { return local_wide_integer_type::template limits_helper_max(); } + static constexpr auto (min) () -> local_wide_integer_type { return local_wide_integer_type::template limits_helper_min(); } + static constexpr auto lowest() -> local_wide_integer_type { return local_wide_integer_type::template limits_helper_min(); } }; template @@ -5662,10 +5562,10 @@ } template - WIDE_INTEGER_CONSTEXPR auto operator%(const uintwide_t& u, const IntegralType& v) -> std::enable_if_t<( std::is_integral::value - && std::is_unsigned::value - && (std::numeric_limits::digits <= std::numeric_limits::digits)), - typename uintwide_t::limb_type> + constexpr auto operator%(const uintwide_t& u, const IntegralType& v) -> std::enable_if_t<( std::is_integral::value + && std::is_unsigned::value + && (std::numeric_limits::digits <= std::numeric_limits::digits)), + typename uintwide_t::limb_type> { using local_wide_integer_type = uintwide_t; @@ -5918,7 +5818,7 @@ #if !defined(WIDE_INTEGER_DISABLE_FLOAT_INTEROP) namespace my_own { - template WIDE_INTEGER_CONSTEXPR auto frexp(FloatingPointType x, int* expptr) -> std::enable_if_t<(std::is_floating_point::value && std::numeric_limits::is_iec559 ), FloatingPointType> + template constexpr auto frexp(FloatingPointType x, int* expptr) -> std::enable_if_t<(std::is_floating_point::value && std::numeric_limits::is_iec559 ), FloatingPointType> { using local_floating_point_type = FloatingPointType; @@ -5962,14 +5862,14 @@ return ((!x_is_neg) ? f : -f); } - template WIDE_INTEGER_CONSTEXPR auto frexp(FloatingPointType x, int* expptr) -> std::enable_if_t<(std::is_floating_point::value && (!std::numeric_limits::is_iec559)), FloatingPointType> + template constexpr auto frexp(FloatingPointType x, int* expptr) -> std::enable_if_t<(std::is_floating_point::value && (!std::numeric_limits::is_iec559)), FloatingPointType> { using std::frexp; return frexp(x, expptr); } - template WIDE_INTEGER_CONSTEXPR auto (isfinite)(FloatingPointType x) -> std::enable_if_t<(std::is_floating_point::value && std::numeric_limits::is_iec559 ), bool> + template constexpr auto (isfinite)(FloatingPointType x) -> std::enable_if_t<(std::is_floating_point::value && std::numeric_limits::is_iec559 ), bool> { using local_floating_point_type = FloatingPointType; @@ -5995,7 +5895,7 @@ return x_is_finite; } - template WIDE_INTEGER_CONSTEXPR auto (isfinite)(FloatingPointType x) -> std::enable_if_t<(std::is_floating_point::value && (!std::numeric_limits::is_iec559)), bool> + template constexpr auto (isfinite)(FloatingPointType x) -> std::enable_if_t<(std::is_floating_point::value && (!std::numeric_limits::is_iec559)), bool> { using std::isfinite; @@ -6120,8 +6020,8 @@ typename LimbType, typename AllocatorType, const bool IsSigned> - WIDE_INTEGER_CONSTEXPR auto swap(uintwide_t& x, - uintwide_t& y) noexcept -> void + constexpr auto swap(uintwide_t& x, + uintwide_t& y) noexcept -> void { if(&x != &y) { @@ -6133,7 +6033,7 @@ typename LimbType, typename AllocatorType, const bool IsSigned> - WIDE_INTEGER_CONSTEXPR auto lsb(const uintwide_t& x) -> unsigned_fast_type + constexpr auto lsb(const uintwide_t& x) -> unsigned_fast_type { // Calculate the position of the least-significant bit. // Use a linear search starting from the least significant limb. @@ -6171,7 +6071,7 @@ typename LimbType, typename AllocatorType, const bool IsSigned> - WIDE_INTEGER_CONSTEXPR auto msb(const uintwide_t& x) -> unsigned_fast_type + constexpr auto msb(const uintwide_t& x) -> unsigned_fast_type { // Calculate the position of the most-significant bit. // Use a linear search starting from the most significant limb. @@ -6220,7 +6120,7 @@ typename LimbType, typename AllocatorType, const bool IsSigned> - WIDE_INTEGER_CONSTEXPR auto sqrt(const uintwide_t& m) -> uintwide_t + constexpr auto sqrt(const uintwide_t& m) -> uintwide_t { // Calculate the square root. @@ -6273,7 +6173,7 @@ typename LimbType, typename AllocatorType, const bool IsSigned> - WIDE_INTEGER_CONSTEXPR auto cbrt(const uintwide_t& m) -> uintwide_t // NOLINT(misc-no-recursion) + constexpr auto cbrt(const uintwide_t& m) -> uintwide_t // NOLINT(misc-no-recursion) { // Calculate the cube root. @@ -6348,7 +6248,7 @@ typename LimbType, typename AllocatorType, const bool IsSigned> - WIDE_INTEGER_CONSTEXPR auto rootk(const uintwide_t& m, std::uint_fast8_t k) -> uintwide_t + constexpr auto rootk(const uintwide_t& m, std::uint_fast8_t k) -> uintwide_t { // Calculate the k'th root. @@ -6431,7 +6331,7 @@ typename LimbType, typename AllocatorType, const bool IsSigned> - WIDE_INTEGER_CONSTEXPR auto pow(const uintwide_t& b, const OtherIntegralTypeP& p) -> uintwide_t + constexpr auto pow(const uintwide_t& b, const OtherIntegralTypeP& p) -> uintwide_t { // Calculate (b ^ p). using local_wide_integer_type = uintwide_t; @@ -6482,9 +6382,9 @@ typename LimbType, typename AllocatorType, const bool IsSigned> - WIDE_INTEGER_CONSTEXPR auto powm(const uintwide_t& b, - const OtherIntegralTypeP& p, - const OtherIntegralTypeM& m) -> uintwide_t + constexpr auto powm(const uintwide_t& b, + const OtherIntegralTypeP& p, + const OtherIntegralTypeM& m) -> uintwide_t { // Calculate (b ^ p) % m. @@ -6543,7 +6443,7 @@ namespace detail { template - WIDE_INTEGER_CONSTEXPR auto integer_gcd_reduce(UnsignedShortType u, UnsignedShortType v) -> UnsignedShortType + constexpr auto integer_gcd_reduce(UnsignedShortType u, UnsignedShortType v) -> UnsignedShortType { #if (defined(__cpp_lib_gcd_lcm) && (__cpp_lib_gcd_lcm >= 201606L)) return std::gcd(u, v); @@ -6558,8 +6458,8 @@ typename LimbType, typename AllocatorType, const bool IsSigned> - WIDE_INTEGER_CONSTEXPR auto gcd(const uintwide_t& a, // NOLINT(readability-function-cognitive-complexity,bugprone-easily-swappable-parameters) - const uintwide_t& b) -> uintwide_t + constexpr auto gcd(const uintwide_t& a, // NOLINT(readability-function-cognitive-complexity,bugprone-easily-swappable-parameters) + const uintwide_t& b) -> uintwide_t { // This implementation of GCD is an adaptation // of existing code from Boost.Multiprecision. @@ -6581,17 +6481,17 @@ if(u == v) { // NOLINT(bugprone-branch-clone) // This handles cases having (u = v) and also (u = v = 0). - result = u; // LCOV_EXCL_LINE + result = std::move(u); // LCOV_EXCL_LINE } else if((static_cast(v) == static_cast(UINT8_C(0))) && (v == static_cast(UINT8_C(0)))) { // This handles cases having (v = 0) with (u != 0). - result = u; // LCOV_EXCL_LINE + result = std::move(u); // LCOV_EXCL_LINE } else if((static_cast(u) == static_cast(UINT8_C(0))) && (u == static_cast(UINT8_C(0)))) { // This handles cases having (u = 0) with (v != 0). - result = v; // LCOV_EXCL_LINE + result = std::move(v); // LCOV_EXCL_LINE } else { @@ -6655,21 +6555,44 @@ result = (u << left_shift_amount); } + + if(u_is_neg != v_is_neg) + { + result.negate(); + } - return ((u_is_neg == v_is_neg) ? result : -result); + return result; } template - WIDE_INTEGER_CONSTEXPR auto gcd(const UnsignedShortType& u, const UnsignedShortType& v) -> std::enable_if_t<( (std::is_integral::value) - && (std::is_unsigned::value)), UnsignedShortType> + constexpr auto gcd(const UnsignedShortType& u, const UnsignedShortType& v) -> std::enable_if_t<( (std::is_integral::value) + && (std::is_unsigned::value)), UnsignedShortType> { return detail::gcd_unsafe(u, v); } namespace detail { + // Use a local, constexpr, unsafe implementation of the abs-function. + template + constexpr auto abs_unsafe(ArithmeticType val) -> ArithmeticType + { + if(val > static_cast(INT8_C(0))) + { + return val; + } + else // NOLINT(llvm-else-after-return,readability-else-after-return) + { + ArithmeticType val_unsigned = std::move(val); + + val_unsigned.negate(); + + return val_unsigned; + } + } + template - WIDE_INTEGER_CONSTEXPR auto lcm_impl(const IntegerType& a, const IntegerType& b) -> IntegerType + constexpr auto lcm_impl(const IntegerType& a, const IntegerType& b) -> IntegerType { using local_integer_type = IntegerType; @@ -6690,15 +6613,15 @@ typename LimbType, typename AllocatorType, const bool IsSigned> - WIDE_INTEGER_CONSTEXPR auto lcm(const uintwide_t& a, - const uintwide_t& b) -> uintwide_t + constexpr auto lcm(const uintwide_t& a, + const uintwide_t& b) -> uintwide_t { return detail::lcm_impl(a, b); } template - WIDE_INTEGER_CONSTEXPR auto lcm(const UnsignedShortType& a, const UnsignedShortType& b) -> std::enable_if_t<( (std::is_integral::value) - && (std::is_unsigned::value)), UnsignedShortType> + constexpr auto lcm(const UnsignedShortType& a, const UnsignedShortType& b) -> std::enable_if_t<( (std::is_integral::value) + && (std::is_unsigned::value)), UnsignedShortType> { return detail::lcm_impl(a, b); } @@ -6708,10 +6631,9 @@ typename AllocatorType, const bool IsSignedLeft, const bool IsSignedRight> - WIDE_INTEGER_CONSTEXPR - auto divmod(const uintwide_t& a, - const uintwide_t& b, - std::enable_if_t<((!IsSignedLeft) && (!IsSignedRight)), int>* p_nullparam) -> std::pair, uintwide_t> + constexpr auto divmod(const uintwide_t& a, + const uintwide_t& b, + std::enable_if_t<((!IsSignedLeft) && (!IsSignedRight)), int>* p_nullparam) -> std::pair, uintwide_t> { static_cast(p_nullparam); @@ -6734,10 +6656,9 @@ typename AllocatorType, const bool IsSignedLeft, const bool IsSignedRight> - WIDE_INTEGER_CONSTEXPR - auto divmod(const uintwide_t& a, - const uintwide_t& b, - std::enable_if_t<(IsSignedLeft || IsSignedRight), int>* p_nullparam) -> std::pair, uintwide_t> + constexpr auto divmod(const uintwide_t& a, + const uintwide_t& b, + std::enable_if_t<(IsSignedLeft || IsSignedRight), int>* p_nullparam) -> std::pair, uintwide_t> { static_cast(p_nullparam); @@ -6803,7 +6724,7 @@ struct param_type { public: - explicit WIDE_INTEGER_CONSTEXPR + explicit constexpr param_type ( const result_type& p_a = (std::numeric_limits::min)(), // NOLINT(modernize-pass-by-value) @@ -6811,16 +6732,16 @@ ) : param_a(p_a), param_b(p_b) { } - WIDE_INTEGER_CONSTEXPR param_type(const param_type& other) : param_a(other.param_a), + constexpr param_type(const param_type& other) : param_a(other.param_a), param_b(other.param_b) { } - WIDE_INTEGER_CONSTEXPR param_type(param_type&& other) noexcept + constexpr param_type(param_type&& other) noexcept : param_a(static_cast(other.param_a)), param_b(static_cast(other.param_b)) { } ~param_type() = default; - WIDE_INTEGER_CONSTEXPR auto operator=(const param_type& other) -> param_type& // NOLINT(cert-oop54-cpp) + constexpr auto operator=(const param_type& other) -> param_type& // NOLINT(cert-oop54-cpp) { if(this != &other) { @@ -6831,7 +6752,7 @@ return *this; } - WIDE_INTEGER_CONSTEXPR auto operator=(param_type&& other) noexcept -> param_type& + constexpr auto operator=(param_type&& other) noexcept -> param_type& { param_a = other.param_a; param_b = other.param_b; @@ -6842,8 +6763,8 @@ WIDE_INTEGER_NODISCARD constexpr auto get_a() const -> result_type { return param_a; } WIDE_INTEGER_NODISCARD constexpr auto get_b() const -> result_type { return param_b; } - WIDE_INTEGER_CONSTEXPR auto set_a(const result_type& p_a) -> void { param_a = p_a; } - WIDE_INTEGER_CONSTEXPR auto set_b(const result_type& p_b) -> void { param_b = p_b; } + constexpr auto set_a(const result_type& p_a) -> void { param_a = p_a; } + constexpr auto set_b(const result_type& p_b) -> void { param_b = p_b; } private: result_type param_a; // NOLINT(readability-identifier-naming) @@ -6864,23 +6785,23 @@ } }; - explicit WIDE_INTEGER_CONSTEXPR + explicit constexpr uniform_int_distribution ( const result_type& p_a = (std::numeric_limits::min)(), const result_type& p_b = (std::numeric_limits::max)() ) : my_params(p_a, p_b) { } - explicit WIDE_INTEGER_CONSTEXPR uniform_int_distribution(const param_type& other_params) + explicit constexpr uniform_int_distribution(const param_type& other_params) : my_params(other_params) { } - WIDE_INTEGER_CONSTEXPR uniform_int_distribution(const uniform_int_distribution& other_distribution) = delete; + constexpr uniform_int_distribution(const uniform_int_distribution& other_distribution) = delete; - WIDE_INTEGER_CONSTEXPR uniform_int_distribution(uniform_int_distribution&& other) noexcept : my_params(other.my_params) { } + constexpr uniform_int_distribution(uniform_int_distribution&& other) noexcept : my_params(other.my_params) { } ~uniform_int_distribution() = default; - auto WIDE_INTEGER_CONSTEXPR operator=(const uniform_int_distribution& other) -> uniform_int_distribution& // NOLINT(cert-oop54-cpp) + auto constexpr operator=(const uniform_int_distribution& other) -> uniform_int_distribution& // NOLINT(cert-oop54-cpp) { if(this != &other) { @@ -6890,14 +6811,14 @@ return *this; } - auto WIDE_INTEGER_CONSTEXPR operator=(uniform_int_distribution&& other) noexcept -> uniform_int_distribution& + auto constexpr operator=(uniform_int_distribution&& other) noexcept -> uniform_int_distribution& { my_params = other.my_params; return *this; } - auto WIDE_INTEGER_CONSTEXPR param(const param_type& new_params) -> void + auto constexpr param(const param_type& new_params) -> void { my_params = new_params; } @@ -6909,7 +6830,7 @@ template::digits> - WIDE_INTEGER_CONSTEXPR auto operator()(GeneratorType& generator) -> result_type + constexpr auto operator()(GeneratorType& generator) -> result_type { return generate @@ -6921,7 +6842,7 @@ template::digits> - WIDE_INTEGER_CONSTEXPR auto operator()( GeneratorType& input_generator, + constexpr auto operator()( GeneratorType& input_generator, const param_type& input_params) -> result_type { return @@ -6937,7 +6858,7 @@ template::digits> - WIDE_INTEGER_CONSTEXPR auto generate( GeneratorType& input_generator, + constexpr auto generate( GeneratorType& input_generator, const param_type& input_params) const -> result_type { // Generate random numbers r, where a <= r <= b. @@ -7269,6 +7190,7 @@ typename LimbType, typename AllocatorType, const bool IsSigned> + constexpr auto to_chars(char* first, char* last, const uintwide_t& x, @@ -7427,6 +7349,53 @@ return result; } + + template + constexpr + auto from_chars(const char* first, + const char* last, + uintwide_t& x, + int base) -> std::from_chars_result + { + using local_wide_integer_type = uintwide_t; + + using local_wide_integer_type = uintwide_t; + using local_limb_type = typename local_wide_integer_type::limb_type; + + detail::fill_unsafe(x.values.begin(), x.values.end(), static_cast(UINT8_C(0))); + + const auto str_len = static_cast(detail::distance_unsafe(first, last)); + + const auto result_rd_string_is_ok = x.rd_string(first, str_len, base); + + std::from_chars_result result { }; + + if(result_rd_string_is_ok) + { + result = + std::from_chars_result + { + last, + std::errc() + }; + } + else + { + result = + std::from_chars_result + { + last, + std::errc::result_out_of_range + }; + + detail::fill_unsafe(x.values.begin(), x.values.end(), static_cast(UINT8_C(0))); + } + + return result; + } #endif #if !defined(WIDE_INTEGER_DISABLE_TO_STRING) @@ -7496,7 +7465,7 @@ typename LimbType, typename AllocatorType, std::enable_if_t::value_type>::digits == std::numeric_limits::digits> const*> - WIDE_INTEGER_CONSTEXPR + constexpr auto import_bits(uintwide_t& val, ForwardIterator first, ForwardIterator last, @@ -7621,7 +7590,7 @@ typename LimbType, typename AllocatorType, std::enable_if_t::value_type>::digits == std::numeric_limits::digits)> const*> - WIDE_INTEGER_CONSTEXPR + constexpr auto import_bits(uintwide_t& val, ForwardIterator first, ForwardIterator last, @@ -7713,7 +7682,7 @@ typename AllocatorType, const bool IsSigned, std::enable_if_t::value_type>::digits == std::numeric_limits::digits> const*> - WIDE_INTEGER_CONSTEXPR + constexpr auto export_bits(const uintwide_t& val, OutputIterator out, unsigned chunk_size, @@ -7731,12 +7700,12 @@ using local_result_value_type = typename detail::iterator_detail::iterator_traits::value_type; using local_input_value_type = typename local_unsigned_wide_integer_type::representation_type::value_type; - const auto val_unsigned = - ( - (!uintwide_t::is_neg(val)) - ? static_cast(val) - : static_cast(-val) - ); + local_unsigned_wide_integer_type val_unsigned(val); + + if(uintwide_t::is_neg(val)) + { + val_unsigned.negate(); + } static_assert(std::numeric_limits::digits == std::numeric_limits::digits, "Error: Erroneous mismatch for input element width and result uintwide_t limb width"); @@ -7829,7 +7798,7 @@ typename AllocatorType, const bool IsSigned, std::enable_if_t::value_type>::digits == std::numeric_limits::digits)> const*> - WIDE_INTEGER_CONSTEXPR + constexpr auto export_bits(const uintwide_t& val, OutputIterator out, unsigned chunk_size, @@ -7845,12 +7814,12 @@ using local_result_value_type = typename detail::iterator_detail::iterator_traits::value_type; using local_input_value_type = typename local_unsigned_wide_integer_type::representation_type::value_type; - const auto val_unsigned = - ( - (!uintwide_t::is_neg(val)) - ? static_cast(val) - : static_cast(-val) - ); + local_unsigned_wide_integer_type val_unsigned(val); + + if(uintwide_t::is_neg(val)) + { + val_unsigned.negate(); + } static_assert(std::numeric_limits::digits != std::numeric_limits::digits, "Error: Erroneous match for input element width and result uintwide_t limb width"); diff --git a/ref_app/src/mcal/mcal_reg_access_static.h b/ref_app/src/mcal/mcal_reg_access_static.h index 060986d7c..13385af2b 100644 --- a/ref_app/src/mcal/mcal_reg_access_static.h +++ b/ref_app/src/mcal/mcal_reg_access_static.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2023. +// Copyright Christopher Kormanyos 2007 - 2024. // Distributed under the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -54,7 +54,6 @@ } #if defined(__GNUC__) && (__GNUC__ >= 12) - // -Warray-bounds #pragma GCC diagnostic pop #endif diff --git a/ref_app/src/util/STL/charconv b/ref_app/src/util/STL/charconv index 4f4fd5e79..1cb80c4ec 100644 --- a/ref_app/src/util/STL/charconv +++ b/ref_app/src/util/STL/charconv @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2021 - 2023. +// Copyright Christopher Kormanyos 2021 - 2024. // Distributed under the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -39,13 +39,9 @@ to_chars_result to_chars(char* first, char* last, bool value, int base = 10) = delete; - inline to_chars_result to_chars(char* first, char* last, float value) { return to_chars_result{ }; } - inline to_chars_result to_chars(char* first, char* last, double value) { return to_chars_result{ }; } - inline to_chars_result to_chars(char* first, char* last, long double value) { return to_chars_result{ }; } - - //to_chars_result to_chars(char* first, char* last, float value, chars_format fmt); - //to_chars_result to_chars(char* first, char* last, double value, chars_format fmt); - //to_chars_result to_chars(char* first, char* last, long double value, chars_format fmt); + inline to_chars_result to_chars(char* first, char* last, float value) { static_cast(first); static_cast(last); static_cast(value); return to_chars_result{ }; } + inline to_chars_result to_chars(char* first, char* last, double value) { static_cast(first); static_cast(last); static_cast(value); return to_chars_result{ }; } + inline to_chars_result to_chars(char* first, char* last, long double value) { static_cast(first); static_cast(last); static_cast(value); return to_chars_result{ }; } } #endif // CHARCONV_2021_04_12_ diff --git a/ref_app/target/micros/atmega2560/make/atmega2560_flags.gmk b/ref_app/target/micros/atmega2560/make/atmega2560_flags.gmk index abf0bd2ef..f9e260128 100644 --- a/ref_app/target/micros/atmega2560/make/atmega2560_flags.gmk +++ b/ref_app/target/micros/atmega2560/make/atmega2560_flags.gmk @@ -1,5 +1,5 @@ # -# Copyright Christopher Kormanyos 2007 - 2021. +# Copyright Christopher Kormanyos 2007 - 2024. # Distributed under the Boost Software License, # Version 1.0. (See accompanying file LICENSE_1_0.txt # or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -10,7 +10,7 @@ # ------------------------------------------------------------------------------ ifneq ($(MAKE),make) -GCC_VERSION = 11.2.0 +GCC_VERSION = 13.2.0 endif GCC_TARGET = avr GCC_PREFIX = avr @@ -24,7 +24,7 @@ TGT_ALLFLAGS = -Os -finline-limit=32 \ -fsigned-char -ifeq ($(GCC_VERSION),11.2.0) +ifeq ($(GCC_VERSION),13.2.0) TGT_ALLFLAGS := $(TGT_ALLFLAGS) \ -mdouble=32 \ -mlong-double=64 diff --git a/ref_app/target/micros/atmega4809/make/atmega4809_flags.gmk b/ref_app/target/micros/atmega4809/make/atmega4809_flags.gmk index 9035157ae..858eb40e9 100644 --- a/ref_app/target/micros/atmega4809/make/atmega4809_flags.gmk +++ b/ref_app/target/micros/atmega4809/make/atmega4809_flags.gmk @@ -1,5 +1,5 @@ # -# Copyright Christopher Kormanyos 2007 - 2023. +# Copyright Christopher Kormanyos 2007 - 2024. # Distributed under the Boost Software License, # Version 1.0. (See accompanying file LICENSE_1_0.txt # or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -10,7 +10,7 @@ # ------------------------------------------------------------------------------ ifneq ($(MAKE),make) -GCC_VERSION = 12.3.0 +GCC_VERSION = 13.2.0 endif GCC_TARGET = avr GCC_PREFIX = avr @@ -25,7 +25,7 @@ TGT_ALLFLAGS = -O2 -finline-limit=16 \ -fsigned-char \ -ifeq ($(GCC_VERSION),12.3.0) +ifeq ($(GCC_VERSION),13.2.0) TGT_ALLFLAGS := $(TGT_ALLFLAGS) \ -mdouble=32 \ -mlong-double=64 diff --git a/ref_app/target/micros/avr/make/avr_flags.gmk b/ref_app/target/micros/avr/make/avr_flags.gmk index 744f2884a..945cd89db 100644 --- a/ref_app/target/micros/avr/make/avr_flags.gmk +++ b/ref_app/target/micros/avr/make/avr_flags.gmk @@ -1,5 +1,5 @@ # -# Copyright Christopher Kormanyos 2007 - 2023. +# Copyright Christopher Kormanyos 2007 - 2024. # Distributed under the Boost Software License, # Version 1.0. (See accompanying file LICENSE_1_0.txt # or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -10,7 +10,7 @@ # ------------------------------------------------------------------------------ ifneq ($(MAKE),make) -GCC_VERSION = 12.3.0 +GCC_VERSION = 13.2.0 endif GCC_TARGET = avr GCC_PREFIX = avr @@ -24,7 +24,7 @@ TGT_ALLFLAGS = -Os -finline-limit=32 \ -fsigned-char -ifeq ($(GCC_VERSION),12.3.0) +ifeq ($(GCC_VERSION),13.2.0) TGT_ALLFLAGS := $(TGT_ALLFLAGS) \ -mdouble=32 \ -mlong-double=64 diff --git a/ref_app/target/micros/v850es_fx2/make/v850es_fx2_flags.gmk b/ref_app/target/micros/v850es_fx2/make/v850es_fx2_flags.gmk index d1ca93e79..a60d37a66 100644 --- a/ref_app/target/micros/v850es_fx2/make/v850es_fx2_flags.gmk +++ b/ref_app/target/micros/v850es_fx2/make/v850es_fx2_flags.gmk @@ -1,5 +1,5 @@ # -# Copyright Christopher Kormanyos 2014 - 2021. +# Copyright Christopher Kormanyos 2014 - 2024. # Distributed under the Boost Software License, # Version 1.0. (See accompanying file LICENSE_1_0.txt # or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -9,7 +9,7 @@ # compiler flags for the target architecture # ------------------------------------------------------------------------------ -GCC_VERSION = 11.2.0 +GCC_VERSION = 13.2.0 GCC_TARGET = v850-unknown-elf GCC_PREFIX = v850-unknown-elf diff --git a/ref_app/target/micros/v850es_fx2/startup/crt0_init_ram.cpp b/ref_app/target/micros/v850es_fx2/startup/crt0_init_ram.cpp index 1cbe19efb..121aa05eb 100644 --- a/ref_app/target/micros/v850es_fx2/startup/crt0_init_ram.cpp +++ b/ref_app/target/micros/v850es_fx2/startup/crt0_init_ram.cpp @@ -1,10 +1,17 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2020. +// Copyright Christopher Kormanyos 2007 - 2024. // Distributed under the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) // +#if (defined(__GNUC__) && (__GNUC__ >= 12)) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Warray-bounds" +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstringop-overflow" +#endif + #include #include #include @@ -42,3 +49,8 @@ void crt::init_ram() static_cast(static_cast(&bss_end)), static_cast(0U)); } + +#if (defined(__GNUC__) && (__GNUC__ >= 12)) +#pragma GCC diagnostic pop +#pragma GCC diagnostic pop +#endif From f31c80ef5fde8bcfbad37ae30cdf379872842995 Mon Sep 17 00:00:00 2001 From: Christopher Kormanyos Date: Sat, 27 Jan 2024 12:21:05 +0100 Subject: [PATCH 2/4] Retry constexpr-ness --- .../benchmark/app_benchmark_wide_integer.cpp | 36 ++++++++++++------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/ref_app/src/app/benchmark/app_benchmark_wide_integer.cpp b/ref_app/src/app/benchmark/app_benchmark_wide_integer.cpp index 579c78c7e..bb95cee36 100644 --- a/ref_app/src/app/benchmark/app_benchmark_wide_integer.cpp +++ b/ref_app/src/app/benchmark/app_benchmark_wide_integer.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2018 - 2023. +// Copyright Christopher Kormanyos 2018 - 2024. // Distributed under the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -9,7 +9,14 @@ #if(APP_BENCHMARK_TYPE == APP_BENCHMARK_TYPE_WIDE_INTEGER) -#define WIDE_INTEGER_DISABLE_WIDE_INTEGER_CONSTEXPR +#if (defined(__GNUC__) && defined(__AVR__) && (__GNUC__ < 10)) +#define APP_BENCHMARK_WIDE_INTEGER_CONSTEXPR_OR_CONST constexpr // NOLINT(cppcoreguidelines-macro-usage) +#define APP_BENCHMARK_WIDE_INTEGER_CONSTEXPR_IS_COMPILE_TIME_CONSTANT 1 // NOLINT(cppcoreguidelines-macro-usage) +#else +#define APP_BENCHMARK_WIDE_INTEGER_CONSTEXPR_OR_CONST constexpr // NOLINT(cppcoreguidelines-macro-usage) +#define APP_BENCHMARK_WIDE_INTEGER_CONSTEXPR_IS_COMPILE_TIME_CONSTANT 1 // NOLINT(cppcoreguidelines-macro-usage) +#endif + #define WIDE_INTEGER_DISABLE_IOSTREAM #define WIDE_INTEGER_DISABLE_TO_STRING #define WIDE_INTEGER_DISABLE_IMPLEMENT_UTIL_DYNAMIC_ARRAY @@ -56,16 +63,17 @@ namespace // Modulus: // a % b = 0x14998D5CA3DB6385F7DEDF4621DE48A9104AC13797C6567713D7ABC216D7AB4C - WIDE_INTEGER_CONSTEXPR uint256_t a("0xF4DF741DE58BCB2F37F18372026EF9CBCFC456CB80AF54D53BDEED78410065DE"); - WIDE_INTEGER_CONSTEXPR uint256_t b("0x166D63E0202B3D90ECCEAA046341AB504658F55B974A7FD63733ECF89DD0DF75"); - WIDE_INTEGER_CONSTEXPR uint512_t c("0x1573D6A7CEA734D99865C4F428184983CDB018B80E9CC44B83C773FBE11993E7E491A360C57EB4306C61F9A04F7F7D99BE3676AAD2D71C5592D5AE70F84AF076"); - WIDE_INTEGER_CONSTEXPR uint256_t m("0x14998D5CA3DB6385F7DEDF4621DE48A9104AC13797C6567713D7ABC216D7AB4C"); + APP_BENCHMARK_WIDE_INTEGER_CONSTEXPR_OR_CONST uint256_t a("0xF4DF741DE58BCB2F37F18372026EF9CBCFC456CB80AF54D53BDEED78410065DE"); + APP_BENCHMARK_WIDE_INTEGER_CONSTEXPR_OR_CONST uint256_t b("0x166D63E0202B3D90ECCEAA046341AB504658F55B974A7FD63733ECF89DD0DF75"); + APP_BENCHMARK_WIDE_INTEGER_CONSTEXPR_OR_CONST uint512_t c("0x1573D6A7CEA734D99865C4F428184983CDB018B80E9CC44B83C773FBE11993E7E491A360C57EB4306C61F9A04F7F7D99BE3676AAD2D71C5592D5AE70F84AF076"); + APP_BENCHMARK_WIDE_INTEGER_CONSTEXPR_OR_CONST uint256_t m("0x14998D5CA3DB6385F7DEDF4621DE48A9104AC13797C6567713D7ABC216D7AB4C"); auto run_wide_integer_mul() -> bool { - WIDE_INTEGER_CONSTEXPR auto result_of_mul_is_ok = ((uint512_t(a) * uint512_t(b)) == c); + APP_BENCHMARK_WIDE_INTEGER_CONSTEXPR_OR_CONST auto result_of_mul_is_ok = ((uint512_t(a) * uint512_t(b)) == c); - #if (defined(WIDE_INTEGER_CONSTEXPR_IS_COMPILE_TIME_CONST) && (WIDE_INTEGER_CONSTEXPR_IS_COMPILE_TIME_CONST != 0)) + #if (defined(APP_BENCHMARK_WIDE_INTEGER_CONSTEXPR_IS_COMPILE_TIME_CONSTANT) \ + && (APP_BENCHMARK_WIDE_INTEGER_CONSTEXPR_IS_COMPILE_TIME_CONSTANT == 1)) static_assert(result_of_mul_is_ok == true, "Error: result_of_mul_is_ok not OK!"); #endif @@ -74,11 +82,12 @@ namespace auto run_wide_integer_div() -> bool { - WIDE_INTEGER_CONSTEXPR uint256_t q(static_cast(UINT8_C(10))); + APP_BENCHMARK_WIDE_INTEGER_CONSTEXPR_OR_CONST uint256_t q(static_cast(UINT8_C(10))); - WIDE_INTEGER_CONSTEXPR auto result_of_div_is_ok = ((a / b) == q); + APP_BENCHMARK_WIDE_INTEGER_CONSTEXPR_OR_CONST auto result_of_div_is_ok = ((a / b) == q); - #if (defined(WIDE_INTEGER_CONSTEXPR_IS_COMPILE_TIME_CONST) && (WIDE_INTEGER_CONSTEXPR_IS_COMPILE_TIME_CONST != 0)) + #if (defined(APP_BENCHMARK_WIDE_INTEGER_CONSTEXPR_IS_COMPILE_TIME_CONSTANT) \ + && (APP_BENCHMARK_WIDE_INTEGER_CONSTEXPR_IS_COMPILE_TIME_CONSTANT == 1)) static_assert(result_of_div_is_ok == true, "Error: result_of_div_is_ok not OK!"); #endif @@ -87,9 +96,10 @@ namespace auto run_wide_integer_mod() -> bool { - WIDE_INTEGER_CONSTEXPR auto result_of_mod_is_ok = ((a % b) == m); + APP_BENCHMARK_WIDE_INTEGER_CONSTEXPR_OR_CONST auto result_of_mod_is_ok = ((a % b) == m); - #if (defined(WIDE_INTEGER_CONSTEXPR_IS_COMPILE_TIME_CONST) && (WIDE_INTEGER_CONSTEXPR_IS_COMPILE_TIME_CONST != 0)) + #if (defined(APP_BENCHMARK_WIDE_INTEGER_CONSTEXPR_IS_COMPILE_TIME_CONSTANT) \ + && (APP_BENCHMARK_WIDE_INTEGER_CONSTEXPR_IS_COMPILE_TIME_CONSTANT == 1)) static_assert(result_of_mod_is_ok == true, "Error: result_of_div_is_ok not OK!"); #endif From cb3586417577c6154f0d013e1f361d94fac95657 Mon Sep 17 00:00:00 2001 From: Christopher Kormanyos Date: Sat, 27 Jan 2024 12:33:00 +0100 Subject: [PATCH 3/4] Handle non-constexpr-ness on old __AVR__ --- ref_app/src/app/benchmark/app_benchmark_wide_integer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ref_app/src/app/benchmark/app_benchmark_wide_integer.cpp b/ref_app/src/app/benchmark/app_benchmark_wide_integer.cpp index bb95cee36..affacc4c5 100644 --- a/ref_app/src/app/benchmark/app_benchmark_wide_integer.cpp +++ b/ref_app/src/app/benchmark/app_benchmark_wide_integer.cpp @@ -10,8 +10,8 @@ #if(APP_BENCHMARK_TYPE == APP_BENCHMARK_TYPE_WIDE_INTEGER) #if (defined(__GNUC__) && defined(__AVR__) && (__GNUC__ < 10)) -#define APP_BENCHMARK_WIDE_INTEGER_CONSTEXPR_OR_CONST constexpr // NOLINT(cppcoreguidelines-macro-usage) -#define APP_BENCHMARK_WIDE_INTEGER_CONSTEXPR_IS_COMPILE_TIME_CONSTANT 1 // NOLINT(cppcoreguidelines-macro-usage) +#define APP_BENCHMARK_WIDE_INTEGER_CONSTEXPR_OR_CONST cons // NOLINT(cppcoreguidelines-macro-usage) +#define APP_BENCHMARK_WIDE_INTEGER_CONSTEXPR_IS_COMPILE_TIME_CONSTANT 0 // NOLINT(cppcoreguidelines-macro-usage) #else #define APP_BENCHMARK_WIDE_INTEGER_CONSTEXPR_OR_CONST constexpr // NOLINT(cppcoreguidelines-macro-usage) #define APP_BENCHMARK_WIDE_INTEGER_CONSTEXPR_IS_COMPILE_TIME_CONSTANT 1 // NOLINT(cppcoreguidelines-macro-usage) From f39e449bf90513a29bce7a72f09b7bf299d51daa Mon Sep 17 00:00:00 2001 From: Christopher Kormanyos Date: Sat, 27 Jan 2024 12:42:53 +0100 Subject: [PATCH 4/4] Repair a macro typo --- ref_app/src/app/benchmark/app_benchmark_wide_integer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ref_app/src/app/benchmark/app_benchmark_wide_integer.cpp b/ref_app/src/app/benchmark/app_benchmark_wide_integer.cpp index affacc4c5..db97c3adb 100644 --- a/ref_app/src/app/benchmark/app_benchmark_wide_integer.cpp +++ b/ref_app/src/app/benchmark/app_benchmark_wide_integer.cpp @@ -10,7 +10,7 @@ #if(APP_BENCHMARK_TYPE == APP_BENCHMARK_TYPE_WIDE_INTEGER) #if (defined(__GNUC__) && defined(__AVR__) && (__GNUC__ < 10)) -#define APP_BENCHMARK_WIDE_INTEGER_CONSTEXPR_OR_CONST cons // NOLINT(cppcoreguidelines-macro-usage) +#define APP_BENCHMARK_WIDE_INTEGER_CONSTEXPR_OR_CONST const // NOLINT(cppcoreguidelines-macro-usage) #define APP_BENCHMARK_WIDE_INTEGER_CONSTEXPR_IS_COMPILE_TIME_CONSTANT 0 // NOLINT(cppcoreguidelines-macro-usage) #else #define APP_BENCHMARK_WIDE_INTEGER_CONSTEXPR_OR_CONST constexpr // NOLINT(cppcoreguidelines-macro-usage)