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

Allow throwing exceptions from pfr::structure_to_tuple (fixes #155) … (#160)

…and fix some warnings
This commit is contained in:
Antony Polukhin
2024-02-15 10:10:46 +03:00
committed by GitHub
parent 4a973c5eb4
commit 8f3b819b1e
5 changed files with 108 additions and 3 deletions

View File

@@ -106,7 +106,7 @@ void test_examples() {
//]
}
#if BOOST_PFR_CORE_NAME_ENABLED
#if BOOST_PFR_CORE_NAME_ENABLED && BOOST_PFR_USE_CPP17
{
//[pfr_quick_examples_get_name
// Get name of field by index

View File

@@ -140,7 +140,7 @@ using tuple_element_t = typename tuple_element<I, T>::type;
/// assert(get<0>(t) == 10);
/// \endcode
template <class T>
constexpr auto structure_to_tuple(const T& val) noexcept {
constexpr auto structure_to_tuple(const T& val) {
return detail::make_stdtuple_from_tietuple(
detail::tie_as_tuple(val),
detail::make_index_sequence< tuple_size_v<T> >()

View File

@@ -14,6 +14,15 @@
#include <boost/pfr/detail/config.hpp>
#ifdef __clang__
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wundefined-internal"
# pragma clang diagnostic ignored "-Wundefined-var-template"
#elif defined(__GNUC__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wundefined-var-template"
#endif
namespace boost { namespace pfr { namespace detail {
// This class has external linkage while T has not sure.
@@ -39,5 +48,10 @@ constexpr const T& fake_object() noexcept {
}}} // namespace boost::pfr::detail
#ifdef __clang__
# pragma clang diagnostic push
#elif defined(__GNUC__)
# pragma GCC diagnostic pop
#endif
#endif // BOOST_PFR_DETAIL_FAKE_OBJECT_HPP

View File

@@ -17,7 +17,7 @@
namespace boost { namespace pfr { namespace detail {
template <class T, std::size_t... I>
constexpr auto make_stdtuple_from_tietuple(const T& t, std::index_sequence<I...>) noexcept {
constexpr auto make_stdtuple_from_tietuple(const T& t, std::index_sequence<I...>) {
return std::make_tuple(
boost::pfr::detail::sequence_tuple::get<I>(t)...
);

View File

@@ -0,0 +1,91 @@
// Copyright (c) 2020-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)
#include <boost/core/lightweight_test.hpp>
#include <boost/pfr/core.hpp>
namespace some {
struct struct1{ int i; };
struct struct2{ int i; short s; };
}
void test_single_field() {
{
some::struct1 s{1};
auto s_tuple = boost::pfr::structure_to_tuple(s);
BOOST_TEST_EQ(std::get<0>(s_tuple), 1);
static_assert(std::is_same<
std::tuple<int>, decltype(s_tuple)
>::value, "");
}
{
const some::struct1 s{1};
auto s_tuple = boost::pfr::structure_to_tuple(s);
BOOST_TEST_EQ(std::get<0>(s_tuple), 1);
static_assert(std::is_same<
std::tuple<int>, decltype(s_tuple)
>::value, "");
}
}
void test_two_fields() {
{
some::struct2 s{1, 2};
auto s_tuple = boost::pfr::structure_to_tuple(s);
BOOST_TEST_EQ(std::get<0>(s_tuple), 1);
BOOST_TEST_EQ(std::get<1>(s_tuple), 2);
static_assert(std::is_same<
std::tuple<int, short>, decltype(s_tuple)
>::value, "");
}
{
const some::struct2 s{1, 2};
auto s_tuple = boost::pfr::structure_to_tuple(s);
BOOST_TEST_EQ(std::get<0>(s_tuple), 1);
BOOST_TEST_EQ(std::get<1>(s_tuple), 2);
static_assert(std::is_same<
std::tuple<int, short>, decltype(s_tuple)
>::value, "");
}
}
// Test from https://github.com/boostorg/pfr/issues/155
void test_throwing_field() {
#if BOOST_PFR_USE_CPP17 || BOOST_PFR_USE_LOOPHOLE
struct throw_on_copy {
throw_on_copy() = default;
throw_on_copy(const throw_on_copy&){ throw 42; }
};
struct throwing_struct {
int i;
throw_on_copy s;
};
throwing_struct s {10, {}};
try {
std::tuple<int, throw_on_copy> t = boost::pfr::structure_to_tuple(s);
BOOST_TEST(false); // the above line should throw
(void)t;
} catch (...) {}
#endif
}
int main() {
test_single_field();
test_two_fields();
test_throwing_field();
return boost::report_errors();
}