25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

191 lines
7.6 KiB

  1. unit uutlInterfaces;
  2. {$mode objfpc}{$H+}
  3. {$modeswitch nestedprocvars}
  4. interface
  5. uses
  6. Classes, SysUtils;
  7. type
  8. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  9. generic IutlEqualityComparer<T> = interface
  10. function EqualityCompare(const i1, i2: T): Boolean;
  11. end;
  12. generic TutlEqualityComparer<T> = class(TInterfacedObject, specialize IutlEqualityComparer<T>)
  13. public
  14. function EqualityCompare(const i1, i2: T): Boolean;
  15. end;
  16. generic TutlEventEqualityComparer<T> = class(TInterfacedObject, specialize IutlEqualityComparer<T>)
  17. public type
  18. TEqualityEvent = function(const i1, i2: T): Boolean;
  19. TEqualityEventO = function(const i1, i2: T): Boolean of object;
  20. TEqualityEventN = function(const i1, i2: T): Boolean is nested;
  21. private type
  22. TEqualityEventType = (eetNormal, eetObject, eetNested);
  23. private
  24. fEvent: TEqualityEvent;
  25. fEventO: TEqualityEventO;
  26. fEventN: TEqualityEventN;
  27. fEventType: TEqualityEventType;
  28. public
  29. function EqualityCompare(const i1, i2: T): Boolean;
  30. constructor Create(const aEvent: TEqualityEvent); overload;
  31. constructor Create(const aEvent: TEqualityEventO); overload;
  32. constructor Create(const aEvent: TEqualityEventN); overload;
  33. { HINT: you need to activate "$modeswitch nestedprocvars" when you want to use nested callbacks }
  34. end;
  35. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  36. generic IutlComparer<T> = interface
  37. function Compare(const i1, i2: T): Integer;
  38. end;
  39. generic TutlComparer<T> = class(TInterfacedObject, specialize IutlComparer<T>)
  40. public
  41. function Compare(const i1, i2: T): Integer;
  42. end;
  43. generic TutlEventComparer<T> = class(TInterfacedObject, specialize IutlComparer<T>)
  44. public type
  45. TEvent = function(const i1, i2: T): Integer;
  46. TEventO = function(const i1, i2: T): Integer of object;
  47. TEventN = function(const i1, i2: T): Integer is nested;
  48. private type
  49. TEventType = (etNormal, etObject, etNested);
  50. private
  51. fEvent: TEvent;
  52. fEventO: TEventO;
  53. fEventN: TEventN;
  54. fEventType: TEventType;
  55. public
  56. function Compare(const i1, i2: T): Integer;
  57. constructor Create(const aEvent: TEvent); overload;
  58. constructor Create(const aEvent: TEventO); overload;
  59. constructor Create(const aEvent: TEventN); overload;
  60. { HINT: you need to activate "$modeswitch nestedprocvars" when you want to use nested callbacks }
  61. end;
  62. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  63. generic IutlReadOnlyList<T> = interface(IUnknown)
  64. function GetCount: Integer;
  65. function GetItem(const aIndex: Integer): T;
  66. end;
  67. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  68. generic IutlList<T> = interface(specialize IutlReadOnlyList<T>)
  69. procedure SetItem(const aIndex: Integer; const aItem: T);
  70. end;
  71. operator < (const i1, i2: TObject): Boolean; inline;
  72. operator > (const i1, i2: TObject): Boolean; inline;
  73. implementation
  74. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  75. operator < (const i1, i2: TObject): Boolean;
  76. begin
  77. result := Pointer(i1) < Pointer(i2);
  78. end;
  79. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  80. operator > (const i1, i2: TObject): Boolean;
  81. begin
  82. result := Pointer(i1) > Pointer(i2);
  83. end;
  84. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  85. //TutlEqualityComparer//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  86. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  87. function TutlEqualityComparer.EqualityCompare(const i1, i2: T): Boolean;
  88. begin
  89. result := (i1 = i2);
  90. end;
  91. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  92. function TutlEventEqualityComparer.EqualityCompare(const i1, i2: T): Boolean;
  93. begin
  94. case fEventType of
  95. eetNormal: result := fEvent(i1, i2);
  96. eetObject: result := fEventO(i1, i2);
  97. eetNested: result := fEventN(i1, i2);
  98. end;
  99. end;
  100. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  101. constructor TutlEventEqualityComparer.Create(const aEvent: TEqualityEvent);
  102. begin
  103. inherited Create;
  104. fEvent := aEvent;
  105. fEventType := eetNormal;
  106. end;
  107. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  108. constructor TutlEventEqualityComparer.Create(const aEvent: TEqualityEventO);
  109. begin
  110. inherited Create;
  111. fEventO := aEvent;
  112. fEventType := eetObject;
  113. end;
  114. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  115. constructor TutlEventEqualityComparer.Create(const aEvent: TEqualityEventN);
  116. begin
  117. inherited Create;
  118. fEventN := aEvent;
  119. fEventType := eetNested;
  120. end;
  121. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  122. //TutlComparer//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  123. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  124. function TutlComparer.Compare(const i1, i2: T): Integer;
  125. begin
  126. if (i1 < i2) then
  127. result := -1
  128. else if (i1 > i2) then
  129. result := 1
  130. else
  131. result := 0;
  132. end;
  133. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  134. function TutlEventComparer.Compare(const i1, i2: T): Integer;
  135. begin
  136. case fEventType of
  137. etNormal: result := fEvent(i1, i2);
  138. etObject: result := fEventO(i1, i2);
  139. etNested: result := fEventN(i1, i2);
  140. end;
  141. end;
  142. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  143. constructor TutlEventComparer.Create(const aEvent: TEvent);
  144. begin
  145. inherited Create;
  146. fEvent := aEvent;
  147. fEventType := etNormal;
  148. end;
  149. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  150. constructor TutlEventComparer.Create(const aEvent: TEventO);
  151. begin
  152. inherited Create;
  153. fEventO := aEvent;
  154. fEventType := etObject;
  155. end;
  156. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  157. constructor TutlEventComparer.Create(const aEvent: TEventN);
  158. begin
  159. inherited Create;
  160. fEventN := aEvent;
  161. fEventType := etNested;
  162. end;
  163. end.