OpOverloads2 (Delphi)

From RAD Studio Code Examples
Jump to: navigation, search

Description

This example shows how to write and invoke more class or record operator overloads. The strings added to the TMemo describe the code being executed and the operators that are actually used.

This example is being referenced from specific records like System.Variant that have many operator overloads, but the example shows you how to implement operator overloads in your own records.

Code

   TMyClass = record
     payload: Real;
     class operator Equal(a, b: TMyClass) : Boolean;
     class operator NotEqual(a, b: TMyClass) : Boolean;
     class operator Trunc(a: TMyClass) : integer;
     class operator Round(a: TMyClass) : integer;
     class operator In(a, b: TMyClass) : Boolean;
     class operator GreaterThan(a, b: TMyClass) : Boolean;
     class operator GreaterThanOrEqual(a, b: TMyClass) : Boolean;
     class operator LessThan(a, b: TMyClass) : Boolean;
     class operator LessThanOrEqual(a, b: TMyClass) : Boolean;
     class operator Multiply(a, b: TMyClass) : TMyClass;
     class operator Divide(a, b: TMyClass) : TMyClass;
     class operator IntDivide(a, b: TMyClass) : TMyClass;
     class operator Modulus(a, b: TMyClass) : TMyClass;
     class operator LeftShift(a, b: TMyClass) : TMyClass;
     class operator RightShift(a, b: TMyClass) : TMyClass;
   end;

class operator TMyClass.Equal(a, b: TMyClass) : Boolean;
begin
  Form1.Memo1.Lines.Add('Equal(a, b: TMyClass) : Boolean;');
  Result:= (a.payload = b.payload);
end;

class operator TMyClass.NotEqual(a, b: TMyClass) : Boolean;
begin
  Form1.Memo1.Lines.Add('NotEqual(a, b: TMyClass) : Boolean;');
  Result:= (a.payload <> b.payload);
end;

class operator TMyClass.Trunc(a: TMyClass) : integer;
begin
  Form1.Memo1.Lines.Add('Trunc(a: TMyClass) : integer;');
  Result:= Trunc(a.payload);
end;

class operator TMyClass.Round(a: TMyClass) : integer;
begin
  Form1.Memo1.Lines.Add('Round(a: TMyClass) : integer;');
  Result:= Round(a.payload);
end;

class operator TMyClass.In(a, b: TMyClass) : Boolean;
var
  aint, bint: Integer;
begin
  Form1.Memo1.Lines.Add('In(a, b: TMyClass) : Boolean;');
  aint:= Trunc(a.payload);
  bint:= Trunc(b.payload);
  Result:= aint in [0..bint];
end;

class operator TMyClass.GreaterThan(a, b: TMyClass) : Boolean;
begin
  Form1.Memo1.Lines.Add('GreaterThan(a, b: TMyClass) : Boolean;');
  Result:= (a.payload > b.payload);
end;

class operator TMyClass.GreaterThanOrEqual(a, b: TMyClass) : Boolean;
begin
  Form1.Memo1.Lines.Add('GreaterThan(a, b: TMyClass) : Boolean;');
  Result:= (a.payload >= b.payload);
end;

class operator TMyClass.LessThan(a, b: TMyClass) : Boolean;
begin
  Form1.Memo1.Lines.Add('LessThan(a, b: TMyClass) : Boolean;');
  Result:= (a.payload < b.payload);
end;

class operator TMyClass.LessThanOrEqual(a, b: TMyClass) : Boolean;
begin
  Form1.Memo1.Lines.Add('LessThanOrEqual(a, b: TMyClass) : Boolean;');
  Result:= (a.payload <= b.payload);
end;

class operator TMyClass.Multiply(a, b: TMyClass) : TMyClass;
var c: TMyClass;
begin
  Form1.Memo1.Lines.Add('Multiply(a, b: TMyClass) : TMyClass;');
  c.payload := a.payload * b.payload;
  Result:= c;
end;

class operator TMyClass.Divide(a, b: TMyClass) : TMyClass;
var c: TMyClass;
begin
  Form1.Memo1.Lines.Add('Multiply(a, b: TMyClass) : TMyClass;');
  c.payload := a.payload / b.payload;
  Result:= c;
end;

class operator TMyClass.IntDivide(a, b: TMyClass) : TMyClass;
var c: TMyClass;
begin
  Form1.Memo1.Lines.Add('IntDivide(a: TMyClass; b: integer) : TMyClass;');
  c.payload := Round(a.payload) div Round(b.payload);
  Result:= c;
end;

