Merge branch 'development' into deduce_if_builtins_are_present

# Conflicts:
#	include/etl/generators/type_traits_generator.h
#	include/etl/profiles/arduino_arm.h
#	include/etl/profiles/armv5.h
#	include/etl/profiles/armv5_no_stl.h
#	include/etl/profiles/armv6.h
#	include/etl/profiles/armv6_no_stl.h
#	include/etl/profiles/armv7.h
#	include/etl/profiles/armv7_no_stl.h
#	include/etl/profiles/cpp03.h
#	include/etl/profiles/cpp03_no_stl.h
#	include/etl/profiles/cpp11.h
#	include/etl/profiles/cpp11_no_stl.h
#	include/etl/profiles/cpp14.h
#	include/etl/profiles/cpp14_no_stl.h
#	include/etl/profiles/cpp17.h
#	include/etl/profiles/cpp17_no_stl.h
#	include/etl/profiles/determine_builtin_support.h
#	include/etl/profiles/ticc.h
#	include/etl/profiles/ticc_no_stl.h
#	include/etl/type_traits.h
This commit is contained in:
John Wellbelove 2026-05-30 11:53:57 +01:00
commit 0ea66204e3
973 changed files with 140865 additions and 91884 deletions

26
.bazelrc Normal file
View File

@ -0,0 +1,26 @@
# Bazel settings for ETL
build --enable_bzlmod
build --cxxopt=-std=c++17
# Cross-compilation: build flags + QEMU (mirrors .devcontainer/run-tests.sh)
# Each config sets CC + tool env vars so Bazel's auto-configured toolchain
# finds the full cross-tool suite, and --run_under for QEMU execution.
build:armhf --repo_env=CC=arm-linux-gnueabihf-gcc --repo_env=AR=arm-linux-gnueabihf-ar --repo_env=LD=arm-linux-gnueabihf-ld --repo_env=NM=arm-linux-gnueabihf-nm --repo_env=STRIP=arm-linux-gnueabihf-strip --repo_env=OBJDUMP=arm-linux-gnueabihf-objdump
build:armhf --cxxopt=-std=c++23 --copt=-DETL_NO_STL --copt=-O0
test:armhf --run_under=/usr/bin/qemu-arm-static
build:i386 --repo_env=CC=i686-linux-gnu-gcc --repo_env=AR=i686-linux-gnu-ar --repo_env=LD=i686-linux-gnu-ld --repo_env=NM=i686-linux-gnu-nm --repo_env=STRIP=i686-linux-gnu-strip --repo_env=OBJDUMP=i686-linux-gnu-objdump
build:i386 --cxxopt=-std=c++23 --copt=-DETL_NO_STL --copt=-O0
test:i386 --run_under=/usr/bin/qemu-i386-static
build:powerpc --repo_env=CC=powerpc-linux-gnu-gcc --repo_env=AR=powerpc-linux-gnu-ar --repo_env=LD=powerpc-linux-gnu-ld --repo_env=NM=powerpc-linux-gnu-nm --repo_env=STRIP=powerpc-linux-gnu-strip --repo_env=OBJDUMP=powerpc-linux-gnu-objdump
build:powerpc --cxxopt=-std=c++23 --copt=-DETL_NO_STL --copt=-O0
test:powerpc --run_under=/usr/bin/qemu-ppc
build:riscv64 --repo_env=CC=riscv64-linux-gnu-gcc --repo_env=AR=riscv64-linux-gnu-ar --repo_env=LD=riscv64-linux-gnu-ld --repo_env=NM=riscv64-linux-gnu-nm --repo_env=STRIP=riscv64-linux-gnu-strip --repo_env=OBJDUMP=riscv64-linux-gnu-objdump
build:riscv64 --cxxopt=-std=c++23 --copt=-DETL_NO_STL --copt=-O0
test:riscv64 --run_under=/usr/bin/qemu-riscv64-static
build:s390x --repo_env=CC=s390x-linux-gnu-gcc --repo_env=AR=s390x-linux-gnu-ar --repo_env=LD=s390x-linux-gnu-ld --repo_env=NM=s390x-linux-gnu-nm --repo_env=STRIP=s390x-linux-gnu-strip --repo_env=OBJDUMP=s390x-linux-gnu-objdump
build:s390x --cxxopt=-std=c++23 --copt=-DETL_NO_STL --copt=-O0
test:s390x --run_under=/usr/bin/qemu-s390x-static

1
.bazelversion Normal file
View File

@ -0,0 +1 @@
8.5.1

View File

@ -1,57 +1,184 @@
---
#------------------------------------
# Configuration for clang-format v12
#------------------------------------
BasedOnStyle: LLVM
Standard: Auto # let the formatter accept any C++ standard
Language: Cpp
# =============================================================================
# Indentation
# =============================================================================
TabWidth: 2
ContinuationIndentWidth: 2
ConstructorInitializerIndentWidth: 2
NamespaceIndentation: All # everything inside namespace is indented
IndentCaseLabels: true # case labels at switch-body indent level
IndentCaseBlocks: true # indent block inside case label
IndentExternBlock: Indent
IndentWrappedFunctionNames: true # keep function name at same indent as return type
IndentPPDirectives: BeforeHash # nested #if / #include get indented before the #
PPIndentWidth: 2
BasedOnStyle: Chromium
# =============================================================================
# Braces & line-break style
# =============================================================================
BreakBeforeBraces: Allman
BreakConstructorInitializers: BeforeComma # colon on new line, commas lead
BreakInheritanceList: BeforeComma
BreakBeforeBinaryOperators: NonAssignment
BreakStringLiterals: false
AlwaysBreakTemplateDeclarations: Yes # template <…> always on its own line
BreakAfterAttributes: Always
SortIncludes: true
IncludeBlocks: Preserve
# =============================================================================
# Short statements
# =============================================================================
AllowShortBlocksOnASingleLine: Empty
AllowShortFunctionsOnASingleLine: Empty # only empty bodies: void f() {}
AllowShortCaseLabelsOnASingleLine: true # case X: stmt; break; on one line
AllowShortLoopsOnASingleLine: true
AllowShortLambdasOnASingleLine: Inline
# =============================================================================
# Empty lines
# =============================================================================
KeepEmptyLinesAtTheStartOfBlocks: false
EmptyLineBeforeAccessModifier: Always # blank line before public:/private:/protected:
EmptyLineAfterAccessModifier: Always # blank line after public:/private:/protected:
InsertNewlineAtEOF: true
# =============================================================================
# Spacing
# =============================================================================
SpacesInAngles: Leave # preserve C++03 "> >" vs C++11 ">>"
SpacesInContainerLiterals: false
# =============================================================================
# Alignment
# =============================================================================
PointerAlignment: Left # T* ptr, const T& ref
ReferenceAlignment: Left
AlignConsecutiveAssignments: true
AlignConsecutiveDeclarations: true
AlignConsecutiveBitFields: true
AlignConsecutiveMacros: true # align macro bodies
# =============================================================================
# Line length and wrapping
# =============================================================================
ColumnLimit: 150
ReflowComments: true # preserve hand-formatted comment rulers
AlignEscapedNewlines: Left
# =============================================================================
# Includes
# =============================================================================
IncludeCategories:
- Regex: '^(<|")(.*/)?platform\.h(>|")$'
Priority: -1
- Regex: 'private'
Priority: 1
- Regex: '.*'
Priority: 2
Priority: 0
BinPackParameters: false
BitFieldColonSpacing: Both
# =============================================================================
# Arguments, parameters and constructor initialisers
# =============================================================================
PackConstructorInitializers: Never # each initialiser on its own line
BreakBeforeBraces: Allman
BreakConstructorInitializers: BeforeComma
# =============================================================================
# Namespaces and using declarations
# =============================================================================
SortUsingDeclarations: Lexicographic
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: true
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: false
# =============================================================================
# Macro-aware formatting
# =============================================================================
# ETL-specific macros that should be treated as statement-level constructs
StatementMacros:
- ETL_DECLARE_DEBUG_COUNT
- ETL_INCREMENT_DEBUG_COUNT
- ETL_DECREMENT_DEBUG_COUNT
- ETL_ADD_DEBUG_COUNT
- ETL_STATIC_ASSERT
- ETL_ASSERT
- ETL_ASSERT_OR_RETURN
- ETL_ASSERT_OR_RETURN_VALUE
- ETL_ASSERT_FAIL
- ETL_ASSERT_FAIL_AND_RETURN
- ETL_ASSERT_FAIL_AND_RETURN_VALUE
- ETL_MOVE
- ETL_ENUM_CLASS
- ETL_ENUM_CLASS_TYPE
- ETL_IF_CONSTEXPR
AllowAllArgumentsOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
# Macros that behave like attributes or specifiers.
AttributeMacros:
- ETL_NORETURN
- ETL_FINAL
- ETL_OVERRIDE
- ETL_EXPLICIT
- ETL_DELETE
- ETL_CONSTANT
- ETL_CONSTEXPR
- ETL_CONSTEXPR11
- ETL_CONSTEXPR14
- ETL_CONSTEXPR17
- ETL_CONSTEXPR20
- ETL_CONSTEXPR23
- ETL_CONSTEVAL
- ETL_NODISCARD
- ETL_NORETURN
- ETL_DEPRECATED
- ETL_DEPRECATED_REASON
- ETL_LIKELY
- ETL_UNLIKELY
- ETL_FALLTHROUGH
- ETL_MAYBE_UNUSED
- ETL_INLINE_VAR
- ETL_ASSUME
- ETL_LVALUE_REF_QUALIFIER
- ETL_RVALUE_REF_QUALIFIER
- ETL_NOEXCEPT
- ETL_NOEXCEPT_EXPR
- ETL_NOEXCEPT_IF
- ETL_NOEXCEPT_FROM
ConstructorInitializerAllOnOneLineOrOnePerLine: 'true'
ConstructorInitializerIndentWidth: '2'
Macros:
- ETL_NORETURN=[[noreturn]]
- ETL_FINAL=final
- ETL_OVERRIDE=override
- ETL_EXPLICIT=explicit
- ETL_DELETE=delete
- ETL_CONSTANT=const
- ETL_CONSTEXPR=constexpr
- ETL_CONSTEXPR11=constexpr
- ETL_CONSTEXPR14=constexpr
- ETL_CONSTEXPR17=constexpr
- ETL_CONSTEXPR20=constexpr
- ETL_CONSTEXPR23=constexpr
- ETL_CONSTEVAL=consteval
- ETL_NODISCARD=[[nodiscard]]
- ETL_NORETURN=[[noreturn]]
- ETL_DEPRECATED=[[deprecated]]
# - ETL_DEPRECATED_REASON=[[deprecated(%0)]] # Hangs with clang-format 18
- ETL_LIKELY=[[likely]]
- ETL_UNLIKELY=[[unlikely]]
- ETL_FALLTHROUGH=[[fallthrough]]
- ETL_MAYBE_UNUSED=[[maybe_unused]]
- ETL_INLINE_VAR=inline
- ETL_ASSUME=[[assume(&0)]]
- ETL_LVALUE_REF_QUALIFIER=&
- ETL_RVALUE_REF_QUALIFIER=&&
- ETL_NOEXCEPT=noexcept
# - ETL_NOEXCEPT_EXPR=noexcept(&0)) # Hangs with clang-format 18
# - ETL_NOEXCEPT_IF=noexcept(&0) # Hangs with clang-format 18
# - ETL_NOEXCEPT_FROM=noexcept(&0) # Hangs with clang-format 18
NamespaceIndentation: All
IndentPPDirectives: BeforeHash
PointerAlignment: Left
ColumnLimit: '0'
ContinuationIndentWidth: '2'
UseTab: Never
TabWidth: '2'
IndentWidth: '2'
AccessModifierOffset : '-2'
IndentCaseLabels: false
Cpp11BracedListStyle: 'true'
AlignAfterOpenBracket: Align
AlignConsecutiveDeclarations: true
# Macros that behave like type names
TypenameMacros:
- ETL_OR_STD
#------------------------------------
# Configurations not supported by clang-format v12
#------------------------------------
# BreakInheritanceList: AfterComma
# EmptyLineBeforeAccessModifier: Always
# EmptyLineAfterAccessModifier: Always
# ReferenceAlignment: Left
...
# Do not reformat these macros — they contain DSL-like content
WhitespaceSensitiveMacros:
- ETL_ERROR_TEXT
- ETL_DECLARE_ENUM_TYPE
- ETL_ENUM_TYPE
- ETL_END_ENUM_TYPE

182
.clang-tidy Normal file
View File

@ -0,0 +1,182 @@
---
# TODO: Enable these checks in smaller steps
# cppcoreguidelines-*,
# portability-* if needed
# readability-*, -readability-magic-numbers,
# misc-*, -misc-no-recursion,
# modernize-*, -modernize-use-trailing-return-type,
# performance-*,
Checks: >-
cert-*, -cert-dcl37-c, -cert-dcl51-cpp,
clang-analyzer-*,
bugprone-*,
-bugprone-easily-swappable-parameters,
cppcoreguidelines-pro-type-vararg,
cppcoreguidelines-pro-type-reinterpret-cast,
llvm-*,-llvm-header-guard,-llvm-include-order,
google-readability-casting
ExtraArgs: ['-Wno-unknown-warning-option']
HeaderFileExtensions: ['h', 'hpp']
HeaderFilterRegex: '.*include/etl/.*'
ImplementationFileExtensions: ['cpp']
UseColor: true
# TODO: Enable these when readability check is enabled
# CheckOptions :
# - key: readability-identifier-naming.AbstractClassCase
# value: snake_case
# - key: readability-identifier-naming.AbstractClassPrefix
# value: I
# - key: readability-identifier-naming.AbstractClassSuffix
# value: ''
# - key: readability-identifier-naming.ClassCase
# value: snake_case
# - key: readability-identifier-naming.ClassPrefix
# value: ''
# - key: readability-identifier-naming.ClassSuffix
# value: ''
# - key: readability-identifier-naming.GlobalConstantCase
# value: UPPER_CASE
# - key: readability-identifier-naming.GlobalConstantPrefix
# value: ''
# - key: readability-identifier-naming.GlobalConstantSuffix
# value: ''
# - key: readability-identifier-naming.ConstantCase
# value: snake_case
# - key: readability-identifier-naming.ConstantPrefix
# value: ''
# - key: readability-identifier-naming.ConstantSuffix
# value: ''
# - key: readability-identifier-naming.ConstantMemberCase
# value: snake_case
# - key: readability-identifier-naming.ConstantMemberPrefix
# value: k
# - key: readability-identifier-naming.ConstantMemberSuffix
# value: ''
# - key: readability-identifier-naming.StaticConstantCase
# value: snake_case
# - key: readability-identifier-naming.StaticConstantPrefix
# value: k
# - key: readability-identifier-naming.StaticConstantSuffix
# value: ''
# - key: readability-identifier-naming.EnumCase
# value: snake_case
# - key: readability-identifier-naming.EnumPrefix
# value: ''
# - key: readability-identifier-naming.EnumSuffix
# value: ''
# - key: readability-identifier-naming.EnumConstantCase
# value: snake_case
# - key: readability-identifier-naming.EnumConstantPrefix
# value: ''
# - key: readability-identifier-naming.EnumConstantSuffix
# value: ''
# - key: readability-identifier-naming.GlobalVariableCase
# value: snake_case
# - key: readability-identifier-naming.GlobalVariablePrefix
# value: g
# - key: readability-identifier-naming.GlobalVariableSuffix
# value: ''
# - key: readability-identifier-naming.LocalVariableCase
# value: snake_case
# - key: readability-identifier-naming.LocalVariablePrefix
# value: ''
# - key: readability-identifier-naming.LocalVariableSuffix
# value: ''
# - key: readability-identifier-naming.StructCase
# value: aNy_CasE
# - key: readability-identifier-naming.StructPrefix
# value: ''
# - key: readability-identifier-naming.StructSuffix
# value: ''
# - key: readability-identifier-naming.FunctionCase
# value: snake_case
# - key: readability-identifier-naming.FunctionPrefix
# value: ''
# - key: readability-identifier-naming.FunctionSuffix
# value: ''
# - key: readability-identifier-naming.MethodCase
# value: snake_case
# - key: readability-identifier-naming.MethodPrefix
# value: ''
# - key: readability-identifier-naming.MethodSuffix
# value: ''
# - key: readability-identifier-naming.ParameterCase
# value: snake_case
# - key: readability-identifier-naming.PrivateMethodCase
# value: snake_case
# - key: readability-identifier-naming.PrivateMethodPrefix
# value: ''
# - key: readability-identifier-naming.PrivateMethodSuffix
# value: ''
# - key: readability-identifier-naming.PublicMethodCase
# value: snake_case
# - key: readability-identifier-naming.PublicMethodPrefix
# value: ''
# - key: readability-identifier-naming.PublicMethodSuffix
# value: ''
# - key: readability-identifier-naming.MemberCase
# value: snake_case
# - key: readability-identifier-naming.MemberPrefix
# value: _
# - key: readability-identifier-naming.MemberSuffix
# value: ''
# - key: readability-identifier-naming.PrivateMemberCase
# value: snake_case
# - key: readability-identifier-naming.PrivateMemberPrefix
# value: _
# - key: readability-identifier-naming.PrivateMemberSuffix
# value: ''
# - key: readability-identifier-naming.PublicMemberCase
# value: snake_case
# - key: readability-identifier-naming.PublicMemberPrefix
# value: ''
# - key: readability-identifier-naming.PublicMemberSuffix
# value: ''
# - key: readability-identifier-naming.NamespaceCase
# value: lower_case
# - key: readability-identifier-naming.NamespacePrefix
# value: ''
# - key: readability-identifier-naming.NamespaceSuffix
# value: ''
# - key: readability-identifier-naming.InlineNamespaceCase
# value: lower_case
# - key: readability-identifier-naming.InlineNamespacePrefix
# value: ''
# - key: readability-identifier-naming.InlineNamespaceSuffix
# value: ''
# - key: readability-identifier-length.IgnoredParameterNames
# value: ^(n|id|a|b|x|y)$
# - key: readability-identifier-length.IgnoredLoopCounterNames
# value: ^[ijkxy_]$
# - key: readability-identifier-naming.GlobalFunctionCase
# value: snake_case
# - key: readability-identifier-naming.GlobalFunctionPrefix
# value: ''
# - key: readability-identifier-naming.GlobalFunctionSuffix
# value: ''
# - key: readability-identifier-naming.TemplateParameterCase
# value: CamelCase
# - key: readability-identifier-naming.TemplateParameterPrefix
# value: ''
# - key: readability-identifier-naming.TemplateParameterSuffix
# value: ''
# - key: readability-identifier-naming.TemplateTemplateParameterCase
# value: CamelCase
# - key: readability-identifier-naming.TemplateTemplateParameterPrefix
# value: 'TPL'
# - key: readability-identifier-naming.TemplateTemplateParameterSuffix
# value: ''
# - key: readability-identifier-naming.TypeTemplateParameterCase
# value: CamelCase
# - key: readability-identifier-naming.TypeTemplateParameterPrefix
# value: 'T'
# - key: readability-identifier-naming.TypeTemplateParameterSuffix
# value: ''
# - key: readability-identifier-naming.ValueTemplateParameterCase
# value: UPPER_CASE
# - key: readability-identifier-naming.ValueTemplateParameterPrefix
# value: ''
# - key: readability-identifier-naming.ValueTemplateParameterSuffix
# value: ''
...

View File

