summary refs log tree commit diff stats
path: root/nimdoc
Commit message (Expand)AuthorAgeFilesLines
* feat: copy to clipboard (#18963)Abishek PY2021-10-221-1/+31
* [minor] give more friendly description (#18973)flywind2021-10-071-1/+1
* we need something better than warningAsError for effect handling viol… (#18...Andreas Rumpf2021-09-041-1/+1
* strict effects (#18777)Andreas Rumpf2021-09-022-5/+7
* docgen: draw frame around active anchors (#18607)Andrey Makarov2021-07-294-74/+154
* support same-line doc comments in routines (#18595)Timothee Cour2021-07-274-1/+171
* docgen: sort symbols (fix #17910) (#18560)Andrey Makarov2021-07-252-335/+335
* nim doc now correctly renders deprecated pragmas for routines and types (#18515)Timothee Cour2021-07-194-3/+23
* rm redundant blank lines before literal blocks (#18465)Andrey Makarov2021-07-081-10/+5
* docgen: move to shared RST state (fix #16990) (#18256)Andrey Makarov2021-06-201-5/+5
* Fix JS error on index page and detect dark mode (#18191)drtheuns2021-06-076-24/+54
* fix #16993, #18054, #17835 runnableExamples now works with templates and nest...Timothee Cour2021-06-023-10/+15
* fix warnings/hints in nimdoc/tester.nim (#18083)Timothee Cour2021-05-303-13/+16
* `doc2tex`: generate docs to Latex (#17997)Andrey Makarov2021-05-142-90/+90
* follow-up #17837: add `Console` for interactive sessions (#17930)Andrey Makarov2021-05-061-0/+8
* typo: nonexistant => nonexistent (#17918)Timothee Cour2021-05-024-11/+11
* gitutils: add diffStrings, diffFiles, and use it in testament to compare expe...Timothee Cour2021-04-302-2/+4
* improve nimsuggest/tester, minor improvements to koch.nim (#17879)Timothee Cour2021-04-291-1/+1
* add RST highlighting for command line / shells (also fixes #16858) (#17789)Andrey Makarov2021-04-211-5/+26
* rst indentation fixes (ref #17340) (#17715)Andrey Makarov2021-04-151-2/+2
* restyle RST option lists (#17637)Andrey Makarov2021-04-101-0/+27
* fix #17615(runnableExamples silently ignored if placed after some code) (#17619)flywind2021-04-022-4/+4
* enable syntax highlighting for inline code (#17585)Andrey Makarov2021-04-023-7/+11
* docgen: render pragmas by default except for a select list (and fix #9074) (#...Timothee Cour2021-04-013-43/+43
* fix https://github.com/nim-lang/RFCs/issues/352: show top-level import for to...Timothee Cour2021-03-291-4/+8
* fix #17260 render `\` properly in nim doc, rst2html (#17315)Timothee Cour2021-03-241-1/+1
* fix #16973 ; nim doc now shows correct, canonical import name in title (#16999)Timothee Cour2021-03-231-2/+2
* fix #16901: sidebar groups now works with all routines, not just proc,func (#...Timothee Cour2021-03-192-33/+90
* RST heading improvements (fix #17091) (#17195)Andrey Makarov2021-03-021-0/+1
* RST: implement footnotes and citations (#16960)Andrey Makarov2021-02-151-0/+13
* fix #16885: nimdoc css warning (#16893)zetashift2021-02-011-0/+2
* fix #9102 docgen: sidebar now shows proc signatures instead of encoding (#16857)Timothee Cour2021-01-295-35/+973
* conservative approach to fix #15184 (#16723)Andrey Makarov2021-01-154-0/+23
* RST: improve line blocks (#16518)Andrey Makarov2020-12-311-1/+1
* doc/rst2html: some few fixes for enumerated and bullet lists (#16295)Andrey Makarov2020-12-141-6/+8
* put both funcs and procs under the same section in the documentation (#16301)Miran2020-12-091-23/+12
* nimdoc: Initialize theme switch and pragma dots on DOMContentLoaded (#16247)Sebastian Reinhard2020-12-066-6/+18
* RST tables: fix latex col number; allow less than three of `=` (#16040)Andrey Makarov2020-12-041-2/+2
* fix #16164, render doc comments (#16230)Miran2020-12-024-1/+18
* add a tester for rst2html (#15936)Miran2020-11-123-0/+863
* Correct all eggs (#15906)Miran2020-11-101-1/+1
* fix #15702, show enum fields documentation (#15792)Miran2020-10-304-1/+44
* [backport: 1.4] Better linebreaks (#15658)Miran2020-10-223-61/+61
* add Source+Edit links on top of every docgend file (#15642)Timothee Cour2020-10-223-0/+3
* docgen: improve alignment of comments (still not perfect) (#15506)Andreas Rumpf2020-10-071-5/+6
* group procs of the same name in TOC (#15487)Miran2020-10-053-61/+157
* Fix theme switch load from local storage (#14897)Manuel Bojato2020-07-105-70/+25
* cleanup comment now that #14434 was fixed (#14874)Timothee Cour2020-07-011-2/+0
* fix #14846; add macros.extractDocCommentsAndRunnables (#14849)Timothee Cour2020-07-014-0/+58
* fix #14691 docgen works again for methods (#14701)Timothee Cour2020-06-184-0/+105
rt 7' href='/ahoang/Nim/commit/lib/pure/collections/sets.nim?h=devel&id=7e0da3e8f7687ba9eb2c24beca7b7a833621d1bc'>7e0da3e8f ^
3bc821aa5 ^







7e0da3e8f ^
3bc821aa5 ^















7e0da3e8f ^
3bc821aa5 ^



f89317988 ^
3bc821aa5 ^









ec2bd53ea ^
3bc821aa5 ^











05a66a6a6 ^
3bc821aa5 ^


05a66a6a6 ^
3bc821aa5 ^
a59abdf8e ^
3bc821aa5 ^










7e0da3e8f ^
3bc821aa5 ^



7e0da3e8f ^
3bc821aa5 ^

7e0da3e8f ^
3bc821aa5 ^






7e0da3e8f ^
3bc821aa5 ^







7e0da3e8f ^
3bc821aa5 ^




















7e0da3e8f ^
3bc821aa5 ^






2c5a2d07f ^

9f29bb8d9 ^
2c5a2d07f ^


9f29bb8d9 ^
2c5a2d07f ^









0b5c14962 ^
e8c87d070 ^
0b5c14962 ^
e8c87d070 ^
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256


                                     
                                         






                                                                             
                                                                            
                                         



                  
                     

                             




                                                   
                                                              

























                                                               
                                 






                                                                        
                                    





                                         
                                         

              








                                                                            

                                             
                            

                     
                                                                          

                 
                                 


                                       
                                                                 

                 
                               
                            
               

                                                     

                  
                                         
                            


                 

                                                     







                                       
                            















                                                                           
                                             



                                                           
                                       









                                       
                                                                           











                                                                          
                    


                                                  
                    
 
                                                                   










                                                             
                                                



                                                    
                            

                     
                                         






                                                                 
                                        







                                       
                                    




















                                                                            
                                                           






                                                                   

                                   
                               


                                    
                        









                                    
 
                                                                         
                       
                                         
#
#
#            Nimrod's Runtime Library
#        (c) Copyright 2012 Andreas Rumpf
#
#    See the file "copying.txt", included in this
#    distribution, for details about the copyright.
#

## The ``sets`` module implements an efficient hash set and ordered hash set.
##
## **Note**: The data types declared here have *value semantics*: This means
## that ``=`` performs a copy of the set.

import
  os, hashes, math

{.pragma: myShallow.}
when not defined(nimhygiene):
  {.pragma: dirty.}

type
  TSlotEnum = enum seEmpty, seFilled, seDeleted
  TKeyValuePair[A] = tuple[slot: TSlotEnum, key: A]
  TKeyValuePairSeq[A] = seq[TKeyValuePair[A]]
  TSet* {.final, myShallow.}[A] = object ## a generic hash set
    data: TKeyValuePairSeq[A]
    counter: int

proc len*[A](s: TSet[A]): int =
  ## returns the number of keys in `s`.
  result = s.counter

proc card*[A](s: TSet[A]): int =
  ## alias for `len`.
  result = s.counter

iterator items*[A](s: TSet[A]): A =
  ## iterates over any key in the table `t`.
  for h in 0..high(s.data):
    if s.data[h].slot == seFilled: yield s.data[h].key

const
  growthFactor = 2

proc mustRehash(length, counter: int): bool {.inline.} =
  assert(length > counter)
  result = (length * 2 < counter * 3) or (length - counter < 4)

proc nextTry(h, maxHash: THash): THash {.inline.} =
  result = ((5 * h) + 1) and maxHash

template rawGetImpl() {.dirty.} =
  var h: THash = hash(key) and high(s.data) # start with real hash value
  while s.data[h].slot != seEmpty:
    if s.data[h].key == key and s.data[h].slot == seFilled:
      return h
    h = nextTry(h, high(s.data))
  result = -1

template rawInsertImpl() {.dirty.} =
  var h: THash = hash(key) and high(data)
  while data[h].slot == seFilled:
    h = nextTry(h, high(data))
  data[h].key = key
  data[h].slot = seFilled

proc rawGet[A](s: TSet[A], key: A): int =
  rawGetImpl()

proc mget*[A](s: var TSet[A], key: A): var A =
  ## returns the element that is actually stored in 's' which has the same
  ## value as 'key' or raises the ``EInvalidKey`` exception. This is useful
  ## when one overloaded 'hash' and '==' but still needs reference semantics
  ## for sharing.
  var index = rawGet(s, key)
  if index >= 0: result = t.data[index].key
  else: raise newException(EInvalidKey, "key not found: " & $key)

proc contains*[A](s: TSet[A], key: A): bool =
  ## returns true iff `key` is in `s`.
  var index = rawGet(s, key)
  result = index >= 0

proc rawInsert[A](s: var TSet[A], data: var TKeyValuePairSeq[A], key: A) =
  rawInsertImpl()

proc enlarge[A](s: var TSet[A]) =
  var n: TKeyValuePairSeq[A]
  newSeq(n, len(s.data) * growthFactor)
  for i in countup(0, high(s.data)):
    if s.data[i].slot == seFilled: rawInsert(s, n, s.data[i].key)
  swap(s.data, n)

template inclImpl() {.dirty.} =
  var index = rawGet(s, key)
  if index < 0:
    if mustRehash(len(s.data), s.counter): enlarge(s)
    rawInsert(s, s.data, key)
    inc(s.counter)

template containsOrInclImpl() {.dirty.} =
  var index = rawGet(s, key)
  if index >= 0:
    result = true
  else:
    if mustRehash(len(s.data), s.counter): enlarge(s)
    rawInsert(s, s.data, key)
    inc(s.counter)

proc incl*[A](s: var TSet[A], key: A) =
  ## includes an element `key` in `s`.
  inclImpl()

proc excl*[A](s: var TSet[A], key: A) =
  ## excludes `key` from the set `s`.
  var index = rawGet(s, key)
  if index >= 0:
    s.data[index].slot = seDeleted
    dec(s.counter)

proc containsOrIncl*[A](s: var TSet[A], key: A): bool =
  ## returns true if `s` contains `key`, otherwise `key` is included in `s`
  ## and false is returned.
  containsOrInclImpl()

proc initSet*[A](initialSize=64): TSet[A] =
  ## creates a new hash set that is empty. `initialSize` needs to be
  ## a power of two.
  assert isPowerOfTwo(initialSize)
  result.counter = 0
  newSeq(result.data, initialSize)

proc toSet*[A](keys: openArray[A]): TSet[A] =
  ## creates a new hash set that contains the given `keys`.
  result = initSet[A](nextPowerOfTwo(keys.len+10))
  for key in items(keys): result.incl(key)

template dollarImpl(): stmt {.dirty.} =
  result = "{"
  for key in items(s):
    if result.len > 1: result.add(", ")
    result.add($key)
  result.add("}")

proc `$`*[A](s: TSet[A]): string =
  ## The `$` operator for hash sets.
  dollarImpl()

# ------------------------------ ordered set ------------------------------

type
  TOrderedKeyValuePair[A] = tuple[
    slot: TSlotEnum, next: int, key: A]
  TOrderedKeyValuePairSeq[A] = seq[TOrderedKeyValuePair[A]]
  TOrderedSet* {.
      final, myShallow.}[A] = object ## set that remembers insertion order
    data: TOrderedKeyValuePairSeq[A]
    counter, first, last: int

proc len*[A](s: TOrderedSet[A]): int {.inline.} =
  ## returns the number of keys in `s`.
  result = s.counter

proc card*[A](s: TOrderedSet[A]): int {.inline.} =
  ## alias for `len`.
  result = s.counter

template forAllOrderedPairs(yieldStmt: stmt) {.dirty, immediate.} =
  var h = s.first
  while h >= 0:
    var nxt = s.data[h].next
    if s.data[h].slot == seFilled: yieldStmt
    h = nxt

iterator items*[A](s: TOrderedSet[A]): A =
  ## iterates over any key in the set `s` in insertion order.
  forAllOrderedPairs:
    yield s.data[h].key

proc rawGet[A](s: TOrderedSet[A], key: A): int =
  rawGetImpl()

proc contains*[A](s: TOrderedSet[A], key: A): bool =
  ## returns true iff `key` is in `s`.
  var index = rawGet(s, key)
  result = index >= 0

proc rawInsert[A](s: var TOrderedSet[A], 
                  data: var TOrderedKeyValuePairSeq[A], key: A) =
  rawInsertImpl()
  data[h].next = -1
  if s.first < 0: s.first = h
  if s.last >= 0: data[s.last].next = h
  s.last = h

proc enlarge[A](s: var TOrderedSet[A]) =
  var n: TOrderedKeyValuePairSeq[A]
  newSeq(n, len(s.data) * growthFactor)
  var h = s.first
  s.first = -1
  s.last = -1
  while h >= 0:
    var nxt = s.data[h].next
    if s.data[h].slot == seFilled: 
      rawInsert(s, n, s.data[h].key)
    h = nxt
  swap(s.data, n)

proc incl*[A](s: var TOrderedSet[A], key: A) =
  ## includes an element `key` in `s`.
  inclImpl()

proc containsOrIncl*[A](s: var TOrderedSet[A], key: A): bool =
  ## returns true if `s` contains `key`, otherwise `key` is included in `s`
  ## and false is returned.
  containsOrInclImpl()

proc initOrderedSet*[A](initialSize=64): TOrderedSet[A] =
  ## creates a new ordered hash set that is empty. `initialSize` needs to be
  ## a power of two.
  assert isPowerOfTwo(initialSize)
  result.counter = 0
  result.first = -1
  result.last = -1
  newSeq(result.data, initialSize)

proc toOrderedSet*[A](keys: openArray[A]): TOrderedSet[A] =
  ## creates a new ordered hash set that contains the given `keys`.
  result = initOrderedSet[A](nextPowerOfTwo(keys.len+10))
  for key in items(keys): result.incl(key)

proc `$`*[A](s: TOrderedSet[A]): string =
  ## The `$` operator for ordered hash sets.
  dollarImpl()

proc `<`*[A](s, t: TSet[A]): bool =
  ## Is s a strict subset of t?
  s.counter != t.counter and s <= t

proc `<=`*[A](s, t: TSet[A]): bool =
  ## Is s a subset of t?
  result = false
  if s.counter > t.counter: return
  result = true
  for item in s:
    if not(t.contains(item)):
      result = false
      return
      
proc `==`*[A](s, t: TSet[A]): bool =
  s.counter == t.counter and s <= t

proc map*[A, B](data: TSet[A], op: proc (x: A): B {.closure.}): TSet[B] =
  result = initSet[B]()
  for item in data: result.incl(op(item))