// TODO: add error cases (e.g., use of field constructors for managed types, etc.)

enum Color { R, G, B };

// empty struct/union should have generated ctor/dtors
union U {};
struct S {};

struct SimpleUnion {
	int x;
	double y;
	char z;
};

struct SimpleStruct {
	int x;
	double y;
	char z;
};

// struct/union with members with generated ctor/dtors should themselves have generated ctor/dtors
union PopulatedUnion {
	Color c;
	U u;
	S s;
};

struct PopulatedStruct {
	Color c;
	U u;
	S s;
};

forall(otype T)
T identity(T x) { return x; }

// can identity e if only sized or only the assertion, but the combination breaks...
// forall(dtype T | sized(T) | { void ?{}(T &); })
// void identity(T x) {  }

int main() {
	S s;
	U u;
	Color e;

	// identity(R);  // Color should be an otype
	// identity((Color)e);
	identity(u);  // U should be an otype
	identity(s);  // S should be an otype

	PopulatedStruct ps;
	PopulatedUnion pu;

	identity(ps); // should recursively be an otype
	identity(pu); // should recursively be an otype
}
