Skip to content

Commit

Permalink
Workaround MSVC issue for the guaranteed copy elision
Browse files Browse the repository at this point in the history
  • Loading branch information
apolukhin committed Mar 26, 2021
1 parent 3b6d3a4 commit f33c357
Show file tree
Hide file tree
Showing 5 changed files with 14 additions and 4 deletions.
1 change: 1 addition & 0 deletions doc/pfr.qbk
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,7 @@ By default Boost.PFR [*auto-detects your compiler abilities] and automatically d
[[*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. ]]
[[*BOOST_PFR_HAS_GUARANTEED_COPY_ELISION*] [Define to `0` if your compiler does not implement C++17 guaranteed copy elision properly and fails to reflect aggregates with non-movable fields. Define to `1` to override Boost.PFR detection logic. ]]
]


Expand Down
8 changes: 8 additions & 0 deletions include/boost/pfr/detail/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@
# endif
#endif

#ifndef BOOST_PFR_HAS_GUARANTEED_COPY_ELISION
# if defined(__cpp_guaranteed_copy_elision) && (!defined(_MSC_VER) || _MSC_VER > 1928)
# define BOOST_PFR_HAS_GUARANTEED_COPY_ELISION 1
# else
# define BOOST_PFR_HAS_GUARANTEED_COPY_ELISION 0
# endif
#endif

#if defined(__has_cpp_attribute)
# if __has_cpp_attribute(maybe_unused)
# define BOOST_PFR_MAYBE_UNUSED [[maybe_unused]]
Expand Down
4 changes: 2 additions & 2 deletions include/boost/pfr/detail/fields_count.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,15 +210,15 @@ constexpr std::size_t fields_count() noexcept {
"====================> Boost.PFR: Attempt to get fields count on a reference. This is not allowed because that could hide an issue and different library users expect different behavior in that case."
);

#ifndef __cpp_guaranteed_copy_elision
#if !BOOST_PFR_HAS_GUARANTEED_COPY_ELISION
static_assert(
std::is_copy_constructible<std::remove_all_extents_t<type>>::value || (
std::is_move_constructible<std::remove_all_extents_t<type>>::value
&& std::is_move_assignable<std::remove_all_extents_t<type>>::value
),
"====================> Boost.PFR: Type and each field in the type must be copy constructible (or move constructible and move assignable)."
);
#endif // #ifndef __cpp_guaranteed_copy_elision
#endif // #if !BOOST_PFR_HAS_GUARANTEED_COPY_ELISION

static_assert(
!std::is_polymorphic<type>::value,
Expand Down
1 change: 1 addition & 0 deletions test/print_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ int main() {
<< "BOOST_PFR_USE_CPP17 == " << BOOST_PFR_USE_CPP17 << '\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'
<< "__cplusplus == " << __cplusplus << '\n'
#ifdef __cpp_structured_bindings
<< "__cpp_structured_bindings == " << __cpp_structured_bindings << '\n'
Expand Down
4 changes: 2 additions & 2 deletions test/run/non_movable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ struct X {
struct S { X x0; X x1; int x2; X x3; };

int main() {
#ifdef __cpp_guaranteed_copy_elision
#if BOOST_PFR_HAS_GUARANTEED_COPY_ELISION
static_assert(boost::pfr::tuple_size_v<S> == 4, "");

struct S5_0 { int x0; int x1; int x2; int x3; X x4; };
Expand All @@ -38,7 +38,7 @@ int main() {

struct S6 { X x0; X x1; X x2; X x3; X x4; X x5;};
static_assert(boost::pfr::tuple_size_v<S6> == 6, "");
#endif // #ifdef __cpp_guaranteed_copy_elision
#endif // #if BOOST_PFR_HAS_GUARANTEED_COPY_ELISION

return boost::report_errors();
}
Expand Down

0 comments on commit f33c357

Please sign in to comment.