deques.nim 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556
  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 `IndexError`
  15. ## on such access. This should not be relied upon, as `-d:release` 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(IndexError, 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 math, typetraits
  53. type
  54. Deque*[T] = object
  55. ## A double-ended queue backed with a ringed seq buffer.
  56. ##
  57. ## To initialize an empty deque use `initDeque proc <#initDeque,int>`_.
  58. data: seq[T]
  59. head, tail, count, mask: int
  60. proc initDeque*[T](initialSize: int = 4): Deque[T] =
  61. ## Create a new empty deque.
  62. ##
  63. ## Optionally, the initial capacity can be reserved via `initialSize`
  64. ## as a performance optimization.
  65. ## The length of a newly created deque will still be 0.
  66. ##
  67. ## ``initialSize`` must be a power of two (default: 4).
  68. ## If you need to accept runtime values for this you could use the
  69. ## `nextPowerOfTwo proc<math.html#nextPowerOfTwo,int>`_ from the
  70. ## `math module<math.html>`_.
  71. assert isPowerOfTwo(initialSize)
  72. result.mask = initialSize-1
  73. newSeq(result.data, initialSize)
  74. proc len*[T](deq: Deque[T]): int {.inline.} =
  75. ## Return the number of elements of `deq`.
  76. result = deq.count
  77. template emptyCheck(deq) =
  78. # Bounds check for the regular deque access.
  79. when compileOption("boundChecks"):
  80. if unlikely(deq.count < 1):
  81. raise newException(IndexError, "Empty deque.")
  82. template xBoundsCheck(deq, i) =
  83. # Bounds check for the array like accesses.
  84. when compileOption("boundChecks"): # d:release should disable this.
  85. if unlikely(i >= deq.count): # x < deq.low is taken care by the Natural parameter
  86. raise newException(IndexError,
  87. "Out of bounds: " & $i & " > " & $(deq.count - 1))
  88. if unlikely(i < 0): # when used with BackwardsIndex
  89. raise newException(IndexError,
  90. "Out of bounds: " & $i & " < 0")
  91. proc `[]`*[T](deq: Deque[T], i: Natural): T {.inline.} =
  92. ## Access the i-th element of `deq`.
  93. runnableExamples:
  94. var a = initDeque[int]()
  95. for i in 1 .. 5:
  96. a.addLast(10*i)
  97. assert a[0] == 10
  98. assert a[3] == 40
  99. doAssertRaises(IndexError, echo a[8])
  100. xBoundsCheck(deq, i)
  101. return deq.data[(deq.head + i) and deq.mask]
  102. proc `[]`*[T](deq: var Deque[T], i: Natural): var T {.inline.} =
  103. ## Access the i-th element of `deq` and return a mutable
  104. ## reference to it.
  105. runnableExamples:
  106. var a = initDeque[int]()
  107. for i in 1 .. 5:
  108. a.addLast(10*i)
  109. assert a[0] == 10
  110. assert a[3] == 40
  111. doAssertRaises(IndexError, echo a[8])
  112. xBoundsCheck(deq, i)
  113. return deq.data[(deq.head + i) and deq.mask]
  114. proc `[]=`*[T](deq: var Deque[T], i: Natural, val: T) {.inline.} =
  115. ## Change the i-th element of `deq`.
  116. runnableExamples:
  117. var a = initDeque[int]()
  118. for i in 1 .. 5:
  119. a.addLast(10*i)
  120. a[0] = 99
  121. a[3] = 66
  122. assert $a == "[99, 20, 30, 66, 50]"
  123. xBoundsCheck(deq, i)
  124. deq.data[(deq.head + i) and deq.mask] = val
  125. proc `[]`*[T](deq: Deque[T], i: BackwardsIndex): T {.inline.} =
  126. ## Access the backwards indexed i-th element.
  127. ##
  128. ## `deq[^1]` is the last element.
  129. runnableExamples:
  130. var a = initDeque[int]()
  131. for i in 1 .. 5:
  132. a.addLast(10*i)
  133. assert a[^1] == 50
  134. assert a[^4] == 20
  135. doAssertRaises(IndexError, echo a[^9])
  136. xBoundsCheck(deq, deq.len - int(i))
  137. return deq[deq.len - int(i)]
  138. proc `[]`*[T](deq: var Deque[T], i: BackwardsIndex): var T {.inline.} =
  139. ## Access the backwards indexed i-th element.
  140. ##
  141. ## `deq[^1]` is the last element.
  142. runnableExamples:
  143. var a = initDeque[int]()
  144. for i in 1 .. 5:
  145. a.addLast(10*i)
  146. assert a[^1] == 50
  147. assert a[^4] == 20
  148. doAssertRaises(IndexError, echo a[^9])
  149. xBoundsCheck(deq, deq.len - int(i))
  150. return deq[deq.len - int(i)]
  151. proc `[]=`*[T](deq: var Deque[T], i: BackwardsIndex, x: T) {.inline.} =
  152. ## Change the backwards indexed i-th element.
  153. ##
  154. ## `deq[^1]` is the last element.
  155. runnableExamples:
  156. var a = initDeque[int]()
  157. for i in 1 .. 5:
  158. a.addLast(10*i)
  159. a[^1] = 99
  160. a[^3] = 77
  161. assert $a == "[10, 20, 77, 40, 99]"
  162. xBoundsCheck(deq, deq.len - int(i))
  163. deq[deq.len - int(i)] = x
  164. iterator items*[T](deq: Deque[T]): T =
  165. ## Yield every element of `deq`.
  166. ##
  167. ## **Examples:**
  168. ##
  169. ## .. code-block::
  170. ## var a = initDeque[int]()
  171. ## for i in 1 .. 3:
  172. ## a.addLast(10*i)
  173. ##
  174. ## for x in a: # the same as: for x in items(a):
  175. ## echo x
  176. ##
  177. ## # 10
  178. ## # 20
  179. ## # 30
  180. ##
  181. var i = deq.head
  182. for c in 0 ..< deq.count:
  183. yield deq.data[i]
  184. i = (i + 1) and deq.mask
  185. iterator mitems*[T](deq: var Deque[T]): var T =
  186. ## Yield every element of `deq`, which can be modified.
  187. runnableExamples:
  188. var a = initDeque[int]()
  189. for i in 1 .. 5:
  190. a.addLast(10*i)
  191. assert $a == "[10, 20, 30, 40, 50]"
  192. for x in mitems(a):
  193. x = 5*x - 1
  194. assert $a == "[49, 99, 149, 199, 249]"
  195. var i = deq.head
  196. for c in 0 ..< deq.count:
  197. yield deq.data[i]
  198. i = (i + 1) and deq.mask
  199. iterator pairs*[T](deq: Deque[T]): tuple[key: int, val: T] =
  200. ## Yield every (position, value) of `deq`.
  201. ##
  202. ## **Examples:**
  203. ##
  204. ## .. code-block::
  205. ## var a = initDeque[int]()
  206. ## for i in 1 .. 3:
  207. ## a.addLast(10*i)
  208. ##
  209. ## for k, v in pairs(a):
  210. ## echo "key: ", k, ", value: ", v
  211. ##
  212. ## # key: 0, value: 10
  213. ## # key: 1, value: 20
  214. ## # key: 2, value: 30
  215. ##
  216. var i = deq.head
  217. for c in 0 ..< deq.count:
  218. yield (c, deq.data[i])
  219. i = (i + 1) and deq.mask
  220. proc contains*[T](deq: Deque[T], item: T): bool {.inline.} =
  221. ## Return true if `item` is in `deq` or false if not found.
  222. ##
  223. ## Usually used via the ``in`` operator.
  224. ## It is the equivalent of ``deq.find(item) >= 0``.
  225. ##
  226. ## .. code-block:: Nim
  227. ## if x in q:
  228. ## assert q.contains(x)
  229. for e in deq:
  230. if e == item: return true
  231. return false
  232. proc expandIfNeeded[T](deq: var Deque[T]) =
  233. var cap = deq.mask + 1
  234. if unlikely(deq.count >= cap):
  235. var n = newSeq[T](cap * 2)
  236. for i, x in pairs(deq): # don't use copyMem because the GC and because it's slower.
  237. shallowCopy(n[i], x)
  238. shallowCopy(deq.data, n)
  239. deq.mask = cap * 2 - 1
  240. deq.tail = deq.count
  241. deq.head = 0
  242. proc addFirst*[T](deq: var Deque[T], item: T) =
  243. ## Add an `item` to the beginning of the `deq`.
  244. ##
  245. ## See also:
  246. ## * `addLast proc <#addLast,Deque[T],T>`_
  247. ## * `peekFirst proc <#peekFirst,Deque[T]>`_
  248. ## * `peekLast proc <#peekLast,Deque[T]>`_
  249. ## * `popFirst proc <#popFirst,Deque[T]>`_
  250. ## * `popLast proc <#popLast,Deque[T]>`_
  251. runnableExamples:
  252. var a = initDeque[int]()
  253. for i in 1 .. 5:
  254. a.addFirst(10*i)
  255. assert $a == "[50, 40, 30, 20, 10]"
  256. expandIfNeeded(deq)
  257. inc deq.count
  258. deq.head = (deq.head - 1) and deq.mask
  259. deq.data[deq.head] = item
  260. proc addLast*[T](deq: var Deque[T], item: T) =
  261. ## Add an `item` to the end of the `deq`.
  262. ##
  263. ## See also:
  264. ## * `addFirst proc <#addFirst,Deque[T],T>`_
  265. ## * `peekFirst proc <#peekFirst,Deque[T]>`_
  266. ## * `peekLast proc <#peekLast,Deque[T]>`_
  267. ## * `popFirst proc <#popFirst,Deque[T]>`_
  268. ## * `popLast proc <#popLast,Deque[T]>`_
  269. runnableExamples:
  270. var a = initDeque[int]()
  271. for i in 1 .. 5:
  272. a.addLast(10*i)
  273. assert $a == "[10, 20, 30, 40, 50]"
  274. expandIfNeeded(deq)
  275. inc deq.count
  276. deq.data[deq.tail] = item
  277. deq.tail = (deq.tail + 1) and deq.mask
  278. proc peekFirst*[T](deq: Deque[T]): T {.inline.} =
  279. ## Returns the first element of `deq`, but does not remove it from the deque.
  280. ##
  281. ## See also:
  282. ## * `addFirst proc <#addFirst,Deque[T],T>`_
  283. ## * `addLast proc <#addLast,Deque[T],T>`_
  284. ## * `peekLast proc <#peekLast,Deque[T]>`_
  285. ## * `popFirst proc <#popFirst,Deque[T]>`_
  286. ## * `popLast proc <#popLast,Deque[T]>`_
  287. runnableExamples:
  288. var a = initDeque[int]()
  289. for i in 1 .. 5:
  290. a.addLast(10*i)
  291. assert $a == "[10, 20, 30, 40, 50]"
  292. assert a.peekFirst == 10
  293. assert len(a) == 5
  294. emptyCheck(deq)
  295. result = deq.data[deq.head]
  296. proc peekLast*[T](deq: Deque[T]): T {.inline.} =
  297. ## Returns the last element of `deq`, but does not remove it from the deque.
  298. ##
  299. ## See also:
  300. ## * `addFirst proc <#addFirst,Deque[T],T>`_
  301. ## * `addLast proc <#addLast,Deque[T],T>`_
  302. ## * `peekFirst proc <#peekFirst,Deque[T]>`_
  303. ## * `popFirst proc <#popFirst,Deque[T]>`_
  304. ## * `popLast proc <#popLast,Deque[T]>`_
  305. runnableExamples:
  306. var a = initDeque[int]()
  307. for i in 1 .. 5:
  308. a.addLast(10*i)
  309. assert $a == "[10, 20, 30, 40, 50]"
  310. assert a.peekLast == 50
  311. assert len(a) == 5
  312. emptyCheck(deq)
  313. result = deq.data[(deq.tail - 1) and deq.mask]
  314. template destroy(x: untyped) =
  315. reset(x)
  316. proc popFirst*[T](deq: var Deque[T]): T {.inline, discardable.} =
  317. ## Remove and returns the first element of the `deq`.
  318. ##
  319. ## See also:
  320. ## * `addFirst proc <#addFirst,Deque[T],T>`_
  321. ## * `addLast proc <#addLast,Deque[T],T>`_
  322. ## * `peekFirst proc <#peekFirst,Deque[T]>`_
  323. ## * `peekLast proc <#peekLast,Deque[T]>`_
  324. ## * `popLast proc <#popLast,Deque[T]>`_
  325. ## * `clear proc <#clear,Deque[T]>`_
  326. ## * `shrink proc <#shrink,Deque[T],int,int>`_
  327. runnableExamples:
  328. var a = initDeque[int]()
  329. for i in 1 .. 5:
  330. a.addLast(10*i)
  331. assert $a == "[10, 20, 30, 40, 50]"
  332. assert a.popFirst == 10
  333. assert $a == "[20, 30, 40, 50]"
  334. emptyCheck(deq)
  335. dec deq.count
  336. result = deq.data[deq.head]
  337. destroy(deq.data[deq.head])
  338. deq.head = (deq.head + 1) and deq.mask
  339. proc popLast*[T](deq: var Deque[T]): T {.inline, discardable.} =
  340. ## Remove and returns the last element of the `deq`.
  341. ##
  342. ## See also:
  343. ## * `addFirst proc <#addFirst,Deque[T],T>`_
  344. ## * `addLast proc <#addLast,Deque[T],T>`_
  345. ## * `peekFirst proc <#peekFirst,Deque[T]>`_
  346. ## * `peekLast proc <#peekLast,Deque[T]>`_
  347. ## * `popFirst proc <#popFirst,Deque[T]>`_
  348. ## * `clear proc <#clear,Deque[T]>`_
  349. ## * `shrink proc <#shrink,Deque[T],int,int>`_
  350. runnableExamples:
  351. var a = initDeque[int]()
  352. for i in 1 .. 5:
  353. a.addLast(10*i)
  354. assert $a == "[10, 20, 30, 40, 50]"
  355. assert a.popLast == 50
  356. assert $a == "[10, 20, 30, 40]"
  357. emptyCheck(deq)
  358. dec deq.count
  359. deq.tail = (deq.tail - 1) and deq.mask
  360. result = deq.data[deq.tail]
  361. destroy(deq.data[deq.tail])
  362. proc clear*[T](deq: var Deque[T]) {.inline.} =
  363. ## Resets the deque so that it is empty.
  364. ##
  365. ## See also:
  366. ## * `clear proc <#clear,Deque[T]>`_
  367. ## * `shrink proc <#shrink,Deque[T],int,int>`_
  368. runnableExamples:
  369. var a = initDeque[int]()
  370. for i in 1 .. 5:
  371. a.addFirst(10*i)
  372. assert $a == "[50, 40, 30, 20, 10]"
  373. clear(a)
  374. assert len(a) == 0
  375. for el in mitems(deq): destroy(el)
  376. deq.count = 0
  377. deq.tail = deq.head
  378. proc shrink*[T](deq: var Deque[T], fromFirst = 0, fromLast = 0) =
  379. ## Remove `fromFirst` elements from the front of the deque and
  380. ## `fromLast` elements from the back.
  381. ##
  382. ## If the supplied number of elements exceeds the total number of elements
  383. ## in the deque, the deque will remain empty.
  384. ##
  385. ## See also:
  386. ## * `clear proc <#clear,Deque[T]>`_
  387. runnableExamples:
  388. var a = initDeque[int]()
  389. for i in 1 .. 5:
  390. a.addFirst(10*i)
  391. assert $a == "[50, 40, 30, 20, 10]"
  392. a.shrink(fromFirst = 2, fromLast = 1)
  393. assert $a == "[30, 20]"
  394. if fromFirst + fromLast > deq.count:
  395. clear(deq)
  396. return
  397. for i in 0 ..< fromFirst:
  398. destroy(deq.data[deq.head])
  399. deq.head = (deq.head + 1) and deq.mask
  400. for i in 0 ..< fromLast:
  401. destroy(deq.data[deq.tail])
  402. deq.tail = (deq.tail - 1) and deq.mask
  403. dec deq.count, fromFirst + fromLast
  404. proc `$`*[T](deq: Deque[T]): string =
  405. ## Turn a deque into its string representation.
  406. result = "["
  407. for x in deq:
  408. if result.len > 1: result.add(", ")
  409. result.addQuoted(x)
  410. result.add("]")
  411. when isMainModule:
  412. var deq = initDeque[int](1)
  413. deq.addLast(4)
  414. deq.addFirst(9)
  415. deq.addFirst(123)
  416. var first = deq.popFirst()
  417. deq.addLast(56)
  418. assert(deq.peekLast() == 56)
  419. deq.addLast(6)
  420. assert(deq.peekLast() == 6)
  421. var second = deq.popFirst()
  422. deq.addLast(789)
  423. assert(deq.peekLast() == 789)
  424. assert first == 123
  425. assert second == 9
  426. assert($deq == "[4, 56, 6, 789]")
  427. assert deq[0] == deq.peekFirst and deq.peekFirst == 4
  428. #assert deq[^1] == deq.peekLast and deq.peekLast == 789
  429. deq[0] = 42
  430. deq[deq.len - 1] = 7
  431. assert 6 in deq and 789 notin deq
  432. assert deq.find(6) >= 0
  433. assert deq.find(789) < 0
  434. block:
  435. var d = initDeque[int](1)
  436. d.addLast 7
  437. d.addLast 8
  438. d.addLast 10
  439. d.addFirst 5
  440. d.addFirst 2
  441. d.addFirst 1
  442. d.addLast 20
  443. d.shrink(fromLast = 2)
  444. doAssert($d == "[1, 2, 5, 7, 8]")
  445. d.shrink(2, 1)
  446. doAssert($d == "[5, 7]")
  447. d.shrink(2, 2)
  448. doAssert d.len == 0
  449. for i in -2 .. 10:
  450. if i in deq:
  451. assert deq.contains(i) and deq.find(i) >= 0
  452. else:
  453. assert(not deq.contains(i) and deq.find(i) < 0)
  454. when compileOption("boundChecks"):
  455. try:
  456. echo deq[99]
  457. assert false
  458. except IndexError:
  459. discard
  460. try:
  461. assert deq.len == 4
  462. for i in 0 ..< 5: deq.popFirst()
  463. assert false
  464. except IndexError:
  465. discard
  466. # grabs some types of resize error.
  467. deq = initDeque[int]()
  468. for i in 1 .. 4: deq.addLast i
  469. deq.popFirst()
  470. deq.popLast()
  471. for i in 5 .. 8: deq.addFirst i
  472. assert $deq == "[8, 7, 6, 5, 2, 3]"
  473. # Similar to proc from the documentation example
  474. proc foo(a, b: Positive) = # assume random positive values for `a` and `b`.
  475. var deq = initDeque[int]()
  476. assert deq.len == 0
  477. for i in 1 .. a: deq.addLast i
  478. if b < deq.len: # checking before indexed access.
  479. assert deq[b] == b + 1
  480. # The following two lines don't need any checking on access due to the logic
  481. # of the program, but that would not be the case if `a` could be 0.
  482. assert deq.peekFirst == 1
  483. assert deq.peekLast == a
  484. while deq.len > 0: # checking if the deque is empty
  485. assert deq.popFirst() > 0
  486. #foo(0,0)
  487. foo(8, 5)
  488. foo(10, 9)
  489. foo(1, 1)
  490. foo(2, 1)
  491. foo(1, 5)
  492. foo(3, 2)