trait detecting anonymous union?

Stanislav Blinov via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon May 22 15:11:15 PDT 2017


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...


More information about the Digitalmars-d-learn mailing list