2
0
mirror of https://github.com/boostorg/pfr.git synced 2026-01-19 04:22:13 +00:00

Compare commits

...

27 Commits

Author SHA1 Message Date
Antony Polukhin
228922fdb5 Update copyright years 2026-01-04 11:26:11 +03:00
Antony Polukhin
ebcac93bcf Update CI (#227) 2025-12-31 14:48:17 +03:00
dependabot[bot]
79a8290374 Bump actions/checkout from 2 to 6 (#226)
Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-31 14:19:43 +03:00
Antony Polukhin
1b0506f44f Add dependabot 2025-12-24 20:19:28 +03:00
Alexander Grund
7aa41ed4f5 CMake: Condition core_name tests on CMake version (#224)
As those tests require C++20 only compile them with CMake 3.12+ to be able to use `cxx_std_20`
2025-10-28 19:40:55 +03:00
Alexander Grund
7509049f2c Fix compatibility with CMake < 3.14 (#223)
`NAME_WLE` was introduced in 3.14
2025-10-06 19:38:26 +03:00
Antony Polukhin
4f9e6457b0 Add multiple tests from different bug reports and make sure that ever… (#222)
…ything works with new unsafe_declval and with sturctured binding pack

Fixes: https://github.com/boostorg/pfr/issues/208,  https://github.com/boostorg/pfr/issues/110, https://github.com/boostorg/pfr/issues/126
Closes: https://github.com/boostorg/pfr/pull/212
Relates: https://github.com/boostorg/pfr/issues/173
2025-09-14 14:59:25 +03:00
Antony Polukhin
fc2dba87d6 Multiple fixes for the structured bindings pack implementation (#221) 2025-09-11 21:51:07 +03:00
Antony Polukhin
d9fde1f2a0 core: add an implementation based on C++26 destructuring into a pack (#220)
Tested with clang-21

---------

Co-authored-by: Jean-Michaël Celerier <jeanmichael.celerier@gmail.com>
2025-09-07 20:26:44 +03:00
Antony Polukhin
5034bf55fb Provide and use an alternative implementation of unsafe_declval (#216)
References https://github.com/boostorg/pfr/issues/208
2025-06-27 20:46:59 +03:00
Antony Polukhin
8cbffcb7ab Harden the CI checks for CMake and fix some issues (#215)
Fixes: https://github.com/boostorg/pfr/issues/214
2025-06-27 20:23:23 +03:00
Antony Polukhin
dcf2deb959 Fix for 'Arrays of Length Zero' compiler extension (#213) 2025-06-20 15:56:51 +03:00
Antony Polukhin
2e3663d0df Fix CI tests and docs build (#211)
Fixes https://github.com/boostorg/pfr/issues/203
2025-06-19 18:36:45 +03:00
Antony Polukhin
7259e35f71 Minor fixes for the misc/strip_boost_namespace.sh 2025-06-19 17:23:29 +03:00
Antony Polukhin
f223709e42 Prepare for the 2.3 release of pfr_non_boost version 2025-06-19 17:09:37 +03:00
Antony Polukhin
f61b90ec59 Update regression test links in Readme 2025-06-18 17:51:35 +03:00
Antony Polukhin
820f56c316 Fix typos (#210)
Thanks to https://github.com/TryKuhn for highlighting the issues
2025-06-17 10:39:53 +03:00
Antony Polukhin
9bc3cb2af7 Another fix attempt for the CMake build from the root directory of Boost (#209)
Fixes https://github.com/boostorg/pfr/issues/206
2025-06-17 09:51:17 +03:00
Antony Polukhin
57fa1018b0 Update OSes in CI and run CMake tests (#207)
Fixes https://github.com/boostorg/pfr/issues/205
2025-06-11 21:40:44 +03:00
Antony Polukhin
db9451143a Fix build on standards before C++20 2025-05-12 19:53:03 +03:00
Antony Polukhin
8417d4fd2d Fix test after Boost.TypeIndex modularization 2025-05-12 19:53:03 +03:00
Antony Polukhin
f004e91c9b Return std::array<std::string_view, 0> type for boost::pfr::names_as_array(empty_struct{}) (fixes #195) 2025-05-12 19:53:03 +03:00
Antony Polukhin
b95fd86595 Fix CMake tests build fail (fixes #198) (#201) 2025-05-12 17:28:20 +03:00
Antony Polukhin
3e5c474337 Minor fixes for modules (#200) 2025-04-29 22:04:16 +03:00
Peter Dimov
c902451cc0 Merge pull request #199 from sdarwin/docs
Docs: fix import path
2025-04-23 19:01:15 +03:00
sdarwin
1756327d0a Docs: fix import path 2025-04-18 07:03:07 -06:00
Antony Polukhin
5a48d7456f Rewrite modules following the new recommended Boost practice (#196)
Changes:

1) `#include <boost/pfr...` is now implicitly does `import boost.pfr` if the modules are supported 
2) CI now tests modules on Ubuntu 24.04 with existing runtime tests
3) Renamed module to `boost.pfr`
4) CMakeLists.txt now uses modules for `Boost::pfr` target if modules are supported
5) All the library internals now have unconditional module level linkage. `1)` allows users to mix `#include <boost/pfr...` and `import boost.pfr` in user code without ODR-violations.

Significant differences from https://anarthal.github.io/cppblog/modules3:
* PFR uses a `BOOST_PFR_USE_STD_MODULE` macro for `import std;` / `includes` while building module. This allows to use `boost.pfr` module in C++20 and even without usable  `std` module.
2025-04-16 09:16:09 +03:00
126 changed files with 1031 additions and 442 deletions

11
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,11 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
- package-ecosystem: "github-actions" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "weekly"

View File

@@ -17,10 +17,10 @@ jobs:
fail-fast: false
matrix:
include:
- toolset: gcc-14
- toolset: gcc-14 # Do not remove! It is the only toolset that tests CMake tests down below
cxxstd: "03,11,14,17,20"
os: ubuntu-24.04
- toolset: gcc-12 # Do not remove! It is the only toolset that tests misc/strip_boost_namespace.sh
- toolset: gcc-12
cxxstd: "03,11,14,17,2a"
os: ubuntu-22.04
cxxflags: "cxxflags=--coverage -fsanitize=address,leak,undefined -fno-sanitize-recover=undefined"
@@ -38,25 +38,21 @@ jobs:
cxxflags: "cxxflags=--coverage -fsanitize=address,leak,undefined -fno-sanitize-recover=undefined"
linkflags: "linkflags=--coverage -lasan -lubsan"
gcov_tool: "gcov-10"
- toolset: gcc-9
cxxstd: "03,11,14,17,2a"
os: ubuntu-22.04
cxxflags: "cxxflags=--coverage -fsanitize=address,leak,undefined -fno-sanitize-recover=undefined"
linkflags: "linkflags=--coverage -lasan -lubsan"
gcov_tool: "gcov-9"
- toolset: clang-15
cxxstd: "03,11,14,17,20"
os: ubuntu-22.04
# - toolset: clang
# cxxstd: "03,11,14,17,2a"
# os: macos-10.15
# cxxflags: "cxxflags=-fsanitize=address,undefined -fno-sanitize-recover=undefined"
# linkflags: "linkflags=-fsanitize=address,undefined"
- toolset: clang-18
cxxstd: "03,11,14,17,20,23"
os: ubuntu-24.04
- toolset: clang-19 # tests misc/strip_boost_namespace.sh and modules
cxxstd: "20,23"
os: ubuntu-24.04
install: clang-19 llvm-19 libclang-rt-19-dev libc++-19-dev libc++abi-19-dev clang-tools-19
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v6
- name: Install packages
if: matrix.install
@@ -84,17 +80,54 @@ jobs:
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
python tools/boostdep/depinst/depinst.py --include benchmark --include example --include examples --include tools --git_args "--depth 10 --jobs 3" $LIBRARY
./bootstrap.sh
./b2 -d0 headers
./b2 variant=debug tools/inspect/build
./b2 variant=debug tools/inspect
- name: Run CMake tests
if: ${{matrix.toolset == 'gcc-14'}}
run: |
cd ../boost-root/
mkdir __build
cd __build
cmake -DBUILD_TESTING=1 -DBOOST_INCLUDE_LIBRARIES=pfr -DCMAKE_CXX_COMPILER=g++-14 -DCMAKE_C_COMPILER=gcc-14 ..
cmake --build . --target tests
ctest --output-on-failure --no-tests=error
cd ..
rm -rf __build
- name: Run modules tests
if: false
# if: ${{matrix.toolset == 'clang-19'}}
run: |
cd ../boost-root/libs/pfr
mkdir build_module
cd build_module
cmake -DBUILD_TESTING=1 -DBOOST_USE_MODULES=1 -DCMAKE_CXX_COMPILER=clang++-19 -DCMAKE_CXX_FLAGS=-stdlib=libc++ -DCMAKE_EXE_LINKER_FLAGS=-stdlib=libc++ -DCMAKE_CXX_STANDARD=23 -DCMAKE_EXPERIMENTAL_CXX_IMPORT_STD=0e5b6991-d74f-4b3d-a41c-cf096e0b2508 -G Ninja ../test/cmake_subdir_test
cmake --build .
ctest -V
cd ..
rm -rf build_module
- name: Run modules tests wihtout 'import std;'
if: ${{matrix.toolset == 'clang-19'}}
run: |
cd ../boost-root/libs/pfr
mkdir build_module
cd build_module
cmake -DBOOST_USE_MODULES=1 -DBUILD_TESTING=1 -GNinja -DCMAKE_CXX_COMPILER=clang++-19 ../test/cmake_subdir_test
cmake --build .
ctest -V
cd ..
rm -rf build_module
- name: Run tests
run: |
cd ../boost-root
./b2 -d0 headers
./b2 libs/$LIBRARY/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} variant=debug,release "${{matrix.cxxflags}}" "${{matrix.linkflags}}" "${{matrix.launcher}}"
dist/bin/inspect libs/$LIBRARY
- name: Test boost namespace stripping
if: ${{matrix.toolset == 'gcc-12'}}
if: ${{matrix.toolset == 'clang-19'}}
run: ../boost-root/libs/$LIBRARY/misc/strip_boost_namespace.sh
- name: Prepare coverage data
@@ -130,30 +163,31 @@ jobs:
fail-fast: false
matrix:
include:
- toolset: msvc-14.0
cxxstd: "14,latest"
addrmd: 32,64
os: windows-2019
- toolset: msvc-14.3 # tests CMake tests down below, does not run b2 tests
cxxstd: "14,17,20,latest"
addrmd: 64
os: windows-2025
threads: "-j3"
- toolset: gcc
cxxstd: "03,11,14,17,2a"
addrmd: 64
os: windows-2019
os: windows-2025
threads: "-j3"
- toolset: msvc-14.3
- toolset: msvc-14.3 # tests CMake tests down below
cxxstd: "20,latest"
addrmd: 64
os: windows-2022
threads: "-j1"
- toolset: clang-win
cxxstd: "14,17,2a,latest"
addrmd: 32,64
os: windows-2022
# Fails with "Unexpected compiler version, expected Clang 19.0.0 or newer."
# - toolset: clang-win
# cxxstd: "14,17,2a,latest"
# addrmd: 32,64
# os: windows-2022
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v6
- name: Setup Boost
shell: cmd
@@ -175,12 +209,58 @@ jobs:
git submodule update --init --depth 10 --jobs 2 tools/boostdep
python tools/boostdep/depinst/depinst.py --include benchmark --include example --include examples --include tools --git_args "--jobs 3" %LIBRARY%
cmd /c bootstrap
b2 -d0 headers
- name: Run CMake tests
if: ${{matrix.toolset == 'msvc-14.3'}}
shell: cmd
run: |
choco install --no-progress ninja
call "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvarsall.bat" x64
cd ../boost-root/
mkdir __build
cd __build
cmake -DBUILD_TESTING=1 -DBOOST_INCLUDE_LIBRARIES=pfr ..
cmake --build . --target tests --config Debug
ctest --output-on-failure --no-tests=error -C Debug
cd ..
rm -rf __build
- name: Run modules tests
if: false
# if: ${{matrix.toolset == 'msvc-14.3'}}
shell: cmd
run: |
choco install --no-progress ninja
call "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvarsall.bat" x64
cd ../boost-root/libs/pfr
mkdir build_module
cd build_module
cmake -DBOOST_USE_MODULES=1 -DBUILD_TESTING=1 -DCMAKE_CXX_STANDARD=23 -DCMAKE_EXPERIMENTAL_CXX_IMPORT_STD=0e5b6991-d74f-4b3d-a41c-cf096e0b2508 -G Ninja ../test/cmake_subdir_test
cmake --build .
ctest --no-tests=error -V
cd ..
rm -rf build_module
- name: Run modules tests wihtout 'import std;'
if: ${{matrix.toolset == 'msvc-14.3'}}
shell: cmd
run: |
choco install --no-progress ninja
call "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvarsall.bat" x64
cd ../boost-root/libs/pfr
mkdir build_module
cd build_module
cmake -DBOOST_USE_MODULES=1 -DBUILD_TESTING=1 -DCMAKE_CXX_STANDARD=20 -G Ninja ../test/cmake_subdir_test
cmake --build .
ctest --no-tests=error -V
cd ..
rm -rf build_module
- name: Run tests
shell: cmd
run: |
cd ../boost-root
b2 -d0 headers
b2 ${{matrix.threads}} libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release
finish:

View File

@@ -1,23 +1,48 @@
# Copyright 2020 Peter Dimov
# Copyright (c) 2016-2025 Antony Polukhin
# Copyright (c) 2016-2026 Antony Polukhin
#
# Distributed under the Boost Software License, Version 1.0.
# https://www.boost.org/LICENSE_1_0.txt
cmake_minimum_required(VERSION 3.5...3.16)
cmake_minimum_required(VERSION 3.5...3.31)
project(boost_pfr VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
add_library(boost_pfr INTERFACE)
if (BOOST_USE_MODULES)
add_library(boost_pfr)
target_sources(boost_pfr PUBLIC
FILE_SET modules_public TYPE CXX_MODULES FILES modules/boost_pfr.cppm
)
target_compile_features(boost_pfr PUBLIC cxx_std_20)
target_compile_definitions(boost_pfr PUBLIC BOOST_USE_MODULES)
if (CMAKE_CXX_COMPILER_IMPORT_STD)
target_compile_definitions(boost_pfr PRIVATE BOOST_PFR_USE_STD_MODULE)
message(STATUS "Using `import std;`")
else()
message(STATUS "`import std;` is not available")
endif()
target_include_directories(boost_pfr PUBLIC include)
else()
add_library(boost_pfr INTERFACE)
target_include_directories(boost_pfr INTERFACE include)
endif()
add_library(Boost::pfr ALIAS boost_pfr)
target_include_directories(boost_pfr INTERFACE include)
if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.28.0" AND BUILD_MODULE)
add_subdirectory(module)
endif()
enable_testing()
if (BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt")
add_subdirectory(test)
add_subdirectory(test)
endif()
if (BOOST_USE_MODULES AND BUILD_TESTING)
add_executable(boost_pfr_module_usage modules/usage_sample.cpp)
target_link_libraries(boost_pfr_module_usage PRIVATE Boost::pfr)
add_test(NAME boost_pfr_module_usage COMMAND boost_pfr_module_usage)
# Make sure that mixing includes and imports is fine for different TU
add_executable(boost_pfr_module_usage_mu modules/usage_test_mu1.cpp modules/usage_test_mu2.cpp)
target_link_libraries(boost_pfr_module_usage_mu PRIVATE Boost::pfr)
add_test(NAME boost_pfr_module_usage_mu COMMAND boost_pfr_module_usage_mu)
endif()

View File

@@ -10,8 +10,8 @@ For a version of the library without `boost::` namespace see [PFR](https://githu
Branches | Build | Tests coverage | More info
----------------|-------------- | -------------- |-----------
Develop: | [![CI](https://github.com/boostorg/pfr/actions/workflows/ci.yml/badge.svg?branch=develop)](https://github.com/boostorg/pfr/actions/workflows/ci.yml) [![Build status](https://ci.appveyor.com/api/projects/status/0mavmnkdmltcdmqa/branch/develop?svg=true)](https://ci.appveyor.com/project/apolukhin/pfr/branch/develop) | [![Coverage Status](https://coveralls.io/repos/github/apolukhin/magic_get/badge.png?branch=develop)](https://coveralls.io/github/apolukhin/magic_get?branch=develop) | [details...](https://www.boost.org/development/tests/develop/developer/pfr.html)
Master: | [![CI](https://github.com/boostorg/pfr/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/boostorg/pfr/actions/workflows/ci.yml) [![Build status](https://ci.appveyor.com/api/projects/status/0mavmnkdmltcdmqa/branch/master?svg=true)](https://ci.appveyor.com/project/apolukhin/pfr/branch/master) | [![Coverage Status](https://coveralls.io/repos/github/apolukhin/magic_get/badge.png?branch=master)](https://coveralls.io/github/apolukhin/magic_get?branch=master) | [details...](https://www.boost.org/development/tests/master/developer/pfr.html)
Develop: | [![CI](https://github.com/boostorg/pfr/actions/workflows/ci.yml/badge.svg?branch=develop)](https://github.com/boostorg/pfr/actions/workflows/ci.yml) [![Build status](https://ci.appveyor.com/api/projects/status/0mavmnkdmltcdmqa/branch/develop?svg=true)](https://ci.appveyor.com/project/apolukhin/pfr/branch/develop) | [![Coverage Status](https://coveralls.io/repos/github/apolukhin/magic_get/badge.png?branch=develop)](https://coveralls.io/github/apolukhin/magic_get?branch=develop) | [details...](https://regression.boost.io/develop/developer/pfr.html)
Master: | [![CI](https://github.com/boostorg/pfr/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/boostorg/pfr/actions/workflows/ci.yml) [![Build status](https://ci.appveyor.com/api/projects/status/0mavmnkdmltcdmqa/branch/master?svg=true)](https://ci.appveyor.com/project/apolukhin/pfr/branch/master) | [![Coverage Status](https://coveralls.io/repos/github/apolukhin/magic_get/badge.png?branch=master)](https://coveralls.io/github/apolukhin/magic_get?branch=master) | [details...](https://regression.boost.io/master/developer/pfr.html)
[Latest developer documentation](https://www.boost.org/doc/libs/develop/doc/html/boost_pfr.html)

View File

@@ -55,9 +55,8 @@ boostbook pfr-doc
pfr.qbk
:
<dependency>autodoc_pfr
<xsl:param>boost.root=https://www.boost.org/doc/libs/1_81_0
#<xsl:param>boost.root=../../../.
<xml:param>html.stylesheet=../../../../doc/src/boostbook.css
#<xsl:param>boost.root=https://www.boost.org/doc/libs/1_88_0
<xsl:param>boost.root=../../../..
;
###############################################################################

View File

@@ -1,7 +1,7 @@
[library Boost.PFR
[quickbook 1.6]
[version 2.2]
[copyright 2016-2025 Antony Polukhin]
[version 2.3]
[copyright 2016-2026 Antony Polukhin]
[category Language Features Emulation]
[license
Distributed under the Boost Software License, Version 1.0.
@@ -501,6 +501,7 @@ Boost.PFRs extraction of field name works with only `SimpleAggregate` types.
By default Boost.PFR [*auto-detects your compiler abilities] and automatically defines the configuration macro into appropriate values. If you wish to override that behavior, just define:
[table:linkmacro Macros
[[Macro name] [Effect]]
[[*BOOST_PFR_USE_CPP26*] [Define to `1` if you wish to override Boost.PFR choice and use C++26 variadic structured bindings for reflection. Define to `0` to override Boost.PFR choice and disable C++26 variadic structured bindings usage.]]
[[*BOOST_PFR_USE_CPP17*] [Define to `1` if you wish to override Boost.PFR choice and use C++17 structured bindings for reflection. Define to `0` to override Boost.PFR choice and disable C++17 structured bindings usage.]]
[[*BOOST_PFR_USE_LOOPHOLE*] [Define to `1` if you wish to override Boost.PFR choice and exploit [@http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2118 CWG 2118] for reflection. Define to `0` to override Boost.PFR choice and disable CWG 2118 usage.]]
[[*BOOST_PFR_USE_STD_MAKE_INTEGRAL_SEQUENCE*] [Define to `0` if you are hit by the template instantiation depth issues with `std::make_integer_sequence` and wish to use Boost.PFR version of that metafunction. Define to `1` to override Boost.PFR detection logic. ]]
@@ -554,34 +555,34 @@ parameters provided to `BOOST_PFR_CORE_NAME_PARSING` macro [*and] the initial ou
[section PFR as a C++20 module]
[caution C++20 PFR module support is on early stage, targets and flags may change in the future]
[caution C++20 PFR module support is on early stage, targets, flags and behavior may change in the future]
If using CMake of version 3.28.0 or higher define CMake option `-DBUILD_MODULE=1`
to make the `Boost::pfr_module` and `Boost::pfr_module_migration` libraries
available. With `Boost::pfr_module` C++20 module Boost.PFR could be used:
If using modern CMake define CMake option `-DBOOST_USE_MODULES=1` to build a C++20 module and
make the `Boost::pfr` CMake target provide it. After that an explicit usage of C++20 module `boost.pfr` is allowed:
[import ../module/usage_sample.cpp]
[import ../modules/usage_sample.cpp]
[pfr_module_example]
The `Boost::pfr_module_migration` CMake target gives an ability to
mix includes and imports of the PFR library in different translation units.
The `Boost::pfr` CMake target gives an ability to mix includes and imports of the PFR library in different translation units. Moreover,
if `BOOST_USE_MODULES` macro is defined then all the `boost/pfr/...` includes implicitly do `import boost.pfr;` to give all the
benifits of modules without changing the existing code.
If not using CMake, then the module could be build manually from the
`module/pfr.cppm` file. If mixing of includes in imports is desired, additionally
define `BOOST_PFR_ATTACH_TO_GLOBAL_MODULE` preprocessor macro to attach all the
module entities to a global module and avoid ODR issues.
[note For better compile times make sure that `import std;` is available when building the `boost.pfr` module (in CMake logs there should be
a 'Using `import std;`' message). ]
For manual module build the following commands could be used for clang compiler:
If not using CMake, then the module could be build manually from the `modules/boost_pfr.cppm` file.
For manual module build the following commands can be used for clang compiler:
```
cd pfr/module
clang++ -I ../include -std=c++20 --precompile -x c++-module pfr.cppm
clang++ -I ../include -std=c++20 --precompile -x c++-module boost_pfr.cppm
```
After that, the module could be used in the following way:
```
clang++ -std=c++20 -fmodule-file=pfr.pcm pfr.pcm usage_sample.cpp
clang++ -std=c++20 -fmodule-file=boost_pfr.pcm boost_pfr.pcm usage_sample.cpp
```
[endsect]
@@ -593,16 +594,18 @@ clang++ -std=c++20 -fmodule-file=pfr.pcm pfr.pcm usage_sample.cpp
Short description:
# at compile-time: use aggregate initialization to detect fields count in user-provided structure
* [*BOOST_PFR_USE_CPP17 == 1]:
* [*BOOST_PFR_USE_CPP26 == 1]:
# at compile-time: structured bindings are used to decompose a type `T` to known variadic amount of fields
* [*BOOST_PFR_USE_CPP26 == 0 && BOOST_PFR_USE_CPP17 == 1]:
# at compile-time: structured bindings are used to decompose a type `T` to known amount of fields
* [*BOOST_PFR_USE_CPP17 == 0 && BOOST_PFR_USE_LOOPHOLE == 1]:
* [*BOOST_PFR_USE_CPP26 == 0 && BOOST_PFR_USE_CPP17 == 0 && BOOST_PFR_USE_LOOPHOLE == 1]:
# at compile-time: use aggregate initialization to detect fields count in user-provided structure
# at compile-time: make a structure that is convertible to anything and remember types it has been converted to during aggregate initialization of user-provided structure
# at compile-time: using knowledge from previous steps create a tuple with exactly the same layout as in user-provided structure
# at compile-time: find offsets for each field in user-provided structure using the tuple from previous step
# at run-time: get pointer to each field, knowing the structure address and each field offset
# at run-time: a tuple of references to fields is returned => all the tuple methods are available for the structure
* [*BOOST_PFR_USE_CPP17 == 0 && BOOST_PFR_USE_LOOPHOLE == 0]:
* [*BOOST_PFR_USE_CPP26 == 0 && BOOST_PFR_USE_CPP17 == 0 && BOOST_PFR_USE_LOOPHOLE == 0]:
# at compile-time: let `I` be is an index of current field, it equals 0
# at run-time: `T` is constructed and field `I` is aggregate initialized using a separate instance of structure that is convertible to anything [note Additional care is taken to make sure that all the information about `T` is available to the compiler and that operations on `T` have no side effects, so the compiler can optimize away the unnecessary temporary objects.]
# at compile-time: `I += 1`

View File

@@ -1,4 +1,4 @@
// Copyright 2016-2025 Antony Polukhin
// Copyright 2016-2026 Antony Polukhin
// Distributed under the Boost Software License, Version 1.0.
// (See the accompanying file LICENSE_1_0.txt

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -1,4 +1,4 @@
// Copyright 2016-2025 Antony Polukhin
// Copyright 2016-2026 Antony Polukhin
// Distributed under the Boost Software License, Version 1.0.
// (See the accompanying file LICENSE_1_0.txt

View File

@@ -1,4 +1,4 @@
// Copyright 2016-2025 Antony Polukhin
// Copyright 2016-2026 Antony Polukhin
// Distributed under the Boost Software License, Version 1.0.
// (See the accompanying file LICENSE_1_0.txt

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
// Copyright (c) 2022 Denis Mikhailov
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -8,10 +8,14 @@
#define BOOST_PFR_CONFIG_HPP
#pragma once
#if __cplusplus >= 201402L || (defined(_MSC_VER) && defined(_MSVC_LANG) && _MSC_VER > 1900)
#if !defined(BOOST_USE_MODULES) && (__cplusplus >= 201402L || (defined(_MSC_VER) && defined(_MSVC_LANG) && _MSC_VER > 1900))
#include <type_traits> // to get non standard platform macro definitions (__GLIBCXX__ for example)
#endif
#if defined(BOOST_USE_MODULES) || __cplusplus >= 202002L
#include <version>
#endif
/// \file boost/pfr/config.hpp
/// Contains all the macros that describe Boost.PFR configuration, like BOOST_PFR_ENABLED
///
@@ -49,6 +53,14 @@
# endif
#endif
#ifndef BOOST_PFR_USE_CPP26
#if __cpp_structured_bindings >= 202411L && __cpp_lib_forward_like >= 202207L
#define BOOST_PFR_USE_CPP26 1
#else
#define BOOST_PFR_USE_CPP26 0
#endif
#endif
#ifndef BOOST_PFR_USE_CPP17
# ifdef __cpp_structured_bindings
# define BOOST_PFR_USE_CPP17 1
@@ -63,15 +75,17 @@
# endif
#endif
#if (!BOOST_PFR_USE_CPP17 && !BOOST_PFR_USE_LOOPHOLE)
#if (!BOOST_PFR_USE_CPP26 && !BOOST_PFR_USE_CPP17 && !BOOST_PFR_USE_LOOPHOLE)
# if (defined(_MSC_VER) && _MSC_VER < 1916) ///< in Visual Studio 2017 v15.9 PFR library with classic engine normally works
# define BOOST_PFR_NOT_SUPPORTED 1
# endif
#endif
#ifndef BOOST_PFR_USE_STD_MAKE_INTEGRAL_SEQUENCE
# if defined(BOOST_USE_MODULES)
# define BOOST_PFR_USE_STD_MAKE_INTEGRAL_SEQUENCE 1
// Assume that libstdc++ since GCC-7.3 does not have linear instantiation depth in std::make_integral_sequence
# if defined( __GLIBCXX__) && __GLIBCXX__ >= 20180101
# elif defined( __GLIBCXX__) && __GLIBCXX__ >= 20180101
# define BOOST_PFR_USE_STD_MAKE_INTEGRAL_SEQUENCE 1
# elif defined(_MSC_VER)
# define BOOST_PFR_USE_STD_MAKE_INTEGRAL_SEQUENCE 1
@@ -145,12 +159,16 @@
#undef BOOST_PFR_NOT_SUPPORTED
#ifndef BOOST_PFR_BEGIN_MODULE_EXPORT
#ifdef BOOST_PFR_INTERFACE_UNIT
# define BOOST_PFR_BEGIN_MODULE_EXPORT export {
# define BOOST_PFR_END_MODULE_EXPORT }
#else
# define BOOST_PFR_BEGIN_MODULE_EXPORT
#endif
#ifndef BOOST_PFR_END_MODULE_EXPORT
# define BOOST_PFR_END_MODULE_EXPORT
#endif
#if defined(BOOST_USE_MODULES) && !defined(BOOST_PFR_INTERFACE_UNIT)
import boost.pfr;
#endif
#endif // BOOST_PFR_CONFIG_HPP

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -9,6 +9,8 @@
#include <boost/pfr/detail/config.hpp>
#if !defined(BOOST_USE_MODULES) || defined(BOOST_PFR_INTERFACE_UNIT)
#include <boost/pfr/detail/core.hpp>
#include <boost/pfr/detail/sequence_tuple.hpp>
@@ -17,10 +19,12 @@
#include <boost/pfr/detail/make_integer_sequence.hpp>
#include <boost/pfr/detail/tie_from_structure_tuple.hpp>
#include <boost/pfr/tuple_size.hpp>
#if !defined(BOOST_PFR_INTERFACE_UNIT)
#include <type_traits>
#include <utility> // metaprogramming stuff
#include <boost/pfr/tuple_size.hpp>
#endif
/// \file boost/pfr/core.hpp
/// Contains all the basic tuple-like interfaces \forcedlink{get}, \forcedlink{tuple_size}, \forcedlink{tuple_element_t}, and others.
@@ -48,24 +52,34 @@ BOOST_PFR_BEGIN_MODULE_EXPORT
/// \endcode
template <std::size_t I, class T>
constexpr decltype(auto) get(const T& val) noexcept {
return detail::sequence_tuple::get<I>( detail::tie_as_tuple(val) );
#if BOOST_PFR_USE_CPP26
const auto& [... members] = val;
return std::forward_like<const T &>(members...[I]);
#else
return detail::sequence_tuple::get<I>(detail::tie_as_tuple(val));
#endif
}
/// \overload get
template <std::size_t I, class T>
constexpr decltype(auto) get(T& val
#if !BOOST_PFR_USE_CPP17
#if !BOOST_PFR_USE_CPP17 && !BOOST_PFR_USE_CPP26
, std::enable_if_t<std::is_assignable<T, T>::value>* = nullptr
#endif
) noexcept {
#if BOOST_PFR_USE_CPP26
auto& [... members] = val;
return std::forward_like<T &>(members...[I]);
#else
return detail::sequence_tuple::get<I>( detail::tie_as_tuple(val) );
#endif
}
#if !BOOST_PFR_USE_CPP17
#if !BOOST_PFR_USE_CPP17 && !BOOST_PFR_USE_CPP26
/// \overload get
template <std::size_t I, class T>
constexpr auto get(T&, std::enable_if_t<!std::is_assignable<T, T>::value>* = nullptr) noexcept {
static_assert(sizeof(T) && false, "====================> Boost.PFR: Calling boost::pfr::get on non const non assignable type is allowed only in C++17");
static_assert(sizeof(T) && false, "====================> Boost.PFR: Calling boost::pfr::get on non const non assignable type is allowed only in C++17 and later");
return 0;
}
#endif
@@ -74,7 +88,12 @@ constexpr auto get(T&, std::enable_if_t<!std::is_assignable<T, T>::value>* = nul
/// \overload get
template <std::size_t I, class T>
constexpr auto get(T&& val, std::enable_if_t< std::is_rvalue_reference<T&&>::value>* = nullptr) noexcept {
#if BOOST_PFR_USE_CPP26
auto&& [... members] = std::forward<T>(val);
return std::move(members...[I]);
#else
return std::move(detail::sequence_tuple::get<I>( detail::tie_as_tuple(val) ));
#endif
}
@@ -88,18 +107,18 @@ constexpr const U& get(const T& val) noexcept {
/// \overload get
template <class U, class T>
constexpr U& get(T& val
#if !BOOST_PFR_USE_CPP17
#if !BOOST_PFR_USE_CPP17 && !BOOST_PFR_USE_CPP26
, std::enable_if_t<std::is_assignable<T, T>::value>* = nullptr
#endif
) noexcept {
return detail::sequence_tuple::get_by_type_impl<U&>( detail::tie_as_tuple(val) );
}
#if !BOOST_PFR_USE_CPP17
#if !BOOST_PFR_USE_CPP17 && !BOOST_PFR_USE_CPP26
/// \overload get
template <class U, class T>
constexpr U& get(T&, std::enable_if_t<!std::is_assignable<T, T>::value>* = nullptr) noexcept {
static_assert(sizeof(T) && false, "====================> Boost.PFR: Calling boost::pfr::get on non const non assignable type is allowed only in C++17");
static_assert(sizeof(T) && false, "====================> Boost.PFR: Calling boost::pfr::get on non const non assignable type is allowed only in C++17 and later");
return 0;
}
#endif
@@ -143,10 +162,15 @@ using tuple_element_t = typename tuple_element<I, T>::type;
/// \endcode
template <class T>
constexpr auto structure_to_tuple(const T& val) {
#if BOOST_PFR_USE_CPP26
const auto& [... members] = val;
return std::make_tuple(members...);
#else
return detail::make_stdtuple_from_tietuple(
detail::tie_as_tuple(val),
detail::make_index_sequence< tuple_size_v<T> >()
);
#endif
}
@@ -168,31 +192,39 @@ constexpr auto structure_to_tuple(const T& val) {
/// \endcode
template <class T>
constexpr auto structure_tie(const T& val) noexcept {
#if BOOST_PFR_USE_CPP26
const auto& [... members] = val;
return std::tie(std::forward_like<const T &>(members)...);
#else
return detail::make_conststdtiedtuple_from_tietuple(
detail::tie_as_tuple(const_cast<T&>(val)),
detail::make_index_sequence< tuple_size_v<T> >()
);
#endif
}
/// \overload structure_tie
template <class T>
constexpr auto structure_tie(T& val
#if !BOOST_PFR_USE_CPP17
#if !BOOST_PFR_USE_CPP17 && !BOOST_PFR_USE_CPP26
, std::enable_if_t<std::is_assignable<T, T>::value>* = nullptr
#endif
) noexcept {
return detail::make_stdtiedtuple_from_tietuple(
detail::tie_as_tuple(val),
detail::make_index_sequence< tuple_size_v<T> >()
);
#if BOOST_PFR_USE_CPP26
auto& [... members] = val;
return std::tie(std::forward_like<T &>(members)...);
#else
return detail::make_stdtiedtuple_from_tietuple(detail::tie_as_tuple(val),
detail::make_index_sequence<tuple_size_v<T> >());
#endif
}
#if !BOOST_PFR_USE_CPP17
#if !BOOST_PFR_USE_CPP17 && !BOOST_PFR_USE_CPP26
/// \overload structure_tie
template <class T>
constexpr auto structure_tie(T&, std::enable_if_t<!std::is_assignable<T, T>::value>* = nullptr) noexcept {
static_assert(sizeof(T) && false, "====================> Boost.PFR: Calling boost::pfr::structure_tie on non const non assignable type is allowed only in C++17");
static_assert(sizeof(T) && false, "====================> Boost.PFR: Calling boost::pfr::structure_tie on non const non assignable type is allowed only in C++17 and later modes");
return 0;
}
#endif
@@ -249,4 +281,6 @@ BOOST_PFR_END_MODULE_EXPORT
}} // namespace boost::pfr
#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_PFR_INTERFACE_UNIT)
#endif // BOOST_PFR_CORE_HPP

View File

@@ -14,16 +14,20 @@
#include <boost/pfr/detail/config.hpp>
#if !defined(BOOST_USE_MODULES) || defined(BOOST_PFR_INTERFACE_UNIT)
#include <boost/pfr/detail/core_name.hpp>
#include <boost/pfr/detail/sequence_tuple.hpp>
#include <boost/pfr/detail/stdarray.hpp>
#include <boost/pfr/detail/make_integer_sequence.hpp>
#include <cstddef> // for std::size_t
#include <boost/pfr/tuple_size.hpp>
#if !defined(BOOST_PFR_INTERFACE_UNIT)
#include <cstddef> // for std::size_t
#endif
/// \file boost/pfr/core_name.hpp
/// Contains functions \forcedlink{get_name} and \forcedlink{names_as_array} to know which names each field of any \aggregate has.
///
@@ -79,8 +83,7 @@ auto
names_as_array() noexcept {
return detail::make_stdarray_from_tietuple(
detail::tie_as_names_tuple<T>(),
detail::make_index_sequence< tuple_size_v<T> >(),
1L
detail::make_index_sequence< tuple_size_v<T> >()
);
}
@@ -110,4 +113,6 @@ BOOST_PFR_END_MODULE_EXPORT
}} // namespace boost::pfr
#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_PFR_INTERFACE_UNIT)
#endif // BOOST_PFR_CORE_NAME_HPP

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
// Copyright (c) 2022 Denis Mikhailov
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -13,7 +13,9 @@
// `boost::pfr::detail::for_each_field_dispatcher` functions.
//
// The whole PFR library is build on top of those two functions.
#if BOOST_PFR_USE_CPP17
#if BOOST_PFR_USE_CPP26
#include <boost/pfr/detail/core26.hpp>
#elif BOOST_PFR_USE_CPP17
# include <boost/pfr/detail/core17.hpp>
#elif BOOST_PFR_USE_LOOPHOLE
# include <boost/pfr/detail/core14_loophole.hpp>

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -9,13 +9,6 @@
#include <boost/pfr/detail/config.hpp>
#ifdef BOOST_PFR_HAS_STD_MODULE
import std;
#else
#include <type_traits>
#include <utility> // metaprogramming stuff
#endif
#include <boost/pfr/detail/sequence_tuple.hpp>
#include <boost/pfr/detail/offset_based_getter.hpp>
#include <boost/pfr/detail/fields_count.hpp>
@@ -25,6 +18,11 @@ import std;
#include <boost/pfr/detail/size_t_.hpp>
#include <boost/pfr/detail/rvalue_t.hpp>
#if !defined(BOOST_PFR_INTERFACE_UNIT)
#include <type_traits>
#include <utility> // metaprogramming stuff
#endif
#ifdef __clang__
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wmissing-braces"

View File

@@ -1,5 +1,5 @@
// Copyright (c) 2017-2018 Alexandr Poltavsky, Antony Polukhin.
// Copyright (c) 2019-2025 Antony Polukhin.
// Copyright (c) 2019-2026 Antony Polukhin.
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -24,13 +24,6 @@
#include <boost/pfr/detail/config.hpp>
#ifdef BOOST_PFR_HAS_STD_MODULE
import std;
#else
#include <type_traits>
#include <utility>
#endif
#include <boost/pfr/detail/offset_based_getter.hpp>
#include <boost/pfr/detail/fields_count.hpp>
#include <boost/pfr/detail/make_flat_tuple_of_references.hpp>
@@ -39,6 +32,9 @@ import std;
#include <boost/pfr/detail/rvalue_t.hpp>
#include <boost/pfr/detail/unsafe_declval.hpp>
#if !defined(BOOST_PFR_INTERFACE_UNIT)
#include <utility>
#endif
#ifdef __clang__
# pragma clang diagnostic push

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
// Copyright (c) 2023 Denis Mikhailov
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -22,9 +22,7 @@
#include <boost/pfr/detail/sequence_tuple.hpp>
#include <boost/pfr/detail/size_t_.hpp>
#ifdef BOOST_PFR_HAS_STD_MODULE
import std;
#else
#if !defined(BOOST_PFR_INTERFACE_UNIT)
#include <type_traits> // for std::conditional_t, std::is_reference
#endif

View File

@@ -0,0 +1,39 @@
// Copyright (c) 2016-2026 Antony Polukhin
// Copyright (c) 2025 Jean-Michaël Celerier
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// boost-no-inspect
#ifndef BOOST_PFR_DETAIL_CORE26_HPP
#define BOOST_PFR_DETAIL_CORE26_HPP
#pragma once
#include <boost/pfr/detail/sequence_tuple.hpp>
namespace boost::pfr::detail {
template<class T>
constexpr auto tie_as_tuple(T &val) noexcept {
static_assert(!std::is_union<T>::value,
"====================> Boost.PFR: For safety reasons it is forbidden to reflect "
"unions. See `Reflection of unions` section in the docs for more info.");
auto &&[... members] = std::forward<T>(val);
return sequence_tuple::tuple<std::add_lvalue_reference_t<decltype(members)>...>{members...};
}
template <class T, class F, std::size_t... I>
constexpr void for_each_field_dispatcher(T& t, F&& f, std::index_sequence<I...>) {
static_assert(
!std::is_union<T>::value,
"====================> Boost.PFR: For safety reasons it is forbidden to reflect unions. See `Reflection of unions` section in the docs for more info."
);
std::forward<F>(f)(
detail::tie_as_tuple(t)
);
}
} // namespace boost::pfr::detail
#endif

View File

@@ -22,9 +22,7 @@
#include <boost/pfr/detail/sequence_tuple.hpp>
#include <boost/pfr/detail/stdarray.hpp>
#ifdef BOOST_PFR_HAS_STD_MODULE
import std;
#else
#if !defined(BOOST_PFR_INTERFACE_UNIT)
#include <type_traits>
#include <string_view>
#include <array>
@@ -218,8 +216,8 @@ constexpr std::string_view get_name() noexcept {
"====================> Boost.PFR: It is impossible to extract name from old C array since it doesn't have named members"
);
static_assert(
sizeof(T) && BOOST_PFR_USE_CPP17,
"====================> Boost.PFR: Extraction of field's names is allowed only when the BOOST_PFR_USE_CPP17 macro enabled."
sizeof(T) && (BOOST_PFR_USE_CPP17 || BOOST_PFR_USE_CPP26),
"====================> Boost.PFR: Extraction of field's names is allowed only when the BOOST_PFR_USE_CPP17 or the BOOST_PFR_USE_CPP26 macro enabled."
);
return stored_name_of_field<T, I>.data();

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -9,9 +9,7 @@
#include <boost/pfr/detail/config.hpp>
#ifdef BOOST_PFR_HAS_STD_MODULE
import std;
#else
#if !defined(BOOST_PFR_INTERFACE_UNIT)
#include <functional>
#include <type_traits>
#endif
@@ -21,7 +19,7 @@ namespace boost { namespace pfr { namespace detail {
struct can_not_apply{};
template <template <class, class> class Detector, class Tleft, class Tright>
struct not_appliable {
struct not_applicable {
static constexpr bool value = std::is_same<
Detector<Tleft, Tright>,
can_not_apply

View File

@@ -1,5 +1,5 @@
// Copyright (c) 2023 Bela Schaum, X-Ryl669, Denis Mikhailov.
// Copyright (c) 2024-2025 Antony Polukhin
// Copyright (c) 2024-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -12,11 +12,8 @@
#include <boost/pfr/detail/size_t_.hpp>
#include <boost/pfr/detail/unsafe_declval.hpp>
#ifdef BOOST_PFR_HAS_STD_MODULE
import std;
#else
#include <climits> // CHAR_BIT
#include <cstdint> // SIZE_MAX
#if !defined(BOOST_PFR_INTERFACE_UNIT)
#include <limits>
#include <type_traits>
#include <utility> // metaprogramming stuff
#endif
@@ -210,6 +207,7 @@ using is_one_element_range = std::integral_constant<bool, Begin == Last>;
using multi_element_range = std::false_type;
using one_element_range = std::true_type;
#if !BOOST_PFR_USE_CPP26
///////////////////// Fields count next expected compiler limitation
constexpr std::size_t fields_count_compiler_limitation_next(std::size_t n) noexcept {
#if defined(_MSC_VER) && (_MSC_VER <= 1920)
@@ -218,13 +216,13 @@ constexpr std::size_t fields_count_compiler_limitation_next(std::size_t n) noexc
#else
static_cast<void>(n);
#endif
return SIZE_MAX;
return (std::numeric_limits<std::size_t>::max)();
}
///////////////////// Fields count upper bound based on sizeof(T)
template <class T>
constexpr std::size_t fields_count_upper_bound_loose() noexcept {
return sizeof(T) * CHAR_BIT;
return sizeof(T) * std::numeric_limits<unsigned char>::digits + 1 /* +1 for "Arrays of Length Zero" extension */;
}
///////////////////// Fields count binary search.
@@ -331,6 +329,7 @@ constexpr std::size_t fields_count_lower_bound_unbounded(int, size_t_<0>) noexce
);
return detail::fields_count_lower_bound_unbounded<T, last + 1>(1L, size_t_<result_maybe>{});
}
#endif
///////////////////// Choosing between array size, unbounded binary search, and linear search followed by unbounded binary search.
template <class T>
@@ -345,6 +344,27 @@ constexpr auto fields_count_dispatch(long, long, std::true_type /*are_preconditi
return sizeof(T) / sizeof(std::remove_all_extents_t<T>);
}
#if BOOST_PFR_USE_CPP26
template<class T>
constexpr auto fields_count_dispatch_impl(const T &t) noexcept
{
const auto &[... elts] = t;
return std::integral_constant<std::size_t, sizeof...(elts)>{};
}
template<class T>
constexpr auto fields_count_dispatch(long, int, std::true_type /*are_preconditions_met*/) noexcept
-> std::enable_if_t<std::is_scalar<T>::value, std::size_t>
{
return 1;
}
template<class T>
constexpr auto fields_count_dispatch(int, int, std::true_type /*are_preconditions_met*/) noexcept
{
return decltype(detail::fields_count_dispatch_impl(std::declval<const T &>()))::value;
}
#else
template <class T>
constexpr auto fields_count_dispatch(long, int, std::true_type /*are_preconditions_met*/) noexcept
-> decltype(sizeof(T{}))
@@ -363,6 +383,7 @@ constexpr std::size_t fields_count_dispatch(int, int, std::true_type /*are_preco
constexpr std::size_t last = detail::fields_count_upper_bound<T, begin, begin + 1>(1L, 1L);
return detail::fields_count_binary_search<T, begin, last>(detail::is_one_element_range<begin, last>{}, 1L);
}
#endif
///////////////////// Returns fields count
template <class T>
@@ -428,9 +449,8 @@ constexpr std::size_t fields_count() noexcept {
constexpr bool no_errors =
type_is_complete && type_is_not_a_reference && type_fields_are_move_constructible
&& type_is_not_polymorphic && type_is_aggregate;
constexpr std::size_t result = detail::fields_count_dispatch<type>(1L, 1L, std::integral_constant<bool, no_errors>{});
constexpr std::size_t result
= detail::fields_count_dispatch<type>(1L, 1L, std::integral_constant<bool, no_errors>{});
detail::assert_first_not_base<type, result>(1L);
#ifndef __cpp_lib_is_aggregate

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -9,21 +9,35 @@
#include <boost/pfr/detail/config.hpp>
#ifdef BOOST_PFR_HAS_STD_MODULE
import std;
#else
#include <type_traits> // metaprogramming stuff
#endif
#include <boost/pfr/detail/core.hpp>
#include <boost/pfr/detail/fields_count.hpp>
#include <boost/pfr/detail/for_each_field_impl.hpp>
#include <boost/pfr/detail/make_integer_sequence.hpp>
#if !defined(BOOST_PFR_INTERFACE_UNIT)
#include <type_traits> // metaprogramming stuff
#include <utility> // forward_like
#endif
namespace boost { namespace pfr { namespace detail {
template <class T, class F>
constexpr void for_each_field(T&& value, F&& func) {
#if BOOST_PFR_USE_CPP26
using no_ref = std::remove_reference_t<T>;
if constexpr (std::is_aggregate_v<no_ref> || std::is_bounded_array_v<no_ref>) {
auto &&[... members] = value;
::boost::pfr::detail::for_each_field_impl(value,
std::forward<F>(func),
std::make_index_sequence<sizeof...(members)>{},
std::is_rvalue_reference<T &&>{});
} else {
::boost::pfr::detail::for_each_field_impl(value,
std::forward<F>(func),
std::make_index_sequence<1>{},
std::is_rvalue_reference<T &&>{});
}
#else
constexpr std::size_t fields_count_val = boost::pfr::detail::fields_count<std::remove_reference_t<T>>();
::boost::pfr::detail::for_each_field_dispatcher(
@@ -42,6 +56,7 @@ constexpr void for_each_field(T&& value, F&& func) {
},
detail::make_index_sequence<fields_count_val>{}
);
#endif
}
}}} // namespace boost::pfr::detail

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -9,15 +9,13 @@
#include <boost/pfr/detail/config.hpp>
#ifdef BOOST_PFR_HAS_STD_MODULE
import std;
#else
#include <utility> // metaprogramming stuff
#endif
#include <boost/pfr/detail/sequence_tuple.hpp>
#include <boost/pfr/detail/rvalue_t.hpp>
#if !defined(BOOST_PFR_INTERFACE_UNIT)
#include <utility> // metaprogramming stuff
#endif
namespace boost { namespace pfr { namespace detail {
template <std::size_t Index>
@@ -33,7 +31,30 @@ constexpr void for_each_field_impl_apply(T&& v, F&& f, I /*i*/, int) {
std::forward<F>(f)(std::forward<T>(v));
}
#if !defined(__cpp_fold_expressions) || __cpp_fold_expressions < 201603
#if BOOST_PFR_USE_CPP26
template<class T, class F, std::size_t... I>
constexpr void for_each_field_impl(T& t, F&& f, std::index_sequence<I...>, auto move_values) {
if constexpr (std::is_aggregate_v<T> || std::is_bounded_array_v<T>) {
auto &&[... members] = t;
if constexpr (move_values)
(detail::for_each_field_impl_apply(std::move(members...[I]),
std::forward<F>(f),
size_t_<I>{},
1L),
...);
else
(detail::for_each_field_impl_apply(
members... [I], std::forward<F>(f), size_t_<I> {}, 1L),
...);
} else {
if constexpr (move_values)
(detail::for_each_field_impl_apply(std::move(t), std::forward<F>(f), size_t_<I>{}, 1L),
...);
else
(detail::for_each_field_impl_apply(t, std::forward<F>(f), size_t_<I>{}, 1L), ...);
}
}
#elif !defined(__cpp_fold_expressions) || __cpp_fold_expressions < 201603
template <class T, class F, std::size_t... I>
constexpr void for_each_field_impl(T& t, F&& f, std::index_sequence<I...>, std::false_type /*move_values*/) {
const int v[] = {0, (
@@ -63,8 +84,6 @@ constexpr void for_each_field_impl(T& t, F&& f, std::index_sequence<I...>, std::
(detail::for_each_field_impl_apply(sequence_tuple::get<I>(std::move(t)), std::forward<F>(f), size_t_<I>{}, 1L), ...);
}
#endif
}}} // namespace boost::pfr::detail
#endif // BOOST_PFR_DETAIL_FOR_EACH_FIELD_IMPL_HPP

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -9,15 +9,13 @@
#include <boost/pfr/detail/config.hpp>
#ifdef BOOST_PFR_HAS_STD_MODULE
import std;
#else
#include <functional>
#include <cstdint>
#endif
#include <boost/pfr/detail/sequence_tuple.hpp>
#if !defined(BOOST_PFR_INTERFACE_UNIT)
#include <cstdint>
#include <functional>
#endif
namespace boost { namespace pfr { namespace detail {
template <std::size_t I, std::size_t N>
struct equal_impl {

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -11,9 +11,7 @@
#include <boost/pfr/detail/sequence_tuple.hpp>
#ifdef BOOST_PFR_HAS_STD_MODULE
import std;
#else
#if !defined(BOOST_PFR_INTERFACE_UNIT)
#include <iosfwd> // stream operators
#include <iomanip>

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -9,16 +9,13 @@
#include <boost/pfr/detail/config.hpp>
#ifdef BOOST_PFR_HAS_STD_MODULE
import std;
#else
#include <utility> // metaprogramming stuff
#endif
#include <boost/pfr/detail/sequence_tuple.hpp>
#include <boost/pfr/detail/rvalue_t.hpp>
#include <boost/pfr/detail/make_integer_sequence.hpp>
#if !defined(BOOST_PFR_INTERFACE_UNIT)
#include <utility> // metaprogramming stuff
#endif
namespace boost { namespace pfr { namespace detail {

View File

@@ -1,5 +1,5 @@
// Copyright (c) 2018 Sergei Fedorov
// Copyright (c) 2019-2025 Antony Polukhin
// Copyright (c) 2019-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -10,9 +10,7 @@
#include <boost/pfr/detail/config.hpp>
#ifdef BOOST_PFR_HAS_STD_MODULE
import std;
#else
#if !defined(BOOST_PFR_INTERFACE_UNIT)
#include <type_traits>
#include <utility>
#include <cstddef>

View File

@@ -1,5 +1,5 @@
// Copyright (c) 2017-2018 Chris Beck
// Copyright (c) 2019-2025 Antony Polukhin
// Copyright (c) 2019-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -10,18 +10,15 @@
#include <boost/pfr/detail/config.hpp>
#ifdef BOOST_PFR_HAS_STD_MODULE
import std;
#else
#include <type_traits>
#include <utility>
#include <memory> // std::addressof
#endif
#include <boost/pfr/detail/sequence_tuple.hpp>
#include <boost/pfr/detail/rvalue_t.hpp>
#include <boost/pfr/detail/size_t_.hpp>
#if !defined(BOOST_PFR_INTERFACE_UNIT)
#include <type_traits>
#include <utility>
#include <memory> // std::addressof
#endif
namespace boost { namespace pfr { namespace detail {

View File

@@ -10,9 +10,7 @@
#include <boost/pfr/detail/config.hpp>
#include <boost/pfr/traits_fwd.hpp>
#ifdef BOOST_PFR_HAS_STD_MODULE
import std;
#else
#if !defined(BOOST_PFR_INTERFACE_UNIT)
#include <type_traits> // for std::is_aggregate
#endif

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -7,9 +7,7 @@
#define BOOST_PFR_DETAIL_RVALUE_T_HPP
#pragma once
#ifdef BOOST_PFR_HAS_STD_MODULE
import std;
#else
#if !defined(BOOST_PFR_INTERFACE_UNIT)
#include <type_traits>
#include <utility> // std::enable_if_t
#endif

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -10,9 +10,7 @@
#include <boost/pfr/detail/config.hpp>
#include <boost/pfr/detail/make_integer_sequence.hpp>
#ifdef BOOST_PFR_HAS_STD_MODULE
import std;
#else
#if !defined(BOOST_PFR_INTERFACE_UNIT)
#include <utility> // metaprogramming stuff
#include <cstddef> // std::size_t
#endif

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -9,9 +9,7 @@
#include <boost/pfr/detail/config.hpp>
#ifdef BOOST_PFR_HAS_STD_MODULE
import std;
#else
#if !defined(BOOST_PFR_INTERFACE_UNIT)
#include <cstddef>
#endif

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -7,6 +7,11 @@
#define BOOST_PFR_DETAIL_SIZE_T_HPP
#pragma once
#if !defined(BOOST_PFR_INTERFACE_UNIT)
#include <type_traits>
#include <cstddef>
#endif
namespace boost { namespace pfr { namespace detail {
///////////////////// General utility stuff

View File

@@ -9,35 +9,31 @@
#include <boost/pfr/detail/config.hpp>
#ifdef BOOST_PFR_HAS_STD_MODULE
import std;
#else
#include <utility> // metaprogramming stuff
#include <array>
#include <type_traits> // for std::common_type_t
#include <cstddef>
#endif
#include <boost/pfr/detail/sequence_tuple.hpp>
#if !defined(BOOST_PFR_INTERFACE_UNIT)
#include <array>
#if BOOST_PFR_CORE_NAME_ENABLED
# include <string_view>
#endif
#include <utility> // metaprogramming stuff
#endif
namespace boost { namespace pfr { namespace detail {
template <class... Types>
constexpr auto make_stdarray(const Types&... t) noexcept {
return std::array<std::common_type_t<Types...>, sizeof...(Types)>{t...};
}
#if BOOST_PFR_CORE_NAME_ENABLED
template <class T, std::size_t... I>
constexpr auto make_stdarray_from_tietuple(const T& t, std::index_sequence<I...>, int) noexcept {
return detail::make_stdarray(
constexpr auto make_stdarray_from_tietuple(const T& t, std::index_sequence<I...>) noexcept {
return std::array<std::string_view, sizeof...(I)>{
boost::pfr::detail::sequence_tuple::get<I>(t)...
);
};
}
template <class T>
constexpr auto make_stdarray_from_tietuple(const T&, std::index_sequence<>, long) noexcept {
return std::array<std::nullptr_t, 0>{};
#else
template <class T, std::size_t... I>
constexpr auto make_stdarray_from_tietuple(const T&, std::index_sequence<I...>) noexcept {
return nullptr;
}
#endif
}}} // namespace boost::pfr::detail

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -9,15 +9,13 @@
#include <boost/pfr/detail/config.hpp>
#ifdef BOOST_PFR_HAS_STD_MODULE
import std;
#else
#include <boost/pfr/detail/sequence_tuple.hpp>
#if !defined(BOOST_PFR_INTERFACE_UNIT)
#include <utility> // metaprogramming stuff
#include <tuple>
#endif
#include <boost/pfr/detail/sequence_tuple.hpp>
namespace boost { namespace pfr { namespace detail {
template <class T, std::size_t... I>

View File

@@ -1,5 +1,5 @@
// Copyright (c) 2018 Adam Butcher, Antony Polukhin
// Copyright (c) 2019-2025 Antony Polukhin
// Copyright (c) 2019-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -16,9 +16,7 @@
#include <boost/pfr/tuple_size.hpp>
#include <boost/pfr/detail/make_integer_sequence.hpp>
#ifdef BOOST_PFR_HAS_STD_MODULE
import std;
#else
#if !defined(BOOST_PFR_INTERFACE_UNIT)
#include <tuple>
#endif

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2019-2025 Antony Polukhin.
// Copyright (c) 2019-2026 Antony Polukhin.
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -9,9 +9,7 @@
#include <boost/pfr/detail/config.hpp>
#ifdef BOOST_PFR_HAS_STD_MODULE
import std;
#else
#if !defined(BOOST_PFR_INTERFACE_UNIT)
#include <type_traits>
#endif
@@ -29,9 +27,19 @@ template <class T>
constexpr T unsafe_declval() noexcept {
report_if_you_see_link_error_with_this_function();
#ifdef BOOST_PFR_USE_LEGACY_UNSAFE_DECLVAL_IMPLEMENTATION
typename std::remove_reference<T>::type* ptr = nullptr;
ptr += 42; // suppresses 'null pointer dereference' warnings
return static_cast<T>(*ptr);
#else
// Looks like `static_cast<T>(*ptr)` to prvalue fails on clang in C++26.
// If this new implementation does not work for some cases, please, fill a
// bug report and feel free to
// define BOOST_PFR_USE_LEGACY_UNSAFE_DECLVAL_IMPLEMENTATION.
using func_ptr_t = T(*)();
func_ptr_t ptr = nullptr;
return ptr();
#endif
}
}}} // namespace boost::pfr::detail

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -9,8 +9,10 @@
#include <boost/pfr/detail/config.hpp>
#if !defined(BOOST_USE_MODULES) || defined(BOOST_PFR_INTERFACE_UNIT)
#include <boost/pfr/ops_fields.hpp>
#include <boost/pfr/io_fields.hpp>
#endif
/// \file boost/pfr/functions_for.hpp
/// Contains BOOST_PFR_FUNCTIONS_FOR macro that defined comparison and stream operators for T along with hash_value function.

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -9,6 +9,8 @@
#include <boost/pfr/detail/config.hpp>
#if !defined(BOOST_USE_MODULES) || defined(BOOST_PFR_INTERFACE_UNIT)
#include <boost/pfr/ops.hpp>
#include <boost/pfr/detail/functional.hpp>
@@ -222,4 +224,6 @@ BOOST_PFR_END_MODULE_EXPORT
}} // namespace boost::pfr
#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_PFR_INTERFACE_UNIT)
#endif // BOOST_PFR_FUNCTORS_HPP

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -9,6 +9,8 @@
#include <boost/pfr/detail/config.hpp>
#if !defined(BOOST_USE_MODULES) || defined(BOOST_PFR_INTERFACE_UNIT)
#include <boost/pfr/detail/detectors.hpp>
#include <boost/pfr/io_fields.hpp>
@@ -38,25 +40,25 @@ namespace detail {
///////////////////// Helper typedefs
template <class Stream, class Type>
using enable_not_ostreamable_t = std::enable_if_t<
not_appliable<ostreamable_detector, Stream&, const std::remove_reference_t<Type>&>::value,
not_applicable<ostreamable_detector, Stream&, const std::remove_reference_t<Type>&>::value,
Stream&
>;
template <class Stream, class Type>
using enable_not_istreamable_t = std::enable_if_t<
not_appliable<istreamable_detector, Stream&, Type&>::value,
not_applicable<istreamable_detector, Stream&, Type&>::value,
Stream&
>;
template <class Stream, class Type>
using enable_ostreamable_t = std::enable_if_t<
!not_appliable<ostreamable_detector, Stream&, const std::remove_reference_t<Type>&>::value,
!not_applicable<ostreamable_detector, Stream&, const std::remove_reference_t<Type>&>::value,
Stream&
>;
template <class Stream, class Type>
using enable_istreamable_t = std::enable_if_t<
!not_appliable<istreamable_detector, Stream&, Type&>::value,
!not_applicable<istreamable_detector, Stream&, Type&>::value,
Stream&
>;
@@ -118,4 +120,6 @@ BOOST_PFR_END_MODULE_EXPORT
}} // namespace boost::pfr
#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_PFR_INTERFACE_UNIT)
#endif // BOOST_PFR_IO_HPP

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -10,16 +10,19 @@
#include <boost/pfr/detail/config.hpp>
#if !defined(BOOST_USE_MODULES) || defined(BOOST_PFR_INTERFACE_UNIT)
#include <boost/pfr/detail/core.hpp>
#include <type_traits>
#include <utility> // metaprogramming stuff
#include <boost/pfr/detail/sequence_tuple.hpp>
#include <boost/pfr/detail/io.hpp>
#include <boost/pfr/detail/make_integer_sequence.hpp>
#include <boost/pfr/tuple_size.hpp>
#if !defined(BOOST_PFR_INTERFACE_UNIT)
#include <type_traits>
#include <utility> // metaprogramming stuff
#endif
/// \file boost/pfr/io_fields.hpp
/// Contains IO manipulator \forcedlink{io_fields} to read/write any \aggregate field-by-field.
///
@@ -52,6 +55,7 @@ struct io_fields_impl {
T value;
};
BOOST_PFR_BEGIN_MODULE_EXPORT
template <class Char, class Traits, class T>
std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& out, io_fields_impl<const T&>&& x) {
@@ -118,8 +122,6 @@ std::basic_istream<Char, Traits>& operator>>(std::basic_istream<Char, Traits>& i
return in;
}
BOOST_PFR_BEGIN_MODULE_EXPORT
template <class Char, class Traits, class T>
std::basic_istream<Char, Traits>& operator>>(std::basic_istream<Char, Traits>& in, io_fields_impl<const T&>&& ) {
static_assert(sizeof(T) && false, "====================> Boost.PFR: Attempt to use istream operator on a boost::pfr::io_fields wrapped type T with const qualifier.");
@@ -169,4 +171,6 @@ BOOST_PFR_END_MODULE_EXPORT
}} // namespace boost::pfr
#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_PFR_INTERFACE_UNIT)
#endif // BOOST_PFR_IO_FIELDS_HPP

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -9,6 +9,8 @@
#include <boost/pfr/detail/config.hpp>
#if !defined(BOOST_USE_MODULES) || defined(BOOST_PFR_INTERFACE_UNIT)
#include <boost/pfr/detail/detectors.hpp>
#include <boost/pfr/ops_fields.hpp>
@@ -40,13 +42,13 @@ namespace detail {
///////////////////// Helper typedefs that are used by all the ops
template <template <class, class> class Detector, class T, class U>
using enable_not_comp_base_t = std::enable_if_t<
not_appliable<Detector, T const&, U const&>::value,
not_applicable<Detector, T const&, U const&>::value,
bool
>;
template <template <class, class> class Detector, class T, class U>
using enable_comp_base_t = std::enable_if_t<
!not_appliable<Detector, T const&, U const&>::value,
!not_applicable<Detector, T const&, U const&>::value,
bool
>;
///////////////////// std::enable_if_t like functions that enable only if types do not support operation
@@ -59,7 +61,7 @@ namespace detail {
template <class T, class U> using enable_not_ge_comp_t = enable_not_comp_base_t<comp_ge_detector, T, U>;
template <class T> using enable_not_hashable_t = std::enable_if_t<
not_appliable<hash_detector, const T&, const T&>::value,
not_applicable<hash_detector, const T&, const T&>::value,
std::size_t
>;
///////////////////// std::enable_if_t like functions that enable only if types do support operation
@@ -72,7 +74,7 @@ namespace detail {
template <class T, class U> using enable_ge_comp_t = enable_comp_base_t<comp_ge_detector, T, U>;
template <class T> using enable_hashable_t = std::enable_if_t<
!not_appliable<hash_detector, const T&, const T&>::value,
!not_applicable<hash_detector, const T&, const T&>::value,
std::size_t
>;
} // namespace detail
@@ -187,4 +189,6 @@ BOOST_PFR_END_MODULE_EXPORT
}} // namespace boost::pfr
#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_PFR_INTERFACE_UNIT)
#endif // BOOST_PFR_OPS_HPP

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -9,6 +9,8 @@
#include <boost/pfr/detail/config.hpp>
#if !defined(BOOST_USE_MODULES) || defined(BOOST_PFR_INTERFACE_UNIT)
#include <boost/pfr/core.hpp>
#include <boost/pfr/detail/functional.hpp>
@@ -129,4 +131,6 @@ BOOST_PFR_END_MODULE_EXPORT
}} // namespace boost::pfr
#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_PFR_INTERFACE_UNIT)
#endif // BOOST_PFR_OPS_HPP

View File

@@ -9,8 +9,13 @@
#include <boost/pfr/detail/config.hpp>
#if !defined(BOOST_USE_MODULES) || defined(BOOST_PFR_INTERFACE_UNIT)
#include <boost/pfr/detail/possible_reflectable.hpp>
#if !defined(BOOST_PFR_INTERFACE_UNIT)
#include <type_traits>
#endif
/// \file boost/pfr/traits.hpp
/// Contains traits \forcedlink{is_reflectable} and \forcedlink{is_implicitly_reflectable} for detecting an ability to reflect type.
@@ -60,5 +65,7 @@ BOOST_PFR_END_MODULE_EXPORT
}} // namespace boost::pfr
#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_PFR_INTERFACE_UNIT)
#endif // BOOST_PFR_TRAITS_HPP

View File

@@ -9,6 +9,8 @@
#include <boost/pfr/detail/config.hpp>
#if !defined(BOOST_USE_MODULES) || defined(BOOST_PFR_INTERFACE_UNIT)
namespace boost { namespace pfr {
BOOST_PFR_BEGIN_MODULE_EXPORT
@@ -20,6 +22,7 @@ BOOST_PFR_END_MODULE_EXPORT
}} // namespace boost::pfr
#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_PFR_INTERFACE_UNIT)
#endif // BOOST_PFR_DETAIL_TRAITS_FWD_HPP

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -10,12 +10,16 @@
#include <boost/pfr/detail/config.hpp>
#include <type_traits>
#include <utility> // metaprogramming stuff
#if !defined(BOOST_USE_MODULES) || defined(BOOST_PFR_INTERFACE_UNIT)
#include <boost/pfr/detail/sequence_tuple.hpp>
#include <boost/pfr/detail/fields_count.hpp>
#if !defined(BOOST_PFR_INTERFACE_UNIT)
#include <type_traits>
#include <utility> // metaprogramming stuff
#endif
/// \file boost/pfr/tuple_size.hpp
/// Contains tuple-like interfaces to get fields count \forcedlink{tuple_size}, \forcedlink{tuple_size_v}.
///
@@ -49,4 +53,6 @@ BOOST_PFR_END_MODULE_EXPORT
}} // namespace boost::pfr
#endif // #if defined(BOOST_USE_MODULES) && !defined(BOOST_PFR_INTERFACE_UNIT)
#endif // BOOST_PFR_TUPLE_SIZE_HPP

View File

@@ -1,6 +1,6 @@
<!DOCTYPE html>
<!--
Copyright (c) 2014-2025 Antony Polukhin
Copyright (c) 2014-2026 Antony Polukhin
antoshkka at gmail dot com
Distributed under the Boost Software License,

View File

@@ -1,6 +1,6 @@
#!/usr/bin/python
# Copyright (c) 2016-2025 Antony Polukhin
# Copyright (c) 2016-2026 Antony Polukhin
# Copyright (c) 2023 Denis Mikhailov
#
# Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -15,7 +15,7 @@ import string
ascii_letters = string.ascii_letters.replace("o", "").replace("O", "").replace("i", "").replace("I", "").replace("T", "")
WORKAROUND_CAST_EXPRESSIONS_LIMIT_PER_LINE = 3
PROLOGUE = """// Copyright (c) 2016-2025 Antony Polukhin
PROLOGUE = """// Copyright (c) 2016-2026 Antony Polukhin
// Copyright (c) 2023 Denis Mikhailov
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -39,9 +39,7 @@ PROLOGUE = """// Copyright (c) 2016-2025 Antony Polukhin
#include <boost/pfr/detail/sequence_tuple.hpp>
#include <boost/pfr/detail/size_t_.hpp>
#ifdef BOOST_PFR_HAS_STD_MODULE
import std;
#else
#if !defined(BOOST_PFR_INTERFACE_UNIT)
#include <type_traits> // for std::conditional_t, std::is_reference
#endif

View File

@@ -1,10 +1,12 @@
#!/bin/bash
# Copyright (c) 2021 Antony Polukhin
# Copyright (c) 2021-2026 Antony Polukhin
#
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
PFR_TEST_COMPILER=clang++-19
echo "***** Making target path"
TARGET_PATH="`dirname \"$0\"`/../../pfr_non_boost"
rm -rf ${TARGET_PATH}/*
@@ -24,61 +26,83 @@ rm ${TARGET_PATH}/misc/strip_boost_namespace.sh
rm -rf ${TARGET_PATH}/meta
echo "***** Changing sources"
find ${TARGET_PATH} -type f | xargs sed -i 's|namespace boost { ||g'
find ${TARGET_PATH} -type f | xargs sed -i 's|namespace boost {||g'
find ${TARGET_PATH} -type f | xargs sed -i 's|} // namespace boost::| // namespace |g'
find ${TARGET_PATH} -type f | xargs sed -i \
-e 's|namespace boost { ||g' \
-e 's|namespace boost {||g' \
-e 's|} // namespace boost::| // namespace |g' \
\
-e 's/::boost::pfr/::pfr/g' \
-e 's/boost::pfr/pfr/g' \
-e 's/BOOST_PFR_/PFR_/g' \
-e 's|boost/pfr|pfr|g' \
\
-e 's/boost_pfr /pfr /g' \
-e 's/boost_pfr_/pfr_/g' \
-e 's/boost_pfr)/pfr)/g' \
-e 's/Boost::pfr/pfr::pfr/g' \
-e 's/BOOST_USE_MODULES/PFR_USE_MODULES/g' \
-e 's|boost\.pfr;|pfr;|g' \
find ${TARGET_PATH} -type f | xargs sed -i 's/::boost::pfr/::pfr/g'
find ${TARGET_PATH} -type f | xargs sed -i 's/boost::pfr/pfr/g'
find ${TARGET_PATH} -type f | xargs sed -i 's/BOOST_PFR_/PFR_/g'
find ${TARGET_PATH} -type f | xargs sed -i 's|boost/pfr|pfr|g'
find ${TARGET_PATH}/doc -type f | xargs sed -i 's|boost.pfr.|pfr.|g'
find ${TARGET_PATH}/doc -type f | xargs sed -i 's|Boost.PFR|PFR|g'
find ${TARGET_PATH}/doc -type f | xargs sed -i \
-e 's|boost\.pfr\.|pfr.|g' \
-e 's|boost\.pfr`|pfr`|g' \
-e 's/boost_pfr\./pfr./g' \
-e 's|Boost\.PFR|PFR|g' \
sed -i 's|# \[Boost.PFR\](https://boost.org/libs/pfr)|# [PFR](https://apolukhin.github.io/pfr_non_boost/)|g' ${TARGET_PATH}/README.md
echo -n "***** Testing: "
if g++-12 -std=c++2a -DPFR_ENABLE_GET_NAME_STATIC=1 -I ${TARGET_PATH}/include/ ${TARGET_PATH}/example/motivating_example0.cpp && ./a.out > /dev/null; then
if ${PFR_TEST_COMPILER} -std=c++2a -DPFR_ENABLE_GET_NAME_STATIC=1 -I ${TARGET_PATH}/include/ ${TARGET_PATH}/example/motivating_example0.cpp && ./a.out > /dev/null; then
echo -n "OK"
else
echo -n "FAIL"
exit 2
fi
if g++-12 -std=c++2a -DPFR_ENABLE_GET_NAME_STATIC=0 -I ${TARGET_PATH}/include/ ${TARGET_PATH}/example/motivating_example0.cpp && ./a.out > /dev/null; then
echo -n "OK"
if ${PFR_TEST_COMPILER} -std=c++2a -DPFR_ENABLE_GET_NAME_STATIC=0 -I ${TARGET_PATH}/include/ ${TARGET_PATH}/example/motivating_example0.cpp && ./a.out > /dev/null; then
echo -n ", OK"
else
echo -n "FAIL"
echo -n ", FAIL"
exit 3
fi
if g++-12 -std=c++2a -DPFR_ENABLE_GET_NAME_STATIC=1 -DBOOST_PFR_USE_CPP17=1 -I ${TARGET_PATH}/include/ ${TARGET_PATH}/example/get_name.cpp && ./a.out > /dev/null; then
echo -e ", OK"
if ${PFR_TEST_COMPILER} -std=c++2a -DPFR_ENABLE_GET_NAME_STATIC=1 -DBOOST_PFR_USE_CPP17=1 -I ${TARGET_PATH}/include/ ${TARGET_PATH}/example/get_name.cpp && ./a.out > /dev/null; then
echo -n ", OK"
else
echo -e ", FAIL"
echo -n ", FAIL"
exit 4
fi
if g++-12 -std=c++2a -DPFR_USE_LOOPHOLE=0 -DPFR_USE_CPP17=1 -I ${TARGET_PATH}/include/ ${TARGET_PATH}/example/motivating_example0.cpp && ./a.out > /dev/null; then
echo -n "OK"
if ${PFR_TEST_COMPILER} -std=c++2a -DPFR_USE_LOOPHOLE=0 -DPFR_USE_CPP17=1 -I ${TARGET_PATH}/include/ ${TARGET_PATH}/example/motivating_example0.cpp && ./a.out > /dev/null; then
echo -n ", OK"
else
echo -n "FAIL"
echo -n ", FAIL"
exit 5
fi
if g++-12 -std=c++2a -DPFR_USE_LOOPHOLE=1 -DPFR_USE_CPP17=0 -I ${TARGET_PATH}/include/ ${TARGET_PATH}/example/motivating_example0.cpp && ./a.out > /dev/null; then
if ${PFR_TEST_COMPILER} -std=c++2a -DPFR_USE_LOOPHOLE=1 -DPFR_USE_CPP17=0 -I ${TARGET_PATH}/include/ ${TARGET_PATH}/example/motivating_example0.cpp && ./a.out > /dev/null; then
echo -n ", OK"
else
echo -n ", FAIL"
exit 6
fi
if g++-12 -std=c++2a -DPFR_USE_LOOPHOLE=0 -DPFR_USE_CPP17=0 -I ${TARGET_PATH}/include/ ${TARGET_PATH}/example/get.cpp && ./a.out > /dev/null; then
echo -e ", OK"
if ${PFR_TEST_COMPILER} -std=c++2a -DPFR_USE_LOOPHOLE=0 -DPFR_USE_CPP17=0 -I ${TARGET_PATH}/include/ ${TARGET_PATH}/example/get.cpp && ./a.out > /dev/null; then
echo -n ", OK"
else
echo -e ", FAIL"
echo -n ", FAIL"
exit 7
fi
mkdir build_module || :
cd build_module
if cmake -DPFR_USE_MODULES=1 -DBUILD_TESTING=1 -GNinja -DCMAKE_CXX_COMPILER=${PFR_TEST_COMPILER} ${TARGET_PATH} && cmake --build .; then
echo "Modules check OK"
else
echo "Modules check FAIL"
exit 8
fi
cd ..
rm -rf build_module || :
rm a.out || :
echo "***** Done"
echo -e "\n***** Done"

View File

@@ -1,37 +0,0 @@
# Copyright (c) 2016-2025 Antony Polukhin
#
# Distributed under the Boost Software License, Version 1.0.
# https://www.boost.org/LICENSE_1_0.txt
cmake_minimum_required(VERSION 3.28)
function (_add_boost_pfr_module_impl NAME)
add_library(${NAME})
target_compile_features(${NAME} PUBLIC cxx_std_20)
target_sources(${NAME} PUBLIC
FILE_SET modules_public TYPE CXX_MODULES FILES
${CMAKE_CURRENT_LIST_DIR}/pfr.cppm
)
endfunction()
function (add_boost_pfr_module NAME)
_add_boost_pfr_module_impl(${NAME})
target_include_directories(${NAME} PRIVATE ${CMAKE_CURRENT_LIST_DIR}/../include)
_add_boost_pfr_module_impl(${NAME}_migration)
target_include_directories(${NAME}_migration PUBLIC ${CMAKE_CURRENT_LIST_DIR}/../include)
target_compile_definitions(${NAME}_migration PRIVATE BOOST_PFR_ATTACH_TO_GLOBAL_MODULE)
endfunction()
add_boost_pfr_module(boost_pfr_module)
add_library(Boost::pfr_module ALIAS boost_pfr_module)
add_library(Boost::pfr_module_migration ALIAS boost_pfr_module_migration)
if (BUILD_TESTING)
add_executable(boost_pfr_module_usage usage_sample.cpp)
target_link_libraries(boost_pfr_module_usage PRIVATE Boost::pfr_module)
# Make sure that mixing includes and imports is fine for different TU
add_executable(boost_pfr_module_usage_mu usage_test_mu1.cpp usage_test_mu2.cpp)
target_link_libraries(boost_pfr_module_usage_mu PRIVATE Boost::pfr_module_migration)
endif()

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -6,16 +6,21 @@
// To compile manually use a command like the folowing:
// clang++ -I ../include -std=c++20 --precompile -x c++-module pfr.cppm
#define BOOST_PFR_BEGIN_MODULE_EXPORT export {
#define BOOST_PFR_END_MODULE_EXPORT }
#ifndef BOOST_PFR_HAS_STD_MODULE
module;
#include <version>
#include <cstddef>
#include <cstdint>
#ifdef BOOST_PFR_USE_STD_MODULE
import std;
#else
#include <array>
#include <cstddef>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <memory>
#include <string>
#include <string_view>
@@ -25,20 +30,13 @@ module;
#include <variant>
#endif
export module Boost.PFR;
#define BOOST_PFR_INTERFACE_UNIT
#ifdef BOOST_PFR_HAS_STD_MODULE
import std;
#endif
export module boost.pfr;
#ifdef __clang__
# pragma clang diagnostic ignored "-Winclude-angled-in-module-purview"
#endif
#ifdef BOOST_PFR_ATTACH_TO_GLOBAL_MODULE
extern "C++" {
#include <boost/pfr.hpp>
}
#else
#include <boost/pfr.hpp>
#endif

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -11,7 +11,7 @@
#include <iomanip>
#include <string>
import Boost.PFR;
import boost.pfr;
struct some_person {
std::string name;

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -9,7 +9,7 @@
#include <iostream>
#include <iomanip>
import Boost.PFR;
import boost.pfr;
struct some_person {
std::string name;

32
test/CMakeLists.txt Normal file
View File

@@ -0,0 +1,32 @@
# Copyright (c) 2016-2026 Antony Polukhin
# Distributed under the Boost Software License, Version 1.0.
# See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt
if(NOT TARGET tests)
add_custom_target(tests)
endif()
file(GLOB CORE_RUN_FILES "core/run/*.cpp")
foreach (testsourcefile ${CORE_RUN_FILES})
get_filename_component(testname ${testsourcefile} NAME_WE)
add_executable(pfr_core_${testname} ${testsourcefile})
target_link_libraries(pfr_core_${testname} Boost::pfr Boost::core Boost::container_hash)
target_include_directories(pfr_core_${testname} PRIVATE ../../../)
add_test(NAME pfr_core_${testname} COMMAND pfr_core_${testname})
add_dependencies(tests pfr_core_${testname})
endforeach()
if(CMAKE_VERSION VERSION_LESS 3.12)
message(AUTHOR_WARNING "Disabling core_name tests as CMake version 3.12+ is required but using ${CMAKE_VERSION}")
else()
file(GLOB CORE_NAME_RUN_FILES "core_name/run/*.cpp")
foreach (testsourcefile ${CORE_NAME_RUN_FILES})
get_filename_component(testname ${testsourcefile} NAME_WE)
add_executable(pfr_corename_${testname} ${testsourcefile})
target_compile_features(pfr_corename_${testname} PUBLIC cxx_std_20)
target_link_libraries(pfr_corename_${testname} Boost::pfr Boost::core Boost::container_hash)
target_include_directories(pfr_corename_${testname} PRIVATE ../../../)
add_test(NAME pfr_corename_${testname} COMMAND pfr_corename_${testname})
add_dependencies(tests pfr_corename_${testname})
endforeach()
endif()

View File

@@ -41,16 +41,16 @@ environment:
# ADDRMD: 32,64
# CXXSTD: 17,latest
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: msvc # clang-win has problems with structured bindings - it can not correclty use std::tuple_size
TOOLSET: msvc # clang-win has problems with structured bindings - it can not correctly use std::tuple_size
ADDRMD: 32,64
CXXSTD: 17,latest
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: msvc # clang-win has problems with structured bindings - it can not correclty use std::tuple_size
TOOLSET: msvc # clang-win has problems with structured bindings - it can not correctly use std::tuple_size
ADDRMD: 32,64
CXXSTD: 17,latest
CXXFLAGS: /permissive-
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: msvc # clang-win has problems with structured bindings - it can not correclty use std::tuple_size
TOOLSET: msvc # clang-win has problems with structured bindings - it can not correctly use std::tuple_size
ADDRMD: 32,64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\cygwin\bin;

View File

@@ -0,0 +1,21 @@
# Copyright (c) 2016-2026 Antony Polukhin
# Distributed under the Boost Software License, Version 1.0.
# See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt
cmake_minimum_required(VERSION 3.5...4.0)
project(pfr_subdir_test LANGUAGES CXX)
add_subdirectory(../../../assert boostorg/assert)
add_subdirectory(../../../container_hash boostorg/container_hash)
add_subdirectory(../../../core boostorg/core)
add_subdirectory(../../../config boostorg/config)
add_subdirectory(../../../detail boostorg/detail)
add_subdirectory(../../../describe boostorg/describe)
add_subdirectory(../../../integer boostorg/integer)
add_subdirectory(../../../mp11 boostorg/mp11)
add_subdirectory(../../../static_assert boostorg/static_assert)
add_subdirectory(../../../throw_exception boostorg/throw_exception)
add_subdirectory(../../../type_traits boostorg/type_traits)
add_subdirectory(../../ boostorg/pfr)

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -14,6 +14,7 @@
int main() {
std::cout << "Platform info:" << '\n'
<< "BOOST_PFR_USE_CPP17 == " << BOOST_PFR_USE_CPP17 << '\n'
<< "BOOST_PFR_USE_CPP26 == " << BOOST_PFR_USE_CPP26 << '\n'
<< "BOOST_PFR_USE_LOOPHOLE == " << BOOST_PFR_USE_LOOPHOLE << '\n'
<< "BOOST_PFR_USE_STD_MAKE_INTEGRAL_SEQUENCE == " << BOOST_PFR_USE_STD_MAKE_INTEGRAL_SEQUENCE << '\n'
<< "BOOST_PFR_HAS_GUARANTEED_COPY_ELISION == " << BOOST_PFR_HAS_GUARANTEED_COPY_ELISION << '\n'

View File

@@ -1,4 +1,4 @@
# Copyright (C) 2016-2025 Antony Polukhin.
# Copyright (C) 2016-2026 Antony Polukhin.
#
# Use, modification and distribution is subject to the Boost Software License,
# Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -23,7 +23,7 @@ project
[ requires cxx14_constexpr ]
;
########## BEGIN of helpers to detect Loophole trick support
########## BEGIN of helpers to detect Loophole and variadic structured binding support
actions mp_simple_run_action
{
@@ -42,6 +42,9 @@ rule mp-run-simple ( sources + : args * : input-files * : requirements * : targe
mp-run-simple loophole_detection.cpp : : : : compiler_supports_loophole ;
explicit compiler_supports_loophole ;
mp-run-simple variadic_structured_binding_detection.cpp : : : : compiler_supports_vsb ;
explicit compiler_supports_vsb ;
########## END of helpers to detect Loophole trick support
@@ -49,10 +52,14 @@ local DISABLE_ON_MSVC = ; #<toolset>msvc:<build>no ;
local REQUIRE_LOOPHOLE =
[ check-target-builds ../core//compiler_supports_loophole : : <build>no ]
;
local REQUIRE_VSB =
[ check-target-builds ../core//compiler_supports_vsb : : <build>no ]
;
local STRUCTURED_BINDING_ENGINE = <define>BOOST_PFR_USE_LOOPHOLE=0 <define>BOOST_PFR_USE_CPP17=1 [ requires cxx17_structured_bindings ] ;
local LOOPHOLE_ENGINE = <define>BOOST_PFR_USE_LOOPHOLE=1 <define>BOOST_PFR_USE_CPP17=0 $(REQUIRE_LOOPHOLE) ;
local CLASSIC_ENGINE = <define>BOOST_PFR_USE_LOOPHOLE=0 <define>BOOST_PFR_USE_CPP17=0 $(DISABLE_ON_MSVC) ;
local VARIADIC_STRUCTURED_BINDING_ENGINE = <define>BOOST_PFR_USE_LOOPHOLE=0 <define>BOOST_PFR_USE_CPP17=0 <define>BOOST_PFR_USE_CPP26=1 $(REQUIRE_VSB) ;
local STRUCTURED_BINDING_ENGINE = <define>BOOST_PFR_USE_LOOPHOLE=0 <define>BOOST_PFR_USE_CPP17=1 <define>BOOST_PFR_USE_CPP26=0 [ requires cxx17_structured_bindings ] ;
local LOOPHOLE_ENGINE = <define>BOOST_PFR_USE_LOOPHOLE=1 <define>BOOST_PFR_USE_CPP17=0 <define>BOOST_PFR_USE_CPP26=0 $(REQUIRE_LOOPHOLE) ;
local CLASSIC_ENGINE = <define>BOOST_PFR_USE_LOOPHOLE=0 <define>BOOST_PFR_USE_CPP17=0 <define>BOOST_PFR_USE_CPP26=0 $(DISABLE_ON_MSVC) ;
test-suite pfr_tests
:
@@ -109,6 +116,7 @@ local BLACKLIST_TESTS_FOR_CLASSIC =
for local source_file in [ glob ./run/*.cpp ] [ glob ../../example/*.cpp ]
{
local target_name = $(source_file[1]:B) ;
pfr_tests += [ run $(source_file) : : : $(VARIADIC_STRUCTURED_BINDING_ENGINE) : $(target_name)_vsb ] ;
pfr_tests += [ run $(source_file) : : : $(STRUCTURED_BINDING_ENGINE) : $(target_name)_sb ] ;
if ! $(target_name) in $(BLACKLIST_TESTS_FOR_LOOPHOLE)

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2023-2025 Antony Polukhin
// Copyright (c) 2023-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2023-2025 Antony Polukhin
// Copyright (c) 2023-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2018-2025 Antony Polukhin
// Copyright (c) 2018-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -1,5 +1,5 @@
// Copyright (c) 2021 Denis Mikhailov
// Copyright (c) 2021 Antony Polukhin
// Copyright (c) 2021-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2021 Antony Polukhin
// Copyright (c) 2021-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2018-2025 Antony Polukhin
// Copyright (c) 2018-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2018-2025 Antony Polukhin
// Copyright (c) 2018-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2018-2025 Antony Polukhin
// Copyright (c) 2018-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2018-2025 Antony Polukhin
// Copyright (c) 2018-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2020-2025 Antony Polukhin
// Copyright (c) 2020-2026 Antony Polukhin
// Copyright (c) 2020 Richard Hodges
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2018-2025 Antony Polukhin
// Copyright (c) 2018-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2018-2025 Antony Polukhin
// Copyright (c) 2018-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2020-2025 Antony Polukhin
// Copyright (c) 2020-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2018-2025 Antony Polukhin
// Copyright (c) 2018-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -0,0 +1,37 @@
// Copyright (c) 2025-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Test from https://github.com/boostorg/pfr/issues/126
#include <boost/pfr.hpp>
struct NoCopy {
NoCopy() = default;
NoCopy(NoCopy const&) = delete;
NoCopy(NoCopy&&) = delete;
NoCopy& operator=(NoCopy&&) = delete;
NoCopy& operator=(NoCopy const&) = delete;
};
struct Group {
NoCopy m;
NoCopy m2;
NoCopy m3;
NoCopy m4;
};
Group ReturnGroup() { return {};}
int main()
{
#ifdef __cpp_lib_is_aggregate
static_assert(std::is_aggregate_v<Group>, "Group is totally an aggregate");
#endif
static_assert(BOOST_PFR_HAS_GUARANTEED_COPY_ELISION, "Compiler implements mandatory copy elision");
Group aggregate_init_test{{}, {}, {}, {}};
Group elision_test = ReturnGroup();
return boost::pfr::tuple_size_v<Group>;
}

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2023-2025 Antony Polukhin
// Copyright (c) 2023-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2020-2025 Antony Polukhin
// Copyright (c) 2020-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -1,5 +1,5 @@
// Copyright (c) 2019 Ilya Kiselev
// Copyright (c) 2019-2025 Antony Polukhin
// Copyright (c) 2019-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -13,7 +13,6 @@
#include <set>
#include <string>
#include <boost/config.hpp>
#include <boost/core/lightweight_test.hpp>
#ifdef __clang__

View File

@@ -24,7 +24,7 @@ struct A {
};
int main() {
#if BOOST_PFR_USE_CPP17
#if BOOST_PFR_USE_CPP17 && !BOOST_PFR_USE_CPP26 && !defined(BOOST_USE_MODULES) // TODO: fix for BOOST_USE_MODULES
const volatile int cv_value = 0;
volatile int v_value = 0;
const int c_value = 0;

View File

@@ -1,5 +1,5 @@
// Copyright (c) 2018 Adam Butcher, Antony Polukhin
// Copyright (c) 2019-2025 Antony Polukhin
// Copyright (c) 2019-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2018-2025 Antony Polukhin
// Copyright (c) 2018-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -13,6 +13,11 @@
#include <iostream>
#include <type_traits>
#if defined(BOOST_USE_MODULES) // TODO: fix for BOOST_USE_MODULES
int main() {}
#else
template <typename T>
class CfgAttrib {
public:
@@ -99,3 +104,5 @@ int main() {
boost::pfr::get<0>(aCfg); // also C1202
#endif
}
#endif

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2018-2025 Antony Polukhin
// Copyright (c) 2018-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -14,7 +14,7 @@
#include <set>
#include <string>
#include <boost/functional/hash.hpp>
#include <boost/container_hash/hash.hpp>
#include <unordered_set>
struct adl_hash {

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2020-2025 Antony Polukhin
// Copyright (c) 2020-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2020-2025 Antony Polukhin
// Copyright (c) 2020-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -6,8 +6,6 @@
#include <boost/pfr/core.hpp>
#include <boost/type_index.hpp>
#include <boost/core/lightweight_test.hpp>
namespace testing {
@@ -27,18 +25,16 @@ void test_get_in_anon_ns_const_field() {
anon x{{1}, {2}};
BOOST_TEST_EQ(boost::pfr::get<0>(x).data, 1);
auto x0_type = boost::typeindex::type_id_with_cvr<decltype(
boost::pfr::get<0>(x)
)>();
// Use runtime check to make sure that Loophole fails to compile structure_tie
BOOST_TEST_EQ(x0_type, boost::typeindex::type_id_with_cvr<other_anon&>());
static_assert(std::is_same<
decltype(boost::pfr::get<0>(x)),
other_anon&
>::value, "");
BOOST_TEST_EQ(boost::pfr::get<1>(x).data, 2);
auto x1_type = boost::typeindex::type_id_with_cvr<decltype(
boost::pfr::get<1>(x)
)>();
// Use runtime check to make sure that Loophole fails to compile structure_tie
BOOST_TEST_EQ(x1_type, boost::typeindex::type_id_with_cvr<const other_anon&>());
static_assert(std::is_same<
decltype(boost::pfr::get<1>(x)),
const other_anon&
>::value, "");
}
} // anonymous namespace
@@ -51,5 +47,3 @@ int main() {
return boost::report_errors();
}

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2018 Antony Polukhin
// Copyright (c) 2018-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2020-2025 Antony Polukhin
// Copyright (c) 2020-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -20,8 +20,17 @@ void test_get_rvalue() {
std::make_unique<int>(43),
};
// Some _MSC_VER are broken:
// boost/pfr/detail/fields_count.hpp(469): error C2338: static_assert failed:
// '====================> Boost.PFR: If there's no other failed static
// asserts then something went wrong. Please report this issue to the github
// along with the structure you're reflecting.'
//
// No known workaround
#if !defined(_MSC_VER) || _MSC_VER != 1944 || !(BOOST_PFR_USE_CPP17 || BOOST_PFR_USE_LOOPHOLE)
auto p = boost::pfr::get<0>(std::move(x));
BOOST_TEST_EQ(*p, 42);
#endif
}
int main() {

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2024 Antony Polukhin
// Copyright (c) 2024-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -9,11 +9,7 @@
#include <cstdint>
#if defined(__clang__)
# if SIZE_MAX > (1ULL << 32) - 1
# define ARRAY_MAX (SIZE_MAX >> 3)
# else
# define ARRAY_MAX SIZE_MAX
# endif
# define ARRAY_MAX INT_MAX
# define OBJECT_MAX SIZE_MAX
#elif defined(__GNUC__)
# define ARRAY_MAX INT_MAX

View File

@@ -7,6 +7,10 @@
#include <boost/pfr/traits.hpp>
#include <type_traits> // for std::true_type, std::false_type and std::is_aggregate
#if defined(BOOST_USE_MODULES) // TODO: fix for BOOST_USE_MODULES
int main() {}
#else
namespace boost { namespace pfr {
struct boost_fusion_tag;
struct boost_json_tag;
@@ -81,3 +85,5 @@ int main() {
#endif // #if BOOST_PFR_ENABLE_IMPLICIT_REFLECTION
}
#endif

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2018-2025 Antony Polukhin
// Copyright (c) 2018-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -9,6 +9,15 @@
#include <boost/pfr.hpp>
#include <boost/core/lightweight_test.hpp>
// Some _MSC_VER are broken:
// boost/pfr/detail/fields_count.hpp(469): error C2338: static_assert failed:
// '====================> Boost.PFR: If there's no other failed static
// asserts then something went wrong. Please report this issue to the github
// along with the structure you're reflecting.'
//
// No known workaround
#if !defined(_MSC_VER) || _MSC_VER != 1944 || !(BOOST_PFR_USE_CPP17 || BOOST_PFR_USE_LOOPHOLE)
struct Message {
std::unique_ptr<int> data;
};
@@ -35,3 +44,9 @@ int main() {
return boost::report_errors();
}
#else
int main() {
return boost::report_errors();
}
#endif

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2018-2025 Antony Polukhin
// Copyright (c) 2018-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -23,7 +23,7 @@ int main() {
// FIXME: https://github.com/boostorg/pfr/issues/131
#if defined(__clang__) && __cplusplus >= 202002L
# if BOOST_PFR_USE_LOOPHOLE == 0 && BOOST_PFR_USE_CPP17 == 0
# if BOOST_PFR_USE_LOOPHOLE == 0 && BOOST_PFR_USE_CPP17 == 0 && BOOST_PFR_USE_CPP26 == 0
# error This test should fail on classic engine
#endif

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2024 Antony Polukhin
// Copyright (c) 2024-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2016-2025 Antony Polukhin
// Copyright (c) 2016-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

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