13c827367444ee418f129b2c238299f49d3264554Jarkko Poyryunit Antlr.Runtime.Collections;
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry(*
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry[The "BSD licence"]
43c827367444ee418f129b2c238299f49d3264554Jarkko PoyryCopyright (c) 2008 Erik van Bilsen
53c827367444ee418f129b2c238299f49d3264554Jarkko PoyryCopyright (c) 2005-2007 Kunle Odutola
63c827367444ee418f129b2c238299f49d3264554Jarkko PoyryAll rights reserved.
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
83c827367444ee418f129b2c238299f49d3264554Jarkko PoyryRedistribution and use in source and binary forms, with or without
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyrymodification, are permitted provided that the following conditions
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyryare met:
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry1. Redistributions of source code MUST RETAIN the above copyright
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry   notice, this list of conditions and the following disclaimer.
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry2. Redistributions in binary form MUST REPRODUCE the above copyright
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry   notice, this list of conditions and the following disclaimer in 
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry   the documentation and/or other materials provided with the 
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry   distribution.
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry3. The name of the author may not be used to endorse or promote products
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry   derived from this software without specific prior WRITTEN permission.
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry4. Unless explicitly state otherwise, any contribution intentionally 
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry   submitted for inclusion in this work to the copyright owner or licensor
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry   shall be under the terms and conditions of this license, without any 
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry   additional terms or conditions.
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTHIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
253c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
263c827367444ee418f129b2c238299f49d3264554Jarkko PoyryOF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
273c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
283c827367444ee418f129b2c238299f49d3264554Jarkko PoyryINCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
293c827367444ee418f129b2c238299f49d3264554Jarkko PoyryNOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
303c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
313c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
333c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTHIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry*)
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinterface
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{$IF CompilerVersion < 20}
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{$MESSAGE ERROR 'You need Delphi 2009 or higher to use the Antlr runtime'}
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{$IFEND}
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyryuses
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  Generics.Collections,
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  Antlr.Runtime.Tools;
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytype
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  /// <summary>
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  /// An Hashtable-backed dictionary that enumerates Keys and Values in
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  /// insertion order.
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  /// </summary>
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  IHashList<TKey, TValue> = interface(IDictionary<TKey, TValue>)
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  end;
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  /// <summary>
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  /// Stack abstraction that also supports the IList interface
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  /// </summary>
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  IStackList<T> = interface(IList<T>)
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    { Methods }
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    /// <summary>
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    /// Adds an element to the top of the stack list.
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    /// </summary>
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    procedure Push(const Item: T);
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    /// <summary>
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    /// Removes the element at the top of the stack list and returns it.
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    /// </summary>
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    /// <returns>The element at the top of the stack.</returns>
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    function Pop: T;
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    /// <summary>
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    /// Removes the element at the top of the stack list without removing it.
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    /// </summary>
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    /// <returns>The element at the top of the stack.</returns>
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    function Peek: T;
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  end;
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytype
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  THashList<TKey, TValue> = class(TANTLRObject, IHashList<TKey, TValue>)
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  strict private
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    type
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      TPairEnumerator = class(TEnumerator<TPair<TKey, TValue>>)
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      private
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        FHashList: THashList<TKey, TValue>;
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        FOrderList: IList<TKey>;
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        FIndex: Integer;
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        FVersion: Integer;
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        FPair: TPair<TKey, TValue>;
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        function GetCurrent: TPair<TKey, TValue>;
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      protected
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        function DoGetCurrent: TPair<TKey, TValue>; override;
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        function DoMoveNext: Boolean; override;
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      public
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        constructor Create(const AHashList: THashList<TKey, TValue>);
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        function MoveNext: Boolean;
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        property Current: TPair<TKey, TValue> read GetCurrent;
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      end;
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  private
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    FDictionary: IDictionary<TKey, TValue>;
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    FInsertionOrderList: IList<TKey>;
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    FVersion: Integer;
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  protected
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    { IDictionary<TKey, TValue> }
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    function GetItem(const Key: TKey): TValue;
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    procedure SetItem(const Key: TKey; const Value: TValue);
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    function GetCount: Integer;
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    procedure Add(const Key: TKey; const Value: TValue);
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    procedure Remove(const Key: TKey);
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    procedure Clear;
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    procedure TrimExcess;
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    function TryGetValue(const Key: TKey; out Value: TValue): Boolean;
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    procedure AddOrSetValue(const Key: TKey; const Value: TValue);
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    function ContainsKey(const Key: TKey): Boolean;
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    function ContainsValue(const Value: TValue): Boolean;
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  public
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    constructor Create; overload;
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    constructor Create(const ACapacity: Integer); overload;
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    function GetEnumerator: TEnumerator<TPair<TKey, TValue>>;
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    property Items[const Key: TKey]: TValue read GetItem write SetItem; default;
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  end;
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  TStackList<T> = class(TList<T>, IStackList<T>)
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  protected
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    { IStackList<T> }
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    procedure Push(const Item: T);
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    function Pop: T;
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    function Peek: T;
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  end;
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  TCollectionUtils = class
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  public
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    /// <summary>
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    /// Returns a string representation of this IDictionary.
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    /// </summary>
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    /// <remarks>
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    /// The string representation is a list of the collection's elements in the order
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    /// they are returned by its enumerator, enclosed in curly brackets ("{}").
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    /// The separator is a comma followed by a space i.e. ", ".
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    /// </remarks>
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    /// <param name="dict">Dictionary whose string representation will be returned</param>
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    /// <returns>A string representation of the specified dictionary or "null"</returns>
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    class function DictionaryToString(const Dict: IDictionary<Integer, IList<IANTLRInterface>>): String; static;
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    /// <summary>
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    /// Returns a string representation of this IList.
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    /// </summary>
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    /// <remarks>
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    /// The string representation is a list of the collection's elements in the order
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    /// they are returned by its enumerator, enclosed in square brackets ("[]").
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    /// The separator is a comma followed by a space i.e. ", ".
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    /// </remarks>
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    /// <param name="coll">Collection whose string representation will be returned</param>
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    /// <returns>A string representation of the specified collection or "null"</returns>
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    class function ListToString(const Coll: IList<IANTLRInterface>): String; overload; static;
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    class function ListToString(const Coll: IList<String>): String; overload; static;
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  end;
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryimplementation
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyryuses
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  Classes,
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  SysUtils;
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ THashList<TKey, TValue> }
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprocedure THashList<TKey, TValue>.Add(const Key: TKey; const Value: TValue);
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybegin
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  FDictionary.Add(Key, Value);
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  FInsertionOrderList.Add(Key);
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  Inc(FVersion);
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryend;
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprocedure THashList<TKey, TValue>.AddOrSetValue(const Key: TKey;
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  const Value: TValue);
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybegin
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  if FDictionary.ContainsKey(Key) then
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    SetItem(Key, Value)
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  else
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    Add(Key, Value);
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyryend;
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprocedure THashList<TKey, TValue>.Clear;
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybegin
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  FDictionary.Clear;
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  FInsertionOrderList.Clear;
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  Inc(FVersion);
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyryend;
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfunction THashList<TKey, TValue>.ContainsKey(const Key: TKey): Boolean;
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybegin
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  Result := FDictionary.ContainsKey(Key);
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyryend;
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfunction THashList<TKey, TValue>.ContainsValue(const Value: TValue): Boolean;
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybegin
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  Result := FDictionary.ContainsValue(Value);
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyryend;
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconstructor THashList<TKey, TValue>.Create;
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybegin
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  Create(-1);
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyryend;
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconstructor THashList<TKey, TValue>.Create(const ACapacity: Integer);
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybegin
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  inherited Create;
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  if (ACapacity < 0) then
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  begin
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    FDictionary := TDictionary<TKey, TValue>.Create;
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    FInsertionOrderList := TList<TKey>.Create;
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  end
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  else
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  begin
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    FDictionary := TDictionary<TKey, TValue>.Create(ACapacity);
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    FInsertionOrderList := TList<TKey>.Create;
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    FInsertionOrderList.Capacity := ACapacity;
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  end;
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyryend;
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfunction THashList<TKey, TValue>.GetCount: Integer;
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybegin
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  Result := FDictionary.Count;
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyryend;
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfunction THashList<TKey, TValue>.GetEnumerator: TEnumerator<TPair<TKey, TValue>>;
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybegin
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  Result := TPairEnumerator.Create(Self);
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyryend;
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfunction THashList<TKey, TValue>.GetItem(const Key: TKey): TValue;
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybegin
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  Result := FDictionary[Key];
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyryend;
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprocedure THashList<TKey, TValue>.Remove(const Key: TKey);
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybegin
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  FDictionary.Remove(Key);
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  FInsertionOrderList.Remove(Key);
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  Inc(FVersion);
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyryend;
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprocedure THashList<TKey, TValue>.SetItem(const Key: TKey; const Value: TValue);
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvar
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  IsNewEntry: Boolean;
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybegin
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  IsNewEntry := (not FDictionary.ContainsKey(Key));
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  FDictionary[Key] := Value;
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  if (IsNewEntry) then
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    FInsertionOrderList.Add(Key);
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  Inc(FVersion);
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryend;
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprocedure THashList<TKey, TValue>.TrimExcess;
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybegin
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  FDictionary.TrimExcess;
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  FInsertionOrderList.Capacity := FDictionary.Count;
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryend;
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfunction THashList<TKey, TValue>.TryGetValue(const Key: TKey;
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  out Value: TValue): Boolean;
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybegin
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  Result := FDictionary.TryGetValue(Key,Value);
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryend;
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ THashList<TKey, TValue>.TPairEnumerator }
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconstructor THashList<TKey, TValue>.TPairEnumerator.Create(
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  const AHashList: THashList<TKey, TValue>);
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybegin
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  inherited Create;
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  FHashList := AHashList;
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  FVersion := FHashList.FVersion;
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  FOrderList := FHashList.FInsertionOrderList;
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyryend;
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfunction THashList<TKey, TValue>.TPairEnumerator.DoGetCurrent: TPair<TKey, TValue>;
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybegin
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  Result := GetCurrent;
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyryend;
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfunction THashList<TKey, TValue>.TPairEnumerator.DoMoveNext: Boolean;
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybegin
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  Result := MoveNext;
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyryend;
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfunction THashList<TKey, TValue>.TPairEnumerator.GetCurrent: TPair<TKey, TValue>;
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybegin
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  Result := FPair;
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyryend;
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfunction THashList<TKey, TValue>.TPairEnumerator.MoveNext: Boolean;
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybegin
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  if (FVersion <> FHashList.FVersion) then
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    raise EInvalidOperation.Create('Collection was modified; enumeration operation may not execute.');
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  if (FIndex < FOrderList.Count) then
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  begin
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    FPair.Key := FOrderList[FIndex];
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    FPair.Value := FHashList[FPair.Key];
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    Inc(FIndex);
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    Result := True;
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  end
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  else
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  begin
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    FPair.Key := Default(TKey);
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    FPair.Value := Default(TValue);
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    Result := False;
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  end;
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyryend;
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ TStackList<T> }
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfunction TStackList<T>.Peek: T;
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybegin
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  Result := GetItem(GetCount - 1);
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyryend;
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfunction TStackList<T>.Pop: T;
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvar
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  I: Integer;
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybegin
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  I := GetCount - 1;
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  Result := GetItem(I);
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  Delete(I);
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyryend;
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprocedure TStackList<T>.Push(const Item: T);
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybegin
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  Add(Item);
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyryend;
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ TCollectionUtils }
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass function TCollectionUtils.DictionaryToString(
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  const Dict: IDictionary<Integer, IList<IANTLRInterface>>): String;
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvar
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  SB: TStringBuilder;
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  I: Integer;
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  E: TPair<Integer, IList<IANTLRInterface>>;
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybegin
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  SB := TStringBuilder.Create;
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  try
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    if Assigned(Dict) then
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    begin
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      SB.Append('{');
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      I := 0;
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      for E in Dict do
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      begin
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        if (I > 0) then
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry          SB.Append(', ');
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        SB.AppendFormat('%d=%s', [E.Key, ListToString(E.Value)]);
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        Inc(I);
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      end;
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      SB.Append('}');
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    end
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    else
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      SB.Insert(0, 'null');
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    Result := SB.ToString;
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  finally
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    SB.Free;
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  end;
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryend;
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass function TCollectionUtils.ListToString(
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  const Coll: IList<IANTLRInterface>): String;
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvar
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  SB: TStringBuilder;
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  I: Integer;
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  Element: IANTLRInterface;
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  Dict: IDictionary<Integer, IList<IANTLRInterface>>;
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  List: IList<IANTLRInterface>;
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybegin
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  SB := TStringBuilder.Create;
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  try
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    if (Coll <> nil) then
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    begin
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      SB.Append('[');
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      for I := 0 to Coll.Count - 1 do
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      begin
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        if (I > 0) then
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry          SB.Append(', ');
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        Element := Coll[I];
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        if (Element = nil) then
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry          SB.Append('null')
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        else
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        if Supports(Element, IDictionary<Integer, IList<IANTLRInterface>>, Dict) then
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry          SB.Append(DictionaryToString(Dict))
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        else
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        if Supports(Element, IList<IANTLRInterface>, List) then
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry          SB.Append(ListToString(List))
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        else
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry          SB.Append(Element.ToString);
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      end;
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      SB.Append(']');
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    end
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    else
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      SB.Insert(0, 'null');
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    Result := SB.ToString;
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  finally
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    SB.Free;
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  end;
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyryend;
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass function TCollectionUtils.ListToString(const Coll: IList<String>): String;
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvar
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  SB: TStringBuilder;
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  I: Integer;
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybegin
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  SB := TStringBuilder.Create;
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  try
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    if (Coll <> nil) then
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    begin
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      SB.Append('[');
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      for I := 0 to Coll.Count - 1 do
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      begin
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        if (I > 0) then
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry          SB.Append(', ');
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        SB.Append(Coll[I]);
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      end;
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      SB.Append(']');
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    end
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    else
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      SB.Insert(0, 'null');
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    Result := SB.ToString;
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  finally
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    SB.Free;
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  end;
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyryend;
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyryend.
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry