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