@ -1,18 +1,78 @@
ARG BASE_IMAGE_NAME="clang:latest"
ARG BASE_IMAGE_NAME="mcr.microsoft.com/devcontainers/cpp:2@sha256:a5eb5a1e9109af88bf82ebb0f71903608a68144851ed1e4b852e31b251ac59c6"
FROM ${BASE_IMAGE_NAME}
ARG REINSTALL_CMAKE_VERSION_FROM_SOURCE="3.31.7"
ARG DEBIAN_SNAPSHOT="20260223T000000Z"
# Optionally install the cmake for vcpkg
COPY ./reinstall-cmake.sh /tmp/
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
&& apt-get -y install --no-install-recommends \
git \
wget
ENV LANG=C.UTF-8 \
LC_ALL=C.UTF-8 \
TZ=UTC
RUN if [ "${REINSTALL_CMAKE_VERSION_FROM_SOURCE}" != "none" ]; then \
chmod +x /tmp/reinstall-cmake.sh && /tmp/reinstall-cmake.sh ${REINSTALL_CMAKE_VERSION_FROM_SOURCE}; \
RUN set -eux \
&& export DEBIAN_FRONTEND=noninteractive \
&& if [[ "${DEBIAN_SNAPSHOT}" != "none" ]]; then \
snapshot_main="http://snapshot.debian.org/archive/debian/${DEBIAN_SNAPSHOT}"; \
snapshot_security="http://snapshot.debian.org/archive/debian-security/${DEBIAN_SNAPSHOT}"; \
if [[ -f /etc/apt/sources.list.d/debian.sources ]]; then \
sed -ri "s|^URIs: https?://deb.debian.org/debian$|URIs: ${snapshot_main}|g" /etc/apt/sources.list.d/debian.sources; \
sed -ri "s|^URIs: https?://deb.debian.org/debian-security$|URIs: ${snapshot_security}|g" /etc/apt/sources.list.d/debian.sources; \
elif [[ -f /etc/apt/sources.list ]] || compgen -G "/etc/apt/sources.list.d/*.list" > /dev/null; then \
for list_file in /etc/apt/sources.list /etc/apt/sources.list.d/*.list; do \
[[ -f "${list_file}" ]] || continue; \
sed -ri "s|https?://deb.debian.org/debian|${snapshot_main}|g" "${list_file}"; \
sed -ri "s|https?://security.debian.org/debian-security|${snapshot_security}|g" "${list_file}"; \
sed -ri "s|https?://deb.debian.org/debian-security|${snapshot_security}|g" "${list_file}"; \
done; \
else \
echo "ERROR: DEBIAN_SNAPSHOT='${DEBIAN_SNAPSHOT}' is set, but no supported apt source files were found."; \
echo "Expected /etc/apt/sources.list.d/debian.sources or one or more .list files under /etc/apt/."; \
exit 1; \
fi; \
printf 'Acquire::Check-Valid-Until "false";\n' > /etc/apt/apt.conf.d/99snapshot; \
fi \
&& rm -f /tmp/reinstall-cmake.sh
&& apt-get update \
&& apt-get -y install --no-install-recommends \
python3-full \
python3-pip \
python3-cogapp \
git \
wget \
cmake \
clang-format \
clang-format-18 \
lcov \
&& rm -rf /var/lib/apt/lists/*
RUN set -eux; \
VERSION="2.4.1"; \
case "$(uname -m)" in \
x86_64) ARCH="amd64"; SHA256="bdaa2c0fbee03e5c2f99e605d9419386ce5d558440baac2017398faada839e04" ;; \
aarch64) ARCH="arm64"; SHA256="0a09e1f04a0f8a86fd4e709552613f5d82adf6bc72f0a4b5e217670894e79fbf" ;; \
*) echo "Unsupported architecture: $(uname -m)"; exit 1 ;; \
esac; \
wget -O treefmt.tar.gz "https://github.com/numtide/treefmt/releases/download/v${VERSION}/treefmt_${VERSION}_linux_${ARCH}.tar.gz" \
&& echo "${SHA256} treefmt.tar.gz" | sha256sum -c \
&& tar xzf treefmt.tar.gz treefmt \
&& install -m 755 treefmt /usr/bin/treefmt \
&& rm treefmt.tar.gz treefmt
# Install Bazelisk as 'bazel'
RUN ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/') && \
wget -qO /usr/local/bin/bazel https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-linux-${ARCH} && \
chmod +x /usr/local/bin/bazel
RUN set -eux \
&& echo "Pip version: " \
&& pip --version \
&& echo "Cogapp version: " \
&& pip show cogapp \
&& echo "Git version: " \
&& git --version \
&& echo "Wget version: " \
&& wget --version \
&& echo "Cmake version: " \
&& cmake --version \
&& echo "Make version: " \
&& make --version

View File

@ -0,0 +1,61 @@
# 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 \
ca-certificates \
file \
libc6:armhf \
libstdc++6:armhf \
libatomic1:armhf \
&& rm -rf /var/lib/apt/lists/*
# Create non-root user with stable UID/GID
ARG USERNAME=vscode
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
# Install Bazelisk as 'bazel'
RUN ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/') && \
wget -qO /usr/local/bin/bazel https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-linux-${ARCH} && \
chmod +x /usr/local/bin/bazel
# 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"]

View File

@ -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"
}

View File

@ -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")

View File

@ -5,7 +5,8 @@
"build": {
"dockerfile": "../Dockerfile",
"args": {
"BASE_IMAGE_NAME": "silkeh/clang:10"
"BASE_IMAGE_NAME": "silkeh/clang:10",
"DEBIAN_SNAPSHOT": "none"
},
"context": "../context"
}

View File

@ -5,7 +5,8 @@
"build": {
"dockerfile": "../Dockerfile",
"args": {
"BASE_IMAGE_NAME": "silkeh/clang:11"
"BASE_IMAGE_NAME": "silkeh/clang:11",
"DEBIAN_SNAPSHOT": "none"
},
"context": "../context"
}

View File

@ -5,7 +5,8 @@
"build": {
"dockerfile": "../Dockerfile",
"args": {
"BASE_IMAGE_NAME": "silkeh/clang:12"
"BASE_IMAGE_NAME": "silkeh/clang:12",
"DEBIAN_SNAPSHOT": "none"
},
"context": "../context"
}

View File

@ -5,7 +5,8 @@
"build": {
"dockerfile": "../Dockerfile",
"args": {
"BASE_IMAGE_NAME": "silkeh/clang:13"
"BASE_IMAGE_NAME": "silkeh/clang:13",
"DEBIAN_SNAPSHOT": "none"
},
"context": "../context"
}

View File

@ -5,7 +5,8 @@
"build": {
"dockerfile": "../Dockerfile",
"args": {
"BASE_IMAGE_NAME": "silkeh/clang:14"
"BASE_IMAGE_NAME": "silkeh/clang:14",
"DEBIAN_SNAPSHOT": "none"
},
"context": "../context"
}

View File

@ -5,7 +5,8 @@
"build": {
"dockerfile": "../Dockerfile",
"args": {
"BASE_IMAGE_NAME": "silkeh/clang:15"
"BASE_IMAGE_NAME": "silkeh/clang:15",
"DEBIAN_SNAPSHOT": "none"
},
"context": "../context"
}

View File

@ -5,7 +5,8 @@
"build": {
"dockerfile": "../Dockerfile",
"args": {
"BASE_IMAGE_NAME": "silkeh/clang:16"
"BASE_IMAGE_NAME": "silkeh/clang:16",
"DEBIAN_SNAPSHOT": "none"
},
"context": "../context"
}

View File

@ -5,7 +5,8 @@
"build": {
"dockerfile": "../Dockerfile",
"args": {
"BASE_IMAGE_NAME": "silkeh/clang:17"
"BASE_IMAGE_NAME": "silkeh/clang:17",
"DEBIAN_SNAPSHOT": "none"
},
"context": "../context"
}

View File

@ -5,7 +5,8 @@
"build": {
"dockerfile": "../Dockerfile",
"args": {
"BASE_IMAGE_NAME": "silkeh/clang:18-bullseye"
"BASE_IMAGE_NAME": "silkeh/clang:18-bullseye",
"DEBIAN_SNAPSHOT": "none"
},
"context": "../context"
}

View File

@ -5,7 +5,8 @@
"build": {
"dockerfile": "../Dockerfile",
"args": {
"BASE_IMAGE_NAME": "silkeh/clang:19-bullseye"
"BASE_IMAGE_NAME": "silkeh/clang:19-bullseye",
"DEBIAN_SNAPSHOT": "none"
},
"context": "../context"
}

View File

@ -5,7 +5,8 @@
"build": {
"dockerfile": "../Dockerfile",
"args": {
"BASE_IMAGE_NAME": "silkeh/clang:20-bullseye"
"BASE_IMAGE_NAME": "silkeh/clang:20-bullseye",
"DEBIAN_SNAPSHOT": "none"
},
"context": "../context"
}

View File

@ -0,0 +1,13 @@
// 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": "Clang 21",
"build": {
"dockerfile": "../Dockerfile",
"args": {
"BASE_IMAGE_NAME": "silkeh/clang:21-bullseye",
"DEBIAN_SNAPSHOT": "none"
},
"context": "../context"
}
}

View File

@ -5,7 +5,8 @@
"build": {
"dockerfile": "../Dockerfile",
"args": {
"BASE_IMAGE_NAME": "silkeh/clang:7"
"BASE_IMAGE_NAME": "silkeh/clang:7",
"DEBIAN_SNAPSHOT": "none"
},
"context": "../context"
}

View File

@ -5,7 +5,8 @@
"build": {
"dockerfile": "../Dockerfile",
"args": {
"BASE_IMAGE_NAME": "silkeh/clang:8"
"BASE_IMAGE_NAME": "silkeh/clang:8",
"DEBIAN_SNAPSHOT": "none"
},
"context": "../context"
}

View File

@ -5,7 +5,8 @@
"build": {
"dockerfile": "../Dockerfile",
"args": {
"BASE_IMAGE_NAME": "silkeh/clang:9"
"BASE_IMAGE_NAME": "silkeh/clang:9",
"DEBIAN_SNAPSHOT": "none"
},
"context": "../context"
}

View File

@ -1,291 +0,0 @@
#!/usr/bin/env bash
# For more detailed debugging, uncomment the next line
# set -x
# Explicitly set CMAKE_VERSION from first argument, default to "none"
CMAKE_VERSION=${1:-"none"}
# --- Configuration ---
DOWNLOAD_ATTEMPTS=3
DOWNLOAD_RETRY_DELAY=5 # seconds
# --- Global Variables ---
TMP_DIR="" # Initialize TMP_DIR, will be set by mktemp
# Filenames used within TMP_DIR
CMAKE_INSTALLER_SCRIPT_LOCAL_NAME="cmake-installer.sh"
CMAKE_CHECKSUM_FILE_LOCAL_NAME="cmake-checksums.txt"
# This will be the actual name of the CMake binary, derived from version and arch
# It's important for matching against the checksum file.
DERIVED_CMAKE_BINARY_FILENAME=""
# --- Cleanup Function ---
# This trap will execute on EXIT, ERR, SIGINT, SIGTERM
# It's crucial for debugging to see the state of TMP_DIR if things go wrong.
cleanup() {
# $? is the exit code of the last command before the trap was triggered
# or the argument to exit if the script called exit explicitly.
LAST_EXIT_CODE=$?
echo # Newline for readability
# Only proceed with detailed cleanup if TMP_DIR was actually created
if [[ -n "${TMP_DIR}" && -d "${TMP_DIR}" ]]; then
echo "--- Cleanup: Temporary Directory Inspector (${TMP_DIR}) ---"
echo "Listing contents of TMP_DIR:"
ls -la "${TMP_DIR}"
# Check and display checksum file content
if [[ -f "${TMP_DIR}/${CMAKE_CHECKSUM_FILE_LOCAL_NAME}" ]]; then
echo "--- Content of downloaded checksum file (${CMAKE_CHECKSUM_FILE_LOCAL_NAME}) ---"
cat "${TMP_DIR}/${CMAKE_CHECKSUM_FILE_LOCAL_NAME}"
echo "--- End of checksum file ---"
else
echo "Checksum file (${CMAKE_CHECKSUM_FILE_LOCAL_NAME}) not found in TMP_DIR."
fi
# Check and display head of (potentially) installer script
# Useful to see if it's an HTML error page
if [[ -f "${TMP_DIR}/${CMAKE_INSTALLER_SCRIPT_LOCAL_NAME}" ]]; then
echo "--- First 10 lines of downloaded installer script (${CMAKE_INSTALLER_SCRIPT_LOCAL_NAME}) ---"
head -n 10 "${TMP_DIR}/${CMAKE_INSTALLER_SCRIPT_LOCAL_NAME}"
echo "--- End of installer script head ---"
elif [[ -f "${TMP_DIR}/${DERIVED_CMAKE_BINARY_FILENAME}" ]]; then
# If it was renamed
echo "--- First 10 lines of downloaded installer script (${DERIVED_CMAKE_BINARY_FILENAME}) ---"
head -n 10 "${TMP_DIR}/${DERIVED_CMAKE_BINARY_FILENAME}"
echo "--- End of installer script head ---"
else
echo "Installer script not found in TMP_DIR (checked for ${CMAKE_INSTALLER_SCRIPT_LOCAL_NAME} and ${DERIVED_CMAKE_BINARY_FILENAME})."
fi
echo "Attempting to remove temporary directory: ${TMP_DIR}"
rm -Rf "${TMP_DIR}"
echo "Temporary directory removed."
echo "--- End of Cleanup ---"
else
echo "--- Cleanup: TMP_DIR was not set or not a directory, no temp files to inspect or clean. ---"
fi
# Ensure the script exits with the LAST_EXIT_CODE observed by the trap
# unless it was 0 and the script is exiting due to an explicit non-zero exit.
# The 'exit' command within the trap will override the script's natural exit code.
# So, if the script was going to exit 0, but cleanup had an issue, this could change it.
# However, for debugging an exit code 8, we want to preserve the code that *caused* the trap.
echo "Script finished with exit code: ${LAST_EXIT_CODE}."
exit "${LAST_EXIT_CODE}"
}
trap cleanup EXIT ERR SIGINT SIGTERM
# Immediately turn on `set -e` after trap setup
set -e
# --- Helper Functions ---
# Function to download a file with retries and basic validation
download_file() {
local url="$1"
local output_filename="$2"
local attempts_left=$DOWNLOAD_ATTEMPTS
local wget_exit_code=0
while [ $attempts_left -gt 0 ]; do
echo "Downloading: ${url}"
echo "Saving to: ${TMP_DIR}/${output_filename}"
echo "Attempt $((DOWNLOAD_ATTEMPTS - attempts_left + 1)) of ${DOWNLOAD_ATTEMPTS}..."
# Use wget with:
# -O: specify output file
# --timeout: connection/read timeout
# --tries: number of retries (wget's own retry, distinct from this loop)
# --quiet: suppress normal output, but errors still go to stderr
# --show-progress: if not quiet, shows a progress bar (optional)
# Using -q for less verbose logs, but on failure, we need to know.
wget -O "${TMP_DIR}/${output_filename}" --timeout=30 --tries=1 "${url}"
wget_exit_code=$?
if [ ${wget_exit_code} -eq 0 ]; then
echo "Download command successful for ${output_filename}."
if [ -s "${TMP_DIR}/${output_filename}" ]; then # -s: file exists and has a size greater than 0
# Basic check for common HTML error page indicators
# This is a heuristic and might not catch all error pages.
if head -n 5 "${TMP_DIR}/${output_filename}" | grep -Eiq '<html|<head|<!doctype html|404 Not Found|Error'; then
echo "WARNING: Downloaded file '${output_filename}' might be an HTML error page."
echo "First 5 lines of ${output_filename}:"
head -n 5 "${TMP_DIR}/${output_filename}"
# Consider this a failure for critical files
return 1 # Treat as failure
fi
echo "File ${output_filename} downloaded and is not empty."
return 0 # Success
else
echo "ERROR: Downloaded file ${output_filename} is empty."
# No need to rm here, loop will retry or fail
fi
else
echo "ERROR: wget failed to download ${url} with exit code ${wget_exit_code}."
fi
attempts_left=$((attempts_left - 1))
if [ $attempts_left -gt 0 ]; then
echo "Retrying in ${DOWNLOAD_RETRY_DELAY} seconds..."
sleep $DOWNLOAD_RETRY_DELAY
else
echo "ERROR: Failed to download ${url} after ${DOWNLOAD_ATTEMPTS} attempts."
return 1 # Explicit failure
fi
done
return 1 # Should be unreachable if loop logic is correct, but as a fallback
}
# --- Main Script Logic ---
if [ "${CMAKE_VERSION}" = "none" ]; then
echo "No CMake version specified by argument, skipping CMake reinstallation."
exit 0
fi
echo "CMake version to install: ${CMAKE_VERSION}"
# 1. Ensure wget is available
echo "Checking for wget..."
if ! command -v wget > /dev/null; then
echo "wget not found. Attempting to install wget via apt-get..."
if command -v apt-get > /dev/null; then
apt-get update -y
apt-get install -y --no-install-recommends wget
echo "wget installed."
else
echo "ERROR: apt-get not found. Cannot install wget. Please install wget manually."
exit 1
fi
else
echo "wget is available."
fi
# 2. (Optional) Remove existing CMake installed via apt
echo "Attempting to remove any existing CMake installed via apt..."
if command -v apt-get > /dev/null; then
if dpkg -s cmake &> /dev/null; then # Check if cmake package is actually installed
apt-get -y purge --auto-remove cmake
echo "cmake package purged."
else
echo "cmake package not found via dpkg, skipping purge."
fi
else
echo "apt-get not found, skipping removal of CMake via apt."
fi
# 3. Create installation and temporary directories
echo "Creating CMake installation directory /opt/cmake..."
mkdir -p /opt/cmake
TMP_DIR=$(mktemp -d -t cmake-install-XXXXXXXXXX)
echo "Temporary directory created: ${TMP_DIR}"
# Crucial: subsequent operations needing temp files should happen in or relative to TMP_DIR
# We will cd into TMP_DIR later, or use full paths like ${TMP_DIR}/filename
# 4. Determine system architecture
echo "Determining system architecture..."
architecture=$(dpkg --print-architecture)
case "${architecture}" in
arm64) ARCH="aarch64" ;;
amd64) ARCH="x86_64" ;;
*)
echo "ERROR: Unsupported architecture '${architecture}' reported by dpkg."
exit 1
;;
esac
echo "Detected architecture: ${architecture} (mapped to CMake arch: ${ARCH})"
# 5. Define CMake download URLs and the filename expected by checksum
DERIVED_CMAKE_BINARY_FILENAME="cmake-${CMAKE_VERSION}-linux-${ARCH}.sh"
CMAKE_BINARY_URL="https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/${DERIVED_CMAKE_BINARY_FILENAME}"
CMAKE_CHECKSUM_FILE_URL="https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/cmake-${CMAKE_VERSION}-SHA-256.txt"
# 6. Download CMake binary and checksum file
echo "--- Downloading Files ---"
if ! download_file "${CMAKE_BINARY_URL}" "${CMAKE_INSTALLER_SCRIPT_LOCAL_NAME}"; then
echo "ERROR: Failed to download CMake binary installer. See messages above."
exit 1
fi
if ! download_file "${CMAKE_CHECKSUM_FILE_URL}" "${CMAKE_CHECKSUM_FILE_LOCAL_NAME}"; then
echo "ERROR: Failed to download CMake checksum file. See messages above."
exit 1
fi
echo "Downloads complete."
echo "--- End of Downloading Files ---"
echo # Newline for readability
# Before checksum, rename the downloaded installer to its derived name,
# as the checksum file refers to this specific name.
echo "Renaming downloaded installer from '${CMAKE_INSTALLER_SCRIPT_LOCAL_NAME}' to '${DERIVED_CMAKE_BINARY_FILENAME}' for checksum verification."
mv "${TMP_DIR}/${CMAKE_INSTALLER_SCRIPT_LOCAL_NAME}" "${TMP_DIR}/${DERIVED_CMAKE_BINARY_FILENAME}"
if [ ! -f "${TMP_DIR}/${DERIVED_CMAKE_BINARY_FILENAME}" ]; then
echo "ERROR: Failed to rename installer script for checksum. File '${TMP_DIR}/${DERIVED_CMAKE_BINARY_FILENAME}' does not exist after move."
exit 1
fi
# 7. Verify checksum
echo "--- Verifying Checksum ---"
echo "Checksum file is: ${TMP_DIR}/${CMAKE_CHECKSUM_FILE_LOCAL_NAME}"
echo "Binary file to check is: ${TMP_DIR}/${DERIVED_CMAKE_BINARY_FILENAME}"
# Ensure the checksum file actually contains an entry for our binary
# This is important because the SHA-256.txt file contains checksums for *all* release assets
echo "Checking if checksum file contains entry for '${DERIVED_CMAKE_BINARY_FILENAME}'..."
if ! grep -q "${DERIVED_CMAKE_BINARY_FILENAME}" "${TMP_DIR}/${CMAKE_CHECKSUM_FILE_LOCAL_NAME}"; then
echo "ERROR: The downloaded checksum file '${CMAKE_CHECKSUM_FILE_LOCAL_NAME}' does NOT contain an entry for '${DERIVED_CMAKE_BINARY_FILENAME}'."
echo "This strongly suggests that the CMAKE_VERSION ('${CMAKE_VERSION}') or ARCH ('${ARCH}') is incorrect, or the specified version does not provide a .sh installer for this architecture."
echo "Please verify the version and available files at https://github.com/Kitware/CMake/releases/tag/v${CMAKE_VERSION}"
exit 1
fi
echo "Checksum file contains an entry for '${DERIVED_CMAKE_BINARY_FILENAME}'."
# Perform the checksum. We need to be in the directory where the files are.
echo "Changing directory to ${TMP_DIR} for checksum verification."
cd "${TMP_DIR}" # <<<<<<< IMPORTANT: sha256sum -c needs to find files
echo "Verifying checksum of '${DERIVED_CMAKE_BINARY_FILENAME}' using '${CMAKE_CHECKSUM_FILE_LOCAL_NAME}'..."
# The --ignore-missing flag is good, as the .txt file has many checksums.
# The --strict flag would cause it to error if there are improperly formatted lines.
# We rely on the grep check above to ensure our specific file is mentioned.
if sha256sum -c --ignore-missing "${CMAKE_CHECKSUM_FILE_LOCAL_NAME}"; then
echo "Checksum verification successful for '${DERIVED_CMAKE_BINARY_FILENAME}'."
else
SHA_EXIT_CODE=$?
echo "ERROR: Checksum verification FAILED for '${DERIVED_CMAKE_BINARY_FILENAME}' with exit code ${SHA_EXIT_CODE}."
# Cleanup trap will show file contents.
exit 1 # Critical failure
fi
echo "--- End of Verifying Checksum ---"
echo # Newline for readability
# 8. Install CMake
echo "--- Installing CMake ---"
echo "Making the CMake installer script '${DERIVED_CMAKE_BINARY_FILENAME}' executable..."
chmod +x "${DERIVED_CMAKE_BINARY_FILENAME}" # Still in TMP_DIR
echo "Executing CMake installer script: ./${DERIVED_CMAKE_BINARY_FILENAME} --prefix=/opt/cmake --skip-license"
# Execute the script. If this script exits with 8, this is our culprit.
if ./"${DERIVED_CMAKE_BINARY_FILENAME}" --prefix=/opt/cmake --skip-license; then
echo "CMake installer script executed successfully."
else
INSTALLER_EXIT_CODE=$?
echo "ERROR: CMake installer script FAILED with exit code ${INSTALLER_EXIT_CODE}."
# This is the most likely place for an exit code 8 if downloads and checksums were okay.
# The trap will handle cleanup. The script will exit with INSTALLER_EXIT_CODE due to the trap.
exit ${INSTALLER_EXIT_CODE} # Explicitly exit with the installer's code
fi
echo "--- End of Installing CMake ---"
echo # Newline for readability
# 9. Create symlinks
echo "Creating symbolic links for cmake and ctest in /usr/local/bin/..."
ln -sf /opt/cmake/bin/cmake /usr/local/bin/cmake
ln -sf /opt/cmake/bin/ctest /usr/local/bin/ctest
echo "Symbolic links created."
echo # Newline for readability
echo "SUCCESS: CMake ${CMAKE_VERSION} installation and setup complete."
# The script will exit with 0 here. The trap will run, see $? is 0, and then exit 0.
exit 0

View File

@ -5,7 +5,8 @@
"build": {
"dockerfile": "./Dockerfile",
"args": {
"BASE_IMAGE_NAME": "mcr.microsoft.com/devcontainers/cpp:debian-12"
"BASE_IMAGE_NAME": "mcr.microsoft.com/devcontainers/cpp:2@sha256:a5eb5a1e9109af88bf82ebb0f71903608a68144851ed1e4b852e31b251ac59c6",
"DEBIAN_SNAPSHOT": "20260223T000000Z"
},
"context": "./context"
}

View File

@ -5,7 +5,8 @@
"build": {
"dockerfile": "../Dockerfile",
"args": {
"BASE_IMAGE_NAME": "gcc:9"
"BASE_IMAGE_NAME": "gcc:9",
"DEBIAN_SNAPSHOT": "none"
},
"context": "../context"
}

View File

@ -5,7 +5,8 @@
"build": {
"dockerfile": "../Dockerfile",
"args": {
"BASE_IMAGE_NAME": "gcc:10"
"BASE_IMAGE_NAME": "gcc:10",
"DEBIAN_SNAPSHOT": "none"
},
"context": "../context"
}

View File

@ -5,7 +5,8 @@
"build": {
"dockerfile": "../Dockerfile",
"args": {
"BASE_IMAGE_NAME": "gcc:11"
"BASE_IMAGE_NAME": "gcc:11",
"DEBIAN_SNAPSHOT": "none"
},
"context": "../context"
}

View File

@ -5,7 +5,8 @@
"build": {
"dockerfile": "../Dockerfile",
"args": {
"BASE_IMAGE_NAME": "gcc:12"
"BASE_IMAGE_NAME": "gcc:12",
"DEBIAN_SNAPSHOT": "none"
},
"context": "../context"
}

View File

@ -5,7 +5,8 @@
"build": {
"dockerfile": "../Dockerfile",
"args": {
"BASE_IMAGE_NAME": "gcc:13"
"BASE_IMAGE_NAME": "gcc:13",
"DEBIAN_SNAPSHOT": "none"
},
"context": "../context"
}

View File

@ -5,7 +5,8 @@
"build": {
"dockerfile": "../Dockerfile",
"args": {
"BASE_IMAGE_NAME": "gcc:14"
"BASE_IMAGE_NAME": "gcc:14",
"DEBIAN_SNAPSHOT": "none"
},
"context": "../context"
}

View File

@ -5,7 +5,8 @@
"build": {
"dockerfile": "../Dockerfile",
"args": {
"BASE_IMAGE_NAME": "gcc:15"
"BASE_IMAGE_NAME": "gcc:15",
"DEBIAN_SNAPSHOT": "none"
},
"context": "../context"
}

View File

@ -0,0 +1,61 @@
# 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 \
ca-certificates \
file \
libc6:i386 \
libstdc++6:i386 \
libatomic1:i386 \
&& rm -rf /var/lib/apt/lists/*
# Create non-root user with stable UID/GID
ARG USERNAME=vscode
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
# Install Bazelisk as 'bazel'
RUN ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/') && \
wget -qO /usr/local/bin/bazel https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-linux-${ARCH} && \
chmod +x /usr/local/bin/bazel
# 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"]

View File

@ -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"
}

View File

@ -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")

View File

@ -0,0 +1,85 @@
# 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 <<EOF > /etc/apt/sources.list.d/debian.sources
Types: deb
URIs: http://snapshot.debian.org/archive/debian/20260406T000000Z
Suites: sid
Components: main
Signed-By: /usr/share/keyrings/debian-archive-keyring.pgp
EOF
RUN cat <<EOF > /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 \
libatomic1:powerpc \
&& rm -rf /var/lib/apt/lists/*
# Create non-root user with stable UID/GID
ARG USERNAME=vscode
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
# Install Bazelisk as 'bazel'
RUN ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/') && \
wget -qO /usr/local/bin/bazel https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-linux-${ARCH} && \
chmod +x /usr/local/bin/bazel
# 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"]

View File

@ -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"
}

View File

@ -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")

View File

@ -0,0 +1,61 @@
# 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 \
ca-certificates \
file \
libc6:riscv64 \
libstdc++6:riscv64 \
libatomic1:riscv64 \
&& rm -rf /var/lib/apt/lists/*
# Create non-root user with stable UID/GID
ARG USERNAME=vscode
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
# Install Bazelisk as 'bazel'
RUN ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/') && \
wget -qO /usr/local/bin/bazel https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-linux-${ARCH} && \
chmod +x /usr/local/bin/bazel
# 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"]

View File

@ -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"
}

View File

@ -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")

56
.devcontainer/run-tests.sh Executable file
View File

@ -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 <architecture>"
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

View File

@ -0,0 +1,61 @@
# s390x Big-Endian Test Environment for ETL
# Uses QEMU user-mode emulation to run s390x binaries on x64 host
FROM debian:trixie
# Avoid prompts from apt
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 \
qemu-user-static \
qemu-user \
binfmt-support \
gcc-s390x-linux-gnu \
g++-s390x-linux-gnu \
cmake \
make \
ninja-build \
git \
wget \
ca-certificates \
file \
libc6:s390x \
libstdc++6:s390x \
libatomic1:s390x \
&& rm -rf /var/lib/apt/lists/*
# Create non-root user with stable UID/GID
ARG USERNAME=vscode
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
# Install Bazelisk as 'bazel'
RUN ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/') && \
wget -qO /usr/local/bin/bazel https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-linux-${ARCH} && \
chmod +x /usr/local/bin/bazel
# Verify QEMU and cross-compilation setup
RUN echo "=== Host Architecture ===" && \
uname -m && \
echo "" && \
echo "=== s390x Cross Compiler ===" && \
s390x-linux-gnu-gcc --version && \
echo "" && \
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"]

View File

@ -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": "s390x Big Endian (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/s390x/toolchain-s390x.cmake",
"-DBUILD_TESTS=ON",
"-DNO_STL=OFF",
"-DETL_CXX_STANDARD=23"
],
"cmake.buildDirectory": "${workspaceFolder}/build-s390x",
"cmake.generator": "Ninja"
}
}
},
"remoteUser": "root"
}

View File

@ -0,0 +1,21 @@
# CMake toolchain file for s390x cross-compilation
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR s390x)
# Specify the cross compiler
set(CMAKE_C_COMPILER s390x-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER s390x-linux-gnu-g++)
set(CMAKE_AR s390x-linux-gnu-ar)
set(CMAKE_RANLIB s390x-linux-gnu-ranlib)
set(CMAKE_STRIP s390x-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-s390x-static CACHE FILEPATH "Path to the emulator for cross-compiled binaries")

View File

@ -0,0 +1,20 @@
FROM ubuntu:26.04
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y \
build-essential \
cmake \
git \
ninja-build \
python3 \
python3-pip \
clang \
docker.io \
&& rm -rf /var/lib/apt/lists/*
RUN useradd -m -s /bin/bash vscode
WORKDIR /etl
CMD ["/bin/bash"]

View File

@ -0,0 +1,22 @@
name: bazel-gcc-c++23-no-stl
on:
push:
branches: [ master, development, pull-request/* ]
pull_request:
branches: [ master, development, pull-request/* ]
types: [opened, synchronize, reopened]
jobs:
build-bazel-gcc-cpp23-no-stl:
name: Bazel GCC C++23 Linux - No STL
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Build
run: bazel build //test:etl_tests --cxxopt=-std=c++23 --copt=-DETL_NO_STL
- name: Run tests
run: bazel test //test:etl_tests --cxxopt=-std=c++23 --copt=-DETL_NO_STL --test_output=all

View File

@ -3,7 +3,7 @@ on:
push:
branches: [ master, development, pull-request/* ]
pull_request:
branches: [ master, pull-request/* ]
branches: [ master, development, pull-request/* ]
types: [opened, synchronize, reopened]
jobs:
@ -25,10 +25,10 @@ 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
run: ./test/etl_tests -v
build-clang-cpp11-linux-no-stl:
name: Clang C++11 Linux - No STL
@ -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
run: ./test/etl_tests -v

View File

@ -3,7 +3,7 @@ on:
push:
branches: [ master, development, pull-request/* ]
pull_request:
branches: [ master, pull-request/* ]
branches: [ master, development, pull-request/* ]
types: [opened, synchronize, reopened]
jobs:
@ -25,10 +25,10 @@ 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
run: ./test/etl_tests -v
build-clang-cpp14-linux-no-stl:
name: Clang C++14 Linux - No STL
@ -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
run: ./test/etl_tests -v

View File

@ -3,7 +3,7 @@ on:
push:
branches: [ master, development, pull-request/* ]
pull_request:
branches: [ master, pull-request/* ]
branches: [ master, development, pull-request/* ]
types: [opened, synchronize, reopened]
jobs:
@ -25,10 +25,10 @@ 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
run: ./test/etl_tests -v
build-clang-cpp17-linux-no-stl:
name: Clang C++17 Linux - No STL
@ -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
run: ./test/etl_tests -v

View File

@ -3,7 +3,7 @@ on:
push:
branches: [ master, development, pull-request/* ]
pull_request:
branches: [ master, pull-request/* ]
branches: [ master, development, pull-request/* ]
types: [opened, synchronize, reopened]
jobs:
@ -32,10 +32,10 @@ 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
run: ./test/etl_tests -v
build-clang-cpp20-linux-stl-force-cpp03:
name: Clang C++20 Linux - STL - Force C++03
@ -61,10 +61,10 @@ 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
run: ./test/etl_tests -v
build-clang-cpp20-linux-no-stl-force-cpp03:
name: Clang C++20 Linux - No STL - Force C++03
@ -90,17 +90,17 @@ 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
run: ./test/etl_tests -v
build-clang-cpp20-osx-stl:
name: Clang C++20 OSX - STL
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macos-13]
os: [macos-15]
steps:
- uses: actions/checkout@v4
@ -112,17 +112,17 @@ 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
run: ./test/etl_tests -v
build-clang-cpp20-osx-no-stl:
name: Clang C++20 OSX - No STL
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macos-13]
os: [macos-15]
steps:
- uses: actions/checkout@v4
@ -134,17 +134,17 @@ 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
run: ./test/etl_tests -v
build-clang-cpp20-osx-stl-force-cpp03:
name: Clang C++20 OSX - STL - Force C++03
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macos-13]
os: [macos-15]
steps:
- uses: actions/checkout@v4
@ -156,17 +156,17 @@ 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
run: ./test/etl_tests -v
build-clang-cpp20-osx-no-stl-force-cpp03:
name: Clang C++20 OSX - No STL - Force C++03
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macos-13]
os: [macos-15]
steps:
- uses: actions/checkout@v4
@ -178,8 +178,8 @@ 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
run: ./test/etl_tests -v

View File

@ -3,7 +3,8 @@ on:
push:
branches: [ master, development, pull-request/* ]
pull_request:
branches: [ master, pull-request/* ]
branches: [ master, development, pull-request/* ]
types: [opened, synchronize, reopened]
jobs:
@ -12,94 +13,73 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-22.04]
os: [ubuntu-24.04]
steps:
- uses: actions/checkout@v4
# Temporary fix. See https://github.com/actions/runner-images/issues/8659
- name: Install newer Clang
run: |
wget https://apt.llvm.org/llvm.sh
chmod +x ./llvm.sh
sudo ./llvm.sh 17
- name: Build
run: |
export CC=clang-17
export CXX=clang++-17
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=OFF -DETL_CXX_STANDARD=23 ./
clang-17 --version
make -j $(getconf _NPROCESSORS_ONLN)
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 -DETL_OPTIMISATION=-O3 ./
clang --version
make -j "$(getconf _NPROCESSORS_ONLN)"
- name: Run tests
run: ./test/etl_tests
run: ./test/etl_tests -v
build-clang-cpp23-linux-stl-force-cpp03:
name: Clang C++23 Linux - STL - Force C++03
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-22.04]
os: [ubuntu-24.04]
steps:
- uses: actions/checkout@v4
# Temporary fix. See https://github.com/actions/runner-images/issues/8659
- name: Install newer Clang
run: |
wget https://apt.llvm.org/llvm.sh
chmod +x ./llvm.sh
sudo ./llvm.sh 17
- name: Build
run: |
export CC=clang-17
export CXX=clang++-17
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 ./
clang-17 --version
make -j $(getconf _NPROCESSORS_ONLN)
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 -DETL_OPTIMISATION=-O3 ./
clang --version
make -j "$(getconf _NPROCESSORS_ONLN)"
- name: Run tests
run: ./test/etl_tests
run: ./test/etl_tests -v
build-clang-cpp2-linux-no-stl-force-cpp03:
name: Clang C++23 Linux - No STL - Force C++03
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-22.04]
os: [ubuntu-24.04]
steps:
- uses: actions/checkout@v4
# Temporary fix. See https://github.com/actions/runner-images/issues/8659
- name: Install newer Clang
run: |
wget https://apt.llvm.org/llvm.sh
chmod +x ./llvm.sh
sudo ./llvm.sh 17
- name: Build
run: |
export CC=clang-17
export CXX=clang++-17
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 ./
clang-17 --version
make -j $(getconf _NPROCESSORS_ONLN)
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 -DETL_OPTIMISATION=-O3 ./
clang --version
make -j "$(getconf _NPROCESSORS_ONLN)"
- name: Run tests
run: ./test/etl_tests
run: ./test/etl_tests -v
build-clang-cpp23-osx-stl:
name: Clang C++23 OSX - STL
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macos-13]
os: [macos-15]
steps:
- uses: actions/checkout@v4
@ -109,19 +89,19 @@ 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 -DETL_OPTIMISATION=-O3 ./
clang --version
make -j $(getconf _NPROCESSORS_ONLN)
make -j "$(getconf _NPROCESSORS_ONLN)"
- name: Run tests
run: ./test/etl_tests
run: ./test/etl_tests -v
build-clang-cpp23-osx-no-stl:
name: Clang C++23 OSX - No STL
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macos-13]
os: [macos-15]
steps:
- uses: actions/checkout@v4
@ -131,19 +111,19 @@ 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 -DETL_OPTIMISATION=-O3 ./
clang --version
make -j $(getconf _NPROCESSORS_ONLN)
make -j "$(getconf _NPROCESSORS_ONLN)"
- name: Run tests
run: ./test/etl_tests
run: ./test/etl_tests -v
build-clang-cpp23-osx-stl-force-cpp03:
name: Clang C++23 OSX - STL - Force C++03
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macos-13]
os: [macos-15]
steps:
- uses: actions/checkout@v4
@ -153,19 +133,19 @@ 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 -DETL_OPTIMISATION=-O3 ./
clang --version
make -j $(getconf _NPROCESSORS_ONLN)
make -j "$(getconf _NPROCESSORS_ONLN)"
- name: Run tests
run: ./test/etl_tests
run: ./test/etl_tests -v
build-clang-cpp23-osx-no-stl-force-cpp03:
name: Clang C++23 OSX - No STL - Force C++03
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macos-13]
os: [macos-15]
steps:
- uses: actions/checkout@v4
@ -175,10 +155,10 @@ 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 -DETL_OPTIMISATION=-O3 ./
clang --version
make -j $(getconf _NPROCESSORS_ONLN)
make -j "$(getconf _NPROCESSORS_ONLN)"
- name: Run tests
run: ./test/etl_tests
run: ./test/etl_tests -v

185
.github/workflows/clang-c++26.yml vendored Normal file
View File

@ -0,0 +1,185 @@
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
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: docker build -t etl-ubuntu-2604 -f .devcontainer/ubuntu-26.04/Dockerfile .
- name: Build and run tests
run: |
docker run --rm --user root -v ${{ github.workspace }}:/workspaces/etl etl-ubuntu-2604 bash -c "\
cd /workspaces/etl && \
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) && \
./test/etl_tests -v"
build-clang-cpp26-linux-no-stl:
name: Clang C++26 Linux - No STL
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: docker build -t etl-ubuntu-2604 -f .devcontainer/ubuntu-26.04/Dockerfile .
- name: Build and run tests
run: |
docker run --rm --user root -v ${{ github.workspace }}:/workspaces/etl etl-ubuntu-2604 bash -c "\
cd /workspaces/etl && \
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) && \
./test/etl_tests -v"
build-clang-cpp26-linux-stl-force-cpp03:
name: Clang C++26 Linux - STL - Force C++03
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: docker build -t etl-ubuntu-2604 -f .devcontainer/ubuntu-26.04/Dockerfile .
- name: Build and run tests
run: |
docker run --rm --user root -v ${{ github.workspace }}:/workspaces/etl etl-ubuntu-2604 bash -c "\
cd /workspaces/etl && \
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=ON -DETL_CXX_STANDARD=26 ./ && \
clang --version && \
make -j \$(getconf _NPROCESSORS_ONLN) && \
./test/etl_tests -v"
build-clang-cpp26-linux-no-stl-force-cpp03:
name: Clang C++26 Linux - No STL - Force C++03
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: docker build -t etl-ubuntu-2604 -f .devcontainer/ubuntu-26.04/Dockerfile .
- name: Build and run tests
run: |
docker run --rm --user root -v ${{ github.workspace }}:/workspaces/etl etl-ubuntu-2604 bash -c "\
cd /workspaces/etl && \
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=ON -DETL_CXX_STANDARD=26 ./ && \
clang --version && \
make -j \$(getconf _NPROCESSORS_ONLN) && \
./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

43
.github/workflows/clang-format.yaml vendored Normal file
View File

@ -0,0 +1,43 @@
name: clang-format
on:
push:
branches: [ master, development, pull-request/* ]
pull_request:
branches: [ master, development, pull-request/* ]
types: [opened, synchronize, reopened]
jobs:
clang-format:
name: clang-format
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install clang-format and git
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends git clang-format
clang-format --version
- name: Run clang-format on added/changed files
run: |
if [ "${{ github.event_name }}" = "pull_request" ]; then
BEFORE="origin/${{ github.base_ref }}"
elif [ "${{ github.event_name }}" = "push" ]; then
BEFORE="${{ github.event.before }}"
else
echo "Unsupported event: ${{ github.event_name }}"
echo "This is likely a bug in the workflow configuration. Please report it to the maintainers."
exit 1
fi
git diff --name-only -z --diff-filter=AMCR "$BEFORE"..HEAD -- \
'*.c' '*.cc' '*.cxx' '*.cpp' \
'*.h' '*.hh' '*.hpp' '*.hxx' \
'*.ipp' '*.inl' \
':(exclude)include/etl/generators/*' \
':(exclude)include/etl/private/*_cpp03.h' \
| xargs -0 --no-run-if-empty clang-format --Werror -n --style=file

View File

@ -0,0 +1,21 @@
name: clang-format-update
on:
workflow_dispatch:
jobs:
clang-format:
runs-on: ubuntu-24.04
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install clang-format
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends clang-format
clang-format --version
- name: Run clang-format
run: |
find . \( -name '*.cpp' -o -name '*.h' -o -name '*.c' \) | xargs clang-format --dry-run --Werror

View File

@ -3,7 +3,7 @@ on:
push:
branches: [ master, development, pull-request/* ]
pull_request:
branches: [ master, pull-request/* ]
branches: [ master, development, pull-request/* ]
types: [opened, synchronize, reopened]
jobs:
@ -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,84 @@ 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
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: docker build -t etl-ubuntu-2604 -f .devcontainer/ubuntu-26.04/Dockerfile .
- name: Build
run: |
docker run --rm --user root -v ${{ github.workspace }}:/workspaces/etl etl-ubuntu-2604 bash -c "\
cd /workspaces/etl && \
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
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: docker build -t etl-ubuntu-2604 -f .devcontainer/ubuntu-26.04/Dockerfile .
- name: Build
run: |
docker run --rm --user root -v ${{ github.workspace }}:/workspaces/etl etl-ubuntu-2604 bash -c "\
cd /workspaces/etl && \
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
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: docker build -t etl-ubuntu-2604 -f .devcontainer/ubuntu-26.04/Dockerfile .
- name: Build
run: |
docker run --rm --user root -v ${{ github.workspace }}:/workspaces/etl etl-ubuntu-2604 bash -c "\
cd /workspaces/etl && \
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
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: docker build -t etl-ubuntu-2604 -f .devcontainer/ubuntu-26.04/Dockerfile .
- name: Build
run: |
docker run --rm --user root -v ${{ github.workspace }}:/workspaces/etl etl-ubuntu-2604 bash -c "\
cd /workspaces/etl && \
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)"

29
.github/workflows/clang-tidy.yaml vendored Normal file
View File

@ -0,0 +1,29 @@
name: clang-tidy
on:
push:
branches: [ master, development, pull-request/* ]
pull_request:
branches: [ master, development, pull-request/* ]
types: [opened, synchronize, reopened]
jobs:
clang-tidy:
name: clang-tidy
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends clang clang-tidy
clang --version
clang-tidy --version
run-clang-tidy --version || true
- name: Run clang-tidy
run: |
test/run-clang-tidy.sh

68
.github/workflows/coverage.yml vendored Normal file
View File

@ -0,0 +1,68 @@
name: coverage
on:
push:
branches: [ master, pull-request/* ]
pull_request:
branches: [ master, pull-request/* ]
types: [opened, synchronize, reopened]
# Allow only one concurrent deployment to GitHub Pages
concurrency:
group: coverage-${{ github.ref }}
cancel-in-progress: true
# Grant GITHUB_TOKEN the minimum permissions needed at the workflow level
permissions:
contents: read
jobs:
coverage:
name: Generate Coverage Report
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y lcov llvm gcc g++ clang cmake
- name: Build, test, and collect coverage
run: |
cd test
./run-coverage.sh
- name: Upload coverage report artifact
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: test/build-coverage/coverage/
retention-days: 30
- name: Upload Pages artifact
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: actions/upload-pages-artifact@v3
with:
path: test/build-coverage/coverage/
deploy-pages:
name: Deploy to GitHub Pages
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
needs: coverage
runs-on: ubuntu-22.04
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v5

View File

@ -3,7 +3,7 @@ on:
push:
branches: [ master, development, pull-request/* ]
pull_request:
branches: [ master, pull-request/* ]
branches: [ master, development, pull-request/* ]
types: [opened, synchronize, reopened]
jobs:
@ -26,10 +26,10 @@ 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
run: ./test/etl_tests -v
build-gcc-cpp11-linux-no-stl:
name: GCC C++11 Linux - No STL
@ -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
run: ./test/etl_tests -v

View File

@ -3,7 +3,7 @@ on:
push:
branches: [ master, development, pull-request/* ]
pull_request:
branches: [ master, pull-request/* ]
branches: [ master, development, pull-request/* ]
types: [opened, synchronize, reopened]
jobs:
@ -25,10 +25,10 @@ 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
run: ./test/etl_tests -v
build-gcc-cpp14-linux-no-stl:
name: GCC C++14 Linux - No STL
@ -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
run: ./test/etl_tests -v

View File

@ -3,7 +3,7 @@ on:
push:
branches: [ master, development, pull-request/* ]
pull_request:
branches: [ master, pull-request/* ]
branches: [ master, development, pull-request/* ]
types: [opened, synchronize, reopened]
jobs:
@ -25,10 +25,10 @@ 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
run: ./test/etl_tests -v
build-gcc-cpp17-linux-no-stl:
name: GCC C++17 Linux - No STL
@ -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
run: ./test/etl_tests -v

View File

@ -3,7 +3,7 @@ on:
push:
branches: [ master, development, pull-request/* ]
pull_request:
branches: [ master, pull-request/* ]
branches: [ master, development, pull-request/* ]
types: [opened, synchronize, reopened]
jobs:
@ -25,10 +25,10 @@ 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
run: ./test/etl_tests -v
build-gcc-cpp20-linux-no-stl:
name: GCC C++20 Linux - No STL
@ -47,10 +47,10 @@ 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
run: ./test/etl_tests -v
build-gcc-cpp20-linux-stl-force-cpp03:
name: GCC C++20 Linux - STL - Force C++03
@ -69,10 +69,10 @@ 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
run: ./test/etl_tests -v
build-gcc-cpp20-linux-no-stl-force-cpp03:
name: GCC C++20 Linux - No STL - Force C++03
@ -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
run: ./test/etl_tests -v

29
.github/workflows/gcc-c++23-armhf.yml vendored Normal file
View File

@ -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"

29
.github/workflows/gcc-c++23-i386.yml vendored Normal file
View File

@ -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"

29
.github/workflows/gcc-c++23-powerpc.yml vendored Normal file
View File

@ -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"

29
.github/workflows/gcc-c++23-riscv64.yml vendored Normal file
View File

@ -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"

29
.github/workflows/gcc-c++23-s390x.yml vendored Normal file
View File

@ -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"

View File

@ -3,7 +3,8 @@ on:
push:
branches: [ master, development, pull-request/* ]
pull_request:
branches: [ master, pull-request/* ]
branches: [ master, development, pull-request/* ]
types: [opened, synchronize, reopened]
jobs:
@ -12,7 +13,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-22.04]
os: [ubuntu-24.04]
steps:
- uses: actions/checkout@v4
@ -22,19 +23,19 @@ 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 -DETL_OPTIMISATION=-O3 ./
gcc --version
make -j $(getconf _NPROCESSORS_ONLN)
make -j "$(getconf _NPROCESSORS_ONLN)"
- name: Run tests
run: ./test/etl_tests
run: ./test/etl_tests -v
build-gcc-cpp23-linux-no-stl:
name: GCC C++23 Linux - No STL
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-22.04]
os: [ubuntu-24.04]
steps:
- uses: actions/checkout@v4
@ -44,19 +45,19 @@ 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 -DETL_OPTIMISATION=-O3 ./
gcc --version
make -j $(getconf _NPROCESSORS_ONLN)
make -j "$(getconf _NPROCESSORS_ONLN)"
- name: Run tests
run: ./test/etl_tests
run: ./test/etl_tests -v
build-gcc-cpp23-linux-stl-force-cpp03:
name: GCC C++23 Linux - STL - Force C++03
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-22.04]
os: [ubuntu-24.04]
steps:
- uses: actions/checkout@v4
@ -66,19 +67,19 @@ 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 -DETL_OPTIMISATION=-O3 ./
gcc --version
make -j $(getconf _NPROCESSORS_ONLN)
make -j "$(getconf _NPROCESSORS_ONLN)"
- name: Run tests
run: ./test/etl_tests
run: ./test/etl_tests -v
build-gcc-cpp23-linux-no-stl-force-cpp03:
name: GCC C++23 Linux - No STL - Force C++03
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-22.04]
os: [ubuntu-24.04]
steps:
- uses: actions/checkout@v4
@ -88,9 +89,9 @@ 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 -DETL_OPTIMISATION=-O3 ./
gcc --version
make -j $(getconf _NPROCESSORS_ONLN)
make -j "$(getconf _NPROCESSORS_ONLN)"
- name: Run tests
run: ./test/etl_tests
run: ./test/etl_tests -v

97
.github/workflows/gcc-c++26.yml vendored Normal file
View File

@ -0,0 +1,97 @@
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
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: docker build -t etl-ubuntu-2604 -f .devcontainer/ubuntu-26.04/Dockerfile .
- name: Build and run tests
run: |
docker run --rm --user root -v ${{ github.workspace }}:/workspaces/etl etl-ubuntu-2604 bash -c "\
cd /workspaces/etl && \
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) && \
./test/etl_tests -v"
build-gcc-cpp26-linux-no-stl:
name: GCC C++26 Linux - No STL
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: docker build -t etl-ubuntu-2604 -f .devcontainer/ubuntu-26.04/Dockerfile .
- name: Build and run tests
run: |
docker run --rm --user root -v ${{ github.workspace }}:/workspaces/etl etl-ubuntu-2604 bash -c "\
cd /workspaces/etl && \
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) && \
./test/etl_tests -v"
build-gcc-cpp26-linux-stl-force-cpp03:
name: GCC C++26 Linux - STL - Force C++03
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: docker build -t etl-ubuntu-2604 -f .devcontainer/ubuntu-26.04/Dockerfile .
- name: Build and run tests
run: |
docker run --rm --user root -v ${{ github.workspace }}:/workspaces/etl etl-ubuntu-2604 bash -c "\
cd /workspaces/etl && \
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) && \
./test/etl_tests -v"
build-gcc-cpp26-linux-no-stl-force-cpp03:
name: GCC C++26 Linux - No STL - Force C++03
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: docker build -t etl-ubuntu-2604 -f .devcontainer/ubuntu-26.04/Dockerfile .
- name: Build and run tests
run: |
docker run --rm --user root -v ${{ github.workspace }}:/workspaces/etl etl-ubuntu-2604 bash -c "\
cd /workspaces/etl && \
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) && \
./test/etl_tests -v"

View File

@ -3,7 +3,7 @@ on:
push:
branches: [ master, development, pull-request/* ]
pull_request:
branches: [ master, pull-request/* ]
branches: [ master, development, pull-request/* ]
types: [opened, synchronize, reopened]
jobs:
@ -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,84 @@ 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)
make -j "$(getconf _NPROCESSORS_ONLN)"
build-gcc-cpp26-linux-STL:
name: Syntax Check - GCC C++26 Linux STL
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: docker build -t etl-ubuntu-2604 -f .devcontainer/ubuntu-26.04/Dockerfile .
- name: Build
run: |
docker run --rm --user root -v ${{ github.workspace }}:/workspaces/etl etl-ubuntu-2604 bash -c "\
cd /workspaces/etl && \
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
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: docker build -t etl-ubuntu-2604 -f .devcontainer/ubuntu-26.04/Dockerfile .
- name: Build
run: |
docker run --rm --user root -v ${{ github.workspace }}:/workspaces/etl etl-ubuntu-2604 bash -c "\
cd /workspaces/etl && \
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
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: docker build -t etl-ubuntu-2604 -f .devcontainer/ubuntu-26.04/Dockerfile .
- name: Build
run: |
docker run --rm --user root -v ${{ github.workspace }}:/workspaces/etl etl-ubuntu-2604 bash -c "\
cd /workspaces/etl && \
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
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: docker build -t etl-ubuntu-2604 -f .devcontainer/ubuntu-26.04/Dockerfile .
- name: Build
run: |
docker run --rm --user root -v ${{ github.workspace }}:/workspaces/etl etl-ubuntu-2604 bash -c "\
cd /workspaces/etl && \
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)"

24
.github/workflows/generator.yml vendored Normal file
View File

@ -0,0 +1,24 @@
name: generator checks
on:
push:
branches: [ master, development, pull-request/* ]
pull_request:
branches: [ master, pull-request/* ]
types: [opened, synchronize, reopened]
jobs:
generator-run:
name: Header Generator
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y python3-cogapp
- name: Run generator_test.py
run: |
cd scripts && python3 generator_test.py

View File

@ -0,0 +1,31 @@
name: meson-gcc-c++23-no-stl
on:
push:
branches: [ master, development, pull-request/* ]
pull_request:
branches: [ master, development, pull-request/* ]
types: [opened, synchronize, reopened]
jobs:
build-meson-gcc-cpp23-no-stl:
name: Meson GCC C++23 Linux - No STL
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v6
- name: Install Meson
run: sudo apt-get install -y meson
- name: Configure
run: |
export CC=gcc
export CXX=g++
meson setup builddir -Duse_stl=false -Dcpp_std=c++23
- name: Build
run: meson compile -C builddir
- name: Run tests
run: meson test -C builddir -v

View File

@ -3,7 +3,7 @@ on:
push:
branches: [ master, development, pull-request/* ]
pull_request:
branches: [ master, pull-request/* ]
branches: [ master, development, pull-request/* ]
types: [opened, synchronize, reopened]
jobs:
@ -22,12 +22,12 @@ jobs:
- name: Build
run: |
cmake -G "Visual Studio 17 2022" -AWin32 -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 ./
cmake -G "Visual Studio 17 2022" -AWin32 -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 ./
MSBuild.exe -version
MSBuild.exe .\etl.sln
- name: Run tests
run: test/Debug/etl_tests.exe
run: test/Debug/etl_tests.exe -v
build-windows-msvc-no-stl:
name: Windows - No STL
@ -48,7 +48,7 @@ jobs:
MSBuild.exe .\etl.sln
- name: Run tests
run: test/Debug/etl_tests.exe
run: test/Debug/etl_tests.exe -v
build-windows-msvc-stl-force-cpp03:
name: Windows - STL - Force C++03
@ -70,7 +70,7 @@ jobs:
MSBuild.exe .\etl.sln
- name: Run tests
run: test/Debug/etl_tests.exe
run: test/Debug/etl_tests.exe -v
build-windows-msvc-no-stl-force-cpp03:
name: Windows - No STL - Force C++03
@ -92,5 +92,5 @@ jobs:
MSBuild.exe .\etl.sln
- name: Run tests
run: test/Debug/etl_tests.exe
run: test/Debug/etl_tests.exe -v

8
.gitignore vendored
View File

@ -3,6 +3,8 @@
## Personal
#################
docs/html
hugo/public
hugo/.hugo_build.lock
include/etl/html/
include/etl/latex/
test/vs2013/Debug
@ -411,3 +413,9 @@ examples/UniquePtrWithPool/UniquePtrWithPool
test/vs2022/Debug Clang C++20 - Optimised -O2
include/etl/header_file_list.txt
temp
test/syntax_check/build-make
hugo/public
hugo/resources
hugo/.hugo_build.lock
docs/*.html
test/build-coverage

45
.treefmt.toml Normal file
View File

@ -0,0 +1,45 @@
[global]
excludes = [
"**/Doxyfile",
"**/Makefile",
"*.*-format",
"*.S",
"*.cmm",
"*.css",
"*.dld",
"*.gdb",
"*.gif",
"*.gitignore",
"*.html",
"*.ini",
"*.josh",
"*.json",
"*.md",
"*.png",
"*.puml",
"*.py",
"*.rb",
"*.rst",
"*.s",
"*.sh",
"*.spec",
"*.toml",
"*.txt",
"*.yaml",
"*.yml",
"docker/**",
"temp/**",
"scripts/clang-format-wrapper",
"include/etl/generators/**",
"include/etl/private/*_cpp03.h",
"subprojects/**",
"test/UnitTest++/**",
"test/Deprecated/**",
"test/Performance/**",
"test/temp/**"
]
[formatter.cpp]
command = "scripts/clang-format-wrapper"
options = [ "-i", "--style=file" ]
includes = [ "*.c", "*.cc", "*.cpp", "*.h", "*.hh", "*.hpp" ]

