From 52e00339f8eab34571f9ad8446cf31037f443fcb Mon Sep 17 00:00:00 2001 From: Yaraslau Tamashevich Date: Fri, 21 Jun 2024 19:35:29 +0300 Subject: [PATCH] Add division check for debug mode --- .github/workflows/build.yml | 10 +++++----- CMakeLists.txt | 3 +++ include/boxed-cpp/boxed.hpp | 40 ++++++++++++++++++++++++++++++++++++- test-boxed-cpp.cpp | 27 +++++++++++++++++++++++++ 4 files changed, 74 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b02eec7..dac5f9a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,17 +11,17 @@ on: jobs: check_clang_format: name: "Check C++ style" - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v3 - name: Install clang run: | wget https://apt.llvm.org/llvm.sh chmod +x llvm.sh - sudo ./llvm.sh 17 - sudo apt-get install clang-format-17 + sudo ./llvm.sh 18 + sudo apt-get install clang-format-18 - name: "Clang-format" - run: clang-format-17 --Werror --dry-run test-boxed-cpp.cpp include/boxed-cpp/boxed.hpp + run: clang-format-18 --Werror --dry-run test-boxed-cpp.cpp include/boxed-cpp/boxed.hpp editorconfig: name: "Check editorconfig" @@ -37,7 +37,7 @@ jobs: matrix: os: [ubuntu-24.04, ubuntu-22.04] cxx: [20] - build_type: ["RelWithDebInfo"] + build_type: ["RelWithDebInfo", "Debug"] llvm_version: [ "17", diff --git a/CMakeLists.txt b/CMakeLists.txt index 75d5ca9..ee9914f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,9 @@ target_include_directories(boxed-cpp INTERFACE $ $ ) +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + target_compile_definitions(boxed-cpp INTERFACE BOXED_DEBUG) +endif() # Generate the version, config and target files include(CMakePackageConfigHelpers) diff --git a/include/boxed-cpp/boxed.hpp b/include/boxed-cpp/boxed.hpp index 5577971..e9f427e 100644 --- a/include/boxed-cpp/boxed.hpp +++ b/include/boxed-cpp/boxed.hpp @@ -4,7 +4,11 @@ #include #include #include +#include #include +#if defined(BOXED_DEBUG) + #include +#endif namespace boxed { @@ -126,7 +130,41 @@ template constexpr boxed& operator/=(boxed& template constexpr boxed& operator%=(boxed& a, boxed const& b) noexcept { a.value %= b.value; return a; } template std::ostream& operator<<(std::ostream& os, boxed const& v) { return os << v.value; } - // clang-format on + +// clang-format on +#if defined(BOXED_DEBUG) + + template + constexpr boxed operator/(boxed const& a, boxed const& b) + { + auto div = std::div(b.value, a.value); + if (div.rem != 0) + throw std::invalid_argument("Division is not exact"); + return boxed { div.quot }; + } + + template + constexpr boxed operator/(boxed const& a, T b) + { + return a / boxed { b }; + } + + template + constexpr boxed operator/(T b, boxed const& a) + { + return boxed { b } / a; + } + + template + constexpr boxed& operator/=(boxed& a, boxed const& b) + { + auto res = a / b; + a = res; + return a; + } + +#endif + } // namespace detail namespace helper diff --git a/test-boxed-cpp.cpp b/test-boxed-cpp.cpp index 7550fd1..537d434 100644 --- a/test-boxed-cpp.cpp +++ b/test-boxed-cpp.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -216,6 +217,32 @@ TEST_CASE("advanced") REQUIRE(x_coord(phi, theta, rho) == x_coord(phi, theta, rho)); } +TEST_CASE("devision of integral_types") +{ + using Int = boxed::boxed; + int int_a { 10 }; + Int Int_a { 10 }; + int int_b { 3 }; + Int Int_b { 3 }; +#if defined(BOXED_DEBUG) + REQUIRE_THROWS_AS(int_a / Int_b, std::invalid_argument); + REQUIRE_THROWS_AS(Int_a / int_b, std::invalid_argument); + REQUIRE_THROWS_AS(Int_a / Int_b, std::invalid_argument); + REQUIRE_THROWS_AS( + [&]() { + Int_a /= Int_b; + }(), + std::invalid_argument); + +#else + REQUIRE(unbox(int_a / Int_b) == 3); + REQUIRE(unbox(Int_a / int_b) == 3); + REQUIRE(unbox(Int_a / Int_b) == 3); + Int_a /= Int_b; + REQUIRE(unbox(Int_a) == 3); +#endif +} + #ifdef __has_include #if __has_include() #include