フォーラム


ゲスト  

ようこそ ゲスト さん。このフォーラムに投稿するには 登録が必要です。

ページ: [1]
トピック: プリミティブ型のヘルパー
DEKO
管理者
投稿数: 2690
プリミティブ型のヘルパー
on: 2017/06/10 10:00 Sat

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 等を直接レコードに実装してもいいのですが、それだとヘルパーを差し替えられないのでこういう事をやりたければ分離するのがいいでしょう。

ページ: [1]
WP Forum Server by ForumPress | LucidCrew
バージョン: 1.7.5 ; ページロード: 0.036 sec.