diff --git a/.github/workflows/clang-c++11.yml b/.github/workflows/clang-c++11.yml index d511f5b7..6b73b7c1 100644 --- a/.github/workflows/clang-c++11.yml +++ b/.github/workflows/clang-c++11.yml @@ -25,7 +25,7 @@ jobs: export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=11 ./ clang --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" - name: Run tests run: ./test/etl_tests -v @@ -47,7 +47,7 @@ jobs: export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -D BUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=11 ./ clang --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" - name: Run tests run: ./test/etl_tests -v \ No newline at end of file diff --git a/.github/workflows/clang-c++14.yml b/.github/workflows/clang-c++14.yml index d06778b1..830832b5 100644 --- a/.github/workflows/clang-c++14.yml +++ b/.github/workflows/clang-c++14.yml @@ -25,7 +25,7 @@ jobs: export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=14 ./ clang --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" - name: Run tests run: ./test/etl_tests -v @@ -47,7 +47,7 @@ jobs: export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -D BUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=14 ./ clang --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" - name: Run tests run: ./test/etl_tests -v \ No newline at end of file diff --git a/.github/workflows/clang-c++17.yml b/.github/workflows/clang-c++17.yml index 9fb4611f..6ae2f4b9 100644 --- a/.github/workflows/clang-c++17.yml +++ b/.github/workflows/clang-c++17.yml @@ -25,7 +25,7 @@ jobs: export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=17 ./ clang --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" - name: Run tests run: ./test/etl_tests -v @@ -47,7 +47,7 @@ jobs: export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -D BUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=17 ./ clang --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" - name: Run tests run: ./test/etl_tests -v \ No newline at end of file diff --git a/.github/workflows/clang-c++20.yml b/.github/workflows/clang-c++20.yml index c68f9870..e246a795 100644 --- a/.github/workflows/clang-c++20.yml +++ b/.github/workflows/clang-c++20.yml @@ -32,7 +32,7 @@ jobs: export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -DBUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=20 ./ clang-17 --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" - name: Run tests run: ./test/etl_tests -v @@ -61,7 +61,7 @@ jobs: export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=20 ./ clang-17 --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" - name: Run tests run: ./test/etl_tests -v @@ -90,7 +90,7 @@ jobs: export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -D BUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=20 ./ clang-17 --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" - name: Run tests run: ./test/etl_tests -v @@ -112,7 +112,7 @@ jobs: export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=20 ./ clang --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" - name: Run tests run: ./test/etl_tests -v @@ -134,7 +134,7 @@ jobs: export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -D BUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=20 ./ clang --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" - name: Run tests run: ./test/etl_tests -v @@ -156,7 +156,7 @@ jobs: export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=20 ./ clang --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" - name: Run tests run: ./test/etl_tests -v @@ -178,7 +178,7 @@ jobs: export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -D BUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=20 ./ clang --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" - name: Run tests run: ./test/etl_tests -v diff --git a/.github/workflows/clang-c++23.yml b/.github/workflows/clang-c++23.yml index 18817aaa..acd22a41 100644 --- a/.github/workflows/clang-c++23.yml +++ b/.github/workflows/clang-c++23.yml @@ -32,7 +32,7 @@ jobs: export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -DBUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=23 ./ clang-17 --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" - name: Run tests run: ./test/etl_tests -v @@ -61,7 +61,7 @@ jobs: export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=23 ./ clang-17 --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" - name: Run tests run: ./test/etl_tests -v @@ -90,7 +90,7 @@ jobs: export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -D BUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=23 ./ clang-17 --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" - name: Run tests run: ./test/etl_tests -v @@ -112,7 +112,7 @@ jobs: export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=23 ./ clang --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" - name: Run tests run: ./test/etl_tests -v @@ -134,7 +134,7 @@ jobs: export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -D BUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=23 ./ clang --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" - name: Run tests run: ./test/etl_tests -v @@ -156,7 +156,7 @@ jobs: export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=23 ./ clang --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" - name: Run tests run: ./test/etl_tests -v @@ -178,7 +178,7 @@ jobs: export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 cmake -D BUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=23 ./ clang --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" - name: Run tests run: ./test/etl_tests -v diff --git a/.github/workflows/clang-c++26.yml b/.github/workflows/clang-c++26.yml new file mode 100644 index 00000000..5a2e9be0 --- /dev/null +++ b/.github/workflows/clang-c++26.yml @@ -0,0 +1,189 @@ +name: clang-c++26 +on: + push: + branches: [ master, development, pull-request/* ] + pull_request: + branches: [ master, development, pull-request/* ] + types: [opened, synchronize, reopened] + +jobs: + + build-clang-cpp26-linux-stl: + name: Clang C++26 Linux - STL + if: false # enabled when ubuntu-26.04 is available in github + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-26.04] + + steps: + - uses: actions/checkout@v4 + + - name: Build + run: | + export CC=clang + export CXX=clang++ + export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 + cmake -DBUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=26 ./ + clang --version + make -j "$(getconf _NPROCESSORS_ONLN)" + + - name: Run tests + run: ./test/etl_tests -v + + build-clang-cpp26-linux-no-stl: + name: Clang C++26 Linux - No STL + if: false # enabled when ubuntu-26.04 is available in github + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-26.04] + + steps: + - uses: actions/checkout@v4 + + - name: Build + run: | + export CC=clang + export CXX=clang++ + export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 + cmake -DBUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=26 ./ + clang --version + make -j "$(getconf _NPROCESSORS_ONLN)" + + - name: Run tests + run: ./test/etl_tests -v + + build-clang-cpp26-linux-stl-force-cpp03: + name: Clang C++26 Linux - STL - Force C++03 + if: false # enabled when ubuntu-26.04 is available in github + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-26.04] + + steps: + - uses: actions/checkout@v4 + + - name: Build + run: | + export CC=clang + export CXX=clang++ + export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 + cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=26 ./ + clang --version + make -j "$(getconf _NPROCESSORS_ONLN)" + + - name: Run tests + run: ./test/etl_tests -v + + build-clang-cpp26-linux-no-stl-force-cpp03: + name: Clang C++26 Linux - No STL - Force C++03 + if: false # enabled when ubuntu-26.04 is available in github + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-26.04] + + steps: + - uses: actions/checkout@v4 + + - name: Build + run: | + export CC=clang + export CXX=clang++ + export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 + cmake -D BUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=26 ./ + clang --version + make -j "$(getconf _NPROCESSORS_ONLN)" + + - name: Run tests + run: ./test/etl_tests -v + + build-clang-cpp26-osx-stl: + name: Clang C++26 OSX - STL + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [macos-26] + + steps: + - uses: actions/checkout@v4 + + - name: Build + run: | + export CC=clang + export CXX=clang++ + export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 + cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=26 ./ + clang --version + make -j "$(getconf _NPROCESSORS_ONLN)" + + - name: Run tests + run: ./test/etl_tests -v + + build-clang-cpp26-osx-no-stl: + name: Clang C++26 OSX - No STL + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [macos-26] + + steps: + - uses: actions/checkout@v4 + + - name: Build + run: | + export CC=clang + export CXX=clang++ + export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 + cmake -D BUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=26 ./ + clang --version + make -j "$(getconf _NPROCESSORS_ONLN)" + + - name: Run tests + run: ./test/etl_tests -v + + build-clang-cpp26-osx-stl-force-cpp03: + name: Clang C++26 OSX - STL - Force C++03 + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [macos-26] + + steps: + - uses: actions/checkout@v4 + + - name: Build + run: | + export CC=clang + export CXX=clang++ + export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 + cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=26 ./ + clang --version + make -j "$(getconf _NPROCESSORS_ONLN)" + + - name: Run tests + run: ./test/etl_tests -v + + build-clang-cpp26-osx-no-stl-force-cpp03: + name: Clang C++26 OSX - No STL - Force C++03 + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [macos-26] + + steps: + - uses: actions/checkout@v4 + + - name: Build + run: | + export CC=clang + export CXX=clang++ + export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 + cmake -D BUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=26 ./ + clang --version + make -j "$(getconf _NPROCESSORS_ONLN)" + + - name: Run tests + run: ./test/etl_tests -v diff --git a/.github/workflows/clang-syntax-checks.yml b/.github/workflows/clang-syntax-checks.yml index 700b2087..416ef290 100644 --- a/.github/workflows/clang-syntax-checks.yml +++ b/.github/workflows/clang-syntax-checks.yml @@ -23,10 +23,10 @@ jobs: export CXX=clang++ cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=03 ./test/syntax_check clang --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-clang-cpp03-linux-No-STL: - name: Syntax Check - Clang C++03 Linux No STL + name: Syntax Check - Clang C++03 Linux No STL runs-on: ${{ matrix.os }} strategy: matrix: @@ -41,7 +41,7 @@ jobs: export CXX=clang++ cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=03 ./test/syntax_check clang --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-clang-cpp11-linux-STL: name: Syntax Check - Clang C++11 Linux STL @@ -59,10 +59,10 @@ jobs: export CXX=clang++ cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=11 ./test/syntax_check clang --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-clang-cpp11-linux-No-STL: - name: Syntax Check - Clang C++11 Linux No STL + name: Syntax Check - Clang C++11 Linux No STL runs-on: ${{ matrix.os }} strategy: matrix: @@ -77,7 +77,7 @@ jobs: export CXX=clang++ cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=11 ./test/syntax_check clang --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-clang-cpp11-linux-STL-Force-CPP03: name: Syntax Check - Clang C++11 Linux STL Force C++03 @@ -95,7 +95,7 @@ jobs: export CXX=clang++ cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=11 ./test/syntax_check clang --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-clang-cpp11-linux-No-STL-Force-CPP03: name: Syntax Check - Clang C++11 Linux No STL Force C++03 @@ -113,7 +113,7 @@ jobs: export CXX=clang++ cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=11 ./test/syntax_check clang --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-clang-cpp14-linux-STL: name: Syntax Check - Clang C++14 Linux STL @@ -131,10 +131,10 @@ jobs: export CXX=clang++ cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=14 ./test/syntax_check clang --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-clang-cpp14-linux-No-STL: - name: Syntax Check - Clang C++14 Linux No STL + name: Syntax Check - Clang C++14 Linux No STL runs-on: ${{ matrix.os }} strategy: matrix: @@ -149,7 +149,7 @@ jobs: export CXX=clang++ cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=14 ./test/syntax_check clang --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-clang-cpp14-linux-STL-Force-CPP03: name: Syntax Check - Clang C++14 Linux STL Force C++03 @@ -167,7 +167,7 @@ jobs: export CXX=clang++ cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=14 ./test/syntax_check clang --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-clang-cpp14-linux-No-STL-Force-CPP03: name: Syntax Check - Clang C++14 Linux No STL Force C++03 @@ -185,7 +185,7 @@ jobs: export CXX=clang++ cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=14 ./test/syntax_check clang --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-clang-cpp17-linux-STL: name: Syntax Check - Clang C++17 Linux STL @@ -203,10 +203,10 @@ jobs: export CXX=clang++ cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=17 ./test/syntax_check clang --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-clang-cpp17-linux-No-STL: - name: Syntax Check - Clang C++17 Linux No STL + name: Syntax Check - Clang C++17 Linux No STL runs-on: ${{ matrix.os }} strategy: matrix: @@ -221,7 +221,7 @@ jobs: export CXX=clang++ cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=17 ./test/syntax_check clang --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-clang-cpp17-linux-STL-Force-CPP03: name: Syntax Check - Clang C++17 Linux STL Force C++03 @@ -239,7 +239,7 @@ jobs: export CXX=clang++ cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=17 ./test/syntax_check clang --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-clang-cpp17-linux-No-STL-Force-CPP03: name: Syntax Check - Clang C++17 Linux No STL Force C++03 @@ -257,7 +257,7 @@ jobs: export CXX=clang++ cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=17 ./test/syntax_check clang --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-clang-cpp20-linux-STL: name: Syntax Check - Clang C++20 Linux STL @@ -275,10 +275,10 @@ jobs: export CXX=clang++ cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=20 ./test/syntax_check clang --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-clang-cpp20-linux-No-STL: - name: Syntax Check - Clang C++20 Linux No STL + name: Syntax Check - Clang C++20 Linux No STL runs-on: ${{ matrix.os }} strategy: matrix: @@ -293,7 +293,7 @@ jobs: export CXX=clang++ cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=20 ./test/syntax_check clang --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-clang-cpp20-linux-STL-Force-CPP03: name: Syntax Check - Clang C++20 Linux STL Force C++03 @@ -311,7 +311,7 @@ jobs: export CXX=clang++ cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=20 ./test/syntax_check clang --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-clang-cpp20-linux-No-STL-Force-CPP03: name: Syntax Check - Clang C++20 Linux No STL Force C++03 @@ -329,7 +329,7 @@ jobs: export CXX=clang++ cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=20 ./test/syntax_check clang --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-clang-cpp23-linux-STL: name: Syntax Check - Clang C++23 Linux STL @@ -347,10 +347,10 @@ jobs: export CXX=clang++ cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=23 ./test/syntax_check clang --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-clang-cpp23-linux-No-STL: - name: Syntax Check - Clang C++23 Linux No STL + name: Syntax Check - Clang C++23 Linux No STL runs-on: ${{ matrix.os }} strategy: matrix: @@ -365,7 +365,7 @@ jobs: export CXX=clang++ cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=23 ./test/syntax_check clang --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-clang-cpp23-linux-STL-Force-CPP03: name: Syntax Check - Clang C++23 Linux STL Force C++03 @@ -383,7 +383,7 @@ jobs: export CXX=clang++ cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=23 ./test/syntax_check clang --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-clang-cpp23-linux-No-STL-Force-CPP03: name: Syntax Check - Clang C++23 Linux No STL Force C++03 @@ -401,4 +401,80 @@ jobs: export CXX=clang++ cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=23 ./test/syntax_check clang --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" + + build-clang-cpp26-linux-STL: + name: Syntax Check - Clang C++26 Linux STL + if: false # enabled when ubuntu-26.04 is available in github + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-26.04] + + steps: + - uses: actions/checkout@v4 + + - name: Build + run: | + export CC=clang + export CXX=clang++ + cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=26 ./test/syntax_check + clang++ --version + make -j "$(getconf _NPROCESSORS_ONLN)" + + build-clang-cpp26-linux-No-STL: + name: Syntax Check - Clang C++26 Linux No STL + if: false # enabled when ubuntu-26.04 is available in github + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-26.04] + + steps: + - uses: actions/checkout@v4 + + - name: Build + run: | + export CC=clang + export CXX=clang++ + cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=26 ./test/syntax_check + clang++ --version + make -j "$(getconf _NPROCESSORS_ONLN)" + + build-clang-cpp26-linux-STL-Force-CPP03: + name: Syntax Check - Clang C++26 Linux STL Force C++03 + if: false # enabled when ubuntu-26.04 is available in github + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-26.04] + + steps: + - uses: actions/checkout@v4 + + - name: Build + run: | + export CC=clang + export CXX=clang++ + cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=26 ./test/syntax_check + clang++ --version + make -j "$(getconf _NPROCESSORS_ONLN)" + + build-clang-cpp26-linux-No-STL-Force-CPP03: + name: Syntax Check - Clang C++26 Linux No STL Force C++03 + if: false # enabled when ubuntu-26.04 is available in github + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-26.04] + + steps: + - uses: actions/checkout@v4 + + - name: Build + run: | + export CC=clang + export CXX=clang++ + cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=26 ./test/syntax_check + clang++ --version + make -j "$(getconf _NPROCESSORS_ONLN)" diff --git a/.github/workflows/gcc-c++11.yml b/.github/workflows/gcc-c++11.yml index 571c6d6e..c9706aeb 100644 --- a/.github/workflows/gcc-c++11.yml +++ b/.github/workflows/gcc-c++11.yml @@ -26,7 +26,7 @@ jobs: export CXX=g++ cmake -DBUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=11 ./ gcc --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" - name: Run tests run: ./test/etl_tests -v @@ -49,7 +49,7 @@ jobs: export CXX=g++ cmake -DBUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=11 ./ gcc --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" - name: Run tests run: ./test/etl_tests -v diff --git a/.github/workflows/gcc-c++14.yml b/.github/workflows/gcc-c++14.yml index f623af08..a3277b66 100644 --- a/.github/workflows/gcc-c++14.yml +++ b/.github/workflows/gcc-c++14.yml @@ -25,7 +25,7 @@ jobs: export CXX=g++ cmake -DBUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=14 ./ gcc --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" - name: Run tests run: ./test/etl_tests -v @@ -47,7 +47,7 @@ jobs: export CXX=g++ cmake -DBUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=14 ./ gcc --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" - name: Run tests run: ./test/etl_tests -v \ No newline at end of file diff --git a/.github/workflows/gcc-c++17.yml b/.github/workflows/gcc-c++17.yml index fc0ddd97..dbeef7fa 100644 --- a/.github/workflows/gcc-c++17.yml +++ b/.github/workflows/gcc-c++17.yml @@ -25,7 +25,7 @@ jobs: export CXX=g++ cmake -DBUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=17 ./ gcc --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" - name: Run tests run: ./test/etl_tests -v @@ -47,7 +47,7 @@ jobs: export CXX=g++ cmake -DBUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=17 ./ gcc --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" - name: Run tests run: ./test/etl_tests -v diff --git a/.github/workflows/gcc-c++20.yml b/.github/workflows/gcc-c++20.yml index 5965e05e..be4e6fb2 100644 --- a/.github/workflows/gcc-c++20.yml +++ b/.github/workflows/gcc-c++20.yml @@ -25,7 +25,7 @@ jobs: export CXX=g++ cmake -DBUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=20 ./ gcc --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" - name: Run tests run: ./test/etl_tests -v @@ -47,7 +47,7 @@ jobs: export CXX=g++ cmake -DBUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=20 ./ gcc --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" - name: Run tests run: ./test/etl_tests -v @@ -69,7 +69,7 @@ jobs: export CXX=g++ cmake -DBUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=20 ./ gcc --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" - name: Run tests run: ./test/etl_tests -v @@ -91,7 +91,7 @@ jobs: export CXX=g++ cmake -DBUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=20 ./ gcc --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" - name: Run tests run: ./test/etl_tests -v \ No newline at end of file diff --git a/.github/workflows/gcc-c++23.yml b/.github/workflows/gcc-c++23.yml index aad4325c..654deff9 100644 --- a/.github/workflows/gcc-c++23.yml +++ b/.github/workflows/gcc-c++23.yml @@ -25,7 +25,7 @@ jobs: export CXX=g++ cmake -DBUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=23 ./ gcc --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" - name: Run tests run: ./test/etl_tests -v @@ -47,7 +47,7 @@ jobs: export CXX=g++ cmake -DBUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=23 ./ gcc --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" - name: Run tests run: ./test/etl_tests -v @@ -69,7 +69,7 @@ jobs: export CXX=g++ cmake -DBUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=23 ./ gcc --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" - name: Run tests run: ./test/etl_tests -v @@ -91,7 +91,7 @@ jobs: export CXX=g++ cmake -DBUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=23 ./ gcc --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" - name: Run tests run: ./test/etl_tests -v \ No newline at end of file diff --git a/.github/workflows/gcc-c++26.yml b/.github/workflows/gcc-c++26.yml new file mode 100644 index 00000000..8f3701b0 --- /dev/null +++ b/.github/workflows/gcc-c++26.yml @@ -0,0 +1,101 @@ +name: gcc-c++26 +on: + push: + branches: [ master, development, pull-request/* ] + pull_request: + branches: [ master, development, pull-request/* ] + types: [opened, synchronize, reopened] + +jobs: + + build-gcc-cpp26-linux-stl: + name: GCC C++26 Linux - STL + if: false # enabled when ubuntu-26.04 is available in github + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-26.04] + + steps: + - uses: actions/checkout@v4 + + - name: Build + run: | + export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 + export CC=gcc + export CXX=g++ + cmake -DBUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=26 ./ + gcc --version + make -j "$(getconf _NPROCESSORS_ONLN)" + + - name: Run tests + run: ./test/etl_tests -v + + build-gcc-cpp26-linux-no-stl: + name: GCC C++26 Linux - No STL + if: false # enabled when ubuntu-26.04 is available in github + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-26.04] + + steps: + - uses: actions/checkout@v4 + + - name: Build + run: | + export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 + export CC=gcc + export CXX=g++ + cmake -DBUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=26 ./ + gcc --version + make -j "$(getconf _NPROCESSORS_ONLN)" + + - name: Run tests + run: ./test/etl_tests -v + + build-gcc-cpp26-linux-stl-force-cpp03: + name: GCC C++26 Linux - STL - Force C++03 + if: false # enabled when ubuntu-26.04 is available in github + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-26.04] + + steps: + - uses: actions/checkout@v4 + + - name: Build + run: | + export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 + export CC=gcc + export CXX=g++ + cmake -DBUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=26 ./ + gcc --version + make -j "$(getconf _NPROCESSORS_ONLN)" + + - name: Run tests + run: ./test/etl_tests -v + + build-gcc-cpp26-linux-no-stl-force-cpp03: + name: GCC C++26 Linux - No STL - Force C++03 + if: false # enabled when ubuntu-26.04 is available in github + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-26.04] + + steps: + - uses: actions/checkout@v4 + + - name: Build + run: | + export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 + export CC=gcc + export CXX=g++ + cmake -DBUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=26 ./ + gcc --version + make -j "$(getconf _NPROCESSORS_ONLN)" + + - name: Run tests + run: ./test/etl_tests -v diff --git a/.github/workflows/gcc-syntax-checks.yml b/.github/workflows/gcc-syntax-checks.yml index 5f3753b1..81bfa4c4 100644 --- a/.github/workflows/gcc-syntax-checks.yml +++ b/.github/workflows/gcc-syntax-checks.yml @@ -23,10 +23,10 @@ jobs: export CXX=g++ cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=03 ./test/syntax_check gcc --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-gcc-cpp03-linux-No-STL: - name: Syntax Check - GCC C++03 Linux No STL + name: Syntax Check - GCC C++03 Linux No STL runs-on: ${{ matrix.os }} strategy: matrix: @@ -41,7 +41,7 @@ jobs: export CXX=g++ cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=03 ./test/syntax_check gcc --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-gcc-cpp11-linux-STL: name: Syntax Check - GCC C++11 Linux STL @@ -59,7 +59,7 @@ jobs: export CXX=g++ cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=11 ./test/syntax_check gcc --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-gcc-cpp11-linux-No-STL: name: Syntax Check - GCC C++11 Linux No STL @@ -77,7 +77,7 @@ jobs: export CXX=g++ cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=11 ./test/syntax_check gcc --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-gcc-cpp11-linux-STL-Force-CPP03: name: Syntax Check - GCC C++11 Linux STL Force C++03 @@ -95,7 +95,7 @@ jobs: export CXX=g++ cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=11 ./test/syntax_check gcc --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-gcc-cpp11-linux-No-STL-Force-CPP03: name: Syntax Check - GCC C++11 Linux No STL Force C++03 @@ -113,7 +113,7 @@ jobs: export CXX=g++ cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=11 ./test/syntax_check gcc --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-gcc-cpp14-linux-STL: name: Syntax Check - GCC C++14 Linux STL @@ -131,7 +131,7 @@ jobs: export CXX=g++ cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=14 ./test/syntax_check gcc --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-gcc-cpp14-linux-No-STL: name: Syntax Check - GCC C++14 Linux No STL @@ -149,7 +149,7 @@ jobs: export CXX=g++ cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=14 ./test/syntax_check gcc --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-gcc-cpp14-linux-STL-Force-CPP03: name: Syntax Check - GCC C++14 Linux STL Force C++03 @@ -167,7 +167,7 @@ jobs: export CXX=g++ cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=14 ./test/syntax_check gcc --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-gcc-cpp14-linux-No-STL-Force-CPP03: name: Syntax Check - GCC C++14 Linux No STL Force C++03 @@ -185,7 +185,7 @@ jobs: export CXX=g++ cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=14 ./test/syntax_check gcc --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-gcc-cpp17-linux-STL: name: Syntax Check - GCC C++17 Linux STL @@ -203,7 +203,7 @@ jobs: export CXX=g++ cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=17 ./test/syntax_check gcc --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-gcc-cpp17-linux-No-STL: name: Syntax Check - GCC C++17 Linux No STL @@ -221,7 +221,7 @@ jobs: export CXX=g++ cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=17 ./test/syntax_check gcc --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-gcc-cpp17-linux-STL-Force-CPP03: name: Syntax Check - GCC C++17 Linux STL Force C++03 @@ -239,7 +239,7 @@ jobs: export CXX=g++ cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=17 ./test/syntax_check gcc --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-gcc-cpp17-linux-No-STL-Force-CPP03: name: Syntax Check - GCC C++17 Linux No STL Force C++03 @@ -257,7 +257,7 @@ jobs: export CXX=g++ cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=17 ./test/syntax_check gcc --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-gcc-cpp20-linux-STL: name: Syntax Check - GCC C++20 Linux STL @@ -275,7 +275,7 @@ jobs: export CXX=g++ cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=20 ./test/syntax_check gcc --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-gcc-cpp20-linux-No-STL: name: Syntax Check - GCC C++20 Linux No STL @@ -293,7 +293,7 @@ jobs: export CXX=g++ cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=20 ./test/syntax_check gcc --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-gcc-cpp20-linux-STL-Force-CPP03: name: Syntax Check - GCC C++20 Linux STL Force C++03 @@ -311,7 +311,7 @@ jobs: export CXX=g++ cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=20 ./test/syntax_check gcc --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-gcc-cpp20-linux-No-STL-Force-CPP03: name: Syntax Check - GCC C++20 Linux No STL Force C++03 @@ -329,7 +329,7 @@ jobs: export CXX=g++ cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=20 ./test/syntax_check gcc --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-gcc-cpp23-linux-STL: name: Syntax Check - GCC C++23 Linux STL @@ -347,7 +347,7 @@ jobs: export CXX=g++ cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=23 ./test/syntax_check gcc --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-gcc-cpp23-linux-No-STL: name: Syntax Check - GCC C++23 Linux No STL @@ -365,7 +365,7 @@ jobs: export CXX=g++ cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=23 ./test/syntax_check gcc --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-gcc-cpp23-linux-STL-Force-CPP03: name: Syntax Check - GCC C++23 Linux STL Force C++03 @@ -383,7 +383,7 @@ jobs: export CXX=g++ cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=23 ./test/syntax_check gcc --version - make -j $(getconf _NPROCESSORS_ONLN) + make -j "$(getconf _NPROCESSORS_ONLN)" build-gcc-cpp23-linux-No-STL-Force-CPP03: name: Syntax Check - GCC C++23 Linux No STL Force C++03 @@ -401,4 +401,80 @@ jobs: export CXX=g++ cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=23 ./test/syntax_check gcc --version - make -j $(getconf _NPROCESSORS_ONLN) \ No newline at end of file + make -j "$(getconf _NPROCESSORS_ONLN)" + + build-gcc-cpp26-linux-STL: + name: Syntax Check - GCC C++26 Linux STL + if: false # enabled when ubuntu-26.04 is available in github + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-26.04] + + steps: + - uses: actions/checkout@v4 + + - name: Build + run: | + export CC=gcc + export CXX=g++ + cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=26 ./test/syntax_check + gcc --version + make -j "$(getconf _NPROCESSORS_ONLN)" + + build-gcc-cpp26-linux-No-STL: + name: Syntax Check - GCC C++26 Linux No STL + if: false # enabled when ubuntu-26.04 is available in github + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-26.04] + + steps: + - uses: actions/checkout@v4 + + - name: Build + run: | + export CC=gcc + export CXX=g++ + cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=26 ./test/syntax_check + gcc --version + make -j "$(getconf _NPROCESSORS_ONLN)" + + build-gcc-cpp26-linux-STL-Force-CPP03: + name: Syntax Check - GCC C++26 Linux STL Force C++03 + if: false # enabled when ubuntu-26.04 is available in github + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-26.04] + + steps: + - uses: actions/checkout@v4 + + - name: Build + run: | + export CC=gcc + export CXX=g++ + cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=26 ./test/syntax_check + gcc --version + make -j "$(getconf _NPROCESSORS_ONLN)" + + build-gcc-cpp26-linux-No-STL-Force-CPP03: + name: Syntax Check - GCC C++26 Linux No STL Force C++03 + if: false # enabled when ubuntu-26.04 is available in github + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-26.04] + + steps: + - uses: actions/checkout@v4 + + - name: Build + run: | + export CC=gcc + export CXX=g++ + cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=26 ./test/syntax_check + gcc --version + make -j "$(getconf _NPROCESSORS_ONLN)" diff --git a/README.md b/README.md index 869455a0..1af9c518 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ![GitHub release (latest by date)](https://img.shields.io/github/v/release/jwellbelove/etl) [![Release date](https://img.shields.io/github/release-date/jwellbelove/etl?color=%231182c3)](https://img.shields.io/github/release-date/jwellbelove/etl?color=%231182c3) -[![Standard](https://img.shields.io/badge/c%2B%2B-98/03/11/14/17/20/23-blue.svg)](https://en.wikipedia.org/wiki/C%2B%2B#Standardization) +[![Standard](https://img.shields.io/badge/c%2B%2B-98/03/11/14/17/20/23/26-blue.svg)](https://en.wikipedia.org/wiki/C%2B%2B#Standardization) [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT) ![GitHub contributors](https://img.shields.io/github/contributors-anon/ETLCPP/etl) ![GitHub forks](https://img.shields.io/github/forks/ETLCPP/etl?style=flat) @@ -15,6 +15,7 @@ ![CI](https://github.com/ETLCPP/etl/actions/workflows/gcc-c++17.yml/badge.svg?branch=master) ![CI](https://github.com/ETLCPP/etl/actions/workflows/gcc-c++20.yml/badge.svg?branch=master) ![CI](https://github.com/ETLCPP/etl/actions/workflows/gcc-c++23.yml/badge.svg?branch=master) +![CI](https://github.com/ETLCPP/etl/actions/workflows/gcc-c++26.yml/badge.svg?branch=master) ![CI](https://github.com/ETLCPP/etl/actions/workflows/gcc-syntax-checks.yml/badge.svg?branch=master) ![CI](https://github.com/ETLCPP/etl/actions/workflows/clang-c++11.yml/badge.svg?branch=master) @@ -22,6 +23,7 @@ ![CI](https://github.com/ETLCPP/etl/actions/workflows/clang-c++17.yml/badge.svg?branch=master) ![CI](https://github.com/ETLCPP/etl/actions/workflows/clang-c++20.yml/badge.svg?branch=master) ![CI](https://github.com/ETLCPP/etl/actions/workflows/clang-c++23.yml/badge.svg?branch=master) +![CI](https://github.com/ETLCPP/etl/actions/workflows/clang-c++26.yml/badge.svg?branch=master) ![CI](https://github.com/ETLCPP/etl/actions/workflows/clang-syntax-checks.yml/badge.svg?branch=master) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/3c14cd918ccf40008d0bcd7b083d5946)](https://www.codacy.com/manual/jwellbelove/etl?utm_source=github.com&utm_medium=referral&utm_content=ETLCPP/etl&utm_campaign=Badge_Grade) @@ -49,7 +51,7 @@ Its design goals include: - Offering APIs that closely resemble those of the STL, enabling familiar and consistent usage. - Maintaining compatibility with C++98 while implementing many features introduced in later standards -(C++11/14/17/20/23) where possible. +(C++11/14/17/20/23/26) where possible. - Ensuring deterministic behavior, which is critical in real-time and resource-constrained environments. diff --git a/include/etl/atomic/atomic_gcc_sync.h b/include/etl/atomic/atomic_gcc_sync.h index 087489aa..425d8707 100644 --- a/include/etl/atomic/atomic_gcc_sync.h +++ b/include/etl/atomic/atomic_gcc_sync.h @@ -341,6 +341,68 @@ namespace etl return __atomic_fetch_xor(&value, v, order); } + // Fetch max + T fetch_max(T v, etl::memory_order order = etl::memory_order_seq_cst) + { + T old = load(order); + + while (v > old) + { + if (compare_exchange_weak(old, v, order)) + { + break; + } + } + + return old; + } + + T fetch_max(T v, etl::memory_order order = etl::memory_order_seq_cst) volatile + { + T old = load(order); + + while (v > old) + { + if (compare_exchange_weak(old, v, order)) + { + break; + } + } + + return old; + } + + // Fetch min + T fetch_min(T v, etl::memory_order order = etl::memory_order_seq_cst) + { + T old = load(order); + + while (v < old) + { + if (compare_exchange_weak(old, v, order)) + { + break; + } + } + + return old; + } + + T fetch_min(T v, etl::memory_order order = etl::memory_order_seq_cst) volatile + { + T old = load(order); + + while (v < old) + { + if (compare_exchange_weak(old, v, order)) + { + break; + } + } + + return old; + } + // Exchange T exchange(T v, etl::memory_order order = etl::memory_order_seq_cst) { @@ -1234,6 +1296,72 @@ namespace etl return __sync_fetch_and_xor(&value, v); } + // Fetch max + T fetch_max(T v, etl::memory_order order = etl::memory_order_seq_cst) + { + (void)order; + T old = load(order); + + while (v > old) + { + if (compare_exchange_weak(old, v, order)) + { + break; + } + } + + return old; + } + + T fetch_max(T v, etl::memory_order order = etl::memory_order_seq_cst) volatile + { + (void)order; + T old = load(order); + + while (v > old) + { + if (compare_exchange_weak(old, v, order)) + { + break; + } + } + + return old; + } + + // Fetch min + T fetch_min(T v, etl::memory_order order = etl::memory_order_seq_cst) + { + (void)order; + T old = load(order); + + while (v < old) + { + if (compare_exchange_weak(old, v, order)) + { + break; + } + } + + return old; + } + + T fetch_min(T v, etl::memory_order order = etl::memory_order_seq_cst) volatile + { + (void)order; + T old = load(order); + + while (v < old) + { + if (compare_exchange_weak(old, v, order)) + { + break; + } + } + + return old; + } + // Exchange T exchange(T v, etl::memory_order order = etl::memory_order_seq_cst) { diff --git a/include/etl/atomic/atomic_std.h b/include/etl/atomic/atomic_std.h index ee765a70..06fcef6c 100644 --- a/include/etl/atomic/atomic_std.h +++ b/include/etl/atomic/atomic_std.h @@ -40,11 +40,98 @@ namespace etl { //*************************************************************************** // ETL Atomic type for compilers that support std::atomic. - // etl::atomic is a simple wrapper around std::atomic. + // etl::atomic is a wrapper around std::atomic that adds fetch_max and + // fetch_min if the standard library does not yet provide them. //*************************************************************************** +#if ETL_HAS_STD_ATOMIC_MIN_MAX + // The standard library already provides fetch_max/fetch_min. template using atomic = std::atomic; +#else + template + class atomic : public std::atomic + { + using base_type = std::atomic; + + public: + + atomic() ETL_NOEXCEPT = default; + + ETL_CONSTEXPR atomic(T desired) ETL_NOEXCEPT + : base_type(desired) + { + } + + atomic(const atomic&) = delete; + atomic& operator=(const atomic&) = delete; + atomic& operator=(const atomic&) volatile = delete; + + using base_type::operator=; + + // Fetch max + T fetch_max(T v, std::memory_order order = std::memory_order_seq_cst) + { + T old = this->load(order); + + while (v > old) + { + if (this->compare_exchange_weak(old, v, order)) + { + break; + } + } + + return old; + } + + T fetch_max(T v, std::memory_order order = std::memory_order_seq_cst) volatile + { + T old = this->load(order); + + while (v > old) + { + if (this->compare_exchange_weak(old, v, order)) + { + break; + } + } + + return old; + } + + // Fetch min + T fetch_min(T v, std::memory_order order = std::memory_order_seq_cst) + { + T old = this->load(order); + + while (v < old) + { + if (this->compare_exchange_weak(old, v, order)) + { + break; + } + } + + return old; + } + + T fetch_min(T v, std::memory_order order = std::memory_order_seq_cst) volatile + { + T old = this->load(order); + + while (v < old) + { + if (this->compare_exchange_weak(old, v, order)) + { + break; + } + } + + return old; + } + }; +#endif using memory_order = std::memory_order; @@ -55,66 +142,66 @@ namespace etl static ETL_CONSTANT etl::memory_order memory_order_acq_rel = std::memory_order_acq_rel; static ETL_CONSTANT etl::memory_order memory_order_seq_cst = std::memory_order_seq_cst; - using atomic_bool = std::atomic; - using atomic_char = std::atomic; - using atomic_schar = std::atomic; - using atomic_uchar = std::atomic; - using atomic_short = std::atomic; - using atomic_ushort = std::atomic; - using atomic_int = std::atomic; - using atomic_uint = std::atomic; - using atomic_long = std::atomic; - using atomic_ulong = std::atomic; - using atomic_llong = std::atomic; - using atomic_ullong = std::atomic; - using atomic_wchar_t = std::atomic; + using atomic_bool = etl::atomic; + using atomic_char = etl::atomic; + using atomic_schar = etl::atomic; + using atomic_uchar = etl::atomic; + using atomic_short = etl::atomic; + using atomic_ushort = etl::atomic; + using atomic_int = etl::atomic; + using atomic_uint = etl::atomic; + using atomic_long = etl::atomic; + using atomic_ulong = etl::atomic; + using atomic_llong = etl::atomic; + using atomic_ullong = etl::atomic; + using atomic_wchar_t = etl::atomic; #if ETL_HAS_NATIVE_CHAR8_T - using atomic_char8_t = std::atomic; + using atomic_char8_t = etl::atomic; #endif #if ETL_HAS_NATIVE_CHAR16_T - using atomic_char16_t = std::atomic; + using atomic_char16_t = etl::atomic; #endif #if ETL_HAS_NATIVE_CHAR32_T - using atomic_char32_t = std::atomic; + using atomic_char32_t = etl::atomic; #endif #if ETL_USING_8BIT_TYPES - using atomic_uint8_t = std::atomic; - using atomic_int8_t = std::atomic; + using atomic_uint8_t = etl::atomic; + using atomic_int8_t = etl::atomic; #endif - using atomic_uint16_t = std::atomic; - using atomic_int16_t = std::atomic; - using atomic_uint32_t = std::atomic; - using atomic_int32_t = std::atomic; + using atomic_uint16_t = etl::atomic; + using atomic_int16_t = etl::atomic; + using atomic_uint32_t = etl::atomic; + using atomic_int32_t = etl::atomic; #if ETL_USING_64BIT_TYPES - using atomic_uint64_t = std::atomic; - using atomic_int64_t = std::atomic; + using atomic_uint64_t = etl::atomic; + using atomic_int64_t = etl::atomic; #endif - using atomic_int_least8_t = std::atomic; - using atomic_uint_least8_t = std::atomic; - using atomic_int_least16_t = std::atomic; - using atomic_uint_least16_t = std::atomic; - using atomic_int_least32_t = std::atomic; - using atomic_uint_least32_t = std::atomic; + using atomic_int_least8_t = etl::atomic; + using atomic_uint_least8_t = etl::atomic; + using atomic_int_least16_t = etl::atomic; + using atomic_uint_least16_t = etl::atomic; + using atomic_int_least32_t = etl::atomic; + using atomic_uint_least32_t = etl::atomic; #if ETL_USING_64BIT_TYPES - using atomic_int_least64_t = std::atomic; - using atomic_uint_least64_t = std::atomic; + using atomic_int_least64_t = etl::atomic; + using atomic_uint_least64_t = etl::atomic; #endif - using atomic_int_fast8_t = std::atomic; - using atomic_uint_fast8_t = std::atomic; - using atomic_int_fast16_t = std::atomic; - using atomic_uint_fast16_t = std::atomic; - using atomic_int_fast32_t = std::atomic; - using atomic_uint_fast32_t = std::atomic; + using atomic_int_fast8_t = etl::atomic; + using atomic_uint_fast8_t = etl::atomic; + using atomic_int_fast16_t = etl::atomic; + using atomic_uint_fast16_t = etl::atomic; + using atomic_int_fast32_t = etl::atomic; + using atomic_uint_fast32_t = etl::atomic; #if ETL_USING_64BIT_TYPES - using atomic_int_fast64_t = std::atomic; - using atomic_uint_fast64_t = std::atomic; + using atomic_int_fast64_t = etl::atomic; + using atomic_uint_fast64_t = etl::atomic; #endif - using atomic_intptr_t = std::atomic; - using atomic_uintptr_t = std::atomic; - using atomic_size_t = std::atomic; - using atomic_ptrdiff_t = std::atomic; - using atomic_intmax_t = std::atomic; - using atomic_uintmax_t = std::atomic; + using atomic_intptr_t = etl::atomic; + using atomic_uintptr_t = etl::atomic; + using atomic_size_t = etl::atomic; + using atomic_ptrdiff_t = etl::atomic; + using atomic_intmax_t = etl::atomic; + using atomic_uintmax_t = etl::atomic; } // namespace etl #endif diff --git a/include/etl/iterator.h b/include/etl/iterator.h index 8394c5f9..263ab5c6 100644 --- a/include/etl/iterator.h +++ b/include/etl/iterator.h @@ -958,8 +958,43 @@ namespace etl template ETL_CONSTANT bool is_random_access_iterator_concept::value; +#if ETL_USING_CPP11 + //*************************************************************************** + /// Trait to detect if a type is a container (has iterator and begin/end) + /// but is not itself an iterator. + /// Used to constrain begin()/end() free functions in C++26. + //*************************************************************************** + namespace private_iterator + { + // Check if T has iterator_category (i.e., is an iterator) + template + struct has_iterator_category : etl::false_type + { + }; + + template + struct has_iterator_category> : etl::true_type + { + }; + + // is_container: has iterator/const_iterator/begin/end but does NOT have iterator_category + template + struct is_container : etl::false_type + { + }; + + template + struct is_container< + T, etl::void_t< typename T::iterator, typename T::const_iterator, decltype(etl::declval().begin()), decltype(etl::declval().end()) >> + : etl::bool_constant::value> + { + }; + } // namespace private_iterator +#endif + #if ETL_NOT_USING_STL || ETL_CPP11_NOT_SUPPORTED - #if ETL_CPP11_SUPPORTED + #if ETL_USING_CPP11 + //***************************************************************************** /// Get the 'begin' iterator. /// Note: Contains SFINAE guard, ensuring they only participate in overload @@ -969,7 +1004,8 @@ namespace etl ///\ingroup container //***************************************************************************** template ().begin())> > - ETL_CONSTEXPR typename TContainer::iterator begin(TContainer& container) + ETL_CONSTEXPR typename etl::enable_if::value, typename TContainer::iterator>::type + begin(TContainer& container) { return container.begin(); } @@ -979,7 +1015,8 @@ namespace etl ///\ingroup container //***************************************************************************** template ().begin())> > - ETL_CONSTEXPR typename TContainer::const_iterator begin(const TContainer& container) + ETL_CONSTEXPR typename etl::enable_if::value, typename TContainer::const_iterator>::type + begin(const TContainer& container) { return container.begin(); } @@ -989,7 +1026,8 @@ namespace etl ///\ingroup container //***************************************************************************** template ().cbegin())> > - ETL_CONSTEXPR typename TContainer::const_iterator cbegin(const TContainer& container) + ETL_CONSTEXPR typename etl::enable_if::value, typename TContainer::const_iterator>::type + cbegin(const TContainer& container) { return container.cbegin(); } @@ -999,7 +1037,7 @@ namespace etl ///\ingroup container //***************************************************************************** template ().end())> > - ETL_CONSTEXPR typename TContainer::iterator end(TContainer& container) + ETL_CONSTEXPR typename etl::enable_if::value, typename TContainer::iterator>::type end(TContainer& container) { return container.end(); } @@ -1009,7 +1047,8 @@ namespace etl ///\ingroup container //***************************************************************************** template ().end())> > - ETL_CONSTEXPR typename TContainer::const_iterator end(const TContainer& container) + ETL_CONSTEXPR typename etl::enable_if::value, typename TContainer::const_iterator>::type + end(const TContainer& container) { return container.end(); } @@ -1019,12 +1058,15 @@ namespace etl ///\ingroup container //***************************************************************************** template ().cend())> > - ETL_CONSTEXPR typename TContainer::const_iterator cend(const TContainer& container) + ETL_CONSTEXPR typename etl::enable_if::value, typename TContainer::const_iterator>::type + cend(const TContainer& container) { return container.cend(); } #else - // C++03 fallback: no SFINAE guards needed since std::ranges does not exist. + // C++03 fallback: + // - no SFINAE guards needed since std::ranges does not exist + // - no constraint needed as C++26 ADL issue doesn't apply //***************************************************************************** /// Get the 'begin' iterator. ///\ingroup container @@ -1148,14 +1190,15 @@ namespace etl #endif #if ETL_NOT_USING_STL || ETL_CPP14_NOT_SUPPORTED - #if ETL_CPP11_SUPPORTED + #if ETL_USING_CPP11 //***************************************************************************** /// Get the 'begin' reverse_iterator for a container. /// Note: Contains SFINAE guard (see begin/end above for rationale). ///\ingroup container //***************************************************************************** template ().rbegin())> > - ETL_CONSTEXPR typename TContainer::reverse_iterator rbegin(TContainer& container) + ETL_CONSTEXPR typename etl::enable_if::value, typename TContainer::reverse_iterator>::type + rbegin(TContainer& container) { return container.rbegin(); } @@ -1165,7 +1208,8 @@ namespace etl ///\ingroup container //***************************************************************************** template ().rbegin())> > - ETL_CONSTEXPR typename TContainer::const_reverse_iterator rbegin(const TContainer& container) + ETL_CONSTEXPR typename etl::enable_if::value, typename TContainer::const_reverse_iterator>::type + rbegin(const TContainer& container) { return container.rbegin(); } @@ -1175,7 +1219,8 @@ namespace etl ///\ingroup container //***************************************************************************** template ().crbegin())> > - ETL_CONSTEXPR typename TContainer::const_reverse_iterator crbegin(const TContainer& container) + ETL_CONSTEXPR typename etl::enable_if::value, typename TContainer::const_reverse_iterator>::type + crbegin(const TContainer& container) { return container.crbegin(); } @@ -1185,7 +1230,8 @@ namespace etl ///\ingroup container //***************************************************************************** template ().rend())> > - ETL_CONSTEXPR typename TContainer::reverse_iterator rend(TContainer& container) + ETL_CONSTEXPR typename etl::enable_if::value, typename TContainer::reverse_iterator>::type + rend(TContainer& container) { return container.rend(); } @@ -1195,7 +1241,8 @@ namespace etl ///\ingroup container //***************************************************************************** template ().rend())> > - ETL_CONSTEXPR typename TContainer::const_reverse_iterator rend(const TContainer& container) + ETL_CONSTEXPR typename etl::enable_if::value, typename TContainer::const_reverse_iterator>::type + rend(const TContainer& container) { return container.rend(); } @@ -1205,12 +1252,15 @@ namespace etl ///\ingroup container //***************************************************************************** template ().crend())> > - ETL_CONSTEXPR typename TContainer::const_reverse_iterator crend(const TContainer& container) + ETL_CONSTEXPR typename etl::enable_if::value, typename TContainer::const_reverse_iterator>::type + crend(const TContainer& container) { return container.crend(); } #else - // C++03 fallback: no SFINAE guards needed since std::ranges does not exist. + // C++03 fallback: + // - no SFINAE guards needed since std::ranges does not exist. + // - no constraint needed as C++26 ADL issue doesn't apply //***************************************************************************** /// Get the 'begin' reverse_iterator for a container. ///\ingroup container diff --git a/include/etl/memory.h b/include/etl/memory.h index b1456298..0bf9e3d6 100644 --- a/include/etl/memory.h +++ b/include/etl/memory.h @@ -1798,6 +1798,117 @@ namespace etl } // namespace ranges #endif +#if ETL_USING_CPP11 + //***************************************************************************** + /// Trivially relocate a range of objects. + /// This function relocates objects by copying their bytes using memmove. + /// The source objects' lifetimes are ended without calling destructors. + /// Based on C++26 P2786R13. + /// https://en.cppreference.com/w/cpp/memory/trivially_relocate + ///\ingroup memory + //***************************************************************************** + template + typename etl::enable_if::value && !etl::is_const::value, T*>::type trivially_relocate(T* first, T* last, + T* result) + { + if (first == result) + { + return last; + } + + const size_t count = static_cast(last - first); + + if (count > 0) + { + // Use memmove to handle overlapping ranges + ::memmove(static_cast(result), static_cast(first), count * sizeof(T)); + } + + return result + count; + } + + //***************************************************************************** + /// Relocate implementation for trivially relocatable types. + /// Delegates to etl::trivially_relocate. + /// Uses SFINAE (enable_if) so that etl::trivially_relocate is never + /// instantiated for non-trivially relocatable types on pre-C++17 compilers, + /// avoiding the ill-formed instantiation that would occur with a plain + /// ETL_IF_CONSTEXPR branch. + ///\ingroup memory + //***************************************************************************** + template + typename etl::enable_if::value, T*>::type relocate_impl(T* first, T* last, T* result) + { + return etl::trivially_relocate(first, last, result); + } + + //***************************************************************************** + /// Relocate implementation for non-trivially relocatable types. + /// Uses move construction + destroy. + ///\ingroup memory + //***************************************************************************** + template + typename etl::enable_if::value, T*>::type relocate_impl(T* first, T* last, T* result) + { + const ptrdiff_t count = last - first; + + // Check if ranges overlap and handle accordingly + if (result < first || result >= last) + { + // No overlap or destination is after source - iterate forward + T* src = first; + T* dst = result; + while (src != last) + { + ::new (static_cast(dst)) T(etl::move(*src)); + src->~T(); + ++src; + ++dst; + } + } + else + { + // Destination overlaps with source from below - iterate backward + T* src = last; + T* dst = result + count; + while (src != first) + { + --src; + --dst; + ::new (static_cast(dst)) T(etl::move(*src)); + src->~T(); + } + } + + return result + count; + } + + //***************************************************************************** + /// Relocate a range of objects. + /// For trivially relocatable types, uses trivially_relocate via relocate_impl. + /// For other nothrow relocatable types, uses move + destroy via relocate_impl. + /// Delegates to SFINAE-guarded relocate_impl overloads instead of using + /// ETL_IF_CONSTEXPR, so that etl::trivially_relocate is never instantiated + /// for non-trivially relocatable types on pre-C++17 compilers. + /// Based on C++26 P2786R13. + /// https://en.cppreference.com/w/cpp/memory/relocate + ///\ingroup memory + //***************************************************************************** + template + typename etl::enable_if::value && !etl::is_const::value, T*>::type relocate(T* first, T* last, T* result) + { + // Handle trivial relocation case + if (first == result || first == last) + { + return (first == result) ? last : result; + } + + // SFINAE on etl::is_trivially_relocatable selects the correct overload + // so that etl::trivially_relocate is only instantiated when valid. + return relocate_impl(first, last, result); + } +#endif + //***************************************************************************** /// Default deleter. ///\tparam T The pointed to type type. diff --git a/include/etl/numeric.h b/include/etl/numeric.h index cc8752d3..7e740839 100644 --- a/include/etl/numeric.h +++ b/include/etl/numeric.h @@ -204,6 +204,284 @@ namespace etl return typecast_a(a) + (typecast_t(t) * (typecast_b(b) - typecast_a(a))); } + + //*************************************************************************** + /// Saturating addition for unsigned integers. + /// Returns x + y, clamped to the range of T. + //*************************************************************************** + template + ETL_CONSTEXPR14 typename etl::enable_if::value && etl::is_unsigned::value, T>::type add_sat(T x, T y) ETL_NOEXCEPT + { + T result = static_cast(x + y); + // Overflow occurred if result < x + if (result < x) + { + return etl::numeric_limits::max(); + } + return result; + } + + //*************************************************************************** + /// Saturating addition for signed integers. + /// Returns x + y, clamped to the range of T. + //*************************************************************************** + template + ETL_CONSTEXPR14 typename etl::enable_if::value && etl::is_signed::value, T>::type add_sat(T x, T y) ETL_NOEXCEPT + { + // Check for overflow: both operands have same sign and result has different sign + if (y > T(0)) + { + // Positive overflow check + if (x > (etl::numeric_limits::max() - y)) + { + return etl::numeric_limits::max(); + } + } + else + { + // Negative overflow check + if (x < (etl::numeric_limits::min() - y)) + { + return etl::numeric_limits::min(); + } + } + + return static_cast(x + y); + } + + //*************************************************************************** + /// Saturating subtraction for unsigned integers. + /// Returns x - y, clamped to the range of T. + //*************************************************************************** + template + ETL_CONSTEXPR14 typename etl::enable_if::value && etl::is_unsigned::value, T>::type sub_sat(T x, T y) ETL_NOEXCEPT + { + // Underflow occurred if y > x + if (y > x) + { + return T(0); + } + return static_cast(x - y); + } + + //*************************************************************************** + /// Saturating subtraction for signed integers. + /// Returns x - y, clamped to the range of T. + //*************************************************************************** + template + ETL_CONSTEXPR14 typename etl::enable_if::value && etl::is_signed::value, T>::type sub_sat(T x, T y) ETL_NOEXCEPT + { + // Check for overflow/underflow + if (y > T(0)) + { + // Subtracting positive: check for underflow + if (x < (etl::numeric_limits::min() + y)) + { + return etl::numeric_limits::min(); + } + } + else + { + // Subtracting negative (adding): check for overflow + if (x > (etl::numeric_limits::max() + y)) + { + return etl::numeric_limits::max(); + } + } + + return static_cast(x - y); + } + + //*************************************************************************** + /// Saturating multiplication for unsigned integers. + /// Returns x * y, clamped to the range of T. + //*************************************************************************** + template + ETL_CONSTEXPR14 typename etl::enable_if::value && etl::is_unsigned::value, T>::type mul_sat(T x, T y) ETL_NOEXCEPT + { + if ((x == T(0)) || (y == T(0))) + { + return T(0); + } + + // Check for overflow: x * y > max => x > max / y + if (x > (etl::numeric_limits::max() / y)) + { + return etl::numeric_limits::max(); + } + + return static_cast(x * y); + } + + //*************************************************************************** + /// Saturating multiplication for signed integers. + /// Returns x * y, clamped to the range of T. + //*************************************************************************** + template + ETL_CONSTEXPR14 typename etl::enable_if::value && etl::is_signed::value, T>::type mul_sat(T x, T y) ETL_NOEXCEPT + { + if ((x == T(0)) || (y == T(0))) + { + return T(0); + } + + // Both positive + if ((x > T(0)) && (y > T(0))) + { + if (x > (etl::numeric_limits::max() / y)) + { + return etl::numeric_limits::max(); + } + } + // Both negative + else if ((x < T(0)) && (y < T(0))) + { + if (x < (etl::numeric_limits::max() / y)) + { + return etl::numeric_limits::max(); + } + } + // Different signs (x positive, y negative) + else if ((x > T(0)) && (y < T(0))) + { + if (y < (etl::numeric_limits::min() / x)) + { + return etl::numeric_limits::min(); + } + } + // Different signs (x negative, y positive) + else + { + if (x < (etl::numeric_limits::min() / y)) + { + return etl::numeric_limits::min(); + } + } + + return static_cast(x * y); + } + + //*************************************************************************** + /// Saturating division for unsigned integers. + /// Returns x / y. For unsigned types, no saturation is needed. + /// \pre y != 0 (undefined behaviour if y is zero, matching C++26). + //*************************************************************************** + template + ETL_CONSTEXPR14 typename etl::enable_if::value && etl::is_unsigned::value, T>::type div_sat(T x, T y) ETL_NOEXCEPT + { + return static_cast(x / y); + } + + //*************************************************************************** + /// Saturating division for signed integers. + /// Returns x / y, clamped to the range of T. + /// The only case of overflow is min / -1. + /// \pre y != 0 (undefined behaviour if y is zero, matching C++26). + //*************************************************************************** + template + ETL_CONSTEXPR14 typename etl::enable_if::value && etl::is_signed::value, T>::type div_sat(T x, T y) ETL_NOEXCEPT + { + // The only overflow case: min / -1 would be max + 1 + if ((x == etl::numeric_limits::min()) && (y == T(-1))) + { + return etl::numeric_limits::max(); + } + + return static_cast(x / y); + } + + //*************************************************************************** + /// saturate_cast + /// Converts an integer value to another integer type, clamping the value + /// to the representable range of the destination type. + /// C++26 equivalent of std::saturate_cast. + /// + /// When the source value is within the range of R, returns the value as R. + /// When the source value is below R's minimum, returns numeric_limits::min(). + /// When the source value is above R's maximum, returns numeric_limits::max(). + //*************************************************************************** + + // Case 1: Both unsigned. + template + ETL_CONSTEXPR14 + typename etl::enable_if::value && etl::is_integral::value && etl::is_unsigned::value && etl::is_unsigned::value, + R>::type + saturate_cast(T value) ETL_NOEXCEPT + { + // If sizeof(R) >= sizeof(T), all values of T fit in R. + // If sizeof(R) < sizeof(T), clamp to R's max. The comparison is safe + // because R's max fits in T when T is wider. + if ((sizeof(R) < sizeof(T)) && (value > static_cast(etl::numeric_limits::max()))) + { + return etl::numeric_limits::max(); + } + return static_cast(value); + } + + // Case 2: Both signed. + template + ETL_CONSTEXPR14 + typename etl::enable_if::value && etl::is_integral::value && etl::is_signed::value && etl::is_signed::value, R>::type + saturate_cast(T value) ETL_NOEXCEPT + { + // Only need to clamp when narrowing (R is smaller than T). + // When sizeof(R) >= sizeof(T), all values of T fit in R. + if (sizeof(R) < sizeof(T)) + { + if (value > static_cast(etl::numeric_limits::max())) + { + return etl::numeric_limits::max(); + } + if (value < static_cast(etl::numeric_limits::min())) + { + return etl::numeric_limits::min(); + } + } + return static_cast(value); + } + + // Case 3: Signed source -> Unsigned destination. + template + ETL_CONSTEXPR14 + typename etl::enable_if::value && etl::is_integral::value && etl::is_unsigned::value && etl::is_signed::value, + R>::type + saturate_cast(T value) ETL_NOEXCEPT + { + if (value < T(0)) + { + return R(0); + } + + typedef typename etl::make_unsigned::type unsigned_t; + unsigned_t uvalue = static_cast(value); + + // Compare in unsigned domain. R's max is always representable as unsigned_t + // when sizeof(T) > sizeof(R), and when sizeof(R) >= sizeof(T) all positive + // values of T fit in R. + if ((sizeof(R) < sizeof(T)) && (uvalue > static_cast(etl::numeric_limits::max()))) + { + return etl::numeric_limits::max(); + } + return static_cast(value); + } + + // Case 4: Unsigned source -> Signed destination. + template + ETL_CONSTEXPR14 + typename etl::enable_if::value && etl::is_integral::value && etl::is_signed::value && etl::is_unsigned::value, + R>::type + saturate_cast(T value) ETL_NOEXCEPT + { + // R's max is positive, so we can safely represent it as T (unsigned) when + // sizeof(T) >= sizeof(R). When sizeof(T) < sizeof(R), all values of T fit. + typedef typename etl::make_unsigned::type unsigned_r; + + if (value > static_cast(static_cast(etl::numeric_limits::max()))) + { + return etl::numeric_limits::max(); + } + return static_cast(value); + } } // namespace etl #endif diff --git a/include/etl/platform.h b/include/etl/platform.h index a9918b24..bbf3022c 100644 --- a/include/etl/platform.h +++ b/include/etl/platform.h @@ -489,6 +489,18 @@ SOFTWARE. #define ETL_ASSUME ETL_DO_NOTHING #endif +//************************************* +// C++26 +#if defined(__has_cpp_attribute) + #if __has_cpp_attribute(indeterminate) + #define ETL_INDETERMINATE [[indeterminate]] + #else + #define ETL_INDETERMINATE + #endif +#else + #define ETL_INDETERMINATE +#endif + //************************************* // Determine if the ETL can use char8_t type. #if ETL_NO_SMALL_CHAR_SUPPORT @@ -650,6 +662,7 @@ namespace etl static ETL_CONSTANT bool using_cpp17 = (ETL_USING_CPP17 == 1); static ETL_CONSTANT bool using_cpp20 = (ETL_USING_CPP20 == 1); static ETL_CONSTANT bool using_cpp23 = (ETL_USING_CPP23 == 1); + static ETL_CONSTANT bool using_cpp26 = (ETL_USING_CPP26 == 1); static ETL_CONSTANT bool using_gcc_compiler = (ETL_USING_GCC_COMPILER == 1); static ETL_CONSTANT bool using_microsoft_compiler = (ETL_USING_MICROSOFT_COMPILER == 1); static ETL_CONSTANT bool using_arm5_compiler = (ETL_USING_ARM5_COMPILER == 1); @@ -697,6 +710,9 @@ namespace etl static ETL_CONSTANT bool has_chrono_literals_microseconds = (ETL_HAS_CHRONO_LITERALS_DURATION == 1); static ETL_CONSTANT bool has_chrono_literals_nanoseconds = (ETL_HAS_CHRONO_LITERALS_DURATION == 1); static ETL_CONSTANT bool has_std_byteswap = (ETL_HAS_STD_BYTESWAP == 1); + static ETL_CONSTANT bool has_std_is_virtual_base_of = (ETL_HAS_STD_IS_VIRTUAL_BASE_OF == 1); + static ETL_CONSTANT bool has_std_trivially_relocatable = (ETL_HAS_STD_TRIVIALLY_RELOCATABLE == 1); + static ETL_CONSTANT bool has_std_atomic_min_max = (ETL_HAS_STD_ATOMIC_MIN_MAX == 1); static ETL_CONSTANT bool has_noexcept_function_type = (ETL_HAS_NOEXCEPT_FUNCTION_TYPE == 1); // Is... diff --git a/include/etl/profiles/cpp20.h b/include/etl/profiles/cpp20.h new file mode 100644 index 00000000..ea1fa98a --- /dev/null +++ b/include/etl/profiles/cpp20.h @@ -0,0 +1,49 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2026 BMW AG + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#ifndef ETL_CPP20_INCLUDED +#define ETL_CPP20_INCLUDED + +//***************************************************************************** +// Generic C++20 +//***************************************************************************** + +#define ETL_TARGET_DEVICE_GENERIC +#define ETL_TARGET_OS_NONE +#define ETL_COMPILER_GENERIC +#define ETL_CPP11_SUPPORTED 1 +#define ETL_CPP14_SUPPORTED 1 +#define ETL_CPP17_SUPPORTED 1 +#define ETL_CPP20_SUPPORTED 1 +#define ETL_NO_NULLPTR_SUPPORT 0 +#define ETL_NO_LARGE_CHAR_SUPPORT 0 +#define ETL_CPP11_TYPE_TRAITS_IS_TRIVIAL_SUPPORTED 1 + +#endif diff --git a/include/etl/profiles/cpp20_no_stl.h b/include/etl/profiles/cpp20_no_stl.h new file mode 100644 index 00000000..c997cdc8 --- /dev/null +++ b/include/etl/profiles/cpp20_no_stl.h @@ -0,0 +1,50 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2026 BMW AG + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#ifndef ETL_CPP20_NO_STL_INCLUDED +#define ETL_CPP20_NO_STL_INCLUDED + +//***************************************************************************** +// Generic C++20 without STL support +//***************************************************************************** + +#define ETL_TARGET_DEVICE_GENERIC +#define ETL_TARGET_OS_NONE +#define ETL_COMPILER_GENERIC +#define ETL_CPP11_SUPPORTED 1 +#define ETL_CPP14_SUPPORTED 1 +#define ETL_CPP17_SUPPORTED 1 +#define ETL_CPP20_SUPPORTED 1 +#define ETL_NO_NULLPTR_SUPPORT 0 +#define ETL_NO_LARGE_CHAR_SUPPORT 0 +#define ETL_CPP11_TYPE_TRAITS_IS_TRIVIAL_SUPPORTED 0 +#define ETL_NO_STL + +#endif diff --git a/include/etl/profiles/cpp23.h b/include/etl/profiles/cpp23.h new file mode 100644 index 00000000..21fc36f0 --- /dev/null +++ b/include/etl/profiles/cpp23.h @@ -0,0 +1,50 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2026 BMW AG + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#ifndef ETL_CPP23_INCLUDED +#define ETL_CPP23_INCLUDED + +//***************************************************************************** +// Generic C++23 +//***************************************************************************** + +#define ETL_TARGET_DEVICE_GENERIC +#define ETL_TARGET_OS_NONE +#define ETL_COMPILER_GENERIC +#define ETL_CPP11_SUPPORTED 1 +#define ETL_CPP14_SUPPORTED 1 +#define ETL_CPP17_SUPPORTED 1 +#define ETL_CPP20_SUPPORTED 1 +#define ETL_CPP23_SUPPORTED 1 +#define ETL_NO_NULLPTR_SUPPORT 0 +#define ETL_NO_LARGE_CHAR_SUPPORT 0 +#define ETL_CPP11_TYPE_TRAITS_IS_TRIVIAL_SUPPORTED 1 + +#endif diff --git a/include/etl/profiles/cpp23_no_stl.h b/include/etl/profiles/cpp23_no_stl.h new file mode 100644 index 00000000..d06a8545 --- /dev/null +++ b/include/etl/profiles/cpp23_no_stl.h @@ -0,0 +1,51 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2026 BMW AG + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#ifndef ETL_CPP23_NO_STL_INCLUDED +#define ETL_CPP23_NO_STL_INCLUDED + +//***************************************************************************** +// Generic C++23 without STL support +//***************************************************************************** + +#define ETL_TARGET_DEVICE_GENERIC +#define ETL_TARGET_OS_NONE +#define ETL_COMPILER_GENERIC +#define ETL_CPP11_SUPPORTED 1 +#define ETL_CPP14_SUPPORTED 1 +#define ETL_CPP17_SUPPORTED 1 +#define ETL_CPP20_SUPPORTED 1 +#define ETL_CPP23_SUPPORTED 1 +#define ETL_NO_NULLPTR_SUPPORT 0 +#define ETL_NO_LARGE_CHAR_SUPPORT 0 +#define ETL_CPP11_TYPE_TRAITS_IS_TRIVIAL_SUPPORTED 0 +#define ETL_NO_STL + +#endif diff --git a/include/etl/profiles/cpp26.h b/include/etl/profiles/cpp26.h new file mode 100644 index 00000000..8ba60ee3 --- /dev/null +++ b/include/etl/profiles/cpp26.h @@ -0,0 +1,51 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2026 BMW AG + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#ifndef ETL_CPP26_INCLUDED +#define ETL_CPP26_INCLUDED + +//***************************************************************************** +// Generic C++26 +//***************************************************************************** + +#define ETL_TARGET_DEVICE_GENERIC +#define ETL_TARGET_OS_NONE +#define ETL_COMPILER_GENERIC +#define ETL_CPP11_SUPPORTED 1 +#define ETL_CPP14_SUPPORTED 1 +#define ETL_CPP17_SUPPORTED 1 +#define ETL_CPP20_SUPPORTED 1 +#define ETL_CPP23_SUPPORTED 1 +#define ETL_CPP26_SUPPORTED 1 +#define ETL_NO_NULLPTR_SUPPORT 0 +#define ETL_NO_LARGE_CHAR_SUPPORT 0 +#define ETL_CPP11_TYPE_TRAITS_IS_TRIVIAL_SUPPORTED 1 + +#endif diff --git a/include/etl/profiles/cpp26_no_stl.h b/include/etl/profiles/cpp26_no_stl.h new file mode 100644 index 00000000..76dcf143 --- /dev/null +++ b/include/etl/profiles/cpp26_no_stl.h @@ -0,0 +1,52 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2026 BMW AG + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#ifndef ETL_CPP26_NO_STL_INCLUDED +#define ETL_CPP26_NO_STL_INCLUDED + +//***************************************************************************** +// Generic C++26 without STL support +//***************************************************************************** + +#define ETL_TARGET_DEVICE_GENERIC +#define ETL_TARGET_OS_NONE +#define ETL_COMPILER_GENERIC +#define ETL_CPP11_SUPPORTED 1 +#define ETL_CPP14_SUPPORTED 1 +#define ETL_CPP17_SUPPORTED 1 +#define ETL_CPP20_SUPPORTED 1 +#define ETL_CPP23_SUPPORTED 1 +#define ETL_CPP26_SUPPORTED 1 +#define ETL_NO_NULLPTR_SUPPORT 0 +#define ETL_NO_LARGE_CHAR_SUPPORT 0 +#define ETL_CPP11_TYPE_TRAITS_IS_TRIVIAL_SUPPORTED 0 +#define ETL_NO_STL + +#endif diff --git a/include/etl/profiles/determine_builtin_support.h b/include/etl/profiles/determine_builtin_support.h index 4a303fc0..b048922e 100644 --- a/include/etl/profiles/determine_builtin_support.h +++ b/include/etl/profiles/determine_builtin_support.h @@ -132,6 +132,14 @@ SOFTWARE. #if !defined(ETL_USING_BUILTIN_MEMCHR) #define ETL_USING_BUILTIN_MEMCHR __has_builtin(__builtin_memchr) #endif + + #if !defined(ETL_USING_BUILTIN_IS_VIRTUAL_BASE_OF) + #define ETL_USING_BUILTIN_IS_VIRTUAL_BASE_OF __has_builtin(__is_virtual_base_of) + #endif + + #if !defined(ETL_USING_BUILTIN_IS_TRIVIALLY_RELOCATABLE) + #define ETL_USING_BUILTIN_IS_TRIVIALLY_RELOCATABLE __has_builtin(__is_trivially_relocatable) + #endif #endif // The default. Set to 0, if not already set. @@ -183,6 +191,14 @@ SOFTWARE. #define ETL_USING_BUILTIN_MEMCHR 0 #endif +#if !defined(ETL_USING_BUILTIN_IS_VIRTUAL_BASE_OF) + #define ETL_USING_BUILTIN_IS_VIRTUAL_BASE_OF 0 +#endif + +#if !defined(ETL_USING_BUILTIN_IS_TRIVIALLY_RELOCATABLE) + #define ETL_USING_BUILTIN_IS_TRIVIALLY_RELOCATABLE 0 +#endif + namespace etl { namespace traits @@ -201,6 +217,8 @@ namespace etl static ETL_CONSTANT bool using_builtin_memset = (ETL_USING_BUILTIN_MEMSET == 1); static ETL_CONSTANT bool using_builtin_memcmp = (ETL_USING_BUILTIN_MEMCMP == 1); static ETL_CONSTANT bool using_builtin_memchr = (ETL_USING_BUILTIN_MEMCHR == 1); + static ETL_CONSTANT bool using_builtin_is_virtual_base_of = (ETL_USING_BUILTIN_IS_VIRTUAL_BASE_OF == 1); + static ETL_CONSTANT bool using_builtin_is_trivially_relocatable = (ETL_USING_BUILTIN_IS_TRIVIALLY_RELOCATABLE == 1); } // namespace traits } // namespace etl diff --git a/include/etl/profiles/determine_compiler_language_support.h b/include/etl/profiles/determine_compiler_language_support.h index 645bd06d..58bda6ef 100644 --- a/include/etl/profiles/determine_compiler_language_support.h +++ b/include/etl/profiles/determine_compiler_language_support.h @@ -35,6 +35,31 @@ SOFTWARE. #include "determine_compiler.h" +// Determine C++26 support +#if !defined(ETL_CPP26_SUPPORTED) + #if defined(__cplusplus) + #if defined(ETL_COMPILER_MICROSOFT) + #define ETL_CPP26_SUPPORTED (__cplusplus >= 202400L) + #elif defined(ETL_COMPILER_ARM5) + #define ETL_CPP26_SUPPORTED 0 + #elif defined(ETL_COMPILER_GCC) + #define ETL_CPP26_SUPPORTED (__cplusplus >= 202400L) + #else + #define ETL_CPP26_SUPPORTED (__cplusplus >= 202400L) + #endif + #else + #define ETL_CPP26_SUPPORTED 0 + #endif +#endif + +#if ETL_CPP26_SUPPORTED + #define ETL_CPP11_SUPPORTED 1 + #define ETL_CPP14_SUPPORTED 1 + #define ETL_CPP17_SUPPORTED 1 + #define ETL_CPP20_SUPPORTED 1 + #define ETL_CPP23_SUPPORTED 1 +#endif + // Determine C++23 support #if !defined(ETL_CPP23_SUPPORTED) #if defined(__cplusplus) @@ -162,6 +187,7 @@ SOFTWARE. #define ETL_CPP17_NOT_SUPPORTED (!ETL_CPP17_SUPPORTED) #define ETL_CPP20_NOT_SUPPORTED (!ETL_CPP20_SUPPORTED) #define ETL_CPP23_NOT_SUPPORTED (!ETL_CPP23_SUPPORTED) +#define ETL_CPP26_NOT_SUPPORTED (!ETL_CPP26_SUPPORTED) // 'Using' macros #define ETL_USING_CPP11 (ETL_CPP11_SUPPORTED == 1) @@ -169,12 +195,14 @@ SOFTWARE. #define ETL_USING_CPP17 (ETL_CPP17_SUPPORTED == 1) #define ETL_USING_CPP20 (ETL_CPP20_SUPPORTED == 1) #define ETL_USING_CPP23 (ETL_CPP23_SUPPORTED == 1) +#define ETL_USING_CPP26 (ETL_CPP26_SUPPORTED == 1) #define ETL_NOT_USING_CPP11 (ETL_CPP11_SUPPORTED == 0) #define ETL_NOT_USING_CPP14 (ETL_CPP14_SUPPORTED == 0) #define ETL_NOT_USING_CPP17 (ETL_CPP17_SUPPORTED == 0) #define ETL_NOT_USING_CPP20 (ETL_CPP20_SUPPORTED == 0) #define ETL_NOT_USING_CPP23 (ETL_CPP23_SUPPORTED == 0) +#define ETL_NOT_USING_CPP26 (ETL_CPP26_SUPPORTED == 0) #if !defined(ETL_NO_NULLPTR_SUPPORT) #define ETL_NO_NULLPTR_SUPPORT ETL_NOT_USING_CPP11 @@ -198,7 +226,9 @@ SOFTWARE. // Language standard #if !defined(ETL_LANGUAGE_STANDARD) - #if ETL_USING_CPP23 + #if ETL_USING_CPP26 + #define ETL_LANGUAGE_STANDARD 26 + #elif ETL_USING_CPP23 #define ETL_LANGUAGE_STANDARD 23 #elif ETL_USING_CPP20 #define ETL_LANGUAGE_STANDARD 20 @@ -227,10 +257,37 @@ SOFTWARE. #define ETL_HAS_STD_BYTESWAP 1 #endif #endif + + #if defined(__cpp_lib_is_virtual_base_of) + #if __cpp_lib_is_virtual_base_of != 0 + #define ETL_HAS_STD_IS_VIRTUAL_BASE_OF 1 + #endif + #endif + + #if defined(__cpp_lib_trivially_relocatable) + #if __cpp_lib_trivially_relocatable != 0 + #define ETL_HAS_STD_TRIVIALLY_RELOCATABLE 1 + #endif + #endif + + #if defined(__cpp_lib_atomic_min_max) + #if __cpp_lib_atomic_min_max != 0 + #define ETL_HAS_STD_ATOMIC_MIN_MAX 1 + #endif + #endif #endif #endif #ifndef ETL_HAS_STD_BYTESWAP #define ETL_HAS_STD_BYTESWAP 0 #endif +#ifndef ETL_HAS_STD_IS_VIRTUAL_BASE_OF + #define ETL_HAS_STD_IS_VIRTUAL_BASE_OF 0 +#endif +#ifndef ETL_HAS_STD_TRIVIALLY_RELOCATABLE + #define ETL_HAS_STD_TRIVIALLY_RELOCATABLE 0 +#endif +#ifndef ETL_HAS_STD_ATOMIC_MIN_MAX + #define ETL_HAS_STD_ATOMIC_MIN_MAX 0 +#endif #endif diff --git a/include/etl/ratio.h b/include/etl/ratio.h index f4476dff..21a2d894 100644 --- a/include/etl/ratio.h +++ b/include/etl/ratio.h @@ -161,12 +161,20 @@ namespace etl #endif //*********************************************************************** -/// Predefined ration types. +/// Predefined ratio types. //*********************************************************************** #if INT_MAX > INT32_MAX - typedef ratio<1, 1000000000000000000> atto; - typedef ratio<1, 1000000000000000> femto; - typedef ratio<1, 1000000000000> pico; + // 2022 SI prefix (10^-30) + typedef ratio<1, 1000000000000000000LL * 1000000000000LL> quecto; + // 2022 SI prefix (10^-27) + typedef ratio<1, 1000000000000000000LL * 1000000000LL> ronto; + // 10^-24 + typedef ratio<1, 1000000000000000000LL * 1000000LL> yocto; + // 10^-21 + typedef ratio<1, 1000000000000000000LL * 1000LL> zepto; + typedef ratio<1, 1000000000000000000> atto; + typedef ratio<1, 1000000000000000> femto; + typedef ratio<1, 1000000000000> pico; #endif #if (INT_MAX >= INT32_MAX) @@ -192,6 +200,14 @@ namespace etl typedef ratio<1000000000000, 1> tera; typedef ratio<1000000000000000, 1> peta; typedef ratio<1000000000000000000, 1> exa; + // 10^21 + typedef ratio<1000000000000000000LL * 1000LL, 1> zetta; + // 10^24 + typedef ratio<1000000000000000000LL * 1000000LL, 1> yotta; + // 2022 SI prefix (10^27) + typedef ratio<1000000000000000000LL * 1000000000LL, 1> ronna; + // 2022 SI prefix (10^30) + typedef ratio<1000000000000000000LL * 1000000000000LL, 1> quetta; #endif /// An approximation of Pi. diff --git a/include/etl/type_traits.h b/include/etl/type_traits.h index 411632ff..ad775db1 100644 --- a/include/etl/type_traits.h +++ b/include/etl/type_traits.h @@ -1170,6 +1170,21 @@ namespace etl inline constexpr bool is_base_of_v = is_base_of::value; #endif + //*************************************************************************** + /// is_virtual_base_of + /// Determines if TBase is a virtual base class of TDerived + #if ETL_USING_CPP11 && ETL_USING_BUILTIN_IS_VIRTUAL_BASE_OF + template + struct is_virtual_base_of : etl::bool_constant<__is_virtual_base_of(TBase, TDerived)> + { + }; + + #if ETL_USING_CPP17 + template + inline constexpr bool is_virtual_base_of_v = is_virtual_base_of::value; + #endif + #endif + //*************************************************************************** /// add_lvalue_reference template @@ -2017,6 +2032,32 @@ namespace etl inline constexpr bool is_base_of_v = std::is_base_of_v; #endif + //*************************************************************************** + /// is_virtual_base_of + /// Determines if TBase is a virtual base class of TDerived + ///\ingroup type_traits + #if ETL_HAS_STD_IS_VIRTUAL_BASE_OF + template + struct is_virtual_base_of : std::is_virtual_base_of + { + }; + + #if ETL_USING_CPP17 + template + inline constexpr bool is_virtual_base_of_v = std::is_virtual_base_of_v; + #endif + #elif ETL_USING_BUILTIN_IS_VIRTUAL_BASE_OF + template + struct is_virtual_base_of : etl::bool_constant<__is_virtual_base_of(TBase, TDerived)> + { + }; + + #if ETL_USING_CPP17 + template + inline constexpr bool is_virtual_base_of_v = is_virtual_base_of::value; + #endif + #endif + //*************************************************************************** /// is_class template @@ -2647,6 +2688,37 @@ namespace etl using is_trivially_copyable = etl::bool_constant::value || etl::is_pointer::value>; #endif + //********************************************* + // is_trivially_relocatable + #if ETL_HAS_STD_TRIVIALLY_RELOCATABLE && ETL_USING_STL + template + using is_trivially_relocatable = std::is_trivially_relocatable; + #elif ETL_USING_BUILTIN_IS_TRIVIALLY_RELOCATABLE + template + using is_trivially_relocatable = etl::bool_constant<__is_trivially_relocatable(T)>; + #else + template + using is_trivially_relocatable = etl::bool_constant::value && etl::is_trivially_destructible::value>; + #endif + + //********************************************* + // is_nothrow_relocatable + // A type is nothrow relocatable if it is trivially relocatable, or + // if it has a nothrow move constructor and nothrow destructor. + #if ETL_HAS_STD_TRIVIALLY_RELOCATABLE && ETL_USING_STL + template + using is_nothrow_relocatable = std::is_nothrow_relocatable; + #elif ETL_USING_STL + template + using is_nothrow_relocatable = etl::bool_constant< etl::is_trivially_relocatable::value + || (std::is_nothrow_move_constructible::type>::value + && std::is_nothrow_destructible::type>::value)>; + #else + // Fallback: only trivially relocatable types are known to be nothrow relocatable + template + using is_nothrow_relocatable = etl::is_trivially_relocatable; + #endif + #elif defined(ETL_USE_TYPE_TRAITS_BUILTINS) && !defined(ETL_USER_DEFINED_TYPE_TRAITS) //********************************************* @@ -2800,6 +2872,29 @@ namespace etl static ETL_CONSTANT bool value = __is_trivially_copyable(T); }; + //********************************************* + // is_trivially_relocatable + template + struct is_trivially_relocatable + { + #if ETL_USING_BUILTIN_IS_TRIVIALLY_RELOCATABLE + static ETL_CONSTANT bool value = __is_trivially_relocatable(T); + #else + static ETL_CONSTANT bool value = etl::is_trivially_copyable::value && etl::is_trivially_destructible::value; + #endif + }; + + //********************************************* + // is_nothrow_relocatable + // A type is nothrow relocatable if it is trivially relocatable, or + // if it has a nothrow move constructor and nothrow destructor. + template + struct is_nothrow_relocatable + { + // In builtins mode, conservatively use trivially_relocatable as the definition + static ETL_CONSTANT bool value = etl::is_trivially_relocatable::value; + }; + #elif defined(ETL_USER_DEFINED_TYPE_TRAITS) && !defined(ETL_USE_TYPE_TRAITS_BUILTINS) //********************************************* @@ -2959,6 +3054,33 @@ namespace etl template struct is_trivially_copyable; + //********************************************* + // is_trivially_relocatable + template ::value || etl::is_pointer::value> + struct is_trivially_relocatable; + + template + struct is_trivially_relocatable : public etl::true_type + { + }; + + template + struct is_trivially_relocatable; + + //********************************************* + // is_nothrow_relocatable + // In user-defined mode, users must specialize for non-trivially-relocatable types + template ::value || etl::is_pointer::value> + struct is_nothrow_relocatable; + + template + struct is_nothrow_relocatable : public etl::true_type + { + }; + + template + struct is_nothrow_relocatable; + #else //********************************************* @@ -3126,6 +3248,25 @@ namespace etl { }; + //********************************************* + // is_trivially_relocatable + template + #if ETL_USING_BUILTIN_IS_TRIVIALLY_RELOCATABLE + struct is_trivially_relocatable : public etl::bool_constant<__is_trivially_relocatable(T)> + #else + struct is_trivially_relocatable : public etl::bool_constant::value && etl::is_trivially_destructible::value> + #endif + { + }; + + //********************************************* + // is_nothrow_relocatable + // Fallback: only trivially relocatable types are known to be nothrow relocatable + template + struct is_nothrow_relocatable : public etl::is_trivially_relocatable + { + }; + #endif template @@ -3195,6 +3336,12 @@ namespace etl template inline constexpr bool is_trivially_copyable_v = etl::is_trivially_copyable::value; + template + inline constexpr bool is_trivially_relocatable_v = etl::is_trivially_relocatable::value; + + template + inline constexpr bool is_nothrow_relocatable_v = etl::is_nothrow_relocatable::value; + #endif #if ETL_USING_CPP11 diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 99792fce..a7e61fb9 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -406,10 +406,26 @@ elseif (ETL_CXX_STANDARD MATCHES "20") message(STATUS "Compiling for C++20") set_property(TARGET etl_tests PROPERTY CXX_STANDARD 20) elseif (ETL_CXX_STANDARD MATCHES "23") - message(STATUS "Compiling for C++23") - set_property(TARGET etl_tests PROPERTY CXX_STANDARD 23) + if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.20") + message(STATUS "Compiling for C++23") + set_property(TARGET etl_tests PROPERTY CXX_STANDARD 23) + else() + message(STATUS "CMake version ${CMAKE_VERSION} does not support C++23, falling back to C++20") + set_property(TARGET etl_tests PROPERTY CXX_STANDARD 20) + endif() +elseif (ETL_CXX_STANDARD MATCHES "26") + if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.25") + message(STATUS "Compiling for C++26") + set_property(TARGET etl_tests PROPERTY CXX_STANDARD 26) + elseif (CMAKE_VERSION VERSION_GREATER_EQUAL "3.20") + message(STATUS "CMake version ${CMAKE_VERSION} does not support C++26, falling back to C++23") + set_property(TARGET etl_tests PROPERTY CXX_STANDARD 23) + else() + message(FATAL_ERROR "CMake version ${CMAKE_VERSION} is too old to support C++23 or C++26. Please upgrade to CMake 3.20 or later.") + endif() else() - message(STATUS "Unsupported C++ standard") + message(STATUS "Compiling for C++17") + set_property(TARGET etl_tests PROPERTY CXX_STANDARD 17) endif() if (NO_STL OR ETL_NO_STL) diff --git a/test/etl_error_handler/assert_function/CMakeLists.txt b/test/etl_error_handler/assert_function/CMakeLists.txt index babd03cc..f9ac1b49 100644 --- a/test/etl_error_handler/assert_function/CMakeLists.txt +++ b/test/etl_error_handler/assert_function/CMakeLists.txt @@ -34,9 +34,27 @@ elseif (ETL_CXX_STANDARD MATCHES "17") elseif (ETL_CXX_STANDARD MATCHES "20") message(STATUS "Compiling for C++20") set_property(TARGET etl_tests PROPERTY CXX_STANDARD 20) +elseif (ETL_CXX_STANDARD MATCHES "23") + if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.20") + message(STATUS "Compiling for C++23") + set_property(TARGET etl_tests PROPERTY CXX_STANDARD 23) + else() + message(STATUS "CMake version ${CMAKE_VERSION} does not support C++23, falling back to C++20") + set_property(TARGET etl_tests PROPERTY CXX_STANDARD 20) + endif() +elseif (ETL_CXX_STANDARD MATCHES "26") + if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.25") + message(STATUS "Compiling for C++26") + set_property(TARGET etl_tests PROPERTY CXX_STANDARD 26) + elseif (CMAKE_VERSION VERSION_GREATER_EQUAL "3.20") + message(STATUS "CMake version ${CMAKE_VERSION} does not support C++26, falling back to C++23") + set_property(TARGET etl_tests PROPERTY CXX_STANDARD 23) + else() + message(FATAL_ERROR "CMake version ${CMAKE_VERSION} is too old to support C++23 or C++26. Please upgrade to CMake 3.20 or later.") + endif() else() - message(STATUS "Compiling for C++23") - set_property(TARGET etl_tests PROPERTY CXX_STANDARD 23) + message(STATUS "Compiling for C++17") + set_property(TARGET etl_tests PROPERTY CXX_STANDARD 17) endif() if (ETL_OPTIMISATION MATCHES "-O1") diff --git a/test/etl_error_handler/exceptions/CMakeLists.txt b/test/etl_error_handler/exceptions/CMakeLists.txt index 2da119b0..eac58405 100644 --- a/test/etl_error_handler/exceptions/CMakeLists.txt +++ b/test/etl_error_handler/exceptions/CMakeLists.txt @@ -32,9 +32,27 @@ elseif (ETL_CXX_STANDARD MATCHES "17") elseif (ETL_CXX_STANDARD MATCHES "20") message(STATUS "Compiling for C++20") set_property(TARGET etl_tests PROPERTY CXX_STANDARD 20) +elseif (ETL_CXX_STANDARD MATCHES "23") + if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.20") + message(STATUS "Compiling for C++23") + set_property(TARGET etl_tests PROPERTY CXX_STANDARD 23) + else() + message(STATUS "CMake version ${CMAKE_VERSION} does not support C++23, falling back to C++20") + set_property(TARGET etl_tests PROPERTY CXX_STANDARD 20) + endif() +elseif (ETL_CXX_STANDARD MATCHES "26") + if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.25") + message(STATUS "Compiling for C++26") + set_property(TARGET etl_tests PROPERTY CXX_STANDARD 26) + elseif (CMAKE_VERSION VERSION_GREATER_EQUAL "3.20") + message(STATUS "CMake version ${CMAKE_VERSION} does not support C++26, falling back to C++23") + set_property(TARGET etl_tests PROPERTY CXX_STANDARD 23) + else() + message(FATAL_ERROR "CMake version ${CMAKE_VERSION} is too old to support C++23 or C++26. Please upgrade to CMake 3.20 or later.") + endif() else() - message(STATUS "Compiling for C++23") - set_property(TARGET etl_tests PROPERTY CXX_STANDARD 23) + message(STATUS "Compiling for C++17") + set_property(TARGET etl_tests PROPERTY CXX_STANDARD 17) endif() if (ETL_OPTIMISATION MATCHES "-O1") diff --git a/test/etl_error_handler/log_errors/CMakeLists.txt b/test/etl_error_handler/log_errors/CMakeLists.txt index 337e6546..4c96e4de 100644 --- a/test/etl_error_handler/log_errors/CMakeLists.txt +++ b/test/etl_error_handler/log_errors/CMakeLists.txt @@ -18,7 +18,7 @@ if (ETL_CXX_STANDARD MATCHES "98") message(STATUS "Compiling for C++98") set_property(TARGET etl_tests PROPERTY CXX_STANDARD 98) elseif (ETL_CXX_STANDARD MATCHES "03") - message(STATUS "Compiling for C++98") + message(STATUS "Compiling for C++03") set_property(TARGET etl_tests PROPERTY CXX_STANDARD 98) elseif (ETL_CXX_STANDARD MATCHES "11") message(STATUS "Compiling for C++11") @@ -32,9 +32,27 @@ elseif (ETL_CXX_STANDARD MATCHES "17") elseif (ETL_CXX_STANDARD MATCHES "20") message(STATUS "Compiling for C++20") set_property(TARGET etl_tests PROPERTY CXX_STANDARD 20) +elseif (ETL_CXX_STANDARD MATCHES "23") + if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.20") + message(STATUS "Compiling for C++23") + set_property(TARGET etl_tests PROPERTY CXX_STANDARD 23) + else() + message(STATUS "CMake version ${CMAKE_VERSION} does not support C++23, falling back to C++20") + set_property(TARGET etl_tests PROPERTY CXX_STANDARD 20) + endif() +elseif (ETL_CXX_STANDARD MATCHES "26") + if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.25") + message(STATUS "Compiling for C++26") + set_property(TARGET etl_tests PROPERTY CXX_STANDARD 26) + elseif (CMAKE_VERSION VERSION_GREATER_EQUAL "3.20") + message(STATUS "CMake version ${CMAKE_VERSION} does not support C++26, falling back to C++23") + set_property(TARGET etl_tests PROPERTY CXX_STANDARD 23) + else() + message(FATAL_ERROR "CMake version ${CMAKE_VERSION} is too old to support C++23 or C++26. Please upgrade to CMake 3.20 or later.") + endif() else() - message(STATUS "Compiling for C++23") - set_property(TARGET etl_tests PROPERTY CXX_STANDARD 23) + message(STATUS "Compiling for C++17") + set_property(TARGET etl_tests PROPERTY CXX_STANDARD 17) endif() if (ETL_OPTIMISATION MATCHES "-O1") @@ -121,7 +139,3 @@ add_test(etl_error_handler_unit_tests etl_tests) # as they appear from UnitTest++ add_custom_target(test_verbose COMMAND ${CMAKE_CTEST_COMMAND} --verbose) - -#RSG -set_property(TARGET etl_tests PROPERTY CXX_STANDARD 17) - diff --git a/test/etl_error_handler/log_errors/test_error_handler.cpp b/test/etl_error_handler/log_errors/test_error_handler.cpp index 01381e36..61d35125 100644 --- a/test/etl_error_handler/log_errors/test_error_handler.cpp +++ b/test/etl_error_handler/log_errors/test_error_handler.cpp @@ -117,12 +117,12 @@ bool AssertFailAndReturnValue() return false; } +static ErrorLog error_log; + //***************************************************************************** int main() { - static ErrorLog error_log; - - etl::error_handler::set_callback(); + etl::error_handler::set_callback(error_log); Assert(false); Assert(true); diff --git a/test/etl_error_handler/log_errors_and_exceptions/CMakeLists.txt b/test/etl_error_handler/log_errors_and_exceptions/CMakeLists.txt index cad344d4..3a7100df 100644 --- a/test/etl_error_handler/log_errors_and_exceptions/CMakeLists.txt +++ b/test/etl_error_handler/log_errors_and_exceptions/CMakeLists.txt @@ -33,9 +33,27 @@ elseif (ETL_CXX_STANDARD MATCHES "17") elseif (ETL_CXX_STANDARD MATCHES "20") message(STATUS "Compiling for C++20") set_property(TARGET etl_tests PROPERTY CXX_STANDARD 20) +elseif (ETL_CXX_STANDARD MATCHES "23") + if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.20") + message(STATUS "Compiling for C++23") + set_property(TARGET etl_tests PROPERTY CXX_STANDARD 23) + else() + message(STATUS "CMake version ${CMAKE_VERSION} does not support C++23, falling back to C++20") + set_property(TARGET etl_tests PROPERTY CXX_STANDARD 20) + endif() +elseif (ETL_CXX_STANDARD MATCHES "26") + if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.25") + message(STATUS "Compiling for C++26") + set_property(TARGET etl_tests PROPERTY CXX_STANDARD 26) + elseif (CMAKE_VERSION VERSION_GREATER_EQUAL "3.20") + message(STATUS "CMake version ${CMAKE_VERSION} does not support C++26, falling back to C++23") + set_property(TARGET etl_tests PROPERTY CXX_STANDARD 23) + else() + message(FATAL_ERROR "CMake version ${CMAKE_VERSION} is too old to support C++23 or C++26. Please upgrade to CMake 3.20 or later.") + endif() else() - message(STATUS "Compiling for C++23") - set_property(TARGET etl_tests PROPERTY CXX_STANDARD 23) + message(STATUS "Compiling for C++17") + set_property(TARGET etl_tests PROPERTY CXX_STANDARD 17) endif() if (ETL_OPTIMISATION MATCHES "-O1") @@ -120,7 +138,3 @@ add_test(etl_error_handler_unit_tests etl_tests) # as they appear from UnitTest++ add_custom_target(test_verbose COMMAND ${CMAKE_CTEST_COMMAND} --verbose) - -#RSG -set_property(TARGET etl_tests PROPERTY CXX_STANDARD 17) - diff --git a/test/etl_initializer_list/CMakeLists.txt b/test/etl_initializer_list/CMakeLists.txt index f29b5515..90437cdf 100644 --- a/test/etl_initializer_list/CMakeLists.txt +++ b/test/etl_initializer_list/CMakeLists.txt @@ -48,9 +48,27 @@ elseif (ETL_CXX_STANDARD MATCHES "17") elseif (ETL_CXX_STANDARD MATCHES "20") message(STATUS "Compiling for C++20") set_property(TARGET etl_tests PROPERTY CXX_STANDARD 20) +elseif (ETL_CXX_STANDARD MATCHES "23") + if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.20") + message(STATUS "Compiling for C++23") + set_property(TARGET etl_tests PROPERTY CXX_STANDARD 23) + else() + message(STATUS "CMake version ${CMAKE_VERSION} does not support C++23, falling back to C++20") + set_property(TARGET etl_tests PROPERTY CXX_STANDARD 20) + endif() +elseif (ETL_CXX_STANDARD MATCHES "26") + if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.25") + message(STATUS "Compiling for C++26") + set_property(TARGET etl_tests PROPERTY CXX_STANDARD 26) + elseif (CMAKE_VERSION VERSION_GREATER_EQUAL "3.20") + message(STATUS "CMake version ${CMAKE_VERSION} does not support C++26, falling back to C++23") + set_property(TARGET etl_tests PROPERTY CXX_STANDARD 23) + else() + message(FATAL_ERROR "CMake version ${CMAKE_VERSION} is too old to support C++23 or C++26. Please upgrade to CMake 3.20 or later.") + endif() else() - message(STATUS "Compiling for C++23") - set_property(TARGET etl_tests PROPERTY CXX_STANDARD 23) + message(STATUS "Compiling for C++17") + set_property(TARGET etl_tests PROPERTY CXX_STANDARD 17) endif() target_include_directories(etl_tests diff --git a/test/run-coverage.sh b/test/run-coverage.sh index bf074a49..9266cd1b 100755 --- a/test/run-coverage.sh +++ b/test/run-coverage.sh @@ -44,7 +44,7 @@ mkdir -p "$BUILD" cd "$BUILD" || exit 1 touch total.info -for CXXSTD in 11 14 17 20 23; do +for CXXSTD in 11 14 17 20 23 26; do for NOSTL in OFF ON; do rm -rf CMakeFiles cmake -DEXTRA_COMPILE_OPTIONS="--coverage" \ diff --git a/test/run-syntax-checks.sh b/test/run-syntax-checks.sh index 8307a51d..f2cc75e5 100755 --- a/test/run-syntax-checks.sh +++ b/test/run-syntax-checks.sh @@ -47,7 +47,7 @@ PrintHelp() echo "$HelpColour" echo "----------------------------------------------------------------------------------" echo " Syntax : ./runtests.sh " - echo " C++ Standard : a, 03, 11, 14, 17, 20 or 23 (a = All standards) " + echo " C++ Standard : a, 03, 11, 14, 17, 20, 23 or 26 (a = All standards) " echo " Threads : Number of threads to use. Default = 4 " echo " Compiler select : gcc or clang. Default All compilers " echo "----------------------------------------------------------------------------------" @@ -101,6 +101,8 @@ elif [ "$1" = "20" ]; then requested_cxx_standard="20" elif [ "$1" = "23" ]; then requested_cxx_standard="23" +elif [ "$1" = "26" ]; then + requested_cxx_standard="26" elif [ "$1" = "A" ]; then requested_cxx_standard="All" elif [ "$1" = "a" ]; then @@ -288,8 +290,8 @@ PrintHeader rm -rdf bgcc rm -rdf bclang cmake -E make_directory bgcc bclang -CC=clang CXX=clang++ cmake -E chdir bgcc cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=ON -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=$cxx_standard .. -cmake --build bgcc +CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=ON -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=$cxx_standard .. +cmake --build bclang if [ $? -eq 0 ]; then PassedCompilation else @@ -305,8 +307,8 @@ PrintHeader rm -rdf bgcc rm -rdf bclang cmake -E make_directory bgcc bclang -CC=clang CXX=clang++ cmake -E chdir bgcc cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=ON -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=$cxx_standard .. -cmake --build bgcc +CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=ON -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=$cxx_standard .. +cmake --build bclang if [ $? -eq 0 ]; then PassedCompilation else @@ -533,8 +535,8 @@ PrintHeader rm -rdf bgcc rm -rdf bclang cmake -E make_directory bgcc bclang -CC=clang CXX=clang++ cmake -E chdir bgcc cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=ON -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=$cxx_standard .. -cmake --build bgcc +CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=ON -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=$cxx_standard .. +cmake --build bclang if [ $? -eq 0 ]; then PassedCompilation else @@ -550,8 +552,8 @@ PrintHeader rm -rdf bgcc rm -rdf bclang cmake -E make_directory bgcc bclang -CC=clang CXX=clang++ cmake -E chdir bgcc cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=ON -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=$cxx_standard .. -cmake --build bgcc +CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=ON -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=$cxx_standard .. +cmake --build bclang if [ $? -eq 0 ]; then PassedCompilation else @@ -777,8 +779,8 @@ PrintHeader rm -rdf bgcc rm -rdf bclang cmake -E make_directory bgcc bclang -CC=clang CXX=clang++ cmake -E chdir bgcc cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=ON -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=$cxx_standard .. -cmake --build bgcc +CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=ON -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=$cxx_standard .. +cmake --build bclang if [ $? -eq 0 ]; then PassedCompilation else @@ -794,8 +796,8 @@ PrintHeader rm -rdf bgcc rm -rdf bclang cmake -E make_directory bgcc bclang -CC=clang CXX=clang++ cmake -E chdir bgcc cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=ON -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=$cxx_standard .. -cmake --build bgcc +CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=ON -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=$cxx_standard .. +cmake --build bclang if [ $? -eq 0 ]; then PassedCompilation else @@ -1021,8 +1023,8 @@ PrintHeader rm -rdf bgcc rm -rdf bclang cmake -E make_directory bgcc bclang -CC=clang CXX=clang++ cmake -E chdir bgcc cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=ON -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=$cxx_standard .. -cmake --build bgcc +CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=ON -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=$cxx_standard .. +cmake --build bclang if [ $? -eq 0 ]; then PassedCompilation else @@ -1038,8 +1040,8 @@ PrintHeader rm -rdf bgcc rm -rdf bclang cmake -E make_directory bgcc bclang -CC=clang CXX=clang++ cmake -E chdir bgcc cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=ON -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=$cxx_standard .. -cmake --build bgcc +CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=ON -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=$cxx_standard .. +cmake --build bclang if [ $? -eq 0 ]; then PassedCompilation else @@ -1265,8 +1267,8 @@ PrintHeader rm -rdf bgcc rm -rdf bclang cmake -E make_directory bgcc bclang -CC=clang CXX=clang++ cmake -E chdir bgcc cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=ON -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=$cxx_standard .. -cmake --build bgcc +CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=ON -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=$cxx_standard .. +cmake --build bclang if [ $? -eq 0 ]; then PassedCompilation else @@ -1282,8 +1284,8 @@ PrintHeader rm -rdf bgcc rm -rdf bclang cmake -E make_directory bgcc bclang -CC=clang CXX=clang++ cmake -E chdir bgcc cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=ON -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=$cxx_standard .. -cmake --build bgcc +CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=ON -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=$cxx_standard .. +cmake --build bclang if [ $? -eq 0 ]; then PassedCompilation else @@ -1509,8 +1511,8 @@ PrintHeader rm -rdf bgcc rm -rdf bclang cmake -E make_directory bgcc bclang -CC=clang CXX=clang++ cmake -E chdir bgcc cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=ON -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=$cxx_standard .. -cmake --build bgcc +CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=ON -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=$cxx_standard .. +cmake --build bclang if [ $? -eq 0 ]; then PassedCompilation else @@ -1526,7 +1528,30 @@ PrintHeader rm -rdf bgcc rm -rdf bclang cmake -E make_directory bgcc bclang -CC=clang CXX=clang++ cmake -E chdir bgcc cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=ON -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=$cxx_standard .. +CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=ON -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=$cxx_standard .. +cmake --build bclang +if [ $? -eq 0 ]; then + PassedCompilation +else + FailedCompilation + exit $? +fi +fi + +fi + +############################################################################### +if [ "$requested_cxx_standard" = "26" ] || [ "$requested_cxx_standard" = "All" ]; then +SetCxxStandard "26" + +if [ "$compiler_enabled" = "gcc" ] || [ "$compiler_enabled" = "All compilers" ]; then +SetConfigurationName "STL" +compiler=$gcc_compiler +PrintHeader +rm -rdf bgcc +rm -rdf bclang +cmake -E make_directory bgcc bclang +CC=gcc CXX=g++ cmake -E chdir bgcc cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=$cxx_standard .. cmake --build bgcc if [ $? -eq 0 ]; then PassedCompilation @@ -1536,6 +1561,193 @@ else fi fi +if [ "$compiler_enabled" = "gcc" ] || [ "$compiler_enabled" = "All compilers" ]; then +SetConfigurationName "No STL" +compiler=$gcc_compiler +PrintHeader +rm -rdf bgcc +rm -rdf bclang +cmake -E make_directory bgcc bclang +CC=gcc CXX=g++ cmake -E chdir bgcc cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=$cxx_standard .. +cmake --build bgcc +if [ $? -eq 0 ]; then + PassedCompilation +else + FailedCompilation + exit $? +fi +fi + +if [ "$compiler_enabled" = "gcc" ] || [ "$compiler_enabled" = "All compilers" ]; then +SetConfigurationName "STL - Force C++03" +compiler=$gcc_compiler +PrintHeader +rm -rdf bgcc +rm -rdf bclang +cmake -E make_directory bgcc bclang +CC=gcc CXX=g++ cmake -E chdir bgcc cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=$cxx_standard .. +cmake --build bgcc +if [ $? -eq 0 ]; then + PassedCompilation +else + FailedCompilation + exit $? +fi +fi + +if [ "$compiler_enabled" = "gcc" ] || [ "$compiler_enabled" = "All compilers" ]; then +SetConfigurationName "No STL - Force C++03" +compiler=$gcc_compiler +PrintHeader +rm -rdf bgcc +rm -rdf bclang +cmake -E make_directory bgcc bclang +CC=gcc CXX=g++ cmake -E chdir bgcc cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=$cxx_standard .. +cmake --build bgcc +if [ $? -eq 0 ]; then + PassedCompilation +else + FailedCompilation + exit $? +fi +fi + +if [ "$compiler_enabled" = "clang" ] || [ "$compiler_enabled" = "All compilers" ]; then +SetConfigurationName "STL" +compiler=$clang_compiler +PrintHeader +rm -rdf bgcc +rm -rdf bclang +cmake -E make_directory bgcc bclang +CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=$cxx_standard .. +cmake --build bclang +if [ $? -eq 0 ]; then + PassedCompilation +else + FailedCompilation + exit $? +fi +fi + +if [ "$compiler_enabled" = "clang" ] || [ "$compiler_enabled" = "All compilers" ]; then +SetConfigurationName "No STL" +compiler=$clang_compiler +PrintHeader +rm -rdf bgcc +rm -rdf bclang +cmake -E make_directory bgcc bclang +CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=$cxx_standard .. +cmake --build bclang +if [ $? -eq 0 ]; then + PassedCompilation +else + FailedCompilation + exit $? +fi +fi + +if [ "$compiler_enabled" = "clang" ] || [ "$compiler_enabled" = "All compilers" ]; then +SetConfigurationName "STL - Force C++03" +compiler=$clang_compiler +PrintHeader +rm -rdf bgcc +rm -rdf bclang +cmake -E make_directory bgcc bclang +CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=$cxx_standard .. +cmake --build bclang +if [ $? -eq 0 ]; then + PassedCompilation +else + FailedCompilation + exit $? +fi +fi + +if [ "$compiler_enabled" = "clang" ] || [ "$compiler_enabled" = "All compilers" ]; then +SetConfigurationName "No STL - Force C++03" +compiler=$clang_compiler +PrintHeader +rm -rdf bgcc +rm -rdf bclang +cmake -E make_directory bgcc bclang +CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_CXX_STANDARD=$cxx_standard .. +cmake --build bclang +if [ $? -eq 0 ]; then + PassedCompilation +else + FailedCompilation + exit $? +fi +fi + +if [ "$compiler_enabled" = "gcc" ] || [ "$compiler_enabled" = "All compilers" ]; then +SetConfigurationName "STL - Built-in traits" +compiler=$gcc_compiler +PrintHeader +rm -rdf bgcc +rm -rdf bclang +cmake -E make_directory bgcc bclang +CC=gcc CXX=g++ cmake -E chdir bgcc cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=ON -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=$cxx_standard .. +cmake --build bgcc +if [ $? -eq 0 ]; then + PassedCompilation +else + FailedCompilation + exit $? +fi +fi + +if [ "$compiler_enabled" = "gcc" ] || [ "$compiler_enabled" = "All compilers" ]; then +SetConfigurationName "No STL - Built-in traits" +compiler=$gcc_compiler +PrintHeader +rm -rdf bgcc +rm -rdf bclang +cmake -E make_directory bgcc bclang +CC=gcc CXX=g++ cmake -E chdir bgcc cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=ON -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=$cxx_standard .. +cmake --build bgcc +if [ $? -eq 0 ]; then + PassedCompilation +else + FailedCompilation + exit $? +fi +fi + +if [ "$compiler_enabled" = "clang" ] || [ "$compiler_enabled" = "All compilers" ]; then +SetConfigurationName "STL - Built-in traits" +compiler=$clang_compiler +PrintHeader +rm -rdf bgcc +rm -rdf bclang +cmake -E make_directory bgcc bclang +CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=ON -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=$cxx_standard .. +cmake --build bclang +if [ $? -eq 0 ]; then + PassedCompilation +else + FailedCompilation + exit $? +fi +fi + +if [ "$compiler_enabled" = "clang" ] || [ "$compiler_enabled" = "All compilers" ]; then +SetConfigurationName "No STL - Built-in traits" +compiler=$clang_compiler +PrintHeader +rm -rdf bgcc +rm -rdf bclang +cmake -E make_directory bgcc bclang +CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=ON -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_CXX_STANDARD=$cxx_standard .. +cmake --build bclang +if [ $? -eq 0 ]; then + PassedCompilation +else + FailedCompilation + exit $? +fi +fi + fi ChecksCompleted diff --git a/test/run-tests.sh b/test/run-tests.sh index d5fd0567..0381ac75 100755 --- a/test/run-tests.sh +++ b/test/run-tests.sh @@ -56,7 +56,7 @@ PrintHelp() echo "$HelpColour" echo "----------------------------------------------------------------------------------------------------------" echo " Syntax : ./run-tests.sh " - echo " C++ Standard : 11, 14, 17, 20, 23 or all " + echo " C++ Standard : 11, 14, 17, 20, 23, 26 or all " echo " Optimisation : 0, 1, 2 or 3. Default = 0 " echo " Threads : Number of threads to use. Default = 4 " echo " Sanitizer : s enables sanitizer checks, n disables. Default disabled " @@ -126,8 +126,10 @@ elif [ "$1" = "20" ]; then cxx_standards="20" elif [ "$1" = "23" ]; then cxx_standards="23" +elif [ "$1" = "26" ]; then + cxx_standards="26" elif [ "$1" = "all" ]; then - cxx_standards="11 14 17 20 23" + cxx_standards="11 14 17 20 23 26" else PrintHelp exit diff --git a/test/syntax_check/CMakeLists.txt b/test/syntax_check/CMakeLists.txt index a9d14be6..a7e87697 100644 --- a/test/syntax_check/CMakeLists.txt +++ b/test/syntax_check/CMakeLists.txt @@ -74,9 +74,25 @@ elseif (ETL_CXX_STANDARD MATCHES "17") elseif (ETL_CXX_STANDARD MATCHES "20") message(STATUS "Compiling for C++20") set_property(TARGET tests PROPERTY CXX_STANDARD 20) +elseif (ETL_CXX_STANDARD MATCHES "23") + if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.20") + message(STATUS "Compiling for C++23") + set_property(TARGET tests PROPERTY CXX_STANDARD 23) + else() + message(STATUS "CMake version ${CMAKE_VERSION} does not support C++23, falling back to C++20") + set_property(TARGET tests PROPERTY CXX_STANDARD 20) + endif() +elseif (ETL_CXX_STANDARD MATCHES "26") + if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.25") + message(STATUS "Compiling for C++26") + set_property(TARGET tests PROPERTY CXX_STANDARD 26) + else() + message(STATUS "CMake version ${CMAKE_VERSION} does not support C++26, falling back to C++23") + set_property(TARGET tests PROPERTY CXX_STANDARD 23) + endif() else() - message(STATUS "Compiling for C++23") - set_property(TARGET tests PROPERTY CXX_STANDARD 23) + message(STATUS "Compiling for C++17") + set_property(TARGET tests PROPERTY CXX_STANDARD 17) endif() target_sources(tests PRIVATE diff --git a/test/test_atomic.cpp b/test/test_atomic.cpp index 2128332b..9870caf8 100644 --- a/test/test_atomic.cpp +++ b/test/test_atomic.cpp @@ -488,6 +488,72 @@ namespace CHECK_EQUAL(compare.fetch_xor(0x55AA55AAUL), test.fetch_xor(0x55AA55AAUL)); } + //************************************************************************* + TEST(test_atomic_operator_fetch_max_when_new_value_is_greater) + { + etl::atomic test(10); + + int old_value = test.fetch_max(20); + + CHECK_EQUAL(10, old_value); + CHECK_EQUAL(20, test.load()); + } + + //************************************************************************* + TEST(test_atomic_operator_fetch_max_when_new_value_is_less) + { + etl::atomic test(30); + + int old_value = test.fetch_max(20); + + CHECK_EQUAL(30, old_value); + CHECK_EQUAL(30, test.load()); + } + + //************************************************************************* + TEST(test_atomic_operator_fetch_max_when_new_value_is_equal) + { + etl::atomic test(20); + + int old_value = test.fetch_max(20); + + CHECK_EQUAL(20, old_value); + CHECK_EQUAL(20, test.load()); + } + + //************************************************************************* + TEST(test_atomic_operator_fetch_min_when_new_value_is_less) + { + etl::atomic test(30); + + int old_value = test.fetch_min(20); + + CHECK_EQUAL(30, old_value); + CHECK_EQUAL(20, test.load()); + } + + //************************************************************************* + TEST(test_atomic_operator_fetch_min_when_new_value_is_greater) + { + etl::atomic test(10); + + int old_value = test.fetch_min(20); + + CHECK_EQUAL(10, old_value); + CHECK_EQUAL(10, test.load()); + } + + //************************************************************************* + TEST(test_atomic_operator_fetch_min_when_new_value_is_equal) + { + etl::atomic test(20); + + int old_value = test.fetch_min(20); + + CHECK_EQUAL(20, old_value); + CHECK_EQUAL(20, test.load()); + } + //************************************************************************* TEST(test_atomic_integer_exchange) { diff --git a/test/test_etl_traits.cpp b/test/test_etl_traits.cpp index 3ddb93fa..a90f073c 100644 --- a/test/test_etl_traits.cpp +++ b/test/test_etl_traits.cpp @@ -49,6 +49,7 @@ namespace CHECK_EQUAL((ETL_USING_CPP17 == 1), etl::traits::using_cpp17); CHECK_EQUAL((ETL_USING_CPP20 == 1), etl::traits::using_cpp20); CHECK_EQUAL((ETL_USING_CPP23 == 1), etl::traits::using_cpp23); + CHECK_EQUAL((ETL_USING_CPP26 == 1), etl::traits::using_cpp26); CHECK_EQUAL((ETL_USING_EXCEPTIONS == 1), etl::traits::using_exceptions); CHECK_EQUAL((ETL_USING_LIBC_WCHAR_H == 1), etl::traits::using_libc_wchar_h); CHECK_EQUAL((ETL_USING_GCC_COMPILER == 1), etl::traits::using_gcc_compiler); @@ -92,7 +93,9 @@ namespace CHECK_EQUAL(ETL_VERSION_MINOR, etl::traits::version_minor); CHECK_EQUAL(ETL_VERSION_PATCH, etl::traits::version_patch); CHECK_EQUAL(ETL_VERSION_VALUE, etl::traits::version); -#if ETL_USING_CPP23 +#if ETL_USING_CPP26 + CHECK_EQUAL(26, etl::traits::language_standard); +#elif ETL_USING_CPP23 CHECK_EQUAL(23, etl::traits::language_standard); #elif ETL_USING_CPP20 CHECK_EQUAL(20, etl::traits::language_standard); diff --git a/test/test_memory.cpp b/test/test_memory.cpp index 9513e778..eeddc426 100644 --- a/test/test_memory.cpp +++ b/test/test_memory.cpp @@ -47,6 +47,64 @@ SOFTWARE. #include #include +//*************************************************************************** +/// A non-trivially-relocatable type that tracks moves and destructions. +/// Used to exercise the manual move-and-destroy path of etl::relocate. +//*************************************************************************** +struct relocatable_t +{ + int value; + bool was_moved_into; ///< true when this object was constructed via move + + static int destructor_count; + + static void reset_counts() + { + destructor_count = 0; + } + + explicit relocatable_t(int v = 0) + : value(v) + , was_moved_into(false) + { + } + + relocatable_t(relocatable_t&& other) ETL_NOEXCEPT + : value(other.value) + , was_moved_into(true) + { + other.value = -1; // mark source as moved-from + } + + ~relocatable_t() + { + ++destructor_count; + } + + // Non-copyable to make the intent clear. + relocatable_t(const relocatable_t&) = delete; + relocatable_t& operator=(const relocatable_t&) = delete; + relocatable_t& operator=(relocatable_t&&) = delete; +}; + +int relocatable_t::destructor_count = 0; + +// In configurations where etl::is_nothrow_relocatable is a class template +// (non-STL builds), we must provide an explicit specialisation so that +// etl::relocate is enabled for relocatable_t. When the STL is available the +// trait is a type alias that already evaluates to true for types with a +// nothrow move constructor and a nothrow destructor, so no specialisation is +// needed (or even possible). +#if !(ETL_USING_STL && ETL_USING_CPP11) +namespace etl +{ + template <> + struct is_nothrow_relocatable : public etl::true_type + { + }; +} // namespace etl +#endif + namespace { typedef std::string non_trivial_t; @@ -2660,5 +2718,267 @@ namespace CHECK(result == p); } #endif + +#if ETL_USING_CPP11 + //************************************************************************* + TEST(test_trivially_relocate_trivial) + { + alignas(trivial_t) unsigned char src_buffer[sizeof(trivial_t) * SIZE]; + alignas(trivial_t) unsigned char dst_buffer[sizeof(trivial_t) * SIZE]; + + trivial_t* src = reinterpret_cast(src_buffer); + trivial_t* dst = reinterpret_cast(dst_buffer); + + // Initialize source + for (size_t i = 0; i < SIZE; ++i) + { + src[i] = test_data_trivial[i]; + } + + // Relocate + trivial_t* result = etl::trivially_relocate(src, src + SIZE, dst); + + // Check result + CHECK(result == dst + SIZE); + + // Check destination values + for (size_t i = 0; i < SIZE; ++i) + { + CHECK_EQUAL(test_data_trivial[i], dst[i]); + } + } + + //************************************************************************* + TEST(test_trivially_relocate_same_location) + { + alignas(trivial_t) unsigned char buffer[sizeof(trivial_t) * SIZE]; + trivial_t* p = reinterpret_cast(buffer); + + // Initialize + for (size_t i = 0; i < SIZE; ++i) + { + p[i] = test_data_trivial[i]; + } + + // Relocate to same location should return last + trivial_t* result = etl::trivially_relocate(p, p + SIZE, p); + + CHECK(result == p + SIZE); + + // Values should be unchanged + for (size_t i = 0; i < SIZE; ++i) + { + CHECK_EQUAL(test_data_trivial[i], p[i]); + } + } + + //************************************************************************* + TEST(test_trivially_relocate_empty_range) + { + alignas(trivial_t) unsigned char src_buffer[sizeof(trivial_t) * SIZE]; + alignas(trivial_t) unsigned char dst_buffer[sizeof(trivial_t) * SIZE]; + + trivial_t* src = reinterpret_cast(src_buffer); + trivial_t* dst = reinterpret_cast(dst_buffer); + + // Relocate empty range + trivial_t* result = etl::trivially_relocate(src, src, dst); + + CHECK(result == dst); + } + + //************************************************************************* + TEST(test_trivially_relocate_overlapping_forward) + { + alignas(trivial_t) unsigned char buffer[sizeof(trivial_t) * (SIZE + 2)]; + trivial_t* p = reinterpret_cast(buffer); + + // Initialize + for (size_t i = 0; i < SIZE; ++i) + { + p[i] = test_data_trivial[i]; + } + + // Relocate forward (overlapping) - shift elements by 2 + trivial_t* result = etl::trivially_relocate(p, p + SIZE, p + 2); + + CHECK(result == p + SIZE + 2); + + // Check values + for (size_t i = 0; i < SIZE; ++i) + { + CHECK_EQUAL(test_data_trivial[i], p[i + 2]); + } + } + + //************************************************************************* + TEST(test_relocate_trivial) + { + alignas(trivial_t) unsigned char src_buffer[sizeof(trivial_t) * SIZE]; + alignas(trivial_t) unsigned char dst_buffer[sizeof(trivial_t) * SIZE]; + + trivial_t* src = reinterpret_cast(src_buffer); + trivial_t* dst = reinterpret_cast(dst_buffer); + + // Initialize source + for (size_t i = 0; i < SIZE; ++i) + { + src[i] = test_data_trivial[i]; + } + + // Relocate + trivial_t* result = etl::relocate(src, src + SIZE, dst); + + // Check result + CHECK(result == dst + SIZE); + + // Check destination values + for (size_t i = 0; i < SIZE; ++i) + { + CHECK_EQUAL(test_data_trivial[i], dst[i]); + } + } + + //************************************************************************* + TEST(test_relocate_same_location) + { + alignas(trivial_t) unsigned char buffer[sizeof(trivial_t) * SIZE]; + trivial_t* p = reinterpret_cast(buffer); + + // Initialize + for (size_t i = 0; i < SIZE; ++i) + { + p[i] = test_data_trivial[i]; + } + + // Relocate to same location should return last + trivial_t* result = etl::relocate(p, p + SIZE, p); + + CHECK(result == p + SIZE); + + // Values should be unchanged + for (size_t i = 0; i < SIZE; ++i) + { + CHECK_EQUAL(test_data_trivial[i], p[i]); + } + } + + //************************************************************************* + TEST(test_relocate_empty_range) + { + alignas(trivial_t) unsigned char src_buffer[sizeof(trivial_t) * SIZE]; + alignas(trivial_t) unsigned char dst_buffer[sizeof(trivial_t) * SIZE]; + + trivial_t* src = reinterpret_cast(src_buffer); + trivial_t* dst = reinterpret_cast(dst_buffer); + + // Relocate empty range + trivial_t* result = etl::relocate(src, src, dst); + + CHECK(result == dst); + } + + //************************************************************************* + TEST(test_relocate_non_trivial) + { + const size_t N = 5; + + alignas(relocatable_t) unsigned char src_buffer[sizeof(relocatable_t) * N]; + alignas(relocatable_t) unsigned char dst_buffer[sizeof(relocatable_t) * N]; + + relocatable_t* src = reinterpret_cast(src_buffer); + relocatable_t* dst = reinterpret_cast(dst_buffer); + + // Placement-new source objects + for (size_t i = 0; i < N; ++i) + { + ::new (static_cast(src + i)) relocatable_t(static_cast(i + 1)); + } + + relocatable_t::reset_counts(); + + // Relocate (non-trivial path: move-construct into dst, destroy src) + relocatable_t* result = etl::relocate(src, src + N, dst); + + // Returned pointer must be one-past-end of destination + CHECK(result == dst + N); + + // Destination objects were move-constructed with correct values + for (size_t i = 0; i < N; ++i) + { + CHECK_EQUAL(static_cast(i + 1), dst[i].value); + CHECK(dst[i].was_moved_into); + } + + // Destructors were called for the N source objects + CHECK_EQUAL(static_cast(N), relocatable_t::destructor_count); + + // Clean up destination objects + relocatable_t::reset_counts(); + for (size_t i = 0; i < N; ++i) + { + dst[i].~relocatable_t(); + } + } + + //************************************************************************* + TEST(test_relocate_non_trivial_same_location) + { + const size_t N = 5; + + alignas(relocatable_t) unsigned char buffer[sizeof(relocatable_t) * N]; + relocatable_t* p = reinterpret_cast(buffer); + + // Placement-new objects + for (size_t i = 0; i < N; ++i) + { + ::new (static_cast(p + i)) relocatable_t(static_cast(i + 1)); + } + + relocatable_t::reset_counts(); + + // Relocating to the same location should be a no-op (early return) + relocatable_t* result = etl::relocate(p, p + N, p); + + CHECK(result == p + N); + + // No destructors should have been called (no move-and-destroy performed) + CHECK_EQUAL(0, relocatable_t::destructor_count); + + // Values should be unchanged + for (size_t i = 0; i < N; ++i) + { + CHECK_EQUAL(static_cast(i + 1), p[i].value); + CHECK(!p[i].was_moved_into); + } + + // Clean up + relocatable_t::reset_counts(); + for (size_t i = 0; i < N; ++i) + { + p[i].~relocatable_t(); + } + } + + //************************************************************************* + TEST(test_relocate_non_trivial_empty_range) + { + alignas(relocatable_t) unsigned char src_buffer[sizeof(relocatable_t)]; + alignas(relocatable_t) unsigned char dst_buffer[sizeof(relocatable_t)]; + + relocatable_t* src = reinterpret_cast(src_buffer); + relocatable_t* dst = reinterpret_cast(dst_buffer); + + relocatable_t::reset_counts(); + + // Empty range: first == last + relocatable_t* result = etl::relocate(src, src, dst); + + CHECK(result == dst); + + // No destructors should have been called + CHECK_EQUAL(0, relocatable_t::destructor_count); + } +#endif } } // namespace diff --git a/test/test_numeric.cpp b/test/test_numeric.cpp index 1f6980bc..f7407fef 100644 --- a/test/test_numeric.cpp +++ b/test/test_numeric.cpp @@ -206,5 +206,411 @@ namespace CHECK_CLOSE(10.0, etl::lerp(10.0, 10.0, 1), 0.001); CHECK_CLOSE(10.0, etl::lerp(10, 10, 1), 0.001); } + + //************************************************************************* + TEST(test_add_sat_unsigned) + { + // Normal addition (no overflow) + CHECK_EQUAL(uint8_t(0), etl::add_sat(uint8_t(0), uint8_t(0))); + CHECK_EQUAL(uint8_t(3), etl::add_sat(uint8_t(1), uint8_t(2))); + CHECK_EQUAL(uint8_t(254), etl::add_sat(uint8_t(127), uint8_t(127))); + CHECK_EQUAL(uint8_t(255), etl::add_sat(uint8_t(200), uint8_t(55))); + + // Overflow saturates to max + CHECK_EQUAL(uint8_t(255), etl::add_sat(uint8_t(255), uint8_t(1))); + CHECK_EQUAL(uint8_t(255), etl::add_sat(uint8_t(1), uint8_t(255))); + CHECK_EQUAL(uint8_t(255), etl::add_sat(uint8_t(255), uint8_t(255))); + CHECK_EQUAL(uint8_t(255), etl::add_sat(uint8_t(200), uint8_t(200))); + CHECK_EQUAL(uint8_t(255), etl::add_sat(uint8_t(128), uint8_t(128))); + + // Identity: adding zero + CHECK_EQUAL(uint8_t(42), etl::add_sat(uint8_t(42), uint8_t(0))); + CHECK_EQUAL(uint8_t(0), etl::add_sat(uint8_t(0), uint8_t(0))); + CHECK_EQUAL(uint8_t(255), etl::add_sat(uint8_t(255), uint8_t(0))); + + // uint16_t + CHECK_EQUAL(uint16_t(65535), etl::add_sat(uint16_t(65535), uint16_t(1))); + CHECK_EQUAL(uint16_t(65535), etl::add_sat(uint16_t(65535), uint16_t(65535))); + CHECK_EQUAL(uint16_t(1000), etl::add_sat(uint16_t(500), uint16_t(500))); + + // uint32_t + CHECK_EQUAL(std::numeric_limits::max(), etl::add_sat(std::numeric_limits::max(), uint32_t(1))); + CHECK_EQUAL(std::numeric_limits::max(), etl::add_sat(std::numeric_limits::max(), std::numeric_limits::max())); + CHECK_EQUAL(uint32_t(100), etl::add_sat(uint32_t(60), uint32_t(40))); + } + + //************************************************************************* + TEST(test_add_sat_signed) + { + // Normal addition (no overflow) + CHECK_EQUAL(int8_t(0), etl::add_sat(int8_t(0), int8_t(0))); + CHECK_EQUAL(int8_t(3), etl::add_sat(int8_t(1), int8_t(2))); + CHECK_EQUAL(int8_t(-3), etl::add_sat(int8_t(-1), int8_t(-2))); + CHECK_EQUAL(int8_t(0), etl::add_sat(int8_t(1), int8_t(-1))); + CHECK_EQUAL(int8_t(0), etl::add_sat(int8_t(-1), int8_t(1))); + CHECK_EQUAL(int8_t(126), etl::add_sat(int8_t(63), int8_t(63))); + + // Positive overflow saturates to max + CHECK_EQUAL(int8_t(127), etl::add_sat(int8_t(127), int8_t(1))); + CHECK_EQUAL(int8_t(127), etl::add_sat(int8_t(1), int8_t(127))); + CHECK_EQUAL(int8_t(127), etl::add_sat(int8_t(127), int8_t(127))); + CHECK_EQUAL(int8_t(127), etl::add_sat(int8_t(100), int8_t(100))); + + // Negative overflow saturates to min + CHECK_EQUAL(int8_t(-128), etl::add_sat(int8_t(-128), int8_t(-1))); + CHECK_EQUAL(int8_t(-128), etl::add_sat(int8_t(-1), int8_t(-128))); + CHECK_EQUAL(int8_t(-128), etl::add_sat(int8_t(-128), int8_t(-128))); + CHECK_EQUAL(int8_t(-128), etl::add_sat(int8_t(-100), int8_t(-100))); + + // Mixed signs: no overflow possible + CHECK_EQUAL(int8_t(-1), etl::add_sat(int8_t(127), int8_t(-128))); + CHECK_EQUAL(int8_t(-1), etl::add_sat(int8_t(-128), int8_t(127))); + CHECK_EQUAL(int8_t(27), etl::add_sat(int8_t(127), int8_t(-100))); + CHECK_EQUAL(int8_t(-28), etl::add_sat(int8_t(-128), int8_t(100))); + + // Identity: adding zero + CHECK_EQUAL(int8_t(42), etl::add_sat(int8_t(42), int8_t(0))); + CHECK_EQUAL(int8_t(-42), etl::add_sat(int8_t(-42), int8_t(0))); + CHECK_EQUAL(int8_t(127), etl::add_sat(int8_t(127), int8_t(0))); + CHECK_EQUAL(int8_t(-128), etl::add_sat(int8_t(-128), int8_t(0))); + + // int16_t + CHECK_EQUAL(int16_t(32767), etl::add_sat(int16_t(32767), int16_t(1))); + CHECK_EQUAL(int16_t(-32768), etl::add_sat(int16_t(-32768), int16_t(-1))); + CHECK_EQUAL(int16_t(32767), etl::add_sat(int16_t(32767), int16_t(32767))); + CHECK_EQUAL(int16_t(-32768), etl::add_sat(int16_t(-32768), int16_t(-32768))); + CHECK_EQUAL(int16_t(1000), etl::add_sat(int16_t(500), int16_t(500))); + + // int32_t + CHECK_EQUAL(std::numeric_limits::max(), etl::add_sat(std::numeric_limits::max(), int32_t(1))); + CHECK_EQUAL(std::numeric_limits::min(), etl::add_sat(std::numeric_limits::min(), int32_t(-1))); + CHECK_EQUAL(std::numeric_limits::max(), etl::add_sat(std::numeric_limits::max(), std::numeric_limits::max())); + CHECK_EQUAL(std::numeric_limits::min(), etl::add_sat(std::numeric_limits::min(), std::numeric_limits::min())); + CHECK_EQUAL(int32_t(100), etl::add_sat(int32_t(60), int32_t(40))); + } + + //************************************************************************* + TEST(test_sub_sat_unsigned) + { + // Normal subtraction (no underflow) + CHECK_EQUAL(uint8_t(0), etl::sub_sat(uint8_t(0), uint8_t(0))); + CHECK_EQUAL(uint8_t(1), etl::sub_sat(uint8_t(3), uint8_t(2))); + CHECK_EQUAL(uint8_t(0), etl::sub_sat(uint8_t(2), uint8_t(2))); + CHECK_EQUAL(uint8_t(255), etl::sub_sat(uint8_t(255), uint8_t(0))); + CHECK_EQUAL(uint8_t(128), etl::sub_sat(uint8_t(255), uint8_t(127))); + + // Underflow saturates to 0 + CHECK_EQUAL(uint8_t(0), etl::sub_sat(uint8_t(0), uint8_t(1))); + CHECK_EQUAL(uint8_t(0), etl::sub_sat(uint8_t(0), uint8_t(255))); + CHECK_EQUAL(uint8_t(0), etl::sub_sat(uint8_t(1), uint8_t(2))); + CHECK_EQUAL(uint8_t(0), etl::sub_sat(uint8_t(100), uint8_t(200))); + CHECK_EQUAL(uint8_t(0), etl::sub_sat(uint8_t(127), uint8_t(255))); + + // Identity: subtracting zero + CHECK_EQUAL(uint8_t(42), etl::sub_sat(uint8_t(42), uint8_t(0))); + CHECK_EQUAL(uint8_t(0), etl::sub_sat(uint8_t(0), uint8_t(0))); + CHECK_EQUAL(uint8_t(255), etl::sub_sat(uint8_t(255), uint8_t(0))); + + // uint16_t + CHECK_EQUAL(uint16_t(0), etl::sub_sat(uint16_t(0), uint16_t(1))); + CHECK_EQUAL(uint16_t(0), etl::sub_sat(uint16_t(0), uint16_t(65535))); + CHECK_EQUAL(uint16_t(100), etl::sub_sat(uint16_t(500), uint16_t(400))); + + // uint32_t + CHECK_EQUAL(uint32_t(0), etl::sub_sat(uint32_t(0), uint32_t(1))); + CHECK_EQUAL(uint32_t(0), etl::sub_sat(uint32_t(0), std::numeric_limits::max())); + CHECK_EQUAL(uint32_t(1), etl::sub_sat(std::numeric_limits::max(), std::numeric_limits::max() - 1)); + CHECK_EQUAL(uint32_t(20), etl::sub_sat(uint32_t(60), uint32_t(40))); + } + + //************************************************************************* + TEST(test_sub_sat_signed) + { + // Normal subtraction (no overflow) + CHECK_EQUAL(int8_t(0), etl::sub_sat(int8_t(0), int8_t(0))); + CHECK_EQUAL(int8_t(1), etl::sub_sat(int8_t(3), int8_t(2))); + CHECK_EQUAL(int8_t(-1), etl::sub_sat(int8_t(2), int8_t(3))); + CHECK_EQUAL(int8_t(0), etl::sub_sat(int8_t(1), int8_t(1))); + CHECK_EQUAL(int8_t(-2), etl::sub_sat(int8_t(-1), int8_t(1))); + CHECK_EQUAL(int8_t(2), etl::sub_sat(int8_t(1), int8_t(-1))); + + // Positive overflow: subtracting large negative from positive saturates to max + CHECK_EQUAL(int8_t(127), etl::sub_sat(int8_t(127), int8_t(-1))); + CHECK_EQUAL(int8_t(127), etl::sub_sat(int8_t(1), int8_t(-127))); + CHECK_EQUAL(int8_t(127), etl::sub_sat(int8_t(127), int8_t(-128))); + CHECK_EQUAL(int8_t(127), etl::sub_sat(int8_t(100), int8_t(-100))); + + // Negative overflow: subtracting large positive from negative saturates to min + CHECK_EQUAL(int8_t(-128), etl::sub_sat(int8_t(-128), int8_t(1))); + CHECK_EQUAL(int8_t(-128), etl::sub_sat(int8_t(-1), int8_t(127))); + CHECK_EQUAL(int8_t(-128), etl::sub_sat(int8_t(-128), int8_t(127))); + CHECK_EQUAL(int8_t(-128), etl::sub_sat(int8_t(-100), int8_t(100))); + + // No overflow when same sign + CHECK_EQUAL(int8_t(0), etl::sub_sat(int8_t(-128), int8_t(-128))); + CHECK_EQUAL(int8_t(-1), etl::sub_sat(int8_t(-128), int8_t(-127))); + + // Identity: subtracting zero + CHECK_EQUAL(int8_t(42), etl::sub_sat(int8_t(42), int8_t(0))); + CHECK_EQUAL(int8_t(-42), etl::sub_sat(int8_t(-42), int8_t(0))); + CHECK_EQUAL(int8_t(127), etl::sub_sat(int8_t(127), int8_t(0))); + CHECK_EQUAL(int8_t(-128), etl::sub_sat(int8_t(-128), int8_t(0))); + + // int16_t + CHECK_EQUAL(int16_t(32767), etl::sub_sat(int16_t(32767), int16_t(-1))); + CHECK_EQUAL(int16_t(-32768), etl::sub_sat(int16_t(-32768), int16_t(1))); + CHECK_EQUAL(int16_t(32767), etl::sub_sat(int16_t(32767), int16_t(-32768))); + CHECK_EQUAL(int16_t(-32768), etl::sub_sat(int16_t(-32768), int16_t(32767))); + CHECK_EQUAL(int16_t(100), etl::sub_sat(int16_t(500), int16_t(400))); + + // int32_t + CHECK_EQUAL(std::numeric_limits::max(), etl::sub_sat(std::numeric_limits::max(), int32_t(-1))); + CHECK_EQUAL(std::numeric_limits::min(), etl::sub_sat(std::numeric_limits::min(), int32_t(1))); + CHECK_EQUAL(std::numeric_limits::max(), etl::sub_sat(std::numeric_limits::max(), std::numeric_limits::min())); + CHECK_EQUAL(std::numeric_limits::min(), etl::sub_sat(std::numeric_limits::min(), std::numeric_limits::max())); + CHECK_EQUAL(int32_t(20), etl::sub_sat(int32_t(60), int32_t(40))); + } + + //************************************************************************* + TEST(test_mul_sat_unsigned) + { + // Normal multiplication (no overflow) + CHECK_EQUAL(uint8_t(0), etl::mul_sat(uint8_t(0), uint8_t(0))); + CHECK_EQUAL(uint8_t(0), etl::mul_sat(uint8_t(0), uint8_t(255))); + CHECK_EQUAL(uint8_t(0), etl::mul_sat(uint8_t(255), uint8_t(0))); + CHECK_EQUAL(uint8_t(6), etl::mul_sat(uint8_t(2), uint8_t(3))); + CHECK_EQUAL(uint8_t(1), etl::mul_sat(uint8_t(1), uint8_t(1))); + CHECK_EQUAL(uint8_t(255), etl::mul_sat(uint8_t(255), uint8_t(1))); + CHECK_EQUAL(uint8_t(250), etl::mul_sat(uint8_t(25), uint8_t(10))); + + // Overflow saturates to max + CHECK_EQUAL(uint8_t(255), etl::mul_sat(uint8_t(255), uint8_t(2))); + CHECK_EQUAL(uint8_t(255), etl::mul_sat(uint8_t(2), uint8_t(255))); + CHECK_EQUAL(uint8_t(255), etl::mul_sat(uint8_t(255), uint8_t(255))); + CHECK_EQUAL(uint8_t(255), etl::mul_sat(uint8_t(128), uint8_t(3))); + CHECK_EQUAL(uint8_t(255), etl::mul_sat(uint8_t(16), uint8_t(16))); + + // uint16_t + CHECK_EQUAL(uint16_t(65535), etl::mul_sat(uint16_t(65535), uint16_t(2))); + CHECK_EQUAL(uint16_t(65535), etl::mul_sat(uint16_t(65535), uint16_t(65535))); + CHECK_EQUAL(uint16_t(10000), etl::mul_sat(uint16_t(100), uint16_t(100))); + + // uint32_t + CHECK_EQUAL(std::numeric_limits::max(), etl::mul_sat(std::numeric_limits::max(), uint32_t(2))); + CHECK_EQUAL(std::numeric_limits::max(), etl::mul_sat(std::numeric_limits::max(), std::numeric_limits::max())); + CHECK_EQUAL(uint32_t(600), etl::mul_sat(uint32_t(20), uint32_t(30))); + } + + //************************************************************************* + TEST(test_mul_sat_signed) + { + // Normal multiplication (no overflow) + CHECK_EQUAL(int8_t(0), etl::mul_sat(int8_t(0), int8_t(0))); + CHECK_EQUAL(int8_t(0), etl::mul_sat(int8_t(0), int8_t(127))); + CHECK_EQUAL(int8_t(0), etl::mul_sat(int8_t(0), int8_t(-128))); + CHECK_EQUAL(int8_t(6), etl::mul_sat(int8_t(2), int8_t(3))); + CHECK_EQUAL(int8_t(-6), etl::mul_sat(int8_t(2), int8_t(-3))); + CHECK_EQUAL(int8_t(-6), etl::mul_sat(int8_t(-2), int8_t(3))); + CHECK_EQUAL(int8_t(6), etl::mul_sat(int8_t(-2), int8_t(-3))); + CHECK_EQUAL(int8_t(1), etl::mul_sat(int8_t(1), int8_t(1))); + CHECK_EQUAL(int8_t(-1), etl::mul_sat(int8_t(1), int8_t(-1))); + CHECK_EQUAL(int8_t(1), etl::mul_sat(int8_t(-1), int8_t(-1))); + CHECK_EQUAL(int8_t(100), etl::mul_sat(int8_t(10), int8_t(10))); + + // Positive overflow: both positive + CHECK_EQUAL(int8_t(127), etl::mul_sat(int8_t(127), int8_t(2))); + CHECK_EQUAL(int8_t(127), etl::mul_sat(int8_t(2), int8_t(127))); + CHECK_EQUAL(int8_t(127), etl::mul_sat(int8_t(127), int8_t(127))); + CHECK_EQUAL(int8_t(127), etl::mul_sat(int8_t(64), int8_t(3))); + + // Positive overflow: both negative + CHECK_EQUAL(int8_t(127), etl::mul_sat(int8_t(-128), int8_t(-2))); + CHECK_EQUAL(int8_t(127), etl::mul_sat(int8_t(-2), int8_t(-128))); + CHECK_EQUAL(int8_t(127), etl::mul_sat(int8_t(-128), int8_t(-128))); + + // Negative overflow: positive * negative + CHECK_EQUAL(int8_t(-128), etl::mul_sat(int8_t(127), int8_t(-2))); + CHECK_EQUAL(int8_t(-128), etl::mul_sat(int8_t(2), int8_t(-127))); + CHECK_EQUAL(int8_t(-128), etl::mul_sat(int8_t(127), int8_t(-128))); + + // Negative overflow: negative * positive + CHECK_EQUAL(int8_t(-128), etl::mul_sat(int8_t(-128), int8_t(2))); + CHECK_EQUAL(int8_t(-128), etl::mul_sat(int8_t(-2), int8_t(127))); + CHECK_EQUAL(int8_t(-128), etl::mul_sat(int8_t(-128), int8_t(127))); + + // int16_t + CHECK_EQUAL(int16_t(32767), etl::mul_sat(int16_t(32767), int16_t(2))); + CHECK_EQUAL(int16_t(-32768), etl::mul_sat(int16_t(32767), int16_t(-2))); + CHECK_EQUAL(int16_t(32767), etl::mul_sat(int16_t(-32768), int16_t(-2))); + CHECK_EQUAL(int16_t(-32768), etl::mul_sat(int16_t(-32768), int16_t(2))); + CHECK_EQUAL(int16_t(10000), etl::mul_sat(int16_t(100), int16_t(100))); + + // int32_t + CHECK_EQUAL(std::numeric_limits::max(), etl::mul_sat(std::numeric_limits::max(), int32_t(2))); + CHECK_EQUAL(std::numeric_limits::min(), etl::mul_sat(std::numeric_limits::max(), int32_t(-2))); + CHECK_EQUAL(std::numeric_limits::max(), etl::mul_sat(std::numeric_limits::min(), int32_t(-2))); + CHECK_EQUAL(std::numeric_limits::min(), etl::mul_sat(std::numeric_limits::min(), int32_t(2))); + CHECK_EQUAL(int32_t(600), etl::mul_sat(int32_t(20), int32_t(30))); + } + + //************************************************************************* + TEST(test_div_sat_unsigned) + { + // Normal division + CHECK_EQUAL(uint8_t(0), etl::div_sat(uint8_t(0), uint8_t(1))); + CHECK_EQUAL(uint8_t(0), etl::div_sat(uint8_t(0), uint8_t(255))); + CHECK_EQUAL(uint8_t(1), etl::div_sat(uint8_t(1), uint8_t(1))); + CHECK_EQUAL(uint8_t(3), etl::div_sat(uint8_t(6), uint8_t(2))); + CHECK_EQUAL(uint8_t(127), etl::div_sat(uint8_t(255), uint8_t(2))); + CHECK_EQUAL(uint8_t(255), etl::div_sat(uint8_t(255), uint8_t(1))); + CHECK_EQUAL(uint8_t(0), etl::div_sat(uint8_t(1), uint8_t(2))); + + // uint16_t + CHECK_EQUAL(uint16_t(32767), etl::div_sat(uint16_t(65535), uint16_t(2))); + CHECK_EQUAL(uint16_t(65535), etl::div_sat(uint16_t(65535), uint16_t(1))); + CHECK_EQUAL(uint16_t(100), etl::div_sat(uint16_t(1000), uint16_t(10))); + + // uint32_t + CHECK_EQUAL(std::numeric_limits::max(), etl::div_sat(std::numeric_limits::max(), uint32_t(1))); + CHECK_EQUAL(uint32_t(1), etl::div_sat(std::numeric_limits::max(), std::numeric_limits::max())); + CHECK_EQUAL(uint32_t(30), etl::div_sat(uint32_t(600), uint32_t(20))); + } + + //************************************************************************* + TEST(test_div_sat_signed) + { + // Normal division + CHECK_EQUAL(int8_t(0), etl::div_sat(int8_t(0), int8_t(1))); + CHECK_EQUAL(int8_t(0), etl::div_sat(int8_t(0), int8_t(-1))); + CHECK_EQUAL(int8_t(1), etl::div_sat(int8_t(1), int8_t(1))); + CHECK_EQUAL(int8_t(-1), etl::div_sat(int8_t(1), int8_t(-1))); + CHECK_EQUAL(int8_t(-1), etl::div_sat(int8_t(-1), int8_t(1))); + CHECK_EQUAL(int8_t(1), etl::div_sat(int8_t(-1), int8_t(-1))); + CHECK_EQUAL(int8_t(3), etl::div_sat(int8_t(6), int8_t(2))); + CHECK_EQUAL(int8_t(-3), etl::div_sat(int8_t(6), int8_t(-2))); + CHECK_EQUAL(int8_t(-3), etl::div_sat(int8_t(-6), int8_t(2))); + CHECK_EQUAL(int8_t(3), etl::div_sat(int8_t(-6), int8_t(-2))); + CHECK_EQUAL(int8_t(127), etl::div_sat(int8_t(127), int8_t(1))); + CHECK_EQUAL(int8_t(-127), etl::div_sat(int8_t(127), int8_t(-1))); + CHECK_EQUAL(int8_t(-128), etl::div_sat(int8_t(-128), int8_t(1))); + CHECK_EQUAL(int8_t(0), etl::div_sat(int8_t(1), int8_t(2))); + + // The only overflow case: min / -1 saturates to max + CHECK_EQUAL(int8_t(127), etl::div_sat(int8_t(-128), int8_t(-1))); + + // int16_t + CHECK_EQUAL(int16_t(32767), etl::div_sat(int16_t(-32768), int16_t(-1))); + CHECK_EQUAL(int16_t(-32768), etl::div_sat(int16_t(-32768), int16_t(1))); + CHECK_EQUAL(int16_t(100), etl::div_sat(int16_t(1000), int16_t(10))); + + // int32_t + CHECK_EQUAL(std::numeric_limits::max(), etl::div_sat(std::numeric_limits::min(), int32_t(-1))); + CHECK_EQUAL(std::numeric_limits::min(), etl::div_sat(std::numeric_limits::min(), int32_t(1))); + CHECK_EQUAL(std::numeric_limits::max(), etl::div_sat(std::numeric_limits::max(), int32_t(1))); + CHECK_EQUAL(int32_t(0), etl::div_sat(std::numeric_limits::max(), std::numeric_limits::min())); + CHECK_EQUAL(int32_t(30), etl::div_sat(int32_t(600), int32_t(20))); + } + + //************************************************************************* + TEST(test_saturate_cast_unsigned_to_unsigned) + { + // Fits + CHECK_EQUAL(uint8_t(42), (etl::saturate_cast(uint16_t(42)))); + CHECK_EQUAL(uint8_t(0), (etl::saturate_cast(uint16_t(0)))); + CHECK_EQUAL(uint8_t(255), (etl::saturate_cast(uint16_t(255)))); + + // Overflow: clamp to max + CHECK_EQUAL(uint8_t(255), (etl::saturate_cast(uint16_t(256)))); + CHECK_EQUAL(uint8_t(255), (etl::saturate_cast(uint16_t(1000)))); + CHECK_EQUAL(uint8_t(255), (etl::saturate_cast(uint16_t(65535)))); + + // Widening (always fits) + CHECK_EQUAL(uint16_t(42), (etl::saturate_cast(uint8_t(42)))); + CHECK_EQUAL(uint16_t(255), (etl::saturate_cast(uint8_t(255)))); + } + + //************************************************************************* + TEST(test_saturate_cast_signed_to_signed) + { + // Fits + CHECK_EQUAL(int8_t(42), (etl::saturate_cast(int16_t(42)))); + CHECK_EQUAL(int8_t(-42), (etl::saturate_cast(int16_t(-42)))); + CHECK_EQUAL(int8_t(0), (etl::saturate_cast(int16_t(0)))); + CHECK_EQUAL(int8_t(127), (etl::saturate_cast(int16_t(127)))); + CHECK_EQUAL(int8_t(-128), (etl::saturate_cast(int16_t(-128)))); + + // Overflow: clamp to max + CHECK_EQUAL(int8_t(127), (etl::saturate_cast(int16_t(128)))); + CHECK_EQUAL(int8_t(127), (etl::saturate_cast(int16_t(1000)))); + + // Underflow: clamp to min + CHECK_EQUAL(int8_t(-128), (etl::saturate_cast(int16_t(-129)))); + CHECK_EQUAL(int8_t(-128), (etl::saturate_cast(int16_t(-1000)))); + + // Widening (always fits) + CHECK_EQUAL(int16_t(42), (etl::saturate_cast(int8_t(42)))); + CHECK_EQUAL(int16_t(-128), (etl::saturate_cast(int8_t(-128)))); + } + + //************************************************************************* + TEST(test_saturate_cast_signed_to_unsigned) + { + // Fits + CHECK_EQUAL(uint8_t(42), (etl::saturate_cast(int16_t(42)))); + CHECK_EQUAL(uint8_t(0), (etl::saturate_cast(int16_t(0)))); + CHECK_EQUAL(uint8_t(255), (etl::saturate_cast(int16_t(255)))); + + // Negative source: clamp to 0 + CHECK_EQUAL(uint8_t(0), (etl::saturate_cast(int16_t(-1)))); + CHECK_EQUAL(uint8_t(0), (etl::saturate_cast(int16_t(-1000)))); + CHECK_EQUAL(uint16_t(0), (etl::saturate_cast(int16_t(-1)))); + + // Overflow: clamp to max + CHECK_EQUAL(uint8_t(255), (etl::saturate_cast(int16_t(256)))); + CHECK_EQUAL(uint8_t(255), (etl::saturate_cast(int16_t(1000)))); + } + + //************************************************************************* + TEST(test_saturate_cast_unsigned_to_signed) + { + // Fits + CHECK_EQUAL(int8_t(42), (etl::saturate_cast(uint16_t(42)))); + CHECK_EQUAL(int8_t(0), (etl::saturate_cast(uint16_t(0)))); + CHECK_EQUAL(int8_t(127), (etl::saturate_cast(uint16_t(127)))); + + // Overflow: clamp to max + CHECK_EQUAL(int8_t(127), (etl::saturate_cast(uint16_t(128)))); + CHECK_EQUAL(int8_t(127), (etl::saturate_cast(uint16_t(1000)))); + CHECK_EQUAL(int8_t(127), (etl::saturate_cast(uint16_t(65535)))); + + // Widening (always fits) + CHECK_EQUAL(int16_t(255), (etl::saturate_cast(uint8_t(255)))); + CHECK_EQUAL(int16_t(0), (etl::saturate_cast(uint8_t(0)))); + } + + //************************************************************************* + TEST(test_saturate_cast_same_type) + { + // Same type, no conversion needed + CHECK_EQUAL(int32_t(42), (etl::saturate_cast(int32_t(42)))); + CHECK_EQUAL(uint32_t(42), (etl::saturate_cast(uint32_t(42)))); + CHECK_EQUAL(int32_t(-42), (etl::saturate_cast(int32_t(-42)))); + } + + //************************************************************************* + TEST(test_saturate_cast_boundary_values) + { + // int32_t max -> uint16_t + CHECK_EQUAL(uint16_t(65535), (etl::saturate_cast(int32_t(2147483647)))); + + // int32_t min -> uint16_t + CHECK_EQUAL(uint16_t(0), (etl::saturate_cast(std::numeric_limits::min()))); + + // uint32_t max -> int32_t + CHECK_EQUAL(std::numeric_limits::max(), (etl::saturate_cast(std::numeric_limits::max()))); + + // uint32_t max -> int16_t + CHECK_EQUAL(int16_t(32767), (etl::saturate_cast(std::numeric_limits::max()))); + } } } // namespace diff --git a/test/test_type_traits.cpp b/test/test_type_traits.cpp index c49b2eda..9f6c7bfc 100644 --- a/test/test_type_traits.cpp +++ b/test/test_type_traits.cpp @@ -1007,6 +1007,64 @@ namespace CHECK((std::is_base_of::value) == (etl::is_base_of::value)); } +#if ETL_USING_BUILTIN_IS_VIRTUAL_BASE_OF + //************************************************************************* + TEST(test_is_virtual_base_of) + { + struct A + { + }; + struct B : public A // Non-virtual base + { + }; + struct C : virtual public A // Virtual base + { + }; + struct D + : public B + , virtual public A // A is both virtual and non-virtual base + { + }; + struct E : public C // A is indirect virtual base + { + }; + struct F // Unrelated class + { + }; + + // A is not a virtual base of A (same class) + CHECK_EQUAL(false, (etl::is_virtual_base_of::value)); + + // A is NOT a virtual base of B (it's a non-virtual base) + CHECK_EQUAL(false, (etl::is_virtual_base_of::value)); + + // A IS a virtual base of C + CHECK_EQUAL(true, (etl::is_virtual_base_of::value)); + + // A IS a virtual base of D (even though it's also a non-virtual base via B) + CHECK_EQUAL(true, (etl::is_virtual_base_of::value)); + + // A IS a virtual base of E (indirect virtual base) + CHECK_EQUAL(true, (etl::is_virtual_base_of::value)); + + // Unrelated classes + CHECK_EQUAL(false, (etl::is_virtual_base_of::value)); + CHECK_EQUAL(false, (etl::is_virtual_base_of::value)); + + // Fundamental types + CHECK_EQUAL(false, (etl::is_virtual_base_of::value)); + CHECK_EQUAL(false, (etl::is_virtual_base_of::value)); + + #if ETL_USING_CPP17 + // Test the _v helper + CHECK_EQUAL(false, etl::is_virtual_base_of_v); + CHECK_EQUAL(true, etl::is_virtual_base_of_v); + CHECK_EQUAL(true, etl::is_virtual_base_of_v); + CHECK_EQUAL(true, etl::is_virtual_base_of_v); + #endif + } +#endif + //************************************************************************* TEST(test_types) { @@ -1574,6 +1632,110 @@ namespace #endif } + //************************************************************************* + TEST(test_is_trivially_relocatable) + { + // Trivially relocatable types (trivially copyable and trivially destructible) + // Primitive types should always be detected as trivially relocatable + CHECK_TRUE(etl::is_trivially_relocatable::value); + CHECK_TRUE(etl::is_trivially_relocatable::value); + CHECK_TRUE(etl::is_trivially_relocatable::value); + CHECK_TRUE(etl::is_trivially_relocatable::value); + + // POD struct should be trivially relocatable when proper detection is available + struct TrivialStruct + { + int x; + double y; + }; + + // Struct with non-trivial destructor should NOT be trivially relocatable + struct NonTrivialDestructor + { + ~NonTrivialDestructor() {} + }; + CHECK_FALSE(etl::is_trivially_relocatable::value); + + // Struct with non-trivial copy constructor should NOT be trivially relocatable + struct NonTrivialCopy + { + NonTrivialCopy() = default; + NonTrivialCopy(const NonTrivialCopy&) {} + NonTrivialCopy& operator=(const NonTrivialCopy&) = default; + }; + CHECK_FALSE(etl::is_trivially_relocatable::value); + +#if ETL_USING_STL || ETL_USING_BUILTIN_IS_TRIVIALLY_RELOCATABLE + // These tests require STL or compiler builtins to correctly detect struct/array triviality + CHECK_TRUE(etl::is_trivially_relocatable::value); + CHECK_TRUE(etl::is_trivially_relocatable::value); + CHECK_TRUE(etl::is_trivially_relocatable::value); +#endif + +#if ETL_USING_CPP17 + // Test the _v helper variable + CHECK_TRUE(etl::is_trivially_relocatable_v); + CHECK_TRUE(etl::is_trivially_relocatable_v); + CHECK_TRUE(etl::is_trivially_relocatable_v); + #if ETL_USING_STL || ETL_USING_BUILTIN_IS_TRIVIALLY_RELOCATABLE + CHECK_TRUE(etl::is_trivially_relocatable_v); + #endif + CHECK_FALSE(etl::is_trivially_relocatable_v); + CHECK_FALSE(etl::is_trivially_relocatable_v); +#endif + + // Verify consistency: if a type is trivially_copyable AND trivially_destructible, + // then it should be trivially_relocatable. The reverse may not hold when compiler + // builtins provide more accurate detection than the fallback implementations. + CHECK_TRUE(!(etl::is_trivially_copyable::value && etl::is_trivially_destructible::value) + || etl::is_trivially_relocatable::value); + CHECK_TRUE(!(etl::is_trivially_copyable::value && etl::is_trivially_destructible::value) + || etl::is_trivially_relocatable::value); + // Non-trivially destructible types should never be trivially relocatable + CHECK_FALSE(etl::is_trivially_relocatable::value); + // Non-trivially copyable types should never be trivially relocatable + CHECK_FALSE(etl::is_trivially_relocatable::value); + } + + //************************************************************************* + TEST(test_is_nothrow_relocatable) + { + // Trivially relocatable types should always be nothrow relocatable + // Primitive types should always be detected correctly + CHECK_TRUE(etl::is_nothrow_relocatable::value); + CHECK_TRUE(etl::is_nothrow_relocatable::value); + CHECK_TRUE(etl::is_nothrow_relocatable::value); + CHECK_TRUE(etl::is_nothrow_relocatable::value); + + // POD struct should be nothrow relocatable when proper detection is available + struct TrivialStruct + { + int x; + double y; + }; + +#if ETL_USING_STL || ETL_USING_BUILTIN_IS_TRIVIALLY_RELOCATABLE + // These tests require STL or compiler builtins to correctly detect struct/array triviality + CHECK_TRUE(etl::is_nothrow_relocatable::value); + CHECK_TRUE(etl::is_nothrow_relocatable::value); + CHECK_TRUE(etl::is_nothrow_relocatable::value); +#endif + +#if ETL_USING_CPP17 + // Test the _v helper variable + CHECK_TRUE(etl::is_nothrow_relocatable_v); + CHECK_TRUE(etl::is_nothrow_relocatable_v); + CHECK_TRUE(etl::is_nothrow_relocatable_v); + #if ETL_USING_STL || ETL_USING_BUILTIN_IS_TRIVIALLY_RELOCATABLE + CHECK_TRUE(etl::is_nothrow_relocatable_v); + #endif +#endif + + // Verify consistency: nothrow_relocatable should be at least as permissive as trivially_relocatable + CHECK_TRUE(!etl::is_trivially_relocatable::value || etl::is_nothrow_relocatable::value); + CHECK_TRUE(!etl::is_trivially_relocatable::value || etl::is_nothrow_relocatable::value); + } + //************************************************************************* TEST(test_is_base_of_any) {