mirror of
https://github.com/boostorg/pfr.git
synced 2026-01-19 04:22:13 +00:00
Initial support for C++20 modules (#177)
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
# Generated by `boostdep --cmake pfr`
|
||||
# Copyright 2020 Peter Dimov
|
||||
# Copyright (c) 2016-2024 Antony Polukhin
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
@@ -12,9 +13,11 @@ add_library(Boost::pfr ALIAS boost_pfr)
|
||||
|
||||
target_include_directories(boost_pfr INTERFACE include)
|
||||
|
||||
if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt")
|
||||
|
||||
add_subdirectory(test)
|
||||
|
||||
if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.28.0" AND BUILD_MODULE)
|
||||
add_subdirectory(module)
|
||||
endif()
|
||||
|
||||
if (BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt")
|
||||
add_subdirectory(test)
|
||||
endif()
|
||||
|
||||
|
||||
34
doc/pfr.qbk
34
doc/pfr.qbk
@@ -549,6 +549,40 @@ parameters provided to `BOOST_PFR_CORE_NAME_PARSING` macro [*and] the initial ou
|
||||
|
||||
[endsect]
|
||||
|
||||
[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]
|
||||
|
||||
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:
|
||||
|
||||
[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.
|
||||
|
||||
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.
|
||||
|
||||
For manual module build the following commands could be used for clang compiler:
|
||||
|
||||
```
|
||||
cd pfr/module
|
||||
clang++ -I ../include -std=c++20 --precompile -x c++-module 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
|
||||
```
|
||||
|
||||
[endsect]
|
||||
|
||||
[section How it works]
|
||||
|
||||
[h2 Fields count detection and getting references to members]
|
||||
|
||||
@@ -145,4 +145,12 @@
|
||||
|
||||
#undef BOOST_PFR_NOT_SUPPORTED
|
||||
|
||||
#ifndef BOOST_PFR_BEGIN_MODULE_EXPORT
|
||||
# define BOOST_PFR_BEGIN_MODULE_EXPORT
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_PFR_END_MODULE_EXPORT
|
||||
# define BOOST_PFR_END_MODULE_EXPORT
|
||||
#endif
|
||||
|
||||
#endif // BOOST_PFR_CONFIG_HPP
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
|
||||
namespace boost { namespace pfr {
|
||||
|
||||
BOOST_PFR_BEGIN_MODULE_EXPORT
|
||||
|
||||
/// \brief Returns reference or const reference to a field with index `I` in \aggregate `val`.
|
||||
/// Overload taking the type `U` returns reference or const reference to a field
|
||||
/// with provided type `U` in \aggregate `val` if there's only one field of such type in `val`.
|
||||
@@ -260,6 +262,8 @@ constexpr detail::tie_from_structure_tuple<Elements...> tie_from_structure(Eleme
|
||||
return detail::tie_from_structure_tuple<Elements...>(args...);
|
||||
}
|
||||
|
||||
BOOST_PFR_END_MODULE_EXPORT
|
||||
|
||||
}} // namespace boost::pfr
|
||||
|
||||
#endif // BOOST_PFR_CORE_HPP
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
|
||||
namespace boost { namespace pfr {
|
||||
|
||||
BOOST_PFR_BEGIN_MODULE_EXPORT
|
||||
|
||||
/// \brief Returns name of a field with index `I` in \aggregate `T`.
|
||||
///
|
||||
/// \b Example:
|
||||
@@ -82,6 +84,8 @@ names_as_array() noexcept {
|
||||
);
|
||||
}
|
||||
|
||||
BOOST_PFR_END_MODULE_EXPORT
|
||||
|
||||
}} // namespace boost::pfr
|
||||
|
||||
#endif // BOOST_PFR_CORE_NAME_HPP
|
||||
|
||||
@@ -9,8 +9,12 @@
|
||||
|
||||
#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>
|
||||
|
||||
@@ -24,8 +24,12 @@
|
||||
|
||||
#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>
|
||||
|
||||
@@ -21,7 +21,12 @@
|
||||
|
||||
#include <boost/pfr/detail/sequence_tuple.hpp>
|
||||
#include <boost/pfr/detail/size_t_.hpp>
|
||||
|
||||
#ifdef BOOST_PFR_HAS_STD_MODULE
|
||||
import std;
|
||||
#else
|
||||
#include <type_traits> // for std::conditional_t, std::is_reference
|
||||
#endif
|
||||
|
||||
namespace boost { namespace pfr { namespace detail {
|
||||
|
||||
|
||||
@@ -19,10 +19,15 @@
|
||||
#include <boost/pfr/detail/fields_count.hpp>
|
||||
#include <boost/pfr/detail/stdarray.hpp>
|
||||
#include <boost/pfr/detail/fake_object.hpp>
|
||||
|
||||
#ifdef BOOST_PFR_HAS_STD_MODULE
|
||||
import std;
|
||||
#else
|
||||
#include <type_traits>
|
||||
#include <string_view>
|
||||
#include <array>
|
||||
#include <memory> // for std::addressof
|
||||
#endif
|
||||
|
||||
namespace boost { namespace pfr { namespace detail {
|
||||
|
||||
|
||||
@@ -9,8 +9,12 @@
|
||||
|
||||
#include <boost/pfr/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_PFR_HAS_STD_MODULE
|
||||
import std;
|
||||
#else
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#endif
|
||||
|
||||
namespace boost { namespace pfr { namespace detail {
|
||||
///////////////////// `value` is true if Detector<Tleft, Tright> does not compile (SFINAE)
|
||||
|
||||
@@ -12,9 +12,13 @@
|
||||
#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 <type_traits>
|
||||
#include <utility> // metaprogramming stuff
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
# pragma clang diagnostic push
|
||||
|
||||
@@ -9,7 +9,11 @@
|
||||
|
||||
#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>
|
||||
|
||||
@@ -9,8 +9,12 @@
|
||||
|
||||
#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>
|
||||
|
||||
|
||||
@@ -10,6 +10,10 @@
|
||||
#include <boost/pfr/detail/config.hpp>
|
||||
|
||||
#include <boost/pfr/detail/sequence_tuple.hpp>
|
||||
|
||||
#ifdef BOOST_PFR_HAS_STD_MODULE
|
||||
import std;
|
||||
#else
|
||||
#include <iosfwd> // stream operators
|
||||
#include <iomanip>
|
||||
|
||||
@@ -19,6 +23,8 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
namespace boost { namespace pfr { namespace detail {
|
||||
|
||||
inline auto quoted_helper(const std::string& s) noexcept {
|
||||
|
||||
@@ -9,7 +9,12 @@
|
||||
|
||||
#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>
|
||||
|
||||
@@ -10,9 +10,13 @@
|
||||
|
||||
#include <boost/pfr/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_PFR_HAS_STD_MODULE
|
||||
import std;
|
||||
#else
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <cstddef>
|
||||
#endif
|
||||
|
||||
namespace boost { namespace pfr { namespace detail {
|
||||
|
||||
|
||||
@@ -10,9 +10,14 @@
|
||||
|
||||
#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>
|
||||
|
||||
@@ -10,7 +10,11 @@
|
||||
#include <boost/pfr/detail/config.hpp>
|
||||
#include <boost/pfr/traits_fwd.hpp>
|
||||
|
||||
#ifdef BOOST_PFR_HAS_STD_MODULE
|
||||
import std;
|
||||
#else
|
||||
#include <type_traits> // for std::is_aggregate
|
||||
#endif
|
||||
|
||||
namespace boost { namespace pfr { namespace detail {
|
||||
|
||||
|
||||
@@ -7,8 +7,12 @@
|
||||
#define BOOST_PFR_DETAIL_RVALUE_T_HPP
|
||||
#pragma once
|
||||
|
||||
#ifdef BOOST_PFR_HAS_STD_MODULE
|
||||
import std;
|
||||
#else
|
||||
#include <type_traits>
|
||||
#include <utility> // std::enable_if_t
|
||||
#endif
|
||||
|
||||
// This header provides aliases rvalue_t and lvalue_t.
|
||||
//
|
||||
|
||||
@@ -10,8 +10,12 @@
|
||||
#include <boost/pfr/detail/config.hpp>
|
||||
#include <boost/pfr/detail/make_integer_sequence.hpp>
|
||||
|
||||
#ifdef BOOST_PFR_HAS_STD_MODULE
|
||||
import std;
|
||||
#else
|
||||
#include <utility> // metaprogramming stuff
|
||||
#include <cstddef> // std::size_t
|
||||
#endif
|
||||
|
||||
///////////////////// Tuple that holds its values in the supplied order
|
||||
namespace boost { namespace pfr { namespace detail { namespace sequence_tuple {
|
||||
|
||||
@@ -9,7 +9,11 @@
|
||||
|
||||
#include <boost/pfr/detail/config.hpp>
|
||||
|
||||
#include <cstddef> // metaprogramming stuff
|
||||
#ifdef BOOST_PFR_HAS_STD_MODULE
|
||||
import std;
|
||||
#else
|
||||
#include <cstddef>
|
||||
#endif
|
||||
|
||||
namespace boost { namespace pfr { namespace detail {
|
||||
|
||||
|
||||
@@ -9,10 +9,14 @@
|
||||
|
||||
#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>
|
||||
|
||||
|
||||
@@ -9,8 +9,12 @@
|
||||
|
||||
#include <boost/pfr/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_PFR_HAS_STD_MODULE
|
||||
import std;
|
||||
#else
|
||||
#include <utility> // metaprogramming stuff
|
||||
#include <tuple>
|
||||
#endif
|
||||
|
||||
#include <boost/pfr/detail/sequence_tuple.hpp>
|
||||
|
||||
|
||||
@@ -16,7 +16,11 @@
|
||||
#include <boost/pfr/tuple_size.hpp>
|
||||
#include <boost/pfr/detail/make_integer_sequence.hpp>
|
||||
|
||||
#ifdef BOOST_PFR_HAS_STD_MODULE
|
||||
import std;
|
||||
#else
|
||||
#include <tuple>
|
||||
#endif
|
||||
|
||||
namespace boost { namespace pfr { namespace detail {
|
||||
|
||||
|
||||
@@ -9,7 +9,11 @@
|
||||
|
||||
#include <boost/pfr/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_PFR_HAS_STD_MODULE
|
||||
import std;
|
||||
#else
|
||||
#include <type_traits>
|
||||
#endif
|
||||
|
||||
namespace boost { namespace pfr { namespace detail {
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
/// \b Synopsis:
|
||||
namespace boost { namespace pfr {
|
||||
|
||||
BOOST_PFR_BEGIN_MODULE_EXPORT
|
||||
|
||||
///////////////////// Comparisons
|
||||
|
||||
/// \brief std::equal_to like comparator that returns \forcedlink{eq}(x, y)
|
||||
@@ -216,6 +218,8 @@ template <class T> struct hash {
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_PFR_END_MODULE_EXPORT
|
||||
|
||||
}} // namespace boost::pfr
|
||||
|
||||
#endif // BOOST_PFR_FUNCTORS_HPP
|
||||
|
||||
@@ -67,6 +67,8 @@ struct io_impl {
|
||||
T value;
|
||||
};
|
||||
|
||||
BOOST_PFR_BEGIN_MODULE_EXPORT
|
||||
|
||||
template <class Char, class Traits, class T>
|
||||
enable_not_ostreamable_t<std::basic_ostream<Char, Traits>, T> operator<<(std::basic_ostream<Char, Traits>& out, io_impl<T>&& x) {
|
||||
return out << boost::pfr::io_fields(std::forward<T>(x.value));
|
||||
@@ -87,8 +89,12 @@ enable_istreamable_t<std::basic_istream<Char, Traits>, T> operator>>(std::basic_
|
||||
return in >> x.value;
|
||||
}
|
||||
|
||||
BOOST_PFR_END_MODULE_EXPORT
|
||||
|
||||
} // namespace detail
|
||||
|
||||
BOOST_PFR_BEGIN_MODULE_EXPORT
|
||||
|
||||
/// IO manipulator to read/write \aggregate `value` using its IO stream operators or using \forcedlink{io_fields} if operators are not available.
|
||||
///
|
||||
/// \b Example:
|
||||
@@ -108,6 +114,8 @@ auto io(T&& value) noexcept {
|
||||
return detail::io_impl<T>{std::forward<T>(value)};
|
||||
}
|
||||
|
||||
BOOST_PFR_END_MODULE_EXPORT
|
||||
|
||||
}} // namespace boost::pfr
|
||||
|
||||
#endif // BOOST_PFR_IO_HPP
|
||||
|
||||
@@ -118,6 +118,8 @@ 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.");
|
||||
@@ -130,8 +132,12 @@ std::basic_istream<Char, Traits>& operator>>(std::basic_istream<Char, Traits>& i
|
||||
return in;
|
||||
}
|
||||
|
||||
BOOST_PFR_END_MODULE_EXPORT
|
||||
|
||||
} // namespace detail
|
||||
|
||||
BOOST_PFR_BEGIN_MODULE_EXPORT
|
||||
|
||||
/// IO manipulator to read/write \aggregate `value` field-by-field.
|
||||
///
|
||||
/// \b Example:
|
||||
@@ -159,6 +165,8 @@ auto io_fields(T&& value) noexcept {
|
||||
return detail::io_fields_impl<T>{std::forward<T>(value)};
|
||||
}
|
||||
|
||||
BOOST_PFR_END_MODULE_EXPORT
|
||||
|
||||
}} // namespace boost::pfr
|
||||
|
||||
#endif // BOOST_PFR_IO_FIELDS_HPP
|
||||
|
||||
@@ -77,6 +77,7 @@ namespace detail {
|
||||
>;
|
||||
} // namespace detail
|
||||
|
||||
BOOST_PFR_BEGIN_MODULE_EXPORT
|
||||
|
||||
/// \brief Compares lhs and rhs for equality using their own comparison and conversion operators; if no operators available returns \forcedlink{eq_fields}(lhs, rhs).
|
||||
///
|
||||
@@ -182,6 +183,8 @@ constexpr detail::enable_hashable_t<T> hash_value(const T& value) {
|
||||
return std::hash<T>{}(value);
|
||||
}
|
||||
|
||||
BOOST_PFR_END_MODULE_EXPORT
|
||||
|
||||
}} // namespace boost::pfr
|
||||
|
||||
#endif // BOOST_PFR_OPS_HPP
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
/// \b Synopsis:
|
||||
namespace boost { namespace pfr {
|
||||
|
||||
BOOST_PFR_BEGIN_MODULE_EXPORT
|
||||
|
||||
/// Does a field-by-field equality comparison.
|
||||
///
|
||||
/// \returns `L == R && tuple_size_v<T> == tuple_size_v<U>`, where `L` and
|
||||
@@ -122,6 +124,9 @@ namespace boost { namespace pfr {
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOST_PFR_END_MODULE_EXPORT
|
||||
|
||||
}} // namespace boost::pfr
|
||||
|
||||
#endif // BOOST_PFR_OPS_HPP
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
namespace boost { namespace pfr {
|
||||
|
||||
BOOST_PFR_BEGIN_MODULE_EXPORT
|
||||
|
||||
/// Has a static const member variable `value` when it is known that type T can or can't be reflected using Boost.PFR; otherwise, there is no member variable.
|
||||
/// Every user may (and in some difficult cases - should) specialize is_reflectable on his own.
|
||||
///
|
||||
@@ -54,6 +56,8 @@ using is_implicitly_reflectable = std::integral_constant< bool, boost::pfr::deta
|
||||
template<class T, class WhatFor>
|
||||
constexpr bool is_implicitly_reflectable_v = is_implicitly_reflectable<T, WhatFor>::value;
|
||||
|
||||
BOOST_PFR_END_MODULE_EXPORT
|
||||
|
||||
}} // namespace boost::pfr
|
||||
|
||||
#endif // BOOST_PFR_TRAITS_HPP
|
||||
|
||||
@@ -11,9 +11,13 @@
|
||||
|
||||
namespace boost { namespace pfr {
|
||||
|
||||
BOOST_PFR_BEGIN_MODULE_EXPORT
|
||||
|
||||
template<class T, class WhatFor>
|
||||
struct is_reflectable;
|
||||
|
||||
BOOST_PFR_END_MODULE_EXPORT
|
||||
|
||||
}} // namespace boost::pfr
|
||||
|
||||
#endif // BOOST_PFR_DETAIL_TRAITS_FWD_HPP
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
/// \b Synopsis:
|
||||
namespace boost { namespace pfr {
|
||||
|
||||
BOOST_PFR_BEGIN_MODULE_EXPORT
|
||||
|
||||
/// Has a static const member variable `value` that contains fields count in a T.
|
||||
/// Works for any T that satisfies \aggregate.
|
||||
///
|
||||
@@ -43,6 +45,8 @@ using tuple_size = detail::size_t_< boost::pfr::detail::fields_count<T>() >;
|
||||
template <class T>
|
||||
constexpr std::size_t tuple_size_v = tuple_size<T>::value;
|
||||
|
||||
BOOST_PFR_END_MODULE_EXPORT
|
||||
|
||||
}} // namespace boost::pfr
|
||||
|
||||
#endif // BOOST_PFR_TUPLE_SIZE_HPP
|
||||
|
||||
@@ -38,7 +38,12 @@ PROLOGUE = """// Copyright (c) 2016-2024 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
|
||||
#include <type_traits> // for std::conditional_t, std::is_reference
|
||||
#endif
|
||||
|
||||
namespace boost { namespace pfr { namespace detail {
|
||||
|
||||
|
||||
37
module/CMakeLists.txt
Normal file
37
module/CMakeLists.txt
Normal file
@@ -0,0 +1,37 @@
|
||||
# Copyright (c) 2016-2024 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()
|
||||
44
module/pfr.cppm
Normal file
44
module/pfr.cppm
Normal file
@@ -0,0 +1,44 @@
|
||||
// Copyright (c) 2016-2024 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)
|
||||
|
||||
// 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 <array>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <variant>
|
||||
#endif
|
||||
|
||||
export module Boost.PFR;
|
||||
|
||||
#ifdef BOOST_PFR_HAS_STD_MODULE
|
||||
import std;
|
||||
#endif
|
||||
|
||||
#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
|
||||
31
module/usage_sample.cpp
Normal file
31
module/usage_sample.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) 2016-2024 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)
|
||||
|
||||
// To compile manually use a command like the folowing:
|
||||
// clang++ -std=c++20 -fmodule-file=pfr.pcm pfr.pcm usage_sample.cpp
|
||||
|
||||
//[pfr_module_example
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <string>
|
||||
|
||||
import Boost.PFR;
|
||||
|
||||
struct some_person {
|
||||
std::string name;
|
||||
unsigned birth_year;
|
||||
};
|
||||
|
||||
int main() {
|
||||
some_person val{"Edgar Allan Poe", 1809};
|
||||
|
||||
std::cout << boost::pfr::get<0>(val) // No macro!
|
||||
<< " was born in " << boost::pfr::get<1>(val); // Works with any aggregate!
|
||||
|
||||
std::cout << '\n' << boost::pfr::io(val); // Outputs: {"Edgar Allan Poe", 1809}
|
||||
std::cout << "\n." << boost::pfr::get_name<0, some_person>()
|
||||
<< '=' << val.name << '\n'; // Outputs: .name=Edgar Allan Poe
|
||||
}
|
||||
//]
|
||||
27
module/usage_test_mu1.cpp
Normal file
27
module/usage_test_mu1.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
// Copyright (c) 2016-2024 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)
|
||||
|
||||
// To compile manually use a command like the folowing:
|
||||
// clang++ -std=c++20 -fmodule-file=pfr.pcm pfr.pcm usage_sample.cpp
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/pfr.hpp>
|
||||
|
||||
struct some_person {
|
||||
std::string name;
|
||||
unsigned birth_year;
|
||||
};
|
||||
|
||||
void mu1_act() {
|
||||
some_person val{"Edgar Allan Poe", 1809};
|
||||
|
||||
std::cout << boost::pfr::get<0>(val) // No macro!
|
||||
<< " was born in " << boost::pfr::get<1>(val); // Works with any aggregate!
|
||||
|
||||
std::cout << '\n' << boost::pfr::io(val); // Outputs: {"Edgar Allan Poe", 1809}
|
||||
std::cout << "\n." << boost::pfr::get_name<0, some_person>()
|
||||
<< '=' << val.name << '\n'; // Outputs: .name=Edgar Allan Poe
|
||||
}
|
||||
32
module/usage_test_mu2.cpp
Normal file
32
module/usage_test_mu2.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
// Copyright (c) 2016-2024 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)
|
||||
|
||||
// To compile manually use a command like the folowing:
|
||||
// clang++ -std=c++20 -fmodule-file=pfr.pcm pfr.pcm usage_sample.cpp
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
import Boost.PFR;
|
||||
|
||||
struct some_person {
|
||||
std::string name;
|
||||
unsigned birth_year;
|
||||
};
|
||||
|
||||
void mu1_act();
|
||||
|
||||
int main() {
|
||||
mu1_act();
|
||||
|
||||
some_person val{"Joseph Brodsky", 1940};
|
||||
|
||||
std::cout << boost::pfr::get<0>(val) // No macro!
|
||||
<< " was born in " << boost::pfr::get<1>(val); // Works with any aggregate!
|
||||
|
||||
std::cout << '\n' << boost::pfr::io(val);
|
||||
std::cout << "\n." << boost::pfr::get_name<0, some_person>()
|
||||
<< '=' << val.name << '\n';
|
||||
}
|
||||
Reference in New Issue
Block a user