diff --git a/.github/workflows/ci_tests.yml b/.github/workflows/ci_tests.yml index 65b2ccc..4c56911 100644 --- a/.github/workflows/ci_tests.yml +++ b/.github/workflows/ci_tests.yml @@ -11,21 +11,31 @@ on: - cron: '30 15 * * *' jobs: - # preset-test: - # runs-on: ubuntu-latest - # strategy: - # matrix: - # preset: [] - # name: "Preset Test: ${{ matrix.preset }}" - # steps: - # - uses: actions/checkout@v4 - # - name: Setup build environment - # uses: lukka/get-cmake@latest - # with: - # cmakeVersion: "~3.25.0" - # ninjaVersion: "^1.11.1" - # - name: Run preset - # run: cmake --workflow --preset ${{ matrix.preset }} + preset-test: + strategy: + fail-fast: false + matrix: + presets: + - preset: "gcc-debug" + platform: "ubuntu-latest" + - preset: "gcc-release" + platform: "ubuntu-latest" + name: "Preset: ${{ matrix.presets.preset }} on ${{ matrix.presets.platform }}" + runs-on: ${{ matrix.presets.platform }} + steps: + - uses: actions/checkout@v4 + - name: Setup build environment + uses: lukka/get-cmake@latest + with: + cmakeVersion: "~3.25.0" + ninjaVersion: "^1.11.1" + - name: Setup MSVC + if: startsWith(matrix.presets.platform, 'windows') + uses: TheMrMilchmann/setup-msvc-dev@v3 + with: + arch: x64 + - name: Run preset + run: cmake --workflow --preset ${{ matrix.presets.preset }} test: strategy: diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 0000000..c6bc9dd --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,120 @@ +{ + "version": 6, + "configurePresets": [ + { + "name": "_root-config", + "hidden": true, + "generator": "Ninja", + "binaryDir": "${sourceDir}/build/${presetName}", + "cacheVariables": { + "CMAKE_CXX_STANDARD": "20" + } + }, + { + "name": "_debug-base", + "hidden": true, + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "BEMAN_BUILDSYS_SANITIZER": "MaxSan" + } + }, + { + "name": "_release-base", + "hidden": true, + "cacheVariables": { + "CMAKE_BUILD_TYPE": "RelWithDebInfo" + } + }, + { + "name": "gcc-debug", + "displayName": "GCC Debug Build", + "inherits": [ + "_root-config", + "_debug-base" + ], + "cacheVariables": { + "CMAKE_TOOLCHAIN_FILE": "cmake/gnu-toolchain.cmake" + } + }, + { + "name": "gcc-release", + "displayName": "GCC Release Build", + "inherits": [ + "_root-config", + "_release-base" + ], + "cacheVariables": { + "CMAKE_TOOLCHAIN_FILE": "cmake/gnu-toolchain.cmake" + } + } + ], + "buildPresets": [ + { + "name": "gcc-debug", + "configurePreset": "gcc-debug" + }, + { + "name": "gcc-release", + "configurePreset": "gcc-release" + } + ], + "testPresets": [ + { + "name": "_test_base", + "hidden": true, + "output": { + "outputOnFailure": true + }, + "execution": { + "noTestsAction": "error", + "stopOnFailure": true + } + }, + { + "name": "gcc-debug", + "inherits": "_test_base", + "configurePreset": "gcc-debug" + }, + { + "name": "gcc-release", + "inherits": "_test_base", + "configurePreset": "gcc-release" + } + ], + "workflowPresets": [ + { + "name": "gcc-debug", + "steps": [ + { + "type": "configure", + "name": "gcc-debug" + }, + { + "type": "build", + "name": "gcc-debug" + }, + { + "type": "test", + "name": "gcc-debug" + } + ] + }, + { + "name": "gcc-release", + "steps": [ + { + "type": "configure", + "name": "gcc-release" + }, + { + "type": "build", + "name": "gcc-release" + }, + { + "type": "test", + "name": "gcc-release" + } + ] + } + ] +} diff --git a/README.md b/README.md index ca68f65..80f060e 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,62 @@ TODO: tested platforms. ### Instructions - +#### Using CMake Preset + +[CMake Preset](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html) +is a new CMake functionality that provides one-line configure + test. + +You can use `gcc-debug` to setup a debug orienated `inplace_vector` development environment. + +```text +$ cmake --workflow --preset gcc-debug +Executing workflow step 1 of 3: configure preset "gcc-debug" + +Preset CMake variables: + + BEMAN_BUILDSYS_SANITIZER="MaxSan" + CMAKE_BUILD_TYPE="Debug" + CMAKE_CXX_STANDARD="20" + CMAKE_TOOLCHAIN_FILE="cmake/gnu-toolchain.cmake" + +-- The CXX compiler identification is GNU 14.2.0 +.... +-- Generating done (0.0s) +-- Build files have been written to: /inplace_vector/build/gcc-debug + +Executing workflow step 2 of 3: build preset "gcc-debug" + +[8/20] Building CXX object tests/beman/inplace_vector/CMakeFiles/beman.inplace_vector.tests.erasure.dir/erasure.test.cpp.o + +Executing workflow step 3 of 3: test preset "gcc-debug" + +Test project /home/bradwu/Desktop/inplace_vector/build/gcc-debug + Start 1: beman.inplace_vector.test + 1/54 Test #1: beman.inplace_vector.test .................................... Passed 0.03 sec + Start 2: beman.inplace_vector.ref-test + 2/54 Test #2: beman.inplace_vector.ref-test ................................ Passed 0.03 sec + Start 3: ContainerRequirements/*.ValueType + 3/54 Test #3: ContainerRequirements/*.ValueType ............................ Passed 0.15 sec + Start 4: ContainerRequirements/*.Reference +... +50/54 Test #50: SizeNCapacity/*.ResizeDown ................................... Passed 0.05 sec + Start 51: SizeNCapacity/*.ResizeUp +51/54 Test #51: SizeNCapacity/*.ResizeUp ..................................... Passed 0.05 sec + Start 52: Data/*.Test +52/54 Test #52: Data/*.Test .................................................. Passed 0.05 sec + Start 53: Erasure/*.ByValue +53/54 Test #53: Erasure/*.ByValue ............................................***Skipped 0.04 sec + Start 54: Erasure/*.ByPred +54/54 Test #54: Erasure/*.ByPred .............................................***Skipped 0.04 sec + +100% tests passed, 0 tests failed out of 54 + +Total Test time (real) = 6.20 sec +``` + +Note that this workflow compiles the project with sanitizers, +if you wish to playaround with `inplace_vector` without sanitizers, +use `gcc-release`. #### Manual CMake Build diff --git a/cmake/appleclang-toolchain.cmake b/cmake/appleclang-toolchain.cmake new file mode 100644 index 0000000..bc12103 --- /dev/null +++ b/cmake/appleclang-toolchain.cmake @@ -0,0 +1,39 @@ +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +# This toolchain file is not meant to be used directly, +# but to be invoked by CMake preset and GitHub CI. +# +# This toolchain file configures for apple clang family of compiler. +# Note this is different from LLVM toolchain. +# +# BEMAN_BUILDSYS_SANITIZER: +# This optional CMake parameter is not meant for public use and is subject to +# change. +# Possible values: +# - MaxSan: configures clang and clang++ to use all available non-conflicting +# sanitizers. Note that apple clang does not support leak sanitizer. +# - TSan: configures clang and clang++ to enable the use of thread sanitizer. + +include_guard(GLOBAL) + +set(CMAKE_C_COMPILER clang) +set(CMAKE_CXX_COMPILER clang++) + +if(BEMAN_BUILDSYS_SANITIZER STREQUAL "MaxSan") + set(SANITIZER_FLAGS + "-fsanitize=address -fsanitize=pointer-compare -fsanitize=pointer-subtract -fsanitize=undefined" + ) +elseif(BEMAN_BUILDSYS_SANITIZER STREQUAL "TSan") + set(SANITIZER_FLAGS "-fsanitize=thread") +endif() + +set(CMAKE_C_FLAGS_DEBUG_INIT "${SANITIZER_FLAGS}") +set(CMAKE_CXX_FLAGS_DEBUG_INIT "${SANITIZER_FLAGS}") + +set(RELEASE_FLAGS "-O3 ${SANITIZER_FLAGS}") + +set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "${RELEASE_FLAGS}") +set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "${RELEASE_FLAGS}") + +set(CMAKE_C_FLAGS_RELEASE_INIT "${RELEASE_FLAGS}") +set(CMAKE_CXX_FLAGS_RELEASE_INIT "${RELEASE_FLAGS}") diff --git a/cmake/gnu-toolchain.cmake b/cmake/gnu-toolchain.cmake new file mode 100644 index 0000000..2e2a2ad --- /dev/null +++ b/cmake/gnu-toolchain.cmake @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +# This toolchain file is not meant to be used directly, +# but to be invoked by CMake preset and GitHub CI. +# +# This toolchain file configures for GNU family of compiler. +# +# BEMAN_BUILDSYS_SANITIZER: +# This optional CMake parameter is not meant for public use and is subject to +# change. +# Possible values: +# - MaxSan: configures gcc and g++ to use all available non-conflicting +# sanitizers. +# - TSan: configures gcc and g++ to enable the use of thread sanitizer + +include_guard(GLOBAL) + +set(CMAKE_C_COMPILER gcc) +set(CMAKE_CXX_COMPILER g++) + +if(BEMAN_BUILDSYS_SANITIZER STREQUAL "MaxSan") + set(SANITIZER_FLAGS + "-fsanitize=address -fsanitize=leak -fsanitize=pointer-compare -fsanitize=pointer-subtract -fsanitize=undefined" + ) +elseif(BEMAN_BUILDSYS_SANITIZER STREQUAL "TSan") + set(SANITIZER_FLAGS "-fsanitize=thread") +endif() + +set(CMAKE_C_FLAGS_DEBUG_INIT "${SANITIZER_FLAGS}") +set(CMAKE_CXX_FLAGS_DEBUG_INIT "${SANITIZER_FLAGS}") + +set(RELEASE_FLAGS "-O3 ${SANITIZER_FLAGS}") + +set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "${RELEASE_FLAGS}") +set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "${RELEASE_FLAGS}") + +set(CMAKE_C_FLAGS_RELEASE_INIT "${RELEASE_FLAGS}") +set(CMAKE_CXX_FLAGS_RELEASE_INIT "${RELEASE_FLAGS}") diff --git a/cmake/llvm-toolchain.cmake b/cmake/llvm-toolchain.cmake new file mode 100644 index 0000000..d783803 --- /dev/null +++ b/cmake/llvm-toolchain.cmake @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +# This toolchain file is not meant to be used directly, +# but to be invoked by CMake preset and GitHub CI. +# +# This toolchain file configures for LLVM family of compiler. +# +# BEMAN_BUILDSYS_SANITIZER: +# This optional CMake parameter is not meant for public use and is subject to +# change. +# Possible values: +# - MaxSan: configures clang and clang++ to use all available non-conflicting +# sanitizers. +# - TSan: configures clang and clang++ to enable the use of thread sanitizer. + +include_guard(GLOBAL) + +set(CMAKE_C_COMPILER clang) +set(CMAKE_CXX_COMPILER clang++) + +if(BEMAN_BUILDSYS_SANITIZER STREQUAL "MaxSan") + set(SANITIZER_FLAGS + "-fsanitize=address -fsanitize=leak -fsanitize=pointer-compare -fsanitize=pointer-subtract -fsanitize=undefined" + ) +elseif(BEMAN_BUILDSYS_SANITIZER STREQUAL "TSan") + set(SANITIZER_FLAGS "-fsanitize=thread") +endif() + +set(CMAKE_C_FLAGS_DEBUG_INIT "${SANITIZER_FLAGS}") +set(CMAKE_CXX_FLAGS_DEBUG_INIT "${SANITIZER_FLAGS}") + +set(RELEASE_FLAGS "-O3 ${SANITIZER_FLAGS}") + +set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "${RELEASE_FLAGS}") +set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "${RELEASE_FLAGS}") + +set(CMAKE_C_FLAGS_RELEASE_INIT "${RELEASE_FLAGS}") +set(CMAKE_CXX_FLAGS_RELEASE_INIT "${RELEASE_FLAGS}") diff --git a/cmake/msvc-toolchain.cmake b/cmake/msvc-toolchain.cmake new file mode 100644 index 0000000..c2fffa7 --- /dev/null +++ b/cmake/msvc-toolchain.cmake @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +# This toolchain file is not meant to be used directly, +# but to be invoked by CMake preset and GitHub CI. +# +# This toolchain file configures for MSVC family of compiler. +# +# BEMAN_BUILDSYS_SANITIZER: +# This optional CMake parameter is not meant for public use and is subject to +# change. +# Possible values: +# - MaxSan: configures cl to use all available non-conflicting sanitizers. +# +# Note that in other toolchain files, TSan is also a possible value for +# BEMAN_BUILDSYS_SANITIZER, however, MSVC does not support thread sanitizer, +# thus this value is omitted. + +include_guard(GLOBAL) + +set(CMAKE_C_COMPILER cl) +set(CMAKE_CXX_COMPILER cl) + +if(BEMAN_BUILDSYS_SANITIZER STREQUAL "MaxSan") + # /Zi flag (add debug symbol) is needed when using address sanitizer + # See C5072: https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-c5072 + set(SANITIZER_FLAGS "/fsanitize=address /Zi") +endif() + +set(CMAKE_CXX_FLAGS_DEBUG_INIT "/EHsc /permissive- ${SANITIZER_FLAGS}") +set(CMAKE_C_FLAGS_DEBUG_INIT "/EHsc /permissive- ${SANITIZER_FLAGS}") + +set(RELEASE_FLAGS "/EHsc /permissive- /O2 ${SANITIZER_FLAGS}") + +set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "${RELEASE_FLAGS}") +set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "${RELEASE_FLAGS}") + +set(CMAKE_C_FLAGS_RELEASE_INIT "${RELEASE_FLAGS}") +set(CMAKE_CXX_FLAGS_RELEASE_INIT "${RELEASE_FLAGS}") diff --git a/include/beman/inplace_vector/inplace_vector.hpp b/include/beman/inplace_vector/inplace_vector.hpp index 7b1b3af..2af0245 100644 --- a/include/beman/inplace_vector/inplace_vector.hpp +++ b/include/beman/inplace_vector/inplace_vector.hpp @@ -262,6 +262,7 @@ Software. #include // for less and equal_to #include // for reverse_iterator and iterator traits #include // for numeric_limits +#include // for destroy #include // for operator new #include #include // for length_error