четверг, 26 марта 2015 г.

Коротко Implicit и Explicit и опять про Implicit. И про Equal

По мотивам - Коротко. Про контроль типов.

Так вот вам "идейка":

// TmsShapeClassName

type
 TmsShapeClassName = record
  rValue : String;
  class operator Implicit(const aValue: String): TmsShapeClassName;
  class operator Explicit(const aSelf: TmsShapeClassName): String;
 end;//TmsShapeClassName

...

class operator TmsShapeClassName.Implicit(const aValue: String): TmsShapeClassName;
begin
 Result.rValue := aValue;
end;

class operator TmsShapeClassName.Explicit(const aSelf: TmsShapeClassName): String;
begin
 Result := aSelf.rValue;
end;

Пока - всё.

Заготовочка - https://bitbucket.org/ingword/mindstream/commits/8d43980ff7c2bf1825c1e0dc60e7db36499e7c37

Так сказать - "следите за обновлениями".

P.S. Ну и ещё там есть:

 TmsColorRec = record
  rIsSet : Boolean;
  rValue : TAlphaColor;
  class operator Implicit(aValue: TAlphaColor): TmsColorRec;
 end;//TmsColorRec

 TmsPixelRec = record
  rIsSet : Boolean;
  rValue : Pixel;
  class operator Implicit(aValue: Pixel): TmsPixelRec;
 end;//TmsPixelRec

 TmsRadiusRec = record
  rIsSet : Boolean;
  rValue : Pixel;
  class operator Implicit(aValue: Pixel): TmsRadiusRec;
 end;//TmsRadiusRec

 TmsStrokeDash = record
  rIsSet : Boolean;
  rValue : TStrokeDash;
  class operator Implicit(aValue: TStrokeDash): TmsStrokeDash;
 end;//TmsStrokeDash

...

(+) https://bitbucket.org/ingword/mindstream/commits/4c28381d98f5a01d82b7e01b2e4456f81b05a72a

(+) https://bitbucket.org/ingword/mindstream/commits/1734dc8f4d07510e62190294de535347a7672493

И ещё:

type
 TmsShapeClassName = record
  rValue : String;
  class operator Implicit(const aValue: String): TmsShapeClassName;
  class operator Explicit(const aSelf: TmsShapeClassName): String; overload;
  class operator Implicit(const aSelf: TmsShapeClassName): String; overload;
  function EQ(const aValue: String): Boolean; overload;
  function EQ(const aValue: TmsShapeClassName): Boolean; overload;
 end;//TmsShapeClassName
...
// TmsShapeClassName

class operator TmsShapeClassName.Implicit(const aValue: String): TmsShapeClassName;
const
 cPref = 'Tms';
begin
 Result.rValue := aValue;
 if ANSIStartsText(cPref, Result.rValue) then
  Result.rValue := Copy(Result.rValue, Length(cPref) + 1, Length(Result.rValue) - Length(cPref));
end;

class operator TmsShapeClassName.Explicit(const aSelf: TmsShapeClassName): String;
begin
 Result := aSelf.rValue;
end;

class operator TmsShapeClassName.Implicit(const aSelf: TmsShapeClassName): String;
begin
 Result := aSelf.rValue;
end;

function TmsShapeClassName.EQ(const aValue: String): Boolean;
begin
 Result := (Self.rValue = aValue);
end;

function TmsShapeClassName.EQ(const aValue: TmsShapeClassName): Boolean;
begin
 Result := (Self.rValue = aValue.rValue);
end;

(+) https://bitbucket.org/ingword/mindstream/commits/7f34f5efa542db681a08d702d38cc32e6441ad6c

И ещё:

type
 TmsShapeClassName = record
  rValue : String;
  class operator Implicit(const aValue: String): TmsShapeClassName;
  class operator Explicit(const aSelf: TmsShapeClassName): String; overload;
  class operator Implicit(const aSelf: TmsShapeClassName): String; overload;
  class operator Equal(const A: TmsShapeClassName; const B: String): Boolean;
//  function EQ(const aValue: String): Boolean; overload;
  function EQ(const aValue: TmsShapeClassName): Boolean; overload;
 end;//TmsShapeClassName

...

// TmsShapeClassName

class operator TmsShapeClassName.Implicit(const aValue: String): TmsShapeClassName;
const
 cPref = 'Tms';
begin
 Result.rValue := aValue;
 if ANSIStartsText(cPref, Result.rValue) then
  Result.rValue := Copy(Result.rValue, Length(cPref) + 1, Length(Result.rValue) - Length(cPref));
end;

class operator TmsShapeClassName.Explicit(const aSelf: TmsShapeClassName): String;
begin
 Result := aSelf.rValue;
