Thread overview
trait detecting anonymous union?
May 22, 2017
Bastiaan Veelo
May 22, 2017
Stanislav Blinov
May 23, 2017
Bastiaan Veelo
May 23, 2017
Vladimir Panteleev
May 23, 2017
Bastiaan Veelo
May 22, 2017
`
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, 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...
May 23, 2017
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 23, 2017
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, 2017
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.