Implémentation d'opérations binaires

De RAD Studio
Aller à : navigation, rechercher

Remonter à Création d'une classe pour le type variant personnalisé


Pour que le type variant personnalisé puisse fonctionner avec les opérateurs binaires standard (+, -, *, /, div, mod, shl, shr, and, or, xor de l'unité System), vous devez redéfinir la méthode BinaryOp. BinaryOp a trois paramètres : la valeur de l'opérande gauche, la valeur de l'opérande droit et l'opérateur. Implémentez cette méthode pour effectuer l'opération et renvoyer le résultat en utilisant la même variable que celle qui contenait l'opérande gauche.

Par exemple, la méthode BinaryOp suivante vient de TComplexVariantType, définie dans l'unité System.VarCmplx :

Delphi :

 procedure TComplexVariantType.BinaryOp(var Left: TVarData; const Right: TVarData;
   const Operator: TVarOp);
 begin
   if Right.VType = VarType then
     case Left.VType of
       varString:
         case Operator of
           opAdd: Variant(Left) := Variant(Left) + TComplexVarData(Right).VComplex.AsString;
         else
           RaiseInvalidOp;
         end;
       else
         if Left.VType = VarType then
           case Operator of
             opAdd:
               TComplexVarData(Left).VComplex.DoAdd(TComplexVarData(Right).VComplex);
             opSubtract:
               TComplexVarData(Left).VComplex.DoSubtract(TComplexVarData(Right).VComplex);
             opMultiply:
               TComplexVarData(Left).VComplex.DoMultiply(TComplexVarData(Right).VComplex);
             opDivide:
               TComplexVarData(Left).VComplex.DoDivide(TComplexVarData(Right).VComplex);
             else
               RaiseInvalidOp;
           end
         else
           RaiseInvalidOp;
     end
   else
     RaiseInvalidOp;
 end;

Plusieurs remarques importantes sur cette implémentation s'imposent :

Cette méthode ne gère que le cas où le variant du côté droit de l'opérateur est un variant personnalisé représentant un nombre complexe. Si l'opérande gauche est un variant complexe et non l'opérande droit, le variant complexe force l'opérande droit à être d'abord transtypé en variant complexe. Il le fait en redéfinissant la méthode RightPromotion pour qu'elle exige toujours le type de la propriété VarType :

Delphi :

 function TComplexVariantType.RightPromotion(const V: TVarData;
 const Operator: TVarOp; out RequiredVarType: TVarType): Boolean;
 begin
   { Complex Op TypeX }
   RequiredVarType := VarType;
   Result := True;
 end;

L'opérateur d'addition est implémenté pour une chaîne et un nombre complexe (par conversion de la valeur complexe en chaîne et concaténation) et les opérateurs d'addition, soustraction, multiplication et division sont implémentés pour deux nombres complexes en utilisant les méthodes de l'objet TComplexData qui est stocké dans les données du variant complexe. On y accède en transtypant l'enregistrement TVarData en enregistrement TComplexVarData et en utilisant son membre VComplex.

Essayer tout autre opérateur ou combinaison de types force la méthode à appeler la méthode RaiseInvalidOp, qui entraîne une erreur d'exécution. La classe TCustomVariantType contient de nombreuses méthodes utilitaires comme RaiseInvalidOp qui peuvent être utilisées dans l'implémentation des types variants personnalisés.

BinaryOp ne fonctionne qu'avec un nombre limité de types : les chaînes et d'autres variants complexes. Il est possible, cependant, d'effectuer des opérations entre des nombres complexes et d'autres types numériques. Pour que la méthode BinaryOp fonctionne, les opérandes doivent être convertis en variants complexes avant que les valeurs ne soient transmises à cette méthode. Nous avons déjà vu (plus haut) comment utiliser la méthode RightPromotion pour forcer l'opérande droit à être un variant complexe quand l'opérande gauche est un complexe. Une méthode similaire, LeftPromotion, force le transtypage de l'opérande gauche quand l'opérande droit est un complexe :

Delphi :

function TComplexVariantType.LeftPromotion(const V: TVarData; const Operator: TVarOp; out RequiredVarType: TVarType): Boolean;
 begin
   { TypeX Op Complex }
   if (Operator = opAdd) and VarDataIsStr(V) then
     RequiredVarType := varString
   else
     RequiredVarType := VarType;
   Result := True;
 end;

Cette méthode LeftPromotion force l'opérande gauche à être transtypé en un autre variant complexe, sauf si c'est une chaîne et que l'opérateur est l'addition, auquel cas LeftPromotion permet à l'opérande de rester une chaîne.

Voir aussi