class operator TMyClass.Modulus(a, b: TMyClass) : TMyClass;
var c: TMyClass;
begin
  Form1.Memo1.Lines.Add('Modulus(a: TMyClass; b: integer) : TMyClass;');
  c.payload := Round(a.payload) div Round(b.payload);
  Result:= c;
end;

class operator TMyClass.LeftShift(a, b: TMyClass) : TMyClass;
var c: TMyClass;
begin
  Form1.Memo1.Lines.Add('LeftShift(a: TMyClass; b: integer) : TMyClass;');
  c.payload := Round(a.payload) shl Round(b.payload);
  Result:= c;
end;

class operator TMyClass.RightShift(a, b: TMyClass) : TMyClass;
var c: TMyClass;
begin
  Form1.Memo1.Lines.Add('RightShift(a: TMyClass; b: integer) : TMyClass;');
  c.payload := Round(a.payload) shr Round(b.payload);
  Result:= c;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  x, y: TMyClass;
  a, b: Double;
  myint: Integer;
  myBool: Boolean;
begin
  x.payload:= StrToFloat(Edit15.Text);
  y.payload:= StrToFloat(Edit16.Text);
  Memo1.Lines.Add('Test: BoolToStr(x = y, True);');
  Edit14.Text:= BoolToStr(x = y, True);  // Calls TMyClass.Equal(a, b: TMyClass) : Boolean;
  Memo1.Lines.Add('Test: BoolToStr(x <> y, True);');
  Edit17.Text:= BoolToStr(x <> y, True);  // Calls TMyClass.NotEqual(a, b: TMyClass) : Boolean;
  Memo1.Lines.Add('Test: IntToStr(Trunc(x));');
  Edit18.Text:= IntToStr(Trunc(x));  // Calls TMyClass.Trunc(a: TMyClass) : Integer;
  Memo1.Lines.Add('Test: IntToStr(Round(x));');
  Edit19.Text:= IntToStr(Round(x));  // Calls TMyClass.Round(a: TMyClass) : Integer;
  Memo1.Lines.Add('Test: x in [0..y];');
  if x in y then
    Edit20.Text:= 'X is between 0 and ' + FloatToStr(y.payload)  // Calls TMyClass.In(a, b: TMyClass) : Boolean;
  else
    Edit20.Text:= 'X is not between 0 and ' + FloatToStr(y.payload);
  Memo1.Lines.Add('Test: BoolToStr(x > y, True);');
  Edit21.Text:= BoolToStr(x > y, True);  // Calls TMyClass.GreaterThan(a, b: TMyClass) : Boolean;
  Memo1.Lines.Add('Test: BoolToStr(x >= y, True);');
  Edit22.Text:= BoolToStr(x >= y, True);  // Calls TMyClass.GreaterThanOrEqual(a, b: TMyClass) : Boolean;
  Memo1.Lines.Add('Test: BoolToStr(x < y, True);');
  Edit23.Text:= BoolToStr(x < y, True);  // Calls TMyClass.LessThan(a, b: TMyClass) : Boolean;
  Memo1.Lines.Add('Test: BoolToStr(x <= y, True);');
  Edit24.Text:= BoolToStr(x <= y, True);  // Calls TMyClass.LessThanOrEqual(a, b: TMyClass) : Boolean;
  Memo1.Lines.Add('Test: x := x * y;');
  x := x * y;
  Edit25.Text:= FloatToStr(x.payload);  // Calls TMyClass.Multiply(a, b: TMyClass) : TMyClass;
  Memo1.Lines.Add('Test: x := x / y;');
  x := x / y;
  Edit26.Text:= FloatToStr(x.payload);  // Calls TMyClass.Divide(a, b: TMyClass) : TMyClass;
  Memo1.Lines.Add('Test: y := y div x;');
  x := y div x;
  Edit27.Text:= FloatToStr(x.payload);  // Calls TMyClass.IntDivide(a, b: TMyClass) : TMyClass;
  Memo1.Lines.Add('Test: x := 21 mod x;');
  y.payload:= 21;
  y := y mod x;
  Edit28.Text:= FloatToStr(y.payload);  // Calls TMyClass.Modulus(a, b: TMyClass) : TMyClass;
  Memo1.Lines.Add('Test: y := y shl x;');
  y := y shl x;
  Edit29.Text:= FloatToStr(y.payload);  // Calls TMyClass.RightShift(a, b: TMyClass) : TMyClass;
  Memo1.Lines.Add('Test: y := y shr x;');
  y := y shr x;
  Edit30.Text:= FloatToStr(y.payload);  // Calls TMyClass.LeftShift(a, b: TMyClass) : TMyClass;

end;

end.

Uses

See Also