pfr icon indicating copy to clipboard operation
pfr copied to clipboard

Iterate over aggregate fields with the name

Open Baduit opened this issue 1 year ago • 2 comments

Add a new function for_each_field_with_name

The goal is to be able to do this:

struct Toto
{
	int a;
	char c;
};

Toto t {5, 'c'};
auto cb = [](std::string_view name, const auto& value){ std::cout << "Name: " << name << " Value: " << value << std::endl; };
boost::pfr::for_each_field_with_name(t, cb);

I think this is more user friendly than we way it can be done without this PR:

auto cb2 = []<std::size_t Index>(const auto& value, std::integral_constant<std::size_t, Index> i)
{
	std::cout << "Name: " << boost::pfr::get_name<Index, Toto>() << " Value: " << value << std::endl;
};
boost::pfr::for_each_field(t, cb2);

I tried to make the code of for_each_field_with_name as close as possible to for_each_field.

I will add new tests if you think this feature could be merged in the future.

I have explored a bit the idea of completing for_each_field instead of creating a new function in this branch https://github.com/Baduit/pfr/tree/feature/for_each_field_can_provide_name, most of the work is done and it makes possible to do stuff like this:

void plop () {
	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(SimpleStruct{ 'e', "test"}, fill);

	assert(m.size() == 2);
	assert(m["c"] == "e");
	assert(m["str"] == "test");
}

void plop2 () {
	std::map<std::string, std::string> m;
	std::map<std::string, std::size_t> mi;
	auto fill = [&m, &mi](std::string_view name, const auto& value, std::size_t i){
		m[std::string(name)] = value;
		mi[std::string(name)] = i;
	};

	boost::pfr::for_each_field(SimpleStruct{ 'e', "test"}, fill);
	assert(m.size() == 2);
	assert(m["c"] == "e");
	assert(m["str"] == "test");
	assert(mi.size() == 2);
	assert(mi["c"] == 0);
	assert(mi["str"] == 1);
}

Do you think it is a better idea ?

Baduit avatar May 14 '24 23:05 Baduit

Looks good!

Please see the comments to make the header changes smaller. Also some docs updates are required

I updated my PR according to your comments.

But on the github action I see a failure that I don't understand https://github.com/Baduit/pfr/actions/runs/9660279058/job/26645491447

Baduit avatar Jun 25 '24 10:06 Baduit

I updated my branch and thanks to your commit to fix the CI the builds are green

Baduit avatar Aug 27 '24 21:08 Baduit

Pull Request Test Coverage Report for Build 10586042298

Details

  • 0 of 0 changed or added relevant lines in 0 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage remained the same at 100.0%

Totals Coverage Status
Change from base Build 10537504895: 0.0%
Covered Lines: 405
Relevant Lines: 405

💛 - Coveralls

coveralls avatar Sep 13 '24 08:09 coveralls

Many thanks for the PR!

apolukhin avatar Sep 13 '24 09:09 apolukhin