[Pre-pitch] "common" fields for union-style enumerations?

Way back in the macOS pre-X days, I remember some APIs had types like:

struct Sample1 {
int a;
int b;
float c;
};

struct Sample2 {
int a;
int b;
double d;
};

The types are supposed to be related, and it was supposed to be guaranteed that if you type-punned Sample1 to or from Sample2, the common members (“a” and “b” here) would have the same semantics. I guess it could be done like this:

struct Sample {
int a;
int b;
union {
float c;
double d;
}
};

too.

I wonder if we need something similar in Swift:

enum Sample {
@common case withFloat(a: Int, b: Int, c: Float)
@common case withDouble(a: Int, b: Int, d: Double)
}

The attribute would ensure that the shared initial members would map to the same internal offset. And, if there were no cases that didn’t have the common members, you can use them as instance level properties:

var x: Sample = .withFloat(1, 2, 3.0)
//…
assert(x.a == 1) // Instead of “x.withFloat.a"

Good idea? Does this already exist?

···


Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com

AFAIK, you can legally access the compatible <Type - cppreference.com; prefix of structure fields in C. (Regardless of whether you have a pointer to a Sample1 or to a Sample2, casting it to either and accessing a or b is guaranteed to work; c or d is UB.)

You can port your second example to Swift as well, by pulling out the common fields in a struct and using an enum as a union for the variable part:

struct Sample {
  enum CD {
    case float(Float)
    case double(Double)
  }
  var a: Int
  var b: Int
  var cd: CD
}

Félix

···

Le 22 juil. 2017 à 17:07, Daryle Walker via swift-evolution <swift-evolution@swift.org> a écrit :

Way back in the macOS pre-X days, I remember some APIs had types like:

struct Sample1 {
int a;
int b;
float c;
};

struct Sample2 {
int a;
int b;
double d;
};

The types are supposed to be related, and it was supposed to be guaranteed that if you type-punned Sample1 to or from Sample2, the common members (“a” and “b” here) would have the same semantics. I guess it could be done like this:

struct Sample {
int a;
int b;
union {
float c;
double d;
}
};

too.

I wonder if we need something similar in Swift:

enum Sample {
@common case withFloat(a: Int, b: Int, c: Float)
@common case withDouble(a: Int, b: Int, d: Double)
}

The attribute would ensure that the shared initial members would map to the same internal offset. And, if there were no cases that didn’t have the common members, you can use them as instance level properties:

var x: Sample = .withFloat(1, 2, 3.0)
//…
assert(x.a == 1) // Instead of “x.withFloat.a"

Good idea? Does this already exist?


Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution