79300213

Date: 2024-12-21 22:44:48
Score: 0.5
Natty:
Report link

Well, I think you can improve a bit if you are using Records. You can try to use Record and do some operator overloads. And you can do some "mapping" containing several operations with each type that exists in Delphi and custom types. I'm already doing something with this idea. Excerpt and link below.

https://github.com/lotexiu/HelperLibrary

[AutoDestroy.pas]
...
  RAD<T> = record
  private
    FValue: TAutoDestroy<T>;
    FRtti: TRttiType;
    FContext: IAD<TRttiContext>;
    function getRtti: TRttiType;
  public
  ...
  {Operations}
  class operator Add(a: RAD<T>; b: RAD<T>): Double;
  class operator Subtract(a: RAD<T>; b: RAD<T>) : Double;
  class operator Multiply(a: RAD<T>; b: RAD<T>) : Double;
  class operator Divide(a: RAD<T>; b: RAD<T>) : Double;
  
  class operator Negative(a: RAD<T>): RAD<T>;
  class operator Positive(a: RAD<T>): RAD<T>;
  class operator Inc(a: RAD<T>): RAD<T>;
  class operator Dec(a: RAD<T>): RAD<T>;
  class operator LogicalNot(a: RAD<T>): Boolean;
  class operator Modulus(a, b: RAD<T>): RAD<T>;
  ...

[UTOperation.pas]
...
TTOperation<T> = class(TInterfacedObject,
  IAdd<T>,        ISubtract<T>,
  IMultiply<T>,   IDivide<T>,
  INegative<T>,   IPositive<T>,
  IInc<T>,        IDec<T>,
  ILogicalNot<T>, IModulus<T>
)
private
  FFAdd:        TFunc2P<T,Double>;
  FFSubtract:   TFunc2P<T,Double>;
  FFMultiply:   TFunc2P<T,Double>;
  FFDivide:     TFunc2P<T,Double>;
  FFIntDivide:  TFunc2P<T,Integer>;
  FFNegative:   TFunc1P<T,T>;
  FFPositive:   TFunc1P<T,T>;
  FFInc:        TFunc1P<T,T>;
  FFDec:        TFunc1P<T,T>;
  FFLogicalNot: TFunc1P<T,Boolean>;
  FFModulus:    TFunc2P<T,T>;
public
  constructor Create;
  property FuncAdd:        TFunc2P<T,Double > read FFAdd        write FFAdd;
  property FuncSubtract:   TFunc2P<T,Double > read FFSubtract   write FFSubtract;
  property FuncMultiply:   TFunc2P<T,Double > read FFMultiply   write FFMultiply;
  property FuncDivide:     TFunc2P<T,Double > read FFDivide     write FFDivide;
  property FuncIntDivide:  TFunc2P<T,Integer> read FFIntDivide  write FFIntDivide;
  property FuncNegative:   TFunc1P<T,T>       read FFNegative   write FFNegative;
  property FuncPositive:   TFunc1P<T,T>       read FFPositive   write FFPositive;
  property FuncInc:        TFunc1P<T,T>       read FFInc        write FFInc;
  property FuncDec:        TFunc1P<T,T>       read FFDec        write FFDec;
  property FuncLogicalNot: TFunc1P<T,Boolean> read FFLogicalNot write FFLogicalNot;
  property FuncModulus:    TFunc2P<T,T>       read FFModulus    write FFModulus;

  function Add       (const A, B: T): Double ;
  function Subtract  (const A, B: T): Double ;
  function Multiply  (const A, B: T): Double ;
  function Divide    (const A, B: T): Double ;
  function IntDivide (const A, B: T): Integer;
  function Negative  (const A: T):    T      ;
  function Positive  (const A: T):    T      ;
  function Inc       (const A: T):    T      ;
  function Dec       (const A: T):    T      ;
  function LogicalNot(const A: T):    Boolean;
  function Modulus   (const A, B: T): T      ;
end;
...

