0

私はこの問題を修正しようとしています (およびその他のいくつかの問題)。

問題

//None of these compile
type
  PAType<T> = ^AType<T>;  
  P<T> = ^T;                
  PAType = ^AType<T>

だから私は、レコードと演算子のオーバーロードを使用して自分自身をロールしようとしています。

私は次のコードを書いています:

  TCell<T> = record
  private
    FData: T;
    procedure SetData(Value: T); inline;
    function GetData: T; inline;
  public
    property data: T read GetData write SetData;
  end;

  //Type safe pointer to T, because it knows SizeOf(T).
  P<T> = record  //wrapper around pointer: ^TCell<T>;^H^H^H^H any <T> actually 
  private
    FPointerToT: pointer;
  public
    class operator Implicit(a: pointer): P<T>; inline;
    class operator Implicit(a: P<T>): pointer; inline;
    class operator Implicit(Cell: TCell<T>): P<T>; inline;
    class operator Implicit(p: P<T>): TCell<T>; inline;
    class operator Add(a: P<T>; b: NativeUInt): P<T>; inline;
    class operator NotEqual(a,b : P<T>): Boolean; inline;
    class operator NotEqual(a: P<T>; b: pointer): Boolean; inline;
    class operator Equal(a,b : P<T>): Boolean; inline;
    class operator GreaterThan(a,b : P<T>): Boolean; inline;
    class operator GreaterThanOrEqual(a,b : P<T>): Boolean; inline;
    class operator LessThan(a,b : P<T>): Boolean; inline;
    class operator LessThanOrEqual(a,b : P<T>): Boolean; inline;
    class operator Inc(a: P<T>): P<T>; inline;
    class operator Dec(a: P<T>): P<T>; inline;
    class operator Explicit(a: P<T>): T; inline;
  end;

ハッシュテーブルを書いています。ハッシュのさまざまなオプションを試しているためです。ハッシュテーブルは、データを含むレコードを取得し、そのレコードを動的配列 (ポインターではなく
レコード自体) に入れ、そのレコードへのポインターを返す必要があります。

これにより、アプリケーションは多かれ少なかれ連続した順序でデータを保存できます (いくつかのギャップがあります)。これはキャッシュに適しています。
ジェネリックを使用したいのは、ハッシュテーブルが一度に 1 つの型しか保持しない場合でも、異なるハッシュテーブルでハッシュされる異なるクラスがあるためです。

ポインターを返すことで、二重ストレージを防ぎます。

上記の未完成の構造により、次のようなコードを書くことができます。

//FCells: array of T;
//FArrayEnd: pointer; //points to element FCells[max_elements+1] (i.e. access violation)  

function THashTable<K, T>.NextItem(Item: P<T>): P<T>;
begin
  Result:= Item + SizeOf(T);  //pointer arithmetic 
  if Result >= FArrayEnd then Result:= @FCells[0];  //comparison and assignment
end;

function THashTable<K, T>.Lookup(const key: K): P<T>;
var
  Index: NativeUInt;
  ItemKey: K;
begin
  if IsValid(key) then begin
    // Check regular cells
    Index:= First_Cell(FGetHashFromKey(key));  //FGet.. is a user supplied key generation proc.
    while (true) do begin
      ItemKey:= FGetKey(FCells[Index]);
      if (IsEqual(ItemKey, key)) then exit(@FCells[Index]);
      if (IsEmpty(ItemKey)) then exit(nil);  //nil pointers denote no-hit 
      Index:= NextIndex(Index);
    end;
  end
  else { if IsEmpty(key) then } begin
    // Check zero cell
    Result:= @FZeroCell;
  end;
end;

Nullable<T>ミスを示すために aは必要ないことに注意してください。私は標準的なnilポインタが動作します。

型キャストを行う必要はなく、ポインタはそれがどれだけ大きいかを認識しています。何が何で
あるか について少し知っています。 T

ジェネリックには多くの落とし穴があることを知っているので、次のようにします。

深く入り込む前に。
これは(原則として)機能しますか、それともこのアプローチは単なる希望的観測ですか?

4

1 に答える 1