9
BUILD.bazel Normal file
View File

@ -0,0 +1,9 @@
load("@rules_cc//cc:defs.bzl", "cc_library")
package(default_visibility = ["//visibility:public"])
cc_library(
name = "etl",
hdrs = glob(["include/**/*.h"]),
includes = ["include"],
)

View File

@ -1,13 +1,17 @@
# How to contribute
If your are considering creating a pull request, please observe the following:
Thanks for considering a contribution! Heres what you need to know before opening a pull request:
- If you are adding or modifying a feature, add *new* unit tests that test that feature.
- If you are fixing a bug, add a unit test that *fails* before the bug fix is implemented.
- Do not initiate a pull request until all of the units tests pass.
- Branches should be based on the branch `master`.
- Do not initiate a pull request until all of the units tests pass. See below for information on project files and test scripts.
- Branches should be based on the branch `master`. If `development` has pending updates, Ill rebase the PR against it before pulling..
- For formatting help, you can use clang-format, or the convenience wrapper treefmt. See also [docs/source-formatting.md](docs/source-formatting.md)
There is a project file for VS2022 for C++14, 17, 20, and bash scripts that run the tests for C++11, 14, 17, 20 under Linux with GCC and Clang.
There is a project file for VS2022 for C++14, 17, 20, 23, and bash scripts that run the tests for C++11, 14, 17, 20, 23 under Linux with GCC and Clang.
There are syntax-only check bash scripts that cover C++03, 11, 14, 17, 20, 23 under Linux with GCC and Clang.
If you are thinking of adding a new feature then raise this on the GitHub Issues page for discussion as the maintainers and user of the ETL may have questions or suggestions.
It is possible that the maintainer of the ETL or another contributor is already working on the same or a related feature.
It is possible that the maintainer of the ETL or another contributor is already working on the same or a related feature.
Take a look through our current issues and see if anything sparks your interest!

