program TupleTest; {$APPTYPE CONSOLE} uses System.SysUtils; type IgnoreElm = record end; Tuple = record {$REGION 'Implementation details'} private type P1 = ^T1; P2 = ^T2; Tier = record Ref1: P1; Ref2: P2; class operator LessThanOrEqual(const Dest: Tier; const Src: Tuple): boolean; overload; end; private class operator Implicit(const Value: Tuple): Tuple; class operator Implicit(const Value: Tuple): Tuple; {$ENDREGION} public Elm1: T1; Elm2: T2; end; Tuple = record public class function From(const Value1: T1; Value2: T2): Tuple; static; class function Tie(var Elm1: T1; var Elm2: T2): Tuple.Tier; overload; static; class function Tie(var Elm1: T1; const Ignored2: IgnoreElm): Tuple.Tier; overload; static; class function Tie(const Ignored1: IgnoreElm; var Elm2: T2): Tuple.Tier; overload; static; end; const Ignore: IgnoreElm = (); procedure Test; var tup: Tuple; i: integer; s: string; begin i := 123; s := 'bar'; tup := Tuple.From(42, 'foo'); Tuple.Tie(Ignore, s) <= tup; WriteLn(i, ', ', s); // 123, foo end; { Tuple } class function Tuple.From(const Value1: T1; Value2: T2): Tuple; begin result.Elm1 := Value1; result.Elm2 := Value2; end; class function Tuple.Tie(var Elm1: T1; var Elm2: T2): Tuple.Tier; begin result.Ref1 := @Elm1; result.Ref2 := @Elm2; end; class function Tuple.Tie(var Elm1: T1; const Ignored2: IgnoreElm): Tuple.Tier; begin result.Ref1 := @Elm1; result.Ref2 := nil; end; class function Tuple.Tie(const Ignored1: IgnoreElm; var Elm2: T2): Tuple.Tier; begin result.Ref1 := nil; result.Ref2 := @Elm2; end; { Tuple.Tier } class operator Tuple.Tier.LessThanOrEqual(const Dest: Tier; const Src: Tuple): boolean; begin if (TypeInfo(T1) <> TypeInfo(IgnoreElm)) then Dest.Ref1^ := Src.Elm1; if (TypeInfo(T2) <> TypeInfo(IgnoreElm)) then Dest.Ref2^ := Src.Elm2; result := True; end; { Tuple } class operator Tuple.Implicit( const Value: Tuple): Tuple; begin result.Elm1 := Value.Elm1; end; class operator Tuple.Implicit( const Value: Tuple): Tuple; begin result.Elm2 := Value.Elm2; end; begin Test; ReadLn; end.