www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - trait detecting anonymous union?

reply Bastiaan Veelo <Bastiaan Veelo.net> writes:
`
void main()
{
	import std.stdio;
	struct S
	{
		int i;
		union
		{
			int a;
                         double b;
		}
	}
	S s;
	writeln(s);                  // S(10, #{overlap a, b})
	import std.traits;
	writeln([FieldNameTuple!S]); // ["i", "a", "b"]
}
`

Is there a way to detect at CT that S has overlapping data 
members, when an anonimous union is used as above?

Thanks,
Bastiaan.
May 22
next sibling parent reply Stanislav Blinov <stanislav.blinov gmail.com> writes:
On Monday, 22 May 2017 at 21:03:42 UTC, Bastiaan Veelo wrote:
 `
 void main()
 {
 	import std.stdio;
 	struct S
 	{
 		int i;
 		union
 		{
 			int a;
                         double b;
 		}
 	}
 	S s;
 	writeln(s);                  // S(10, #{overlap a, b})
 	import std.traits;
 	writeln([FieldNameTuple!S]); // ["i", "a", "b"]
 }
 `

 Is there a way to detect at CT that S has overlapping data 
 members, when an anonimous union is used as above?

 Thanks,
 Bastiaan.
There isn't a built-in one. The best I can muster at 1AM is finding all fields that have the same offset: size_t[] memberOffsetsOf(T)() { size_t[] result; foreach(i, _; typeof(T.tupleof)) result ~= T.tupleof[i].offsetof; return result; } string[] overlappingFieldsOf(T)() { import std.traits : FieldNameTuple; import std.range : array, enumerate; import std.algorithm : map, filter, count; enum offsets = memberOffsetsOf!T; auto names = [FieldNameTuple!T]; bool isOverlapping(size_t i) { return offsets.count(offsets[i]) > 1; } return names .enumerate .filter!(a => isOverlapping(a.index)) .map!(a => a.value) .array; } void main() { import std.stdio; struct S { int i; union { int a; double b; } int j; union { struct { short n, m; } float k; } } S s; writeln(overlappingFieldsOf!S); // ["a", "b", "n", "k"] } which is not quite the same as full overlap. This looks like a fun exercise, considering fields can also have arbitrary alignment...
May 22
parent Bastiaan Veelo <Bastiaan Veelo.net> writes:
On Monday, 22 May 2017 at 22:11:15 UTC, Stanislav Blinov wrote:
 On Monday, 22 May 2017 at 21:03:42 UTC, Bastiaan Veelo wrote:
 Is there a way to detect at CT that S has overlapping data 
 members, when an anonimous union is used as above?
There isn't a built-in one. The best I can muster at 1AM is finding all fields that have the same offset:
Good idea, thanks for staying up while I was asleep :-)
May 23
prev sibling parent reply Vladimir Panteleev <thecybershadow.lists gmail.com> writes:
On Monday, 22 May 2017 at 21:03:42 UTC, Bastiaan Veelo wrote:
 Is there a way to detect at CT that S has overlapping data 
 members, when an anonimous union is used as above?
I have an implementation here: https://github.com/CyberShadow/rclidasm/blob/31bde3347ec1259026b6ab15e2305f2a99e63a30/src/rclidasm/meta.d#L110-L183
May 22
parent Bastiaan Veelo <Bastiaan Veelo.net> writes:
On Tuesday, 23 May 2017 at 01:02:59 UTC, Vladimir Panteleev wrote:
 On Monday, 22 May 2017 at 21:03:42 UTC, Bastiaan Veelo wrote:
 Is there a way to detect at CT that S has overlapping data 
 members, when an anonimous union is used as above?
I have an implementation here: https://github.com/CyberShadow/rclidasm/blob/31bde3347ec1259026b6ab15e2305f2a99e63a30/src/rclidasm/meta.d#L110-L183
Interesting work. Thanks or sharing! Bastiaan.
May 23