7
MODULE.bazel Normal file
View File

@ -0,0 +1,7 @@
module(
name = "etl",
version = "0.0.0",
)
bazel_dep(name = "platforms", version = "0.0.11")
bazel_dep(name = "rules_cc", version = "0.1.1")

205
MODULE.bazel.lock generated Normal file
View File

@ -0,0 +1,205 @@
{
"lockFileVersion": 24,
"registryFileHashes": {
"https://bcr.bazel.build/bazel_registry.json": "8a28e4aff06ee60aed2a8c281907fb8bcbf3b753c91fb5a5c57da3215d5b3497",
"https://bcr.bazel.build/modules/abseil-cpp/20210324.2/MODULE.bazel": "7cd0312e064fde87c8d1cd79ba06c876bd23630c83466e9500321be55c96ace2",
"https://bcr.bazel.build/modules/abseil-cpp/20211102.0/MODULE.bazel": "70390338f7a5106231d20620712f7cccb659cd0e9d073d1991c038eb9fc57589",
"https://bcr.bazel.build/modules/abseil-cpp/20230125.1/MODULE.bazel": "89047429cb0207707b2dface14ba7f8df85273d484c2572755be4bab7ce9c3a0",
"https://bcr.bazel.build/modules/abseil-cpp/20230802.0.bcr.1/MODULE.bazel": "1c8cec495288dccd14fdae6e3f95f772c1c91857047a098fad772034264cc8cb",
"https://bcr.bazel.build/modules/abseil-cpp/20230802.0/MODULE.bazel": "d253ae36a8bd9ee3c5955384096ccb6baf16a1b1e93e858370da0a3b94f77c16",
"https://bcr.bazel.build/modules/abseil-cpp/20230802.1/MODULE.bazel": "fa92e2eb41a04df73cdabeec37107316f7e5272650f81d6cc096418fe647b915",
"https://bcr.bazel.build/modules/abseil-cpp/20240116.1/MODULE.bazel": "37bcdb4440fbb61df6a1c296ae01b327f19e9bb521f9b8e26ec854b6f97309ed",
"https://bcr.bazel.build/modules/abseil-cpp/20240116.1/source.json": "9be551b8d4e3ef76875c0d744b5d6a504a27e3ae67bc6b28f46415fd2d2957da",
"https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd",
"https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8",
"https://bcr.bazel.build/modules/bazel_features/1.15.0/MODULE.bazel": "d38ff6e517149dc509406aca0db3ad1efdd890a85e049585b7234d04238e2a4d",
"https://bcr.bazel.build/modules/bazel_features/1.17.0/MODULE.bazel": "039de32d21b816b47bd42c778e0454217e9c9caac4a3cf8e15c7231ee3ddee4d",
"https://bcr.bazel.build/modules/bazel_features/1.18.0/MODULE.bazel": "1be0ae2557ab3a72a57aeb31b29be347bcdc5d2b1eb1e70f39e3851a7e97041a",
"https://bcr.bazel.build/modules/bazel_features/1.19.0/MODULE.bazel": "59adcdf28230d220f0067b1f435b8537dd033bfff8db21335ef9217919c7fb58",
"https://bcr.bazel.build/modules/bazel_features/1.30.0/MODULE.bazel": "a14b62d05969a293b80257e72e597c2da7f717e1e69fa8b339703ed6731bec87",
"https://bcr.bazel.build/modules/bazel_features/1.30.0/source.json": "b07e17f067fe4f69f90b03b36ef1e08fe0d1f3cac254c1241a1818773e3423bc",
"https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7",
"https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a",
"https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8",
"https://bcr.bazel.build/modules/bazel_skylib/1.1.1/MODULE.bazel": "1add3e7d93ff2e6998f9e118022c84d163917d912f5afafb3058e3d2f1545b5e",
"https://bcr.bazel.build/modules/bazel_skylib/1.2.0/MODULE.bazel": "44fe84260e454ed94ad326352a698422dbe372b21a1ac9f3eab76eb531223686",
"https://bcr.bazel.build/modules/bazel_skylib/1.2.1/MODULE.bazel": "f35baf9da0efe45fa3da1696ae906eea3d615ad41e2e3def4aeb4e8bc0ef9a7a",
"https://bcr.bazel.build/modules/bazel_skylib/1.3.0/MODULE.bazel": "20228b92868bf5cfc41bda7afc8a8ba2a543201851de39d990ec957b513579c5",
"https://bcr.bazel.build/modules/bazel_skylib/1.4.1/MODULE.bazel": "a0dcb779424be33100dcae821e9e27e4f2901d9dfd5333efe5ac6a8d7ab75e1d",
"https://bcr.bazel.build/modules/bazel_skylib/1.4.2/MODULE.bazel": "3bd40978e7a1fac911d5989e6b09d8f64921865a45822d8b09e815eaa726a651",
"https://bcr.bazel.build/modules/bazel_skylib/1.5.0/MODULE.bazel": "32880f5e2945ce6a03d1fbd588e9198c0a959bb42297b2cfaf1685b7bc32e138",
"https://bcr.bazel.build/modules/bazel_skylib/1.6.1/MODULE.bazel": "8fdee2dbaace6c252131c00e1de4b165dc65af02ea278476187765e1a617b917",
"https://bcr.bazel.build/modules/bazel_skylib/1.7.0/MODULE.bazel": "0db596f4563de7938de764cc8deeabec291f55e8ec15299718b93c4423e9796d",
"https://bcr.bazel.build/modules/bazel_skylib/1.7.1/MODULE.bazel": "3120d80c5861aa616222ec015332e5f8d3171e062e3e804a2a0253e1be26e59b",
"https://bcr.bazel.build/modules/bazel_skylib/1.7.1/source.json": "f121b43eeefc7c29efbd51b83d08631e2347297c95aac9764a701f2a6a2bb953",
"https://bcr.bazel.build/modules/buildozer/7.1.2/MODULE.bazel": "2e8dd40ede9c454042645fd8d8d0cd1527966aa5c919de86661e62953cd73d84",
"https://bcr.bazel.build/modules/buildozer/7.1.2/source.json": "c9028a501d2db85793a6996205c8de120944f50a0d570438fcae0457a5f9d1f8",
"https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb",
"https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4",
"https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6",
"https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/source.json": "41e9e129f80d8c8bf103a7acc337b76e54fad1214ac0a7084bf24f4cd924b8b4",
"https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f",
"https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075",
"https://bcr.bazel.build/modules/jsoncpp/1.9.5/source.json": "4108ee5085dd2885a341c7fab149429db457b3169b86eb081fa245eadf69169d",
"https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902",
"https://bcr.bazel.build/modules/platforms/0.0.10/MODULE.bazel": "8cb8efaf200bdeb2150d93e162c40f388529a25852b332cec879373771e48ed5",
"https://bcr.bazel.build/modules/platforms/0.0.11/MODULE.bazel": "0daefc49732e227caa8bfa834d65dc52e8cc18a2faf80df25e8caea151a9413f",
"https://bcr.bazel.build/modules/platforms/0.0.11/source.json": "f7e188b79ebedebfe75e9e1d098b8845226c7992b307e28e1496f23112e8fc29",
"https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee",
"https://bcr.bazel.build/modules/platforms/0.0.5/MODULE.bazel": "5733b54ea419d5eaf7997054bb55f6a1d0b5ff8aedf0176fef9eea44f3acda37",
"https://bcr.bazel.build/modules/platforms/0.0.6/MODULE.bazel": "ad6eeef431dc52aefd2d77ed20a4b353f8ebf0f4ecdd26a807d2da5aa8cd0615",
"https://bcr.bazel.build/modules/platforms/0.0.7/MODULE.bazel": "72fd4a0ede9ee5c021f6a8dd92b503e089f46c227ba2813ff183b71616034814",
"https://bcr.bazel.build/modules/platforms/0.0.8/MODULE.bazel": "9f142c03e348f6d263719f5074b21ef3adf0b139ee4c5133e2aa35664da9eb2d",
"https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel": "a5a29bb89544f9b97edce05642fac225a808b5b7be74038ea3640fae2f8e66a7",
"https://bcr.bazel.build/modules/protobuf/27.0/MODULE.bazel": "7873b60be88844a0a1d8f80b9d5d20cfbd8495a689b8763e76c6372998d3f64c",
"https://bcr.bazel.build/modules/protobuf/27.1/MODULE.bazel": "703a7b614728bb06647f965264967a8ef1c39e09e8f167b3ca0bb1fd80449c0d",
"https://bcr.bazel.build/modules/protobuf/29.0-rc2/MODULE.bazel": "6241d35983510143049943fc0d57937937122baf1b287862f9dc8590fc4c37df",
"https://bcr.bazel.build/modules/protobuf/29.0/MODULE.bazel": "319dc8bf4c679ff87e71b1ccfb5a6e90a6dbc4693501d471f48662ac46d04e4e",
"https://bcr.bazel.build/modules/protobuf/29.0/source.json": "b857f93c796750eef95f0d61ee378f3420d00ee1dd38627b27193aa482f4f981",
"https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0",
"https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e",
"https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/source.json": "be4789e951dd5301282729fe3d4938995dc4c1a81c2ff150afc9f1b0504c6022",
"https://bcr.bazel.build/modules/re2/2023-09-01/MODULE.bazel": "cb3d511531b16cfc78a225a9e2136007a48cf8a677e4264baeab57fe78a80206",
"https://bcr.bazel.build/modules/re2/2023-09-01/source.json": "e044ce89c2883cd957a2969a43e79f7752f9656f6b20050b62f90ede21ec6eb4",
"https://bcr.bazel.build/modules/rules_android/0.1.1/MODULE.bazel": "48809ab0091b07ad0182defb787c4c5328bd3a278938415c00a7b69b50c4d3a8",
"https://bcr.bazel.build/modules/rules_android/0.1.1/source.json": "e6986b41626ee10bdc864937ffb6d6bf275bb5b9c65120e6137d56e6331f089e",
"https://bcr.bazel.build/modules/rules_cc/0.0.1/MODULE.bazel": "cb2aa0747f84c6c3a78dad4e2049c154f08ab9d166b1273835a8174940365647",
"https://bcr.bazel.build/modules/rules_cc/0.0.10/MODULE.bazel": "ec1705118f7eaedd6e118508d3d26deba2a4e76476ada7e0e3965211be012002",
"https://bcr.bazel.build/modules/rules_cc/0.0.13/MODULE.bazel": "0e8529ed7b323dad0775ff924d2ae5af7640b23553dfcd4d34344c7e7a867191",
"https://bcr.bazel.build/modules/rules_cc/0.0.14/MODULE.bazel": "5e343a3aac88b8d7af3b1b6d2093b55c347b8eefc2e7d1442f7a02dc8fea48ac",
"https://bcr.bazel.build/modules/rules_cc/0.0.15/MODULE.bazel": "6704c35f7b4a72502ee81f61bf88706b54f06b3cbe5558ac17e2e14666cd5dcc",
"https://bcr.bazel.build/modules/rules_cc/0.0.16/MODULE.bazel": "7661303b8fc1b4d7f532e54e9d6565771fea666fbdf839e0a86affcd02defe87",
"https://bcr.bazel.build/modules/rules_cc/0.0.2/MODULE.bazel": "6915987c90970493ab97393024c156ea8fb9f3bea953b2f3ec05c34f19b5695c",
"https://bcr.bazel.build/modules/rules_cc/0.0.6/MODULE.bazel": "abf360251023dfe3efcef65ab9d56beefa8394d4176dd29529750e1c57eaa33f",
"https://bcr.bazel.build/modules/rules_cc/0.0.8/MODULE.bazel": "964c85c82cfeb6f3855e6a07054fdb159aced38e99a5eecf7bce9d53990afa3e",
"https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5",
"https://bcr.bazel.build/modules/rules_cc/0.1.1/MODULE.bazel": "2f0222a6f229f0bf44cd711dc13c858dad98c62d52bd51d8fc3a764a83125513",
"https://bcr.bazel.build/modules/rules_cc/0.1.1/source.json": "d61627377bd7dd1da4652063e368d9366fc9a73920bfa396798ad92172cf645c",
"https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6",
"https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8",
"https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/source.json": "c8b1e2c717646f1702290959a3302a178fb639d987ab61d548105019f11e527e",
"https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74",
"https://bcr.bazel.build/modules/rules_java/5.3.5/MODULE.bazel": "a4ec4f2db570171e3e5eb753276ee4b389bae16b96207e9d3230895c99644b86",
"https://bcr.bazel.build/modules/rules_java/6.0.0/MODULE.bazel": "8a43b7df601a7ec1af61d79345c17b31ea1fedc6711fd4abfd013ea612978e39",
"https://bcr.bazel.build/modules/rules_java/6.4.0/MODULE.bazel": "e986a9fe25aeaa84ac17ca093ef13a4637f6107375f64667a15999f77db6c8f6",
"https://bcr.bazel.build/modules/rules_java/6.5.2/MODULE.bazel": "1d440d262d0e08453fa0c4d8f699ba81609ed0e9a9a0f02cd10b3e7942e61e31",
"https://bcr.bazel.build/modules/rules_java/7.10.0/MODULE.bazel": "530c3beb3067e870561739f1144329a21c851ff771cd752a49e06e3dc9c2e71a",
"https://bcr.bazel.build/modules/rules_java/7.12.2/MODULE.bazel": "579c505165ee757a4280ef83cda0150eea193eed3bef50b1004ba88b99da6de6",
"https://bcr.bazel.build/modules/rules_java/7.2.0/MODULE.bazel": "06c0334c9be61e6cef2c8c84a7800cef502063269a5af25ceb100b192453d4ab",
"https://bcr.bazel.build/modules/rules_java/7.3.2/MODULE.bazel": "50dece891cfdf1741ea230d001aa9c14398062f2b7c066470accace78e412bc2",
"https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe",
"https://bcr.bazel.build/modules/rules_java/8.14.0/MODULE.bazel": "717717ed40cc69994596a45aec6ea78135ea434b8402fb91b009b9151dd65615",
"https://bcr.bazel.build/modules/rules_java/8.14.0/source.json": "8a88c4ca9e8759da53cddc88123880565c520503321e2566b4e33d0287a3d4bc",
"https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7",
"https://bcr.bazel.build/modules/rules_jvm_external/5.1/MODULE.bazel": "33f6f999e03183f7d088c9be518a63467dfd0be94a11d0055fe2d210f89aa909",
"https://bcr.bazel.build/modules/rules_jvm_external/5.2/MODULE.bazel": "d9351ba35217ad0de03816ef3ed63f89d411349353077348a45348b096615036",
"https://bcr.bazel.build/modules/rules_jvm_external/5.3/MODULE.bazel": "bf93870767689637164657731849fb887ad086739bd5d360d90007a581d5527d",
"https://bcr.bazel.build/modules/rules_jvm_external/6.1/MODULE.bazel": "75b5fec090dbd46cf9b7d8ea08cf84a0472d92ba3585b476f44c326eda8059c4",
"https://bcr.bazel.build/modules/rules_jvm_external/6.3/MODULE.bazel": "c998e060b85f71e00de5ec552019347c8bca255062c990ac02d051bb80a38df0",
"https://bcr.bazel.build/modules/rules_jvm_external/6.3/source.json": "6f5f5a5a4419ae4e37c35a5bb0a6ae657ed40b7abc5a5189111b47fcebe43197",
"https://bcr.bazel.build/modules/rules_kotlin/1.9.0/MODULE.bazel": "ef85697305025e5a61f395d4eaede272a5393cee479ace6686dba707de804d59",
"https://bcr.bazel.build/modules/rules_kotlin/1.9.6/MODULE.bazel": "d269a01a18ee74d0335450b10f62c9ed81f2321d7958a2934e44272fe82dcef3",
"https://bcr.bazel.build/modules/rules_kotlin/1.9.6/source.json": "2faa4794364282db7c06600b7e5e34867a564ae91bda7cae7c29c64e9466b7d5",
"https://bcr.bazel.build/modules/rules_license/0.0.3/MODULE.bazel": "627e9ab0247f7d1e05736b59dbb1b6871373de5ad31c3011880b4133cafd4bd0",
"https://bcr.bazel.build/modules/rules_license/0.0.7/MODULE.bazel": "088fbeb0b6a419005b89cf93fe62d9517c0a2b8bb56af3244af65ecfe37e7d5d",
"https://bcr.bazel.build/modules/rules_license/1.0.0/MODULE.bazel": "a7fda60eefdf3d8c827262ba499957e4df06f659330bbe6cdbdb975b768bb65c",
"https://bcr.bazel.build/modules/rules_license/1.0.0/source.json": "a52c89e54cc311196e478f8382df91c15f7a2bfdf4c6cd0e2675cc2ff0b56efb",
"https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc",
"https://bcr.bazel.build/modules/rules_pkg/1.0.1/MODULE.bazel": "5b1df97dbc29623bccdf2b0dcd0f5cb08e2f2c9050aab1092fd39a41e82686ff",
"https://bcr.bazel.build/modules/rules_pkg/1.0.1/source.json": "bd82e5d7b9ce2d31e380dd9f50c111d678c3bdaca190cb76b0e1c71b05e1ba8a",
"https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06",
"https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7",
"https://bcr.bazel.build/modules/rules_proto/6.0.2/MODULE.bazel": "ce916b775a62b90b61888052a416ccdda405212b6aaeb39522f7dc53431a5e73",
"https://bcr.bazel.build/modules/rules_proto/7.0.2/MODULE.bazel": "bf81793bd6d2ad89a37a40693e56c61b0ee30f7a7fdbaf3eabbf5f39de47dea2",
"https://bcr.bazel.build/modules/rules_proto/7.0.2/source.json": "1e5e7260ae32ef4f2b52fd1d0de8d03b606a44c91b694d2f1afb1d3b28a48ce1",
"https://bcr.bazel.build/modules/rules_python/0.10.2/MODULE.bazel": "cc82bc96f2997baa545ab3ce73f196d040ffb8756fd2d66125a530031cd90e5f",
"https://bcr.bazel.build/modules/rules_python/0.23.1/MODULE.bazel": "49ffccf0511cb8414de28321f5fcf2a31312b47c40cc21577144b7447f2bf300",
"https://bcr.bazel.build/modules/rules_python/0.25.0/MODULE.bazel": "72f1506841c920a1afec76975b35312410eea3aa7b63267436bfb1dd91d2d382",
"https://bcr.bazel.build/modules/rules_python/0.28.0/MODULE.bazel": "cba2573d870babc976664a912539b320cbaa7114cd3e8f053c720171cde331ed",
"https://bcr.bazel.build/modules/rules_python/0.31.0/MODULE.bazel": "93a43dc47ee570e6ec9f5779b2e64c1476a6ce921c48cc9a1678a91dd5f8fd58",
"https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c",
"https://bcr.bazel.build/modules/rules_python/0.40.0/MODULE.bazel": "9d1a3cd88ed7d8e39583d9ffe56ae8a244f67783ae89b60caafc9f5cf318ada7",
"https://bcr.bazel.build/modules/rules_python/0.40.0/source.json": "939d4bd2e3110f27bfb360292986bb79fd8dcefb874358ccd6cdaa7bda029320",
"https://bcr.bazel.build/modules/rules_shell/0.2.0/MODULE.bazel": "fda8a652ab3c7d8fee214de05e7a9916d8b28082234e8d2c0094505c5268ed3c",
"https://bcr.bazel.build/modules/rules_shell/0.2.0/source.json": "7f27af3c28037d9701487c4744b5448d26537cc66cdef0d8df7ae85411f8de95",
"https://bcr.bazel.build/modules/stardoc/0.5.1/MODULE.bazel": "1a05d92974d0c122f5ccf09291442580317cdd859f07a8655f1db9a60374f9f8",
"https://bcr.bazel.build/modules/stardoc/0.5.3/MODULE.bazel": "c7f6948dae6999bf0db32c1858ae345f112cacf98f174c7a8bb707e41b974f1c",
"https://bcr.bazel.build/modules/stardoc/0.5.6/MODULE.bazel": "c43dabc564990eeab55e25ed61c07a1aadafe9ece96a4efabb3f8bf9063b71ef",
"https://bcr.bazel.build/modules/stardoc/0.7.0/MODULE.bazel": "05e3d6d30c099b6770e97da986c53bd31844d7f13d41412480ea265ac9e8079c",
"https://bcr.bazel.build/modules/stardoc/0.7.1/MODULE.bazel": "3548faea4ee5dda5580f9af150e79d0f6aea934fc60c1cc50f4efdd9420759e7",
"https://bcr.bazel.build/modules/stardoc/0.7.1/source.json": "b6500ffcd7b48cd72c29bb67bcac781e12701cc0d6d55d266a652583cfcdab01",
"https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43",
"https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0",
"https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/MODULE.bazel": "eec517b5bbe5492629466e11dae908d043364302283de25581e3eb944326c4ca",
"https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/source.json": "22bc55c47af97246cfc093d0acf683a7869377de362b5d1c552c2c2e16b7a806",
"https://bcr.bazel.build/modules/zlib/1.3.1/MODULE.bazel": "751c9940dcfe869f5f7274e1295422a34623555916eb98c174c1e945594bf198"
},
"selectedYankedVersions": {},
"moduleExtensions": {
"@@rules_kotlin+//src/main/starlark/core/repositories:bzlmod_setup.bzl%rules_kotlin_extensions": {
"general": {
"bzlTransitiveDigest": "rL/34P1aFDq2GqVC2zCFgQ8nTuOC6ziogocpvG50Qz8=",
"usagesDigest": "QI2z8ZUR+mqtbwsf2fLqYdJAkPOHdOV+tF2yVAUgRzw=",
"recordedFileInputs": {},
"recordedDirentsInputs": {},
"envVariables": {},
"generatedRepoSpecs": {
"com_github_jetbrains_kotlin_git": {
"repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:compiler.bzl%kotlin_compiler_git_repository",
"attributes": {
"urls": [
"https://github.com/JetBrains/kotlin/releases/download/v1.9.23/kotlin-compiler-1.9.23.zip"
],
"sha256": "93137d3aab9afa9b27cb06a824c2324195c6b6f6179d8a8653f440f5bd58be88"
}
},
"com_github_jetbrains_kotlin": {
"repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:compiler.bzl%kotlin_capabilities_repository",
"attributes": {
"git_repository_name": "com_github_jetbrains_kotlin_git",
"compiler_version": "1.9.23"
}
},
"com_github_google_ksp": {
"repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:ksp.bzl%ksp_compiler_plugin_repository",
"attributes": {
"urls": [
"https://github.com/google/ksp/releases/download/1.9.23-1.0.20/artifacts.zip"
],
"sha256": "ee0618755913ef7fd6511288a232e8fad24838b9af6ea73972a76e81053c8c2d",
"strip_version": "1.9.23-1.0.20"
}
},
"com_github_pinterest_ktlint": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file",
"attributes": {
"sha256": "01b2e0ef893383a50dbeb13970fe7fa3be36ca3e83259e01649945b09d736985",
"urls": [
"https://github.com/pinterest/ktlint/releases/download/1.3.0/ktlint"
],
"executable": true
}
},
"rules_android": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"sha256": "cd06d15dd8bb59926e4d65f9003bfc20f9da4b2519985c27e190cddc8b7a7806",
"strip_prefix": "rules_android-0.1.1",
"urls": [
"https://github.com/bazelbuild/rules_android/archive/v0.1.1.zip"
]
}
}
},
"recordedRepoMappingEntries": [
[
"rules_kotlin+",
"bazel_tools",
"bazel_tools"
]
]
}
}
},
"facts": {}
}

