bloomberg/clang-p2996

members_of declaration order guarantee

Closed this issue · 2 comments

Hello, I'm really enjoying trying out your project, and I'd like to thank everyone who is making it possible.

Feature Proposition
I think it would be interesting to guarantee that the order of the members infos returned by members_of matches their declaration order.

Reasoning
If this guarantee is provided, it enables the use of tags delimiting scopes in the code.
I think this guarantee will become even more interesting as support for methods and functions expands.

I hope this example will speak for itself:

struct magic_attribute_1
{
	int n;
	constexpr magic_attribute_1(int in_n)
		: n (in_n)
	{}
};

template<std::size_t n>
struct magic_attribute_2
{
	std::array<char, n> magic{};
	constexpr magic_attribute_2(char const (&in_magic)[n])
	{ std::ranges::copy(in_magic, this->magic.data()); }
};

template<auto ... magics>
struct members_group_begin
{};

struct members_group_end
{};

struct baz
{
	float im_not_in_a_group;

	using properties_group = members_group_begin<magic_attribute_1(12)>;

	std::string m1;
	int			m2;

	using group_1 = members_group_begin<magic_attribute_2("more magic")>;

	void f1();
	void f2();

	using group_2 = members_group_begin<magic_attribute_2("even more magic")>;

	void f3();
	using some_int_type = int;

	using there_is_no_more_group = members_group_end;

	char im_not_in_a_group_neither;
};

Hey @Pespon ! Thanks for these bug reports and ideas, and thanks for checking out the project!

The guarantees that we're offering for P2996 are as follows:

Non-static data members are indexed in the order in which they are declared, but the order of other kinds of members is unspecified. [ Note 1: Base classes are not members. — end note ]

We guarantee this order because the language specification already requires that compilers keep track of the order of non-static data members - after all, they're initialized in declaration order. On the other hand, there is no such requirement for compilers to track e.g., the relative ordering of a non-static data member and a type alias (as in your example above). We aren't confident that implementing such a "global ordering" on all member declarations would be feasible for all implementations, so we're restricting the ordering requirement to those members whose order must already be known.

Thanks for your answer. I just noticed that you may use source_location_of to emulate this feature, wich is nice :).