title: How do you design FIFO queue with variable data size?
body: <p>I'm just working on the FIFO queue (the simple one, just what's pushed first, pops at first) with the variable data size but I'm not sure with the way I'm designing it. The data types I will store there will be known in advance and let's say will be the same for each instance of this class. I was thinking about using TList where the records with the following definition will be stored (@David - it's for D2007, so I have no <a href="http://docwiki.embarcadero.com/VCL/en/Generics.Collections" rel="nofollow">Generics.Collections</a> available :)</p>
  
  <pre><code>type
    PListItem = ^TListItem;
    TListItem = record
      Size: Integer; // size of the data pointed by the following member
      Data: Pointer; // pointer to the target data reserved in memory
    end;
  </code></pre>
  
  <p>with the implementation like this (I'm pretending here that everything works fine, so no exception handling is used)</p>
  
  <pre><code>type
    TListQueue = class
  private
    FList: TList;
  public
    constructor Create;
    destructor Destroy; override;
    procedure Clear;
    procedure Push(const Value; const Size: Integer);
    procedure Pop(var Value; var Size: Integer);
  end;
  
  constructor TListQueue.Create;
  begin
    inherited;
    FList := TList.Create;
  end;
  
  destructor TListQueue.Destroy;
  begin
    Clear;
    FList.Free;
    inherited;
  end;
  
  procedure TListQueue.Push(const Value; const Size: Integer);
  var ListItem: PListItem;
  begin
    New(ListItem);
    ListItem.Size := Size;
    ListItem.Data := AllocMem(Size);
    Move(Value, ListItem.Data^, Size);
    FList.Add(ListItem);
  end;
  
  procedure TListQueue.Pop(var Value; var Size: Integer);
  var ListItem: PListItem;
  begin
    if FList.Count &gt; 0 then
    begin
      ListItem := FList.Items[0];
      Size := ListItem^.Size;
      Move(ListItem.Data^, Value, ListItem.Size);
      FreeMem(ListItem.Data, ListItem.Size);
      Dispose(ListItem);
      FList.Delete(0);
    end;
  end;
  
  procedure TListQueue.Clear;
  var I: Integer;
      ListItem: PListItem;
  begin
    for I := 0 to FList.Count - 1 do
    begin
      ListItem := FList.Items[I];
      FreeMem(ListItem.Data, ListItem.Size);
      Dispose(ListItem);
    end;
    FList.Clear;
  end;
  </code></pre>
  
  <p>My question is:<br><br>
  Is this the efficient way how to make FIFO queue (for data types like strings, streams, records) with size from several bytes to about 1MB (in case of stream) ?</p>
  
  <p>Thanks a lot</p>