end;

class operator TmsShapeClassName.Implicit(const aSelf: TmsShapeClassName): String;
begin
 Result := aSelf.rValue;
end;

class operator TmsShapeClassName.Equal(const A: TmsShapeClassName; const B: String): Boolean;
begin
 Result := (A.rValue = B);
end;

(*function TmsShapeClassName.EQ(const aValue: String): Boolean;
begin
 Result := (Self.rValue = aValue);
end;*)

function TmsShapeClassName.EQ(const aValue: TmsShapeClassName): Boolean;
begin
 Result := (Self.rValue = aValue.rValue);
end;

И вот ещё куда стоит посмотреть:

  TPointF = record
    class function Create(const AX, AY: Single): TPointF; overload; static; inline;
    class function Create(const APoint: TPoint): TPointF; overload; static; inline;

    class operator Add(const APoint1, APoint2: TPointF): TPointF;
    class operator Subtract(const APoint1, APoint2: TPointF): TPointF;
    class operator Equal(const APoint1, APoint2: TPointF): Boolean;
    class operator NotEqual(const APoint1, APoint2: TPointF): Boolean;
    class operator Implicit(const APoint: TPoint): TPointF;
    class operator Negative(const APoint: TPointF): TPointF;
    class operator Multiply(const APoint1, APoint2: TPointF): TPointF;
    class operator Multiply(const APoint: TPointF; const AFactor: Single): TPointF;
    class operator Multiply(const AFactor: Single; const APoint: TPointF): TPointF;
    class operator Divide(const APoint: TPointF; const AFactor: Single): TPointF;

    class function PointInCircle(const Point, Center: TPointF; const Radius: Integer): Boolean; static; inline;

    function Distance(const APoint: TPointF): Single;
    // 3D cross-product with Z = 0
    function CrossProduct(const APoint: TPointF): Single;
    function DotProduct(const APoint: TPointF): Single; inline;

    procedure Offset(const APoint: TPointF); overload; inline;
    procedure Offset(const ADeltaX, ADeltaY: Single); overload; inline;
    procedure Offset(const APoint: TPoint); overload; inline;

    procedure SetLocation(const X, Y: Single); overload; deprecated 'Use ":=" assignment instead';
    procedure SetLocation(const P: TPointF); overload; deprecated 'Use ":=" assignment instead';
    procedure SetLocation(const P: TPoint); overload; deprecated 'Use ":=" assignment instead';
    function Subtract(const Point: TPointF): TPointF; overload; deprecated 'Use TPointF.Offset instead';
    function Subtract(const Point: TPoint): TPointF; overload; deprecated 'Use TPointF.Offset instead';
    function Add(const Point: TPointF): TPointF; overload; deprecated 'Use TPointF.Offset instead';
    function Add(const Point: TPoint): TPointF; overload; deprecated 'Use TPointF.Offset instead';
    function Scale(const AFactor: Single): TPointF; deprecated;
    function EqualsTo(const Point: TPointF; const Epsilon: Single = 0): Boolean;

    function IsZero: Boolean;
    function Ceiling: TPoint;
    function Truncate: TPoint;
    function Round: TPoint;

    function Normalize: TPointF;
    function Length: Single;
    function Rotate(const AAngle: Single): TPointF; 
    function Reflect(const APoint: TPointF): TPointF; inline;
    function MidPoint(const APoint: TPointF): TPointF; inline;
    function AngleCosine(const APoint: TPointF): Single;
    function Angle(const APoint: TPointF): Single;

    case Integer of
      0: (V: TPointFType;);
      1: (X: Single;
          Y: Single;);
  end;

Особенно вот сюда:

class operator TPointF.Equal(const APoint1, APoint2: TPointF): Boolean;
begin
  Result := SameValue(APoint1.X, APoint2.X) and SameValue(APoint1.Y, APoint2.Y);
end;

function TPointF.EqualsTo(const Point: TPointF; const Epsilon: Single): Boolean;
begin
  Result := SameValue(X, Point.X, Epsilon) and SameValue(Y, Point.Y, Epsilon);
end;

class operator TPointF.NotEqual(const APoint1, APoint2: TPointF): Boolean;
begin
  Result := not (APoint1 = APoint2);
end;

class operator TPointF.Implicit(const APoint: TPoint): TPointF;
begin
  Result.X := APoint.X;
  Result.Y := APoint.Y;
end;

Оператор сравнения с учётом Epsilon хорош. Не правда ли?

(+) https://bitbucket.org/ingword/mindstream/commits/2291e3309b5ee49de09d0e219298859dbb721a8b

Комментариев нет:

Отправить комментарий