From 4f9e6457b0e79df1e705e79911078d51647f88c4 Mon Sep 17 00:00:00 2001 From: Antony Polukhin Date: Sun, 14 Sep 2025 14:59:25 +0300 Subject: [PATCH] =?UTF-8?q?Add=20multiple=20tests=20from=20different=20bug?= =?UTF-8?q?=20reports=20and=20make=20sure=20that=20ever=E2=80=A6=20(#222)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …ything works with new unsafe_declval and with sturctured binding pack Fixes: https://github.com/boostorg/pfr/issues/208, https://github.com/boostorg/pfr/issues/110, https://github.com/boostorg/pfr/issues/126 Closes: https://github.com/boostorg/pfr/pull/212 Relates: https://github.com/boostorg/pfr/issues/173 --- .github/workflows/ci.yml | 1 - .../boost/pfr/detail/core_name20_static.hpp | 4 +- test/core/fields_count_immutable.cpp | 37 +++++++++++ test/core/run/get_rvalue.cpp | 9 +++ test/core/run/issue30.cpp | 15 +++++ test/core/run/tie_anonymous.cpp | 9 +++ test/core_name/run/unique_ptr_wrapper.cpp | 63 +++++++++++++++++++ test/core_name/run/void_ptr.cpp | 30 +++++++++ 8 files changed, 165 insertions(+), 3 deletions(-) create mode 100644 test/core/fields_count_immutable.cpp create mode 100644 test/core_name/run/unique_ptr_wrapper.cpp create mode 100644 test/core_name/run/void_ptr.cpp diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index eaf4250..f735fa7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -260,7 +260,6 @@ jobs: rm -rf build_module - name: Run tests - if: ${{matrix.os != 'windows-2025'}} # TODO: workaround issues shell: cmd run: | cd ../boost-root diff --git a/include/boost/pfr/detail/core_name20_static.hpp b/include/boost/pfr/detail/core_name20_static.hpp index 551564f..4c61590 100644 --- a/include/boost/pfr/detail/core_name20_static.hpp +++ b/include/boost/pfr/detail/core_name20_static.hpp @@ -216,8 +216,8 @@ constexpr std::string_view get_name() noexcept { "====================> Boost.PFR: It is impossible to extract name from old C array since it doesn't have named members" ); static_assert( - sizeof(T) && BOOST_PFR_USE_CPP17, - "====================> Boost.PFR: Extraction of field's names is allowed only when the BOOST_PFR_USE_CPP17 macro enabled." + sizeof(T) && (BOOST_PFR_USE_CPP17 || BOOST_PFR_USE_CPP26), + "====================> Boost.PFR: Extraction of field's names is allowed only when the BOOST_PFR_USE_CPP17 or the BOOST_PFR_USE_CPP26 macro enabled." ); return stored_name_of_field.data(); diff --git a/test/core/fields_count_immutable.cpp b/test/core/fields_count_immutable.cpp new file mode 100644 index 0000000..f8029e0 --- /dev/null +++ b/test/core/fields_count_immutable.cpp @@ -0,0 +1,37 @@ +// Copyright (c) 2025-2025 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 from https://github.com/boostorg/pfr/issues/126 + +#include + +struct NoCopy { + NoCopy() = default; + NoCopy(NoCopy const&) = delete; + NoCopy(NoCopy&&) = delete; + NoCopy& operator=(NoCopy&&) = delete; + NoCopy& operator=(NoCopy const&) = delete; +}; + +struct Group { + NoCopy m; + NoCopy m2; + NoCopy m3; + NoCopy m4; +}; + +Group ReturnGroup() { return {};} + +int main() +{ +#ifdef __cpp_lib_is_aggregate + static_assert(std::is_aggregate_v, "Group is totally an aggregate"); +#endif + static_assert(BOOST_PFR_HAS_GUARANTEED_COPY_ELISION, "Compiler implements mandatory copy elision"); + Group aggregate_init_test{{}, {}, {}, {}}; + Group elision_test = ReturnGroup(); + return boost::pfr::tuple_size_v; +} + diff --git a/test/core/run/get_rvalue.cpp b/test/core/run/get_rvalue.cpp index fa1ff01..ab6da7c 100644 --- a/test/core/run/get_rvalue.cpp +++ b/test/core/run/get_rvalue.cpp @@ -20,8 +20,17 @@ void test_get_rvalue() { std::make_unique(43), }; + // Some _MSC_VER are broken: + // boost/pfr/detail/fields_count.hpp(469): error C2338: static_assert failed: + // '====================> Boost.PFR: If there's no other failed static + // asserts then something went wrong. Please report this issue to the github + // along with the structure you're reflecting.' + // + // No known workaround +#if !defined(_MSC_VER) || _MSC_VER != 1944 || !(BOOST_PFR_USE_CPP17 || BOOST_PFR_USE_LOOPHOLE) auto p = boost::pfr::get<0>(std::move(x)); BOOST_TEST_EQ(*p, 42); +#endif } int main() { diff --git a/test/core/run/issue30.cpp b/test/core/run/issue30.cpp index 7872f8e..309c344 100644 --- a/test/core/run/issue30.cpp +++ b/test/core/run/issue30.cpp @@ -9,6 +9,15 @@ #include #include +// Some _MSC_VER are broken: +// boost/pfr/detail/fields_count.hpp(469): error C2338: static_assert failed: +// '====================> Boost.PFR: If there's no other failed static +// asserts then something went wrong. Please report this issue to the github +// along with the structure you're reflecting.' +// +// No known workaround +#if !defined(_MSC_VER) || _MSC_VER != 1944 || !(BOOST_PFR_USE_CPP17 || BOOST_PFR_USE_LOOPHOLE) + struct Message { std::unique_ptr data; }; @@ -35,3 +44,9 @@ int main() { return boost::report_errors(); } + +#else +int main() { + return boost::report_errors(); +} +#endif diff --git a/test/core/run/tie_anonymous.cpp b/test/core/run/tie_anonymous.cpp index a1ef257..3111619 100644 --- a/test/core/run/tie_anonymous.cpp +++ b/test/core/run/tie_anonymous.cpp @@ -7,6 +7,7 @@ #include +#include #include #include @@ -47,6 +48,12 @@ struct other_anon_with_optional { std::optional d; }; + +// from https://github.com/boostorg/pfr/issues/110 +struct optional_linked_list { + int value; + std::optional> next; +}; #endif struct other_anon { @@ -93,6 +100,8 @@ void test_in_non_non_ns() { other_anon_with_optional opt{"test again", {}, {}, {}}; auto opt_val = boost::pfr::structure_tie(opt); BOOST_TEST_EQ(std::get<0>(opt_val), "test again"); + + static_assert(boost::pfr::tuple_size_v == 2, ""); #endif } diff --git a/test/core_name/run/unique_ptr_wrapper.cpp b/test/core_name/run/unique_ptr_wrapper.cpp new file mode 100644 index 0000000..d2c6f01 --- /dev/null +++ b/test/core_name/run/unique_ptr_wrapper.cpp @@ -0,0 +1,63 @@ +// Copyright (c) 2025-2025 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 + +// Test inspired by https://github.com/boostorg/pfr/issues/208 + +#include +#include +#include +#include +#include +#include +#include + +template +struct Field { + Field() = default; + + template()})> + constexpr Field(Arg&& arg) : value_{std::forward(arg)} {} + + private: + [[no_unique_address]] T value_; +}; + +struct CustomFields2 { + Field some_int; + Field> some_vector; + Field> some_unique_ptr; + Field> some_shared_ptr; + Field> some_atomic; +}; + +int main() { + +// Compilers have issues with this test in C++17. +// +// GCC-9 and GCC-10 are fine +// +// GCC-11: +// ./boost/pfr/detail/fields_count.hpp:351:58: in constexpr expansion of boost::pfr::detail::fields_count_binary_search((boost::pfr::detail::is_one_element_range<0, 5>{}, boost::pfr::detail::is_one_element_range<0, 5>()), 1) +// libs/pfr/test/core_name/run/unique_ptr_wrapper.cpp:23:32: error: use of deleted function std::atomic::atomic(const std::atomic&) +// 23 | constexpr Field(Arg&& arg) : value_{std::forward(arg)} {} +// | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// GCC-12: +// libs/pfr/test/core_name/run/unique_ptr_wrapper.cpp:39:39: required from here +// libs/pfr/test/core_name/run/unique_ptr_wrapper.cpp:23:32: error: use of deleted function std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int] +// 23 | constexpr Field(Arg&& arg) : value_{std::forward(arg)} {} +// | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// GCC-14 is fine +// +// Because of the above issues we test mostly in C++26. + +#if BOOST_PFR_USE_CPP26 || (defined(__GNUC__) && (__GNUC__ != 11 && __GNUC__ != 12)) || defined(__clang__) + CustomFields2 cf2; + boost::pfr::for_each_field_with_name(cf2, [](const auto&, const auto&) {}); +#endif +} diff --git a/test/core_name/run/void_ptr.cpp b/test/core_name/run/void_ptr.cpp new file mode 100644 index 0000000..b6a65c8 --- /dev/null +++ b/test/core_name/run/void_ptr.cpp @@ -0,0 +1,30 @@ +// Copyright (c) 2025-2025 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 from https://github.com/boostorg/pfr/issues/173 + +#include +#include +#include + +#include + +struct LongPointerTest { + long* OwningThread; +}; + +struct VoidPointerTest { + void* OwningThread; +}; + +int main() { + static_assert(boost::pfr::get_name<0, LongPointerTest>() == "OwningThread"); + + // No known workaround for MSVC +#if !defined(_MSC_VER) || _MSC_VER > 1944 + static_assert(boost::pfr::get_name<0, VoidPointerTest>() == "OwningThread"); +#endif +} +