View File

@ -1,22 +1,21 @@
Embedded Template Library (ETL)
-------------------------
# ![alt text](https://github.com/ETLCPP/etl/blob/master/images/etl64.png?raw=true) Embedded Template Library (ETL)
![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)
![GitHub Repo stars](https://img.shields.io/github/stars/ETLCPP/etl?style=flat)
![CI](https://github.com/ETLCPP/etl/actions/workflows/msvc.yml/badge.svg?branch=master)
[![Build status](https://ci.appveyor.com/api/projects/status/b7jgecv7unqjw4u0/branch/master?svg=true)](https://ci.appveyor.com/project/jwellbelove/etl/branch/master)
![CI](https://github.com/ETLCPP/etl/actions/workflows/gcc-c++11.yml/badge.svg?branch=master)
![CI](https://github.com/ETLCPP/etl/actions/workflows/gcc-c++14.yml/badge.svg?branch=master)
![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)
@ -24,6 +23,7 @@ Embedded Template Library (ETL)
![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&amp;utm_medium=referral&amp;utm_content=ETLCPP/etl&amp;utm_campaign=Badge_Grade)
@ -50,8 +50,8 @@ 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.
- Maintaining compatibility with C++98 while implementing many features introduced in later standards
(C++11/14/17/20/23/26) where possible.
- Ensuring deterministic behavior, which is critical in real-time and resource-constrained environments.
@ -184,6 +184,84 @@ add_executable(foo main.cpp)
target_link_libraries(foo PRIVATE etl::etl)
```
## Profile definition
When using ETL in a project, there is typically an `etl_profile.h` defined to
adjust ETL to the project needs. ETL will automatically find `etl_profile.h`
if it is available in the include path(s). If it's not available, ETL will
work with default values.
### Example
```
#ifndef __ETL_PROFILE_H__
#define __ETL_PROFILE_H__
#define ETL_TARGET_DEVICE_GENERIC
#define ETL_TARGET_OS_NONE
#define ETL_NO_STL
#endif
```
## Platform specific implementation
Although ETL is generally a self-contained header-only library, some interfaces need to be
implemented in every project or platform, at least if those interfaces are actually being
used, due to project specifics:
| ETL header | Platform specific API to be implemented | Needed when using |
|------------|-----------------------------------------|-------------------------------------|
| `chrono.h` | `etl_get_high_resolution_clock()` | `etl::high_resolution_clock::now()` |
| | `etl_get_system_clock()` | `etl::system_clock::now()` |
| | `etl_get_steady_clock()` | `etl::steady_clock::now()` |
| `print.h` | `etl_putchar()` | `etl::print()` |
| | | `etl::println()` |
### Example
```
#include <etl/chrono.h>
#include <etl/print.h>
extern "C"
{
etl::chrono::high_resolution_clock::rep etl_get_high_resolution_clock()
{
return etl::chrono::high_resolution_clock::rep(static_cast<int64_t>(getSystemTimeNs()));
}
etl::chrono::system_clock::rep etl_get_system_clock()
{
return etl::chrono::system_clock::rep(static_cast<int64_t>(getSystemTimeNs()));
}
etl::chrono::system_clock::rep etl_get_steady_clock()
{
return etl::chrono::system_clock::rep(static_cast<int64_t>(getSystemTimeNs()));
}
void etl_putchar(int c)
{
putByteToStdout(static_cast<uint8_t>(c));
}
}
```
The following default values apply if the respective macros are not defined
(e.g. in `etl_profile.h`):
| Macro | Default |
|-----------------------------------------------|----------------------------|
| `ETL_CHRONO_SYSTEM_CLOCK_DURATION` | `etl::chrono::nanoseconds` |
| `ETL_CHRONO_SYSTEM_CLOCK_IS_STEADY` | `true` |
| `ETL_CHRONO_HIGH_RESOLUTION_CLOCK_DURATION` | `etl::chrono::nanoseconds` |
| `ETL_CHRONO_HIGH_RESOLUTION_CLOCK_IS_STEADY` | `true` |
| `ETL_CHRONO_STEADY_CLOCK_DURATION` | `etl::chrono::nanoseconds` |
## Arduino library
The content of this repo is available as a library in the Arduino IDE (search for the "Embedded Template Library" in the IDE library manager). The Arduino library repository is available at ```https://github.com/ETLCPP/etl-arduino```, see there for more details.

View File

@ -2,79 +2,95 @@
#ifndef ETL_EMBEDDED_TEMPLATE_LIBRARY_INCLUDED
#define ETL_EMBEDDED_TEMPLATE_LIBRARY_INCLUDED
#if defined(TEENSYDUINO)
#if defined(TEENSYDUINO)
#if defined(__AVR_ATmega32U4__)
#define ARDUINO_BOARD "Teensy 2.0"
#elif defined(__AVR_AT90USB1286__)
#define ARDUINO_BOARD "Teensy++ 2.0"
#elif defined(__MK20DX128__)
#define ARDUINO_BOARD "Teensy 3.0"
#elif defined(__MK20DX256__)
#define ARDUINO_BOARD "Teensy 3.2" // and Teensy 3.1
#elif defined(__MKL26Z64__)
#define ARDUINO_BOARD "Teensy LC"
#elif defined(__MK64FX512__)
#define ARDUINO_BOARD "Teensy 3.5"
#elif defined(__MK66FX1M0__)
#define ARDUINO_BOARD "Teensy 3.6"
#else
#define ARDUINO_BOARD "Unknown"
#endif
#if defined(__AVR_ATmega32U4__)
#define ARDUINO_BOARD "Teensy 2.0"
#elif defined(__AVR_AT90USB1286__)
#define ARDUINO_BOARD "Teensy++ 2.0"
#elif defined(__MK20DX128__)
#define ARDUINO_BOARD "Teensy 3.0"
#elif defined(__MK20DX256__)
#define ARDUINO_BOARD "Teensy 3.2" // and Teensy 3.1
#elif defined(__MKL26Z64__)
#define ARDUINO_BOARD "Teensy LC"
#elif defined(__MK64FX512__)
#define ARDUINO_BOARD "Teensy 3.5"
#elif defined(__MK66FX1M0__)
#define ARDUINO_BOARD "Teensy 3.6"
#elif defined(ARDUINO_TEENSY40)
#define ARDUINO_BOARD "Teensy 4.0"
#elif defined(ARDUINO_TEENSY41)
#define ARDUINO_BOARD "Teensy 4.1"
#elif defined(ARDUINO_TEENSY_MICROMOD)
#define ARDUINO_BOARD "Teensy MicroMod"
#else
#define ARDUINO_BOARD "Unknown"
#endif
#elif defined(CORE_ARDUINO_PICO)
#if defined(PICO_RP2040)
#define ARDUINO_BOARD "RP2040"
#elif defined(PICO_RP2350)
#define ARDUINO_BOARD "RP2350"
#else
#define ARDUINO_BOARD "Unknown"
#endif
#else // --------------- Arduino ------------------
#if defined(ARDUINO_AVR_ADK)
#define ARDUINO_BOARD "Mega Adk"
#elif defined(ARDUINO_AVR_BT)
#define ARDUINO_BOARD "Bt"
#elif defined(ARDUINO_AVR_DUEMILANOVE)
#define ARDUINO_BOARD "Duemilanove"
#elif defined(ARDUINO_AVR_ESPLORA)
#define ARDUINO_BOARD "Esplora"
#elif defined(ARDUINO_AVR_ETHERNET)
#define ARDUINO_BOARD "Ethernet"
#elif defined(ARDUINO_AVR_FIO)
#define ARDUINO_BOARD "Fio"
#elif defined(ARDUINO_AVR_GEMMA)
#define ARDUINO_BOARD "Gemma"
#elif defined(ARDUINO_AVR_LEONARDO)
#define ARDUINO_BOARD "Leonardo"
#elif defined(ARDUINO_AVR_LILYPAD)
#define ARDUINO_BOARD "Lilypad"
#elif defined(ARDUINO_AVR_LILYPAD_USB)
#define ARDUINO_BOARD "Lilypad Usb"
#elif defined(ARDUINO_AVR_MEGA)
#define ARDUINO_BOARD "Mega"
#elif defined(ARDUINO_AVR_MEGA2560)
#define ARDUINO_BOARD "Mega 2560"
#elif defined(ARDUINO_AVR_MICRO)
#define ARDUINO_BOARD "Micro"
#elif defined(ARDUINO_AVR_MINI)
#define ARDUINO_BOARD "Mini"
#elif defined(ARDUINO_AVR_NANO)
#define ARDUINO_BOARD "Nano"
#elif defined(ARDUINO_AVR_NG)
#define ARDUINO_BOARD "NG"
#elif defined(ARDUINO_AVR_PRO)
#define ARDUINO_BOARD "Pro"
#elif defined(ARDUINO_AVR_ROBOT_CONTROL)
#define ARDUINO_BOARD "Robot Ctrl"
#elif defined(ARDUINO_AVR_ROBOT_MOTOR)
#define ARDUINO_BOARD "Robot Motor"
#elif defined(ARDUINO_AVR_UNO)
#define ARDUINO_BOARD "Uno"
#elif defined(ARDUINO_AVR_YUN)
#define ARDUINO_BOARD "Yun"
#elif defined(ARDUINO_SAM_DUE)
#define ARDUINO_BOARD "Due"
#elif defined(ARDUINO_SAMD_ZERO)
#define ARDUINO_BOARD "Zero"
#elif defined(ARDUINO_ARC32_TOOLS)
#define ARDUINO_BOARD "101"
#else
#define ARDUINO_BOARD "Unknown"
#endif
#if defined(ARDUINO_AVR_ADK)
#define ARDUINO_BOARD "Mega Adk"
#elif defined(ARDUINO_AVR_BT)
#define ARDUINO_BOARD "Bt"
#elif defined(ARDUINO_AVR_DUEMILANOVE)
#define ARDUINO_BOARD "Duemilanove"
#elif defined(ARDUINO_AVR_ESPLORA)
#define ARDUINO_BOARD "Esplora"
#elif defined(ARDUINO_AVR_ETHERNET)
#define ARDUINO_BOARD "Ethernet"
#elif defined(ARDUINO_AVR_FIO)
#define ARDUINO_BOARD "Fio"
#elif defined(ARDUINO_AVR_GEMMA)
#define ARDUINO_BOARD "Gemma"
#elif defined(ARDUINO_AVR_LEONARDO)
#define ARDUINO_BOARD "Leonardo"
#elif defined(ARDUINO_AVR_LILYPAD)
#define ARDUINO_BOARD "Lilypad"
#elif defined(ARDUINO_AVR_LILYPAD_USB)
#define ARDUINO_BOARD "Lilypad Usb"
#elif defined(ARDUINO_AVR_MEGA)
#define ARDUINO_BOARD "Mega"
#elif defined(ARDUINO_AVR_MEGA2560)
#define ARDUINO_BOARD "Mega 2560"
#elif defined(ARDUINO_AVR_MICRO)
#define ARDUINO_BOARD "Micro"
#elif defined(ARDUINO_AVR_MINI)
#define ARDUINO_BOARD "Mini"
#elif defined(ARDUINO_AVR_NANO)
#define ARDUINO_BOARD "Nano"
#elif defined(ARDUINO_AVR_NG)
#define ARDUINO_BOARD "NG"
#elif defined(ARDUINO_AVR_PRO)
#define ARDUINO_BOARD "Pro"
#elif defined(ARDUINO_AVR_ROBOT_CONTROL)
#define ARDUINO_BOARD "Robot Ctrl"
#elif defined(ARDUINO_AVR_ROBOT_MOTOR)
#define ARDUINO_BOARD "Robot Motor"
#elif defined(ARDUINO_AVR_UNO)
#define ARDUINO_BOARD "Uno"
#elif defined(ARDUINO_AVR_YUN)
#define ARDUINO_BOARD "Yun"
#elif defined(ARDUINO_SAM_DUE)
#define ARDUINO_BOARD "Due"
#elif defined(ARDUINO_SAMD_ZERO)
#define ARDUINO_BOARD "Zero"
#elif defined(ARDUINO_ARC32_TOOLS)
#define ARDUINO_BOARD "101"
#else
#define ARDUINO_BOARD "Unknown"
#endif
#endif
#endif

View File

@ -1,6 +1,6 @@
{
"name": "Embedded Template Library ETL",
"version": "20.44.1",
"version": "20.47.1",
"authors": {
"name": "John Wellbelove",
"email": "john.wellbelove@etlcpp.com"

View File

@ -1,5 +1,5 @@
name=Embedded Template Library ETL
version=20.44.1
version=20.47.1
author= John Wellbelove <john.wellbelove@etlcpp.com>
maintainer=John Wellbelove <john.wellbelove@etlcpp.com>
license=MIT

6
docs/_config.yml Normal file
View File

@ -0,0 +1,6 @@
plugins:
- jekyll-relative-links
relative_links:
enabled: true
include:
- manchester.md

295
docs/bazel.md Normal file
View File

@ -0,0 +1,295 @@
# Building ETL with Bazel
ETL provides first-class [Bazel](https://bazel.build/) support, both for developing ETL itself and for consuming it as a dependency in your own projects.
## Prerequisites
- [Bazelisk](https://github.com/bazelbuild/bazelisk) (recommended) or [Bazel](https://bazel.build/install) 7.0 or later (with Bzlmod support)
[Bazelisk](https://github.com/bazelbuild/bazelisk) is a launcher that automatically downloads and runs the Bazel version specified in the `.bazelversion` file at the project root. This ensures all contributors use a consistent Bazel version. Simply install Bazelisk and use `bazel` as usual — it transparently delegates to the correct version.
## Syntax Checks
To validate that every ETL header is well-formed and compiles on its own (equivalent to `test/run-syntax-checks.sh` for CMake):
```sh
bazel build //test/syntax_check:syntax_check
```
This compiles a set of minimal `.t.cpp` files, each of which includes a single ETL header, with strict warning flags enabled.
## Cleaning Build Artifacts
To remove all build outputs and symlinks (`bazel-bin`, `bazel-out`, `bazel-etl`, etc.):
```sh
bazel clean
```
For a full cleanup including the external dependency cache:
```sh
bazel clean --expunge
```
## Running Unit Tests
To run the full test suite:
```sh
bazel test //test:etl_tests
```
You can also pass standard Bazel flags:
```sh
# Run with verbose test output
bazel test //test:etl_tests --test_output=all
# Run tests matching a filter (UnitTest++ subset)
bazel test //test:etl_tests --test_arg=<suite_name>
```
## Using ETL in Your Project
### With Bzlmod (recommended, Bazel 7+)
Add ETL as a dependency in your project's `MODULE.bazel`:
```python
bazel_dep(name = "etl", version = "20.47.1")
git_override(
module_name = "etl",
remote = "https://github.com/ETLCPP/etl.git",
tag = "20.47.1", # or a specific commit
)
```
Then depend on it in your `BUILD.bazel`:
```python
cc_library(
name = "my_library",
srcs = ["my_library.cpp"],
hdrs = ["my_library.h"],
deps = ["@etl//:etl"],
)
```
### With WORKSPACE (legacy)
In your `WORKSPACE` file:
```python
load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
git_repository(
name = "etl",
remote = "https://github.com/ETLCPP/etl.git",
tag = "20.47.1",
)
```
Then use `deps = ["@etl//:etl"]` in your targets as shown above.
## Project Structure
| File | Purpose |
|---|---|
| `MODULE.bazel` | Module definition and dependencies |
| `BUILD.bazel` | Exposes ETL as a `cc_library` |
| `.bazelversion` | Bazel version for Bazelisk |
| `.bazelrc` | Default Bazel settings |
| `test/BUILD.bazel` | Unit test target |
| `test/syntax_check/BUILD.bazel` | Header syntax check target |
| `test/UnitTest++/BUILD.bazel` | Vendored UnitTest++ framework |
## Cross-Compilation
Bazel supports cross-compilation through its [platforms](https://bazel.build/extending/platforms) and [toolchains](https://bazel.build/extending/toolchains) system. Since ETL is a header-only library, there is nothing to cross-compile for the library itself. However, when building tests or consuming ETL in an application targeting a different architecture, you need to define a platform and register an appropriate C++ toolchain.
Example platform definition (e.g. in a `platforms/BUILD.bazel`):
```python
platform(
name = "linux_arm64",
constraint_values = [
"@platforms//os:linux",
"@platforms//cpu:aarch64",
],
)
```
Then build with:
```sh
bazel build //:etl --platforms=//platforms:linux_arm64
```
> **Note:** You must also have a C++ toolchain registered that supports the target platform.
> See the [Bazel toolchains documentation](https://bazel.build/extending/toolchains) for details.
### Running Cross-Compiled Tests under QEMU
Cross-compiled test binaries cannot run natively on the host. Pre-defined configurations in `.bazelrc` select the correct cross-compiler via `--repo_env=CC`, set the build flags to match `.devcontainer/run-tests.sh` (C++23, No-STL, `-O0`), and use `--run_under` to execute the resulting binary under the appropriate QEMU emulator:
```sh
# Cross-build and run tests for ARM (armhf)
bazel test //test:etl_tests --config=armhf
# Other architectures
bazel test //test:etl_tests --config=i386
bazel test //test:etl_tests --config=powerpc
bazel test //test:etl_tests --config=riscv64
bazel test //test:etl_tests --config=s390x
```
These configs are designed to run inside the Docker containers under `.devcontainer/`, which provide the cross-compiler toolchains and QEMU binaries. Each config sets `CC`, `AR`, `LD`, `NM`, `STRIP`, and `OBJDUMP` via `--repo_env` so that Bazel's auto-configured toolchain finds the complete prefixed cross-tool suite.
You can also use `--run_under` directly for custom setups:
```sh
bazel test //test:etl_tests --run_under=/usr/bin/qemu-arm-static
```
## Compiler and Build Configuration
Unlike CMake where options like `ETL_CXX_STANDARD` and `CMAKE_CXX_COMPILER` are set at configure time, Bazel uses command-line flags and `.bazelrc` configurations.
### C++ Standard Version
Use `--cxxopt` to pass the desired standard flag:
```sh
# C++17 (default in .bazelrc)
bazel test //test:etl_tests --cxxopt=-std=c++17
# C++20
bazel test //test:etl_tests --cxxopt=-std=c++20
# C++23
bazel test //test:etl_tests --cxxopt=-std=c++23
# C++14
bazel test //test:etl_tests --cxxopt=-std=c++14
```
### Optimization Level
Use `--compilation_mode` (shorthand `-c`) for standard profiles, or `--copt` for explicit flags:
```sh
# Debug (default) — no optimization, debug symbols
bazel test //test:etl_tests -c dbg
# Optimized — O2 with NDEBUG
bazel test //test:etl_tests -c opt
# Fast build — no optimization, no debug symbols
bazel test //test:etl_tests -c fastbuild
# Custom optimization level
bazel test //test:etl_tests --copt=-O3
bazel test //test:etl_tests --copt=-O1
bazel test //test:etl_tests --copt=-Os
```
### Selecting the Compiler (GCC vs Clang)
Bazel uses the system's default `CC` environment variable. Override it to switch compilers:
```sh
# Use Clang
bazel test //test:etl_tests --repo_env=CC=clang
# Use a specific GCC version
bazel test //test:etl_tests --repo_env=CC=gcc-13
# Use a specific Clang version
bazel test //test:etl_tests --repo_env=CC=clang-18
```
> **Note:** Bazel's auto-configured toolchain infers the C++ compiler from `CC` automatically
> (e.g. `CC=gcc-13``g++-13` for C++ compilation). There is no need to set `CXX` separately.
### Combining Options
Flags can be combined freely:
```sh
# Clang, C++20, optimized
bazel test //test:etl_tests --repo_env=CC=clang --cxxopt=-std=c++20 -c opt
# GCC 13, C++23, debug
bazel test //test:etl_tests --repo_env=CC=gcc-13 --cxxopt=-std=c++23 -c dbg
```
### STL vs. No-STL Mode
ETL can operate without the standard library, which is common on bare-metal embedded targets. Use `--copt` to define `ETL_NO_STL`:
```sh
# Build and test without STL
bazel test //test:etl_tests --copt=-DETL_NO_STL
# Build with STL (default, no flag needed)
bazel test //test:etl_tests
```
When `ETL_NO_STL` is defined, ETL provides its own implementations of containers, algorithms, and utilities instead of delegating to `<algorithm>`, `<type_traits>`, etc.
### Type Traits Configuration
ETL supports three type traits strategies, controlled via preprocessor defines:
| Mode | Define | Description |
|---|---|---|
| **STL type traits** | *(default)* | Uses `<type_traits>` from the standard library |
| **Compiler builtins** | `ETL_USE_TYPE_TRAITS_BUILTINS` | Uses compiler intrinsics (`__is_trivially_copyable`, etc.) — useful when STL headers are unavailable or incomplete |
| **User-defined** | `ETL_USER_DEFINED_TYPE_TRAITS` | Uses ETL's own type traits implementations |
```sh
# Use compiler built-in type traits
bazel test //test:etl_tests --copt=-DETL_USE_TYPE_TRAITS_BUILTINS
# Use ETL's own user-defined type traits
bazel test //test:etl_tests --copt=-DETL_USER_DEFINED_TYPE_TRAITS
```
These are mutually exclusive — define at most one. If neither is defined and STL is available, ETL uses `<type_traits>`.
### Other Configuration Defines
Additional defines can be passed the same way via `--copt=-D...`:
| Define | Description |
|---|---|
| `ETL_FORCE_TEST_CPP03_IMPLEMENTATION` | Force C++03 code paths even when a newer standard is available |
| `ETL_MESSAGES_ARE_NOT_VIRTUAL` | Use non-virtual message types |
```sh
# Force C++03 implementation paths
bazel test //test:etl_tests --copt=-DETL_FORCE_TEST_CPP03_IMPLEMENTATION
```
### Using `.bazelrc` Presets
To avoid retyping flags, add configurations to `.bazelrc`:
```
# .bazelrc
# Named configurations
build:clang --repo_env=CC=clang
build:gcc13 --repo_env=CC=gcc-13
build:c++20 --cxxopt=-std=c++20
build:c++23 --cxxopt=-std=c++23
build:release --compilation_mode=opt
```
Then use them with `--config`:
```sh
bazel test //test:etl_tests --config=clang --config=c++20 --config=release
```

289
docs/docker.md Normal file
View File

@ -0,0 +1,289 @@
# Docker for Development
## Overview
The ETL repository ships a set of Docker-based development environments under
`.devcontainer/`. They give every contributor an identical, reproducible toolchain
regardless of host operating system. Three flavours are provided:
| Flavour | Path | Purpose |
|---|---|---|
| **Default** | `.devcontainer/` | Day-to-day development (Microsoft C++ dev-container base image) |
| **Compiler-specific** | `.devcontainer/gcc09/``.devcontainer/gcc15/`, `.devcontainer/clang7/``.devcontainer/clang21/` | Test against a specific GCC or Clang version |
| **s390x big-endian** | `.devcontainer/s390x/` | Cross-compile and run tests on an s390x target via QEMU |
All containers include CMake, Make, Git, Python 3, cogapp (the code generator used
by ETL), clang-format 18, and treefmt.
## Prerequisites
- **Docker** (or Docker Desktop) any recent version that supports `docker build`
and `docker run`.
- **VS Code** with the
[Dev Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)
extension (optional, but recommended for the smoothest experience).
- **Git** to clone the repository.
## Quick Start
### Using the helper script
The fastest way to get a shell inside the default container from the project root:
```bash
./scripts/run-docker.sh
```
This script performs two steps:
1. **Builds** the image from `.devcontainer/Dockerfile` and tags it `etl`.
2. **Runs** an interactive container that bind-mounts the repository at
`/home/vscode/etl` so that edits made inside the container are visible on
the host (and vice versa).
You are dropped into a Bash shell as the `vscode` user with the working
directory set to the repository root.
### Using VS Code Dev Containers
1. Open the repository folder in VS Code.
2. When prompted, click **Reopen in Container** or run the command
*Dev Containers: Reopen in Container* from the command palette.
3. VS Code reads `.devcontainer/devcontainer.json`, builds the image, and
attaches to the running container automatically.
To open a **specific compiler variant** instead, run
*Dev Containers: Open Folder in Container…* and pick the sub-folder (e.g.
`.devcontainer/gcc14/`), or use the command palette action
*Dev Containers: Open Named Container Configuration…* and select the desired
name (e.g. "Gcc 14", "Clang 18").
## Default Development Container
The file `.devcontainer/Dockerfile` is a multi-purpose image used by the
default configuration **and** by every compiler-specific variant (they simply
override the `BASE_IMAGE_NAME` build argument).
### Base image
```text
mcr.microsoft.com/devcontainers/cpp:2
```
The exact digest is pinned in `devcontainer.json` so that builds are
reproducible even if the upstream tag is updated.
### Installed tools
The Dockerfile installs the following on top of the base image:
| Tool | Purpose |
|---|---|
| `python3`, `pip` | Runtime for helper scripts |
| `python3-cogapp` / `cogapp` | ETL code generator |
| `git` | Version control |
| `wget` | Downloading additional tooling |
| `cmake`, `make` | Build system |
| `clang-format` (v18) | Source formatting (see [source-formatting.md](source-formatting.md)) |
| `treefmt` (v2.4.1) | Single-command formatting wrapper |
### Reproducible builds with Debian snapshots
The default configuration sets the build argument
`DEBIAN_SNAPSHOT=20260223T000000Z`. When this value is not `"none"`, the
Dockerfile rewrites the APT sources to point at
`snapshot.debian.org/archive/debian/<timestamp>`, ensuring that every
contributor installs identical package versions. Compiler-specific variants
that are based on upstream `gcc:*` or `silkeh/clang:*` images set
`DEBIAN_SNAPSHOT=none` because those images manage their own package sources.
## Compiler-Specific Containers
Each sub-folder under `.devcontainer/` contains a `devcontainer.json` that
reuses the **same** `Dockerfile` (`../Dockerfile`) but overrides the
`BASE_IMAGE_NAME` build argument to select a different compiler.
### GCC variants
| Folder | Base image | Name |
|---|---|---|
| `gcc09/` | `gcc:9` | Gcc 09 |
| `gcc10/` | `gcc:10` | Gcc 10 |
| `gcc11/` | `gcc:11` | Gcc 11 |
| `gcc12/` | `gcc:12` | Gcc 12 |
| `gcc13/` | `gcc:13` | Gcc 13 |
| `gcc14/` | `gcc:14` | Gcc 14 |
| `gcc15/` | `gcc:15` | Gcc 15 |
### Clang variants
| Folder | Base image | Name |
|---|---|---|
| `clang7/` | `silkeh/clang:7` | Clang 7 |
| `clang8/` | `silkeh/clang:8` | Clang 8 |
| `clang9/` | `silkeh/clang:9` | Clang 9 |
| `clang10/` | `silkeh/clang:10` | Clang 10 |
| `clang11/` | `silkeh/clang:11` | Clang 11 |
| `clang12/` | `silkeh/clang:12` | Clang 12 |
| `clang13/` | `silkeh/clang:13` | Clang 13 |
| `clang14/` | `silkeh/clang:14` | Clang 14 |
| `clang15/` | `silkeh/clang:15` | Clang 15 |
| `clang16/` | `silkeh/clang:16` | Clang 16 |
| `clang17/` | `silkeh/clang:17` | Clang 17 |
| `clang18/` | `silkeh/clang:18` | Clang 18 |
| `clang19/` | `silkeh/clang:19` | Clang 19 |
| `clang20/` | `silkeh/clang:20` | Clang 20 |
| `clang21/` | `silkeh/clang:21` | Clang 21 |
All compiler-specific variants set `DEBIAN_SNAPSHOT` to `"none"` because they
rely on the upstream image's own package sources.
## s390x Big-Endian Cross-Compilation
The `s390x` container lives in `.devcontainer/s390x/` and has its **own**
Dockerfile (it does not reuse the default one). It is based on
`debian:trixie` and installs:
- QEMU user-mode emulation (`qemu-user-static`, `qemu-user`, `binfmt-support`)
- s390x cross-compilation toolchain (`gcc-s390x-linux-gnu`,
`g++-s390x-linux-gnu`)
- CMake, Make, Ninja, Git, wget
### Container setup
Open `.devcontainer/s390x/` as a Dev Container in VS Code, or build manually:
```bash
docker build -t etl-s390x .devcontainer/s390x
docker run -it --rm -v .:/workspaces/etl -w /workspaces/etl etl-s390x
```
### CMake toolchain
A CMake toolchain file is provided at
`.devcontainer/s390x/toolchain-s390x.cmake`. It sets:
- `CMAKE_SYSTEM_PROCESSOR` to `s390x`
- Cross-compilers `s390x-linux-gnu-gcc` / `g++`
- `CMAKE_CROSSCOMPILING_EMULATOR` to `/usr/bin/qemu-s390x-static`
The VS Code Dev Container configuration already passes this toolchain file
via `cmake.configureArgs`, so CMake Tools picks it up automatically.
### Running tests under QEMU
Because the toolchain file sets `CMAKE_CROSSCOMPILING_EMULATOR`, CTest
automatically invokes `qemu-s390x-static` when running test binaries.
No extra flags are needed:
```bash
cmake -S test -B build-s390x \
-DCMAKE_TOOLCHAIN_FILE=.devcontainer/s390x/toolchain-s390x.cmake \
-DBUILD_TESTS=ON -DNO_STL=OFF -DETL_CXX_STANDARD=17 -G Ninja
cmake --build build-s390x
ctest --test-dir build-s390x
```
## Building and Running Tests
Once inside any container (default, compiler-specific, or s390x) you can
build and run the ETL test suite.
### Quick CMake workflow
```bash
# Configure build tests with C++17
cmake -S test -B build -DBUILD_TESTS=ON -DETL_CXX_STANDARD=17
# Build
cmake --build build -j $(nproc)
# Run tests
ctest --test-dir build
```
Change `DETL_CXX_STANDARD` to `11`, `14`, `17`, `20`, or `23` as needed.
Add `-DNO_STL=ON` to build without the standard library.
### Using the run-tests script
The repository also provides a convenience script in `test/`:
```bash
cd test
./run-tests.sh <standard> [optimisation] [threads] [sanitizer] [compiler] [verbose]
```
| Argument | Values | Default |
|---|---|---|
| C++ standard | `11`, `14`, `17`, `20`, `23` | *(required)* |
| Optimisation | `0`, `1`, `2`, `3` | `0` |
| Threads | any integer | `4` |
| Sanitizer | `s` (enable) / `n` (disable) | `n` |
| Compiler | `gcc` / `clang` | all |
| Verbose | `v` (enable) / `n` (disable) | `n` |
Example run C++17 tests at `-O2` with 8 threads using GCC:
```bash
./run-tests.sh 17 2 8 n gcc n
```
## Formatting Inside the Container
The default container ships with **clang-format 18** and **treefmt**.
See [source-formatting.md](source-formatting.md) for the full formatting guide.
Quick reference:
```bash
# Format all tracked C/C++ files with treefmt
treefmt
# Or use clang-format directly via the wrapper
./scripts/clang-format-wrapper -i include/etl/*.h
```
The wrapper script `scripts/clang-format-wrapper` resolves the correct
clang-format binary (prefers `clang-format-18`, falls back to `clang-format`
after checking the major version).
## Customisation
To add extra packages or tools to the default container, edit
`.devcontainer/Dockerfile`. The image follows a straightforward
`apt-get install` pattern, so adding a new package is as simple as appending
it to the existing `apt-get` line.
To create a new compiler variant:
1. Create a folder under `.devcontainer/` (e.g. `.devcontainer/gcc16/`).
2. Add a `devcontainer.json` that references `"../Dockerfile"` and sets
`BASE_IMAGE_NAME` to the desired image (e.g. `gcc:16`).
3. Set `DEBIAN_SNAPSHOT` to `"none"` for upstream compiler images.
Example:
```jsonc
{
"name": "Gcc 16",
"build": {
"dockerfile": "../Dockerfile",
"args": {
"BASE_IMAGE_NAME": "gcc:16",
"DEBIAN_SNAPSHOT": "none"
},
"context": "../context"
}
}
```
## Troubleshooting
| Symptom | Cause / Fix |
|---|---|
| `apt-get` fails with *"Release file … is not valid yet"* | The Debian snapshot timestamp is in the future relative to the build host clock. Either update `DEBIAN_SNAPSHOT` in `devcontainer.json` or set it to `"none"`. |
| `clang-format` reports the wrong version | The wrapper expects version **18**. Make sure the image installs `clang-format` (or `clang-format-18`) and that the binary is on `PATH`. |
| Permission errors on mounted files | The `run-docker.sh` script runs as user `vscode`. Ensure your host UID matches, or adjust the `--user` flag. |
| s390x tests crash immediately | Verify that `qemu-user-static` is installed and that `binfmt-support` is active. On some hosts you may need to register binfmt handlers with `docker run --privileged --rm tonistiigi/binfmt --install all`. |
| Build is very slow the first time | Docker is downloading and building the image from scratch. Subsequent builds use the layer cache and are much faster. |

389
docs/format.md Normal file
View File

@ -0,0 +1,389 @@
# ETL Format & Print
## 1. Overview
ETL provides text formatting facilities modelled on C++20 `std::format` and C++23
`std::print`. They allow type-safe, positional formatting of values into strings
or directly to a character output device — without heap allocation.
**Minimum language standard:** C++11 (`ETL_USING_CPP11`).
**Headers:**
| Header | Provides |
|---|---|
| `etl/format.h` | `etl::format_to`, `etl::format_to_n`, `etl::formatted_size` |
| `etl/print.h` | `etl::print`, `etl::println` (includes `etl/format.h`) |
## 2. `etl::format_to`
### Generic output-iterator overload
```cpp
template<typename OutputIt, class... Args>
OutputIt format_to(OutputIt out, format_string<Args...> fmt, Args&&... args);
```
Formats `args` according to the format string `fmt` and writes the result through
the output iterator `out`. Returns an iterator past the last character written.
`OutputIt` can be any output iterator whose dereferenced type is assignable from
`char`, for example `etl::istring::iterator` or
`etl::back_insert_iterator<etl::istring>`.
```cpp
etl::string<100> s;
// Using a raw iterator — you must resize the string yourself
etl::istring::iterator result = etl::format_to(s.begin(), "{0} {1}", 34, 56);
s.uninitialized_resize(static_cast<size_t>(result - s.begin()));
// s == "34 56"
// Using a back_insert_iterator — string grows automatically
s.clear();
etl::back_insert_iterator<etl::istring> it(s);
etl::format_to(it, "{} {}", 65, 34);
// s == "65 34"
```
### `etl::istring&` overload (ETL-specific)
```cpp
template<class... Args>
etl::istring::iterator format_to(etl::istring& out,
format_string<Args...> fmt,
Args&&... args);
```
Convenience overload that writes into an `etl::istring` (or any derived
`etl::string<N>`). The string is automatically resized to the number of
characters written, up to `out.max_size()`. Returns an iterator past the
last character written.
```cpp
etl::string<100> s;
etl::format_to(s, "Hello, {}!", "world");
// s == "Hello, world!"
```
### `etl::format_to_n`
```cpp
template<typename OutputIt, class... Args>
OutputIt format_to_n(OutputIt out, size_t n,
format_string<Args...> fmt, Args&&... args);
```
Like `format_to`, but writes **at most** `n` characters. Characters beyond the
limit are silently discarded.
```cpp
etl::string<10> s = "abcdefghij";
etl::format_to_n(s.begin(), 3, "xy{}", 123);
// s == "xy1defghij" (only 3 chars written)
```
## 3. `etl::formatted_size`
```cpp
template<class... Args>
size_t formatted_size(format_string<Args...> fmt, Args&&... args);
```
Returns the total number of characters that `format_to` would produce, without
actually writing anything. Useful for pre-computing buffer sizes.
```cpp
size_t n;
n = etl::formatted_size(""); // 0
n = etl::formatted_size("{}", ""); // 0
n = etl::formatted_size("xyz{}", 12); // 5
n = etl::formatted_size("{}", "abc"); // 3
```
## 4. `etl::print` and `etl::println`
Declared in `etl/print.h`.
### `etl::print`
```cpp
template<class... Args>
void print(etl::format_string<Args...> fmt, Args&&... args);
```
Formats the arguments and outputs each character by calling `etl_putchar()`.
### `etl::println`
```cpp
// With arguments — prints formatted text followed by '\n'
template<class... Args>
void println(etl::format_string<Args...> fmt, Args&&... args);
// Without arguments — prints a bare newline
void println();
```
### Implementing `etl_putchar`
`etl/print.h` declares (but does not define) the following C-linkage function:
```cpp
extern "C" void etl_putchar(int c);
```
You **must** provide a definition in your project. The `int` parameter follows
the convention of the standard `putchar()` and carries a single `char` value.
Typical implementations forward to a UART, a debug probe, `putchar`, or any
other single-character output sink:
```cpp
// Example: forward to standard putchar
extern "C" void etl_putchar(int c)
{
putchar(c);
}
```
### Example
```cpp
etl::print("x = {}, y = {}\n", 10, 20); // "x = 10, y = 20\n"
etl::println("Hello, {}!", "world"); // "Hello, world!\n"
etl::println(); // "\n"
```
## 5. Format String Syntax
A format string is ordinary text with **replacement fields** delimited by braces:
```
"literal text {} more text {1:>10} end"
```
### Replacement field grammar
```
replacement_field ::= '{' [arg_id] [':' format_spec] '}'
arg_id ::= integer // e.g. 0, 1, 2 …
format_spec ::= [[fill]align] [sign] ['#'] ['0'] [width] ['.' precision] ['L'] [type]
```
| Component | Syntax | Description |
|---|---|---|
| **Argument index** | `{0}`, `{1}`, … | Manual positional indexing. Cannot be mixed with automatic indexing. |
| **Automatic index** | `{}` | Uses the next argument in order. Cannot be mixed with manual indexing. |
| **Fill character** | any character except `{` or `}` | Used together with an alignment specifier. Default is space (` `). |
| **Alignment** | `<` left, `>` right, `^` center | Aligns the formatted value within the given *width*. |
| **Sign** | `+` always, `-` negative only (default), ` ` space for positive | Controls sign display for numeric types. |
| **`#` (alt form)** | `#` | Adds `0x`/`0X` for hex, `0b`/`0B` for binary, `0` for octal. |
| **`0` (zero-pad)** | `0` | Pads the number with leading zeros (after sign/prefix). |
| **Width** | integer, or `{}` / `{n}` | Minimum field width. Supports nested replacement fields for dynamic width. |
| **Precision** | `.` integer, or `.{}` / `.{n}` | For strings: maximum characters to output. For floats: number of decimal digits. Supports nested replacement fields. |
| **`L`** | `L` | Locale-specific flag (parsed but currently ignored). |
| **Type** | see [Presentation Types](#7-presentation-types-per-argument-kind) | Selects the output representation. |
### Examples
```cpp
etl::format_to(s, "{:>10}", 42); // " 42"
etl::format_to(s, "{:*^10}", 42); // "****42****"
etl::format_to(s, "{:+05d}", 67); // "+00067"
etl::format_to(s, "{:#x}", 0x3f4); // "0x3f4"
etl::format_to(s, "{:.3s}", "abcdef"); // "abc"
etl::format_to(s, "{1} {0}", 1, 2); // "2 1"
```
## 6. Supported Argument Types
The core set of formattable types (matching `std::basic_format_arg`):
| Category | Types |
|---|---|
| Boolean | `bool` |
| Character | `char` |
| Signed integer | `int`, `long long int` |
| Unsigned integer | `unsigned int`, `unsigned long long int` |
| Floating-point *(opt-in)* | `float`, `double`, `long double` — requires `ETL_USING_FORMAT_FLOATING_POINT` |
| String | `const char*`, `etl::string_view` |
| Pointer | `const void*` |
### Implicit conversions
Types not listed above are converted automatically before formatting:
| Source type | Stored as |
|---|---|
| `short` | `int` |
| `unsigned short`, `uint16_t` | `unsigned int` |
| `long int` | `int` or `long long int` (platform-dependent) |
| `unsigned long int`, `size_t` | `unsigned int` or `unsigned long long int` |
| `int8_t` (`signed char`) | `char` |
| `uint8_t` (`unsigned char`) | `char` |
| `int16_t` | `int` |
| `uint32_t` | `unsigned int` |
| `int32_t` | `int` |
| `etl::string<N>` | `etl::string_view` (lifetime of the temporary is guaranteed) |
| any pointer `T*` | `const void*` |
## 7. Presentation Types per Argument Kind
### Integers (`int`, `unsigned int`, `long long int`, `unsigned long long int`)
| Type | Meaning | Example |
|---|---|---|
| `d` *(default)* | Decimal | `134``"134"` |
| `x` | Lowercase hexadecimal | `0x3f4``"3f4"` |
| `X` | Uppercase hexadecimal | `0x3f4``"3F4"` |
| `o` | Octal | `034``"34"` |
| `b` | Lowercase binary | `0b1010``"1010"` |
| `B` | Uppercase binary | `0b1010``"1010"` |
| `c` | Character (value as char) | `67``"C"` |
With `#`: prefixes `0x`/`0X`, `0b`/`0B`, or leading `0` for octal.
### Characters (`char`, `signed char`, `unsigned char`)
| Type | Meaning | Example |
|---|---|---|
| `c` *(default)* | Character itself | `'s'``"s"` |
| `?` | Debug / escaped | `'\n'``"'\\n'"` |
| `d` | Decimal code point | `'a'``"97"` |
| `x` / `X` | Hex code point | `'a'``"61"` |
### Booleans (`bool`)
| Type | Meaning | Example |
|---|---|---|
| *(default)* | `false` / `true` | `true``"true"` |
| `s` | Same as default | `true``"true"` |
| `d` | `0` / `1` | `true``"1"` |
| `x` / `X` | Hex `0` / `1` | `true``"1"` |
| `o` | Octal (with `#`: `01`) | `true``"01"` |
### Strings (`const char*`, `etl::string_view`, `etl::string<N>`)
| Type | Meaning | Example |
|---|---|---|
| `s` *(default)* | String output | `"data1"``"data1"` |
| `?` | Debug / escaped | `"data1\n"``"\"data1\\n\""` |
Width and precision apply: width sets the minimum field width; precision (`.N`)
truncates the string to at most *N* characters.
```cpp
etl::format_to(s, "{:>10s}", "data1"); // " data1"
etl::format_to(s, "{:.3s}", "abcdef"); // "abc"
etl::format_to(s, ".{:^8.3s}!", "data1"); // ". dat !"
```
### Pointers (`const void*`)
| Type | Meaning | Example |
|---|---|---|
| `p` *(default)* | Lowercase hex with `0x` prefix | `nullptr``"0x0"` |
| `P` | Uppercase hex with `0X` prefix | `nullptr``"0X0"` |
### Floating-point (`float`, `double`, `long double`)
Requires `ETL_USING_FORMAT_FLOATING_POINT`.
| Type | Meaning | Example |
|---|---|---|
| *(default)* | Shortest representation | `1.5f``"1.5"` |
| `e` / `E` | Scientific notation | `1.0f``"1.000000e+00"` |
| `f` / `F` | Fixed-point notation | `1.125f``"1.125000"` |
| `g` / `G` | General (fixed or scientific) | `1e10f``"1.000000e+10"` |
| `a` / `A` | Hexadecimal floating-point | `1.5f``"0x1.8p+0"` |
`nan`, `inf` (lowercase for `e`/`f`/`g`/`a`, uppercase for `E`/`F`/`G`/`A`).
## 8. Escape Sequences and Literal Braces
### Literal braces
Because `{` and `}` delimit replacement fields, they must be escaped by
doubling:
| Input | Output |
|---|---|
| `{{` | `{` |
| `}}` | `}` |
```cpp
etl::format_to(s, "abc{{def"); // "abc{def"
etl::format_to(s, "}}abc"); // "}abc"
```
### Debug / escaped presentation (`?`)
The `?` type specifier produces a debug representation:
- **Characters** are wrapped in single quotes with C-style escape sequences:
| Character | Output |
|---|---|
| `\t` | `'\\t'` |
| `\n` | `'\\n'` |
| `\r` | `'\\r'` |
| `"` | `'\\\"'` |
| `'` | `'\\''` |
| `\\` | `'\\\\'` |
- **Strings** are wrapped in double quotes with the same escape sequences:
```cpp
etl::format_to(s, "{:?}", "data1\n"); // "\"data1\\n\""
```
## 9. Error Handling
Invalid format strings cause an `etl::bad_format_string_exception` (derived from
`etl::format_exception`, which is derived from `etl::exception`).
Common error conditions:
| Condition | Example |
|---|---|
| Missing closing brace | `"a{b"` |
| Unescaped `}` without matching `{` | `"a}b"` |
| Invalid characters inside `{}` | `"a{b}"` |
| Argument index out of range | `"{1}"` with only one argument |
| Mixing manual and automatic indexing | `"{0} {}"` |
| Invalid type specifier for the argument | `"{:d}"` on a `string_view` |
| Double colon in format spec | `"{::}"` |
| Precision on an integer | `"{:+#05.5X}"` on an `int` |
```cpp
etl::string<100> s;
// These all throw etl::bad_format_string_exception:
etl::format_to(s, "a{b}", 1); // bad index spec
etl::format_to(s, "a{b", 1); // closing brace missing
etl::format_to(s, "a}b"); // unescaped }
etl::format_to(s, "{:d}", sv); // invalid type for string_view
```
> **Note:** On C++20 and later, format strings are validated at compile time
> via `consteval`. The checks cover syntax (balanced braces, valid format spec
> grammar, index bounds, no mixing of automatic and manual indexing) as well as
> type/specifier compatibility (e.g. `{:d}` is rejected for string arguments).
> A malformed format string produces a compile error whose diagnostic mentions
> `please_note_this_is_error_message_format_string_syntax_error`.
>
> On C++11C++17, the same checks run at runtime and throw
> `etl::bad_format_string_exception`.
## 10. Differences from `std::format`
| Area | `std::format` (C++20/23) | ETL |
|---|---|---|
| **Output target** | Returns `std::string` | Writes through an output iterator or into `etl::istring&` — no heap allocation. |
| **`etl::istring&` overload** | Not available | `format_to(etl::istring&, ...)` automatically resizes the string. |
| **`print` / `println` output** | Writes to `FILE*` / `stdout` | Writes character-by-character via user-defined `etl_putchar(int)`. |
| **Floating-point support** | Always available | Opt-in via `ETL_USING_FORMAT_FLOATING_POINT`. |
| **User-defined formatters** | `std::formatter<T>` specialisations | Not yet supported. |
| **Locale** | `L` flag uses `std::locale` | `L` flag is parsed but has no effect. |
| **Compile-time validation** | Enforced via `consteval` on C++20 | Enforced via `consteval` on C++20 (syntax and type/specifier compatibility); validates at run time and throws `etl::bad_format_string_exception` on C++11C++17. |
| **`format_to_n` return type** | `std::format_to_n_result` | Returns the underlying `OutputIt` directly. |

190
docs/generators.md Normal file
View File

@ -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<file>` | Write output to the specified file |
| `-D<var>=<value>` | 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 <typename T1, ")
for n in range(2, int(NTypes)):
cog.out("typename T%s = void, " % n)
cog.outl("typename T%s = void>" % 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/<name>_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/<name>_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 |

7
docs/index.md Normal file
View File

@ -0,0 +1,7 @@
---
title: ETL documentation
---
## Pages
* [Manchester](manchester.md)

259
docs/manchester.md Normal file
View File

@ -0,0 +1,259 @@
---
title: Manchester encoding and decoding
---
Efficient Manchester encoding and decoding of data. The Manchester code represents a data bit as a sequence of a 'high' and a 'low' value. In software this translates to a conversion from one to two bits, or in a practical situation, from `n` bytes to `n*2` bytes.
## See also
[Manchester code](https://en.wikipedia.org/wiki/Manchester_code)
## Features
- Normal and inverted Manchester encoding
- Support for multiple encoding chunk sizes: 8-bit, 16-bit and 32-bit
- Span-based operations or chunk-based operations
- Constexpr functions for compile-time encoding/decoding
- Validation of encoded data
- Chunked span I/O uses little-endian byte order for multi-byte chunks, independent of host platform endianness
## Algorithm background
To encode the value `0b11001100` we must first duplicate all bits to create the value `0b1111000011110000`. We then perform an XOR of this value with the constant `0b1010101010101010` (`0xAAAA`) to obtain the Manchester coded value of `0b1010010110100101`. We have now replaced each `1` bit with the sequence `10` and each `0` bit with the sequence `01`.
### 2. Bit duplication
Bit duplication is achieved with the following steps. This is also called binary interleaving. The example shows encoding of an 8-bit value.
| Step | High Byte | Low Byte | Operation |
|------|--------------------|--------------------|----------------------------|
| 0 | `_ _ _ _ _ _ _ _` | `A B C D E F G H` | input value (i) |
| 1 | `_ _ _ _ A B C D` | `_ _ _ _ E F G H` | `(i \| (i << 4)) & 0x0F0F` |
| 2 | `_ _ A B _ _ C D` | `_ _ E F _ _ G H` | `(i \| (i << 2)) & 0x3333` |
| 3 | `_ A _ B _ C _ D` | `_ E _ F _ G _ H` | `(i \| (i << 1)) & 0x5555` |
| 4 | `A A B B C C D D` | `E E F F G G H H` | `(i \| (i << 1))` |
This process can be easily extended to 16-bit or 32-bit values by adding additional steps to the bit duplication.
### 3. Manchester Decoding
Manchester decoding is done in a similar, but reversed way.
### 4. Error Detection
Error detection in Manchester coded data is done by comparing 2 neighboring bits. If they are
equal, then there is an error in the encoded input data.
Comparing all 8 bit pairs in a 16-bit word is done as follows.
| Step | Binary Value | Operation | Description |
|------|--------------|-------------------|-----------------------------------------------------------------------------------------------|
| 1 | `11011000` | Original | First bit pair (lsb, 00) is invalid. Last bit pair is also invalid. Other bit pairs are valid |
| 2 | `01101100` | Shift right by 1 | Shift the original value right by one bit |
| 3 | `10110100` | XOR | XOR the original with the shifted value |
| 4 | `01010101` | Mask with 0x55 | Apply mask to isolate bit pairs |
| 5 | `00010100` | Result | If result is not equal to 0x55, there was an error in the input |
## Analysis
Most traditional ways to Manchester encode data consist of a loop over all bits and a nested if-statement to check the value of the current bit. This approach does not scale well to increasing number of bits. The algorithm implemented here contains no conditional code and scales well. Doubling the number of processed bits per step (the chunk size) adds a single row to the bit duplication table. Because of the lack of loops and conditional code, this algorithm is likely to perform better than traditional ones on simple processors or when compiler optimization is disabled. On modern, powerful processors with caches and advanced optimization possibilities this algorithm may not show much benefit. In any case, the performance of the algorithm depends heavily on the processor type, compiler and compiler (optimization) settings.
## API Reference
### Classes
Classes `etl::manchester` and `etl::manchester_inverted` contain static functions for encoding, decoding and validity checking. It is not necessary to instantiate objects of these classes.
#### etl::manchester
```cpp
typedef manchester_base<private_manchester::manchester_type_normal> manchester;
```
Manchester encoder using normal encoding (no inversion).
#### etl::manchester_inverted
```cpp
typedef manchester_base<private_manchester::manchester_type_inverted> manchester_inverted;
```
Manchester encoder using inverted encoding.
### Encoding Functions
#### Encode single value
```cpp
template <typename TDecoded>
static ETL_CONSTEXPR14 typename encoded<TDecoded>::type encode(TDecoded decoded)
```
Encodes a single value using Manchester encoding.
**Parameters:**
- `decoded`: The value to encode (`uint8_t`, `uint16_t`, or `uint32_t`)
**Returns:**
- The Manchester encoded value (twice the bit width of input)
**Example:**
```cpp
uint16_t encoded = etl::manchester::encode(0x55);
```
#### Encode range
```cpp
template <typename TChunk = uint_least8_t>
static ETL_CONSTEXPR14 void encode(etl::span<const uint_least8_t> decoded,
etl::span<uint_least8_t> encoded)
```
Encodes a span of data using the specified chunk size.
**Parameters:**
- `decoded`: Source data to encode
- `encoded`: Destination for encoded data (must be twice the size of `decoded`)
**Template Parameters:**
- `TChunk`: Chunk size for encoding (`uint8_t`, `uint16_t` or `uint32_t`)
**Example:**
```cpp
std::array<uint8_t, 4> data = {0x12, 0x34, 0x56, 0x78};
std::array<uint8_t, 8> encoded_data1{};
std::array<uint8_t, 8> encoded_data2{};
// Encode with TChunk == uint8_t
etl::manchester::encode(data, encoded_data1);
// Encode with TChunk == uint32_t
etl::manchester::encode<uint32_t>(data, encoded_data2);
```
### Decoding Functions
#### Decode single value
```cpp
template <typename TEncoded>
static ETL_CONSTEXPR14 typename decoded<TEncoded>::type decode(TEncoded encoded)
```
Decodes a single Manchester encoded value.
**Parameters:**
- `encoded`: The encoded value to decode (`uint16_t`, `uint32_t`, or `uint64_t`)
**Returns:**
- The Manchester decoded value (half the bit width of input)
**Example:**
```cpp
uint8_t decoded = etl::manchester::decode(0x5A5A);
```
#### Decode range
```cpp
template <typename TChunk = typename private_manchester::encoded<uint_least8_t>::type>
static ETL_CONSTEXPR14 void decode(etl::span<const uint_least8_t> encoded,
etl::span<uint_least8_t> decoded)
```
Decodes a span of Manchester encoded data.
**Parameters:**
- `encoded`: Source data to decode
- `decoded`: Destination for decoded data (must be half the size of `encoded`)
**Template Parameters:**
- `TChunk`: Chunk type for decoding (`uint16_t`, `uint32_t`, or `uint64_t`)
**Example:**
```cpp
std::array<uint8_t, 8> encoded = {/* ... */};
std::array<uint8_t, 4> decoded1 {};
std::array<uint8_t, 4> decoded2 {};
// Decode with TChunk == uint16_t
etl::manchester::decode(encoded, decoded1);
// Decode with TChunk == uint64_t
etl::manchester::decode<uint64_t>(encoded, decoded2);
```
### Validation Functions
#### Single value
```cpp
template <typename TChunk>
static ETL_CONSTEXPR14 bool is_valid(TChunk encoded)
```
Validates that a single value contains valid Manchester encoded data.
**Parameters:**
- `encoded`: The encoded value to validate
**Returns:**
- `true` if the value contains valid Manchester encoded data, `false` otherwise
**Example:**
```cpp
bool valid = etl::manchester::is_valid(0x5A5A);
```
#### Range
```cpp
static ETL_CONSTEXPR14 bool is_valid(etl::span<const uint_least8_t> encoded)
```
Validates that a range contains valid Manchester encoded data.
**Parameters:**
- `encoded`: The range of encoded data to validate
**Returns:**
- `true` if all data is valid Manchester encoding, `false` otherwise
**Example:**
```cpp
std::array<uint8_t, 8> encoded_data = {/* ... */};
bool valid = etl::manchester::is_valid(encoded_data);
```
## Supported Types
### Input/chunk types for encoding
- `uint8_t``uint16_t` (if 8-bit types are supported)
- `uint16_t``uint32_t`
- `uint32_t``uint64_t` (if 64-bit types are supported)
### Input/chunk types for decoding
- `uint16_t``uint8_t` (if 8-bit types are supported)
- `uint32_t``uint16_t`
- `uint64_t``uint32_t` (if 64-bit types are supported)

116
docs/meson.md Normal file
View File

@ -0,0 +1,116 @@
# Building ETL with Meson
## Prerequisites
- [Meson](https://mesonbuild.com/) >= 0.57.0
- A C++17 compiler (GCC, Clang, or MSVC)
- [Ninja](https://ninja-build.org/) (default Meson backend)
UnitTest++ is fetched automatically as a Meson subproject — no manual dependency installation is needed.
## Quick Start
```bash
# Configure (from the project root)
meson setup builddir
# Build
meson compile -C builddir
# Run tests
meson test -C builddir
```
## Build Options
### ETL project options
| Option | Type | Default | Description |
|---------------------|------|---------|-------------------------------------------------------------------|
| `use_stl` | bool | `true` | Build with STL support. When `false`, defines `ETL_NO_STL`. |
| `enable_sanitizer` | bool | `false` | Enable AddressSanitizer and UndefinedBehaviorSanitizer (GCC/Clang only). |
### Meson built-in options
| Option | Type | Default | Description |
|-------------|--------|----------|----------------------------------------------------------|
| `cpp_std` | string | `c++17` | C++ standard to compile with (e.g. `c++20`, `c++23`). |
| `buildtype` | string | `debug` | Build type: `plain`, `debug`, `debugoptimized`, `release`, `minsize`. |
| `werror` | bool | `false` | Treat compiler warnings as errors. |
These are handled by Meson directly — no `get_option()` call is needed in the build files.
### Examples
```bash
# No STL, C++23
meson setup builddir -Duse_stl=false -Dcpp_std=c++23
# Release build with sanitizers
meson setup builddir -Dbuildtype=release -Denable_sanitizer=true
# Override the C++ standard on an existing build directory
meson configure builddir -Dcpp_std=c++20
```
## Selecting a Compiler
The compiler is chosen at configure time via environment variables:
```bash
# GCC
CC=gcc CXX=g++ meson setup builddir
# Clang
CC=clang CXX=clang++ meson setup builddir
# Specific versions
CC=gcc-14 CXX=g++-14 meson setup builddir
CC=clang-18 CXX=clang++-18 meson setup builddir
```
To switch compilers on an existing build directory, wipe it first:
```bash
CC=clang CXX=clang++ meson setup --wipe builddir
```
Or use separate directories per compiler:
```bash
CC=gcc CXX=g++ meson setup build-gcc
CC=clang CXX=clang++ meson setup build-clang
```
## Running Tests
```bash
# Run all tests
meson test -C builddir
# Verbose output (shows individual test results)
meson test -C builddir -v
# Run the test binary directly
./builddir/test/etl_unit_tests
```
## Sanitizers
On GCC and Clang, AddressSanitizer and UndefinedBehaviorSanitizer can be enabled via the `enable_sanitizer` option:
```bash
meson setup builddir -Denable_sanitizer=true
```
Note: UBSan may prevent certain `constexpr` evaluations involving function pointers from compiling (e.g. in the closure tests). This matches the CMake build, where sanitizers are also opt-in via `ETL_ENABLE_SANITIZER=ON`.
## Using ETL as a Subproject
ETL can be consumed as a Meson subproject. In your project's `subprojects/` directory, create an `etl.wrap` file, then use:
```meson
etl_dep = dependency('etl', fallback: ['etl', 'etl_dep'])
```
When built as a subproject, the ETL test suite is not compiled.

328
docs/ranges.md Normal file
View File

@ -0,0 +1,328 @@
# ETL C++17 Ranges Implementation
## Overview
The Embedded Template Library provides a C++17-compatible implementation of ranges, inspired by the C++20 ranges library. This implementation enables range-based algorithms and views for embedded and resource-constrained environments where full C++20 support may not be available.
## Features
- **Ranges**: Provides range types and iterator wrappers for composing operations over sequences.
- **Views**: Includes lightweight, composable views such as `filter_view`, `transform_view`, and `subrange`.
- **Algorithms**: Supports range-based algorithms compatible with ETL containers and standard containers.
- **Compatibility**: Designed for C++17, with minimal dependencies and no reliance on C++20 features.
## Getting Started
Include the main header in your project:
```cpp
#include <etl/ranges.h>
```
### Example Usage
#### Using Ranges
```cpp
#include <etl/print.h>
#include <etl/ranges.h>
#include <etl/vector.h>
...
etl::vector<int, 10> data = {6, 1, 3, 3, 2};
etl::ranges::sort(data);
etl::ranges::for_each(data, [](const int& i){etl::print(" {}", i);});
```
Output:
```text
1 2 3 3 6
```
#### Using Views
```cpp
#include <etl/print.h>
#include <etl/ranges.h>
#include <etl/vector.h>
...
etl::vector<int, 10> data = {1, 2, 3, 4, 5};
auto even = [](int v) { return v % 2 == 0; };
auto filtered = etl::ranges::filter_view(data, even);
etl::ranges::for_each(filtered, [](const int& i){etl::print(" {}", i);});
```
Output:
```text
2 4
```
#### Transforming Elements
```cpp
#include <etl/print.h>
#include <etl/ranges.h>
#include <etl/vector.h>
...
etl::vector<int, 10> data = {1, 2, 3, 4, 5};
auto squared = etl::ranges::transform_view(data, [](int v) { return v * v; });
etl::ranges::for_each(squared, [](const int& i){etl::print(" {}", i);});
```
Output:
```text
1 4 9 16 25
```
#### Composition
Views can be composed using the pipe (`|`) operator, allowing you to chain multiple transformations in a readable, left-to-right style:
```cpp
#include <etl/print.h>
#include <etl/ranges.h>
#include <etl/vector.h>
namespace views = etl::ranges::views;
...
etl::vector<int, 10> data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
auto result = data
| views::filter([](const int& v) { return v % 2 == 0; })
| views::transform([](const int& v) { return v * v; });
etl::ranges::for_each(result, [](const int& i){ etl::print(" {}", i); });
```
Output:
```text
4 16 36 64 100
```
This first filters the even numbers and then squares them. Each `|` passes the result of the previous stage as input to the next view adaptor.
## Supported Views
All views are in the `etl::ranges` namespace. Corresponding range adaptor objects are available in `etl::ranges::views`.
### Range Factories
| View | `views::` adaptor | Description |
|---|---|---|
| `empty_view<T>` | `views::empty<T>` | A view with no elements. |
| `single_view` | `views::single` | A view containing exactly one element. |
| `iota_view` | `views::iota` | A view of sequentially increasing values. |
| `repeat_view` | `views::repeat` | A view that repeats a value a given number of times. |
### Range Adaptors
| View | `views::` adaptor | Description |
|---|---|---|
| `ref_view` | `views::ref` | A non-owning view that wraps a reference to a range. |
| `owning_view` | `views::owning` | A view that takes ownership of a range via move. |
| — | `views::all` | Returns the range itself (if already a view), a `ref_view`, or an `owning_view`. |
| `filter_view` | `views::filter` | Filters elements based on a predicate. |
| `transform_view` | `views::transform` | Applies a transformation to each element. |
| `as_rvalue_view` | `views::as_rvalue` | Casts each element to an rvalue reference. |
| `as_const_view` | `views::as_const` | Provides a const view of the elements. |
| `cache_latest_view` | `views::cache_latest` | Caches the most recently accessed element (avoids recomputation). |
| `reverse_view` | `views::reverse` | Reverses the order of elements. |
| `drop_view` | `views::drop` | Skips the first *n* elements. |
| `drop_while_view` | `views::drop_while` | Skips leading elements while a predicate is true. |
| `take_view` | `views::take` | Takes the first *n* elements. |
| `take_while_view` | `views::take_while` | Takes leading elements while a predicate is true. |
| `join_view` | `views::join` | Flattens a range of ranges into a single range. |
| `join_with_view` | `views::join_with` | Flattens a range of ranges, inserting a delimiter between each. |
| `split_view` | `views::split` | Splits a range into subranges around a delimiter pattern. |
| `lazy_split_view` | `views::lazy_split` | Lazily splits a range by a pattern (inner ranges discovered on iteration). |
| — | `views::counted` | Creates a view of *n* elements starting from an iterator. |
| `concat_view` | `views::concat` | Concatenates multiple ranges into a single view. |
| `zip_view` | `views::zip` | Zips multiple ranges into a view of tuples (length of shortest range). |
| `zip_transform_view` | `views::zip_transform` | Zips multiple ranges and applies a function to each tuple of elements. |
| `common_view` | `views::common` | Adapts a view so that its iterator and sentinel types are the same. |
| `enumerate_view` | `views::enumerate` | Pairs each element with its index, producing tuples of (index, value). |
| `elements_view` | `views::elements` | Extracts the *N*-th element from each tuple-like value. |
| `keys_view` | `views::keys` | Alias for `elements_view` with *N*=0 (extracts first element of pairs/tuples). |
| `values_view` | `views::values` | Alias for `elements_view` with *N*=1 (extracts second element of pairs/tuples). |
| `adjacent_view` | `views::adjacent` | Produces a view of tuples of *N* adjacent elements (sliding window of tuples). |
| — | `views::pairwise` | Alias for `views::adjacent<2>`. |
| `adjacent_transform_view` | `views::adjacent_transform` | Applies a function to each group of *N* adjacent elements. |
| — | `views::pairwise_transform` | Alias for `views::adjacent_transform<2>`. |
| `chunk_view` | `views::chunk` | Splits a range into non-overlapping chunks of a given size. |
| `slide_view` | `views::slide` | Produces overlapping subranges (sliding windows) of a given size. |
| `chunk_by_view` | `views::chunk_by` | Splits a range into subranges between adjacent elements where a predicate is false. |
| `stride_view` | `views::stride` | Yields every *N*-th element from the underlying range. |
| `cartesian_product_view` | `views::cartesian_product` | Produces the Cartesian product of multiple ranges as a view of tuples. |
| `to_input_view` | `views::to_input` | Downgrades iterator category to input iterator while preserving elements and order. |
| `subrange` | — | Represents a sub-range defined by an iteratorsentinel pair. |
All views support range-based for-loop iteration and can be composed with the pipe (`|`) operator.
## Supported Algorithms
All algorithms are callable objects in the `etl::ranges` namespace. Each supports both an iterator-pair overload and a range overload (where applicable), and most accept optional projection and comparator arguments.
### Non-modifying Sequence Operations
| Algorithm | Description |
|---|---|
| `for_each` | Applies a function to each element in a range. |
| `for_each_n` | Applies a function to the first *n* elements. |
| `find` | Finds the first element equal to a value. |
| `find_if` | Finds the first element satisfying a predicate. |
| `find_if_not` | Finds the first element not satisfying a predicate. |
| `find_end` | Finds the last occurrence of a subsequence. |
| `find_first_of` | Finds the first element matching any in a second range. |
| `adjacent_find` | Finds the first pair of adjacent equal elements. |
| `count` | Counts elements equal to a value. |
| `count_if` | Counts elements satisfying a predicate. |
| `all_of` | Checks if all elements satisfy a predicate. |
| `any_of` | Checks if any element satisfies a predicate. |
| `none_of` | Checks if no elements satisfy a predicate. |
| `mismatch` | Finds the first position where two ranges differ. |
| `equal` | Checks if two ranges are equal. |
| `is_permutation` | Checks if one range is a permutation of another. |
| `search` | Searches for the first occurrence of a subsequence. |
| `search_n` | Searches for *n* consecutive copies of a value. |
| `starts_with` | Checks if a range starts with another range. |
| `ends_with` | Checks if a range ends with another range. |
| `lexicographical_compare` | Compares two ranges lexicographically. |
### Fold Operations
| Algorithm | Description |
|---|---|
| `fold_left` | Left-folds elements with a binary operation. |
| `fold_left_with_iter` | Left-folds, returning both the result and an iterator. |
| `fold_left_first` | Left-folds using the first element as the initial value. |
| `fold_left_first_with_iter` | Like `fold_left_first`, also returning an iterator. |
| `fold_right` | Right-folds elements with a binary operation. |
| `fold_right_last` | Right-folds using the last element as the initial value. |
### Modifying Sequence Operations
| Algorithm | Description |
|---|---|
| `copy` | Copies elements to a destination range. |
| `copy_n` | Copies *n* elements to a destination range. |
| `copy_if` | Copies elements satisfying a predicate. |
| `copy_backward` | Copies elements backwards to a destination range. |
| `move` | Moves elements to a destination range. |
| `move_backward` | Moves elements backwards to a destination range. |
| `swap_ranges` | Swaps elements between two ranges. |
| `replace` | Replaces elements equal to a value. |
| `replace_if` | Replaces elements satisfying a predicate. |
| `replace_copy` | Copies, replacing elements equal to a value. |
| `replace_copy_if` | Copies, replacing elements satisfying a predicate. |
| `remove` | Removes elements equal to a value. |
| `remove_if` | Removes elements satisfying a predicate. |
| `remove_copy` | Copies, omitting elements equal to a value. |
| `fill` | Fills a range with a value. |
| `fill_n` | Fills *n* elements with a value. |
| `generate` | Assigns each element the result of a generator function. |
| `generate_n` | Assigns *n* elements the result of a generator function. |
| `iota` | Fills a range with sequentially increasing values. |
| `unique` | Removes consecutive duplicate elements. |
| `unique_copy` | Copies, removing consecutive duplicates. |
| `transform` | Applies a transformation to each element. |
| `reverse` | Reverses the order of elements. |
| `reverse_copy` | Copies elements in reverse order. |
| `rotate` | Rotates elements in a range. |
| `rotate_copy` | Copies elements with rotation. |
| `shift_left` | Shifts elements to the left. |
| `shift_right` | Shifts elements to the right. |
| `shuffle` | Randomly reorders elements. |
| `sample` | Selects *n* random elements from a range. |
### Sorting Operations
| Algorithm | Description |
|---|---|
| `sort` | Sorts elements in a range. |
| `stable_sort` | Sorts elements preserving relative order of equivalent elements. |
| `partial_sort` | Partially sorts a range so that the first *n* elements are sorted. |
| `partial_sort_copy` | Copies and partially sorts elements. |
| `nth_element` | Partially sorts so that the *n*-th element is in its sorted position. |
| `is_sorted` | Checks if a range is sorted. |
| `is_sorted_until` | Finds the first unsorted element. |
### Partitioning Operations
| Algorithm | Description |
|---|---|
| `partition` | Partitions elements by a predicate. |
| `stable_partition` | Partitions elements, preserving relative order. |
| `is_partitioned` | Checks if a range is partitioned. |
| `partition_copy` | Copies elements into two ranges based on a predicate. |
| `partition_point` | Finds the partition point. |
### Binary Search (on sorted ranges)
| Algorithm | Description |
|---|---|
| `lower_bound` | Finds the first element not less than a value. |
| `upper_bound` | Finds the first element greater than a value. |
| `equal_range` | Returns the range of elements equal to a value. |
| `binary_search` | Checks if a sorted range contains a value. |
### Set Operations (on sorted ranges)
| Algorithm | Description |
|---|---|
| `includes` | Checks if one sorted range includes another. |
| `merge` | Merges two sorted ranges. |
| `inplace_merge` | Merges two consecutive sorted sub-ranges in place. |
| `set_union` | Computes the union of two sorted ranges. |
| `set_intersection` | Computes the intersection of two sorted ranges. |
| `set_difference` | Computes the difference of two sorted ranges. |
| `set_symmetric_difference` | Computes the symmetric difference of two sorted ranges. |
### Heap Operations
| Algorithm | Description |
|---|---|
| `make_heap` | Creates a heap from a range. |
| `push_heap` | Pushes an element onto a heap. |
| `pop_heap` | Pops the top element from a heap. |
| `sort_heap` | Sorts a heap into a sorted range. |
| `is_heap` | Checks if a range is a heap. |
| `is_heap_until` | Finds the first element that breaks the heap property. |
### Min/Max Operations
| Algorithm | Description |
|---|---|
| `min` | Returns the smaller of two values or the smallest in an initializer list. |
| `min_element` | Finds the smallest element in a range. |
| `max` | Returns the larger of two values or the largest in an initializer list. |
| `max_element` | Finds the largest element in a range. |
| `minmax` | Returns the smaller and larger of two values. |
| `minmax_element` | Finds both the smallest and largest elements in a range. |
| `clamp` | Clamps a value between a minimum and maximum. |
### Permutation Operations
| Algorithm | Description |
|---|---|
| `next_permutation` | Generates the next lexicographic permutation. |
| `prev_permutation` | Generates the previous lexicographic permutation. |
## Reference
For reference to the STD implementation, see also:
- Algorithms: https://en.cppreference.com/w/cpp/algorithm.html
- Ranges/Views: https://en.cppreference.com/w/cpp/ranges.html
## Limitations
- Not all C++20 range features are available due to limitation to C++17. Especially C++20 concepts are not used.
- Designed for ETL containers but can work with standard containers if compatible with ETL's iterator requirements.

100
docs/source-formatting.md Normal file
View File

@ -0,0 +1,100 @@
# Source Formatting
This project uses **clang-format** (version 18) to enforce a consistent coding style
for C and C++ source files. For convenience, **treefmt** is also configured as a
single-command wrapper that discovers and formats every file in the tree.
---
## clang-format
### Configuration file
The formatting rules live in [`.clang-format`](../.clang-format) at the repository
root. The style is based on **LLVM**.
See the `.clang-format` file itself for the complete list.
### Version requirement
clang-format **18** is required.
The helper script [`scripts/clang-format-wrapper`](../scripts/clang-format-wrapper)
automatically resolves the correct binary: it first looks for `clang-format-18` on
`PATH`, then falls back to `clang-format` and verifies that its major version is 18.
All other tooling in the repo calls this wrapper instead of `clang-format` directly.
### Running clang-format manually
Format every tracked source file in the repository:
```bash
git ls-files -z \
'*.c' '*.cc' '*.cpp' \
'*.h' '*.hh' '*.hpp' \
':(exclude)include/etl/generators/*' \
':(exclude)include/etl/private/*_cpp03.h' | xargs -0 scripts/clang-format-wrapper -i --verbose --style=file
```
You can also format individual files directly:
```bash
scripts/clang-format-wrapper -i --style=file path/to/file.cpp
```
---
## treefmt
[treefmt](https://treefmt.com) is a language-agnostic source-tree formatter.
It reads a single configuration file and dispatches each file to the appropriate
formatter. In this project, it delegates all C/C++ formatting to the same
`clang-format-wrapper` described above.
In comparison to calling clang-format directly, it brings a significant speedup.
### Configuration file
The configuration lives in [`.treefmt.toml`](../.treefmt.toml) at the repository root.
### Installing treefmt
treefmt is a standalone Go binary. Install it with any of:
```bash
# Using the official install script
curl -fsSL https://raw.githubusercontent.com/numtide/treefmt/main/install.sh | bash
# Or via Homebrew
brew install treefmt
# Or via Nix
nix profile install nixpkgs#treefmt2
```
See the [treefmt documentation](https://treefmt.com) for more options.
### Running treefmt
From the repository root:
```bash
# Format everything
treefmt
# Check formatting without modifying files (useful in CI)
treefmt --fail-on-change
```
---
## Excluded paths
`.treefmt.toml` excludes generated files under
`include/etl/generators/`. Do **not** format those files manually via clang-format or treefmt.
## Pre-commit
Before submitting a PR / contribution, run `treefmt --fail-on-change` to catch
unformatted code before merge.
Alternatively, a plain `treefmt` automatically fixes any issues.

412
docs/testing.md Normal file
View File

@ -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 <C++ Standard> [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 <C++ Standard> [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 <architecture>
```
### 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/<arch>/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-<arch>` and runs CMake with the appropriate cross-
compilation toolchain file
(`.devcontainer/<arch>/toolchain-<arch>.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/<arch>/`, 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.

View File

@ -10,6 +10,6 @@
#define ETL_CALLBACK_TIMER_USE_ATOMIC_LOCK
#define ETL_NO_STL
//#include "etl/profiles/auto.h"
// #include "etl/profiles/auto.h"
#endif

View File

@ -1,23 +1,23 @@
#include <stdio.h>
//#if (__cplusplus < 201103L)
// #if (__cplusplus < 201103L)
extern "C"
{
//#endif
#include "Board_LED.h" // ::Board Support:LED
// #endif
#include "Board_Buttons.h" // ::Board Support:Buttons
//#if (__cplusplus < 201103L)
#include "Board_LED.h" // ::Board Support:LED
// #if (__cplusplus < 201103L)
}
//#endif
// #endif
#include "stm32f4xx.h" // Device header
#include "stm32f4xx.h" // Device header
#include "etl/function.h"
#include "etl/callback_timer.h"
#include "etl/vector.h"
#include "etl/iterator.h"
#include "etl/binary.h"
#include "etl/callback_timer.h"
#include "etl/function.h"
#include "etl/iterator.h"
#include "etl/vector.h"
struct FP
{
@ -28,7 +28,7 @@ static etl::vector<FP, 10> power_callbacks;
void register_poweroff_callback(void (*function)())
{
FP fp = { function };
FP fp = {function};
power_callbacks.push_back(fp);
}
@ -45,38 +45,38 @@ etl::timer::id::type swap_timers;
* SystemCoreClockConfigure: configure SystemCoreClock using HSI
(HSE is not populated on Nucleo board)
*----------------------------------------------------------------------------*/
void SystemCoreClockConfigure(void) {
void SystemCoreClockConfigure(void)
{
RCC->CR |= ((uint32_t)RCC_CR_HSION); // Enable HSI
while ((RCC->CR & RCC_CR_HSIRDY) == 0); // Wait for HSI Ready
RCC->CR |= ((uint32_t)RCC_CR_HSION); // Enable HSI
while ((RCC->CR & RCC_CR_HSIRDY) == 0); // Wait for HSI Ready
RCC->CFGR = RCC_CFGR_SW_HSI; // HSI is system clock
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI); // Wait for HSI used as system clock
RCC->CFGR = RCC_CFGR_SW_HSI; // HSI is system clock
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI); // Wait for HSI used as system clock
FLASH->ACR = FLASH_ACR_PRFTEN; // Enable Prefetch Buffer
FLASH->ACR |= FLASH_ACR_ICEN; // Instruction cache enable
FLASH->ACR |= FLASH_ACR_DCEN; // Data cache enable
FLASH->ACR |= FLASH_ACR_LATENCY_5WS; // Flash 5 wait state
FLASH->ACR = FLASH_ACR_PRFTEN; // Enable Prefetch Buffer
FLASH->ACR |= FLASH_ACR_ICEN; // Instruction cache enable
FLASH->ACR |= FLASH_ACR_DCEN; // Data cache enable
FLASH->ACR |= FLASH_ACR_LATENCY_5WS; // Flash 5 wait state
RCC->CFGR |= RCC_CFGR_HPRE_DIV1; // HCLK = SYSCLK
RCC->CFGR |= RCC_CFGR_PPRE1_DIV4; // APB1 = HCLK/4
RCC->CFGR |= RCC_CFGR_PPRE2_DIV2; // APB2 = HCLK/2
RCC->CFGR |= RCC_CFGR_HPRE_DIV1; // HCLK = SYSCLK
RCC->CFGR |= RCC_CFGR_PPRE1_DIV4; // APB1 = HCLK/4
RCC->CFGR |= RCC_CFGR_PPRE2_DIV2; // APB2 = HCLK/2
RCC->CR &= ~RCC_CR_PLLON; // Disable PLL
RCC->CR &= ~RCC_CR_PLLON; // Disable PLL
// PLL configuration: VCO = HSI/M * N, Sysclk = VCO/P
RCC->PLLCFGR = ( 16ul | // PLL_M = 16
(384ul << 6U) | // PLL_N = 384
( 3ul << 16U) | // PLL_P = 8
(RCC_PLLCFGR_PLLSRC_HSI) | // PLL_SRC = HSI
( 8ul << 24U) ); // PLL_Q = 8
RCC->PLLCFGR = (16ul | // PLL_M = 16
(384ul << 6U) | // PLL_N = 384
(3ul << 16U) | // PLL_P = 8
(RCC_PLLCFGR_PLLSRC_HSI) | // PLL_SRC = HSI
(8ul << 24U)); // PLL_Q = 8
RCC->CR |= RCC_CR_PLLON; // Enable PLL
while((RCC->CR & RCC_CR_PLLRDY) == 0) __NOP(); // Wait till PLL is ready
RCC->CR |= RCC_CR_PLLON; // Enable PLL
while ((RCC->CR & RCC_CR_PLLRDY) == 0) __NOP(); // Wait till PLL is ready
RCC->CFGR &= ~RCC_CFGR_SW; // Select PLL as system clock source
RCC->CFGR |= RCC_CFGR_SW_PLL;
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL); // Wait till PLL is system clock src
RCC->CFGR &= ~RCC_CFGR_SW; // Select PLL as system clock source
RCC->CFGR |= RCC_CFGR_SW_PLL;
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL); // Wait till PLL is system clock src
}
void StartTimers()
@ -123,7 +123,7 @@ void LedToggle()
int main()
{
SystemCoreClockConfigure(); // configure HSI as System Clock
SystemCoreClockConfigure(); // configure HSI as System Clock
SystemCoreClockUpdate();
LED_Initialize();
@ -131,10 +131,10 @@ int main()
// The LEDs will start flashing fast after 2 seconds.
// After another 5 seconds they will start flashing slower.
short_toggle = callback_timer.register_timer(LedToggle, 50, etl::timer::mode::REPEATING);
long_toggle = callback_timer.register_timer(LedToggle, 100, etl::timer::mode::REPEATING);
short_toggle = callback_timer.register_timer(LedToggle, 50, etl::timer::mode::REPEATING);
long_toggle = callback_timer.register_timer(LedToggle, 100, etl::timer::mode::REPEATING);
start_timers = callback_timer.register_timer(StartTimers, 2000, etl::timer::mode::SINGLE_SHOT);
swap_timers = callback_timer.register_timer(SwapTimers, 1500, etl::timer::mode::SINGLE_SHOT);
swap_timers = callback_timer.register_timer(SwapTimers, 1500, etl::timer::mode::SINGLE_SHOT);
SysTick_Config(SystemCoreClock / 1000);
@ -152,7 +152,7 @@ extern "C"
{
void SysTick_Handler()
{
const uint32_t TICK = 1U;
const uint32_t TICK = 1U;
static uint32_t nticks = TICK;
if (callback_timer.tick(nticks))

View File

@ -11,8 +11,8 @@ enum VectorId
USART1_IRQ_HANDLER = 52,
USART2_IRQ_HANDLER = 53,
VECTOR_ID_END,
VECTOR_ID_OFFSET = TIM1_CC_IRQ_HANDLER,
VECTOR_ID_RANGE = VECTOR_ID_END - VECTOR_ID_OFFSET
VECTOR_ID_OFFSET = TIM1_CC_IRQ_HANDLER,
VECTOR_ID_RANGE = VECTOR_ID_END - VECTOR_ID_OFFSET
};
typedef etl::delegate_service<VECTOR_ID_RANGE, VECTOR_ID_OFFSET> InterruptVectors;
@ -91,8 +91,8 @@ public:
// Constructor.
Uart(int port_id, size_t interruptId)
: port_id(port_id),
callback(etl::delegate<void(size_t)>::create<Uart, &Uart::InterruptHandler>(*this))
: port_id(port_id)
, callback(etl::delegate<void(size_t)>::create<Uart, &Uart::InterruptHandler>(*this))
{
GetInterruptVectorsInstance().register_delegate(interruptId, callback);
}
@ -119,7 +119,8 @@ Uart uart1(0, USART1_IRQ_HANDLER);
Uart uart2(1, USART2_IRQ_HANDLER);
// Declare a global callback for the timer.
// Uses the most efficient callback type for a class, as everything is known at compile time.
// Uses the most efficient callback type for a class, as everything is known at
// compile time.
etl::delegate<void(size_t)> timer_member_callback = etl::delegate<void(size_t)>::create<Timer, timer, &Timer::InterruptHandler>();
// Declare the callbacks for the free functions.

View File

@ -1,7 +1,7 @@
#include <iostream>
#include "etl/function.h"
#include "etl/callback_service.h"
#include "etl/function.h"
enum VectorId
{
@ -11,8 +11,8 @@ enum VectorId
USART1_IRQ_HANDLER = 52,
USART2_IRQ_HANDLER = 53,
VECTOR_ID_END,
VECTOR_ID_OFFSET = TIM1_CC_IRQ_HANDLER,
VECTOR_ID_RANGE = VECTOR_ID_END - VECTOR_ID_OFFSET
VECTOR_ID_OFFSET = TIM1_CC_IRQ_HANDLER,
VECTOR_ID_RANGE = VECTOR_ID_END - VECTOR_ID_OFFSET
};
typedef etl::callback_service<VECTOR_ID_RANGE, VECTOR_ID_OFFSET> InterruptVectors;
@ -91,8 +91,8 @@ public:
// Constructor.
Uart(int port_id, int interruptId)
: port_id(port_id),
callback(*this)
: port_id(port_id)
, callback(*this)
{
GetInterruptVectorsInstance().register_callback(interruptId, callback);
}
@ -119,7 +119,8 @@ Uart uart1(0, USART1_IRQ_HANDLER);
Uart uart2(1, USART2_IRQ_HANDLER);
// Declare a global callback for the timer.
// Uses the most efficient callback type for a class, as everything is known at compile time.
// Uses the most efficient callback type for a class, as everything is known at
// compile time.
etl::function_imp<Timer, size_t, timer, &Timer::InterruptHandler> timer_member_callback;
// Declare the callbacks for the free functions.

View File

@ -1,13 +1,13 @@
#include <iostream>
#include <thread>
#include <atomic>
#include <string>
#include <chrono>
#include <iostream>
#include <string>
#include <thread>
#include "etl/mutex.h"
#include "etl/message.h"
#include "etl/message_router.h"
#include "etl/mutex.h"
//*************************************
struct Message1 : public etl::message<1>
@ -48,9 +48,7 @@ public:
}
//*****************
void on_receive_unknown(const etl::imessage&)
{
}
void on_receive_unknown(const etl::imessage&) {}
std::string result;
@ -61,7 +59,7 @@ private:
//*************************************
etl::atomic<bool> start = false;
Router router;
Router router;
//*************************************
void thread1()
@ -106,5 +104,3 @@ int main()
return 0;
}

Some files were not shown because too many files have changed in this diff Show More