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

Add function for_each_field_with_name (#171)

This commit is contained in:
Lena
2024-09-13 10:57:49 +02:00
committed by GitHub
parent e1e908e804
commit 3d090e7c6f
6 changed files with 111 additions and 1 deletions

View File

@@ -230,6 +230,9 @@ Boost.PFR is a header only library that does not depend on Boost. You can just c
[funcref boost::pfr::io]
]
][
[ [pfr_quick_examples_for_each_with_name] ]
[ [funcref boost::pfr::for_each_field_with_name] ]
][
[ [pfr_quick_examples_functions_for] ]
[ [macroref BOOST_PFR_FUNCTIONS_FOR] ]

View File

@@ -77,6 +77,35 @@ void test_examples() {
}
// Disabling for MSVC as it gives a hard error on using local types:
//
// error C7631:
// 'boost::pfr::detail::do_not_use_PFR_with_local_types<test_examples::sample>':
// variable with internal linkage declared but not defined
#if BOOST_PFR_CORE_NAME_ENABLED && BOOST_PFR_USE_CPP17 && !defined(_MSC_VER)
{
//[pfr_quick_examples_for_each_with_name
// Print the name and value
// of each element of the structure
struct test {
int n;
std::string str;
};
test var{42, "Hello, World!"};
// Outputs:
// n: 42
// str: Hello, World!
boost::pfr::for_each_field_with_name(var,
[](std::string_view name, const auto& value) {
std::cout << name << ": " << value << std::endl;
});
//]
}
#endif
{
//[pfr_quick_examples_tuple_size
// Getting fields count of some structure

View File

@@ -84,9 +84,30 @@ names_as_array() noexcept {
);
}
/// Calls `func` for each field with its name of a `value`
///
/// \param func must have one of the following signatures:
/// * any_return_type func(std::string_view name, U&& field) // field of value is perfect forwarded to function
/// * any_return_type func(std::string_view name, U&& field, std::size_t i)
/// * any_return_type func(std::string_view name, U&& value, I i) // Here I is an `std::integral_constant<size_t, field_index>`
///
/// \param value To each field of this variable will be the `func` applied.
///
/// \b Example:
/// \code
/// struct Toto { int a; char c; };
/// Toto t {5, 'c'};
/// auto print = [](std::string_view name, const auto& value){ std::cout << "Name: " << name << " Value: " << value << std::endl; };
/// for_each_field_with_name(t, print);
/// \endcode
template <class T, class F>
constexpr void for_each_field_with_name(T&& value, F&& func) {
return boost::pfr::detail::for_each_field_with_name(std::forward<T>(value), std::forward<F>(func));
}
BOOST_PFR_END_MODULE_EXPORT
}} // namespace boost::pfr
#endif // BOOST_PFR_CORE_NAME_HPP

View File

@@ -37,6 +37,15 @@ constexpr auto tie_as_names_tuple() noexcept {
return detail::sequence_tuple::make_sequence_tuple();
}
template <class T, class F>
constexpr void for_each_field_with_name(T&& value, F&& func) {
static_assert(
sizeof(T) && false,
"====================> Boost.PFR: Field's names extracting functionality requires C++20."
);
}
}}} // namespace boost::pfr::detail
#endif // BOOST_PFR_DETAIL_CORE_NAME14_DISABLED_HPP

View File

@@ -12,6 +12,7 @@
#define BOOST_PFR_DETAIL_CORE_NAME20_STATIC_HPP
#pragma once
#include <boost/pfr/core.hpp>
#include <boost/pfr/detail/config.hpp>
#include <boost/pfr/detail/core.hpp>
#include <boost/pfr/detail/sequence_tuple.hpp>
@@ -241,6 +242,22 @@ constexpr auto tie_as_names_tuple() noexcept {
return detail::tie_as_names_tuple_impl<T>(detail::make_index_sequence<detail::fields_count<T>()>{});
}
template <class T, class F>
constexpr void for_each_field_with_name(T&& value, F&& func) {
return boost::pfr::for_each_field(
std::forward<T>(value),
[f = std::forward<F>(func)](auto&& field, auto index) mutable {
using IndexType = decltype(index);
using FieldType = decltype(field);
constexpr auto name = boost::pfr::detail::get_name<std::remove_reference_t<T>, IndexType::value>();
if constexpr (std::is_invocable_v<F, std::string_view, FieldType, IndexType>) {
f(name, std::forward<FieldType>(field), index);
} else {
f(name, std::forward<FieldType>(field));
}
});
}
}}} // namespace boost::pfr::detail
#endif // BOOST_PFR_DETAIL_CORE_NAME20_STATIC_HPP

View File

@@ -0,0 +1,31 @@
// Copyright (c) 2016-2024 Lena Bertho
//
// 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 <map>
#include <string>
#include <boost/pfr/core_name.hpp>
#include <boost/core/lightweight_test.hpp>
struct SimpleStruct {
char c;
std::string str;
};
int main () {
std::map<std::string, std::string> m;
auto fill = [&m](std::string_view name, const auto& value){
m[std::string(name)] = value;
};
boost::pfr::for_each_field_with_name(SimpleStruct{ 'e', "test"}, fill);
BOOST_TEST_EQ(m.size(), 2);
BOOST_TEST_EQ(m["c"], "e");
BOOST_TEST_EQ(m["str"], "test");
return boost::report_errors();
}