// 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 }