Implémentation d'opérations binaires
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.