Browse Source

Merge pull request #10 from maciej-izak/master

Update Generics.* library to latest version with pointer optimization…
Herman Schoenfeld 7 years ago
parent
commit
75036b7328

File diff suppressed because it is too large
+ 174 - 154
PasOpenCL/CL.pas


+ 28 - 20
PasOpenCL/CL_GL.pas

@@ -107,20 +107,22 @@ const
   CL_CGL_SHAREGROUP_KHR         =  $200C;
 
 
+{$IFDEF DYNLINK}
 type
+{$ENDIF}
 {$IFDEF CL_VERSION_1_0}
-  TclCreateFromGLBuffer = function (
+  {$IFDEF DYNLINK}TclCreateFromGLBuffer = {$ENDIF}function {$IFNDEF DYNLINK}clCreateFromGLBuffer{$ENDIF}(
                                       context: Pcl_context;                     (* context *)
                                       flags: Tcl_mem_flags;                     (* flags *)
                                       bufobj:  GLuint;                          (* bufobj *)
                                       errcode_ret: PInteger                     (* errcode_ret *)
                                       ): PCL_mem;
-                                      {$IFDEF CDECL}cdecl{$ELSE}stdcall{$ENDIF};
+                                      extdecl; {$IFNDEF DYNLINK}external name 'clCreateFromGLBuffer';{$ENDIF}
 {$ENDIF}
 
 {$IFDEF CL_VERSION_1_0}
   {$IFDEF CL_USE_DEPRECATED_OPENCL_1_1_APIS}
-    TclCreateFromGLTexture2D = function (
+    {$IFDEF DYNLINK}TclCreateFromGLTexture2D = {$ENDIF}function {$IFNDEF DYNLINK}clCreateFromGLTexture2D{$ENDIF}(
                                          context: Pcl_context;                  (* context *)
                                          flags: Tcl_mem_flags;                  (* flags *)
                                          target: GLenum;                        (* target *)
@@ -128,13 +130,13 @@ type
                                          texture: GLuint;                       (* texture *)
                                          errcode_ret: Pcl_int                   (* errcode_ret *)
                                          ): PCL_mem;
-                                         {$IFDEF CDECL}cdecl{$ELSE}stdcall{$ENDIF};
+                                         extdecl; {$IFNDEF DYNLINK}external name 'clCreateFromGLTexture2D';{$ENDIF}
   {$ENDIF}
 {$ENDIF}
 
 {$IFDEF CL_VERSION_1_0}
   {$IFDEF CL_USE_DEPRECATED_OPENCL_1_1_APIS}
-    TclCreateFromGLTexture3D = function (
+    {$IFDEF DYNLINK}TclCreateFromGLTexture3D = {$ENDIF}function {$IFNDEF DYNLINK}clCreateFromGLTexture3D{$ENDIF}(
                                          context: Pcl_context;                  (* context *)
                                          flags: Tcl_mem_flags;                  (* flags *)
                                          target: GLenum;                        (* target *)
@@ -142,12 +144,12 @@ type
                                          texture: GLuint;                       (* texture *)
                                          errcode_ret: Pcl_int                   (* errcode_ret *)
                                          ): PCL_mem;
-                                         {$IFDEF CDECL}cdecl{$ELSE}stdcall{$ENDIF};
+                                         extdecl; {$IFNDEF DYNLINK}external name 'clCreateFromGLTexture3D';{$ENDIF}
   {$ENDIF}
 {$ENDIF}
 
 {$IFDEF CL_VERSION_1_2}
-  TclCreateFromGLTexture = function(
+  {$IFDEF DYNLINK}TclCreateFromGLTexture = {$ENDIF}function {$IFNDEF DYNLINK}clCreateFromGLTexture{$ENDIF}(
                                          context: Pcl_context;                  (* context *)
                                          flags: Tcl_mem_flags;                  (* flags *)
                                          target: GLenum;                        (* target *)
@@ -155,41 +157,41 @@ type
                                          texture: GLuint;                       (* texture *)
                                          errcode_ret: Pcl_int                   (* errcode_ret *)
                                          ): PCL_mem;
-                                         {$IFDEF CDECL}cdecl{$ELSE}stdcall{$ENDIF};
+                                         extdecl; {$IFNDEF DYNLINK}external name 'clCreateFromGLTexture';{$ENDIF}
 {$ENDIF}
 
 {$IFDEF CL_VERSION_1_0}
-  TclCreateFromGLRenderbuffer = function (
+  {$IFDEF DYNLINK}TclCreateFromGLRenderbuffer = {$ENDIF}function {$IFNDEF DYNLINK}clCreateFromGLRenderbuffer{$ENDIF}(
                                             context: Pcl_context;               (* context *)
                                             flags: Tcl_mem_flags;               (* flags *)
                                             renderbuffer: GLuint;               (* renderbuffer *)
                                             errcode_ret: Pcl_int                (* errcode_ret *)
                                             ): Pcl_mem;
-                                            {$IFDEF CDECL}cdecl{$ELSE}stdcall{$ENDIF};
+                                            extdecl; {$IFNDEF DYNLINK}external name 'clCreateFromGLRenderbuffer';{$ENDIF}
 {$ENDIF}
 
 {$IFDEF CL_VERSION_1_0}
-  TclGetGLObjectInfo = function (
+  {$IFDEF DYNLINK}TclGetGLObjectInfo = {$ENDIF}function {$IFNDEF DYNLINK}clGetGLObjectInfo{$ENDIF}(
                                    memobj: Pcl_mem;                             (* memobj *)
                                    gl_object_type: Pcl_gl_object_type;          (* gl_object_type *)
                                    gl_object_name: PGLuint                      (* gl_object_name *)
                                    ): TCL_int;
-                                   {$IFDEF CDECL}cdecl{$ELSE}stdcall{$ENDIF};
+                                   extdecl; {$IFNDEF DYNLINK}external name 'clGetGLObjectInfo';{$ENDIF}
 {$ENDIF}
 
 {$IFDEF CL_VERSION_1_0}
-  TclGetGLTextureInfo = function (
+  {$IFDEF DYNLINK}TclGetGLTextureInfo = {$ENDIF}function {$IFNDEF DYNLINK}clGetGLTextureInfo{$ENDIF}(
                                     memobj: Pcl_mem;                            (* memobj *)
                                     param_name: Tcl_gl_texture_info;            (* param_name *)
                                     param_value_size: Tsize_t;                  (* param_value_size *)
                                     param_value: Pointer;                       (* param_value *)
                                     param_value_size_ret: Psize_t               (* param_value_size_ret *)
                                     ): TCL_int;
-                                    {$IFDEF CDECL}cdecl{$ELSE}stdcall{$ENDIF};
+                                    extdecl; {$IFNDEF DYNLINK}external name 'clGetGLTextureInfo';{$ENDIF}
 {$ENDIF}
 
 {$IFDEF CL_VERSION_1_0}
-  TclEnqueueAcquireGLObjects = function (
+  {$IFDEF DYNLINK}TclEnqueueAcquireGLObjects = {$ENDIF}function {$IFNDEF DYNLINK}clEnqueueAcquireGLObjects{$ENDIF}(
                                            command_queue: Pcl_command_queue;    (* command_queue *)
                                            num_objects: Tcl_uint;               (* num_objects *)
                                            const mem_objects: PPcl_mem;         (* mem_objects *)
@@ -197,11 +199,11 @@ type
                                            const event_wait_list: PPcl_event;   (* event_wait_list *)
                                            event: PPcl_event                    (* event *)
                                            ): TCL_int;
-                                           {$IFDEF CDECL}cdecl{$ELSE}stdcall{$ENDIF};
+                                           extdecl; {$IFNDEF DYNLINK}external name 'clEnqueueAcquireGLObjects';{$ENDIF}
 {$ENDIF}
 
 {$IFDEF CL_VERSION_1_0}
-  TclEnqueueReleaseGLObjects = function (
+  {$IFDEF DYNLINK}TclEnqueueReleaseGLObjects = {$ENDIF}function {$IFNDEF DYNLINK}clEnqueueReleaseGLObjects{$ENDIF}(
                                            command_queue: Pcl_command_queue;    (* command_queue *)
                                            num_objects: Tcl_uint;               (* num_objects *)
                                            const mem_objects: PPcl_mem;         (* mem_objects *)
@@ -209,7 +211,7 @@ type
                                            const event_wait_list: PPcl_event;   (* event_wait_list *)
                                            event: PPcl_event                    (* event *)
                                            ): TCL_int;
-                                           {$IFDEF CDECL}cdecl{$ELSE}stdcall{$ENDIF};
+                                           extdecl; {$IFNDEF DYNLINK}external name 'clEnqueueReleaseGLObjects';{$ENDIF}
 {$ENDIF}
 type
      Pcl_gl_context_info = ^Tcl_gl_context_info;
@@ -217,15 +219,16 @@ type
 
 
 {$IFDEF CL_VERSION_1_0}
-  TclGetGLContextInfoKHR = function (
+  {$IFDEF DYNLINK}TclGetGLContextInfoKHR = {$ENDIF}function {$IFNDEF DYNLINK}clGetGLContextInfoKHR{$ENDIF}(
                                        const properties: Pcl_context_properties;(* properties *)
                                        param_name: Tcl_gl_context_info;         (* param_name *)
                                        param_value_size: Tsize_t;               (* param_value_size *)
                                        param_value: Pointer;                    (* param_value *)
                                        param_value_size_ret : Psize_t           (* param_value_size_ret *)
                                        ): TCL_int;
-                                       {$IFDEF CDECL}cdecl{$ELSE}stdcall{$ENDIF};
+                                       extdecl; {$IFNDEF DYNLINK}external name 'clGetGLContextInfoKHR';{$ENDIF}
 {$ENDIF}
+{$IFDEF DYNLINK}
 var
 {$IFDEF CL_VERSION_1_0}
   clCreateFromGLBuffer:       TclCreateFromGLBuffer;
@@ -244,6 +247,7 @@ var
 {$IFDEF CL_VERSION_1_2}
   clCreateFromGLTexture:      TclCreateFromGLTexture;
 {$ENDIF}
+{$ENDIF}
 
 function InitCL_GL: Boolean;
 
@@ -251,6 +255,7 @@ implementation
 
 function InitCL_GL: Boolean;
 begin
+  {$IFDEF DYNLINK}
   Result := False;
   if OCL_LibHandle <> nil then
   begin
@@ -272,6 +277,9 @@ begin
     {$ENDIF}
     Result := True;
   end;
+  {$ELSE}
+  Result := true;
+  {$ENDIF}
 end;
 
 end.

+ 3 - 3
PasOpenCL/DelphiCL.pas

@@ -2192,9 +2192,9 @@ begin
   //MacOsX not yet (Andoid hm....)
   //MacOSX, Linux, Windows: http://www.dyn-lab.com/articles/cl-gl.html
   {$IFDEF WINDOWS}
-    props[1] := wglGetCurrentContext();//glXGetCurrentContext(),
-    props[2] := CL_WGL_HDC_KHR;
-    props[3] := wglGetCurrentDC();//glXGetCurrentDisplay(),
+    props[1] := Pointer(wglGetCurrentContext());//glXGetCurrentContext(),
+    props[2] := Pointer(CL_WGL_HDC_KHR);
+    props[3] := Pointer(wglGetCurrentDC());//glXGetCurrentDisplay(),
   {$ENDIF}
   {$IFDEF LINUX}
     props[1] := glXGetCurrentContext();

+ 14 - 0
PasOpenCL/OpenCL.inc

@@ -16,6 +16,20 @@
 (*                                          *)
 (*********Copyright (c) niello 2008-2011*****)
 
+{$MACRO ON}
+
+{$IFDEF WINDOWS}
+{$DEFINE DYNLINK}
+{$DEFINE extdecl := stdcall}
+{$ENDIF}
+{$IFDEF LINUX}
+{$DEFINE DYNLINK}
+{$DEFINE extdecl := cdecl}
+{$ENDIF}
+{$IFDEF DARWIN}
+{$DEFINE DYNLINK}
+{$DEFINE extdecl := cdecl}
+{$ENDIF}
 
 {$IFDEF MSWINDOWS}
   {$DEFINE WINDOWS}

+ 2 - 2
PascalCoinMiner.pp

@@ -40,7 +40,7 @@ type
     procedure OnMinerValuesChanged(Sender : TObject);
     procedure OnFoundNOnce(Sender : TCustomMinerDeviceThread; Timestamp, nOnce : Cardinal);
     procedure WriteLine(nline : Integer; txt : String);
-    procedure OnInThreadNewLog(logtype : TLogType; Time : TDateTime; ThreadID : Cardinal; Const sender, logtext : AnsiString);
+    procedure OnInThreadNewLog(logtype : TLogType; Time : TDateTime; ThreadID : TThreadID; Const sender, logtext : AnsiString);
   protected
     FWindow32X1,FWindow32Y1,FWindow32X2,FWindow32Y2: DWord;
     FLock : TCriticalSection;
@@ -169,7 +169,7 @@ begin
 end;
 
 procedure TPascalMinerApp.OnInThreadNewLog(logtype: TLogType; Time: TDateTime;
-  ThreadID: Cardinal; const sender, logtext: AnsiString);
+  ThreadID: TThreadID; const sender, logtext: AnsiString);
 var msg : String;
   i,nline : Integer;
 begin

+ 45 - 0
PascalCoinWallet.app/Contents/Info.plist

@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+  <key>CFBundleDevelopmentRegion</key>
+  <string>English</string>
+  <key>CFBundleExecutable</key>
+  <string>PascalCoinWallet</string>
+  <key>CFBundleName</key>
+  <string>PascalCoin Wallet</string>
+  <key>CFBundleIdentifier</key>
+  <string>com.company.PascalCoinWallet</string>
+  <key>CFBundleInfoDictionaryVersion</key>
+  <string>6.0</string>
+  <key>CFBundlePackageType</key>
+  <string>APPL</string>
+  <key>CFBundleSignature</key>
+  <string>Pasc</string>
+  <key>CFBundleShortVersionString</key>
+  <string>0.1</string>
+  <key>CFBundleVersion</key>
+  <string>1</string>
+  <key>CSResourcesFileMapped</key>
+  <true/>
+  <key>CFBundleDocumentTypes</key>
+  <array>
+    <dict>
+      <key>CFBundleTypeRole</key>
+      <string>Viewer</string>
+      <key>CFBundleTypeExtensions</key>
+      <array>
+        <string>*</string>
+      </array>
+      <key>CFBundleTypeOSTypes</key>
+      <array>
+        <string>fold</string>
+        <string>disk</string>
+        <string>****</string>
+      </array>
+    </dict>
+  </array>
+  <key>NSHighResolutionCapable</key>
+  <true/>
+</dict>
+</plist>

+ 1 - 0
PascalCoinWallet.app/Contents/MacOS/PascalCoinWallet

@@ -0,0 +1 @@
+../../../PascalCoinWallet

+ 1 - 0
PascalCoinWallet.app/Contents/PkgInfo

@@ -0,0 +1 @@
+APPL????

+ 4 - 1
PascalCoinWallet.dpr

@@ -1,9 +1,12 @@
 program PascalCoinWallet;
 
 {$mode delphi}
+{$DEFINE UseCThreads}
 
 uses
-  {$IFDEF LINUX}cthreads,{$ENDIF}
+  {$IFDEF UNIX}{$IFDEF UseCThreads}
+  cthreads,
+  {$ENDIF}{$ENDIF}
   Interfaces,
   sysutils,
   UOpenSSL,

+ 0 - 1
PascalCoinWallet.lpi

@@ -12,7 +12,6 @@
       <SessionStorage Value="InProjectDir"/>
       <MainUnit Value="0"/>
       <Title Value="PascalCoin Wallet"/>
-      <UseAppBundle Value="False"/>
       <ResourceType Value="res"/>
       <Icon Value="0"/>
     </General>

+ 5 - 4
Units/Forms/UFRMLogs.pas

@@ -31,7 +31,7 @@ type
     pnlTopLogs: TPanel;
     procedure FormCreate(Sender: TObject);
     procedure FormDestroy(Sender: TObject);
-    procedure OnNewLog(logtype : TLogType; Time : TDateTime; ThreadID : Cardinal; Const sender, logtext : AnsiString);
+    procedure OnNewLog(logtype : TLogType; Time : TDateTime; ThreadID : TThreadID; Const sender, logtext : AnsiString);
   private
     { private declarations }
   public
@@ -58,11 +58,11 @@ begin
   TUserInterface.Log.OnNewLog := nil;
 end;
 
-procedure TFRMLogs.OnNewLog(logtype: TLogType; Time : TDateTime; ThreadID : Cardinal; const sender,logtext: AnsiString);
+procedure TFRMLogs.OnNewLog(logtype: TLogType; Time : TDateTime; ThreadID : TThreadID; const sender,logtext: AnsiString);
 Var s : AnsiString;
 begin
   if (logtype=ltdebug) And (Not cbShowDebugLogs.Checked) then exit;
-  if ThreadID=MainThreadID then s := ' MAIN:' else s:=' TID:';
+  if ThreadID=MainThreadID then s := 'MAIN:' else s:='TID:';
   if MemoLogs.Lines.Count>300 then begin
     // Limit max lines in logs...
     memoLogs.Lines.BeginUpdate;
@@ -72,7 +72,8 @@ begin
       memoLogs.Lines.EndUpdate;
     end;
   end;
-  memoLogs.Lines.Add(formatDateTime('dd/mm/yyyy hh:nn:ss.zzz',Time)+s+IntToHex(ThreadID,8)+' ['+CT_LogType[Logtype]+'] <'+sender+'> '+logtext);
+  memoLogs.Lines.Add('%s %s %p [%s] <%s> %s',
+    [FormatDateTime('dd/mm/yyyy hh:nn:ss.zzz',Time), s, ThreadID, CT_LogType[Logtype], sender, logtext]);
 end;
 
 end.

+ 1 - 1
Units/Forms/UFRMNodes.pas

@@ -220,7 +220,7 @@ begin
     strings.BeginUpdate;
     Try
       strings.Clear;
-      strings.Add('BlackList Updated: '+DateTimeToStr(now)+' by TID:'+IntToHex(TThread.CurrentThread.ThreadID,8));
+      strings.Add('BlackList Updated: %s by TID: %p', [DateTimeToStr(now), TThread.CurrentThread.ThreadID]);
       j := 0; n:=0;
       for i := 0 to l.Count - 1 do begin
         P := l[i];

+ 4 - 0
Units/Forms/UUserInterface.pas

@@ -189,12 +189,16 @@ begin
 
     FTrayIcon := TTrayIcon.Create(FMainForm);
     FTrayIcon.OnDblClick := OnTrayIconDblClick;
+    {$IFNDEF LCLCarbon}
     FTrayIcon.Visible := true;
+    {$ENDIF}
     FTrayIcon.Hint := FMainForm.Caption;
     FTrayIcon.BalloonTitle := 'Restoring the window.';
     FTrayIcon.BalloonHint := 'Double click the system tray icon to restore Pascal Coin';
     FTrayIcon.BalloonFlags := bfInfo;
+    {$IFNDEF LCLCarbon}
     FTrayIcon.Show;
+    {$ENDIF}
     FTimerUpdateStatus := TTimer.Create(FMainForm);
     FTimerUpdateStatus.Enabled := false;
     FDisplayedStartupSyncDialog:=false;

+ 6 - 4
Units/PascalCoin/ULog.pas

@@ -24,7 +24,7 @@ type
   TLogType = (ltinfo, ltupdate, lterror, ltdebug);
   TLogTypes = set of TLogType;
 
-  TNewLogEvent = procedure(logtype : TLogType; Time : TDateTime; ThreadID : Cardinal; Const sender, logtext : AnsiString) of object;
+  TNewLogEvent = procedure(logtype : TLogType; Time : TDateTime; ThreadID : TThreadID; Const sender, logtext : AnsiString) of object;
 
   TLog = Class;
 
@@ -42,7 +42,7 @@ type
   TLogData = Record
     Logtype : TLogType;
     Time : TDateTime;
-    ThreadID : Cardinal;
+    ThreadID : TThreadID;
     Sender, Logtext : AnsiString
   End;
 
@@ -156,8 +156,10 @@ begin
   FLock.Acquire;
   try
     if assigned(FFileStream) And (logType in FSaveTypes) then begin
-      if TThread.CurrentThread.ThreadID=MainThreadID then tid := ' MAIN:' else tid:=' TID:';
-      s := FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz',now)+tid+IntToHex(TThread.CurrentThread.ThreadID,8)+' ['+CT_LogType[logtype]+'] <'+sender+'> '+logtext+#13#10;
+      if TThread.CurrentThread.ThreadID=MainThreadID then tid := 'MAIN:' else tid:='TID:';
+      s := Format('%s %s %p [%s] <%s> %s'#13#10, [
+        FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz',now), tid, Pointer(TThread.CurrentThread.ThreadID), CT_LogType[logtype], sender, logtext
+        ]);
       FFileStream.Write(s[1],length(s));
     end;
     if Assigned(FOnInThreadNewLog) then begin

+ 11 - 0
Units/PascalCoin/UOpenSSL.pas

@@ -28,10 +28,21 @@ Uses UOpenSSLdef;
 
 var
 {$IFDEF UNIX}
+  {$IF not (Defined(LINUX) or Defined(DARWIN))}
+    {$ERROR 'unsupported target'}
+  {$IFEND}
   {$IFDEF OpenSSL10}
+  {$IFDEF LINUX}
   SSL_C_LIB : AnsiString = './libcrypto.so.1.0.0';
   {$ELSE}
+  SSL_C_LIB : AnsiString = './libcrypto.1.0.0.dylib';
+  {$ENDIF}
+  {$ELSE}
+  {$IFDEF LINUX}
   SSL_C_LIB : AnsiString = './libcrypto.so.1.1';
+  {$ELSE}
+  SSL_C_LIB : AnsiString = './libcrypto.1.1.dylib';
+  {$ENDIF}
   {$ENDIF}
 {$ELSE}
   // Windows + Lazarus uses a OpenSSL v1.0 32 or 64 bits

+ 3 - 3
Units/Utils/UFolderHelper.pas

@@ -48,17 +48,17 @@ Type TFileVersionInfo = record
 implementation
 
 uses
-  {$IFnDEF LINUX}
+  {$IF not (Defined(LINUX) or Defined(DARWIN))}
   Windows,
   {$DEFINE FILEVERSIONINFO}
-  {$ENDIF}
+  {$IFEND}
   SysUtils;
 
 {$I .\..\PascalCoin\config.inc}
 
 class function TFolderHelper.GetAppDataFolder: string;
 begin
-  {$IFDEF LINUX}
+  {$IFDEF UNIX}
   Result :=GetEnvironmentVariable('HOME');
   {$ELSE}
   Result :=GetEnvironmentVariable('APPDATA');

+ 411 - 91
Units/Utils/generics.collections.pas

@@ -136,9 +136,14 @@ type
   private
     FOnNotify: TCollectionNotifyEvent<T>;
     function GetCapacity: SizeInt; inline;
+  private type
+    PItems = ^TItems;
+    TItems = record
+      FLength: SizeInt;
+      FItems: array of T;
+    end;
   protected
-    FItemsLength: SizeInt;
-    FItems: array of T;
+    FItems: TItems;
 
     function PrepareAddingItem: SizeInt; virtual;
     function PrepareAddingRange(ACount: SizeInt): SizeInt; virtual;
@@ -154,7 +159,7 @@ type
     property OnNotify: TCollectionNotifyEvent<T> read FOnNotify write FOnNotify;
   end;
 
-  TCustomListEnumerator<T> = class abstract(TEnumerator< T >)
+  TCustomListEnumerator<T> = class abstract(TEnumerator<T>)
   private
     FList: TCustomList<T>;
     FIndex: SizeInt;
@@ -166,7 +171,48 @@ type
     constructor Create(AList: TCustomList<T>);
   end;
 
-  TList<T> = class(TCustomList<T>)
+  TCustomListPointersEnumerator<T, PT> = class abstract(TEnumerator<PT>)
+  private type
+    TList = TCustomList<T>; // lazarus bug workaround
+  private var
+    FList: TList.PItems;
+    FIndex: SizeInt;
+  protected
+    function DoMoveNext: boolean; override;
+    function DoGetCurrent: PT; override;
+    function GetCurrent: PT; virtual;
+  public
+    constructor Create(AList: TList.PItems);
+  end;
+
+  TCustomListPointersCollection<TPointersEnumerator, T, PT> = record
+  private type
+    TList = TCustomList<T>; // lazarus bug workaround
+  private
+    function List: TList.PItems; inline;
+    function GetCount: SizeInt; inline;
+    function GetItem(AIndex: SizeInt): PT;
+  public
+    function GetEnumerator: TPointersEnumerator;
+    function ToArray: TArray<PT>;
+    property Count: SizeInt read GetCount;
+    property Items[Index: SizeInt]: PT read GetItem; default;
+  end;
+
+  TCustomListWithPointers<T> = class(TCustomList<T>)
+  public type
+    PT = ^T;
+  private type
+    TPointersEnumerator = class(TCustomListPointersEnumerator<T, PT>);
+    PPointersCollection = ^TPointersCollection;
+    TPointersCollection = TCustomListPointersCollection<TPointersEnumerator, T, PT>;
+  private
+    function GetPointers: PPointersCollection; inline;
+  public
+    property Ptr: PPointersCollection read GetPointers;
+  end;
+
+  TList<T> = class(TCustomListWithPointers<T>)
   private var
     FComparer: IComparer<T>;
   protected
@@ -230,7 +276,7 @@ type
     function BinarySearch(constref AItem: T; out AIndex: SizeInt): Boolean; overload;
     function BinarySearch(constref AItem: T; out AIndex: SizeInt; const AComparer: IComparer<T>): Boolean; overload;
 
-    property Count: SizeInt read FItemsLength write SetCount;
+    property Count: SizeInt read FItems.FLength write SetCount;
     property Items[Index: SizeInt]: T read GetItem write SetItem; default;
   end;
 
@@ -284,7 +330,7 @@ type
     procedure TrimExcess;
   end;
 
-  TStack<T> = class(TCustomList<T>)
+  TStack<T> = class(TCustomListWithPointers<T>)
   protected
   // bug #24287 - workaround for generics type name conflict (Identifier not found)
   // next bug workaround - for another error related to previous workaround
@@ -349,8 +395,53 @@ type
 
 {$I generics.dictionariesh.inc}
 
+  { THashSet }
+
+  THashSet<T> = class(TEnumerable<T>)
+  protected
+    FInternalDictionary : TDictionary<T, TEmptyRecord>;
+    function DoGetEnumerator: TEnumerator<T>; override;
+  public type
+    TSetEnumerator = class(TEnumerator<T>)
+    protected
+      FEnumerator: TDictionary<T, TEmptyRecord>.TKeyEnumerator;
+      function DoMoveNext: boolean; override;
+      function DoGetCurrent: T; override;
+      function GetCurrent: T; virtual;
+    public
+      constructor Create(ASet: THashSet<T>);
+      destructor Destroy; override;
+    end;
+  private
+    function GetCount: SizeInt; inline;
+    function GetPointers: TDictionary<T, TEmptyRecord>.TKeyCollection.PPointersCollection; inline;
+  public type
+    TEnumerator = TSetEnumerator;
+    PT = ^T;
+
+    function GetEnumerator: TEnumerator; reintroduce;
+  public
+    constructor Create; overload;
+    constructor Create(const AComparer: IEqualityComparer<T>); overload;
+    constructor Create(ACollection: TEnumerable<T>); overload;
+    destructor Destroy; override;
+    function Add(constref AValue: T): Boolean;
+    function Remove(constref AValue: T): Boolean;
+    procedure Clear;
+    function Contains(constref AValue: T): Boolean; inline;
+    procedure UnionWith(AHashSet: THashSet<T>);
+    procedure IntersectWith(AHashSet: THashSet<T>);
+    procedure ExceptWith(AHashSet: THashSet<T>);
+    procedure SymmetricExceptWith(AHashSet: THashSet<T>);
+    property Count: SizeInt read GetCount;
+    property Ptr: TDictionary<T, TEmptyRecord>.TKeyCollection.PPointersCollection read GetPointers;
+  end;
+
 function InCircularRange(ABottom, AItem, ATop: SizeInt): Boolean;
 
+var
+  EmptyRecord: TEmptyRecord;
+
 implementation
 
 function InCircularRange(ABottom, AItem, ATop: SizeInt): Boolean;
@@ -554,17 +645,17 @@ end;
 
 function TCustomList<T>.PrepareAddingItem: SizeInt;
 begin
-  Result := Length(FItems);
+  Result := Length(FItems.FItems);
 
-  if (FItemsLength < 4) and (Result < 4) then
-    SetLength(FItems, 4)
-  else if FItemsLength = High(FItemsLength) then
+  if (FItems.FLength < 4) and (Result < 4) then
+    SetLength(FItems.FItems, 4)
+  else if FItems.FLength = High(FItems.FLength) then
     OutOfMemoryError
-  else if FItemsLength = Result then
-    SetLength(FItems, CUSTOM_LIST_CAPACITY_INC);
+  else if FItems.FLength = Result then
+    SetLength(FItems.FItems, CUSTOM_LIST_CAPACITY_INC);
 
-  Result := FItemsLength;
-  Inc(FItemsLength);
+  Result := FItems.FLength;
+  Inc(FItems.FLength);
 end;
 
 function TCustomList<T>.PrepareAddingRange(ACount: SizeInt): SizeInt;
@@ -572,22 +663,22 @@ begin
   if ACount < 0 then
     raise EArgumentOutOfRangeException.CreateRes(@SArgumentOutOfRange);
   if ACount = 0 then
-    Exit(FItemsLength - 1);
+    Exit(FItems.FLength - 1);
 
-  if (FItemsLength = 0) and (Length(FItems) = 0) then
-    SetLength(FItems, 4)
-  else if FItemsLength = High(FItemsLength) then
+  if (FItems.FLength = 0) and (Length(FItems.FItems) = 0) then
+    SetLength(FItems.FItems, 4)
+  else if FItems.FLength = High(FItems.FLength) then
     OutOfMemoryError;
 
-  Result := Length(FItems);
-  while Pred(FItemsLength + ACount) >= Result do
+  Result := Length(FItems.FItems);
+  while Pred(FItems.FLength + ACount) >= Result do
   begin
-    SetLength(FItems, CUSTOM_LIST_CAPACITY_INC);
-    Result := Length(FItems);
+    SetLength(FItems.FItems, CUSTOM_LIST_CAPACITY_INC);
+    Result := Length(FItems.FItems);
   end;
 
-  Result := FItemsLength;
-  Inc(FItemsLength, ACount);
+  Result := FItems.FLength;
+  Inc(FItems.FLength, ACount);
 end;
 
 function TCustomList<T>.ToArray: TArray<T>;
@@ -597,7 +688,7 @@ end;
 
 function TCustomList<T>.GetCount: SizeInt;
 begin
-  Result := FItemsLength;
+  Result := FItems.FLength;
 end;
 
 procedure TCustomList<T>.Notify(constref AValue: T; ACollectionNotification: TCollectionNotification);
@@ -608,17 +699,17 @@ end;
 
 function TCustomList<T>.DoRemove(AIndex: SizeInt; ACollectionNotification: TCollectionNotification): T;
 begin
-  if (AIndex < 0) or (AIndex >= FItemsLength) then
+  if (AIndex < 0) or (AIndex >= FItems.FLength) then
     raise EArgumentOutOfRangeException.CreateRes(@SArgumentOutOfRange);
 
-  Result := FItems[AIndex];
-  Dec(FItemsLength);
+  Result := FItems.FItems[AIndex];
+  Dec(FItems.FLength);
 
-  FItems[AIndex] := Default(T);
-  if AIndex <> FItemsLength then
+  FItems.FItems[AIndex] := Default(T);
+  if AIndex <> FItems.FLength then
   begin
-    System.Move(FItems[AIndex + 1], FItems[AIndex], (FItemsLength - AIndex) * SizeOf(T));
-    FillChar(FItems[FItemsLength], SizeOf(T), 0);
+    System.Move(FItems.FItems[AIndex + 1], FItems.FItems[AIndex], (FItems.FLength - AIndex) * SizeOf(T));
+    FillChar(FItems.FItems[FItems.FLength], SizeOf(T), 0);
   end;
 
   Notify(Result, ACollectionNotification);
@@ -626,7 +717,7 @@ end;
 
 function TCustomList<T>.GetCapacity: SizeInt;
 begin
-  Result := Length(FItems);
+  Result := Length(FItems.FItems);
 end;
 
 { TCustomListEnumerator<T> }
@@ -634,7 +725,7 @@ end;
 function TCustomListEnumerator<T>.DoMoveNext: boolean;
 begin
   Inc(FIndex);
-  Result := (FList.FItemsLength <> 0) and (FIndex < FList.FItemsLength)
+  Result := (FList.FItems.FLength <> 0) and (FIndex < FList.FItems.FLength)
 end;
 
 function TCustomListEnumerator<T>.DoGetCurrent: T;
@@ -644,7 +735,7 @@ end;
 
 function TCustomListEnumerator<T>.GetCurrent: T;
 begin
-  Result := FList.FItems[FIndex];
+  Result := FList.FItems.FItems[FIndex];
 end;
 
 constructor TCustomListEnumerator<T>.Create(AList: TCustomList<T>);
@@ -654,6 +745,85 @@ begin
   FList := AList;
 end;
 
+{ TCustomListPointersEnumerator<T, PT> }
+
+function TCustomListPointersEnumerator<T, PT>.DoMoveNext: boolean;
+begin
+  Inc(FIndex);
+  Result := (FList.FLength <> 0) and (FIndex < FList.FLength)
+end;
+
+function TCustomListPointersEnumerator<T, PT>.DoGetCurrent: PT;
+begin
+  Result := GetCurrent;
+end;
+
+function TCustomListPointersEnumerator<T, PT>.GetCurrent: PT;
+begin
+  Result := @FList.FItems[FIndex];
+end;
+
+constructor TCustomListPointersEnumerator<T, PT>.Create(AList: TCustomList<T>.PItems);
+begin
+  inherited Create;
+  FIndex := -1;
+  FList := AList;
+end;
+
+{ TCustomListPointersCollection<TPointersEnumerator, T, PT> }
+
+function TCustomListPointersCollection<TPointersEnumerator, T, PT>.List: TCustomList<T>.PItems;
+begin
+  Result := @(TCustomList<T>.TItems(Pointer(@Self)^));
+end;
+
+function TCustomListPointersCollection<TPointersEnumerator, T, PT>.GetCount: SizeInt;
+begin
+  Result := List.FLength;
+end;
+
+function TCustomListPointersCollection<TPointersEnumerator, T, PT>.GetItem(AIndex: SizeInt): PT;
+begin
+  Result := @List.FItems[AIndex];
+end;
+
+function TCustomListPointersCollection<TPointersEnumerator, T, PT>.{Do}GetEnumerator: TPointersEnumerator;
+begin
+  Result := TPointersEnumerator(TPointersEnumerator.NewInstance);
+  TCustomListPointersEnumerator<T, PT>(Result).Create(List);
+end;
+
+function TCustomListPointersCollection<TPointersEnumerator, T, PT>.ToArray: TArray<PT>;
+{begin
+  Result := ToArrayImpl(FList.Count);
+end;}
+var
+  i: SizeInt;
+  LEnumerator: TPointersEnumerator;
+begin
+  SetLength(Result, Count);
+
+  try
+    LEnumerator := GetEnumerator;
+
+    i := 0;
+    while LEnumerator.MoveNext do
+    begin
+      Result[i] := LEnumerator.Current;
+      Inc(i);
+    end;
+  finally
+    LEnumerator.Free;
+  end;
+end;
+
+{ TCustomListWithPointers<T> }
+
+function TCustomListWithPointers<T>.GetPointers: PPointersCollection;
+begin
+  Result := PPointersCollection(@FItems);
+end;
+
 { TList<T> }
 
 constructor TList<T>.Create;
@@ -685,7 +855,7 @@ begin
   if AValue < Count then
     Count := AValue;
 
-  SetLength(FItems, AValue);
+  SetLength(FItems.FItems, AValue);
 end;
 
 procedure TList<T>.SetCount(AValue: SizeInt);
@@ -698,7 +868,7 @@ begin
   if AValue < Count then
     DeleteRange(AValue, Count - AValue);
 
-  FItemsLength := AValue;
+  FItems.FLength := AValue;
 end;
 
 function TList<T>.GetItem(AIndex: SizeInt): T;
@@ -706,15 +876,15 @@ begin
   if (AIndex < 0) or (AIndex >= Count) then
     raise EArgumentOutOfRangeException.CreateRes(@SArgumentOutOfRange);
 
-  Result := FItems[AIndex];
+  Result := FItems.FItems[AIndex];
 end;
 
 procedure TList<T>.SetItem(AIndex: SizeInt; const AValue: T);
 begin
   if (AIndex < 0) or (AIndex >= Count) then
     raise EArgumentOutOfRangeException.CreateRes(@SArgumentOutOfRange);   
-  Notify(FItems[AIndex], cnRemoved);
-  FItems[AIndex] := AValue;
+  Notify(FItems.FItems[AIndex], cnRemoved);
+  FItems.FItems[AIndex] := AValue;
   Notify(AValue, cnAdded);
 end;
 
@@ -731,7 +901,7 @@ end;
 function TList<T>.Add(constref AValue: T): SizeInt;
 begin
   Result := PrepareAddingItem;
-  FItems[Result] := AValue;
+  FItems.FItems[Result] := AValue;
   Notify(AValue, cnAdded);
 end;
 
@@ -763,11 +933,11 @@ begin
 
   if AIndex <> PrepareAddingItem then
   begin
-    System.Move(FItems[AIndex], FItems[AIndex + 1], ((Count - AIndex) - 1) * SizeOf(T));
-    FillChar(FItems[AIndex], SizeOf(T), 0);
+    System.Move(FItems.FItems[AIndex], FItems.FItems[AIndex + 1], ((Count - AIndex) - 1) * SizeOf(T));
+    FillChar(FItems.FItems[AIndex], SizeOf(T), 0);
   end;
 
-  FItems[AIndex] := AValue;
+  FItems.FItems[AIndex] := AValue;
   Notify(AValue, cnAdded);
 end;
 
@@ -786,14 +956,14 @@ begin
 
   if AIndex <> PrepareAddingRange(LLength) then
   begin
-    System.Move(FItems[AIndex], FItems[AIndex + LLength], ((Count - AIndex) - LLength) * SizeOf(T));
-    FillChar(FItems[AIndex], SizeOf(T) * LLength, 0);
+    System.Move(FItems.FItems[AIndex], FItems.FItems[AIndex + LLength], ((Count - AIndex) - LLength) * SizeOf(T));
+    FillChar(FItems.FItems[AIndex], SizeOf(T) * LLength, 0);
   end;
 
   LValue := @AValues[0];
   for i := AIndex to Pred(AIndex + LLength) do
   begin
-    FItems[i] := LValue^;
+    FItems.FItems[i] := LValue^;
     Notify(LValue^, cnAdded);
     Inc(LValue);
   end;
@@ -856,19 +1026,19 @@ begin
     raise EArgumentOutOfRangeException.CreateRes(@SArgumentOutOfRange);
 
   SetLength(LDeleted, Count);
-  System.Move(FItems[AIndex], LDeleted[0], ACount * SizeOf(T));
+  System.Move(FItems.FItems[AIndex], LDeleted[0], ACount * SizeOf(T));
 
   LMoveDelta := Count - (AIndex + ACount);
 
   if LMoveDelta = 0 then
-    FillChar(FItems[AIndex], ACount * SizeOf(T), #0)
+    FillChar(FItems.FItems[AIndex], ACount * SizeOf(T), #0)
   else
   begin
-    System.Move(FItems[AIndex + ACount], FItems[AIndex], LMoveDelta * SizeOf(T));
-    FillChar(FItems[Count - ACount], ACount * SizeOf(T), #0);
+    System.Move(FItems.FItems[AIndex + ACount], FItems.FItems[AIndex], LMoveDelta * SizeOf(T));
+    FillChar(FItems.FItems[Count - ACount], ACount * SizeOf(T), #0);
   end;
 
-  FItemsLength -= ACount;
+  FItems.FLength -= ACount;
 
   for i := 0 to High(LDeleted) do
     Notify(LDeleted[i], cnRemoved);
@@ -894,9 +1064,9 @@ procedure TList<T>.Exchange(AIndex1, AIndex2: SizeInt);
 var
   LTemp: T;
 begin
-  LTemp := FItems[AIndex1];
-  FItems[AIndex1] := FItems[AIndex2];
-  FItems[AIndex2] := LTemp;
+  LTemp := FItems.FItems[AIndex1];
+  FItems.FItems[AIndex1] := FItems.FItems[AIndex2];
+  FItems.FItems[AIndex2] := LTemp;
 end;
 
 procedure TList<T>.Move(AIndex, ANewIndex: SizeInt);
@@ -909,16 +1079,16 @@ begin
   if (ANewIndex < 0) or (ANewIndex >= Count) then
     raise EArgumentOutOfRangeException.CreateRes(@SArgumentOutOfRange);
 
-  LTemp := FItems[AIndex];
-  FItems[AIndex] := Default(T);
+  LTemp := FItems.FItems[AIndex];
+  FItems.FItems[AIndex] := Default(T);
 
   if AIndex < ANewIndex then
-    System.Move(FItems[Succ(AIndex)], FItems[AIndex], (ANewIndex - AIndex) * SizeOf(T))
+    System.Move(FItems.FItems[Succ(AIndex)], FItems.FItems[AIndex], (ANewIndex - AIndex) * SizeOf(T))
   else
-    System.Move(FItems[ANewIndex], FItems[Succ(ANewIndex)], (AIndex - ANewIndex) * SizeOf(T));
+    System.Move(FItems.FItems[ANewIndex], FItems.FItems[Succ(ANewIndex)], (AIndex - ANewIndex) * SizeOf(T));
 
-  FillChar(FItems[ANewIndex], SizeOf(T), #0);
-  FItems[ANewIndex] := LTemp;
+  FillChar(FItems.FItems[ANewIndex], SizeOf(T), #0);
+  FItems.FItems[ANewIndex] := LTemp;
 end;
 
 function TList<T>.First: T;
@@ -952,7 +1122,7 @@ var
   i: SizeInt;
 begin
   for i := 0 to Count - 1 do
-    if FComparer.Compare(AValue, FItems[i]) = 0 then
+    if FComparer.Compare(AValue, FItems.FItems[i]) = 0 then
       Exit(i);
   Result := -1;
 end;
@@ -962,7 +1132,7 @@ var
   i: SizeInt;
 begin
   for i := Count - 1 downto 0 do
-    if FComparer.Compare(AValue, FItems[i]) = 0 then
+    if FComparer.Compare(AValue, FItems.FItems[i]) = 0 then
       Exit(i);
   Result := -1;
 end;
@@ -976,9 +1146,9 @@ begin
   b := Count - 1;
   while a < b do
   begin
-    LTemp := FItems[a];
-    FItems[a] := FItems[b];
-    FItems[b] := LTemp;
+    LTemp := FItems.FItems[a];
+    FItems.FItems[a] := FItems.FItems[b];
+    FItems.FItems[b] := LTemp;
     Inc(a);
     Dec(b);
   end;
@@ -986,22 +1156,22 @@ end;
 
 procedure TList<T>.Sort;
 begin
-  TArrayHelperBugHack.Sort(FItems, FComparer, 0, Count);
+  TArrayHelperBugHack.Sort(FItems.FItems, FComparer, 0, Count);
 end;
 
 procedure TList<T>.Sort(const AComparer: IComparer<T>);
 begin
-  TArrayHelperBugHack.Sort(FItems, AComparer, 0, Count);
+  TArrayHelperBugHack.Sort(FItems.FItems, AComparer, 0, Count);
 end;
 
 function TList<T>.BinarySearch(constref AItem: T; out AIndex: SizeInt): Boolean;
 begin
-  Result := TArrayHelperBugHack.BinarySearch(FItems, AItem, AIndex);
+  Result := TArrayHelperBugHack.BinarySearch(FItems.FItems, AItem, AIndex);
 end;
 
 function TList<T>.BinarySearch(constref AItem: T; out AIndex: SizeInt; const AComparer: IComparer<T>): Boolean;
 begin
-  Result := TArrayHelperBugHack.BinarySearch(FItems, AItem, AIndex, AComparer);
+  Result := TArrayHelperBugHack.BinarySearch(FItems.FItems, AItem, AIndex, AComparer);
 end;
 
 { TThreadList<T> }
@@ -1101,14 +1271,14 @@ end;
 
 function TQueue<T>.DoRemove(AIndex: SizeInt; ACollectionNotification: TCollectionNotification): T;
 begin
-  Result := FItems[AIndex];
-  FItems[AIndex] := Default(T);
+  Result := FItems.FItems[AIndex];
+  FItems.FItems[AIndex] := Default(T);
   Notify(Result, ACollectionNotification);
   FLow += 1;
-  if FLow = FItemsLength then
+  if FLow = FItems.FLength then
   begin
     FLow := 0;
-    FItemsLength := 0;
+    FItems.FLength := 0;
   end;
 end;
 
@@ -1117,23 +1287,23 @@ begin
   if AValue < Count then
     raise EArgumentOutOfRangeException.CreateRes(@SArgumentOutOfRange);
 
-  if AValue = FItemsLength then
+  if AValue = FItems.FLength then
     Exit;
 
   if (Count > 0) and (FLow > 0) then
   begin
-    Move(FItems[FLow], FItems[0], Count * SizeOf(T));
-    FillChar(FItems[Count], (FItemsLength - Count) * SizeOf(T), #0);
+    Move(FItems.FItems[FLow], FItems.FItems[0], Count * SizeOf(T));
+    FillChar(FItems.FItems[Count], (FItems.FLength - Count) * SizeOf(T), #0);
   end;
 
-  SetLength(FItems, AValue);
-  FItemsLength := Count;
+  SetLength(FItems.FItems, AValue);
+  FItems.FLength := Count;
   FLow := 0;
 end;
 
 function TQueue<T>.GetCount: SizeInt;
 begin
-  Result := FItemsLength - FLow;
+  Result := FItems.FLength - FLow;
 end;
 
 constructor TQueue<T>.Create(ACollection: TEnumerable<T>);
@@ -1154,7 +1324,7 @@ var
   LIndex: SizeInt;
 begin
   LIndex := PrepareAddingItem;
-  FItems[LIndex] := AValue;
+  FItems.FItems[LIndex] := AValue;
   Notify(AValue, cnAdded);
 end;
 
@@ -1173,7 +1343,7 @@ begin
   if (Count = 0) then
     raise EArgumentOutOfRangeException.CreateRes(@SArgumentOutOfRange);
 
-  Result := FItems[FLow];
+  Result := FItems.FItems[FLow];
 end;
 
 procedure TQueue<T>.Clear;
@@ -1181,7 +1351,7 @@ begin
   while Count <> 0 do
     Dequeue;
   FLow := 0;
-  FItemsLength := 0;
+  FItems.FLength := 0;
 end;
 
 procedure TQueue<T>.TrimExcess;
@@ -1214,9 +1384,9 @@ begin
   if AIndex < 0 then
     raise EArgumentOutOfRangeException.CreateRes(@SArgumentOutOfRange);
 
-  Result := FItems[AIndex];
-  FItems[AIndex] := Default(T);
-  FItemsLength -= 1;
+  Result := FItems.FItems[AIndex];
+  FItems.FItems[AIndex] := Default(T);
+  FItems.FLength -= 1;
   Notify(Result, ACollectionNotification);
 end;
 
@@ -1236,7 +1406,7 @@ begin
   if AValue < Count then
     AValue := Count;
 
-  SetLength(FItems, AValue);
+  SetLength(FItems.FItems, AValue);
 end;
 
 procedure TStack<T>.Push(constref AValue: T);
@@ -1244,13 +1414,13 @@ var
   LIndex: SizeInt;
 begin
   LIndex := PrepareAddingItem;
-  FItems[LIndex] := AValue;
+  FItems.FItems[LIndex] := AValue;
   Notify(AValue, cnAdded);
 end;
 
 function TStack<T>.Pop: T;
 begin
-  Result := DoRemove(FItemsLength - 1, cnRemoved);
+  Result := DoRemove(FItems.FLength - 1, cnRemoved);
 end;
 
 function TStack<T>.Peek: T;
@@ -1258,12 +1428,12 @@ begin
   if (Count = 0) then
     raise EArgumentOutOfRangeException.CreateRes(@SArgumentOutOfRange);
 
-  Result := FItems[FItemsLength - 1];
+  Result := FItems.FItems[FItems.FLength - 1];
 end;
 
 function TStack<T>.Extract: T;
 begin
-  Result := DoRemove(FItemsLength - 1, cnExtracted);
+  Result := DoRemove(FItems.FLength - 1, cnExtracted);
 end;
 
 procedure TStack<T>.TrimExcess;
@@ -1360,4 +1530,154 @@ end;
 
 {$I generics.dictionaries.inc}
 
+{ THashSet<T> }
+
+function THashSet<T>.TEnumerator.DoMoveNext: boolean;
+begin
+  Result := FEnumerator.DoMoveNext;
+end;
+
+function THashSet<T>.TEnumerator.DoGetCurrent: T;
+begin
+  Result := FEnumerator.DoGetCurrent;
+end;
+
+function THashSet<T>.TEnumerator.GetCurrent: T;
+begin
+  Result := FEnumerator.GetCurrent;
+end;
+
+constructor THashSet<T>.TEnumerator.Create(ASet: THashSet<T>);
+begin
+  FEnumerator := ASet.FInternalDictionary.Keys.DoGetEnumerator;
+end;
+
+destructor THashSet<T>.TEnumerator.Destroy;
+begin
+  FEnumerator.Free;
+end;
+
+function THashSet<T>.DoGetEnumerator: Generics.Collections.TEnumerator<T>;
+begin
+  Result := GetEnumerator;
+end;
+
+function THashSet<T>.GetCount: SizeInt;
+begin
+  Result := FInternalDictionary.Count;
+end;
+
+function THashSet<T>.GetPointers: TDictionary<T, TEmptyRecord>.TKeyCollection.PPointersCollection;
+begin
+  Result := FInternalDictionary.Keys.Ptr;
+end;
+
+function THashSet<T>.GetEnumerator: TEnumerator;
+begin
+  Result := TEnumerator.Create(Self);
+end;
+
+constructor THashSet<T>.Create;
+begin
+  FInternalDictionary := TDictionary<T, TEmptyRecord>.Create;
+end;
+
+constructor THashSet<T>.Create(const AComparer: IEqualityComparer<T>);
+begin
+  FInternalDictionary := TDictionary<T, TEmptyRecord>.Create(AComparer);
+end;
+
+constructor THashSet<T>.Create(ACollection: TEnumerable<T>);
+var
+  i: T;
+begin
+  Create;
+  for i in ACollection do
+    Add(i);
+end;
+
+destructor THashSet<T>.Destroy;
+begin
+  FInternalDictionary.Free;
+end;
+
+function THashSet<T>.Add(constref AValue: T): Boolean;
+begin
+  Result := not FInternalDictionary.ContainsKey(AValue);
+  if Result then
+    FInternalDictionary.Add(AValue, EmptyRecord);
+end;
+
+function THashSet<T>.Remove(constref AValue: T): Boolean;
+var
+  LIndex: SizeInt;
+begin
+  LIndex := FInternalDictionary.FindBucketIndex(AValue);
+  Result := LIndex >= 0;
+  if Result then
+    FInternalDictionary.DoRemove(LIndex, cnRemoved);
+end;
+
+procedure THashSet<T>.Clear;
+begin
+  FInternalDictionary.Clear;
+end;
+
+function THashSet<T>.Contains(constref AValue: T): Boolean;
+begin
+  Result := FInternalDictionary.ContainsKey(AValue);
+end;
+
+procedure THashSet<T>.UnionWith(AHashSet: THashSet<T>);
+var
+  i: PT;
+begin
+  for i in AHashSet.Ptr^ do
+    Add(i^);
+end;
+
+procedure THashSet<T>.IntersectWith(AHashSet: THashSet<T>);
+var
+  LList: TList<PT>;
+  i: PT;
+begin
+  LList := TList<PT>.Create;
+
+  for i in Ptr^ do
+    if not AHashSet.Contains(i^) then
+      LList.Add(i);
+
+  for i in LList do
+    Remove(i^);
+
+  LList.Free;
+end;
+
+procedure THashSet<T>.ExceptWith(AHashSet: THashSet<T>);
+var
+  i: PT;
+begin
+  for i in AHashSet.Ptr^ do
+    FInternalDictionary.Remove(i^);
+end;
+
+procedure THashSet<T>.SymmetricExceptWith(AHashSet: THashSet<T>);
+var
+  LList: TList<PT>;
+  i: PT;
+begin
+  LList := TList<PT>.Create;
+
+  for i in AHashSet.Ptr^ do
+    if Contains(i^) then
+      LList.Add(i)
+    else
+      Add(i^);
+
+  for i in LList do
+    Remove(i^);
+
+  LList.Free;
+end;
+
 end.

+ 97 - 23
Units/Utils/generics.dictionaries.inc

@@ -143,27 +143,73 @@ begin
   Result := GetCurrent;
 end;
 
-{ TDictionaryEnumerable<TDictionaryEnumerator, T, CUSTOM_DICTIONARY_CONSTRAINTS> }
+{ TDictionaryEnumerable<TDictionaryEnumerator, TDictionaryPointersEnumerator, T, CUSTOM_DICTIONARY_CONSTRAINTS> }
 
-constructor TDictionaryEnumerable<TDictionaryEnumerator, T, CUSTOM_DICTIONARY_CONSTRAINTS>.Create(
+function TDictionaryEnumerable<TDictionaryEnumerator, TDictionaryPointersEnumerator, T, PT, CUSTOM_DICTIONARY_CONSTRAINTS>.
+  TPointersCollection.Dictionary: TCustomDictionary<CUSTOM_DICTIONARY_CONSTRAINTS>;
+begin
+  Result := TCustomDictionary<CUSTOM_DICTIONARY_CONSTRAINTS>(Pointer(@Self)^);
+end;
+
+function TDictionaryEnumerable<TDictionaryEnumerator, TDictionaryPointersEnumerator, T, PT, CUSTOM_DICTIONARY_CONSTRAINTS>.
+  TPointersCollection.{Do}GetEnumerator: TDictionaryPointersEnumerator;
+begin
+  Result := TDictionaryPointersEnumerator(TDictionaryPointersEnumerator.NewInstance);
+  TCustomDictionaryEnumerator<PT, CUSTOM_DICTIONARY_CONSTRAINTS>(Result).Create(Dictionary);
+end;
+
+function TDictionaryEnumerable<TDictionaryEnumerator, TDictionaryPointersEnumerator, T, PT, CUSTOM_DICTIONARY_CONSTRAINTS>.
+  TPointersCollection.GetCount: SizeInt;
+begin
+  Result := Dictionary.Count;
+end;
+
+function TDictionaryEnumerable<TDictionaryEnumerator, TDictionaryPointersEnumerator, T, PT, CUSTOM_DICTIONARY_CONSTRAINTS>.
+  TPointersCollection.ToArray: TArray<PT>;
+var
+  i: SizeInt;
+  LEnumerator: TDictionaryPointersEnumerator;
+begin
+  SetLength(Result, Count);
+
+  try
+    LEnumerator := GetEnumerator;
+
+    i := 0;
+    while LEnumerator.MoveNext do
+    begin
+      Result[i] := LEnumerator.Current;
+      Inc(i);
+    end;
+  finally
+    LEnumerator.Free;
+  end;
+end;
+
+constructor TDictionaryEnumerable<TDictionaryEnumerator, TDictionaryPointersEnumerator, T, PT, CUSTOM_DICTIONARY_CONSTRAINTS>.Create(
   ADictionary: TCustomDictionary<CUSTOM_DICTIONARY_CONSTRAINTS>);
 begin
   FDictionary := ADictionary;
 end;
 
-function TDictionaryEnumerable<TDictionaryEnumerator, T, CUSTOM_DICTIONARY_CONSTRAINTS>.
+function TDictionaryEnumerable<TDictionaryEnumerator, TDictionaryPointersEnumerator, T, PT, CUSTOM_DICTIONARY_CONSTRAINTS>.
   DoGetEnumerator: TDictionaryEnumerator;
 begin
   Result := TDictionaryEnumerator(TDictionaryEnumerator.NewInstance);
   TCustomDictionaryEnumerator<T, CUSTOM_DICTIONARY_CONSTRAINTS>(Result).Create(FDictionary);
 end;
 
-function TDictionaryEnumerable<TDictionaryEnumerator, T, CUSTOM_DICTIONARY_CONSTRAINTS>.GetCount: SizeInt;
+function TDictionaryEnumerable<TDictionaryEnumerator, TDictionaryPointersEnumerator, T, PT, CUSTOM_DICTIONARY_CONSTRAINTS>.GetCount: SizeInt;
 begin
   Result := TCustomDictionary<CUSTOM_DICTIONARY_CONSTRAINTS>(FDictionary).Count;
 end;
 
-function TDictionaryEnumerable<TDictionaryEnumerator, T, CUSTOM_DICTIONARY_CONSTRAINTS>.ToArray: TArray<T>;
+function TDictionaryEnumerable<TDictionaryEnumerator, TDictionaryPointersEnumerator, T, PT, CUSTOM_DICTIONARY_CONSTRAINTS>.GetPointers: PPointersCollection;
+begin
+  Result := @FPointers;
+end;
+
+function TDictionaryEnumerable<TDictionaryEnumerator, TDictionaryPointersEnumerator, T, PT, CUSTOM_DICTIONARY_CONSTRAINTS>.ToArray: TArray<T>;
 begin
   Result := ToArrayImpl(FDictionary.Count);
 end;
@@ -224,7 +270,7 @@ begin
   Result := FindBucketIndex(FItems, AKey, LHash);
 end;
 
-function TOpenAddressing<OPEN_ADDRESSING_CONSTRAINTS>.PrepareAddingItem: SizeInt;
+procedure TOpenAddressing<OPEN_ADDRESSING_CONSTRAINTS>.PrepareAddingItem;
 begin
   if RealItemsLength > FItemsThreshold then
     Rehash(Length(FItems) shl 1)
@@ -235,9 +281,6 @@ begin
   end
   else if FItemsLength = $40000001 then // High(TIndex) ... Error: Type mismatch
     OutOfMemoryError;
-
-  Result := FItemsLength;
-  Inc(FItemsLength);
 end;
 
 procedure TOpenAddressing<OPEN_ADDRESSING_CONSTRAINTS>.UpdateItemsThreshold(ASize: SizeInt);
@@ -255,6 +298,9 @@ begin
   AItem.Pair.Key := AKey;
   AItem.Pair.Value := AValue;
 
+  // ! very important. FItemsLength must be increased after above code (because constref has meaning)
+  Inc(FItemsLength);
+
   PairNotify(AItem.Pair, cnAdded);
 end;
 
@@ -302,7 +348,7 @@ var
   LIndex: SizeInt;
 begin
   LIndex := FindBucketIndex(AKey);
-  if LIndex  < 0 then
+  if LIndex < 0 then
     Exit;
 
   DoRemove(LIndex, cnRemoved);
@@ -313,7 +359,7 @@ var
   LIndex: SizeInt;
 begin
   LIndex := FindBucketIndex(AKey);
-  if LIndex  < 0 then
+  if LIndex < 0 then
     Exit(Default(TPair<TKey, TValue>));
 
   Result.Key := AKey;
@@ -555,6 +601,13 @@ begin
   Result := TOpenAddressing<OPEN_ADDRESSING_CONSTRAINTS>(FDictionary).FItems[FIndex].Pair.Value;
 end;
 
+{ TOpenAddressing<OPEN_ADDRESSING_CONSTRAINTS>.TPValueEnumerator }
+
+function TOpenAddressing<OPEN_ADDRESSING_CONSTRAINTS>.TPValueEnumerator.GetCurrent: PValue;
+begin
+  Result := @(TOpenAddressing<OPEN_ADDRESSING_CONSTRAINTS>(FDictionary).FItems[FIndex].Pair.Value);
+end;
+
 { TOpenAddressing<OPEN_ADDRESSING_CONSTRAINTS>.TKeyEnumerator }
 
 function TOpenAddressing<OPEN_ADDRESSING_CONSTRAINTS>.TKeyEnumerator.GetCurrent: TKey;
@@ -562,6 +615,13 @@ begin
   Result := TOpenAddressing<OPEN_ADDRESSING_CONSTRAINTS>(FDictionary).FItems[FIndex].Pair.Key;
 end;
 
+{ TOpenAddressing<OPEN_ADDRESSING_CONSTRAINTS>.TPKeyEnumerator }
+
+function TOpenAddressing<OPEN_ADDRESSING_CONSTRAINTS>.TPKeyEnumerator.GetCurrent: PKey;
+begin
+  Result := @(TOpenAddressing<OPEN_ADDRESSING_CONSTRAINTS>(FDictionary).FItems[FIndex].Pair.Key);
+end;
+
 { TOpenAddressingLP<DICTIONARY_CONSTRAINTS> }
 
 procedure TOpenAddressingLP<OPEN_ADDRESSING_CONSTRAINTS>.NotifyIndexChange(AFrom, ATo: SizeInt);
@@ -1133,7 +1193,7 @@ end;
 
 function TDeamortizedDArrayCuckooMap<CUCKOO_CONSTRAINTS>.TQueueDictionary.Pop: Pointer;
 var
-  AIndex, LGap: SizeInt;
+  AIndex: SizeInt;
   //LResult: TDeamortizedDArrayCuckooMap<CUCKOO_CONSTRAINTS>.TItem; !!!bug #25917
 begin
   AIndex := FIdx.DoRemove(FIdx.Count - 1, cnExtracted);
@@ -1310,7 +1370,7 @@ begin
   Result := LR_NIL;
 end;
 
-function TDeamortizedDArrayCuckooMap<CUCKOO_CONSTRAINTS>.PrepareAddingItem: SizeInt;
+procedure TDeamortizedDArrayCuckooMap<CUCKOO_CONSTRAINTS>.PrepareAddingItem;
 var
   i: SizeInt;
 begin
@@ -1324,9 +1384,6 @@ begin
   end
   else if FItemsLength = $40000001 then // High(TIndex) ... Error: Type mismatch
     OutOfMemoryError;
-
-  Result := FItemsLength;
-  Inc(FItemsLength);
 end;
 
 procedure TDeamortizedDArrayCuckooMap<CUCKOO_CONSTRAINTS>.UpdateItemsThreshold(ASize: SizeInt);
@@ -1348,7 +1405,7 @@ var
   y: boolean = false;
   b: UInt32;
   LIndex: UInt32;
-  i, j, LLengthMask: SizeInt;
+  i, LLengthMask: SizeInt;
   LTempItem: TItem;
   LHashList: array[0..1] of UInt32;
   LHashListParams: array[0..3] of UInt16 absolute LHashList;
@@ -1411,10 +1468,11 @@ begin
     FQueue.InsertIntoHead(@LNewItem);
 end;
 
-procedure TDeamortizedDArrayCuckooMap<CUCKOO_CONSTRAINTS>.DoAdd(constref AKey: TKey; constref AValue: TValue;
+procedure TDeamortizedDArrayCuckooMap<CUCKOO_CONSTRAINTS>.DoAdd(const AKey: TKey; const AValue: TValue;
   const AHashList: PUInt32);
 begin
   AddItem(FItems, AKey, AValue, AHashList);
+  Inc(FItemsLength);
   KeyNotify(AKey, cnAdded);
   ValueNotify(AValue, cnAdded);
 end;
@@ -1545,10 +1603,8 @@ end;
 procedure TDeamortizedDArrayCuckooMap<CUCKOO_CONSTRAINTS>.Rehash(ASizePow2: SizeInt);
 var
   LNewItems: TItemsDArray;
-  LHash: UInt32;
-  LIndex: SizeInt;
   i, j: SizeInt;
-  LItem, LNewItem: PItem;
+  LItem: PItem;
   LOldQueue: TQueueDictionary;
 var
   LHashList: array[0..1] of UInt32;
@@ -1711,7 +1767,6 @@ var
   LHashList: array[0..TCuckooCfg.D] of UInt32;
   LHashListOrIndex: PUint32;
   LLookupResult: SizeInt;
-  LIndex: UInt32;
 begin
   LHashListOrIndex := @LHashList[0];
   LLookupResult := Lookup(AKey, LHashListOrIndex);
@@ -1747,7 +1802,6 @@ var
   LHashList: array[0..TCuckooCfg.D] of UInt32;
   LHashListOrIndex: PUint32;
   LLookupResult: SizeInt;
-  LIndex: UInt32;
 begin
   LHashListOrIndex := @LHashList[0];
   LLookupResult := Lookup(AKey, LHashListOrIndex);
@@ -1832,6 +1886,16 @@ begin
     Result := TDeamortizedDArrayCuckooMap<CUCKOO_CONSTRAINTS>(FDictionary).FItems[FMainIndex][FIndex].Pair.Value;
 end;
 
+{ TDeamortizedDArrayCuckooMap<CUCKOO_CONSTRAINTS>.TPValueEnumerator }
+
+function TDeamortizedDArrayCuckooMap<CUCKOO_CONSTRAINTS>.TPValueEnumerator.GetCurrent: PValue;
+begin
+  if FMainIndex = TCuckooCfg.D then
+    Result := @(TDeamortizedDArrayCuckooMap<CUCKOO_CONSTRAINTS>(FDictionary).FQueue.FItems[FIndex].Pair.Value.Pair.Value)
+  else
+    Result := @(TDeamortizedDArrayCuckooMap<CUCKOO_CONSTRAINTS>(FDictionary).FItems[FMainIndex][FIndex].Pair.Value);
+end;
+
 { TDeamortizedDArrayCuckooMap<CUCKOO_CONSTRAINTS>.TKeyEnumerator }
 
 function TDeamortizedDArrayCuckooMap<CUCKOO_CONSTRAINTS>.TKeyEnumerator.GetCurrent: TKey;
@@ -1842,6 +1906,16 @@ begin
     Result := TDeamortizedDArrayCuckooMap<CUCKOO_CONSTRAINTS>(FDictionary).FItems[FMainIndex][FIndex].Pair.Key;
 end;
 
+{ TDeamortizedDArrayCuckooMap<CUCKOO_CONSTRAINTS>.TPKeyEnumerator }
+
+function TDeamortizedDArrayCuckooMap<CUCKOO_CONSTRAINTS>.TPKeyEnumerator.GetCurrent: TKey;
+begin
+  if FMainIndex = TCuckooCfg.D then
+    Result := @(TDeamortizedDArrayCuckooMap<CUCKOO_CONSTRAINTS>(FDictionary).FQueue.FItems[FIndex].Pair.Value.Pair.Key)
+  else
+    Result := @(TDeamortizedDArrayCuckooMap<CUCKOO_CONSTRAINTS>(FDictionary).FItems[FMainIndex][FIndex].Pair.Key);
+end;
+
 { TObjectDictionary<DICTIONARY_CONSTRAINTS> }
 
 procedure TObjectDeamortizedDArrayCuckooMap<CUCKOO_CONSTRAINTS>.KeyNotify(

+ 43 - 12
Units/Utils/generics.dictionariesh.inc

@@ -110,16 +110,30 @@ type
 
   { TDictionaryEnumerable }
 
-  TDictionaryEnumerable<TDictionaryEnumerator: TObject; // ... inherits from TCustomDictionaryEnumerator. workaround...
-    T, CUSTOM_DICTIONARY_CONSTRAINTS> = class abstract(TEnumerable<T>)
+  TDictionaryEnumerable<TDictionaryEnumerator: TObject; TDictionaryPointersEnumerator, // ... inherits from TCustomDictionaryEnumerator. workaround...
+    T, PT, CUSTOM_DICTIONARY_CONSTRAINTS> = class abstract(TEnumerable<T>)
+  private type
+    PPointersCollection = ^TPointersCollection;
+    TPointersCollection = record
+    private
+      function Dictionary: TCustomDictionary<CUSTOM_DICTIONARY_CONSTRAINTS>; inline;
+      function GetCount: SizeInt; inline;
+    public
+      function GetEnumerator: TDictionaryPointersEnumerator;
+      function ToArray: TArray<PT>;
+      property Count: SizeInt read GetCount;
+    end;
   private
+    FPointers: TPointersCollection;
     FDictionary: TCustomDictionary<CUSTOM_DICTIONARY_CONSTRAINTS>;
     function GetCount: SizeInt;
+    function GetPointers: PPointersCollection; inline;
   public
     constructor Create(ADictionary: TCustomDictionary<CUSTOM_DICTIONARY_CONSTRAINTS>);
     function DoGetEnumerator: TDictionaryEnumerator; override;
     function ToArray: TArray<T>; override; final;
     property Count: SizeInt read GetCount;
+    property Ptr: PPointersCollection read GetPointers;
   end;
 
   // more info : http://en.wikipedia.org/wiki/Open_addressing
@@ -147,7 +161,7 @@ type
     FItems: TItemsArray;
 
     procedure Resize(ANewSize: SizeInt);
-    function PrepareAddingItem: SizeInt;
+    procedure PrepareAddingItem;
   protected
     function RealItemsLength: SizeInt; virtual;
     function Rehash(ASizePow2: SizeInt; AForce: Boolean = False): boolean; virtual;
@@ -166,15 +180,25 @@ type
         function GetCurrent: TValue; override;
       end;
 
+      TPValueEnumerator = class(TOpenAddressingEnumerator<PValue, OPEN_ADDRESSING_CONSTRAINTS>)
+      protected
+        function GetCurrent: PValue; override;
+      end;
+
       TKeyEnumerator = class(TOpenAddressingEnumerator<TKey, OPEN_ADDRESSING_CONSTRAINTS>)
       protected
         function GetCurrent: TKey; override;
       end;
 
+      TPKeyEnumerator = class(TOpenAddressingEnumerator<PKey, OPEN_ADDRESSING_CONSTRAINTS>)
+      protected
+        function GetCurrent: PKey; override;
+      end;
+
       // Collections
-      TValueCollection = class(TDictionaryEnumerable<TValueEnumerator, TValue, CUSTOM_DICTIONARY_CONSTRAINTS>);
+      TValueCollection = class(TDictionaryEnumerable<TValueEnumerator, TPValueEnumerator, TValue, PValue, CUSTOM_DICTIONARY_CONSTRAINTS>);
 
-      TKeyCollection = class(TDictionaryEnumerable<TKeyEnumerator, TKey, CUSTOM_DICTIONARY_CONSTRAINTS>);
+      TKeyCollection = class(TDictionaryEnumerable<TKeyEnumerator, TPKeyEnumerator, TKey, PKey, CUSTOM_DICTIONARY_CONSTRAINTS>);
 
     // bug #24283 - workaround related to lack of DoGetEnumerator
     function GetEnumerator: TPairEnumerator; reintroduce;
@@ -373,7 +397,7 @@ type
 
     procedure Resize(ANewSize: SizeInt);
     procedure Rehash(ASizePow2: SizeInt);
-    function PrepareAddingItem: SizeInt;
+    procedure PrepareAddingItem;
   protected
     procedure UpdateItemsThreshold(ASize: SizeInt); override;
     function Lookup(constref AKey: TKey; var AHashListOrIndex: PUInt32): SizeInt; inline; overload;
@@ -391,15 +415,25 @@ type
         function GetCurrent: TValue; override;
       end;
 
+      TPValueEnumerator = class(TDeamortizedDArrayCuckooMapEnumerator<PValue, CUCKOO_CONSTRAINTS>)
+      protected
+        function GetCurrent: PValue; override;
+      end;
+
       TKeyEnumerator = class(TDeamortizedDArrayCuckooMapEnumerator<TKey, CUCKOO_CONSTRAINTS>)
       protected
         function GetCurrent: TKey; override;
       end;
 
+      TPKeyEnumerator = class(TDeamortizedDArrayCuckooMapEnumerator<PKey, CUCKOO_CONSTRAINTS>)
+      protected
+        function GetCurrent: PKey; override;
+      end;
+
       // Collections
-      TValueCollection = class(TDictionaryEnumerable<TValueEnumerator, TValue, CUSTOM_DICTIONARY_CONSTRAINTS>);
+      TValueCollection = class(TDictionaryEnumerable<TValueEnumerator, TPValueEnumerator, TValue, PValue, CUSTOM_DICTIONARY_CONSTRAINTS>);
 
-      TKeyCollection = class(TDictionaryEnumerable<TKeyEnumerator, TKey, CUSTOM_DICTIONARY_CONSTRAINTS>);
+      TKeyCollection = class(TDictionaryEnumerable<TKeyEnumerator, TPKeyEnumerator, TKey, PKey, CUSTOM_DICTIONARY_CONSTRAINTS>);
 
     // bug #24283 - workaround related to lack of DoGetEnumerator
     function GetEnumerator: TPairEnumerator; reintroduce;
@@ -412,7 +446,7 @@ type
     procedure SetItem(constref AValue: TValue; const AHashListOrIndex: PUInt32; ALookupResult: SizeInt); overload;
 
     procedure AddItem(constref AItems: TItemsDArray; constref AKey: TKey; constref AValue: TValue; const AHashList: PUInt32); overload;
-    procedure DoAdd(constref AKey: TKey; constref AValue: TValue; const AHashList: PUInt32); overload; inline;
+    procedure DoAdd(const AKey: TKey; const AValue: TValue; const AHashList: PUInt32); overload; inline;
     function DoRemove(const AHashListOrIndex: PUInt32; ALookupResult: SizeInt;
       ACollectionNotification: TCollectionNotification): TValue;
 
@@ -539,6 +573,3 @@ type
 
   THashMap<TKey, TValue> = class(TCuckooD4<TKey, TValue>);
   TObjectHashMap<TKey, TValue> = class(TObjectCuckooD4<TKey, TValue>);
-
-var
-  EmptyRecord: TEmptyRecord;

+ 2 - 0
Units/Utils/generics.helpers.pas

@@ -20,6 +20,8 @@ unit Generics.Helpers;
 
 {$MODE DELPHI}{$H+}
 {$MODESWITCH TYPEHELPERS}
+{$OVERFLOWCHECKS OFF}
+{$RANGECHECKS OFF}
 
 interface
 

+ 2 - 0
Units/Utils/generics.memoryexpanders.pas

@@ -21,6 +21,8 @@ unit Generics.MemoryExpanders;
 
 {$mode delphi}
 {$MACRO ON}
+{$OVERFLOWCHECKS OFF}
+{$RANGECHECKS OFF}
 {.$WARN 5024 OFF}
 {.$WARN 4079 OFF}
 

Some files were not shown because too many files changed in this diff