XE4 からプリミティブ型にヘルパーが付いていて、
var i: Integer; s: string; begin i := 100; s := i.ToString; end;
ToString が使えるようになっています。
でも、レコードヘルパーや高度なレコード型は 2006 辺りから実装されているので、
unit uPrimitive;
interface
type { TInteger } TInteger = packed record // 型変換 (代入時) class operator Implicit(a: Integer): TInteger; // 暗黙の型変換: TInteger に Integer を代入 (レコードが左辺) class operator Implicit(a: TInteger): Integer; // 暗黙の型変換: Integer に TInteger を代入 (レコードが右辺) // 算術演算子 (単項) class operator Negative(a: TInteger): TInteger; // 符号反転: - class operator Positive(a: TInteger): TInteger; // 符号恒等: + // 算術演算子 class operator Add(a, b: TInteger): TInteger; // 加算: + class operator Subtract(a, b: TInteger): TInteger; // 減算: - class operator Multiply(a, b: TInteger): TInteger; // 乗算: * class operator IntDivide(a, b: TInteger): TInteger; // 整数除算: div class operator Modulus(a, b: TInteger): TInteger; // 剰余: mod // 論理演算子 class operator LogicalNot(a: TInteger): TInteger; // 否定: not class operator LogicalAnd(a, b: TInteger): Boolean; // 論理積: and class operator LogicalOr(a, b: TInteger): Boolean; // 論理和: or class operator LogicalXor(a, b: TInteger): Boolean; // 排他的論理和: xor // 論理(ビット)演算子 class operator BitwiseAnd(a, b: TInteger): TInteger; // ビット and: and class operator BitwiseOr(a, b: TInteger): TInteger; // ビット or: or class operator BitwiseXor(a, b: TInteger): TInteger; // ビット xor: xor class operator LeftShift(a, b: TInteger): TInteger; // ビット単位の左シフト: shl class operator RightShift(a, b: TInteger): TInteger; // ビット単位の右シフト: shr // 関係演算子 class operator Equal(a, b: TInteger): Boolean; // 等しい: = class operator NotEqual(a, b: TInteger): Boolean; // 等しくない: <> class operator LessThan(a, b: TInteger): Boolean; // より小さい: < class operator GreaterThan(a, b: TInteger): Boolean; // より大きい: > class operator LessThanOrEqual(a, b: TInteger): Boolean; // 以下: <= class operator GreaterThanOrEqual(a, b: TInteger): Boolean; // 以上: >= // インクリメント / デクリメント class operator Inc(a: TInteger): TInteger; // インクリメント: Inc() class operator Dec(a: TInteger): TInteger; // デクリメント: Dec() public // ペイロード Value: Integer end;
implementation
{ TInteger }
class operator TInteger.Add(a, b: TInteger): TInteger; begin result.Value := a.Value + b.Value; end;
class operator TInteger.BitwiseAnd(a, b: TInteger): TInteger; begin result.Value := (a.Value and b.Value); end;
class operator TInteger.BitwiseOr(a, b: TInteger): TInteger; begin result.Value := (a.Value or b.Value); end;
class operator TInteger.BitwiseXor(a, b: TInteger): TInteger; begin result.Value := (a.Value xor b.Value); end;
class operator TInteger.Dec(a: TInteger): TInteger; begin result.Value := a.Value - 1; end;
class operator TInteger.Equal(a, b: TInteger): Boolean; begin result := (a.Value = b.Value); end;
class operator TInteger.GreaterThan(a, b: TInteger): Boolean; begin result := (a.Value > b.Value); end;
class operator TInteger.GreaterThanOrEqual(a, b: TInteger): Boolean; begin result := (a.Value >= b.Value); end;
class operator TInteger.Implicit(a: TInteger): Integer; begin result := a.Value; end;
class operator TInteger.Implicit(a: Integer): TInteger; begin result.Value := a; end;
class operator TInteger.Inc(a: TInteger): TInteger; begin result.Value := a.Value + 1; end;
class operator TInteger.IntDivide(a, b: TInteger): TInteger; begin result.Value := a.Value div b.Value; end;
class operator TInteger.LeftShift(a, b: TInteger): TInteger; begin result.Value := a.Value shl b.Value; end;
class operator TInteger.LessThan(a, b: TInteger): Boolean; begin result := (a.Value < b.Value); end;
class operator TInteger.LessThanOrEqual(a, b: TInteger): Boolean; begin result := (a.Value <= b.Value); end;
class operator TInteger.LogicalAnd(a, b: TInteger): Boolean; begin result := (a.Value and b.Value) > 0; end;
class operator TInteger.LogicalNot(a: TInteger): TInteger; begin result.Value := not a.Value; end;
class operator TInteger.LogicalOr(a, b: TInteger): Boolean; begin result := (a.Value or b.Value) > 0; end;
class operator TInteger.LogicalXor(a, b: TInteger): Boolean; begin result := (a.Value xor b.Value) > 0; end;
class operator TInteger.Modulus(a, b: TInteger): TInteger; begin result.Value := a.Value mod b.Value; end;
class operator TInteger.Multiply(a, b: TInteger): TInteger; begin result.Value := a.Value * b.Value; end;
class operator TInteger.Negative(a: TInteger): TInteger; begin result.Value := -a.Value; end;
class operator TInteger.NotEqual(a, b: TInteger): Boolean; begin result := (a.Value <> b.Value); end;
class operator TInteger.Positive(a: TInteger): TInteger; begin result.Value := +a.Value; end;
class operator TInteger.RightShift(a, b: TInteger): TInteger; begin result.Value := a.Value shr b.Value; end;
class operator TInteger.Subtract(a, b: TInteger): TInteger; begin result.Value := a.Value - b.Value; end;
end.
こんなレコードを定義しておいて、
unit uPrimitive.Helper;
interface
uses SysUtils, uPrimitive;
type TIntegerHelper = record helper for TInteger public function ToString: string; end;
implementation
{ TIntegerHelper }
function TIntegerHelper.ToString: string; begin result := IntToStr(Self.Value); end;
end.
こんなヘルパーを作れば、
uses ... uPrimitive, uPrimitive.Helper;
var i: TInteger; // <- 変更 s: string; begin i := 100; s := i.ToString; end;
XE3 以前でも XE4 以降とほぼ同等の使い方ができます。プリミティブ型のレコードとレコードヘルパーを分離せず、ToString 等を直接レコードに実装してもいいのですが、それだとヘルパーを差し替えられないのでこういう事をやりたければ分離するのがいいでしょう。
|