deques.nim 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529
  1. #
  2. #
  3. # Nim's Runtime Library
  4. # (c) Copyright 2012 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. ## Implementation of a `deque`:idx: (double-ended queue).
  10. ## The underlying implementation uses a ``seq``.
  11. ##
  12. ## None of the procs that get an individual value from the deque can be used
  13. ## on an empty deque.
  14. ## If compiled with `boundChecks` option, those procs will raise an `IndexDefect`
  15. ## on such access. This should not be relied upon, as `-d:danger` or `--checks:off` will
  16. ## disable those checks and may return garbage or crash the program.
  17. ##
  18. ## As such, a check to see if the deque is empty is needed before any
  19. ## access, unless your program logic guarantees it indirectly.
  20. ##
  21. ## .. code-block:: Nim
  22. ## import deques
  23. ##
  24. ## var a = initDeque[int]()
  25. ##
  26. ## doAssertRaises(IndexDefect, echo a[0])
  27. ##
  28. ## for i in 1 .. 5:
  29. ## a.addLast(10*i)
  30. ## assert $a == "[10, 20, 30, 40, 50]"
  31. ##
  32. ## assert a.peekFirst == 10
  33. ## assert a.peekLast == 50
  34. ## assert len(a) == 5
  35. ##
  36. ## assert a.popFirst == 10
  37. ## assert a.popLast == 50
  38. ## assert len(a) == 3
  39. ##
  40. ## a.addFirst(11)
  41. ## a.addFirst(22)
  42. ## a.addFirst(33)
  43. ## assert $a == "[33, 22, 11, 20, 30, 40]"
  44. ##
  45. ## a.shrink(fromFirst = 1, fromLast = 2)
  46. ## assert $a == "[22, 11, 20]"
  47. ##
  48. ##
  49. ## **See also:**
  50. ## * `lists module <lists.html>`_ for singly and doubly linked lists and rings
  51. ## * `channels module <channels.html>`_ for inter-thread communication
  52. import std/private/since
  53. import math
  54. type
  55. Deque*[T] = object
  56. ## A double-ended queue backed with a ringed seq buffer.
  57. ##
  58. ## To initialize an empty deque use `initDeque proc <#initDeque,int>`_.
  59. data: seq[T]
  60. head, tail, count, mask: int
  61. const
  62. defaultInitialSize* = 4
  63. template initImpl(result: typed, initialSize: int) =
  64. let correctSize = nextPowerOfTwo(initialSize)
  65. result.mask = correctSize-1
  66. newSeq(result.data, correctSize)
  67. template checkIfInitialized(deq: typed) =
  68. when compiles(defaultInitialSize):
  69. if deq.mask == 0:
  70. initImpl(deq, defaultInitialSize)
  71. proc initDeque*[T](initialSize: int = 4): Deque[T] =
  72. ## Creates a new empty deque.
  73. ##
  74. ## Optionally, the initial capacity can be reserved via `initialSize`
  75. ## as a performance optimization.
  76. ## The length of a newly created deque will still be 0.
  77. ##
  78. ## See also:
  79. ## * `toDeque proc <#toDeque,openArray[T]>`_
  80. result.initImpl(initialSize)
  81. proc toDeque*[T](x: openArray[T]): Deque[T] {.since: (1, 3).} =
  82. ## Creates a new deque that contains the elements of `x` (in the same order).
  83. ##
  84. ## See also:
  85. ## * `initDeque proc <#initDeque,int>`_
  86. runnableExamples:
  87. var a = toDeque([7, 8, 9])
  88. assert len(a) == 3
  89. assert a.popFirst == 7
  90. assert len(a) == 2
  91. result.initImpl(x.len)
  92. for item in items(x):
  93. result.addLast(item)
  94. proc len*[T](deq: Deque[T]): int {.inline.} =
  95. ## Returns the number of elements of `deq`.
  96. result = deq.count
  97. template emptyCheck(deq) =
  98. # Bounds check for the regular deque access.
  99. when compileOption("boundChecks"):
  100. if unlikely(deq.count < 1):
  101. raise newException(IndexDefect, "Empty deque.")
  102. template xBoundsCheck(deq, i) =
  103. # Bounds check for the array like accesses.
  104. when compileOption("boundChecks"): # `-d:danger` or `--checks:off` should disable this.
  105. if unlikely(i >= deq.count): # x < deq.low is taken care by the Natural parameter
  106. raise newException(IndexDefect,
  107. "Out of bounds: " & $i & " > " & $(deq.count - 1))
  108. if unlikely(i < 0): # when used with BackwardsIndex
  109. raise newException(IndexDefect,
  110. "Out of bounds: " & $i & " < 0")
  111. proc `[]`*[T](deq: Deque[T], i: Natural): T {.inline.} =
  112. ## Accesses the i-th element of `deq`.
  113. runnableExamples:
  114. var a = initDeque[int]()
  115. for i in 1 .. 5:
  116. a.addLast(10*i)
  117. assert a[0] == 10
  118. assert a[3] == 40
  119. doAssertRaises(IndexDefect, echo a[8])
  120. xBoundsCheck(deq, i)
  121. return deq.data[(deq.head + i) and deq.mask]
  122. proc `[]`*[T](deq: var Deque[T], i: Natural): var T {.inline.} =
  123. ## Accesses the i-th element of `deq` and return a mutable
  124. ## reference to it.
  125. runnableExamples:
  126. var a = initDeque[int]()
  127. for i in 1 .. 5:
  128. a.addLast(10*i)
  129. assert a[0] == 10
  130. assert a[3] == 40
  131. doAssertRaises(IndexDefect, echo a[8])
  132. xBoundsCheck(deq, i)
  133. return deq.data[(deq.head + i) and deq.mask]
  134. proc `[]=`*[T](deq: var Deque[T], i: Natural, val: T) {.inline.} =
  135. ## Changes the i-th element of `deq`.
  136. runnableExamples:
  137. var a = initDeque[int]()
  138. for i in 1 .. 5:
  139. a.addLast(10*i)
  140. a[0] = 99
  141. a[3] = 66
  142. assert $a == "[99, 20, 30, 66, 50]"
  143. checkIfInitialized(deq)
  144. xBoundsCheck(deq, i)
  145. deq.data[(deq.head + i) and deq.mask] = val
  146. proc `[]`*[T](deq: Deque[T], i: BackwardsIndex): T {.inline.} =
  147. ## Accesses the backwards indexed i-th element.
  148. ##
  149. ## `deq[^1]` is the last element.
  150. runnableExamples:
  151. var a = initDeque[int]()
  152. for i in 1 .. 5:
  153. a.addLast(10*i)
  154. assert a[^1] == 50
  155. assert a[^4] == 20
  156. doAssertRaises(IndexDefect, echo a[^9])
  157. xBoundsCheck(deq, deq.len - int(i))
  158. return deq[deq.len - int(i)]
  159. proc `[]`*[T](deq: var Deque[T], i: BackwardsIndex): var T {.inline.} =
  160. ## Accesses the backwards indexed i-th element.
  161. ##
  162. ## `deq[^1]` is the last element.
  163. runnableExamples:
  164. var a = initDeque[int]()
  165. for i in 1 .. 5:
  166. a.addLast(10*i)
  167. assert a[^1] == 50
  168. assert a[^4] == 20
  169. doAssertRaises(IndexDefect, echo a[^9])
  170. xBoundsCheck(deq, deq.len - int(i))
  171. return deq[deq.len - int(i)]
  172. proc `[]=`*[T](deq: var Deque[T], i: BackwardsIndex, x: T) {.inline.} =
  173. ## Changes the backwards indexed i-th element.
  174. ##
  175. ## `deq[^1]` is the last element.
  176. runnableExamples:
  177. var a = initDeque[int]()
  178. for i in 1 .. 5:
  179. a.addLast(10*i)
  180. a[^1] = 99
  181. a[^3] = 77
  182. assert $a == "[10, 20, 77, 40, 99]"
  183. checkIfInitialized(deq)
  184. xBoundsCheck(deq, deq.len - int(i))
  185. deq[deq.len - int(i)] = x
  186. iterator items*[T](deq: Deque[T]): T =
  187. ## Yields every element of `deq`.
  188. ##
  189. ## **Examples:**
  190. ##
  191. ## .. code-block::
  192. ## var a = initDeque[int]()
  193. ## for i in 1 .. 3:
  194. ## a.addLast(10*i)
  195. ##
  196. ## for x in a: # the same as: for x in items(a):
  197. ## echo x
  198. ##
  199. ## # 10
  200. ## # 20
  201. ## # 30
  202. ##
  203. var i = deq.head
  204. for c in 0 ..< deq.count:
  205. yield deq.data[i]
  206. i = (i + 1) and deq.mask
  207. iterator mitems*[T](deq: var Deque[T]): var T =
  208. ## Yields every element of `deq`, which can be modified.
  209. runnableExamples:
  210. var a = initDeque[int]()
  211. for i in 1 .. 5:
  212. a.addLast(10*i)
  213. assert $a == "[10, 20, 30, 40, 50]"
  214. for x in mitems(a):
  215. x = 5*x - 1
  216. assert $a == "[49, 99, 149, 199, 249]"
  217. var i = deq.head
  218. for c in 0 ..< deq.count:
  219. yield deq.data[i]
  220. i = (i + 1) and deq.mask
  221. iterator pairs*[T](deq: Deque[T]): tuple[key: int, val: T] =
  222. ## Yields every (position, value) of `deq`.
  223. ##
  224. ## **Examples:**
  225. ##
  226. ## .. code-block::
  227. ## var a = initDeque[int]()
  228. ## for i in 1 .. 3:
  229. ## a.addLast(10*i)
  230. ##
  231. ## for k, v in pairs(a):
  232. ## echo "key: ", k, ", value: ", v
  233. ##
  234. ## # key: 0, value: 10
  235. ## # key: 1, value: 20
  236. ## # key: 2, value: 30
  237. ##
  238. var i = deq.head
  239. for c in 0 ..< deq.count:
  240. yield (c, deq.data[i])
  241. i = (i + 1) and deq.mask
  242. proc contains*[T](deq: Deque[T], item: T): bool {.inline.} =
  243. ## Returns true if `item` is in `deq` or false if not found.
  244. ##
  245. ## Usually used via the ``in`` operator.
  246. ## It is the equivalent of ``deq.find(item) >= 0``.
  247. ##
  248. ## .. code-block:: Nim
  249. ## if x in q:
  250. ## assert q.contains(x)
  251. for e in deq:
  252. if e == item: return true
  253. return false
  254. proc expandIfNeeded[T](deq: var Deque[T]) =
  255. checkIfInitialized(deq)
  256. var cap = deq.mask + 1
  257. if unlikely(deq.count >= cap):
  258. var n = newSeq[T](cap * 2)
  259. var i = 0
  260. for x in mitems(deq):
  261. when nimVM: n[i] = x # workaround for VM bug
  262. else: n[i] = move(x)
  263. inc i
  264. deq.data = move(n)
  265. deq.mask = cap * 2 - 1
  266. deq.tail = deq.count
  267. deq.head = 0
  268. proc addFirst*[T](deq: var Deque[T], item: T) =
  269. ## Adds an `item` to the beginning of the `deq`.
  270. ##
  271. ## See also:
  272. ## * `addLast proc <#addLast,Deque[T],T>`_
  273. ## * `peekFirst proc <#peekFirst,Deque[T]>`_
  274. ## * `peekLast proc <#peekLast,Deque[T]>`_
  275. ## * `popFirst proc <#popFirst,Deque[T]>`_
  276. ## * `popLast proc <#popLast,Deque[T]>`_
  277. runnableExamples:
  278. var a = initDeque[int]()
  279. for i in 1 .. 5:
  280. a.addFirst(10*i)
  281. assert $a == "[50, 40, 30, 20, 10]"
  282. expandIfNeeded(deq)
  283. inc deq.count
  284. deq.head = (deq.head - 1) and deq.mask
  285. deq.data[deq.head] = item
  286. proc addLast*[T](deq: var Deque[T], item: T) =
  287. ## Adds an `item` to the end of the `deq`.
  288. ##
  289. ## See also:
  290. ## * `addFirst proc <#addFirst,Deque[T],T>`_
  291. ## * `peekFirst proc <#peekFirst,Deque[T]>`_
  292. ## * `peekLast proc <#peekLast,Deque[T]>`_
  293. ## * `popFirst proc <#popFirst,Deque[T]>`_
  294. ## * `popLast proc <#popLast,Deque[T]>`_
  295. runnableExamples:
  296. var a = initDeque[int]()
  297. for i in 1 .. 5:
  298. a.addLast(10*i)
  299. assert $a == "[10, 20, 30, 40, 50]"
  300. expandIfNeeded(deq)
  301. inc deq.count
  302. deq.data[deq.tail] = item
  303. deq.tail = (deq.tail + 1) and deq.mask
  304. proc peekFirst*[T](deq: Deque[T]): T {.inline.} =
  305. ## Returns the first element of `deq`, but does not remove it from the deque.
  306. ##
  307. ## See also:
  308. ## * `addFirst proc <#addFirst,Deque[T],T>`_
  309. ## * `addLast proc <#addLast,Deque[T],T>`_
  310. ## * `peekLast proc <#peekLast,Deque[T]>`_
  311. ## * `popFirst proc <#popFirst,Deque[T]>`_
  312. ## * `popLast proc <#popLast,Deque[T]>`_
  313. runnableExamples:
  314. var a = initDeque[int]()
  315. for i in 1 .. 5:
  316. a.addLast(10*i)
  317. assert $a == "[10, 20, 30, 40, 50]"
  318. assert a.peekFirst == 10
  319. assert len(a) == 5
  320. emptyCheck(deq)
  321. result = deq.data[deq.head]
  322. proc peekLast*[T](deq: Deque[T]): T {.inline.} =
  323. ## Returns the last element of `deq`, but does not remove it from the deque.
  324. ##
  325. ## See also:
  326. ## * `addFirst proc <#addFirst,Deque[T],T>`_
  327. ## * `addLast proc <#addLast,Deque[T],T>`_
  328. ## * `peekFirst proc <#peekFirst,Deque[T]>`_
  329. ## * `popFirst proc <#popFirst,Deque[T]>`_
  330. ## * `popLast proc <#popLast,Deque[T]>`_
  331. runnableExamples:
  332. var a = initDeque[int]()
  333. for i in 1 .. 5:
  334. a.addLast(10*i)
  335. assert $a == "[10, 20, 30, 40, 50]"
  336. assert a.peekLast == 50
  337. assert len(a) == 5
  338. emptyCheck(deq)
  339. result = deq.data[(deq.tail - 1) and deq.mask]
  340. proc peekFirst*[T](deq: var Deque[T]): var T {.inline, since: (1, 3).} =
  341. ## Returns the first element of `deq`, but does not remove it from the deque.
  342. ##
  343. ## See also:
  344. ## * `addFirst proc <#addFirst,Deque[T],T>`_
  345. ## * `addLast proc <#addLast,Deque[T],T>`_
  346. ## * `peekLast proc <#peekLast,Deque[T]>`_
  347. ## * `popFirst proc <#popFirst,Deque[T]>`_
  348. ## * `popLast proc <#popLast,Deque[T]>`_
  349. runnableExamples:
  350. var a = initDeque[int]()
  351. for i in 1 .. 5:
  352. a.addLast(10*i)
  353. assert $a == "[10, 20, 30, 40, 50]"
  354. assert a.peekFirst == 10
  355. assert len(a) == 5
  356. emptyCheck(deq)
  357. result = deq.data[deq.head]
  358. proc peekLast*[T](deq: var Deque[T]): var T {.inline, since: (1, 3).} =
  359. ## Returns the last element of `deq`, but does not remove it from the deque.
  360. ##
  361. ## See also:
  362. ## * `addFirst proc <#addFirst,Deque[T],T>`_
  363. ## * `addLast proc <#addLast,Deque[T],T>`_
  364. ## * `peekFirst proc <#peekFirst,Deque[T]>`_
  365. ## * `popFirst proc <#popFirst,Deque[T]>`_
  366. ## * `popLast proc <#popLast,Deque[T]>`_
  367. runnableExamples:
  368. var a = initDeque[int]()
  369. for i in 1 .. 5:
  370. a.addLast(10*i)
  371. assert $a == "[10, 20, 30, 40, 50]"
  372. assert a.peekLast == 50
  373. assert len(a) == 5
  374. emptyCheck(deq)
  375. result = deq.data[(deq.tail - 1) and deq.mask]
  376. template destroy(x: untyped) =
  377. reset(x)
  378. proc popFirst*[T](deq: var Deque[T]): T {.inline, discardable.} =
  379. ## Removes and returns the first element of the `deq`.
  380. ##
  381. ## See also:
  382. ## * `addFirst proc <#addFirst,Deque[T],T>`_
  383. ## * `addLast proc <#addLast,Deque[T],T>`_
  384. ## * `peekFirst proc <#peekFirst,Deque[T]>`_
  385. ## * `peekLast proc <#peekLast,Deque[T]>`_
  386. ## * `popLast proc <#popLast,Deque[T]>`_
  387. ## * `clear proc <#clear,Deque[T]>`_
  388. ## * `shrink proc <#shrink,Deque[T],int,int>`_
  389. runnableExamples:
  390. var a = initDeque[int]()
  391. for i in 1 .. 5:
  392. a.addLast(10*i)
  393. assert $a == "[10, 20, 30, 40, 50]"
  394. assert a.popFirst == 10
  395. assert $a == "[20, 30, 40, 50]"
  396. emptyCheck(deq)
  397. dec deq.count
  398. result = deq.data[deq.head]
  399. destroy(deq.data[deq.head])
  400. deq.head = (deq.head + 1) and deq.mask
  401. proc popLast*[T](deq: var Deque[T]): T {.inline, discardable.} =
  402. ## Removes and returns the last element of the `deq`.
  403. ##
  404. ## See also:
  405. ## * `addFirst proc <#addFirst,Deque[T],T>`_
  406. ## * `addLast proc <#addLast,Deque[T],T>`_
  407. ## * `peekFirst proc <#peekFirst,Deque[T]>`_
  408. ## * `peekLast proc <#peekLast,Deque[T]>`_
  409. ## * `popFirst proc <#popFirst,Deque[T]>`_
  410. ## * `clear proc <#clear,Deque[T]>`_
  411. ## * `shrink proc <#shrink,Deque[T],int,int>`_
  412. runnableExamples:
  413. var a = initDeque[int]()
  414. for i in 1 .. 5:
  415. a.addLast(10*i)
  416. assert $a == "[10, 20, 30, 40, 50]"
  417. assert a.popLast == 50
  418. assert $a == "[10, 20, 30, 40]"
  419. emptyCheck(deq)
  420. dec deq.count
  421. deq.tail = (deq.tail - 1) and deq.mask
  422. result = deq.data[deq.tail]
  423. destroy(deq.data[deq.tail])
  424. proc clear*[T](deq: var Deque[T]) {.inline.} =
  425. ## Resets the deque so that it is empty.
  426. ##
  427. ## See also:
  428. ## * `clear proc <#clear,Deque[T]>`_
  429. ## * `shrink proc <#shrink,Deque[T],int,int>`_
  430. runnableExamples:
  431. var a = initDeque[int]()
  432. for i in 1 .. 5:
  433. a.addFirst(10*i)
  434. assert $a == "[50, 40, 30, 20, 10]"
  435. clear(a)
  436. assert len(a) == 0
  437. for el in mitems(deq): destroy(el)
  438. deq.count = 0
  439. deq.tail = deq.head
  440. proc shrink*[T](deq: var Deque[T], fromFirst = 0, fromLast = 0) =
  441. ## Removes `fromFirst` elements from the front of the deque and
  442. ## `fromLast` elements from the back.
  443. ##
  444. ## If the supplied number of elements exceeds the total number of elements
  445. ## in the deque, the deque will remain empty.
  446. ##
  447. ## See also:
  448. ## * `clear proc <#clear,Deque[T]>`_
  449. runnableExamples:
  450. var a = initDeque[int]()
  451. for i in 1 .. 5:
  452. a.addFirst(10*i)
  453. assert $a == "[50, 40, 30, 20, 10]"
  454. a.shrink(fromFirst = 2, fromLast = 1)
  455. assert $a == "[30, 20]"
  456. if fromFirst + fromLast > deq.count:
  457. clear(deq)
  458. return
  459. for i in 0 ..< fromFirst:
  460. destroy(deq.data[deq.head])
  461. deq.head = (deq.head + 1) and deq.mask
  462. for i in 0 ..< fromLast:
  463. destroy(deq.data[deq.tail])
  464. deq.tail = (deq.tail - 1) and deq.mask
  465. dec deq.count, fromFirst + fromLast
  466. proc `$`*[T](deq: Deque[T]): string =
  467. ## Turns a deque into its string representation.
  468. result = "["
  469. for x in deq:
  470. if result.len > 1: result.add(", ")
  471. result.addQuoted(x)
  472. result.add("]")