mirror of
https://github.com/boostorg/pfr.git
synced 2026-01-19 04:22:13 +00:00
Add multiple tests from different bug reports and make sure that ever… (#222)
…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
This commit is contained in:
1
.github/workflows/ci.yml
vendored
1
.github/workflows/ci.yml
vendored
@@ -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
|
||||
|
||||
@@ -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<T, I>.data();
|
||||
|
||||
37
test/core/fields_count_immutable.cpp
Normal file
37
test/core/fields_count_immutable.cpp
Normal file
@@ -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 <boost/pfr.hpp>
|
||||
|
||||
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>, "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<Group>;
|
||||
}
|
||||
|
||||
@@ -20,8 +20,17 @@ void test_get_rvalue() {
|
||||
std::make_unique<int>(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() {
|
||||
|
||||
@@ -9,6 +9,15 @@
|
||||
#include <boost/pfr.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
// 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<int> data;
|
||||
};
|
||||
@@ -35,3 +44,9 @@ int main() {
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#else
|
||||
int main() {
|
||||
return boost::report_errors();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <boost/pfr/core.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
@@ -47,6 +48,12 @@ struct other_anon_with_optional {
|
||||
std::optional<some::struct2> d;
|
||||
|
||||
};
|
||||
|
||||
// from https://github.com/boostorg/pfr/issues/110
|
||||
struct optional_linked_list {
|
||||
int value;
|
||||
std::optional<std::unique_ptr<optional_linked_list>> 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<optional_linked_list> == 2, "");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
63
test/core_name/run/unique_ptr_wrapper.cpp
Normal file
63
test/core_name/run/unique_ptr_wrapper.cpp
Normal file
@@ -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 <boost/pfr.hpp>
|
||||
|
||||
// Test inspired by https://github.com/boostorg/pfr/issues/208
|
||||
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
template <typename T>
|
||||
struct Field {
|
||||
Field() = default;
|
||||
|
||||
template<typename Arg, class = decltype(T{std::declval<Arg&&>()})>
|
||||
constexpr Field(Arg&& arg) : value_{std::forward<Arg>(arg)} {}
|
||||
|
||||
private:
|
||||
[[no_unique_address]] T value_;
|
||||
};
|
||||
|
||||
struct CustomFields2 {
|
||||
Field<int> some_int;
|
||||
Field<std::vector<int>> some_vector;
|
||||
Field<std::unique_ptr<int>> some_unique_ptr;
|
||||
Field<std::shared_ptr<int>> some_shared_ptr;
|
||||
Field<std::atomic<int>> 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<CustomFields2, 0, 5>((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<int>::atomic(const std::atomic<int>&)
|
||||
// 23 | constexpr Field(Arg&& arg) : value_{std::forward<Arg>(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>(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
|
||||
}
|
||||
30
test/core_name/run/void_ptr.cpp
Normal file
30
test/core_name/run/void_ptr.cpp
Normal file
@@ -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 <boost/pfr/core.hpp>
|
||||
#include <boost/pfr/core_name.hpp>
|
||||
#include <boost/pfr/traits.hpp>
|
||||
|
||||
#include <string_view>
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user