gdeque.pp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. {
  2. This file is part of the Free Pascal FCL library.
  3. BSD parts (c) 2011 Vlado Boza
  4. See the file COPYING.FPC, included in this distribution,
  5. for details about the copyright.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY;without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  9. **********************************************************************}
  10. {$mode objfpc}
  11. unit gdeque;
  12. interface
  13. type
  14. generic TDeque<T>=class
  15. private
  16. type
  17. PT=^T;
  18. TArr=array of T;
  19. var
  20. FData:TArr;
  21. FDataSize:SizeUInt;
  22. FCapacity:SizeUInt;
  23. FStart:SizeUInt;
  24. procedure SetValue(position:SizeUInt; value:T);inline;
  25. function GetValue(position:SizeUInt):T;inline;
  26. function GetMutable(position:SizeUInt):PT;inline;
  27. procedure IncreaseCapacity();inline;
  28. public
  29. function Size():SizeUInt;inline;
  30. constructor Create();
  31. procedure PushBack(value:T);inline;
  32. procedure PushFront(value:T);inline;
  33. procedure PopBack();inline;
  34. procedure PopFront();inline;
  35. function Front():T;inline;
  36. function Back():T;inline;
  37. function IsEmpty():boolean;inline;
  38. procedure Reserve(cap:SizeUInt);inline;
  39. procedure Resize(cap:SizeUInt);inline;
  40. procedure Insert(Position:SizeUInt; Value:T);inline;
  41. procedure Erase(Position:SIzeUInt);inline;
  42. property Items[i : SizeUInt]: T read GetValue write SetValue; default;
  43. property Mutable[i : SizeUInt]:PT read GetMutable;
  44. end;
  45. implementation
  46. constructor TDeque.Create();
  47. begin
  48. FDataSize:=0;
  49. FCapacity:=0;
  50. FStart:=0;
  51. end;
  52. function TDeque.Size():SizeUInt;inline;
  53. begin
  54. Size:=FDataSize;
  55. end;
  56. function TDeque.IsEmpty():boolean;inline;
  57. begin
  58. if Size()=0 then
  59. IsEmpty:=true
  60. else
  61. IsEmpty:=false;
  62. end;
  63. procedure TDeque.PushBack(value:T);inline;
  64. begin
  65. if(FDataSize=FCapacity) then
  66. IncreaseCapacity;
  67. FData[(FStart+FDataSize)mod FCapacity]:=value;
  68. inc(FDataSize);
  69. end;
  70. procedure TDeque.PopFront();inline;
  71. begin
  72. if(FDataSize>0) then
  73. begin
  74. inc(FStart);
  75. dec(FDataSize);
  76. if(FStart=FCapacity) then
  77. FStart:=0;
  78. end;
  79. end;
  80. procedure TDeque.PopBack();inline;
  81. begin
  82. if(FDataSize>0) then
  83. dec(FDataSize);
  84. end;
  85. procedure TDeque.PushFront(value:T);inline;
  86. begin
  87. if(FDataSize=FCapacity) then
  88. IncreaseCapacity;
  89. if(FStart=0) then
  90. FStart:=FCapacity-1
  91. else
  92. dec(FStart);
  93. FData[FStart]:=value;
  94. inc(FDataSize);
  95. end;
  96. function TDeque.Front():T;inline;
  97. begin
  98. Assert(size > 0, 'Accessing empty deque');
  99. Front:=FData[FStart];
  100. end;
  101. function TDeque.Back():T;inline;
  102. begin
  103. Assert(size > 0, 'Accessing empty deque');
  104. Back:=FData[(FStart+FDataSize-1)mod FCapacity];
  105. end;
  106. procedure TDeque.SetValue(position:SizeUInt; value:T);inline;
  107. begin
  108. Assert(position < size, 'Deque access out of range');
  109. FData[(FStart+position)mod FCapacity]:=value;
  110. end;
  111. function TDeque.GetValue(position:SizeUInt):T;inline;
  112. begin
  113. Assert(position < size, 'Deque access out of range');
  114. GetValue:=FData[(FStart+position) mod FCapacity];
  115. end;
  116. function TDeque.GetMutable(position:SizeUInt):PT;inline;
  117. begin
  118. Assert(position < size, 'Deque access out of range');
  119. GetMutable:=@FData[(FStart+position) mod FCapacity];
  120. end;
  121. procedure TDeque.IncreaseCapacity;inline;
  122. var i,OldEnd:SizeUInt;
  123. begin
  124. OldEnd:=FCapacity;
  125. if(FCapacity=0) then
  126. FCapacity:=1
  127. else
  128. FCapacity:=FCapacity*2;
  129. SetLength(FData, FCapacity);
  130. if (FStart>0) then
  131. for i:=0 to FStart-1 do
  132. FData[OldEnd+i]:=FData[i];
  133. end;
  134. procedure TDeque.Reserve(cap:SizeUInt);inline;
  135. var i,OldEnd:SizeUInt;
  136. begin
  137. if(cap<FCapacity) then
  138. exit
  139. else if(cap<=2*FCapacity) then
  140. IncreaseCapacity
  141. else
  142. begin
  143. OldEnd:=FCapacity;
  144. FCapacity:=cap;
  145. SetLength(FData, FCapacity);
  146. if FStart > 0 then
  147. for i:=0 to FStart-1 do
  148. FData[OldEnd+i]:=FData[i];
  149. end;
  150. end;
  151. procedure TDeque.Resize(cap:SizeUInt);inline;
  152. begin
  153. Reserve(cap);
  154. FDataSize:=cap;
  155. end;
  156. procedure TDeque.Insert(Position:SizeUInt; Value: T);inline;
  157. var i:SizeUInt;
  158. begin
  159. pushBack(Value);
  160. for i:=Size-1 downto Position+1 do
  161. begin
  162. Items[i]:=Items[i-1];
  163. end;
  164. Items[Position]:=Value;
  165. end;
  166. procedure TDeque.Erase(Position:SizeUInt);inline;
  167. var i:SizeUInt;
  168. begin
  169. if Position <= Size then
  170. begin
  171. for i:=Position to Size-2 do
  172. begin
  173. Items[i]:=Items[i+1];
  174. end;
  175. popBack();
  176. end;
  177. end;
  178. end.