mirror of
https://github.com/ETLCPP/etl.git
synced 2026-10-28 18:07:10 +08:00
Merge 5a110847a19e4a758c2f06dab04c21b5e2d844c0 into 60ba92928e8af3441f2a4eea5f18fd2563d98ad0
This commit is contained in:
commit
8a20befca4
57
.devcontainer/gcc16/Dockerfile
Normal file
57
.devcontainer/gcc16/Dockerfile
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
# Pinned by digest for reproducible builds.
|
||||||
|
# To update: docker buildx imagetools inspect debian:sid-slim
|
||||||
|
FROM debian:sid-slim@sha256:ec3fa4e0b2987ae47be353f56854191e300261915470e40165b1c906d22a65db
|
||||||
|
|
||||||
|
# Pin the package archive to a snapshot.debian.org timestamp so that
|
||||||
|
# `apt-get install` resolves the same package versions on every build.
|
||||||
|
# This is the snapshot the base image itself was built from - see the comment
|
||||||
|
# in /etc/apt/sources.list.d/debian.sources of the pinned image above.
|
||||||
|
ARG DEBIAN_SNAPSHOT=20260918T000000Z
|
||||||
|
|
||||||
|
# snapshot.debian.org serves archived Release files whose Valid-Until has long
|
||||||
|
# since passed, so that check has to be disabled.
|
||||||
|
# http is used rather than https because the slim base image has no
|
||||||
|
# ca-certificates; integrity is guaranteed by the archive's GPG signature.
|
||||||
|
RUN printf '%s\n' \
|
||||||
|
'Types: deb' \
|
||||||
|
"URIs: http://snapshot.debian.org/archive/debian/${DEBIAN_SNAPSHOT}/" \
|
||||||
|
'Suites: sid' \
|
||||||
|
'Components: main' \
|
||||||
|
'Check-Valid-Until: no' \
|
||||||
|
'Signed-By: /usr/share/keyrings/debian-archive-keyring.pgp' \
|
||||||
|
> /etc/apt/sources.list.d/debian.sources
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
build-essential \
|
||||||
|
cmake \
|
||||||
|
git \
|
||||||
|
ninja-build \
|
||||||
|
python3 \
|
||||||
|
python3-cogapp \
|
||||||
|
gcc-16 \
|
||||||
|
g++-16 \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-16 100 \
|
||||||
|
--slave /usr/bin/gcc-ar gcc-ar /usr/bin/gcc-ar-16 \
|
||||||
|
--slave /usr/bin/gcc-nm gcc-nm /usr/bin/gcc-nm-16 \
|
||||||
|
--slave /usr/bin/gcc-ranlib gcc-ranlib /usr/bin/gcc-ranlib-16 \
|
||||||
|
&& update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-16 100
|
||||||
|
|
||||||
|
# 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}
|
||||||
|
|
||||||
|
# Ensure workspace directory ownership for non-root user
|
||||||
|
RUN mkdir -p /etl && chown -R ${USERNAME}:${USERNAME} /etl
|
||||||
|
|
||||||
|
WORKDIR /etl
|
||||||
|
|
||||||
|
# Switch to non-root user
|
||||||
|
USER ${USERNAME}
|
||||||
|
|
||||||
|
CMD ["/bin/bash"]
|
||||||
12
.devcontainer/gcc16/devcontainer.json
Normal file
12
.devcontainer/gcc16/devcontainer.json
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// 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
|
||||||
|
//
|
||||||
|
// GCC 16 is the reference toolchain for the C++26 static reflection support in
|
||||||
|
// etl/meta.h. It cannot use the shared ../Dockerfile because there is no
|
||||||
|
// 'gcc:16' base image yet, so gcc-16 is taken from Debian sid instead.
|
||||||
|
{
|
||||||
|
"name": "Gcc 16",
|
||||||
|
"build": {
|
||||||
|
"dockerfile": "./Dockerfile"
|
||||||
|
}
|
||||||
|
}
|
||||||
78
.github/workflows/gcc16-c++26-reflection.yml
vendored
Normal file
78
.github/workflows/gcc16-c++26-reflection.yml
vendored
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
name: gcc16-c++26-reflection
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ master, development, pull-request/* ]
|
||||||
|
paths:
|
||||||
|
- '.github/workflows/**'
|
||||||
|
- 'include/**'
|
||||||
|
- 'test/**'
|
||||||
|
- 'CMakeLists.txt'
|
||||||
|
- 'cmake/**'
|
||||||
|
- '.devcontainer/**'
|
||||||
|
pull_request:
|
||||||
|
branches: [ master, development, pull-request/* ]
|
||||||
|
types: [opened, synchronize, reopened]
|
||||||
|
paths:
|
||||||
|
- '.github/workflows/**'
|
||||||
|
- 'include/**'
|
||||||
|
- 'test/**'
|
||||||
|
- 'CMakeLists.txt'
|
||||||
|
- 'cmake/**'
|
||||||
|
- '.devcontainer/**'
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
build-gcc16-cpp26-reflection-stl:
|
||||||
|
name: GCC 16 C++26 Reflection - STL
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v6.0.3
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
|
- name: Build Docker image
|
||||||
|
run: docker build -t etl-gcc16 -f .devcontainer/gcc16/Dockerfile .
|
||||||
|
|
||||||
|
- name: Build and run tests
|
||||||
|
run: |
|
||||||
|
docker run --rm --user root -v ${{ github.workspace }}:/etl etl-gcc16 bash -c "\
|
||||||
|
cd /etl && \
|
||||||
|
export CC=gcc-16 && \
|
||||||
|
export CXX=g++-16 && \
|
||||||
|
g++-16 --version && \
|
||||||
|
cmake -G Ninja -B /tmp/build-stl -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 -DETL_OPTIMISATION=-O0 /etl/test && \
|
||||||
|
grep -q 'ETL_GNU_HAS_FREFLECTION:INTERNAL=1' /tmp/build-stl/CMakeCache.txt || (echo 'ERROR: -freflection was not detected - C++26 reflection is not being tested.' && exit 1) && \
|
||||||
|
cmake --build /tmp/build-stl -j \$(getconf _NPROCESSORS_ONLN) && \
|
||||||
|
ctest --test-dir /tmp/build-stl --output-on-failure"
|
||||||
|
|
||||||
|
build-gcc16-cpp26-reflection-no-stl:
|
||||||
|
name: GCC 16 C++26 Reflection - No STL
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v6.0.3
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
|
- name: Build Docker image
|
||||||
|
run: docker build -t etl-gcc16 -f .devcontainer/gcc16/Dockerfile .
|
||||||
|
|
||||||
|
- name: Build and run tests
|
||||||
|
run: |
|
||||||
|
docker run --rm --user root -v ${{ github.workspace }}:/etl etl-gcc16 bash -c "\
|
||||||
|
cd /etl && \
|
||||||
|
export CC=gcc-16 && \
|
||||||
|
export CXX=g++-16 && \
|
||||||
|
g++-16 --version && \
|
||||||
|
cmake -G Ninja -B /tmp/build-no-stl -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 -DETL_OPTIMISATION=-O0 /etl/test && \
|
||||||
|
grep -q 'ETL_GNU_HAS_FREFLECTION:INTERNAL=1' /tmp/build-no-stl/CMakeCache.txt || (echo 'ERROR: -freflection was not detected - C++26 reflection is not being tested.' && exit 1) && \
|
||||||
|
cmake --build /tmp/build-no-stl -j \$(getconf _NPROCESSORS_ONLN) && \
|
||||||
|
ctest --test-dir /tmp/build-no-stl --output-on-failure"
|
||||||
@ -103,6 +103,7 @@ These may be defined in the project settings or the user created `etl_profile.h`
|
|||||||
| `ETL_HAS_IDEQUE_REPAIR` | Set to `1` if the repair functionality for `etl::ideque` is enabled, otherwise `0`.|
|
| `ETL_HAS_IDEQUE_REPAIR` | Set to `1` if the repair functionality for `etl::ideque` is enabled, otherwise `0`.|
|
||||||
| `ETL_IS_DEBUG_BUILD` | Set to `1` if in a debug build, otherwise `0`.|
|
| `ETL_IS_DEBUG_BUILD` | Set to `1` if in a debug build, otherwise `0`.|
|
||||||
| `ETL_HAS_POLYMORPHIC_MESSAGES` | Set to `1` if messages are polymorphic, otherwise `0`.|
|
| `ETL_HAS_POLYMORPHIC_MESSAGES` | Set to `1` if messages are polymorphic, otherwise `0`.|
|
||||||
|
| `ETL_HAS_REFLECTION` | Defined by `etl/meta.h`. Set to `1` if the compiler supports C++26 static reflection (P2996) and `etl::meta` is available, otherwise `0`.|
|
||||||
| `ETL_HAS_ERROR_ON_STRING_TRUNCATION` | Set to `1` if truncated strings are an error, otherwise `0`.|
|
| `ETL_HAS_ERROR_ON_STRING_TRUNCATION` | Set to `1` if truncated strings are an error, otherwise `0`.|
|
||||||
| `ETL_USING_LIBC_WCHAR_H` | These macros will be defined as `0` & `1` depending on whether `ETL_NO_LIBC_WCHAR_H` is defined or not.|
|
| `ETL_USING_LIBC_WCHAR_H` | These macros will be defined as `0` & `1` depending on whether `ETL_NO_LIBC_WCHAR_H` is defined or not.|
|
||||||
| `ETL_NOT_USING_LIBC_WCHAR_H` | Inversion of `ETL_USING_LIBC_WCHAR_H`.|
|
| `ETL_NOT_USING_LIBC_WCHAR_H` | Inversion of `ETL_USING_LIBC_WCHAR_H`.|
|
||||||
|
|||||||
97
docs/types/meta.md
Normal file
97
docs/types/meta.md
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
---
|
||||||
|
title: "meta"
|
||||||
|
---
|
||||||
|
|
||||||
|
{{< callout type="info">}}
|
||||||
|
Header: `meta.h`
|
||||||
|
From: `20.50.0`
|
||||||
|
Similar to: `std::meta`
|
||||||
|
{{< /callout >}}
|
||||||
|
|
||||||
|
C++26 static reflection (P2996) in namespace `etl::meta`.
|
||||||
|
|
||||||
|
`etl::meta` mirrors `std::meta`, but is usable in both STL and non-STL builds.
|
||||||
|
In an STL build it is a thin layer of using-declarations over `std::meta`.
|
||||||
|
In a non-STL build ETL supplies the minimal declarations that the compiler's
|
||||||
|
reflection builtins require, so no standard library is needed.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "etl/meta.h"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Compiler support
|
||||||
|
|
||||||
|
Static reflection is a very new language feature, and at the time of writing
|
||||||
|
**GCC 16** is the only compiler that implements enough of P2996 to be usable.
|
||||||
|
Clang (including the Bloomberg `clang-p2996` fork) and MSVC are not supported.
|
||||||
|
|
||||||
|
`etl/meta.h` may always be included. It defines a single macro,
|
||||||
|
`ETL_HAS_REFLECTION`, as `1` or `0`; when it is `0` the header defines nothing
|
||||||
|
else. This is the only reflection feature switch in the ETL, and user code
|
||||||
|
should test it before using anything in `etl::meta`.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "etl/meta.h"
|
||||||
|
|
||||||
|
#if ETL_HAS_REFLECTION
|
||||||
|
static_assert(etl::meta::identifier_of(^^my_type) == "my_type");
|
||||||
|
#endif
|
||||||
|
```
|
||||||
|
|
||||||
|
GCC requires the `-freflection` option in addition to `-std=c++26`.
|
||||||
|
The reference toolchain is defined in `.devcontainer/gcc16`.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Names are used exactly as their `std::meta` equivalents.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
struct point
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr auto members =
|
||||||
|
etl::meta::nonstatic_data_members_of(^^point,
|
||||||
|
etl::meta::access_context::unchecked());
|
||||||
|
|
||||||
|
static_assert(etl::meta::identifier_of(members[0]) == "x");
|
||||||
|
static_assert(etl::meta::type_of(members[0]) == ^^int);
|
||||||
|
static_assert(etl::meta::size_of(^^point) == 2 * sizeof(int));
|
||||||
|
```
|
||||||
|
|
||||||
|
`identifier_of`, `display_string_of` and `symbol_of` return `std::string_view`
|
||||||
|
in an STL build and `etl::string_view` in a non-STL build.
|
||||||
|
|
||||||
|
## info_array
|
||||||
|
|
||||||
|
GCC cannot keep the heap allocation of a `std::vector<info>` alive across a
|
||||||
|
constant evaluation, so a `template for` over the result of `members_of` does
|
||||||
|
not compile. `etl::meta::info_array` is a fixed-size, allocation-free array of
|
||||||
|
`info` that can be iterated instead.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
constexpr auto ctx = etl::meta::access_context::unchecked();
|
||||||
|
constexpr auto count = etl::meta::nonstatic_data_members_of(^^point, ctx).size();
|
||||||
|
constexpr auto members =
|
||||||
|
etl::meta::to_info_array<count>(etl::meta::nonstatic_data_members_of(^^point, ctx));
|
||||||
|
|
||||||
|
template for (constexpr auto member : members)
|
||||||
|
{
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
| Member | Description |
|
||||||
|
|--------|-------------|
|
||||||
|
| `begin()` | Pointer to the first element. |
|
||||||
|
| `end()` | Pointer past the last element. |
|
||||||
|
| `size()` | The number of elements. |
|
||||||
|
| `operator[](size_t)` | The element at the index. |
|
||||||
|
|
||||||
|
All members are `consteval`.
|
||||||
|
|
||||||
|
## Tests
|
||||||
|
|
||||||
|
`test_meta.cpp`
|
||||||
73
include/etl/meta.h
Normal file
73
include/etl/meta.h
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
///\file
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
The MIT License(MIT)
|
||||||
|
|
||||||
|
Embedded Template Library.
|
||||||
|
https://github.com/ETLCPP/etl
|
||||||
|
https://www.etlcpp.com
|
||||||
|
|
||||||
|
Copyright(c) 2026 BMW AG
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files(the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions :
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef ETL_META_INCLUDED
|
||||||
|
#define ETL_META_INCLUDED
|
||||||
|
|
||||||
|
#include "platform.h"
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
/// \defgroup meta meta
|
||||||
|
/// C++26 static reflection (P2996).
|
||||||
|
/// \ingroup etl
|
||||||
|
//*****************************************************************************
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// This is the one and only place where reflection support is detected.
|
||||||
|
//
|
||||||
|
// GCC 16 is currently the only compiler that implements enough of P2996 for
|
||||||
|
// etl::meta, and it does so for both STL and non-STL builds.
|
||||||
|
// See .devcontainer/gcc16 for the reference toolchain.
|
||||||
|
//
|
||||||
|
// Clang (including the Bloomberg p2996 fork) and MSVC are not supported yet.
|
||||||
|
//
|
||||||
|
// ETL_HAS_REFLECTION is always defined, as 1 or 0.
|
||||||
|
// When it is 0 this header defines nothing else, so user code can include
|
||||||
|
// etl/meta.h unconditionally and test ETL_HAS_REFLECTION.
|
||||||
|
//*****************************************************************************
|
||||||
|
#if defined(ETL_COMPILER_GCC) && defined(__cpp_impl_reflection) && (__cpp_impl_reflection >= 202506L)
|
||||||
|
#define ETL_HAS_REFLECTION 1
|
||||||
|
#else
|
||||||
|
#define ETL_HAS_REFLECTION 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ETL_HAS_REFLECTION
|
||||||
|
#if ETL_USING_STL
|
||||||
|
// The full standard library is available, so etl::meta is a thin
|
||||||
|
// using-declaration layer over std::meta.
|
||||||
|
#include "private/meta/stl.h"
|
||||||
|
#else
|
||||||
|
// No standard library: etl::meta supplies the minimal std declarations
|
||||||
|
// that the reflection builtins require.
|
||||||
|
#include "private/meta/gcc.h"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // ETL_META_INCLUDED
|
||||||
1179
include/etl/private/meta/gcc.h
Normal file
1179
include/etl/private/meta/gcc.h
Normal file
File diff suppressed because it is too large
Load Diff
117
include/etl/private/meta/stl.h
Normal file
117
include/etl/private/meta/stl.h
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
///\file
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
The MIT License(MIT)
|
||||||
|
|
||||||
|
Embedded Template Library.
|
||||||
|
https://github.com/ETLCPP/etl
|
||||||
|
https://www.etlcpp.com
|
||||||
|
|
||||||
|
Copyright(c) 2026 BMW AG
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files(the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions :
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef ETL_PRIVATE_META_STL_H_INCLUDED
|
||||||
|
#define ETL_PRIVATE_META_STL_H_INCLUDED
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <initializer_list>
|
||||||
|
#include <optional>
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <meta>
|
||||||
|
#include <source_location> // Workaround for GCC 16: <meta> depends on <source_location> but does not include it.
|
||||||
|
|
||||||
|
///\defgroup meta meta
|
||||||
|
///\ingroup etl
|
||||||
|
|
||||||
|
namespace etl
|
||||||
|
{
|
||||||
|
namespace meta
|
||||||
|
{
|
||||||
|
//*************************************************************************
|
||||||
|
// Standard <meta> path, used when the full standard library is available.
|
||||||
|
//
|
||||||
|
// A using-directive is sufficient here: qualified lookup for
|
||||||
|
// etl::meta::foo also searches the namespaces nominated by the
|
||||||
|
// using-directives of etl::meta ([namespace.qual]), so every std::meta
|
||||||
|
// name - including the function templates such as extract<> - is
|
||||||
|
// reachable as etl::meta::name. This mirrors the non-STL implementation
|
||||||
|
// in gcc.h, which uses the same mechanism.
|
||||||
|
//*************************************************************************
|
||||||
|
using namespace std::meta;
|
||||||
|
|
||||||
|
// Enumerators of std::meta::operators (op_equals_equals, etc.) are scoped,
|
||||||
|
// so they need a using-enum-declaration rather than the using-directive.
|
||||||
|
using enum std::meta::operators;
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
/// info_array — fixed-size, zero-allocation array of info values.
|
||||||
|
///
|
||||||
|
/// GCC limitation: template-for over a std::vector<info> fails because the
|
||||||
|
/// vector's heap allocation cannot persist in a constant expression. The
|
||||||
|
/// workaround is to copy the elements into a plain aggregate array (no
|
||||||
|
/// allocation) and iterate that instead.
|
||||||
|
///
|
||||||
|
/// Usage pattern:
|
||||||
|
/// constexpr auto N = std::meta::members_of(^^T, ctx).size();
|
||||||
|
/// constexpr auto arr = etl::meta::to_info_array<N>(
|
||||||
|
/// std::meta::members_of(^^T, ctx));
|
||||||
|
/// template for (constexpr auto m : arr) { ... }
|
||||||
|
//*************************************************************************
|
||||||
|
template <size_t N>
|
||||||
|
struct info_array
|
||||||
|
{
|
||||||
|
info elems[N > 0 ? N : 1]{};
|
||||||
|
consteval const info* begin() const
|
||||||
|
{
|
||||||
|
return elems;
|
||||||
|
}
|
||||||
|
consteval const info* end() const
|
||||||
|
{
|
||||||
|
return elems + N;
|
||||||
|
}
|
||||||
|
consteval size_t size() const
|
||||||
|
{
|
||||||
|
return N;
|
||||||
|
}
|
||||||
|
consteval const info& operator[](size_t i) const
|
||||||
|
{
|
||||||
|
return elems[i];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <size_t N>
|
||||||
|
consteval info_array<N> to_info_array(const std::vector<info>& v)
|
||||||
|
{
|
||||||
|
info_array<N> a{};
|
||||||
|
for (size_t i = 0; i < N; ++i)
|
||||||
|
{
|
||||||
|
a.elems[i] = v[i];
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace meta
|
||||||
|
} // namespace etl
|
||||||
|
|
||||||
|
#endif // ETL_PRIVATE_META_STL_H_INCLUDED
|
||||||
@ -3808,9 +3808,14 @@ namespace etl
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
struct is_nothrow_relocatable
|
struct is_nothrow_relocatable
|
||||||
{
|
{
|
||||||
|
#if ETL_USING_CPP11
|
||||||
static ETL_CONSTANT bool value = etl::is_trivially_relocatable<T>::value
|
static ETL_CONSTANT bool value = etl::is_trivially_relocatable<T>::value
|
||||||
|| (etl::is_nothrow_move_constructible<typename etl::remove_all_extents<T>::type>::value
|
|| (etl::is_nothrow_move_constructible<typename etl::remove_all_extents<T>::type>::value
|
||||||
&& etl::is_nothrow_destructible<typename etl::remove_all_extents<T>::type>::value);
|
&& etl::is_nothrow_destructible<typename etl::remove_all_extents<T>::type>::value);
|
||||||
|
#else
|
||||||
|
// No move semantics: only trivially relocatable types are known to be nothrow relocatable.
|
||||||
|
static ETL_CONSTANT bool value = etl::is_trivially_relocatable<T>::value;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#elif defined(ETL_USER_DEFINED_TYPE_TRAITS) && !defined(ETL_USE_TYPE_TRAITS_BUILTINS)
|
#elif defined(ETL_USER_DEFINED_TYPE_TRAITS) && !defined(ETL_USE_TYPE_TRAITS_BUILTINS)
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
cmake_minimum_required(VERSION 3.10)
|
cmake_minimum_required(VERSION 3.10)
|
||||||
project(etl_unit_tests LANGUAGES CXX)
|
project(etl_unit_tests LANGUAGES CXX)
|
||||||
|
|
||||||
|
include(CheckCXXCompilerFlag)
|
||||||
|
|
||||||
#include(FetchContent)
|
#include(FetchContent)
|
||||||
#FetchContent_Declare(
|
#FetchContent_Declare(
|
||||||
# googletest
|
# googletest
|
||||||
@ -232,6 +234,7 @@ add_executable(etl_tests
|
|||||||
test_map.cpp
|
test_map.cpp
|
||||||
test_math.cpp
|
test_math.cpp
|
||||||
test_math_functions.cpp
|
test_math_functions.cpp
|
||||||
|
test_meta.cpp
|
||||||
test_mean.cpp
|
test_mean.cpp
|
||||||
test_memory.cpp
|
test_memory.cpp
|
||||||
test_mem_cast.cpp
|
test_mem_cast.cpp
|
||||||
@ -513,6 +516,16 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
|||||||
${EXTRA_COMPILE_OPTIONS}
|
${EXTRA_COMPILE_OPTIONS}
|
||||||
)
|
)
|
||||||
target_link_options(etl_tests PRIVATE ${EXTRA_LINK_OPTIONS})
|
target_link_options(etl_tests PRIVATE ${EXTRA_LINK_OPTIONS})
|
||||||
|
|
||||||
|
if (ETL_CXX_STANDARD MATCHES "26")
|
||||||
|
# -freflection is only accepted when compiling as C++26, so probe with that standard.
|
||||||
|
set(CMAKE_REQUIRED_FLAGS "-std=c++26")
|
||||||
|
check_cxx_compiler_flag(-freflection ETL_GNU_HAS_FREFLECTION)
|
||||||
|
unset(CMAKE_REQUIRED_FLAGS)
|
||||||
|
if (ETL_GNU_HAS_FREFLECTION)
|
||||||
|
target_compile_options(etl_tests PRIVATE -freflection)
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||||
|
|||||||
@ -234,6 +234,7 @@ etl_test_sources = files(
|
|||||||
'test_message_timer_atomic.cpp',
|
'test_message_timer_atomic.cpp',
|
||||||
'test_message_timer_interrupt.cpp',
|
'test_message_timer_interrupt.cpp',
|
||||||
'test_message_timer_locked.cpp',
|
'test_message_timer_locked.cpp',
|
||||||
|
'test_meta.cpp',
|
||||||
'test_multi_array.cpp',
|
'test_multi_array.cpp',
|
||||||
'test_multi_range.cpp',
|
'test_multi_range.cpp',
|
||||||
'test_multi_span.cpp',
|
'test_multi_span.cpp',
|
||||||
|
|||||||
@ -289,6 +289,7 @@ target_sources(tests PRIVATE
|
|||||||
message_timer_interrupt.h.t.cpp
|
message_timer_interrupt.h.t.cpp
|
||||||
message_timer_locked.h.t.cpp
|
message_timer_locked.h.t.cpp
|
||||||
message_types.h.t.cpp
|
message_types.h.t.cpp
|
||||||
|
meta.h.t.cpp
|
||||||
multimap.h.t.cpp
|
multimap.h.t.cpp
|
||||||
multiset.h.t.cpp
|
multiset.h.t.cpp
|
||||||
multi_array.h.t.cpp
|
multi_array.h.t.cpp
|
||||||
|
|||||||
40
test/syntax_check/meta.h.t.cpp
Normal file
40
test/syntax_check/meta.h.t.cpp
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
The MIT License(MIT)
|
||||||
|
|
||||||
|
Embedded Template Library.
|
||||||
|
https://github.com/ETLCPP/etl
|
||||||
|
https://www.etlcpp.com
|
||||||
|
|
||||||
|
Copyright(c) 2026 BMW AG
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files(the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions :
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#include <etl/meta.h>
|
||||||
|
|
||||||
|
// etl/meta.h must be includable unconditionally, on every compiler and every
|
||||||
|
// language standard. Where reflection is unavailable it defines nothing
|
||||||
|
// except ETL_HAS_REFLECTION, which is always defined as either 1 or 0.
|
||||||
|
#if !defined(ETL_HAS_REFLECTION)
|
||||||
|
#error ETL_HAS_REFLECTION is not defined by etl/meta.h
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (ETL_HAS_REFLECTION != 0) && (ETL_HAS_REFLECTION != 1)
|
||||||
|
#error ETL_HAS_REFLECTION must be defined as 0 or 1
|
||||||
|
#endif
|
||||||
2391
test/test_meta.cpp
Normal file
2391
test/test_meta.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -10447,6 +10447,7 @@
|
|||||||
<ClCompile Include="..\test_message_timer_atomic.cpp" />
|
<ClCompile Include="..\test_message_timer_atomic.cpp" />
|
||||||
<ClCompile Include="..\test_message_timer_interrupt.cpp" />
|
<ClCompile Include="..\test_message_timer_interrupt.cpp" />
|
||||||
<ClCompile Include="..\test_message_timer_locked.cpp" />
|
<ClCompile Include="..\test_message_timer_locked.cpp" />
|
||||||
|
<ClCompile Include="..\test_meta.cpp" />
|
||||||
<ClCompile Include="..\test_multi_array.cpp" />
|
<ClCompile Include="..\test_multi_array.cpp" />
|
||||||
<ClCompile Include="..\test_array.cpp">
|
<ClCompile Include="..\test_array.cpp">
|
||||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../../unittest-cpp</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../../unittest-cpp</AdditionalIncludeDirectories>
|
||||||
|
|||||||
@ -1664,6 +1664,9 @@
|
|||||||
<ClCompile Include="..\test_message_timer_locked.cpp">
|
<ClCompile Include="..\test_message_timer_locked.cpp">
|
||||||
<Filter>Tests\Messaging</Filter>
|
<Filter>Tests\Messaging</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\test_meta.cpp">
|
||||||
|
<Filter>Tests\Types</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="..\test_shared_message.cpp">
|
<ClCompile Include="..\test_shared_message.cpp">
|
||||||
<Filter>Tests\Messaging</Filter>
|
<Filter>Tests\Messaging</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user