2
0
mirror of https://github.com/boostorg/pfr.git synced 2026-01-19 04:22:13 +00:00
This commit is contained in:
denzor200
2023-09-03 02:53:57 +03:00
parent dbbfa6ea7f
commit 2c79ac703b
3 changed files with 26 additions and 12 deletions

View File

@@ -10,7 +10,7 @@
#include <boost/pfr/config.hpp>
#if BOOST_PFR_ENABLE_GET_NAME_STATIC
#if BOOST_PFR_ENABLE_GET_NAME_STATIC && BOOST_PFR_USE_CPP17
//[pfr_example_get_name
/*`
Since C++20 it's possible to read name of structure fields by index using Boost.PFR library.
@@ -34,7 +34,7 @@ constexpr auto r2 = boost::pfr::get_name<1, foo>(); // reading name of field wit
#endif
int main() {
#if BOOST_PFR_ENABLE_GET_NAME_STATIC
#if BOOST_PFR_ENABLE_GET_NAME_STATIC && BOOST_PFR_USE_CPP17
if (r1 != "some_integer") return 1;
if (r2 != "c") return 2;
#endif

View File

@@ -106,7 +106,8 @@ void test_examples() {
//]
}
#if BOOST_PFR_ENABLE_GET_NAME_STATIC
// Disabled from testing since it's unportable
#if 0
{
//[pfr_quick_examples_get_name
// Get name of field by index

View File

@@ -110,9 +110,17 @@ consteval void failed_to_get_function_name() noexcept {
);
}
// it might be compilation failed without this workaround sometimes
// See https://github.com/llvm/llvm-project/issues/41751 for details
template <class>
consteval std::string_view clang_workaround(std::string_view value) noexcept
{
return value;
}
template <typename MsvcWorkaround, auto ptr>
consteval auto name_of_field_impl() noexcept {
constexpr std::string_view sv = BOOST_PFR_FUNCTION_SIGNATURE;
constexpr std::string_view sv = detail::clang_workaround<MsvcWorkaround>(BOOST_PFR_FUNCTION_SIGNATURE);
if constexpr (sv.empty()) {
detail::failed_to_get_function_name<MsvcWorkaround>();
return detail::make_stdarray<char>(0);
@@ -140,32 +148,37 @@ extern const T fake_object;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundefined-var-template"
// clang 16 doesn't support address of non-static member as template parameter
// but fortunately it's possible to use C++20 non-type template parameters in another way
// even in clang 16 and more older clangs
// all we need is to wrap pointer into 'clang_wrapper_t' and then pass it into template
template<class T>
struct clang_workaround_t {
struct clang_wrapper_t {
T v;
};
template<class T>
clang_workaround_t(T) -> clang_workaround_t<T>;
clang_wrapper_t(T) -> clang_wrapper_t<T>;
template<typename T>
constexpr auto clang_workaround(const T& arg) noexcept {
return clang_workaround_t{arg};
constexpr auto make_clang_wrapper(const T& arg) noexcept {
return clang_wrapper_t{arg};
}
#else
template<typename T>
constexpr const T& clang_workaround(const T& arg) noexcept {
// It's everything OK with this compiler
// so we don't need a workaround here
constexpr const T& make_clang_wrapper(const T& arg) noexcept {
// It's everything OK with address of non-static member as template parameter support on this compiler
// so we don't need a wrapper here, just pass the pointer into template
return arg;
}
#endif
// Without passing 'T' into 'name_of_field_impl' different fields from different structures might have the same name!
// See https://developercommunity.visualstudio.com/t/__FUNCSIG__-outputs-wrong-value-with-C/10458554 for details
template <class T, std::size_t I>
constexpr auto stored_name_of_field = name_of_field_impl<T, clang_workaround(&detail::sequence_tuple::get<I>(
constexpr auto stored_name_of_field = name_of_field_impl<T, make_clang_wrapper(&detail::sequence_tuple::get<I>(
detail::tie_as_tuple(fake_object<T>)
))>();