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:
@@ -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 {
|
||||
|
||||
@@ -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
26
test/precise/issue33.cpp
Normal 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();
|
||||
}
|
||||
Reference in New Issue
Block a user