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

Fix reflection of Standard Library containers in C++14 loophole (fixes #33)

This commit is contained in:
Antony Polukhin
2019-01-23 23:26:01 +03:00
parent 8e9ac75fd7
commit 6b03224636
3 changed files with 40 additions and 3 deletions

View File

@@ -68,7 +68,16 @@ template <class T> constexpr T& unsafe_declval_like() noexcept {
// The definitions of friend functions.
template <class T, class U, std::size_t N, bool B>
struct fn_def_lref {
friend auto loophole(tag<T,N>) { return boost::pfr::detail::unsafe_declval_like< std::remove_all_extents_t<U> >(); }
friend auto loophole(tag<T,N>) {
// Standard Library containers do not SFINAE on invalid copy constructor. Because of that std::vector<std::unique_ptr<int>> reports that it is copyable,
// which leads to an instantiation error at this place.
//
// To workaround the issue, we check that the type U is movable, and move it in that case.
using no_extents_t = std::remove_all_extents_t<U>;
return static_cast< std::conditional_t<std::is_move_constructible<no_extents_t>::value, no_extents_t&&, no_extents_t&> >(
boost::pfr::detail::unsafe_declval_like<no_extents_t>()
);
}
};
template <class T, class U, std::size_t N, bool B>
struct fn_def_rref {

View File

@@ -139,8 +139,9 @@ test-suite pfr
[ run precise/error_pfr_c1202.cpp : : : $(CLASSIC_PREC_DEF) : precise_c1202_issue21 ]
[ compile-fail precise/non_aggregate.cpp : $(CLASSIC_PREC_DEF) : precise_non_aggregate ]
# This test may compile of fail depending on C++ Standard version.
#[ compile-fail precise/issue30.cpp : : : $(CLASSIC_PREC_DEF) : precise_issue30 ]
# The following tests may compile of fail depending on C++ Standard version.
#[ compile-fail precise/issue30.cpp : $(CLASSIC_PREC_DEF) : precise_issue30 ]
#[ compile-fail precise/issue33.cpp : $(CLASSIC_PREC_DEF) : precise_issue33 ]
##### Loophole tests running precise and flat specific tests
@@ -161,6 +162,7 @@ test-suite pfr
[ run precise/get_non_default_constructible.cpp : : : $(LOOPHOLE_PREC_DEF) : precise_lh_get_non_default_constructible ]
[ run precise/error_pfr_c1202.cpp : : : $(LOOPHOLE_PREC_DEF) : precise_lh_c1202_issue21 ]
[ run precise/issue30.cpp : : : $(LOOPHOLE_PREC_DEF) : precise_lh_issue30 ]
[ run precise/issue33.cpp : : : $(LOOPHOLE_PREC_DEF) : precise_lh_issue33 ]
[ compile-fail precise/non_aggregate.cpp : $(LOOPHOLE_PREC_DEF) : precise_lh_non_aggregate ]

26
test/precise/issue33.cpp Normal file
View File

@@ -0,0 +1,26 @@
// Copyright (c) 2018-2019 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 case for https://github.com/apolukhin/magic_get/issues/33
#include <iostream>
#include <vector>
#include <boost/pfr.hpp>
#include <boost/core/lightweight_test.hpp>
struct TestStruct {
std::vector<std::unique_ptr<int>> vec;
};
int main() {
TestStruct temp;
temp.vec.emplace_back();
boost::pfr::for_each_field(temp, [](const auto& value) {
BOOST_TEST_EQ(value.size(), 1);
});
return boost::report_errors();
}