diff --git a/.devcontainer/armhf/Dockerfile b/.devcontainer/armhf/Dockerfile new file mode 100644 index 00000000..7d5632a6 --- /dev/null +++ b/.devcontainer/armhf/Dockerfile @@ -0,0 +1,54 @@ +# armhf Test Environment for ETL +# Uses QEMU user-mode emulation to run armhf binaries on x64 host +FROM debian:trixie + +# Avoid prompts from apt +ENV DEBIAN_FRONTEND=noninteractive + +# Install QEMU user-mode emulation and armhf cross-compilation tools +RUN dpkg --add-architecture armhf && \ + apt-get update && apt-get install -y --no-install-recommends \ + qemu-user-static \ + qemu-user \ + binfmt-support \ + gcc-arm-linux-gnueabihf \ + g++-arm-linux-gnueabihf \ + cmake \ + make \ + ninja-build \ + git \ + wget \ + file \ + libc6:armhf \ + libstdc++6:armhf \ + && rm -rf /var/lib/apt/lists/* + +# Create non-root user with stable UID/GID +ARG USERNAME=devuser +ARG USER_UID=1000 +ARG USER_GID=1000 + +RUN groupadd --gid ${USER_GID} ${USERNAME} && \ + useradd --uid ${USER_UID} --gid ${USER_GID} --shell /bin/bash --create-home ${USERNAME} + +# Set working directory +WORKDIR /workspaces/etl + +# Verify QEMU and cross-compilation setup +RUN echo "=== Host Architecture ===" && \ + uname -m && \ + echo "" && \ + echo "=== armhf Cross Compiler ===" && \ + arm-linux-gnueabihf-gcc --version && \ + echo "" && \ + echo "=== QEMU arm ===" && \ + qemu-arm-static --version | head -n1 + +# Ensure workspace directory ownership for non-root user +RUN mkdir -p /workspaces/etl && chown -R ${USERNAME}:${USERNAME} /workspaces + +# Switch to non-root user +USER ${USERNAME} + +# Default command +CMD ["/bin/bash"] diff --git a/.devcontainer/armhf/devcontainer.json b/.devcontainer/armhf/devcontainer.json new file mode 100644 index 00000000..a1dc285e --- /dev/null +++ b/.devcontainer/armhf/devcontainer.json @@ -0,0 +1,29 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/cpp +{ + "name": "armhf (Debian)", + "build": { + "dockerfile": "./Dockerfile", + "context": "." + }, + "customizations": { + "vscode": { + "extensions": [ + "ms-vscode.cpptools", + "ms-vscode.cmake-tools" + ], + "settings": { + "cmake.sourceDirectory": "${workspaceFolder}/test", + "cmake.configureArgs": [ + "-DCMAKE_TOOLCHAIN_FILE=${workspaceFolder}/.devcontainer/armhf/toolchain-armhf.cmake", + "-DBUILD_TESTS=ON", + "-DNO_STL=OFF", + "-DETL_CXX_STANDARD=23" + ], + "cmake.buildDirectory": "${workspaceFolder}/build-armhf", + "cmake.generator": "Ninja" + } + } + }, + "remoteUser": "root" +} diff --git a/.devcontainer/armhf/toolchain-armhf.cmake b/.devcontainer/armhf/toolchain-armhf.cmake new file mode 100644 index 00000000..a7f9f00a --- /dev/null +++ b/.devcontainer/armhf/toolchain-armhf.cmake @@ -0,0 +1,21 @@ +# CMake toolchain file for armhf cross-compilation +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR arm) + +# Specify the cross compiler +set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc) +set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++) +set(CMAKE_AR arm-linux-gnueabihf-ar) +set(CMAKE_RANLIB arm-linux-gnueabihf-ranlib) +set(CMAKE_STRIP arm-linux-gnueabihf-strip) + +# Search for programs in the build host directories +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + +# For libraries and headers in the target directories +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +# Set QEMU for running tests +set(CMAKE_CROSSCOMPILING_EMULATOR /usr/bin/qemu-arm-static CACHE FILEPATH "Path to the emulator for cross-compiled binaries") diff --git a/.devcontainer/i386/Dockerfile b/.devcontainer/i386/Dockerfile new file mode 100644 index 00000000..99223eb9 --- /dev/null +++ b/.devcontainer/i386/Dockerfile @@ -0,0 +1,54 @@ +# i386 Test Environment for ETL +# Uses QEMU user-mode emulation to run i386 binaries on x64 host +FROM debian:trixie + +# Avoid prompts from apt +ENV DEBIAN_FRONTEND=noninteractive + +# Install QEMU user-mode emulation and i386 cross-compilation tools +RUN dpkg --add-architecture i386 && \ + apt-get update && apt-get install -y --no-install-recommends \ + qemu-user-static \ + qemu-user \ + binfmt-support \ + gcc-i686-linux-gnu \ + g++-i686-linux-gnu \ + cmake \ + make \ + ninja-build \ + git \ + wget \ + file \ + libc6:i386 \ + libstdc++6:i386 \ + && rm -rf /var/lib/apt/lists/* + +# Create non-root user with stable UID/GID +ARG USERNAME=devuser +ARG USER_UID=1000 +ARG USER_GID=1000 + +RUN groupadd --gid ${USER_GID} ${USERNAME} && \ + useradd --uid ${USER_UID} --gid ${USER_GID} --shell /bin/bash --create-home ${USERNAME} + +# Set working directory +WORKDIR /workspaces/etl + +# Verify QEMU and cross-compilation setup +RUN echo "=== Host Architecture ===" && \ + uname -m && \ + echo "" && \ + echo "=== i386 Cross Compiler ===" && \ + i686-linux-gnu-gcc --version && \ + echo "" && \ + echo "=== QEMU i386 ===" && \ + qemu-i386-static --version | head -n1 + +# Ensure workspace directory ownership for non-root user +RUN mkdir -p /workspaces/etl && chown -R ${USERNAME}:${USERNAME} /workspaces + +# Switch to non-root user +USER ${USERNAME} + +# Default command +CMD ["/bin/bash"] diff --git a/.devcontainer/i386/devcontainer.json b/.devcontainer/i386/devcontainer.json new file mode 100644 index 00000000..84e28a8e --- /dev/null +++ b/.devcontainer/i386/devcontainer.json @@ -0,0 +1,29 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/cpp +{ + "name": "i386 (Debian)", + "build": { + "dockerfile": "./Dockerfile", + "context": "." + }, + "customizations": { + "vscode": { + "extensions": [ + "ms-vscode.cpptools", + "ms-vscode.cmake-tools" + ], + "settings": { + "cmake.sourceDirectory": "${workspaceFolder}/test", + "cmake.configureArgs": [ + "-DCMAKE_TOOLCHAIN_FILE=${workspaceFolder}/.devcontainer/i386/toolchain-i386.cmake", + "-DBUILD_TESTS=ON", + "-DNO_STL=OFF", + "-DETL_CXX_STANDARD=23" + ], + "cmake.buildDirectory": "${workspaceFolder}/build-i386", + "cmake.generator": "Ninja" + } + } + }, + "remoteUser": "root" +} diff --git a/.devcontainer/i386/toolchain-i386.cmake b/.devcontainer/i386/toolchain-i386.cmake new file mode 100644 index 00000000..502e2285 --- /dev/null +++ b/.devcontainer/i386/toolchain-i386.cmake @@ -0,0 +1,21 @@ +# CMake toolchain file for i386 cross-compilation +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR i386) + +# Specify the cross compiler +set(CMAKE_C_COMPILER i686-linux-gnu-gcc) +set(CMAKE_CXX_COMPILER i686-linux-gnu-g++) +set(CMAKE_AR i686-linux-gnu-ar) +set(CMAKE_RANLIB i686-linux-gnu-ranlib) +set(CMAKE_STRIP i686-linux-gnu-strip) + +# Search for programs in the build host directories +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + +# For libraries and headers in the target directories +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +# Set QEMU for running tests +set(CMAKE_CROSSCOMPILING_EMULATOR /usr/bin/qemu-i386-static CACHE FILEPATH "Path to the emulator for cross-compiled binaries") diff --git a/.devcontainer/powerpc/Dockerfile b/.devcontainer/powerpc/Dockerfile new file mode 100644 index 00000000..06bab1d0 --- /dev/null +++ b/.devcontainer/powerpc/Dockerfile @@ -0,0 +1,71 @@ +# powerpc Test Environment for ETL +# Uses QEMU user-mode emulation to run powerpc binaries on x64 host +FROM debian:sid-20260406 + +# Avoid prompts from apt +ENV DEBIAN_FRONTEND=noninteractive + +# Install QEMU user-mode emulation and powerpc cross-compilation tools +RUN dpkg --add-architecture powerpc && \ + apt-get update && apt-get install -y --no-install-recommends \ + binfmt-support \ + gpg \ + ca-certificates \ + cmake \ + make \ + ninja-build \ + git \ + wget \ + file \ + debian-ports-archive-keyring \ + && rm -rf /var/lib/apt/lists/* + +RUN cat < /etc/apt/sources.list.d/powerpc.sources +Types: deb +URIs: http://snapshot.debian.org/archive/debian-ports/20260406T000000Z +Suites: sid +Components: main +Architectures: powerpc +Signed-By: /usr/share/keyrings/debian-ports-archive-keyring.gpg +EOF + +RUN echo 'Acquire::Check-Valid-Until "false";' > /etc/apt/apt.conf.d/99no-check-valid + +RUN apt-get update && apt-get install -y --no-install-recommends \ + qemu-user-static \ + qemu-user \ + gcc-powerpc-linux-gnu \ + g++-powerpc-linux-gnu \ + libc6:powerpc \ + libstdc++6:powerpc \ + && rm -rf /var/lib/apt/lists/* + +# Create non-root user with stable UID/GID +ARG USERNAME=devuser +ARG USER_UID=1000 +ARG USER_GID=1000 + +RUN groupadd --gid ${USER_GID} ${USERNAME} && \ + useradd --uid ${USER_UID} --gid ${USER_GID} --shell /bin/bash --create-home ${USERNAME} + +# Set working directory +WORKDIR /workspaces/etl + +# Verify QEMU and cross-compilation setup +RUN echo "=== Host Architecture ===" && \ + uname -m && \ + echo "" && \ + echo "=== powerpc Cross Compiler ===" && \ + powerpc-linux-gnu-gcc --version && \ + echo "" && \ + echo "=== QEMU powerpc ===" && \ + qemu-ppc-static --version | head -n1 + +# Ensure workspace directory ownership for non-root user +RUN mkdir -p /workspaces/etl && chown -R ${USERNAME}:${USERNAME} /workspaces + +# Switch to non-root user +USER ${USERNAME} + +# Default command +CMD ["/bin/bash"] diff --git a/.devcontainer/powerpc/devcontainer.json b/.devcontainer/powerpc/devcontainer.json new file mode 100644 index 00000000..1d7a9a05 --- /dev/null +++ b/.devcontainer/powerpc/devcontainer.json @@ -0,0 +1,29 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/cpp +{ + "name": "powerpc (Debian)", + "build": { + "dockerfile": "./Dockerfile", + "context": "." + }, + "customizations": { + "vscode": { + "extensions": [ + "ms-vscode.cpptools", + "ms-vscode.cmake-tools" + ], + "settings": { + "cmake.sourceDirectory": "${workspaceFolder}/test", + "cmake.configureArgs": [ + "-DCMAKE_TOOLCHAIN_FILE=${workspaceFolder}/.devcontainer/powerpc/toolchain-powerpc.cmake", + "-DBUILD_TESTS=ON", + "-DNO_STL=ON", + "-DETL_CXX_STANDARD=23" + ], + "cmake.buildDirectory": "${workspaceFolder}/build-powerpc", + "cmake.generator": "Ninja" + } + } + }, + "remoteUser": "root" +} diff --git a/.devcontainer/powerpc/toolchain-powerpc.cmake b/.devcontainer/powerpc/toolchain-powerpc.cmake new file mode 100644 index 00000000..1afea7da --- /dev/null +++ b/.devcontainer/powerpc/toolchain-powerpc.cmake @@ -0,0 +1,21 @@ +# CMake toolchain file for powerpc cross-compilation +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR powerpc) + +# Specify the cross compiler +set(CMAKE_C_COMPILER powerpc-linux-gnu-gcc) +set(CMAKE_CXX_COMPILER powerpc-linux-gnu-g++) +set(CMAKE_AR powerpc-linux-gnu-ar) +set(CMAKE_RANLIB powerpc-linux-gnu-ranlib) +set(CMAKE_STRIP powerpc-linux-gnu-strip) + +# Search for programs in the build host directories +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + +# For libraries and headers in the target directories +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +# Set QEMU for running tests +set(CMAKE_CROSSCOMPILING_EMULATOR /usr/bin/qemu-ppc CACHE FILEPATH "Path to the emulator for cross-compiled binaries") diff --git a/.devcontainer/riscv64/Dockerfile b/.devcontainer/riscv64/Dockerfile new file mode 100644 index 00000000..081e42ed --- /dev/null +++ b/.devcontainer/riscv64/Dockerfile @@ -0,0 +1,54 @@ +# riscv64 Test Environment for ETL +# Uses QEMU user-mode emulation to run riscv64 binaries on x64 host +FROM debian:trixie + +# Avoid prompts from apt +ENV DEBIAN_FRONTEND=noninteractive + +# Install QEMU user-mode emulation and riscv64 cross-compilation tools +RUN dpkg --add-architecture riscv64 && \ + apt-get update && apt-get install -y --no-install-recommends \ + qemu-user-static \ + qemu-user \ + binfmt-support \ + gcc-riscv64-linux-gnu \ + g++-riscv64-linux-gnu \ + cmake \ + make \ + ninja-build \ + git \ + wget \ + file \ + libc6:riscv64 \ + libstdc++6:riscv64 \ + && rm -rf /var/lib/apt/lists/* + +# Create non-root user with stable UID/GID +ARG USERNAME=devuser +ARG USER_UID=1000 +ARG USER_GID=1000 + +RUN groupadd --gid ${USER_GID} ${USERNAME} && \ + useradd --uid ${USER_UID} --gid ${USER_GID} --shell /bin/bash --create-home ${USERNAME} + +# Set working directory +WORKDIR /workspaces/etl + +# Verify QEMU and cross-compilation setup +RUN echo "=== Host Architecture ===" && \ + uname -m && \ + echo "" && \ + echo "=== riscv64 Cross Compiler ===" && \ + riscv64-linux-gnu-gcc --version && \ + echo "" && \ + echo "=== QEMU riscv64 ===" && \ + qemu-riscv64-static --version | head -n1 + +# Ensure workspace directory ownership for non-root user +RUN mkdir -p /workspaces/etl && chown -R ${USERNAME}:${USERNAME} /workspaces + +# Switch to non-root user +USER ${USERNAME} + +# Default command +CMD ["/bin/bash"] diff --git a/.devcontainer/riscv64/devcontainer.json b/.devcontainer/riscv64/devcontainer.json new file mode 100644 index 00000000..0e673f24 --- /dev/null +++ b/.devcontainer/riscv64/devcontainer.json @@ -0,0 +1,29 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/cpp +{ + "name": "riscv64 (Debian)", + "build": { + "dockerfile": "./Dockerfile", + "context": "." + }, + "customizations": { + "vscode": { + "extensions": [ + "ms-vscode.cpptools", + "ms-vscode.cmake-tools" + ], + "settings": { + "cmake.sourceDirectory": "${workspaceFolder}/test", + "cmake.configureArgs": [ + "-DCMAKE_TOOLCHAIN_FILE=${workspaceFolder}/.devcontainer/riscv64/toolchain-riscv64.cmake", + "-DBUILD_TESTS=ON", + "-DNO_STL=OFF", + "-DETL_CXX_STANDARD=23" + ], + "cmake.buildDirectory": "${workspaceFolder}/build-riscv64", + "cmake.generator": "Ninja" + } + } + }, + "remoteUser": "root" +} diff --git a/.devcontainer/riscv64/toolchain-riscv64.cmake b/.devcontainer/riscv64/toolchain-riscv64.cmake new file mode 100644 index 00000000..adc1c7f3 --- /dev/null +++ b/.devcontainer/riscv64/toolchain-riscv64.cmake @@ -0,0 +1,20 @@ +# CMake toolchain file for riscv64 cross-compilation +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR riscv64) + +# Specify the cross compiler +set(CMAKE_C_COMPILER riscv64-linux-gnu-gcc) +set(CMAKE_CXX_COMPILER riscv64-linux-gnu-g++) +set(CMAKE_AR riscv64-linux-gnu-ar) +set(CMAKE_RANLIB riscv64-linux-gnu-ranlib) +set(CMAKE_STRIP riscv64-linux-gnu-strip) +# Search for programs in the build host directories +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + +# For libraries and headers in the target directories +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +# Set QEMU for running tests +set(CMAKE_CROSSCOMPILING_EMULATOR /usr/bin/qemu-riscv64-static CACHE FILEPATH "Path to the emulator for cross-compiled binaries") diff --git a/.devcontainer/run-tests.sh b/.devcontainer/run-tests.sh new file mode 100755 index 00000000..218dc032 --- /dev/null +++ b/.devcontainer/run-tests.sh @@ -0,0 +1,56 @@ +#!/bin/bash +# +# Run tests inside the separately created docker container for different hardware architecture +# +# Strategy: +# * Create docker image +# * Enter image +# * Cross build tests +# * Run tests via QEMU +# + +set -e + +usage() +{ + echo "Usage: run-tests.sh " + echo "Architecture: armhf|i386|powerpc|riscv64|s390x" + echo "(run from project root)" +} + +ARCHLIST="armhf i386 powerpc riscv64 s390x" + +if [[ " $ARCHLIST " =~ " $1 " ]] ; then + ARCH=$1 +else + echo "Unsupported architecture: $1" + usage + exit 1 +fi + +if [ "$2" = "" ] ; then + echo "Creating docker image..." + docker build -t $ARCH .devcontainer/$ARCH + + echo "Entering container..." + docker run -it --rm -v "$PWD":/workspaces/etl -w /workspaces/etl $ARCH /bin/bash .devcontainer/run-tests.sh $ARCH inside_container + +elif [ "$2" = "inside_container" ] ; then + echo "Cross building tests..." + mkdir -p build-$ARCH + cd build-$ARCH + cmake -DCMAKE_TOOLCHAIN_FILE=../.devcontainer/$ARCH/toolchain-$ARCH.cmake \ + -DBUILD_TESTS=ON -DNO_STL=ON -DETL_CXX_STANDARD=23 \ + -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_OPTIMISATION=-O0 -DETL_ENABLE_SANITIZER=Off -DETL_MESSAGES_ARE_NOT_VIRTUAL=OFF \ + ../test + export CMAKE_BUILD_PARALLEL_LEVEL=$(nproc) + cmake --build . + + echo "Running tests via CTest (using QEMU emulator from toolchain)..." + ctest -V --output-on-failure + echo "Tests successful." +else + echo "Invalid second argument: $2" + usage + exit 1 +fi diff --git a/.devcontainer/s390x/Dockerfile b/.devcontainer/s390x/Dockerfile index 21a6289c..f8c6ff87 100644 --- a/.devcontainer/s390x/Dockerfile +++ b/.devcontainer/s390x/Dockerfile @@ -7,7 +7,7 @@ ENV DEBIAN_FRONTEND=noninteractive # Install QEMU user-mode emulation and s390x cross-compilation tools RUN dpkg --add-architecture s390x && \ - apt-get update && apt-get install -y --no-install-recommends\ + apt-get update && apt-get install -y --no-install-recommends \ qemu-user-static \ qemu-user \ binfmt-support \ @@ -23,6 +23,14 @@ RUN dpkg --add-architecture s390x && \ libstdc++6:s390x \ && rm -rf /var/lib/apt/lists/* +# Create non-root user with stable UID/GID +ARG USERNAME=devuser +ARG USER_UID=1000 +ARG USER_GID=1000 + +RUN groupadd --gid ${USER_GID} ${USERNAME} && \ + useradd --uid ${USER_UID} --gid ${USER_GID} --shell /bin/bash --create-home ${USERNAME} + # Set working directory WORKDIR /workspaces/etl @@ -36,5 +44,11 @@ RUN echo "=== Host Architecture ===" && \ echo "=== QEMU s390x ===" && \ qemu-s390x-static --version | head -n1 +# Ensure workspace directory ownership for non-root user +RUN mkdir -p /workspaces/etl && chown -R ${USERNAME}:${USERNAME} /workspaces + +# Switch to non-root user +USER ${USERNAME} + # Default command CMD ["/bin/bash"] diff --git a/.devcontainer/s390x/devcontainer.json b/.devcontainer/s390x/devcontainer.json index 8b7f8235..535a0799 100644 --- a/.devcontainer/s390x/devcontainer.json +++ b/.devcontainer/s390x/devcontainer.json @@ -18,7 +18,7 @@ "-DCMAKE_TOOLCHAIN_FILE=${workspaceFolder}/.devcontainer/s390x/toolchain-s390x.cmake", "-DBUILD_TESTS=ON", "-DNO_STL=OFF", - "-DETL_CXX_STANDARD=17" + "-DETL_CXX_STANDARD=23" ], "cmake.buildDirectory": "${workspaceFolder}/build-s390x", "cmake.generator": "Ninja" diff --git a/.github/workflows/clang-c++23.yml b/.github/workflows/clang-c++23.yml index ffa88744..18817aaa 100644 --- a/.github/workflows/clang-c++23.yml +++ b/.github/workflows/clang-c++23.yml @@ -30,7 +30,7 @@ jobs: export CC=clang-17 export CXX=clang++-17 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=OFF -DETL_CXX_STANDARD=23 ./ + 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) @@ -59,7 +59,7 @@ jobs: export CC=clang-17 export CXX=clang++-17 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=ON -DETL_CXX_STANDARD=23 ./ + 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) @@ -88,7 +88,7 @@ jobs: export CC=clang-17 export CXX=clang++-17 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=ON -DETL_CXX_STANDARD=23 ./ + 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) @@ -110,7 +110,7 @@ jobs: 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=OFF -DETL_CXX_STANDARD=23 ./ + 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) @@ -132,7 +132,7 @@ jobs: 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=OFF -DETL_CXX_STANDARD=23 ./ + 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) @@ -154,7 +154,7 @@ jobs: 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=ON -DETL_CXX_STANDARD=23 ./ + 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) @@ -176,7 +176,7 @@ jobs: 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=ON -DETL_CXX_STANDARD=23 ./ + 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) diff --git a/.github/workflows/gcc-c++23-armhf.yml b/.github/workflows/gcc-c++23-armhf.yml new file mode 100644 index 00000000..1bd2912b --- /dev/null +++ b/.github/workflows/gcc-c++23-armhf.yml @@ -0,0 +1,29 @@ +name: gcc-c++23-armhf +on: + push: + branches: [ master, development, pull-request/* ] + pull_request: + branches: [ master, development, pull-request/* ] + types: [opened, synchronize, reopened] + +jobs: + + build-gcc-cpp23-linux-no-stl-armhf: + name: GCC C++23 Linux - No STL - armhf + runs-on: ubuntu-24.04 + + steps: + - uses: actions/checkout@v4 + + - name: Build Docker image + run: docker build -t etl-armhf -f .devcontainer/armhf/Dockerfile . + + - name: Build and run tests + run: | + docker run --rm --user root -v ${{ github.workspace }}:/workspaces/etl etl-armhf bash -c "\ + 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 -DCMAKE_TOOLCHAIN_FILE=.devcontainer/armhf/toolchain-armhf.cmake \ + -DEXTRA_TESTING_FLAGS=-v \ + ./ && \ + cmake --build . -- -j \$(getconf _NPROCESSORS_ONLN) && \ + ctest -V" diff --git a/.github/workflows/gcc-c++23-i386.yml b/.github/workflows/gcc-c++23-i386.yml new file mode 100644 index 00000000..31bfc331 --- /dev/null +++ b/.github/workflows/gcc-c++23-i386.yml @@ -0,0 +1,29 @@ +name: gcc-c++23-i386 +on: + push: + branches: [ master, development, pull-request/* ] + pull_request: + branches: [ master, development, pull-request/* ] + types: [opened, synchronize, reopened] + +jobs: + + build-gcc-cpp23-linux-no-stl-i386: + name: GCC C++23 Linux - No STL - i386 + runs-on: ubuntu-24.04 + + steps: + - uses: actions/checkout@v4 + + - name: Build Docker image + run: docker build -t etl-i386 -f .devcontainer/i386/Dockerfile . + + - name: Build and run tests + run: | + docker run --rm --user root -v ${{ github.workspace }}:/workspaces/etl etl-i386 bash -c "\ + 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 -DCMAKE_TOOLCHAIN_FILE=.devcontainer/i386/toolchain-i386.cmake \ + -DEXTRA_TESTING_FLAGS=-v \ + ./ && \ + cmake --build . -- -j \$(getconf _NPROCESSORS_ONLN) && \ + ctest -V" diff --git a/.github/workflows/gcc-c++23-powerpc.yml b/.github/workflows/gcc-c++23-powerpc.yml new file mode 100644 index 00000000..7494ae55 --- /dev/null +++ b/.github/workflows/gcc-c++23-powerpc.yml @@ -0,0 +1,29 @@ +name: gcc-c++23-powerpc +on: + push: + branches: [ master, development, pull-request/* ] + pull_request: + branches: [ master, development, pull-request/* ] + types: [opened, synchronize, reopened] + +jobs: + + build-gcc-cpp23-linux-no-stl-powerpc: + name: GCC C++23 Linux - No STL - powerpc + runs-on: ubuntu-24.04 + + steps: + - uses: actions/checkout@v4 + + - name: Build Docker image + run: docker build -t etl-powerpc -f .devcontainer/powerpc/Dockerfile . + + - name: Build and run tests + run: | + docker run --rm --user root -v ${{ github.workspace }}:/workspaces/etl etl-powerpc bash -c "\ + 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 -DCMAKE_TOOLCHAIN_FILE=.devcontainer/powerpc/toolchain-powerpc.cmake \ + -DEXTRA_TESTING_FLAGS=-v \ + ./ && \ + cmake --build . -- -j \$(getconf _NPROCESSORS_ONLN) && \ + ctest -V" diff --git a/.github/workflows/gcc-c++23-riscv64.yml b/.github/workflows/gcc-c++23-riscv64.yml new file mode 100644 index 00000000..695056a8 --- /dev/null +++ b/.github/workflows/gcc-c++23-riscv64.yml @@ -0,0 +1,29 @@ +name: gcc-c++23-riscv64 +on: + push: + branches: [ master, development, pull-request/* ] + pull_request: + branches: [ master, development, pull-request/* ] + types: [opened, synchronize, reopened] + +jobs: + + build-gcc-cpp23-linux-no-stl-riscv64: + name: GCC C++23 Linux - No STL - riscv64 + runs-on: ubuntu-24.04 + + steps: + - uses: actions/checkout@v4 + + - name: Build Docker image + run: docker build -t etl-riscv64 -f .devcontainer/riscv64/Dockerfile . + + - name: Build and run tests + run: | + docker run --rm --user root -v ${{ github.workspace }}:/workspaces/etl etl-riscv64 bash -c "\ + 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 -DCMAKE_TOOLCHAIN_FILE=.devcontainer/riscv64/toolchain-riscv64.cmake \ + -DEXTRA_TESTING_FLAGS=-v \ + ./ && \ + cmake --build . -- -j \$(getconf _NPROCESSORS_ONLN) && \ + ctest -V" diff --git a/.github/workflows/gcc-c++23-s390x.yml b/.github/workflows/gcc-c++23-s390x.yml new file mode 100644 index 00000000..f6a15aca --- /dev/null +++ b/.github/workflows/gcc-c++23-s390x.yml @@ -0,0 +1,29 @@ +name: gcc-c++23-s390x +on: + push: + branches: [ master, development, pull-request/* ] + pull_request: + branches: [ master, development, pull-request/* ] + types: [opened, synchronize, reopened] + +jobs: + + build-gcc-cpp23-linux-no-stl-s390x: + name: GCC C++23 Linux - No STL - s390x + runs-on: ubuntu-24.04 + + steps: + - uses: actions/checkout@v4 + + - name: Build Docker image + run: docker build -t etl-s390x -f .devcontainer/s390x/Dockerfile . + + - name: Build and run tests + run: | + docker run --rm --user root -v ${{ github.workspace }}:/workspaces/etl etl-s390x bash -c "\ + 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 -DCMAKE_TOOLCHAIN_FILE=.devcontainer/s390x/toolchain-s390x.cmake \ + -DEXTRA_TESTING_FLAGS=-v \ + ./ && \ + cmake --build . -- -j \$(getconf _NPROCESSORS_ONLN) && \ + ctest -V" diff --git a/.github/workflows/gcc-c++23.yml b/.github/workflows/gcc-c++23.yml index f91924bd..aad4325c 100644 --- a/.github/workflows/gcc-c++23.yml +++ b/.github/workflows/gcc-c++23.yml @@ -23,7 +23,7 @@ jobs: 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=OFF -DETL_CXX_STANDARD=23 ./ + 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) @@ -45,7 +45,7 @@ jobs: 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=OFF -DETL_CXX_STANDARD=23 ./ + 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) @@ -67,7 +67,7 @@ jobs: 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=ON -DETL_CXX_STANDARD=23 ./ + 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) @@ -89,7 +89,7 @@ jobs: 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=ON -DETL_CXX_STANDARD=23 ./ + 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) diff --git a/docs/generators.md b/docs/generators.md new file mode 100644 index 00000000..d44a38b6 --- /dev/null +++ b/docs/generators.md @@ -0,0 +1,190 @@ +# Code Generation for Pre-C++11 Support + +ETL supports C++03 (also referred to as C++98) environments where variadic +templates, `constexpr`, and other modern features are unavailable. To +provide equivalent functionality, certain headers are **generated** using +[Cog](https://nedbatchelder.com/code/cog/), a Python-based code generation +tool that embeds Python snippets inside source files. + +This document explains how the code generation system works and how to +regenerate the headers if you modify a generator template. + +--- + +## Overview + +| Directory | Contents | +|---|---| +| `include/etl/generators/` | Generator templates (`*_generator.h`) and batch scripts | +| `include/etl/private/` | Generated output (`*_cpp03.h`) committed to the repository | +| `scripts/generator_test.py` | CI script that verifies generators match committed files | + +The generator templates contain embedded Python code (delimited by `[[[cog` +and `]]]`) that produces the repetitive C++03 boilerplate. Cog processes +these templates and writes the expanded output to `include/etl/private/`. + +--- + +## Generated Headers + +The following C++03 compatibility headers are generated: + +| Generator | Output | Purpose | +|---|---|---| +| `fsm_fwd_decl_cpp03_generator.h` | `fsm_fwd_decl_cpp03.h` | FSM forward declarations | +| `fsm_friend_decl_cpp03_generator.h` | `fsm_friend_decl_cpp03.h` | FSM friend declarations | +| `fsm_cpp03_generator.h` | `fsm_cpp03.h` | Finite state machine implementation | +| `message_router_cpp03_generator.h` | `message_router_cpp03.h` | Message router | +| `message_packet_cpp03_generator.h` | `message_packet_cpp03.h` | Message packet | +| `largest_type_cpp03_generator.h` | `largest_type_cpp03.h` | Largest type metafunction | +| `largest_alignment_cpp03_generator.h` | `largest_alignment_cpp03.h` | Largest alignment metafunction | +| `largest_cpp03_generator.h` | `largest_cpp03.h` | Largest type/size utilities | +| `smallest_cpp03_generator.h` | `smallest_cpp03.h` | Smallest type/size utilities | +| `type_traits_cpp03_generator.h` | `type_traits_cpp03.h` | Type traits (`is_one_of`, etc.) | +| `type_lookup_cpp03_generator.h` | `type_lookup_cpp03.h` | Type lookup metafunction | +| `type_select_cpp03_generator.h` | `type_select_cpp03.h` | Type selection metafunction | +| `variant_pool_cpp03_generator.h` | `variant_pool_cpp03.h` | Variant pool | + +--- + +## Generator Parameters + +Cog variables control how many template parameter overloads are generated: + +| Variable | Default | Used by | +|---|---|---| +| `Handlers` | 16 | FSM and message router generators | +| `NTypes` | 16 | Type utility generators (largest, smallest, lookup, select, variant pool) | +| `IsOneOf` | 16 | Type traits generator (`is_one_of`) | + +These defaults produce overloads supporting up to 16 types or handlers, +which is sufficient for most embedded applications while keeping compile +times reasonable. + +--- + +## Prerequisites + +* **Python 3** +* **cogapp** – install via: + + ```bash + pip install cogapp + ``` + +--- + +## Regenerating Headers + +### Using the batch scripts (Windows) + +Each generator has a corresponding `.bat` file in `include/etl/generators/`: + +```bat +cd include/etl/generators +generate.bat # Regenerate all headers +generate_fsm.bat # Regenerate FSM headers only +generate_smallest.bat # Regenerate smallest_cpp03.h only +# etc. +``` + +### Manual invocation + +Run Cog directly from the `include/etl/generators/` directory: + +```bash +cd include/etl/generators + +# Example: regenerate smallest_cpp03.h +python3 -m cogapp -d -e -o../private/smallest_cpp03.h -DNTypes=16 smallest_cpp03_generator.h + +# Example: regenerate fsm_cpp03.h +python3 -m cogapp -d -e -o../private/fsm_cpp03.h -DHandlers=16 fsm_cpp03_generator.h +``` + +Cog options used: + +| Option | Meaning | +|---|---| +| `-d` | Delete the generator markers from output | +| `-e` | Warn if the input file has no generator markers | +| `-o` | Write output to the specified file | +| `-D=` | Define a Cog variable | + +### Regenerating all headers + +The `generate.bat` script regenerates every header: + +```bash +cd include/etl/generators +./generate.bat # Windows +# or run the commands manually on Linux/macOS +``` + +On Linux/macOS you can run the commands from `generate.bat` directly in +your shell (they are standard `python3 -m cogapp` invocations). + +--- + +## Verifying Generators + +After modifying a generator template, verify the output matches the +committed file: + +```bash +python3 scripts/generator_test.py +``` + +This script: + +1. Runs Cog on every `*_generator.h` file. +2. Compares each output against the corresponding file in + `include/etl/private/`. +3. Reports success or failure. + +The `generator.yml` GitHub Actions workflow runs this automatically on +every push and pull request. + +--- + +## How Generators Work + +A generator template contains standard C++ code interspersed with Cog +directives. For example, from `smallest_cpp03_generator.h`: + +```cpp +/*[[[cog +import cog +cog.outl("template " % int(NTypes)) +]]]*/ +// Generated code appears here after running Cog +/*[[[end]]]*/ +``` + +When Cog processes this file with `-DNTypes=16`, the Python code executes +and outputs the expanded template parameter list supporting 16 types. + +--- + +## Adding a New Generator + +1. Create `include/etl/generators/_cpp03_generator.h` with Cog + directives. +2. Add a corresponding entry to `generate.bat`. +3. Run `generate.bat` (or the equivalent Cog command) to produce + `include/etl/private/_cpp03.h`. +4. Commit both the generator and the generated output. +5. Verify with `python3 scripts/generator_test.py`. + +--- + +## Troubleshooting + +| Problem | Solution | +|---|---| +| `ModuleNotFoundError: No module named 'cogapp'` | Install Cog: `pip install cogapp` | +| Generator output differs from committed file | Regenerate and commit the updated output | +| Need more than 16 types/handlers | Change `-DNTypes=` or `-DHandlers=` and regenerate | diff --git a/docs/testing.md b/docs/testing.md new file mode 100644 index 00000000..c6773f6f --- /dev/null +++ b/docs/testing.md @@ -0,0 +1,412 @@ +# Testing ETL + +This document describes how to build and run the ETL test suite locally, +inside Dev Containers, and in CI. + +## Table of Contents + +1. [Prerequisites](#prerequisites) +2. [Running Tests Locally (`test/run-tests.sh`)](#running-tests-locally) +3. [Syntax Checks (`test/run-syntax-checks.sh`)](#syntax-checks) +4. [Cross-Architecture Testing (`.devcontainer/run-tests.sh`)](#cross-architecture-testing) +5. [Dev Containers for Native Compilers](#dev-containers-for-native-compilers) +6. [CMake Options Reference](#cmake-options-reference) +7. [CI Checks (GitHub Actions)](#ci-checks-github-actions) +8. [Appveyor (Windows / MSVC)](#appveyor-windows--msvc) +9. [Code Coverage](#code-coverage) +10. [Generator Tests (`scripts/generator_test.py`)](#generator-tests) + +--- + +## Prerequisites + +* **CMake** ≥ 3.10 +* **GCC** and/or **Clang** (any version supported by the project) +* **Make** or **Ninja** (build backend) +* **Docker** (only needed for cross-architecture testing via `.devcontainer/run-tests.sh`) +* **QEMU user-mode** (installed automatically inside the cross-arch Docker images) + +The project is header-only, so there is no library to compile – the build +step compiles the test binary `etl_tests` which links against a bundled copy +of **UnitTest++**. + +--- + +## Running Tests Locally + +The main entry point for local testing is **`test/run-tests.sh`**. It +iterates over a matrix of compiler / configuration combinations, creates a +temporary `build-make` directory for each one, runs CMake + Make + CTest, +and reports coloured pass/fail output (also appended to `log.txt`). + +### Synopsis + +```bash +cd test +./run-tests.sh [Optimisation] [Threads] [Sanitizer] [Compiler] [Verbose] +``` + +| Argument | Values | Default | +|---|---|---| +| C++ Standard | `11`, `14`, `17`, `20`, `23`, or `all` | *(required)* | +| Optimisation | `0`, `1`, `2`, `3` | `0` | +| Threads | any positive integer | `4` | +| Sanitizer | `s` (enable) / `n` (disable) | `n` (disabled) | +| Compiler | `gcc`, `clang` | all compilers | +| Verbose | `v` (enable) / `n` (disable) | `n` (disabled) | + +### Examples + +```bash +# Run all C++17 tests with GCC only, optimisation -O0, 8 threads +./run-tests.sh 17 0 8 n gcc + +# Run every standard with both compilers, sanitizers enabled, verbose +./run-tests.sh all 0 4 s "" v +``` + +### What the script does + +For every selected C++ standard the script loops over a built-in list of +configurations (STL / No STL / Force C++03 / Non-virtual messages / …) for +each selected compiler. For every combination it: + +1. Creates a fresh `build-make` directory inside the configuration's source + subdirectory. +2. Invokes `cmake` with the appropriate `-D` flags (see + [CMake Options Reference](#cmake-options-reference)). +3. Builds via `cmake --build .` (parallel level controlled by + `CMAKE_BUILD_PARALLEL_LEVEL`). +4. Runs `ctest -V`. +5. Reports success or failure and removes the build directory. + +The script exits immediately on the first compilation or test failure. + +### Test configurations exercised + +| Compiler | Configuration | +|---|---| +| GCC | STL | +| GCC | STL – Non-virtual messages | +| GCC | STL – Force C++03 | +| GCC | No STL | +| GCC | No STL – Force C++03 | +| GCC | No STL – Builtin mem functions | +| Clang | STL | +| Clang | STL – Force C++03 | +| Clang | No STL | +| Clang | No STL – Force C++03 | +| Clang | No STL – Builtin mem functions | +| GCC / Clang | Initializer list test | +| GCC / Clang | Error macros – log_errors, exceptions, log_errors_and_exceptions, assert_function | + +--- + +## Syntax Checks + +The script **`test/run-syntax-checks.sh`** performs compilation-only syntax +checks across multiple C++ standards and configurations. Unlike +`run-tests.sh`, it **does not run the test binary** – it only verifies that +the code compiles successfully. This is useful for quickly validating that +header changes do not introduce compilation errors across the supported +standard/configuration matrix. + +### Synopsis + +```bash +cd test +./run-syntax-checks.sh [Threads] [Compiler] +``` + +| Argument | Values | Default | +|---|---|---| +| C++ Standard | `03`, `11`, `14`, `17`, `20`, `23`, or `a` (all) | *(required)* | +| Threads | any positive integer | `4` | +| Compiler | `gcc`, `clang` | all compilers | + +### Examples + +```bash +# Check C++17 syntax with GCC only, using 8 threads +./run-syntax-checks.sh 17 8 gcc + +# Check all standards with both compilers +./run-syntax-checks.sh a +``` + +### What the script does + +The script operates from the `test/syntax_check` directory and iterates over +the selected C++ standard(s). For each standard and compiler combination it: + +1. Creates fresh build directories (`bgcc` / `bclang`). +2. Invokes `cmake` with the appropriate `-D` flags for the configuration. +3. Builds via `cmake --build`. +4. Reports compilation success or failure (logged to `log.txt`). + +The script exits immediately on the first compilation failure. + +### Configurations checked per standard + +For each C++ standard the following configurations are compiled: + +| Compiler | Configuration | +|---|---| +| GCC | STL | +| GCC | No STL | +| GCC | STL – Built-in traits | +| GCC | No STL – Built-in traits | +| Clang | STL | +| Clang | No STL | +| Clang | STL – Built-in traits | +| Clang | No STL – Built-in traits | + +--- + +## Cross-Architecture Testing + +**`.devcontainer/run-tests.sh`** builds and runs the test suite for +non-x86_64 architectures using Docker and QEMU user-mode emulation. It is +designed to be run **from the project root**. + +### Supported architectures + +| Argument | Target | Endianness | QEMU binary | +|---|---|---|---| +| `armhf` | ARM hard-float (32-bit) | Little | `qemu-arm-static` | +| `i386` | x86 32-bit | Little | `qemu-i386-static` | +| `powerpc` | PowerPC 32-bit | Big | `qemu-ppc` | +| `riscv64` | RISC-V 64-bit | Little | `qemu-riscv64-static` | +| `s390x` | IBM Z (64-bit) | Big | `qemu-s390x-static` | + +### Synopsis + +```bash +# From the project root +.devcontainer/run-tests.sh +``` + +### How it works + +The script has two phases controlled by a second (internal) argument: + +1. **Outside the container** (no second argument): + * Builds a Docker image from `.devcontainer//Dockerfile`. + * Starts a container, bind-mounting the project at `/workspaces/etl`. + * Re-invokes itself *inside* the container with the `inside_container` + flag. + +2. **Inside the container** (`inside_container`): + * Creates `build-` and runs CMake with the appropriate cross- + compilation toolchain file + (`.devcontainer//toolchain-.cmake`). + * Builds with `cmake --build .` using all available cores. + * Runs the test suite via `ctest --output-on-failure`. + +The toolchain files set `CMAKE_CROSSCOMPILING_EMULATOR` so that CTest can +run the binary transparently through QEMU. + +### Example + +```bash +# Build & run the armhf test suite +.devcontainer/run-tests.sh armhf +``` + +The cross-arch containers build with the following fixed settings: + +* C++23, No STL, sanitizer off, optimisation -O0. + +--- + +## Dev Containers for Native Compilers + +The `.devcontainer/` directory also provides Dev Container definitions for a +wide range of **native** (x86_64) compiler versions. These are intended for +use with **VS Code Dev Containers** or **GitHub Codespaces**. + +| Directory | Compiler | +|---|---| +| `gcc09` – `gcc15` | GCC 9 through 15 | +| `clang7` – `clang21` | Clang 7 through 21 | + +Each subdirectory contains a `devcontainer.json` that references the shared +`Dockerfile` (`.devcontainer/Dockerfile`) and passes the appropriate base +Docker image via the `BASE_IMAGE_NAME` build argument (e.g. `gcc:15`). + +The default Dev Container (`.devcontainer/devcontainer.json`) uses the +Microsoft C++ dev-container base image. + +To use one of these containers: + +1. Open the repository in VS Code. +2. **Ctrl+Shift+P → Dev Containers: Reopen in Container** and select the + desired configuration (e.g. *Gcc 15*). +3. Use `test/run-tests.sh` inside the container as described above. + +--- + +## CMake Options Reference + +When invoking CMake for the test suite (source directory is `test/`), the +following `-D` options control the build: + +| Option | Type | Description | +|---|---|---| +| `BUILD_TESTS` | `BOOL` | Must be `ON` to compile the test binary. | +| `NO_STL` | `BOOL` | Build without the C++ Standard Library. | +| `ETL_CXX_STANDARD` | `STRING` | C++ standard: `11`, `14`, `17`, `20`, `23`. | +| `ETL_OPTIMISATION` | `STRING` | Compiler optimisation flag, e.g. `-O0`. | +| `ETL_ENABLE_SANITIZER` | `BOOL` | Enable address / undefined-behaviour sanitizers. | +| `ETL_USE_TYPE_TRAITS_BUILTINS` | `BOOL` | Use compiler built-in type traits. | +| `ETL_USER_DEFINED_TYPE_TRAITS` | `BOOL` | Use user-defined type traits. | +| `ETL_FORCE_TEST_CPP03_IMPLEMENTATION` | `BOOL` | Force the C++03 code paths even on newer standards. | +| `ETL_MESSAGES_ARE_NOT_VIRTUAL` | `BOOL` | Use non-virtual message types. | +| `ETL_USE_BUILTIN_MEM_FUNCTIONS` | `BOOL` | Use built-in memory functions in No-STL mode. | +| `CMAKE_TOOLCHAIN_FILE` | `PATH` | Toolchain file for cross-compilation. | + +### Minimal manual build example + +```bash +cd test +mkdir build && cd build +cmake -DBUILD_TESTS=ON -DNO_STL=OFF -DETL_CXX_STANDARD=20 .. +cmake --build . -j$(nproc) +ctest -V +``` + +--- + +## CI Checks (GitHub Actions) + +Every push or pull request to `master`, `development`, or `pull-request/*` +branches triggers a comprehensive set of GitHub Actions workflows defined in +`.github/workflows/`. + +### Workflow matrix + +| Workflow file | Compiler | Standard | Notes | +|---|---|---|---| +| `gcc-c++11.yml` | GCC | C++11 | STL, No STL, Force C++03 | +| `gcc-c++14.yml` | GCC | C++14 | STL, No STL, Force C++03 | +| `gcc-c++17.yml` | GCC | C++17 | STL, No STL, Force C++03 | +| `gcc-c++20.yml` | GCC | C++20 | STL, No STL, Force C++03 | +| `gcc-c++23.yml` | GCC | C++23 | STL, No STL, Force C++03 | +| `clang-c++11.yml` | Clang | C++11 | STL, No STL, Force C++03 | +| `clang-c++14.yml` | Clang | C++14 | STL, No STL, Force C++03 | +| `clang-c++17.yml` | Clang | C++17 | STL, No STL, Force C++03 | +| `clang-c++20.yml` | Clang | C++20 | STL, No STL, Force C++03 | +| `clang-c++23.yml` | Clang | C++23 | STL, No STL, Force C++03 | +| `gcc-syntax-checks.yml` | GCC | C++03 – C++23 | Compilation-only syntax checks (no tests run) | +| `clang-syntax-checks.yml` | Clang | C++03 – C++23 | Compilation-only syntax checks (no tests run) | +| `msvc.yml` | MSVC 2022 | C++17 | Windows, STL & No STL | +| `gcc-c++23-armhf.yml` | GCC cross | C++23 | armhf via QEMU | +| `gcc-c++23-i386.yml` | GCC cross | C++23 | i386 via QEMU | +| `gcc-c++23-powerpc.yml` | GCC cross | C++23 | powerpc via QEMU | +| `gcc-c++23-riscv64.yml` | GCC cross | C++23 | RISC-V 64 via QEMU | +| `gcc-c++23-s390x.yml` | GCC cross | C++23 | s390x via QEMU | +| `coverage.yml` | GCC | — | Generates lcov coverage report, deploys to GitHub Pages | +| `generator.yml` | — | — | Runs the code generator | +| `platformio-update.yml` | — | — | PlatformIO registry update | + +### Typical CI job structure + +Each compiler/standard workflow follows the same pattern: + +1. **Checkout** – `actions/checkout@v4`. +2. **Build** – set `CC`/`CXX`, call `cmake` with the appropriate `-D` flags, + then `make -j`. +3. **Run tests** – execute `./test/etl_tests -v` (or `ctest -V` for cross- + arch jobs). + +The cross-architecture CI jobs additionally install a cross-compiler +toolchain and QEMU inside a `debian:trixie` container, use the matching +toolchain file from `.devcontainer//`, and run tests via CTest (which +delegates to QEMU through `CMAKE_CROSSCOMPILING_EMULATOR`). + +### Branches tested + +* `master` +* `development` +* `pull-request/*` + +All workflows run on both `push` and `pull_request` events (types: opened, +synchronize, reopened). + +--- + +## Appveyor (Windows / MSVC) + +The `appveyor.yml` at the repository root provides additional Windows CI +using **Visual Studio 2022**. It builds the `master` branch only. + +Configurations tested: + +* Debug MSVC C++14 +* Debug MSVC C++14 – No STL +* Debug MSVC C++17 +* Debug MSVC C++17 – No STL +* Debug MSVC C++20 +* Debug MSVC C++20 – No STL + +The build uses the VS 2022 solution file at `test/vs2022/etl.vcxproj`. + +--- + +## Code Coverage + +The `coverage.yml` GitHub Actions workflow generates an **lcov** coverage +report: + +1. Runs `test/run-coverage.sh` which builds and tests with GCC coverage + flags. +2. Uploads the HTML report as a build artifact (retained for 30 days). +3. On pushes to `master`, deploys the report to **GitHub Pages**. + +To generate coverage locally: + +```bash +cd test +./run-coverage.sh +# Open test/build-coverage/coverage/index.html +``` + +--- + +## Generator Tests + +The script **`scripts/generator_test.py`** verifies that the code generators +in `include/etl/generators/` produce output matching the checked-in header +files in `include/etl/private/`. + +ETL uses [Cog](https://nedbatchelder.com/code/cog/) to generate certain +repetitive header files (e.g. `delegate.h`, `message_packet.h`). The +generator templates live in `include/etl/generators/*_generator.h` and the +generated output is committed to `include/etl/private/*.h`. This test +ensures the two stay in sync. + +### Prerequisites + +* **Python 3** +* **cogapp** – install via `pip install cogapp` + +### Synopsis + +```bash +python3 scripts/generator_test.py +``` + +### What the script does + +1. Iterates over every `*_generator.h` file in `include/etl/generators/`. +2. Runs Cog on each generator, outputting to `build/generator_tmp/`. +3. Compares each generated file against the corresponding file in + `include/etl/private/`. +4. Reports success if all files match, or failure if any differ. + +The script exits with code `0` on success and `1` on failure. + +### CI integration + +The `generator.yml` GitHub Actions workflow runs this script automatically +on pushes and pull requests to verify generator consistency. diff --git a/include/etl/algorithm.h b/include/etl/algorithm.h index 162deaf9..b1d570e2 100644 --- a/include/etl/algorithm.h +++ b/include/etl/algorithm.h @@ -558,7 +558,8 @@ namespace etl { while (first != last) { - *first = value; + // This cast is necessary because the signedness can differ + *first = static_cast::value_type>(value); ++first; } } diff --git a/include/etl/bip_buffer_spsc_atomic.h b/include/etl/bip_buffer_spsc_atomic.h index 0901af80..783e3ea6 100644 --- a/include/etl/bip_buffer_spsc_atomic.h +++ b/include/etl/bip_buffer_spsc_atomic.h @@ -404,7 +404,7 @@ namespace etl //************************************************************************* void read_commit(const span& reserve) { - size_type rindex = etl::distance(p_buffer, reserve.data()); + size_type rindex = static_cast(etl::distance(p_buffer, reserve.data())); apply_read_reserve(rindex, reserve.size()); } @@ -438,7 +438,7 @@ namespace etl //************************************************************************* void write_commit(const span& reserve) { - size_type windex = etl::distance(p_buffer, reserve.data()); + size_type windex = static_cast(etl::distance(p_buffer, reserve.data())); apply_write_reserve(windex, reserve.size()); } diff --git a/include/etl/ipool.h b/include/etl/ipool.h index c71254bf..e53c4014 100644 --- a/include/etl/ipool.h +++ b/include/etl/ipool.h @@ -644,7 +644,7 @@ namespace etl // in debug. #if ETL_IS_DEBUG_BUILD // Is the address on a valid object boundary? - bool is_valid_address = ((distance % Item_Size) == 0); + bool is_valid_address = ((static_cast(distance) % Item_Size) == 0); #else bool is_valid_address = true; #endif diff --git a/include/etl/iterator.h b/include/etl/iterator.h index 8a09e7c0..8394c5f9 100644 --- a/include/etl/iterator.h +++ b/include/etl/iterator.h @@ -959,11 +959,16 @@ namespace etl ETL_CONSTANT bool is_random_access_iterator_concept::value; #if ETL_NOT_USING_STL || ETL_CPP11_NOT_SUPPORTED + #if ETL_CPP11_SUPPORTED //***************************************************************************** /// Get the 'begin' iterator. + /// Note: Contains SFINAE guard, ensuring they only participate in overload + /// resolution when TContainer actually has the corresponding member function. + /// This prevents ADL from matching these templates when std::ranges::begin + /// performs an unqualified call on etl:: iterator types. ///\ingroup container //***************************************************************************** - template + template ().begin())> > ETL_CONSTEXPR typename TContainer::iterator begin(TContainer& container) { return container.begin(); @@ -973,7 +978,7 @@ namespace etl /// Get the 'begin' const_iterator for a container. ///\ingroup container //***************************************************************************** - template + template ().begin())> > ETL_CONSTEXPR typename TContainer::const_iterator begin(const TContainer& container) { return container.begin(); @@ -983,7 +988,7 @@ namespace etl /// Get the 'begin' const_iterator for a container. ///\ingroup container //***************************************************************************** - template + template ().cbegin())> > ETL_CONSTEXPR typename TContainer::const_iterator cbegin(const TContainer& container) { return container.cbegin(); @@ -993,7 +998,7 @@ namespace etl /// Get the 'end' iterator for a container. ///\ingroup container //***************************************************************************** - template + template ().end())> > ETL_CONSTEXPR typename TContainer::iterator end(TContainer& container) { return container.end(); @@ -1003,7 +1008,7 @@ namespace etl /// Get the 'end' const_iterator for a container. ///\ingroup container //***************************************************************************** - template + template ().end())> > ETL_CONSTEXPR typename TContainer::const_iterator end(const TContainer& container) { return container.end(); @@ -1013,11 +1018,73 @@ namespace etl /// Get the 'end' const_iterator for a container. ///\ingroup container //***************************************************************************** - template + template ().cend())> > ETL_CONSTEXPR typename TContainer::const_iterator cend(const TContainer& container) { return container.cend(); } + #else + // C++03 fallback: no SFINAE guards needed since std::ranges does not exist. + //***************************************************************************** + /// Get the 'begin' iterator. + ///\ingroup container + //***************************************************************************** + template + typename TContainer::iterator begin(TContainer& container) + { + return container.begin(); + } + + //***************************************************************************** + /// Get the 'begin' const_iterator for a container. + ///\ingroup container + //***************************************************************************** + template + typename TContainer::const_iterator begin(const TContainer& container) + { + return container.begin(); + } + + //***************************************************************************** + /// Get the 'begin' const_iterator for a container. + ///\ingroup container + //***************************************************************************** + template + typename TContainer::const_iterator cbegin(const TContainer& container) + { + return container.cbegin(); + } + + //***************************************************************************** + /// Get the 'end' iterator for a container. + ///\ingroup container + //***************************************************************************** + template + typename TContainer::iterator end(TContainer& container) + { + return container.end(); + } + + //***************************************************************************** + /// Get the 'end' const_iterator for a container. + ///\ingroup container + //***************************************************************************** + template + typename TContainer::const_iterator end(const TContainer& container) + { + return container.end(); + } + + //***************************************************************************** + /// Get the 'end' const_iterator for a container. + ///\ingroup container + //***************************************************************************** + template + typename TContainer::const_iterator cend(const TContainer& container) + { + return container.cend(); + } + #endif //***************************************************************************** /// Get the 'begin' pointer for an array. @@ -1081,11 +1148,13 @@ namespace etl #endif #if ETL_NOT_USING_STL || ETL_CPP14_NOT_SUPPORTED + #if ETL_CPP11_SUPPORTED //***************************************************************************** /// Get the 'begin' reverse_iterator for a container. + /// Note: Contains SFINAE guard (see begin/end above for rationale). ///\ingroup container //***************************************************************************** - template + template ().rbegin())> > ETL_CONSTEXPR typename TContainer::reverse_iterator rbegin(TContainer& container) { return container.rbegin(); @@ -1095,7 +1164,7 @@ namespace etl /// Get the 'begin' reverse_iterator for a container. ///\ingroup container //***************************************************************************** - template + template ().rbegin())> > ETL_CONSTEXPR typename TContainer::const_reverse_iterator rbegin(const TContainer& container) { return container.rbegin(); @@ -1105,7 +1174,7 @@ namespace etl /// Get the 'begin' reverse_iterator for a container. ///\ingroup container //***************************************************************************** - template + template ().crbegin())> > ETL_CONSTEXPR typename TContainer::const_reverse_iterator crbegin(const TContainer& container) { return container.crbegin(); @@ -1115,7 +1184,7 @@ namespace etl /// Get the 'end' reverse_iterator for a container. ///\ingroup container //***************************************************************************** - template + template ().rend())> > ETL_CONSTEXPR typename TContainer::reverse_iterator rend(TContainer& container) { return container.rend(); @@ -1125,7 +1194,7 @@ namespace etl /// Get the 'end' reverse_iterator for a container. ///\ingroup container //***************************************************************************** - template + template ().rend())> > ETL_CONSTEXPR typename TContainer::const_reverse_iterator rend(const TContainer& container) { return container.rend(); @@ -1135,11 +1204,73 @@ namespace etl /// Get the 'end' reverse_iterator for a container. ///\ingroup container //***************************************************************************** - template + template ().crend())> > ETL_CONSTEXPR typename TContainer::const_reverse_iterator crend(const TContainer& container) { return container.crend(); } + #else + // C++03 fallback: no SFINAE guards needed since std::ranges does not exist. + //***************************************************************************** + /// Get the 'begin' reverse_iterator for a container. + ///\ingroup container + //***************************************************************************** + template + typename TContainer::reverse_iterator rbegin(TContainer& container) + { + return container.rbegin(); + } + + //***************************************************************************** + /// Get the 'begin' reverse_iterator for a container. + ///\ingroup container + //***************************************************************************** + template + typename TContainer::const_reverse_iterator rbegin(const TContainer& container) + { + return container.rbegin(); + } + + //***************************************************************************** + /// Get the 'begin' reverse_iterator for a container. + ///\ingroup container + //***************************************************************************** + template + typename TContainer::const_reverse_iterator crbegin(const TContainer& container) + { + return container.crbegin(); + } + + //***************************************************************************** + /// Get the 'end' reverse_iterator for a container. + ///\ingroup container + //***************************************************************************** + template + typename TContainer::reverse_iterator rend(TContainer& container) + { + return container.rend(); + } + + //***************************************************************************** + /// Get the 'end' reverse_iterator for a container. + ///\ingroup container + //***************************************************************************** + template + typename TContainer::const_reverse_iterator rend(const TContainer& container) + { + return container.rend(); + } + + //***************************************************************************** + /// Get the 'end' reverse_iterator for a container. + ///\ingroup container + //***************************************************************************** + template + typename TContainer::const_reverse_iterator crend(const TContainer& container) + { + return container.crend(); + } + #endif //***************************************************************************** /// Get the 'begin' reverse_iterator for an array. diff --git a/include/etl/numeric.h b/include/etl/numeric.h index 633755e5..cc8752d3 100644 --- a/include/etl/numeric.h +++ b/include/etl/numeric.h @@ -130,11 +130,11 @@ namespace etl { if (a > b) { - return b + (etl::distance(b, a) / 2U); + return b + (etl::distance(b, a) / 2); } else { - return a + (etl::distance(a, b) / 2U); + return a + (etl::distance(a, b) / 2); } } @@ -151,11 +151,11 @@ namespace etl { if (a > b) { - return b + (etl::distance(b, a) / 2U); + return b + (etl::distance(b, a) / 2); } else { - return a + (etl::distance(a, b) / 2U); + return a + (etl::distance(a, b) / 2); } } @@ -172,7 +172,7 @@ namespace etl || etl::is_same::iterator_category, ETL_OR_STD::bidirectional_iterator_tag>::value)), int>::type = 0) { - etl::advance(a, etl::distance(a, b) / 2U); + etl::advance(a, etl::distance(a, b) / 2); return a; } diff --git a/include/etl/private/bitset_new.h b/include/etl/private/bitset_new.h index 89d4a0a8..19d21794 100644 --- a/include/etl/private/bitset_new.h +++ b/include/etl/private/bitset_new.h @@ -1078,7 +1078,7 @@ namespace etl /// Extract an value from multiple elements. //************************************************************************* template - static ETL_CONSTEXPR14 typename etl::make_unsigned::type extract_from_multiple_elements(const element_type* pbuffer, int element_index, + static ETL_CONSTEXPR14 typename etl::make_unsigned::type extract_from_multiple_elements(const element_type* pbuffer, size_t element_index, size_t active_bits_in_msb, size_t length) ETL_NOEXCEPT { typedef typename etl::make_unsigned::type unsigned_t; @@ -1133,8 +1133,8 @@ namespace etl unsigned_t value(0); - const int Msb_Element_Index = (position + length - 1) >> etl::log2::value; - const int Lsb_Element_Index = position >> etl::log2::value; + const size_t Msb_Element_Index = (position + length - 1) >> etl::log2::value; + const size_t Lsb_Element_Index = position >> etl::log2::value; // Is the value contained within one element? if (Msb_Element_Index == Lsb_Element_Index) @@ -1150,7 +1150,7 @@ namespace etl size_t active_bits_in_msb = (position + length) - (static_cast(Msb_Element_Index) * Bits_Per_Element); // Start with index of the element containing the msb. - int element_index = Msb_Element_Index; + size_t element_index = Msb_Element_Index; value = extract_from_multiple_elements(pbuffer, element_index, active_bits_in_msb, length); } @@ -1169,7 +1169,7 @@ namespace etl { typedef typename etl::make_unsigned::type unsigned_t; - const int Element_Index = (Position + Length - 1) >> etl::log2::value; + const size_t Element_Index = (Position + Length - 1) >> etl::log2::value; const unsigned_t Mask = etl::lsb_mask::value; const unsigned_t Shift = Position % Bits_Per_Element; @@ -1186,7 +1186,7 @@ namespace etl extract_from_buffer(const_pointer pbuffer) { // Start with index of the element containing the msb. - const int Msb_Element_Index = (Position + Length - 1) >> etl::log2::value; + const size_t Msb_Element_Index = (Position + Length - 1) >> etl::log2::value; // Get the number of active bits in the first element const size_t Active_Bits_In_Msb = ((Position + Length - 1) % Bits_Per_Element) + 1; diff --git a/include/etl/private/diagnostic_sign_conversion_push.h b/include/etl/private/diagnostic_sign_conversion_push.h new file mode 100644 index 00000000..50c0532e --- /dev/null +++ b/include/etl/private/diagnostic_sign_conversion_push.h @@ -0,0 +1,44 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2025 John Wellbelove + +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. +******************************************************************************/ + +/* + * The header include guard has been intentionally omitted. + * This file is intended to evaluated multiple times by design. + */ + +#if defined(__GNUC__) && !defined(__clang__) && !defined(__llvm__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wsign-conversion" +#endif + +#if defined(__clang__) || defined(__llvm__) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wsign-conversion" +#endif diff --git a/include/etl/vector.h b/include/etl/vector.h index ba10ac79..f014ab2f 100644 --- a/include/etl/vector.h +++ b/include/etl/vector.h @@ -479,7 +479,9 @@ namespace etl { ETL_ASSERT_CHECK_PUSH_POP(size() != CAPACITY, ETL_ERROR(vector_full)); + #include "private/diagnostic_sign_conversion_push.h" ::new (p_end) T(etl::forward(args)...); + #include "private/diagnostic_pop.h" ++p_end; ETL_INCREMENT_DEBUG_COUNT; return back(); @@ -668,7 +670,9 @@ namespace etl (*position_).~T(); } + #include "private/diagnostic_sign_conversion_push.h" ::new (p) T(etl::forward(args)...); + #include "private/diagnostic_pop.h" return position_; } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 9f325bb9..99792fce 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -385,6 +385,7 @@ option(ETL_NO_STL "No STL" OFF) set(EXTRA_COMPILE_OPTIONS "" CACHE STRING "Additional compiler options") set(EXTRA_LINK_OPTIONS "" CACHE STRING "Additional linker options") set(EXTRA_LINK_LIBS "" CACHE STRING "Additional libraries to link") +set(EXTRA_TESTING_FLAGS "" CACHE STRING "Additional testing flags for ctest") if (ETL_CXX_STANDARD MATCHES "98") message(STATUS "Compiling for C++98") @@ -538,7 +539,7 @@ target_link_libraries(etl_tests PRIVATE UnitTestpp ${EXTRA_LINK_LIBS}) enable_testing() # Enable the 'make test' CMake target using the executable defined above -add_test(NAME etl_unit_tests COMMAND etl_tests) +add_test(NAME etl_unit_tests COMMAND etl_tests ${EXTRA_TESTING_FLAGS}) # Since ctest will only show you the results of the single executable # define a target that will output all of the failing or passing tests diff --git a/test/run-tests.sh b/test/run-tests.sh index 06e39400..d5fd0567 100755 --- a/test/run-tests.sh +++ b/test/run-tests.sh @@ -2,6 +2,8 @@ shopt -s xpg_echo +set -e + clear export ASAN_OPTIONS=symbol_line=1 @@ -54,7 +56,7 @@ PrintHelp() echo "$HelpColour" echo "----------------------------------------------------------------------------------------------------------" echo " Syntax : ./run-tests.sh " - echo " C++ Standard : 11, 14, 17, 20 or 23 " + echo " C++ Standard : 11, 14, 17, 20, 23 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 " @@ -115,15 +117,17 @@ TestsCompleted() # Set the language standard. #****************************************************************************** if [ "$1" = "11" ]; then - cxx_standard="11" + cxx_standards="11" elif [ "$1" = "14" ]; then - cxx_standard="14" + cxx_standards="14" elif [ "$1" = "17" ]; then - cxx_standard="17" + cxx_standards="17" elif [ "$1" = "20" ]; then - cxx_standard="20" + cxx_standards="20" elif [ "$1" = "23" ]; then - cxx_standard="23" + cxx_standards="23" +elif [ "$1" = "all" ]; then + cxx_standards="11 14 17 20 23" else PrintHelp exit @@ -180,10 +184,10 @@ fi #****************************************************************************** if [ "$6" = "v" ]; then verbose="On" - verbose_flag="-v" + verbose_cmake_flag="-DEXTRA_TESTING_FLAGS=-v" else verbose="Off" - verbose_flag="" + verbose_cmake_flag="" fi #****************************************************************************** @@ -196,66 +200,66 @@ etl_version=$(echo $etl_version_raw | sed -e 's/\r//g') # Remove trailing \r # Get the compiler versions #****************************************************************************** -while read i ; do - CC=`echo $i | cut -d, -f1 | sed -e 's/ *$//'` - MSG=`echo $i | cut -d, -f2 | sed -e 's/ *$//'` - DIR=`echo $i | cut -d, -f3 | sed -e 's/ *$//'` - CMD=`echo $i | cut -d, -f4 | sed -e 's/ *$//'` +for cxx_standard in $cxx_standards ; do + while read i ; do + CC=`echo $i | cut -d, -f1 | sed -e 's/ *$//'` + MSG=`echo $i | cut -d, -f2 | sed -e 's/ *$//'` + DIR=`echo $i | cut -d, -f3 | sed -e 's/ *$//'` + CMD=`echo $i | cut -d, -f4 | sed -e 's/ *$//'` - if [ "$compiler_enabled" = "$CC" ] || [ "$compiler_enabled" = "All compilers" ]; then - if [ "$CC" = "gcc" ] ; then - compiler=$(g++ --version | grep g++) - else - compiler=$(clang++ --version | grep clang) + if [ "$compiler_enabled" = "$CC" ] || [ "$compiler_enabled" = "All compilers" ]; then + if [ "$CC" = "gcc" ] ; then + compiler=$(g++ --version | grep g++) + else + compiler=$(clang++ --version | grep clang) + fi + OLD_DIR=`pwd` + cd $DIR + mkdir -p build-make || exit 1 + cd build-make || exit 1 + echo "ETL Tests" > log.txt + SetConfigurationName "$MSG" + PrintHeader + $CMD + if cmake --build .; then + PassedCompilation + else + FailedCompilation + exit 1 + fi + if ctest -V; then + PassedTests + else + FailedTests + exit 1 + fi + cd .. + rm -rf build-make + cd $OLD_DIR fi - OLD_DIR=`pwd` - cd $DIR - mkdir -p build-make || exit 1 - cd build-make || exit 1 - echo "ETL Tests" > log.txt - SetConfigurationName "$MSG" - PrintHeader - $CMD - cmake --build . - if [ $? -eq 0 ]; then - PassedCompilation - else - FailedCompilation - exit $? - fi - ./etl_tests $verbose_flag - if [ $? -eq 0 ]; then - PassedTests - else - FailedTests - exit $? - fi - cd .. - rm -rf build-make - cd $OLD_DIR - fi -done <<-EOF -gcc ,STL ,.,cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize -DETL_MESSAGES_ARE_NOT_VIRTUAL=OFF .. -gcc ,STL - Non-virtual messages,.,cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize -DETL_MESSAGES_ARE_NOT_VIRTUAL=ON .. -gcc ,STL - Force C++03 ,.,cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize -DETL_MESSAGES_ARE_NOT_VIRTUAL=OFF .. -gcc ,No STL ,.,cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize -DETL_MESSAGES_ARE_NOT_VIRTUAL=OFF .. -gcc ,No STL - Force C++03 ,.,cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize -DETL_MESSAGES_ARE_NOT_VIRTUAL=OFF .. -gcc ,No STL - Builtin mem functions ,.,cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize -DETL_MESSAGES_ARE_NOT_VIRTUAL=OFF -DETL_USE_BUILTIN_MEM_FUNCTIONS=ON .. -clang,STL ,.,cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize -DETL_MESSAGES_ARE_NOT_VIRTUAL=OFF .. -clang,STL - Force C++03 ,.,cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize -DETL_MESSAGES_ARE_NOT_VIRTUAL=OFF .. -clang,No STL ,.,cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize -DETL_MESSAGES_ARE_NOT_VIRTUAL=OFF .. -clang,No STL - Force C++03 ,.,cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize -DETL_MESSAGES_ARE_NOT_VIRTUAL=OFF .. -clang,No STL - Builtin mem functions ,.,cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize -DETL_MESSAGES_ARE_NOT_VIRTUAL=OFF -DETL_USE_BUILTIN_MEM_FUNCTIONS=ON .. -gcc ,Initializer list test ,etl_initializer_list,cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize .. -clang,Initializer list test ,etl_initializer_list,cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize .. -gcc ,Error macros 'log_errors' test,etl_error_handler/log_errors ,cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize .. -gcc ,Error macros 'exceptions' test,etl_error_handler/exceptions ,cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize .. -gcc ,Error macros 'log_errors and exceptions' test,etl_error_handler/log_errors_and_exceptions,cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize .. -gcc ,Error macros 'assert function' test,etl_error_handler/assert_function ,cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize .. -clang,Error macros 'log_errors' test,etl_error_handler/log_errors ,cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize .. -clang,Error macros 'exceptions' test,etl_error_handler/exceptions ,cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize .. -clang,Error macros 'log_errors and exceptions' test,etl_error_handler/log_errors_and_exceptions,cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize .. -clang,Error macros 'assert function' test,etl_error_handler/assert_function ,cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize .. + done <<-EOF +gcc ,STL ,.,cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize -DETL_MESSAGES_ARE_NOT_VIRTUAL=OFF $verbose_cmake_flag .. +gcc ,STL - Non-virtual messages,.,cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize -DETL_MESSAGES_ARE_NOT_VIRTUAL=ON $verbose_cmake_flag .. +gcc ,STL - Force C++03 ,.,cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize -DETL_MESSAGES_ARE_NOT_VIRTUAL=OFF $verbose_cmake_flag .. +gcc ,No STL ,.,cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize -DETL_MESSAGES_ARE_NOT_VIRTUAL=OFF $verbose_cmake_flag .. +gcc ,No STL - Force C++03 ,.,cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize -DETL_MESSAGES_ARE_NOT_VIRTUAL=OFF $verbose_cmake_flag .. +gcc ,No STL - Builtin mem functions ,.,cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize -DETL_MESSAGES_ARE_NOT_VIRTUAL=OFF -DETL_USE_BUILTIN_MEM_FUNCTIONS=ON $verbose_cmake_flag .. +clang,STL ,.,cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize -DETL_MESSAGES_ARE_NOT_VIRTUAL=OFF $verbose_cmake_flag .. +clang,STL - Force C++03 ,.,cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize -DETL_MESSAGES_ARE_NOT_VIRTUAL=OFF $verbose_cmake_flag .. +clang,No STL ,.,cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize -DETL_MESSAGES_ARE_NOT_VIRTUAL=OFF $verbose_cmake_flag .. +clang,No STL - Force C++03 ,.,cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize -DETL_MESSAGES_ARE_NOT_VIRTUAL=OFF $verbose_cmake_flag .. +clang,No STL - Builtin mem functions ,.,cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize -DETL_MESSAGES_ARE_NOT_VIRTUAL=OFF -DETL_USE_BUILTIN_MEM_FUNCTIONS=ON $verbose_cmake_flag .. +gcc ,Initializer list test ,etl_initializer_list,cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize $verbose_cmake_flag .. +clang,Initializer list test ,etl_initializer_list,cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize $verbose_cmake_flag .. +gcc ,Error macros 'log_errors' test,etl_error_handler/log_errors ,cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize $verbose_cmake_flag .. +gcc ,Error macros 'exceptions' test,etl_error_handler/exceptions ,cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize $verbose_cmake_flag .. +gcc ,Error macros 'log_errors and exceptions' test,etl_error_handler/log_errors_and_exceptions,cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize $verbose_cmake_flag .. +gcc ,Error macros 'assert function' test,etl_error_handler/assert_function ,cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize $verbose_cmake_flag .. +clang,Error macros 'log_errors' test,etl_error_handler/log_errors ,cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize $verbose_cmake_flag .. +clang,Error macros 'exceptions' test,etl_error_handler/exceptions ,cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize $verbose_cmake_flag .. +clang,Error macros 'log_errors and exceptions' test,etl_error_handler/log_errors_and_exceptions,cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize $verbose_cmake_flag .. +clang,Error macros 'assert function' test,etl_error_handler/assert_function ,cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize $verbose_cmake_flag .. EOF +done TestsCompleted diff --git a/test/test_bit_stream.cpp b/test/test_bit_stream.cpp index 2c515224..d7e1cdbc 100644 --- a/test/test_bit_stream.cpp +++ b/test/test_bit_stream.cpp @@ -869,7 +869,7 @@ namespace TEST(put_get_multiple_full_size) { char c1 = 90; - char c2 = -91; + char c2 = static_cast(-91); unsigned short s1 = 23205; unsigned short s2 = 42330; int32_t i1 = 1520786085L; // 0x5AA55AA5 diff --git a/test/test_bit_stream_writer_big_endian.cpp b/test/test_bit_stream_writer_big_endian.cpp index 893a5f04..c22e66db 100644 --- a/test/test_bit_stream_writer_big_endian.cpp +++ b/test/test_bit_stream_writer_big_endian.cpp @@ -614,7 +614,7 @@ namespace TEST(test_write_multiple_full_size) { char c1 = 90; // 0x5A - char c2 = -91; // 0xA5 + char c2 = static_cast(-91); // 0xA5 unsigned short s1 = 4660; // 0x1234 unsigned short s2 = 22136; // 0x5678 int32_t i1 = static_cast(0x89ABCDEFU); // 0x89ABCDEF @@ -660,7 +660,7 @@ namespace TEST(test_write_multiple_variable_size) { char c1 = 90; // 0x5A 6 bits - char c2 = -91; // 0xA5 7 bits + char c2 = static_cast(-91); // 0xA5 7 bits unsigned short s1 = 4660; // 0x1234 13 bits unsigned short s2 = 22136; // 0x5678 11 bits int32_t i1 = static_cast(0x89ABCDEFU); // 0x89ABCDEF 23 bits @@ -705,7 +705,7 @@ namespace Accumulator accumulator; char c1 = 90; // 0x5A 6 bits - char c2 = -91; // 0xA5 7 bits + char c2 = static_cast(-91); // 0xA5 7 bits unsigned short s1 = 4660U; // 0x1234 13 bits unsigned short s2 = 22136U; // 0x5678 11 bits int32_t i1 = static_cast(0x89ABCDEFU); // 0x89ABCDEF 23 bits diff --git a/test/test_bit_stream_writer_little_endian.cpp b/test/test_bit_stream_writer_little_endian.cpp index 1d6f85d5..07348253 100644 --- a/test/test_bit_stream_writer_little_endian.cpp +++ b/test/test_bit_stream_writer_little_endian.cpp @@ -702,7 +702,7 @@ namespace TEST(test_write_multiple_full_size) { char c1 = 90; // 0x5A - char c2 = -91; // 0xA5 + char c2 = static_cast(-91); // 0xA5 unsigned short s1 = 4660; // 0x1234 unsigned short s2 = 22136; // 0x5678 int32_t i1 = static_cast(0x89ABCDEFU); // 0x89ABCDEF @@ -748,7 +748,7 @@ namespace TEST(test_write_multiple_variable_size) { char c1 = 90; // 0x5A 6 bits - char c2 = -91; // 0xA5 7 bits + char c2 = static_cast(-91); // 0xA5 7 bits unsigned short s1 = 4660; // 0x1234 13 bits unsigned short s2 = 22136; // 0x5678 11 bits int32_t i1 = static_cast(0x89ABCDEFU); // 0x89ABCDEF 23 bits @@ -791,7 +791,7 @@ namespace TEST(test_write_multiple_variable_size_with_callback) { char c1 = 90; // 0x5A 6 bits - char c2 = -91; // 0xA5 7 bits + char c2 = static_cast(-91); // 0xA5 7 bits unsigned short s1 = 4660; // 0x1234 13 bits unsigned short s2 = 22136; // 0x5678 11 bits int32_t i1 = static_cast(0x89ABCDEFU); // 0x89ABCDEF 23 bits diff --git a/test/test_byte_stream.cpp b/test/test_byte_stream.cpp index 29570ac1..06b2a453 100644 --- a/test/test_byte_stream.cpp +++ b/test/test_byte_stream.cpp @@ -1026,7 +1026,7 @@ namespace TEST(write_read_multiple_big_endian) { char c1 = 90; - char c2 = -91; + char c2 = static_cast(-91); unsigned short s1 = 23205; unsigned short s2 = 42330; int32_t i1 = 1520786085; // 0x5AA55AA5 @@ -1089,7 +1089,7 @@ namespace TEST(write_read_multiple_little_endian) { char c1 = 90; - char c2 = -91; + char c2 = static_cast(-91); unsigned short s1 = 23205; unsigned short s2 = 42330; int32_t i1 = 1520786085; // 0x5AA55AA5 diff --git a/test/test_format.cpp b/test/test_format.cpp index 591d83f1..16b0ac1b 100644 --- a/test/test_format.cpp +++ b/test/test_format.cpp @@ -214,7 +214,7 @@ namespace etl::string<100> s; CHECK_EQUAL("1.0", test_format(s, "{}", 1.0)); - CHECK_EQUAL("1.234564", test_format(s, "{}", 1.234564)); + CHECK_EQUAL("1.234563", test_format(s, "{}", 1.234563)); CHECK_EQUAL("1.234567", test_format(s, "{}", 1.2345678)); CHECK_EQUAL("1.5", test_format(s, "{}", 1.5)); } diff --git a/test/test_hash.cpp b/test/test_hash.cpp index 73a616f8..d1acd6b1 100644 --- a/test/test_hash.cpp +++ b/test/test_hash.cpp @@ -149,7 +149,14 @@ namespace if (ETL_PLATFORM_32BIT) { - CHECK_EQUAL(0xEC6A8D69UL, hash); + if (etl::endianness::value() == etl::endian::little) + { + CHECK_EQUAL(0xEC6A8D69UL, hash); + } + else + { + CHECK_EQUAL(0x5F69FD19UL, hash); + } } if (ETL_PLATFORM_64BIT) @@ -165,7 +172,14 @@ namespace if (ETL_PLATFORM_32BIT) { - CHECK_EQUAL(0xEC6A8D69UL, hash); + if (etl::endianness::value() == etl::endian::little) + { + CHECK_EQUAL(0xEC6A8D69UL, hash); + } + else + { + CHECK_EQUAL(0x5F69FD19UL, hash); + } } if (ETL_PLATFORM_64BIT) @@ -177,7 +191,7 @@ namespace //************************************************************************* TEST(test_hash_float) { - size_t hash = etl::hash()((float)(1.2345)); + size_t hash = etl::hash()(1.2345f); if (ETL_PLATFORM_32BIT) { @@ -204,7 +218,14 @@ namespace if (ETL_PLATFORM_32BIT) { - CHECK_EQUAL(0x86FBF224UL, hash); + if (etl::endianness::value() == etl::endian::little) + { + CHECK_EQUAL(0x86FBF224UL, hash); + } + else + { + CHECK_EQUAL(0xD1F372DEUL, hash); + } } if (ETL_PLATFORM_64BIT) diff --git a/test/test_histogram.cpp b/test/test_histogram.cpp index 92857deb..a68970f9 100644 --- a/test/test_histogram.cpp +++ b/test/test_histogram.cpp @@ -166,7 +166,7 @@ namespace for (size_t i = 0UL; i < output1.size(); ++i) { - CHECK_EQUAL(int(output1[i]), int(histogram[i])); + CHECK_EQUAL(static_cast(output1[i]), static_cast(histogram[static_cast(i)])); } } @@ -203,7 +203,7 @@ namespace for (size_t i = 0UL; i < output1.size(); ++i) { - CHECK_EQUAL(int(output1[i]), int(histogram[i - 4])); + CHECK_EQUAL(static_cast(output1[i]), static_cast(histogram[static_cast(i) - 4])); } } diff --git a/test/test_set.cpp b/test/test_set.cpp index 0fe643bf..2fb624d4 100644 --- a/test/test_set.cpp +++ b/test/test_set.cpp @@ -594,8 +594,8 @@ namespace for (size_t i = 0; i < MAX_SIZE; ++i) { - data_result = data.insert(i); - compare_result = compare_data.insert(i); + data_result = data.insert(static_cast(i)); + compare_result = compare_data.insert(static_cast(i)); // Check that both return successful return results CHECK_EQUAL(*data_result.first, *compare_result.first); @@ -608,8 +608,8 @@ namespace // not throw error for (size_t i = 0; i < MAX_SIZE; ++i) { - data_result = data.insert(i); - compare_result = compare_data.insert(i); + data_result = data.insert(static_cast(i)); + compare_result = compare_data.insert(static_cast(i)); // Check that both return successful return results CHECK_EQUAL(*data_result.first, *compare_result.first);