mirror of
https://github.com/boostorg/pfr.git
synced 2026-01-19 04:22:13 +00:00
Allow reflection of aggregates with non movable fields if guaranteed copy elision is on
This commit is contained in:
@@ -41,8 +41,8 @@ struct ubiq_lref_constructor {
|
||||
///////////////////// Structure that can be converted to rvalue reference to anything
|
||||
struct ubiq_rref_constructor {
|
||||
std::size_t ignore;
|
||||
template <class Type> /*constexpr*/ operator Type&&() const && noexcept { // Allows initialization of rvalue reference fields and move-only types
|
||||
return detail::unsafe_declval<Type&&>();
|
||||
template <class Type> /*constexpr*/ operator Type() const && noexcept { // Allows initialization of rvalue reference fields and move-only types
|
||||
return detail::unsafe_declval<Type>();
|
||||
};
|
||||
};
|
||||
|
||||
@@ -210,6 +210,7 @@ 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
|
||||
static_assert(
|
||||
std::is_copy_constructible<std::remove_all_extents_t<type>>::value || (
|
||||
std::is_move_constructible<std::remove_all_extents_t<type>>::value
|
||||
@@ -217,6 +218,7 @@ constexpr std::size_t fields_count() noexcept {
|
||||
),
|
||||
"====================> 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
|
||||
|
||||
static_assert(
|
||||
!std::is_polymorphic<type>::value,
|
||||
|
||||
45
test/run/non_movable.cpp
Normal file
45
test/run/non_movable.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
// Copyright (c) 2018-2021 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)
|
||||
|
||||
#include <boost/pfr/tuple_size.hpp>
|
||||
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
struct X {
|
||||
X() = default;
|
||||
X(X&&) = delete;
|
||||
X(const X&) = delete;
|
||||
|
||||
X& operator=(X&&) = delete;
|
||||
X& operator=(const X&) = delete;
|
||||
};
|
||||
struct S { X x0; X x1; int x2; X x3; };
|
||||
|
||||
int main() {
|
||||
#ifdef __cpp_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; };
|
||||
static_assert(boost::pfr::tuple_size_v<S5_0> == 5, "");
|
||||
|
||||
struct S5_1 { X x0; int x1; int x2; int x3; int x4; };
|
||||
static_assert(boost::pfr::tuple_size_v<S5_1> == 5, "");
|
||||
|
||||
struct S5_2 { int x0; int x1; X x2; int x3; int x4; };
|
||||
static_assert(boost::pfr::tuple_size_v<S5_2> == 5, "");
|
||||
|
||||
struct S5_3 { int x0; int x1; X x2; int x3; X x4; };
|
||||
static_assert(boost::pfr::tuple_size_v<S5_3> == 5, "");
|
||||
|
||||
struct S5_4 { X x0; X x1; X x2; X x3; X x4; };
|
||||
static_assert(boost::pfr::tuple_size_v<S5_4> == 5, "");
|
||||
|
||||
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
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user