From 0f9469eca61f58e209d07f9b9584b4b06bae85a9 Mon Sep 17 00:00:00 2001 From: guza Date: Sat, 16 Mar 2024 16:52:07 +0800 Subject: [PATCH 1/5] add package target and the example of for-error --- CMakeLists.txt | 22 +++++++++++++++++----- examples/for-error.cc | 27 +++++++++++++++++++++++++++ src/include/integer.hh | 28 +++++++++++++++++++++++++--- src/include/uinteger.hh | 22 ++++++++++++++++++++++ 4 files changed, 91 insertions(+), 8 deletions(-) create mode 100644 examples/for-error.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index a33c0e5..d3ab543 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,10 @@ set(BUILD_SHARED_LIBS OFF) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(version 0.0.2) + +project(numbers VERSION ${version} LANGUAGES CXX) + string(COMPARE EQUAL ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR} PROJECT_IS_TOP_LEVEL) if (PROJECT_IS_TOP_LEVEL) @@ -12,11 +16,7 @@ endif() option(NUMBERS_TEST "Build and perform numbers tests" ${PROJECT_IS_TOP_LEVEL}) -set(version 0.0.2) - -project(numbers VERSION ${version} LANGUAGES CXX) - -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +set(CMAKE_EXPORT_COMPILE_COMMANDS ${PROJECT_IS_TOP_LEVEL}) # Includes. set(SRC_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/src/include) @@ -35,4 +35,16 @@ if (NUMBERS_TEST) add_subdirectory(examples) add_subdirectory(third_party) add_subdirectory(tests) + + # Provide only the minimum source files needed by downstream users + set(package_files src/ CMakeLists.txt LICENSE.txt) + set(packaged_zip ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-src.zip) + add_custom_command( + OUTPUT ${packaged_zip} + COMMAND ${CMAKE_COMMAND} -E tar c ${packaged_zip} --format=zip -- ${package_files} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMENT "The source files have been packaged into ${packaged_zip}" + DEPENDS ${package_files} + ) + add_custom_target(package DEPENDS ${packaged_zip}) endif() diff --git a/examples/for-error.cc b/examples/for-error.cc new file mode 100644 index 0000000..2add76e --- /dev/null +++ b/examples/for-error.cc @@ -0,0 +1,27 @@ +#include +#include + +#include "numbers.h" + +void for_error() { + size_t i; + + for (i = 10; i >= 0; i--) { + printf("[ID %u] Hello, World\n", i); + } +} + +void for_correct() { + using namespace numbers; + + u8 i; + bool flag = false; + for (i = 10; !flag && i >= 0; std::tie(i, flag) = i.overflowing_sub(1)) { + printf("[ID %u] Hello, World\n", i); + } +} + +int main(int argc, char const *argv[]) { + for_correct(); + return 0; +} diff --git a/src/include/integer.hh b/src/include/integer.hh index a8a0427..7dc0d0f 100644 --- a/src/include/integer.hh +++ b/src/include/integer.hh @@ -210,9 +210,11 @@ class Integer { return Integer(-num_); } - constexpr bool operator==(const Integer &other) const noexcept { return num_ == other.num_; } - constexpr bool operator<(const Integer &other) const noexcept { return num_ < other.num_; } - constexpr bool operator>(const Integer &other) const noexcept { return num_ > other.num_; } + constexpr bool operator==(Integer other) const noexcept { return num_ == other.num_; } + constexpr bool operator<(Integer other) const noexcept { return num_ < other.num_; } + constexpr bool operator>(Integer other) const noexcept { return num_ > other.num_; } + constexpr bool operator<=(Integer other) const noexcept { return num_ <= other.num_; } + constexpr bool operator>=(Integer other) const noexcept { return num_ >= other.num_; } Integer &operator+=(Integer other) { *this = *this + other; @@ -401,6 +403,26 @@ constexpr bool operator==(U lhs, Integer rhs) noexcept { return Integer(lhs) == rhs; } +template && std::is_convertible_v>> +constexpr bool operator>(U lhs, Integer rhs) noexcept { + return Integer(lhs) > rhs; +} + +template && std::is_convertible_v>> +constexpr bool operator>=(U lhs, Integer rhs) noexcept { + return Integer(lhs) >= rhs; +} + +template && std::is_convertible_v>> +constexpr bool operator<(U lhs, Integer rhs) noexcept { + return Integer(lhs) < rhs; +} + +template && std::is_convertible_v>> +constexpr bool operator<=(U lhs, Integer rhs) noexcept { + return Integer(lhs) <= rhs; +} + using i8 = Integer; using i16 = Integer; using i32 = Integer; diff --git a/src/include/uinteger.hh b/src/include/uinteger.hh index a39bb0f..1cdf2d0 100644 --- a/src/include/uinteger.hh +++ b/src/include/uinteger.hh @@ -169,6 +169,8 @@ class Uinteger { constexpr bool operator==(Uinteger other) const noexcept { return num_ == other.num_; } constexpr bool operator<(Uinteger other) const noexcept { return num_ < other.num_; } constexpr bool operator>(Uinteger other) const noexcept { return num_ > other.num_; } + constexpr bool operator<=(Uinteger other) const noexcept { return num_ <= other.num_; } + constexpr bool operator>=(Uinteger other) const noexcept { return num_ >= other.num_; } Uinteger &operator+=(Uinteger other) { *this = *this + other; @@ -340,6 +342,26 @@ constexpr bool operator==(U lhs, Uinteger rhs) noexcept { return Uinteger(lhs) == rhs; } +template >> +constexpr bool operator>(U lhs, Uinteger rhs) noexcept { + return Uinteger(lhs) > rhs; +} + +template >> +constexpr bool operator>=(U lhs, Uinteger rhs) noexcept { + return Uinteger(lhs) >= rhs; +} + +template >> +constexpr bool operator<(U lhs, Uinteger rhs) noexcept { + return Uinteger(lhs) < rhs; +} + +template >> +constexpr bool operator<=(U lhs, Uinteger rhs) noexcept { + return Uinteger(lhs) <= rhs; +} + using u8 = Uinteger; using u16 = Uinteger; using u32 = Uinteger; From b3098a07a82836ff4297e54ef4c115d3854caba4 Mon Sep 17 00:00:00 2001 From: Paulden Date: Sat, 16 Mar 2024 22:09:37 +0800 Subject: [PATCH 2/5] add release workflows --- .github/workflows/release.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..369ad48 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,23 @@ +name: Release + +on: + release: + types: [published] + +jobs: + release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Create build environment + run: cmake -B build-release + - name: Package source code + working-directory: build-release/ + run: cmake --build . --target package + - name: Add packaged source code to release + uses: svenstaro/upload-release-action@v2 + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + file: build-release/numbers-src.zip + tag: ${{ github.ref }} \ No newline at end of file From 296f53979037674d2b1e7850e742cd30b21489f5 Mon Sep 17 00:00:00 2001 From: Paulden Date: Sun, 17 Mar 2024 11:09:07 +0800 Subject: [PATCH 3/5] refactor CMakeLists; enhance usability --- CMakeLists.txt | 23 +++++++++++-------- examples/{for-error.cc => overflowing-sub.cc} | 1 + src/CMakeLists.txt | 4 ++-- 3 files changed, 17 insertions(+), 11 deletions(-) rename examples/{for-error.cc => overflowing-sub.cc} (94%) diff --git a/CMakeLists.txt b/CMakeLists.txt index d3ab543..f45faec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,22 +1,27 @@ cmake_minimum_required(VERSION 3.10) -set(BUILD_SHARED_LIBS OFF) -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -set(version 0.0.2) +set(version 0.0.3) project(numbers VERSION ${version} LANGUAGES CXX) +set(BUILD_SHARED_LIBS OFF) + string(COMPARE EQUAL ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR} PROJECT_IS_TOP_LEVEL) -if (PROJECT_IS_TOP_LEVEL) - message(STATUS "Project is top level") +set(CMAKE_EXPORT_COMPILE_COMMANDS ${PROJECT_IS_TOP_LEVEL}) + +if (PROJECT_IS_TOP_LEVEL) + set(CMAKE_CXX_STANDARD 17) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + message(STATUS "Project ${PROJECT_NAME} is top level") endif() -option(NUMBERS_TEST "Build and perform numbers tests" ${PROJECT_IS_TOP_LEVEL}) +# Check if the compiler supports C++17 +if(NOT CMAKE_CXX_STANDARD OR CMAKE_CXX_STANDARD LESS 17) + message(FATAL_ERROR "Error: ${PROJECT_NAME} is a library for C++17 and later versions.") +endif() -set(CMAKE_EXPORT_COMPILE_COMMANDS ${PROJECT_IS_TOP_LEVEL}) +option(NUMBERS_TEST "Build and perform ${PROJECT_NAME} tests" ${PROJECT_IS_TOP_LEVEL}) # Includes. set(SRC_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/src/include) diff --git a/examples/for-error.cc b/examples/overflowing-sub.cc similarity index 94% rename from examples/for-error.cc rename to examples/overflowing-sub.cc index 2add76e..d9e567d 100644 --- a/examples/for-error.cc +++ b/examples/overflowing-sub.cc @@ -6,6 +6,7 @@ void for_error() { size_t i; + // error - infinite loop for (i = 10; i >= 0; i--) { printf("[ID %u] Hello, World\n", i); } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5570d8d..0471082 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,7 +1,7 @@ add_subdirectory(numbers) -add_library(numbers STATIC ${ALL_OBJECT_FILES}) +add_library(${PROJECT_NAME} STATIC ${ALL_OBJECT_FILES}) -target_include_directories(numbers PUBLIC $ +target_include_directories(${PROJECT_NAME} PUBLIC $ $ ) From a581c43fe3e4b56dacb448ac3ca52ed173bfcd88 Mon Sep 17 00:00:00 2001 From: Paulden Date: Sun, 17 Mar 2024 16:32:30 +0800 Subject: [PATCH 4/5] format CMakeLists --- CMakeLists.txt | 54 +++++++++++++++++------------------ src/CMakeLists.txt | 2 +- src/numbers/CMakeLists.txt | 10 +++---- tests/integer/CMakeLists.txt | 22 +++++++------- tests/uinteger/CMakeLists.txt | 22 +++++++------- tests/utils/CMakeLists.txt | 12 ++++---- 6 files changed, 61 insertions(+), 61 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f45faec..1369929 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,15 +10,15 @@ string(COMPARE EQUAL ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR} PROJECT_IS_ set(CMAKE_EXPORT_COMPILE_COMMANDS ${PROJECT_IS_TOP_LEVEL}) -if (PROJECT_IS_TOP_LEVEL) - set(CMAKE_CXX_STANDARD 17) - set(CMAKE_CXX_STANDARD_REQUIRED ON) - message(STATUS "Project ${PROJECT_NAME} is top level") +if(PROJECT_IS_TOP_LEVEL) + set(CMAKE_CXX_STANDARD 17) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + message(STATUS "Project ${PROJECT_NAME} is top level") endif() # Check if the compiler supports C++17 if(NOT CMAKE_CXX_STANDARD OR CMAKE_CXX_STANDARD LESS 17) - message(FATAL_ERROR "Error: ${PROJECT_NAME} is a library for C++17 and later versions.") + message(FATAL_ERROR "Error: ${PROJECT_NAME} is a library for C++17 and later versions.") endif() option(NUMBERS_TEST "Build and perform ${PROJECT_NAME} tests" ${PROJECT_IS_TOP_LEVEL}) @@ -30,26 +30,26 @@ include_directories(${SRC_INCLUDE_DIR}) add_subdirectory(src) -if (NUMBERS_TEST) - message(STATUS "Building and running tests") - set(THIRD_PARTY_INCLUDE_DIR - ${PROJECT_SOURCE_DIR}/third_party - ) - include_directories(${THIRD_PARTY_INCLUDE_DIR}) - - add_subdirectory(examples) - add_subdirectory(third_party) - add_subdirectory(tests) - - # Provide only the minimum source files needed by downstream users - set(package_files src/ CMakeLists.txt LICENSE.txt) - set(packaged_zip ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-src.zip) - add_custom_command( - OUTPUT ${packaged_zip} - COMMAND ${CMAKE_COMMAND} -E tar c ${packaged_zip} --format=zip -- ${package_files} - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - COMMENT "The source files have been packaged into ${packaged_zip}" - DEPENDS ${package_files} - ) - add_custom_target(package DEPENDS ${packaged_zip}) +if(NUMBERS_TEST) + message(STATUS "Building and running tests") + set(THIRD_PARTY_INCLUDE_DIR + ${PROJECT_SOURCE_DIR}/third_party + ) + include_directories(${THIRD_PARTY_INCLUDE_DIR}) + + add_subdirectory(examples) + add_subdirectory(third_party) + add_subdirectory(tests) + + # Provide only the minimum source files needed by downstream users + set(package_files src/ CMakeLists.txt LICENSE.txt) + set(packaged_zip ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-src.zip) + add_custom_command( + OUTPUT ${packaged_zip} + COMMAND ${CMAKE_COMMAND} -E tar c ${packaged_zip} --format=zip -- ${package_files} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMENT "The source files have been packaged into ${packaged_zip}" + DEPENDS ${package_files} + ) + add_custom_target(package DEPENDS ${packaged_zip}) endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0471082..e9cebbe 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,5 +3,5 @@ add_subdirectory(numbers) add_library(${PROJECT_NAME} STATIC ${ALL_OBJECT_FILES}) target_include_directories(${PROJECT_NAME} PUBLIC $ - $ + $ ) diff --git a/src/numbers/CMakeLists.txt b/src/numbers/CMakeLists.txt index bbd2392..49d7422 100644 --- a/src/numbers/CMakeLists.txt +++ b/src/numbers/CMakeLists.txt @@ -1,11 +1,11 @@ file(GLOB obj_files "${CMAKE_CURRENT_SOURCE_DIR}/*.cc") add_library( - numbers_obj - OBJECT - ${obj_files} + numbers_obj + OBJECT + ${obj_files} ) set(ALL_OBJECT_FILES - ${ALL_OBJECT_FILES} $ - PARENT_SCOPE) \ No newline at end of file + ${ALL_OBJECT_FILES} $ + PARENT_SCOPE) \ No newline at end of file diff --git a/tests/integer/CMakeLists.txt b/tests/integer/CMakeLists.txt index f2a6a6c..b691a48 100644 --- a/tests/integer/CMakeLists.txt +++ b/tests/integer/CMakeLists.txt @@ -3,25 +3,25 @@ file(GLOB_RECURSE test_files "${CMAKE_CURRENT_SOURCE_DIR}/*.test.cc") set(PROJECT_NAME integer_test) add_executable( - ${PROJECT_NAME} - EXCLUDE_FROM_ALL - ${test_files} + ${PROJECT_NAME} + EXCLUDE_FROM_ALL + ${test_files} ) target_link_libraries(${PROJECT_NAME} PRIVATE numbers_obj test_utils gtest gmock_main) gtest_discover_tests(${PROJECT_NAME} - EXTRA_ARGS - --gtest_output=xml:${CMAKE_BINARY_DIR}/test/${PROJECT_NAME}.xml - --gtest_catch_exceptions=0 - DISCOVERY_TIMEOUT 120 - PROPERTIES - TIMEOUT 120 + EXTRA_ARGS + --gtest_output=xml:${CMAKE_BINARY_DIR}/test/${PROJECT_NAME}.xml + --gtest_catch_exceptions=0 + DISCOVERY_TIMEOUT 120 + PROPERTIES + TIMEOUT 120 ) set_target_properties(${PROJECT_NAME} - PROPERTIES - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/test" + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/test" ) list(APPEND TEST_TARGETS ${PROJECT_NAME} PARENT_SCOPE) diff --git a/tests/uinteger/CMakeLists.txt b/tests/uinteger/CMakeLists.txt index 9393b16..601de01 100644 --- a/tests/uinteger/CMakeLists.txt +++ b/tests/uinteger/CMakeLists.txt @@ -3,25 +3,25 @@ file(GLOB_RECURSE test_files "${CMAKE_CURRENT_SOURCE_DIR}/*.test.cc") set(PROJECT_NAME uinteger_test) add_executable( - ${PROJECT_NAME} - EXCLUDE_FROM_ALL - ${test_files} + ${PROJECT_NAME} + EXCLUDE_FROM_ALL + ${test_files} ) target_link_libraries(${PROJECT_NAME} PRIVATE numbers_obj test_utils gtest gmock_main) gtest_discover_tests(${PROJECT_NAME} - EXTRA_ARGS - --gtest_output=xml:${CMAKE_BINARY_DIR}/test/${PROJECT_NAME}.xml - --gtest_catch_exceptions=0 - DISCOVERY_TIMEOUT 120 - PROPERTIES - TIMEOUT 120 + EXTRA_ARGS + --gtest_output=xml:${CMAKE_BINARY_DIR}/test/${PROJECT_NAME}.xml + --gtest_catch_exceptions=0 + DISCOVERY_TIMEOUT 120 + PROPERTIES + TIMEOUT 120 ) set_target_properties(${PROJECT_NAME} - PROPERTIES - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/test" + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/test" ) list(APPEND TEST_TARGETS ${PROJECT_NAME} PARENT_SCOPE) diff --git a/tests/utils/CMakeLists.txt b/tests/utils/CMakeLists.txt index d27b7f5..fdf7004 100644 --- a/tests/utils/CMakeLists.txt +++ b/tests/utils/CMakeLists.txt @@ -1,10 +1,10 @@ add_library( - test_utils - EXCLUDE_FROM_ALL - OBJECT - utils.cc + test_utils + EXCLUDE_FROM_ALL + OBJECT + utils.cc ) set(ALL_OBJECT_FILES - ${ALL_OBJECT_FILES} $ - PARENT_SCOPE) \ No newline at end of file + ${ALL_OBJECT_FILES} $ + PARENT_SCOPE) \ No newline at end of file From 76b4972cd3ae84806847a48618526384b4787ada Mon Sep 17 00:00:00 2001 From: Paulden Date: Sun, 17 Mar 2024 21:25:47 +0800 Subject: [PATCH 5/5] add alias for library name --- CMakeLists.txt | 16 ++++++++++------ src/CMakeLists.txt | 1 + 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1369929..0e4a60d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,14 +6,14 @@ project(numbers VERSION ${version} LANGUAGES CXX) set(BUILD_SHARED_LIBS OFF) -string(COMPARE EQUAL ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR} PROJECT_IS_TOP_LEVEL) +string(COMPARE EQUAL ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR} PROJECT_IS_IN_ROOT) -set(CMAKE_EXPORT_COMPILE_COMMANDS ${PROJECT_IS_TOP_LEVEL}) +set(CMAKE_EXPORT_COMPILE_COMMANDS ${PROJECT_IS_IN_ROOT}) -if(PROJECT_IS_TOP_LEVEL) +if(PROJECT_IS_IN_ROOT) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) - message(STATUS "Project ${PROJECT_NAME} is top level") + message(STATUS "Project ${PROJECT_NAME} is in root") endif() # Check if the compiler supports C++17 @@ -21,7 +21,8 @@ if(NOT CMAKE_CXX_STANDARD OR CMAKE_CXX_STANDARD LESS 17) message(FATAL_ERROR "Error: ${PROJECT_NAME} is a library for C++17 and later versions.") endif() -option(NUMBERS_TEST "Build and perform ${PROJECT_NAME} tests" ${PROJECT_IS_TOP_LEVEL}) +option(NUMBERS_TEST "Build and perform ${PROJECT_NAME} tests" ${PROJECT_IS_IN_ROOT}) +option(NUMBERS_EXAMPLE "Build and perform ${PROJECT_NAME} examples" ${PROJECT_IS_IN_ROOT}) # Includes. set(SRC_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/src/include) @@ -30,6 +31,10 @@ include_directories(${SRC_INCLUDE_DIR}) add_subdirectory(src) +if(NUMBERS_EXAMPLE) + add_subdirectory(examples) +endif() + if(NUMBERS_TEST) message(STATUS "Building and running tests") set(THIRD_PARTY_INCLUDE_DIR @@ -37,7 +42,6 @@ if(NUMBERS_TEST) ) include_directories(${THIRD_PARTY_INCLUDE_DIR}) - add_subdirectory(examples) add_subdirectory(third_party) add_subdirectory(tests) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e9cebbe..2565205 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,6 +1,7 @@ add_subdirectory(numbers) add_library(${PROJECT_NAME} STATIC ${ALL_OBJECT_FILES}) +add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) target_include_directories(${PROJECT_NAME} PUBLIC $ $