Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ jobs:
- toolset: clang-15
cxxstd: "03,11,14,17,20"
os: ubuntu-22.04
- toolset: clang-19
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
# - toolset: clang
# cxxstd: "03,11,14,17,2a"
# os: macos-10.15
Expand Down Expand Up @@ -87,6 +91,31 @@ jobs:
./b2 -d0 headers
./b2 variant=debug tools/inspect/build

- name: Run modules tests
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd strongly advise to add a job covering modules under MSVC, since it's much more restrictive than clang. You can have a look at my mp11/charconv proposal for some inspiration.

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 ..
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 ..
cmake --build .
ctest -V
cd ..
rm -rf build_module

- name: Run tests
run: |
cd ../boost-root
Expand Down Expand Up @@ -177,6 +206,37 @@ jobs:
cmd /c bootstrap
b2 -d0 headers

- 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 ..
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 ..
cmake --build .
ctest --no-tests=error -V
cd ..
rm -rf build_module

- name: Run tests
shell: cmd
run: |
Expand Down
42 changes: 34 additions & 8 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,46 @@
# 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)
add_library(Boost::pfr ALIAS boost_pfr)

target_include_directories(boost_pfr INTERFACE include)
if (BOOST_USE_MODULES)
add_library(boost_pfr)
target_sources(boost_pfr PUBLIC
FILE_SET modules_public TYPE CXX_MODULES FILES
${CMAKE_CURRENT_LIST_DIR}/modules/pfr.cppm
)

if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.28.0" AND BUILD_MODULE)
add_subdirectory(module)
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 awailable")
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)

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()

20 changes: 10 additions & 10 deletions doc/pfr.qbk
Original file line number Diff line number Diff line change
Expand Up @@ -554,22 +554,22 @@ 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]
[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 implicilty 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). ]

If not using CMake, then the module could be build manually from the `module/pfr.cppm` file.

For manual module build the following commands could be used for clang compiler:

Expand Down
18 changes: 13 additions & 5 deletions include/boost/pfr/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
#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)
#elif defined(BOOST_USE_MODULES)
#include <version>
#endif

/// \file boost/pfr/config.hpp
Expand Down Expand Up @@ -70,8 +72,10 @@
#endif

#ifndef BOOST_PFR_USE_STD_MAKE_INTEGRAL_SEQUENCE
# if defined(BOOST_USE_MODULES)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe you can attempt to include <version> to get __GLIBCXX__? Although that makes the include heavier.

# 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
Expand Down Expand Up @@ -145,12 +149,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
# define BOOST_PFR_END_MODULE_EXPORT
#endif

#ifndef BOOST_PFR_END_MODULE_EXPORT
# define BOOST_PFR_END_MODULE_EXPORT
#if defined(BOOST_USE_MODULES) && !defined(BOOST_PFR_INTERFACE_UNIT)
import boost.pfr;
#endif

#endif // BOOST_PFR_CONFIG_HPP
10 changes: 8 additions & 2 deletions include/boost/pfr/core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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.
Expand Down Expand Up @@ -249,4 +253,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
10 changes: 8 additions & 2 deletions include/boost/pfr/core_name.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
///
Expand Down Expand Up @@ -110,4 +114,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
12 changes: 5 additions & 7 deletions include/boost/pfr/detail/core14_classic.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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"
Expand Down
10 changes: 3 additions & 7 deletions include/boost/pfr/detail/core14_loophole.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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
Expand Down
4 changes: 1 addition & 3 deletions include/boost/pfr/detail/core17_generated.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
4 changes: 1 addition & 3 deletions include/boost/pfr/detail/core_name20_static.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
4 changes: 1 addition & 3 deletions include/boost/pfr/detail/detectors.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 4 additions & 7 deletions include/boost/pfr/detail/fields_count.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -218,13 +215,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;
}

///////////////////// Fields count binary search.
Expand Down
Loading