procedure DefaultOperations;
var
  LObjOp: TTOperation<TObject>;
  LIntOp: TTOperation<Integer>;
  LDblOp: TTOperation<Double>;
  LStrOp: TTOperation<String>;
begin
  LStrOp := TTOperation<String>.Create;
  with LStrOp do
  begin { TODO - Try to convert first to Number }
    FuncAdd      := function(A,B: String): Double begin Result := Length(A) + Length(B) end;
    FuncSubtract := function(A,B: String): Double begin Result := Length(A) - Length(B) end;
    FuncMultiply := function(A,B: String): Double begin Result := Length(A) * Length(B) end;
    FuncDivide   := function(A,B: String): Double begin Result := Length(A) / Length(B) end;
    FuncIntDivide:= function(A,B: String): Integer begin Result := Length(A) div Length(B) end;
  end;

  LObjOp := TTOperation<TObject>.Create;
  with LObjOp do
  begin
    FuncAdd      := function(A,B: TObject): Double begin Result := NativeInt(A) + NativeInt(B) end;
    FuncSubtract := function(A,B: TObject): Double begin Result := NativeInt(A) - NativeInt(B) end;
    FuncMultiply := function(A,B: TObject): Double begin Result := NativeInt(A) * NativeInt(B) end;
    FuncDivide   := function(A,B: TObject): Double begin Result := NativeInt(A) / NativeInt(B) end;
  end;

  LIntOp := TTOperation<Integer>.Create;
  with LIntOp do
  begin
    FuncAdd         := function(A,B: Integer):  Double begin Result := A + B      end;
    FuncSubtract    := function(A,B: Integer):  Double begin Result := A - B      end;
    FuncMultiply    := function(A,B: Integer):  Double begin Result := A * B      end;
    FuncDivide      := function(A,B: Integer):  Double begin Result := A / B      end;
    FuncIntDivide   := function(A,B: Integer): Integer begin Result := A div B    end;
    FuncNegative    := function(A: Integer):   Integer begin Result := -A;        end;
    FuncPositive    := function(A: Integer):   Integer begin Result := Abs(A);    end;
    FuncInc         := function(A: Integer):   Integer begin Result := A + 1;     end;
    FuncDec         := function(A: Integer):   Integer begin Result := A - 1;     end;
    FuncLogicalNot  := function(A: Integer):   Boolean begin Result := A = 0;     end;
    FuncModulus     := function(A, B: Integer): Integer begin Result := A mod B;  end;
  end;

  LDblOp := TTOperation<Double>.Create;
  with LDblOp do
  begin
    FuncAdd         := function(A,B: Double): Double begin Result := A + B        end;
    FuncSubtract    := function(A,B: Double): Double begin Result := A - B        end;
    FuncMultiply    := function(A,B: Double): Double begin Result := A * B        end;
    FuncDivide      := function(A,B: Double): Double begin Result := A / B        end;
    FuncNegative    := function(A: Double):   Double begin Result := -A;          end;
    FuncPositive    := function(A: Double):   Double begin Result := Abs(A);      end;
    FuncInc         := function(A: Double):   Double begin Result := A + 1;       end;
    FuncDec         := function(A: Double):   Double begin Result := A - 1;       end;
    FuncLogicalNot  := function(A: Double):   Boolean begin Result := A = 0;      end;
    FuncModulus     := function(A, B: Double): Double begin Result := A - (Int(A/B) * B); end;
  end;

  TOperations.new<TObject>('Default',LObjOp);
  TOperations.new<Integer>('Default',LIntOp);
  TOperations.new<Double> ('Default',LDblOp);
  TOperations.new<String> ('Default',LStrOp);
end;

initialization
  TOperations.Operations := TGenericDictionary.Create;
  DefaultOperations;

finalization
  TOperations.Operations.FreeValuesOnDestroy := True;
  TGenU.freeAndNil(TOperations.Operations);
Reasons:
  • Contains signature (1):
  • Long answer (-1):
  • Has code block (-0.5):
  • Low reputation (1):
Posted by: Lotexiu