hamster 1.0.0 → 1.0.1.pre.rc.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (509) hide show
  1. checksums.yaml +4 -4
  2. data/lib/hamster.rb +2 -3
  3. data/lib/hamster/core_ext.rb +1 -0
  4. data/lib/hamster/core_ext/enumerable.rb +17 -17
  5. data/lib/hamster/core_ext/enumerator.rb +16 -0
  6. data/lib/hamster/core_ext/io.rb +17 -15
  7. data/lib/hamster/enumerable.rb +107 -123
  8. data/lib/hamster/experimental/mutable_queue.rb +6 -2
  9. data/lib/hamster/experimental/mutable_set.rb +3 -1
  10. data/lib/hamster/experimental/mutable_stack.rb +30 -0
  11. data/lib/hamster/hash.rb +95 -713
  12. data/lib/hamster/immutable.rb +0 -4
  13. data/lib/hamster/list.rb +242 -1062
  14. data/lib/hamster/mutable_hash.rb +3 -1
  15. data/lib/hamster/queue.rb +87 -0
  16. data/lib/hamster/read_copy_update.rb +1 -2
  17. data/lib/hamster/set.rb +73 -478
  18. data/lib/hamster/sorter.rb +25 -0
  19. data/lib/hamster/stack.rb +75 -0
  20. data/lib/hamster/trie.rb +48 -199
  21. data/lib/hamster/tuple.rb +39 -0
  22. data/lib/hamster/undefined.rb +3 -1
  23. data/lib/hamster/vector.rb +72 -1326
  24. data/lib/hamster/version.rb +1 -1
  25. data/spec/hamster/core_ext/array_spec.rb +20 -0
  26. data/spec/{lib/hamster → hamster}/core_ext/enumerable_spec.rb +0 -5
  27. data/spec/hamster/core_ext/enumerator_spec.rb +19 -0
  28. data/spec/{lib/hamster → hamster}/core_ext/io_spec.rb +0 -0
  29. data/spec/hamster/experimental/mutable_set/add_qm_spec.rb +47 -0
  30. data/spec/hamster/experimental/mutable_set/add_spec.rb +51 -0
  31. data/spec/hamster/experimental/mutable_set/delete_qm_spec.rb +47 -0
  32. data/spec/hamster/experimental/mutable_set/delete_spec.rb +47 -0
  33. data/spec/hamster/experimental/mutable_stack/pop_spec.rb +41 -0
  34. data/spec/hamster/experimental/mutable_stack/push_spec.rb +41 -0
  35. data/spec/hamster/hash/all_spec.rb +59 -0
  36. data/spec/hamster/hash/any_spec.rb +67 -0
  37. data/spec/hamster/hash/clear_spec.rb +36 -0
  38. data/spec/hamster/hash/construction_spec.rb +35 -0
  39. data/spec/{lib/hamster → hamster}/hash/copying_spec.rb +12 -3
  40. data/spec/hamster/hash/delete_spec.rb +47 -0
  41. data/spec/hamster/hash/each_spec.rb +41 -0
  42. data/spec/hamster/hash/empty_spec.rb +27 -0
  43. data/spec/hamster/hash/eql_spec.rb +62 -0
  44. data/spec/hamster/hash/except_spec.rb +31 -0
  45. data/spec/hamster/hash/fetch_spec.rb +95 -0
  46. data/spec/hamster/hash/filter_spec.rb +63 -0
  47. data/spec/hamster/hash/find_spec.rb +58 -0
  48. data/spec/hamster/hash/get_spec.rb +55 -0
  49. data/spec/hamster/hash/has_key_spec.rb +35 -0
  50. data/spec/hamster/hash/hash_spec.rb +52 -0
  51. data/spec/{lib/hamster → hamster}/hash/immutable_spec.rb +3 -0
  52. data/spec/hamster/hash/inspect_spec.rb +32 -0
  53. data/spec/hamster/hash/keys_spec.rb +21 -0
  54. data/spec/hamster/hash/map_spec.rb +64 -0
  55. data/spec/{lib/hamster → hamster}/hash/marshal_spec.rb +3 -3
  56. data/spec/hamster/hash/merge_spec.rb +36 -0
  57. data/spec/{lib/hamster → hamster}/hash/none_spec.rb +14 -12
  58. data/spec/hamster/hash/put_spec.rb +65 -0
  59. data/spec/hamster/hash/reduce_spec.rb +60 -0
  60. data/spec/hamster/hash/remove_spec.rb +63 -0
  61. data/spec/{lib/hamster → hamster}/hash/size_spec.rb +2 -2
  62. data/spec/hamster/hash/slice_spec.rb +26 -0
  63. data/spec/hamster/hash/uniq_spec.rb +23 -0
  64. data/spec/hamster/hash/values_spec.rb +34 -0
  65. data/spec/{lib/hamster → hamster}/immutable/copying_spec.rb +8 -1
  66. data/spec/{lib/hamster → hamster}/immutable/immutable_spec.rb +14 -1
  67. data/spec/{lib/hamster → hamster}/immutable/memoize_spec.rb +3 -2
  68. data/spec/{lib/hamster → hamster}/immutable/new_spec.rb +0 -0
  69. data/spec/{lib/hamster → hamster}/immutable/transform_spec.rb +0 -0
  70. data/spec/{lib/hamster → hamster}/immutable/transform_unless_spec.rb +0 -0
  71. data/spec/hamster/list/add_spec.rb +16 -0
  72. data/spec/hamster/list/all_spec.rb +111 -0
  73. data/spec/hamster/list/any_spec.rb +79 -0
  74. data/spec/{lib/hamster → hamster}/list/append_spec.rb +22 -11
  75. data/spec/hamster/list/at_spec.rb +49 -0
  76. data/spec/hamster/list/break_spec.rb +85 -0
  77. data/spec/{lib/hamster → hamster}/list/cadr_spec.rb +17 -6
  78. data/spec/{lib/hamster → hamster}/list/chunk_spec.rb +17 -6
  79. data/spec/{lib/hamster → hamster}/list/clear_spec.rb +16 -5
  80. data/spec/hamster/list/combinations_spec.rb +51 -0
  81. data/spec/{lib/hamster → hamster}/list/compact_spec.rb +17 -6
  82. data/spec/hamster/list/cons_spec.rb +41 -0
  83. data/spec/hamster/list/construction_spec.rb +166 -0
  84. data/spec/{lib/hamster → hamster}/list/copying_spec.rb +16 -4
  85. data/spec/hamster/list/count_spec.rb +66 -0
  86. data/spec/hamster/list/cycle_spec.rb +45 -0
  87. data/spec/{lib/hamster → hamster}/list/drop_spec.rb +17 -6
  88. data/spec/hamster/list/drop_while_spec.rb +59 -0
  89. data/spec/hamster/list/each_slice_spec.rb +80 -0
  90. data/spec/hamster/list/each_spec.rb +72 -0
  91. data/spec/hamster/list/each_with_index_spec.rb +42 -0
  92. data/spec/hamster/list/elem_index_spec.rb +58 -0
  93. data/spec/hamster/list/elem_indices_spec.rb +45 -0
  94. data/spec/hamster/list/empty_spec.rb +47 -0
  95. data/spec/hamster/list/eql_spec.rb +78 -0
  96. data/spec/hamster/list/filter_spec.rb +70 -0
  97. data/spec/{lib/hamster → hamster}/list/find_all_spec.rb +2 -3
  98. data/spec/{lib/hamster → hamster}/list/find_index_spec.rb +27 -5
  99. data/spec/hamster/list/find_indices_spec.rb +45 -0
  100. data/spec/{lib/hamster → hamster}/list/find_spec.rb +33 -11
  101. data/spec/{lib/hamster → hamster}/list/flat_map_spec.rb +0 -0
  102. data/spec/{lib/hamster → hamster}/list/flatten_spec.rb +17 -6
  103. data/spec/{lib/hamster → hamster}/list/grep_spec.rb +33 -10
  104. data/spec/{lib/hamster → hamster}/list/group_by_spec.rb +44 -9
  105. data/spec/{lib/hamster → hamster}/list/hash_spec.rb +12 -4
  106. data/spec/{lib/hamster → hamster}/list/head_spec.rb +18 -3
  107. data/spec/{lib/hamster → hamster}/list/include_spec.rb +27 -6
  108. data/spec/{lib/hamster → hamster}/list/init_spec.rb +17 -6
  109. data/spec/hamster/list/inits_spec.rb +42 -0
  110. data/spec/hamster/list/inspect_spec.rb +43 -0
  111. data/spec/{lib/hamster → hamster}/list/intersperse_spec.rb +17 -6
  112. data/spec/hamster/list/join_spec.rb +81 -0
  113. data/spec/hamster/list/last_spec.rb +44 -0
  114. data/spec/{lib/hamster → hamster}/list/map_spec.rb +35 -12
  115. data/spec/hamster/list/maximum_spec.rb +77 -0
  116. data/spec/{lib/hamster → hamster}/list/merge_by_spec.rb +32 -5
  117. data/spec/{lib/hamster → hamster}/list/merge_spec.rb +20 -1
  118. data/spec/hamster/list/minimum_spec.rb +77 -0
  119. data/spec/{lib/hamster → hamster}/list/none_spec.rb +39 -12
  120. data/spec/{lib/hamster → hamster}/list/one_spec.rb +38 -13
  121. data/spec/hamster/list/partition_spec.rb +75 -0
  122. data/spec/{lib/hamster → hamster}/list/pop_spec.rb +1 -1
  123. data/spec/hamster/list/product_spec.rb +44 -0
  124. data/spec/hamster/list/reduce_spec.rb +73 -0
  125. data/spec/{lib/hamster/list/reject_spec.rb → hamster/list/remove_spec.rb} +35 -11
  126. data/spec/{lib/hamster → hamster}/list/reverse_spec.rb +25 -8
  127. data/spec/{lib/hamster → hamster}/list/select_spec.rb +2 -3
  128. data/spec/{lib/hamster → hamster}/list/size_spec.rb +26 -5
  129. data/spec/hamster/list/slice_spec.rb +50 -0
  130. data/spec/{lib/hamster → hamster}/list/sorting_spec.rb +34 -11
  131. data/spec/hamster/list/span_spec.rb +86 -0
  132. data/spec/{lib/hamster → hamster}/list/split_at_spec.rb +23 -14
  133. data/spec/hamster/list/sum_spec.rb +44 -0
  134. data/spec/hamster/list/tail_spec.rb +48 -0
  135. data/spec/hamster/list/tails_spec.rb +42 -0
  136. data/spec/{lib/hamster → hamster}/list/take_spec.rb +17 -6
  137. data/spec/{lib/hamster → hamster}/list/take_while_spec.rb +18 -11
  138. data/spec/hamster/list/to_a_spec.rb +54 -0
  139. data/spec/{lib/hamster → hamster}/list/to_ary_spec.rb +4 -1
  140. data/spec/{lib/hamster → hamster}/list/to_list_spec.rb +16 -4
  141. data/spec/hamster/list/to_set_spec.rb +33 -0
  142. data/spec/{lib/hamster → hamster}/list/union_spec.rb +23 -6
  143. data/spec/hamster/list/uniq_spec.rb +45 -0
  144. data/spec/{lib/hamster → hamster}/list/zip_spec.rb +9 -2
  145. data/spec/hamster/queue/clear_spec.rb +36 -0
  146. data/spec/hamster/queue/construction_spec.rb +43 -0
  147. data/spec/hamster/queue/dequeue_spec.rb +40 -0
  148. data/spec/hamster/queue/empty_spec.rb +47 -0
  149. data/spec/{lib/hamster/deque → hamster/queue}/enqueue_spec.rb +21 -8
  150. data/spec/hamster/queue/head_spec.rb +35 -0
  151. data/spec/hamster/queue/inspect_spec.rb +31 -0
  152. data/spec/{lib/hamster/deque → hamster/queue}/size_spec.rb +20 -5
  153. data/spec/hamster/queue/to_a_spec.rb +42 -0
  154. data/spec/{lib/hamster/deque → hamster/queue}/to_ary_spec.rb +6 -6
  155. data/spec/hamster/queue/to_list_spec.rb +44 -0
  156. data/spec/hamster/set/add_spec.rb +51 -0
  157. data/spec/hamster/set/all_spec.rb +67 -0
  158. data/spec/hamster/set/any_spec.rb +67 -0
  159. data/spec/hamster/set/clear_spec.rb +36 -0
  160. data/spec/{lib/hamster → hamster}/set/compact_spec.rb +16 -5
  161. data/spec/{lib/hamster → hamster}/set/construction_spec.rb +17 -5
  162. data/spec/{lib/hamster → hamster}/set/copying_spec.rb +12 -3
  163. data/spec/{lib/hamster → hamster}/set/count_spec.rb +28 -11
  164. data/spec/hamster/set/delete_spec.rb +47 -0
  165. data/spec/{lib/hamster/sorted_set → hamster/set}/difference_spec.rb +21 -7
  166. data/spec/{lib/hamster/set/reverse_each_spec.rb → hamster/set/each_spec.rb} +7 -8
  167. data/spec/hamster/set/empty_spec.rb +35 -0
  168. data/spec/{lib/hamster → hamster}/set/eqeq_spec.rb +0 -0
  169. data/spec/{lib/hamster → hamster}/set/eql_spec.rb +1 -7
  170. data/spec/{lib/hamster/sorted_set → hamster/set}/exclusion_spec.rb +20 -5
  171. data/spec/hamster/set/filter_spec.rb +79 -0
  172. data/spec/{lib/hamster → hamster}/set/find_spec.rb +25 -8
  173. data/spec/hamster/set/flatten_spec.rb +49 -0
  174. data/spec/hamster/set/foreach_spec.rb +39 -0
  175. data/spec/{lib/hamster → hamster}/set/grep_spec.rb +1 -1
  176. data/spec/hamster/set/group_by_spec.rb +65 -0
  177. data/spec/hamster/set/hash_spec.rb +20 -0
  178. data/spec/hamster/set/head_spec.rb +39 -0
  179. data/spec/{lib/hamster → hamster}/set/immutable_spec.rb +4 -1
  180. data/spec/hamster/set/include_spec.rb +35 -0
  181. data/spec/hamster/set/inspect_spec.rb +32 -0
  182. data/spec/hamster/set/intersection_spec.rb +46 -0
  183. data/spec/{lib/hamster/vector → hamster/set}/join_spec.rb +33 -23
  184. data/spec/hamster/set/map_spec.rb +64 -0
  185. data/spec/{lib/hamster → hamster}/set/marshal_spec.rb +9 -4
  186. data/spec/hamster/set/maximum_spec.rb +65 -0
  187. data/spec/hamster/set/minimum_spec.rb +65 -0
  188. data/spec/{lib/hamster → hamster}/set/none_spec.rb +30 -15
  189. data/spec/{lib/hamster → hamster}/set/one_spec.rb +29 -14
  190. data/spec/hamster/set/partition_spec.rb +71 -0
  191. data/spec/{lib/hamster → hamster}/set/product_spec.rb +15 -7
  192. data/spec/hamster/set/reduce_spec.rb +87 -0
  193. data/spec/hamster/set/remove_spec.rb +63 -0
  194. data/spec/{lib/hamster → hamster}/set/size_spec.rb +10 -1
  195. data/spec/{lib/hamster → hamster}/set/sorting_spec.rb +16 -18
  196. data/spec/hamster/set/subset_spec.rb +39 -0
  197. data/spec/{lib/hamster/vector → hamster/set}/sum_spec.rb +18 -4
  198. data/spec/hamster/set/superset_spec.rb +39 -0
  199. data/spec/hamster/set/to_a_spec.rb +42 -0
  200. data/spec/{lib/hamster/vector → hamster/set}/to_list_spec.rb +23 -8
  201. data/spec/{lib/hamster → hamster}/set/to_set_spec.rb +15 -3
  202. data/spec/hamster/set/union_spec.rb +45 -0
  203. data/spec/hamster/set/uniq_spec.rb +23 -0
  204. data/spec/hamster/sorter/immutable_spec.rb +12 -0
  205. data/spec/hamster/stack/clear_spec.rb +36 -0
  206. data/spec/hamster/stack/construction_spec.rb +43 -0
  207. data/spec/hamster/stack/copying_spec.rb +31 -0
  208. data/spec/hamster/stack/empty_spec.rb +31 -0
  209. data/spec/hamster/stack/eql_spec.rb +60 -0
  210. data/spec/hamster/stack/immutable_spec.rb +12 -0
  211. data/spec/hamster/stack/inspect_spec.rb +31 -0
  212. data/spec/hamster/stack/peek_spec.rb +40 -0
  213. data/spec/hamster/stack/pop_spec.rb +41 -0
  214. data/spec/hamster/stack/push_spec.rb +41 -0
  215. data/spec/hamster/stack/size_spec.rb +35 -0
  216. data/spec/hamster/stack/to_a_spec.rb +42 -0
  217. data/spec/hamster/stack/to_ary.rb +37 -0
  218. data/spec/hamster/stack/to_list_spec.rb +33 -0
  219. data/spec/hamster/trie/remove_spec.rb +117 -0
  220. data/spec/hamster/tuple/copying_spec.rb +24 -0
  221. data/spec/hamster/tuple/eql_spec.rb +61 -0
  222. data/spec/hamster/tuple/first_spec.rb +19 -0
  223. data/spec/hamster/tuple/immutable_spec.rb +12 -0
  224. data/spec/hamster/tuple/inspect_spec.rb +19 -0
  225. data/spec/hamster/tuple/last_spec.rb +19 -0
  226. data/spec/hamster/tuple/to_a_spec.rb +38 -0
  227. data/spec/hamster/tuple/to_ary_spec.rb +38 -0
  228. data/spec/hamster/undefined/erase_spec.rb +47 -0
  229. data/spec/hamster/vector/add_spec.rb +48 -0
  230. data/spec/{lib/hamster → hamster}/vector/any_spec.rb +0 -0
  231. data/spec/hamster/vector/clear_spec.rb +35 -0
  232. data/spec/{lib/hamster → hamster}/vector/copying_spec.rb +14 -4
  233. data/spec/hamster/vector/each_spec.rb +45 -0
  234. data/spec/hamster/vector/each_with_index_spec.rb +41 -0
  235. data/spec/hamster/vector/empty_spec.rb +34 -0
  236. data/spec/hamster/vector/eql_spec.rb +64 -0
  237. data/spec/hamster/vector/filter_spec.rb +62 -0
  238. data/spec/hamster/vector/first_spec.rb +35 -0
  239. data/spec/hamster/vector/get_spec.rb +80 -0
  240. data/spec/{lib/hamster → hamster}/vector/include_spec.rb +17 -4
  241. data/spec/hamster/vector/inspect_spec.rb +33 -0
  242. data/spec/{lib/hamster → hamster}/vector/last_spec.rb +3 -12
  243. data/spec/{lib/hamster → hamster}/vector/length_spec.rb +3 -12
  244. data/spec/hamster/vector/map_spec.rb +63 -0
  245. data/spec/{lib/hamster → hamster}/vector/reduce_spec.rb +47 -16
  246. data/spec/hamster/vector/set_spec.rb +113 -0
  247. data/spec/{lib/hamster → hamster}/vector/to_a_spec.rb +12 -11
  248. data/spec/{lib/hamster → hamster}/vector/to_ary_spec.rb +0 -0
  249. data/spec/lib/hamster/vector/cons_spec.rb +48 -0
  250. data/spec/lib/hamster/vector/exist_spec.rb +70 -0
  251. data/spec/lib/hamster/vector/exists_spec.rb +70 -0
  252. data/spec/lib/hamster/vector/ltlt_spec.rb +2 -20
  253. data/spec/spec_helper.rb +5 -36
  254. metadata +510 -723
  255. data/lib/hamster/deque.rb +0 -252
  256. data/lib/hamster/nested.rb +0 -36
  257. data/lib/hamster/sorted_set.rb +0 -1397
  258. data/spec/lib/hamster/core_ext/array_spec.rb +0 -14
  259. data/spec/lib/hamster/deque/clear_spec.rb +0 -34
  260. data/spec/lib/hamster/deque/construction_spec.rb +0 -30
  261. data/spec/lib/hamster/deque/copying_spec.rb +0 -20
  262. data/spec/lib/hamster/deque/dequeue_spec.rb +0 -35
  263. data/spec/lib/hamster/deque/empty_spec.rb +0 -40
  264. data/spec/lib/hamster/deque/first_spec.rb +0 -18
  265. data/spec/lib/hamster/deque/inspect_spec.rb +0 -24
  266. data/spec/lib/hamster/deque/last_spec.rb +0 -18
  267. data/spec/lib/hamster/deque/marshal_spec.rb +0 -34
  268. data/spec/lib/hamster/deque/new_spec.rb +0 -44
  269. data/spec/lib/hamster/deque/pop_spec.rb +0 -33
  270. data/spec/lib/hamster/deque/pretty_print_spec.rb +0 -24
  271. data/spec/lib/hamster/deque/random_modification_spec.rb +0 -34
  272. data/spec/lib/hamster/deque/to_a_spec.rb +0 -27
  273. data/spec/lib/hamster/deque/to_list_spec.rb +0 -26
  274. data/spec/lib/hamster/deque/unshift_spec.rb +0 -26
  275. data/spec/lib/hamster/experimental/mutable_set/add_qm_spec.rb +0 -39
  276. data/spec/lib/hamster/experimental/mutable_set/add_spec.rb +0 -37
  277. data/spec/lib/hamster/experimental/mutable_set/delete_qm_spec.rb +0 -38
  278. data/spec/lib/hamster/experimental/mutable_set/delete_spec.rb +0 -37
  279. data/spec/lib/hamster/hash/all_spec.rb +0 -54
  280. data/spec/lib/hamster/hash/any_spec.rb +0 -54
  281. data/spec/lib/hamster/hash/assoc_spec.rb +0 -52
  282. data/spec/lib/hamster/hash/clear_spec.rb +0 -43
  283. data/spec/lib/hamster/hash/construction_spec.rb +0 -39
  284. data/spec/lib/hamster/hash/default_proc_spec.rb +0 -73
  285. data/spec/lib/hamster/hash/delete_spec.rb +0 -40
  286. data/spec/lib/hamster/hash/each_spec.rb +0 -78
  287. data/spec/lib/hamster/hash/each_with_index_spec.rb +0 -30
  288. data/spec/lib/hamster/hash/empty_spec.rb +0 -44
  289. data/spec/lib/hamster/hash/eql_spec.rb +0 -70
  290. data/spec/lib/hamster/hash/except_spec.rb +0 -43
  291. data/spec/lib/hamster/hash/fetch_spec.rb +0 -58
  292. data/spec/lib/hamster/hash/find_spec.rb +0 -44
  293. data/spec/lib/hamster/hash/flat_map_spec.rb +0 -36
  294. data/spec/lib/hamster/hash/flatten_spec.rb +0 -99
  295. data/spec/lib/hamster/hash/get_spec.rb +0 -80
  296. data/spec/lib/hamster/hash/has_key_spec.rb +0 -32
  297. data/spec/lib/hamster/hash/has_value_spec.rb +0 -28
  298. data/spec/lib/hamster/hash/hash_spec.rb +0 -30
  299. data/spec/lib/hamster/hash/inspect_spec.rb +0 -31
  300. data/spec/lib/hamster/hash/invert_spec.rb +0 -31
  301. data/spec/lib/hamster/hash/key_spec.rb +0 -28
  302. data/spec/lib/hamster/hash/keys_spec.rb +0 -17
  303. data/spec/lib/hamster/hash/map_spec.rb +0 -46
  304. data/spec/lib/hamster/hash/merge_spec.rb +0 -83
  305. data/spec/lib/hamster/hash/min_max_spec.rb +0 -46
  306. data/spec/lib/hamster/hash/new_spec.rb +0 -71
  307. data/spec/lib/hamster/hash/partition_spec.rb +0 -36
  308. data/spec/lib/hamster/hash/pretty_print_spec.rb +0 -35
  309. data/spec/lib/hamster/hash/put_spec.rb +0 -103
  310. data/spec/lib/hamster/hash/reduce_spec.rb +0 -36
  311. data/spec/lib/hamster/hash/reject_spec.rb +0 -62
  312. data/spec/lib/hamster/hash/reverse_each_spec.rb +0 -28
  313. data/spec/lib/hamster/hash/sample_spec.rb +0 -14
  314. data/spec/lib/hamster/hash/select_spec.rb +0 -58
  315. data/spec/lib/hamster/hash/slice_spec.rb +0 -45
  316. data/spec/lib/hamster/hash/sort_spec.rb +0 -27
  317. data/spec/lib/hamster/hash/store_spec.rb +0 -76
  318. data/spec/lib/hamster/hash/take_spec.rb +0 -36
  319. data/spec/lib/hamster/hash/to_a_spec.rb +0 -14
  320. data/spec/lib/hamster/hash/to_hash_spec.rb +0 -22
  321. data/spec/lib/hamster/hash/update_in_spec.rb +0 -80
  322. data/spec/lib/hamster/hash/values_at_spec.rb +0 -14
  323. data/spec/lib/hamster/hash/values_spec.rb +0 -25
  324. data/spec/lib/hamster/list/add_spec.rb +0 -26
  325. data/spec/lib/hamster/list/all_spec.rb +0 -58
  326. data/spec/lib/hamster/list/any_spec.rb +0 -50
  327. data/spec/lib/hamster/list/at_spec.rb +0 -30
  328. data/spec/lib/hamster/list/break_spec.rb +0 -70
  329. data/spec/lib/hamster/list/combination_spec.rb +0 -34
  330. data/spec/lib/hamster/list/compare_spec.rb +0 -31
  331. data/spec/lib/hamster/list/cons_spec.rb +0 -26
  332. data/spec/lib/hamster/list/construction_spec.rb +0 -111
  333. data/spec/lib/hamster/list/count_spec.rb +0 -37
  334. data/spec/lib/hamster/list/cycle_spec.rb +0 -29
  335. data/spec/lib/hamster/list/delete_at_spec.rb +0 -19
  336. data/spec/lib/hamster/list/delete_spec.rb +0 -17
  337. data/spec/lib/hamster/list/drop_while_spec.rb +0 -39
  338. data/spec/lib/hamster/list/each_slice_spec.rb +0 -52
  339. data/spec/lib/hamster/list/each_spec.rb +0 -41
  340. data/spec/lib/hamster/list/each_with_index_spec.rb +0 -29
  341. data/spec/lib/hamster/list/empty_spec.rb +0 -24
  342. data/spec/lib/hamster/list/eql_spec.rb +0 -62
  343. data/spec/lib/hamster/list/fill_spec.rb +0 -50
  344. data/spec/lib/hamster/list/index_spec.rb +0 -34
  345. data/spec/lib/hamster/list/indices_spec.rb +0 -62
  346. data/spec/lib/hamster/list/inits_spec.rb +0 -29
  347. data/spec/lib/hamster/list/insert_spec.rb +0 -47
  348. data/spec/lib/hamster/list/inspect_spec.rb +0 -30
  349. data/spec/lib/hamster/list/join_spec.rb +0 -64
  350. data/spec/lib/hamster/list/last_spec.rb +0 -24
  351. data/spec/lib/hamster/list/ltlt_spec.rb +0 -20
  352. data/spec/lib/hamster/list/maximum_spec.rb +0 -40
  353. data/spec/lib/hamster/list/minimum_spec.rb +0 -40
  354. data/spec/lib/hamster/list/multithreading_spec.rb +0 -48
  355. data/spec/lib/hamster/list/partition_spec.rb +0 -116
  356. data/spec/lib/hamster/list/permutation_spec.rb +0 -56
  357. data/spec/lib/hamster/list/product_spec.rb +0 -24
  358. data/spec/lib/hamster/list/reduce_spec.rb +0 -54
  359. data/spec/lib/hamster/list/rotate_spec.rb +0 -37
  360. data/spec/lib/hamster/list/sample_spec.rb +0 -14
  361. data/spec/lib/hamster/list/slice_spec.rb +0 -230
  362. data/spec/lib/hamster/list/span_spec.rb +0 -77
  363. data/spec/lib/hamster/list/subsequences_spec.rb +0 -24
  364. data/spec/lib/hamster/list/sum_spec.rb +0 -24
  365. data/spec/lib/hamster/list/tail_spec.rb +0 -31
  366. data/spec/lib/hamster/list/tails_spec.rb +0 -29
  367. data/spec/lib/hamster/list/to_a_spec.rb +0 -40
  368. data/spec/lib/hamster/list/to_set_spec.rb +0 -19
  369. data/spec/lib/hamster/list/transpose_spec.rb +0 -20
  370. data/spec/lib/hamster/list/uniq_spec.rb +0 -30
  371. data/spec/lib/hamster/nested/construction_spec.rb +0 -44
  372. data/spec/lib/hamster/set/add_spec.rb +0 -76
  373. data/spec/lib/hamster/set/all_spec.rb +0 -52
  374. data/spec/lib/hamster/set/any_spec.rb +0 -52
  375. data/spec/lib/hamster/set/clear_spec.rb +0 -34
  376. data/spec/lib/hamster/set/delete_spec.rb +0 -72
  377. data/spec/lib/hamster/set/difference_spec.rb +0 -50
  378. data/spec/lib/hamster/set/disjoint_spec.rb +0 -26
  379. data/spec/lib/hamster/set/each_spec.rb +0 -46
  380. data/spec/lib/hamster/set/empty_spec.rb +0 -45
  381. data/spec/lib/hamster/set/exclusion_spec.rb +0 -48
  382. data/spec/lib/hamster/set/first_spec.rb +0 -29
  383. data/spec/lib/hamster/set/flatten_spec.rb +0 -47
  384. data/spec/lib/hamster/set/group_by_spec.rb +0 -60
  385. data/spec/lib/hamster/set/hash_spec.rb +0 -23
  386. data/spec/lib/hamster/set/include_spec.rb +0 -61
  387. data/spec/lib/hamster/set/inspect_spec.rb +0 -48
  388. data/spec/lib/hamster/set/intersect_spec.rb +0 -26
  389. data/spec/lib/hamster/set/intersection_spec.rb +0 -53
  390. data/spec/lib/hamster/set/join_spec.rb +0 -65
  391. data/spec/lib/hamster/set/map_spec.rb +0 -60
  392. data/spec/lib/hamster/set/maximum_spec.rb +0 -37
  393. data/spec/lib/hamster/set/minimum_spec.rb +0 -37
  394. data/spec/lib/hamster/set/new_spec.rb +0 -54
  395. data/spec/lib/hamster/set/partition_spec.rb +0 -53
  396. data/spec/lib/hamster/set/reduce_spec.rb +0 -56
  397. data/spec/lib/hamster/set/reject_spec.rb +0 -51
  398. data/spec/lib/hamster/set/sample_spec.rb +0 -14
  399. data/spec/lib/hamster/set/select_spec.rb +0 -74
  400. data/spec/lib/hamster/set/subset_spec.rb +0 -52
  401. data/spec/lib/hamster/set/sum_spec.rb +0 -24
  402. data/spec/lib/hamster/set/superset_spec.rb +0 -52
  403. data/spec/lib/hamster/set/to_a_spec.rb +0 -31
  404. data/spec/lib/hamster/set/to_list_spec.rb +0 -37
  405. data/spec/lib/hamster/set/union_spec.rb +0 -64
  406. data/spec/lib/hamster/sorted_set/above_spec.rb +0 -52
  407. data/spec/lib/hamster/sorted_set/add_spec.rb +0 -63
  408. data/spec/lib/hamster/sorted_set/at_spec.rb +0 -25
  409. data/spec/lib/hamster/sorted_set/below_spec.rb +0 -52
  410. data/spec/lib/hamster/sorted_set/between_spec.rb +0 -52
  411. data/spec/lib/hamster/sorted_set/clear_spec.rb +0 -44
  412. data/spec/lib/hamster/sorted_set/construction_spec.rb +0 -29
  413. data/spec/lib/hamster/sorted_set/delete_at_spec.rb +0 -19
  414. data/spec/lib/hamster/sorted_set/delete_spec.rb +0 -90
  415. data/spec/lib/hamster/sorted_set/disjoint_spec.rb +0 -26
  416. data/spec/lib/hamster/sorted_set/drop_spec.rb +0 -56
  417. data/spec/lib/hamster/sorted_set/drop_while_spec.rb +0 -35
  418. data/spec/lib/hamster/sorted_set/each_spec.rb +0 -29
  419. data/spec/lib/hamster/sorted_set/empty_spec.rb +0 -35
  420. data/spec/lib/hamster/sorted_set/eql_spec.rb +0 -121
  421. data/spec/lib/hamster/sorted_set/fetch_spec.rb +0 -65
  422. data/spec/lib/hamster/sorted_set/find_index_spec.rb +0 -41
  423. data/spec/lib/hamster/sorted_set/first_spec.rb +0 -19
  424. data/spec/lib/hamster/sorted_set/from_spec.rb +0 -52
  425. data/spec/lib/hamster/sorted_set/group_by_spec.rb +0 -58
  426. data/spec/lib/hamster/sorted_set/include_spec.rb +0 -24
  427. data/spec/lib/hamster/sorted_set/inspect_spec.rb +0 -38
  428. data/spec/lib/hamster/sorted_set/intersect_spec.rb +0 -26
  429. data/spec/lib/hamster/sorted_set/intersection_spec.rb +0 -29
  430. data/spec/lib/hamster/sorted_set/last_spec.rb +0 -37
  431. data/spec/lib/hamster/sorted_set/map_spec.rb +0 -36
  432. data/spec/lib/hamster/sorted_set/marshal_spec.rb +0 -37
  433. data/spec/lib/hamster/sorted_set/maximum_spec.rb +0 -37
  434. data/spec/lib/hamster/sorted_set/minimum_spec.rb +0 -20
  435. data/spec/lib/hamster/sorted_set/new_spec.rb +0 -52
  436. data/spec/lib/hamster/sorted_set/reverse_each_spec.rb +0 -29
  437. data/spec/lib/hamster/sorted_set/sample_spec.rb +0 -14
  438. data/spec/lib/hamster/sorted_set/select_spec.rb +0 -62
  439. data/spec/lib/hamster/sorted_set/size_spec.rb +0 -18
  440. data/spec/lib/hamster/sorted_set/slice_spec.rb +0 -257
  441. data/spec/lib/hamster/sorted_set/sorting_spec.rb +0 -45
  442. data/spec/lib/hamster/sorted_set/subset_spec.rb +0 -48
  443. data/spec/lib/hamster/sorted_set/superset_spec.rb +0 -48
  444. data/spec/lib/hamster/sorted_set/take_spec.rb +0 -55
  445. data/spec/lib/hamster/sorted_set/take_while_spec.rb +0 -34
  446. data/spec/lib/hamster/sorted_set/to_set_spec.rb +0 -19
  447. data/spec/lib/hamster/sorted_set/union_spec.rb +0 -28
  448. data/spec/lib/hamster/sorted_set/up_to_spec.rb +0 -52
  449. data/spec/lib/hamster/sorted_set/values_at_spec.rb +0 -34
  450. data/spec/lib/hamster/vector/add_spec.rb +0 -68
  451. data/spec/lib/hamster/vector/assoc_spec.rb +0 -36
  452. data/spec/lib/hamster/vector/bsearch_spec.rb +0 -58
  453. data/spec/lib/hamster/vector/clear_spec.rb +0 -34
  454. data/spec/lib/hamster/vector/combination_spec.rb +0 -82
  455. data/spec/lib/hamster/vector/compact_spec.rb +0 -30
  456. data/spec/lib/hamster/vector/compare_spec.rb +0 -32
  457. data/spec/lib/hamster/vector/concat_spec.rb +0 -35
  458. data/spec/lib/hamster/vector/count_spec.rb +0 -18
  459. data/spec/lib/hamster/vector/delete_at_spec.rb +0 -54
  460. data/spec/lib/hamster/vector/delete_spec.rb +0 -31
  461. data/spec/lib/hamster/vector/drop_spec.rb +0 -42
  462. data/spec/lib/hamster/vector/drop_while_spec.rb +0 -55
  463. data/spec/lib/hamster/vector/each_index_spec.rb +0 -41
  464. data/spec/lib/hamster/vector/each_spec.rb +0 -45
  465. data/spec/lib/hamster/vector/each_with_index_spec.rb +0 -40
  466. data/spec/lib/hamster/vector/empty_spec.rb +0 -42
  467. data/spec/lib/hamster/vector/eql_spec.rb +0 -77
  468. data/spec/lib/hamster/vector/fetch_spec.rb +0 -65
  469. data/spec/lib/hamster/vector/fill_spec.rb +0 -89
  470. data/spec/lib/hamster/vector/first_spec.rb +0 -19
  471. data/spec/lib/hamster/vector/flat_map_spec.rb +0 -51
  472. data/spec/lib/hamster/vector/flatten_spec.rb +0 -44
  473. data/spec/lib/hamster/vector/get_spec.rb +0 -75
  474. data/spec/lib/hamster/vector/group_by_spec.rb +0 -58
  475. data/spec/lib/hamster/vector/insert_spec.rb +0 -69
  476. data/spec/lib/hamster/vector/inspect_spec.rb +0 -50
  477. data/spec/lib/hamster/vector/map_spec.rb +0 -52
  478. data/spec/lib/hamster/vector/marshal_spec.rb +0 -32
  479. data/spec/lib/hamster/vector/maximum_spec.rb +0 -34
  480. data/spec/lib/hamster/vector/minimum_spec.rb +0 -34
  481. data/spec/lib/hamster/vector/multiply_spec.rb +0 -48
  482. data/spec/lib/hamster/vector/new_spec.rb +0 -51
  483. data/spec/lib/hamster/vector/partition_spec.rb +0 -53
  484. data/spec/lib/hamster/vector/permutation_spec.rb +0 -92
  485. data/spec/lib/hamster/vector/pop_spec.rb +0 -27
  486. data/spec/lib/hamster/vector/product_spec.rb +0 -71
  487. data/spec/lib/hamster/vector/reject_spec.rb +0 -44
  488. data/spec/lib/hamster/vector/repeated_combination_spec.rb +0 -78
  489. data/spec/lib/hamster/vector/repeated_permutation_spec.rb +0 -94
  490. data/spec/lib/hamster/vector/reverse_each_spec.rb +0 -32
  491. data/spec/lib/hamster/vector/reverse_spec.rb +0 -22
  492. data/spec/lib/hamster/vector/rindex_spec.rb +0 -37
  493. data/spec/lib/hamster/vector/rotate_spec.rb +0 -74
  494. data/spec/lib/hamster/vector/sample_spec.rb +0 -14
  495. data/spec/lib/hamster/vector/select_spec.rb +0 -64
  496. data/spec/lib/hamster/vector/set_spec.rb +0 -175
  497. data/spec/lib/hamster/vector/shift_spec.rb +0 -28
  498. data/spec/lib/hamster/vector/shuffle_spec.rb +0 -44
  499. data/spec/lib/hamster/vector/slice_spec.rb +0 -241
  500. data/spec/lib/hamster/vector/sorting_spec.rb +0 -57
  501. data/spec/lib/hamster/vector/take_spec.rb +0 -43
  502. data/spec/lib/hamster/vector/take_while_spec.rb +0 -35
  503. data/spec/lib/hamster/vector/to_set_spec.rb +0 -23
  504. data/spec/lib/hamster/vector/transpose_spec.rb +0 -49
  505. data/spec/lib/hamster/vector/uniq_spec.rb +0 -56
  506. data/spec/lib/hamster/vector/unshift_spec.rb +0 -29
  507. data/spec/lib/hamster/vector/update_in_spec.rb +0 -83
  508. data/spec/lib/hamster/vector/values_at_spec.rb +0 -34
  509. data/spec/lib/hamster/vector/zip_spec.rb +0 -58
@@ -1,3 +1,4 @@
1
+ require "forwardable"
1
2
  require "hamster/hash"
2
3
  require "hamster/read_copy_update"
3
4
 
@@ -7,6 +8,7 @@ module Hamster
7
8
  end
8
9
 
9
10
  class MutableHash
11
+ extend Forwardable
10
12
  include ReadCopyUpdate
11
13
 
12
14
  def put(key, value = Undefined, &block)
@@ -17,7 +19,7 @@ module Hamster
17
19
  put(key, value)
18
20
  value
19
21
  end
20
- alias :[]= :store
22
+ def_delegator :self, :store, :[]=
21
23
 
22
24
  def delete(key)
23
25
  old_value = nil
@@ -0,0 +1,87 @@
1
+ require "forwardable"
2
+ require "hamster/immutable"
3
+ require "hamster/list"
4
+
5
+ module Hamster
6
+ def self.queue(*items)
7
+ items.reduce(EmptyQueue) { |queue, item| queue.enqueue(item) }
8
+ end
9
+
10
+ class Queue
11
+ extend Forwardable
12
+ include Immutable
13
+
14
+ def initialize
15
+ @front = @rear = EmptyList
16
+ end
17
+
18
+ def empty?
19
+ @front.empty? && @rear.empty?
20
+ end
21
+ def_delegator :self, :empty?, :null?
22
+
23
+ def size
24
+ @front.size + @rear.size
25
+ end
26
+ def_delegator :self, :size, :length
27
+
28
+ def head
29
+ return @front.head unless @front.empty?
30
+ @rear.last
31
+ end
32
+ def_delegator :self, :head, :first
33
+ def_delegator :self, :head, :peek
34
+ def_delegator :self, :head, :front
35
+
36
+ def enqueue(item)
37
+ transform { @rear = @rear.cons(item) }
38
+ end
39
+ def_delegator :self, :enqueue, :<<
40
+ def_delegator :self, :enqueue, :add
41
+
42
+ def dequeue
43
+ front = @front
44
+ rear = @rear
45
+ if front.empty?
46
+ return EmptyQueue if rear.empty?
47
+ front = rear.reverse
48
+ rear = EmptyList
49
+ end
50
+
51
+ transform do
52
+ @front = front.tail
53
+ @rear = rear
54
+ end
55
+ end
56
+ def_delegator :self, :dequeue, :tail
57
+
58
+ def clear
59
+ EmptyQueue
60
+ end
61
+
62
+ def eql?(other)
63
+ instance_of?(other.class) &&
64
+ to_list.eql?(other.to_list)
65
+ end
66
+ def_delegator :self, :eql?, :==
67
+
68
+ def to_a
69
+ to_list.to_a
70
+ end
71
+ def_delegator :self, :to_a, :entries
72
+
73
+ def to_ary
74
+ to_list.to_ary
75
+ end
76
+
77
+ def to_list
78
+ @front.append(@rear.reverse)
79
+ end
80
+
81
+ def inspect
82
+ to_list.inspect
83
+ end
84
+ end
85
+
86
+ EmptyQueue = Hamster::Queue.new
87
+ end
@@ -2,7 +2,6 @@ require "forwardable"
2
2
  require "thread"
3
3
 
4
4
  module Hamster
5
- # @private
6
5
  module ReadCopyUpdate
7
6
  extend Forwardable
8
7
 
@@ -14,7 +13,7 @@ module Hamster
14
13
  def eql?(other)
15
14
  instance_of?(other.class) && @content.eql?(other.instance_variable_get(:@content))
16
15
  end
17
- alias :== :eql?
16
+ def_delegator :self, :eql?, :==
18
17
 
19
18
  def_delegator :@content, :inspect
20
19
  def_delegator :@content, :to_s
@@ -1,572 +1,167 @@
1
+ require "forwardable"
1
2
  require "hamster/immutable"
2
3
  require "hamster/undefined"
3
4
  require "hamster/enumerable"
4
- require "hamster/hash"
5
+ require "hamster/sorter"
5
6
  require "hamster/trie"
6
- require "hamster/sorted_set"
7
- require "set"
7
+ require "hamster/list"
8
8
 
9
9
  module Hamster
10
10
  def self.set(*items)
11
- items.empty? ? EmptySet : Set.new(items)
11
+ items.reduce(EmptySet) { |set, item| set.add(item) }
12
12
  end
13
13
 
14
- # `Hamster::Set` is a collection of unordered values with no duplicates. Testing whether
15
- # an object is present in the `Set` is fast. `Set` is also `Enumerable`, so you can
16
- # iterate over the members of the set with {#each}, transform them with {#map}, filter
17
- # them with {#select}, and so on. Some of the `Enumerable` methods are overridden to
18
- # return Hamster collections.
19
- #
20
- # Like the `Set` class in Ruby's standard library, which we will call RubySet,
21
- # `Hamster::Set` defines equivalency of objects using `#hash` and `#eql?`. No two
22
- # objects with the same `#hash` code, and which are also `#eql?`, can coexist in the
23
- # same `Set`. If one is already in the `Set`, attempts to add another one will have
24
- # no effect.
25
- #
26
- # `Set`s have no natural ordering and cannot be compared using `#<=>`. However, they
27
- # define {#<}, {#>}, {#<=}, and {#>=} as shorthand for {#proper_subset?},
28
- # {#proper_superset?}, {#subset?}, and {#superset?} (respectively).
29
- #
30
- # The basic set-theoretic operations {#union}, {#intersection}, {#difference}, and
31
- # {#exclusion} work with any `Enumerable` object. They may be more efficient when used
32
- # with another `Hamster::Set`, or a RubySet.
33
- #
34
- # A `Set` can be created in any of the following ways:
35
- #
36
- # Hamster.set('Tom', 'Dick', 'Harry')
37
- # Hamster::Set.new([1, 2, 3]) # any Enumerable can be used to initialize
38
- # Hamster::Set['A', 'B', 'C', 'D']
39
- #
40
- # The latter 2 forms of initialization can be used with your own, custom subclasses
41
- # of `Hamster::Set`.
42
- #
43
- # Unlike RubySet, all methods which you might expect to "modify" a `Hamster::Set`
44
- # actually return a new set and leave the existing one unchanged.
45
- #
46
- # @example
47
- # require 'hamster/set'
48
- # set1 = Hamster.set(1, 2) # => Hamster::Set[1, 2]
49
- # set2 = Hamster::Set[1, 2] # => Hamster::Set[1, 2]
50
- # set1 == set2 # => true
51
- # set3 = set1.add("foo") # => Hamster::Set[1, 2, "foo"]
52
- # set3 - set2 # => Hamster::Set["foo"]
53
- # set3.subset?(set1) # => false
54
- # set1.subset?(set3) # => true
55
- #
56
14
  class Set
15
+ extend Forwardable
57
16
  include Immutable
58
17
  include Enumerable
59
18
 
60
- class << self
61
- # Create a new `Set` populated with the given items.
62
- # @return [Set]
63
- def [](*items)
64
- new(items)
65
- end
66
-
67
- # Return an empty `Set`. If used on a subclass, returns an empty instance
68
- # of that class.
69
- #
70
- # @return [Set]
71
- def empty
72
- @empty ||= self.new
73
- end
74
-
75
- # "Raw" allocation of a new `Set`. Used internally to create a new
76
- # instance quickly after obtaining a modified {Trie}.
77
- #
78
- # @return [Set]
79
- # @private
80
- def alloc(trie = EmptyTrie)
81
- allocate.tap { |s| s.instance_variable_set(:@trie, trie) }
82
- end
83
- end
84
-
85
- def initialize(items=[])
86
- @trie = Trie.new(0)
87
- items.each { |item| @trie.put!(item, nil) }
19
+ def initialize(trie = EmptyTrie)
20
+ @trie = trie
88
21
  end
89
22
 
90
- # Return `true` if this `Set` contains no items.
91
- # @return [Boolean]
92
23
  def empty?
93
24
  @trie.empty?
94
25
  end
26
+ def_delegator :self, :empty?, :null?
95
27
 
96
- # Return the number of items in this `Set`.
97
- # @return [Integer]
98
28
  def size
99
29
  @trie.size
100
30
  end
101
- alias :length :size
31
+ def_delegator :self, :size, :length
102
32
 
103
- # Return a new `Set` with `item` added. If `item` is already in the set,
104
- # return `self`.
105
- #
106
- # @example
107
- # Hamster::Set[1, 2, 3].add(4) # => Hamster::Set[1, 2, 4, 3]
108
- # Hamster::Set[1, 2, 3].add(2) # => Hamster::Set[1, 2, 3]
109
- #
110
- # @param item [Object] The object to add
111
- # @return [Set]
112
33
  def add(item)
113
- include?(item) ? self : self.class.alloc(@trie.put(item, nil))
114
- end
115
- alias :<< :add
116
-
117
- # If `item` is not a member of this `Set`, return a new `Set` with `item` added.
118
- # Otherwise, return `false`.
119
- #
120
- # @example
121
- # Hamster::Set[1, 2, 3].add?(4) # => Hamster::Set[1, 2, 4, 3]
122
- # Hamster::Set[1, 2, 3].add?(2) # => false
123
- #
124
- # @param item [Object] The object to add
125
- # @return [Set, false]
126
- def add?(item)
127
- !include?(item) && add(item)
34
+ transform_unless(include?(item)) { @trie = @trie.put(item, nil) }
128
35
  end
36
+ def_delegator :self, :add, :<<
129
37
 
130
- # Return a new `Set` with `item` removed. If `item` is not a member of the set,
131
- # return `self`.
132
- #
133
- # @example
134
- # Hamster::Set[1, 2, 3].delete(1) # => Hamster::Set[2, 3]
135
- # Hamster::Set[1, 2, 3].delete(99) # => Hamster::Set[1, 2, 3]
136
- #
137
- # @param item [Object] The object to remove
138
- # @return [Set]
139
38
  def delete(item)
140
39
  trie = @trie.delete(item)
141
- new_trie(trie)
40
+ transform_unless(trie.equal?(@trie)) { @trie = trie }
142
41
  end
143
42
 
144
- # If `item` is a member of this `Set`, return a new `Set` with `item` removed.
145
- # Otherwise, return `false`.
146
- #
147
- # @example
148
- # Hamster::Set[1, 2, 3].delete?(1) # => Hamster::Set[2, 3]
149
- # Hamster::Set[1, 2, 3].delete?(99) # => false
150
- #
151
- # @param item [Object] The object to remove
152
- # @return [Set, false]
153
- def delete?(item)
154
- include?(item) && delete(item)
155
- end
156
-
157
- # Call the block once for each item in this `Set`. No specific iteration order
158
- # is guaranteed (but the order will be stable for any particular `Set`.)
159
- #
160
- # @example
161
- # Hamster::Set["Dog", "Elephant", "Lion"].each { |e| puts e }
162
- # Elephant
163
- # Dog
164
- # Lion
165
- # # => Hamster::Set["Dog", "Elephant", "Lion"]
166
- #
167
- # @return [self]
168
43
  def each
169
- return to_enum if not block_given?
170
- @trie.each { |key, _| yield(key) }
171
- self
44
+ return self unless block_given?
45
+ @trie.each { |entry| yield(entry.key) }
172
46
  end
173
47
 
174
- # Call the block once for each item in this `Set`. Iteration order will be
175
- # the opposite of {#each}.
176
- #
177
- # @example
178
- # Hamster::Set["Dog", "Elephant", "Lion"].reverse_each { |e| puts e }
179
- # Lion
180
- # Dog
181
- # Elephant
182
- # # => Hamster::Set["Dog", "Elephant", "Lion"]
183
- #
184
- # @return [self]
185
- def reverse_each
186
- return enum_for(:reverse_each) if not block_given?
187
- @trie.reverse_each { |key, _| yield(key) }
188
- self
189
- end
190
-
191
- # Return a new `Set` with all the items for which the block returns true.
192
- #
193
- # @example
194
- # Hamster::Set["Elephant", "Dog", "Lion"].select { |e| e.size >= 4 }
195
- # # => Hamster::Set["Elephant", "Lion"]
196
- #
197
- # @return [Set]
198
- def select
199
- return enum_for(:select) unless block_given?
200
- trie = @trie.select { |key, _| yield(key) }
201
- new_trie(trie)
202
- end
203
- alias :find_all :select
204
- alias :keep_if :select
205
-
206
- # Call the block once for each item in this `Set`.
207
- # All the values returned from the block will be gathered into a new `Set`.
208
- #
209
- # @example
210
- # Hamster::Set["Cat", "Elephant", "Dog", "Lion"].map { |e| e.size }
211
- # # => Hamster::Set[8, 4, 3]
212
- #
213
- # @return [Set]
214
48
  def map
215
- return enum_for(:map) if not block_given?
49
+ return self unless block_given?
216
50
  return self if empty?
217
- self.class.new(super)
51
+ transform { @trie = @trie.reduce(EmptyTrie) { |trie, entry| trie.put(yield(entry.key), nil) } }
52
+ end
53
+ def_delegator :self, :map, :collect
54
+
55
+ def filter
56
+ return self unless block_given?
57
+ trie = @trie.filter { |entry| yield(entry.key) }
58
+ return EmptySet if trie.empty?
59
+ transform_unless(trie.equal?(@trie)) { @trie = trie }
218
60
  end
219
- alias :collect :map
220
61
 
221
- # Return `true` if the given item is present in this `Set`. More precisely,
222
- # return `true` if an object with the same `#hash` code, and which is also `#eql?`
223
- # to the given object is present.
224
- #
225
- # @example
226
- # Hamster::Set["A", "B", "C"].include?("B") # => true
227
- # Hamster::Set["A", "B", "C"].include?("Z") # => false
228
- #
229
- # @param object [Object] The object to check for
230
- # @return [Boolean]
231
62
  def include?(object)
232
- @trie.key?(object)
63
+ any? { |item| item.eql?(object) }
233
64
  end
234
- alias :member? :include?
235
65
 
236
- # Return a member of this `Set`. The member chosen will be the first one which
237
- # would be yielded by {#each}. If the set is empty, return `nil`.
238
- #
239
- # @example
240
- # Hamster::Set["A", "B", "C"].first # => "C"
241
- #
242
- # @return [Object]
243
- def first
244
- (entry = @trie.at(0)) && entry[0]
66
+ def head
67
+ find { true }
245
68
  end
69
+ def_delegator :self, :head, :first
246
70
 
247
- # Return a {SortedSet} which contains the same items as this `Set`, ordered by
248
- # the given comparator block. The comparator block should take 2 parameters and
249
- # return 0, 1, or -1 depending on whether the first parameter is equal, greater than,
250
- # or less than the second.
251
- #
252
- # @example
253
- # Hamster::Set["Elephant", "Dog", "Lion"].sort
254
- # # => Hamster::SortedSet["Dog", "Elephant", "Lion"]
255
- # Hamster::Set["Elephant", "Dog", "Lion"].sort { |a,b| a.size <=> b.size }
256
- # # => Hamster::SortedSet["Dog", "Lion", "Elephant"]
257
- #
258
- # @yield [a, b] A pair of items to be compared
259
- # @yieldreturn [Integer]
260
- # @return [SortedSet]
261
71
  def sort(&comparator)
262
- SortedSet.new(self.to_a, &comparator)
72
+ Stream.new { Sorter.new(self).sort(&comparator) }
263
73
  end
264
74
 
265
- # Return a {SortedSet} which contains the same items as this `Set`, ordered by
266
- # mapping each item through the provided block to obtain sort keys, and then
267
- # sorting the keys.
268
- #
269
- # @example
270
- # Hamster::Set["Elephant", "Dog", "Lion"].sort_by { |e| e.size }
271
- # # => Hamster::SortedSet["Dog", "Lion", "Elephant"]
272
- #
273
- # @yield [item] The item to obtain a sort key for
274
- # @yieldreturn [Object]
275
- # @return [SortedSet]
276
- def sort_by(&mapper)
277
- SortedSet.new(self.to_a, &mapper)
75
+ def sort_by(&transformer)
76
+ return sort unless block_given?
77
+ Stream.new { Sorter.new(self).sort_by(&transformer) }
78
+ end
79
+
80
+ def join(sep = nil)
81
+ to_a.join(sep)
278
82
  end
279
83
 
280
- # Return a new `Set` which contains all the members of both this `Set` and `other`.
281
- # `other` can be any `Enumerable` object.
282
- #
283
- # @example
284
- # Hamster::Set[1, 2] | Hamster::Set[2, 3] # => Hamster::Set[1, 2, 3]
285
- #
286
- # @param other [Enumerable] The collection to merge with
287
- # @return [Set]
288
84
  def union(other)
289
- if other.is_a?(Hamster::Set)
290
- if other.size > size
291
- small_set_pairs = @trie
292
- large_set_trie = other.instance_variable_get(:@trie)
293
- else
294
- small_set_pairs = other.instance_variable_get(:@trie)
295
- large_set_trie = @trie
296
- end
297
- else
298
- if other.respond_to?(:lazy)
299
- small_set_pairs = other.lazy.map { |e| [e, nil] }
300
- else
301
- small_set_pairs = other.map { |e| [e, nil] }
302
- end
303
- large_set_trie = @trie
85
+ trie = other.reduce(@trie) do |a, element|
86
+ next a if a.key?(element)
87
+ a.put(element, nil)
304
88
  end
305
-
306
- trie = large_set_trie.bulk_put(small_set_pairs)
307
- new_trie(trie)
89
+ transform_unless(trie.equal?(@trie)) { @trie = trie }
308
90
  end
309
- alias :| :union
310
- alias :+ :union
311
- alias :merge :union
91
+ def_delegator :self, :union, :|
92
+ def_delegator :self, :union, :+
93
+ def_delegator :self, :union, :merge
312
94
 
313
- # Return a new `Set` which contains all the items which are members of both
314
- # this `Set` and `other`. `other` can be any `Enumerable` object.
315
- #
316
- # @example
317
- # Hamster::Set[1, 2] & Hamster::Set[2, 3] # => Hamster::Set[2]
318
- #
319
- # @param other [Enumerable] The collection to intersect with
320
- # @return [Set]
321
95
  def intersection(other)
322
- if other.size < @trie.size
323
- if other.is_a?(Hamster::Set)
324
- trie = other.instance_variable_get(:@trie).select { |key, _| include?(key) }
325
- else
326
- trie = Trie.new(0)
327
- other.each { |obj| trie.put!(obj, nil) if include?(obj) }
328
- end
329
- else
330
- trie = @trie.select { |key, _| other.include?(key) }
331
- end
332
- new_trie(trie)
96
+ trie = @trie.filter { |entry| other.include?(entry.key) }
97
+ transform_unless(trie.equal?(@trie)) { @trie = trie }
333
98
  end
334
- alias :& :intersection
99
+ def_delegator :self, :intersection, :intersect
100
+ def_delegator :self, :intersection, :&
335
101
 
336
- # Return a new `Set` with all the items in `other` removed. `other` can be
337
- # any `Enumerable` object.
338
- #
339
- # @example
340
- # Hamster::Set[1, 2] - Hamster::Set[2, 3] # => Hamster::Set[1]
341
- #
342
- # @param other [Enumerable] The collection to subtract from this set
343
- # @return [Set]
344
102
  def difference(other)
345
- trie = if (@trie.size <= other.size) && (other.is_a?(Hamster::Set) || (defined?(::Set) && other.is_a?(::Set)))
346
- @trie.select { |key, _| !other.include?(key) }
347
- else
348
- @trie.bulk_delete(other)
349
- end
350
- new_trie(trie)
103
+ trie = @trie.filter { |entry| !other.include?(entry.key) }
104
+ transform_unless(trie.equal?(@trie)) { @trie = trie }
351
105
  end
352
- alias :subtract :difference
353
- alias :- :difference
106
+ def_delegator :self, :difference, :diff
107
+ def_delegator :self, :difference, :subtract
108
+ def_delegator :self, :difference, :-
354
109
 
355
- # Return a new `Set` which contains all the items which are members of this
356
- # `Set` or of `other`, but not both. `other` can be any `Enumerable` object.
357
- #
358
- # @example
359
- # Hamster::Set[1, 2] ^ Hamster::Set[2, 3] # => Hamster::Set[1, 3]
360
- #
361
- # @param other [Enumerable] The collection to take the exclusive disjunction of
362
- # @return [Set]
363
110
  def exclusion(other)
364
111
  ((self | other) - (self & other))
365
112
  end
366
- alias :^ :exclusion
113
+ def_delegator :self, :exclusion, :^
367
114
 
368
- # Return `true` if all items in this `Set` are also in `other`.
369
- #
370
- # @example
371
- # Hamster::Set[2, 3].subset?(Hamster::Set[1, 2, 3]) # => true
372
- #
373
- # @param other [Set]
374
- # @return [Boolean]
375
115
  def subset?(other)
376
- return false if other.size < size
377
-
378
- # This method has the potential to be very slow if 'other' is a large Array, so to avoid that,
379
- # we convert those Arrays to Sets before checking presence of items
380
- # Time to convert Array -> Set is linear in array.size
381
- # Time to check for presence of all items in an Array is proportional to set.size * array.size
382
- # Note that both sides of that equation have array.size -- hence those terms cancel out,
383
- # and the break-even point is solely dependent on the size of this collection
384
- # After doing some benchmarking to estimate the constants, it appears break-even is at ~190 items
385
- # We also check other.size, to avoid the more expensive #is_a? checks in cases where it doesn't matter
386
- #
387
- if other.size >= 150 && @trie.size >= 190 && !(other.is_a?(Hamster::Set) || other.is_a?(::Set))
388
- other = ::Set.new(other)
389
- end
390
116
  all? { |item| other.include?(item) }
391
117
  end
392
- alias :<= :subset?
393
118
 
394
- # Return `true` if all items in `other` are also in this `Set`.
395
- #
396
- # @example
397
- # Hamster::Set[1, 2, 3].superset?(Hamster::Set[2, 3]) # => true
398
- #
399
- # @param other [Set]
400
- # @return [Boolean]
401
119
  def superset?(other)
402
120
  other.subset?(self)
403
121
  end
404
- alias :>= :superset?
405
-
406
- # Returns `true` if `other` contains all the items in this `Set`, plus at least
407
- # one item which is not in this set.
408
- #
409
- # @example
410
- # Hamster::Set[2, 3].proper_subset?(Hamster::Set[1, 2, 3]) # => true
411
- # Hamster::Set[1, 2, 3].proper_subset?(Hamster::Set[1, 2, 3]) # => false
412
- #
413
- # @param other [Set]
414
- # @return [Boolean]
415
- def proper_subset?(other)
416
- return false if other.size <= size
417
- # See comments above
418
- if other.size >= 150 && @trie.size >= 190 && !(other.is_a?(Hamster::Set) || other.is_a?(::Set))
419
- other = ::Set.new(other)
420
- end
421
- all? { |item| other.include?(item) }
422
- end
423
- alias :< :proper_subset?
424
-
425
- # Returns `true` if this `Set` contains all the items in `other`, plus at least
426
- # one item which is not in `other`.
427
- #
428
- # @example
429
- # Hamster::Set[1, 2, 3].proper_superset?(Hamster::Set[2, 3]) # => true
430
- # Hamster::Set[1, 2, 3].proper_superset?(Hamster::Set[1, 2, 3]) # => false
431
- #
432
- # @param other [Set]
433
- # @return [Boolean]
434
- def proper_superset?(other)
435
- other.proper_subset?(self)
436
- end
437
- alias :> :proper_superset?
438
-
439
- # Return `true` if this `Set` and `other` do not share any items.
440
- #
441
- # @example
442
- # Hamster::Set[1, 2].disjoint?(Hamster::Set[8, 9]) # => true
443
- #
444
- # @param other [Set]
445
- # @return [Boolean]
446
- def disjoint?(other)
447
- if other.size <= size
448
- other.each { |item| return false if include?(item) }
449
- else
450
- # See comment on #subset?
451
- if other.size >= 150 && @trie.size >= 190 && !(other.is_a?(Hamster::Set) || other.is_a?(::Set))
452
- other = ::Set.new(other)
453
- end
454
- each { |item| return false if other.include?(item) }
455
- end
456
- true
457
- end
458
-
459
- # Return `true` if this `Set` and `other` have at least one item in common.
460
- #
461
- # @example
462
- # Hamster::Set[1, 2].intersect?(Hamster::Set[2, 3]) # => true
463
- #
464
- # @param other [Set]
465
- # @return [Boolean]
466
- def intersect?(other)
467
- !disjoint?(other)
468
- end
469
122
 
470
- # Recursively insert the contents of any nested `Set`s into this `Set`, and
471
- # remove them.
472
- #
473
- # @example
474
- # Hamster::Set[Hamster::Set[1, 2], Hamster::Set[3, 4]].flatten
475
- # # => Hamster::Set[1, 2, 3, 4]
476
- #
477
- # @return [Set]
478
123
  def flatten
479
- reduce(self.class.empty) do |set, item|
124
+ reduce(EmptySet) do |set, item|
480
125
  next set.union(item.flatten) if item.is_a?(Set)
481
126
  set.add(item)
482
127
  end
483
128
  end
484
129
 
485
- alias :group :group_by
486
- alias :classify :group_by
487
-
488
- # Return a randomly chosen item from this `Set`. If the set is empty, return `nil`.
489
- #
490
- # @example
491
- # Hamster::Set[1, 2, 3, 4, 5].sample # => 3
492
- #
493
- # @return [Object]
494
- def sample
495
- empty? ? nil : @trie.at(rand(size))[0]
130
+ def group_by(&block)
131
+ return group_by { |item| item } unless block_given?
132
+ reduce(EmptyHash) do |hash, item|
133
+ key = yield(item)
134
+ hash.put(key, (hash.get(key) || EmptySet).add(item))
135
+ end
496
136
  end
137
+ def_delegator :self, :group_by, :group
497
138
 
498
- # Return an empty `Set` instance, of the same class as this one. Useful if you
499
- # have multiple subclasses of `Set` and want to treat them polymorphically.
500
- #
501
- # @return [Hash]
502
139
  def clear
503
- self.class.empty
140
+ EmptySet
504
141
  end
505
142
 
506
- # Return true if `other` has the same type and contents as this `Set`.
507
- #
508
- # @param other [Object] The object to compare with
509
- # @return [Boolean]
510
143
  def eql?(other)
511
- return true if other.equal?(self)
512
- return false if not instance_of?(other.class)
513
- other_trie = other.instance_variable_get(:@trie)
514
- return false if @trie.size != other_trie.size
515
- @trie.each do |key, _|
516
- return false if !other_trie.key?(key)
517
- end
518
- true
144
+ instance_of?(other.class) && @trie.eql?(other.instance_variable_get(:@trie))
519
145
  end
520
- alias :== :eql?
146
+ def_delegator :self, :eql?, :==
521
147
 
522
- # See `Object#hash`.
523
- # @return [Integer]
524
148
  def hash
525
149
  reduce(0) { |hash, item| (hash << 5) - hash + item.hash }
526
150
  end
527
151
 
528
- undef :"<=>" # Sets are not ordered, so Enumerable#<=> will give a meaningless result
529
- undef :each_index # Set members cannot be accessed by 'index', so #each_index is not meaningful
152
+ def_delegator :self, :dup, :uniq
153
+ def_delegator :self, :dup, :nub
154
+ def_delegator :self, :dup, :to_set
155
+ def_delegator :self, :dup, :remove_duplicates
530
156
 
531
- # Return `self`.
532
- #
533
- # @return [self]
534
- def to_set
535
- self
536
- end
537
-
538
- # @private
539
- def marshal_dump
540
- output = {}
541
- each do |key|
542
- output[key] = nil
543
- end
544
- output
157
+ def to_list
158
+ reduce(EmptyList) { |list, item| list.cons(item) }
545
159
  end
546
160
 
547
- # @private
548
- def marshal_load(dictionary)
549
- @trie = dictionary.reduce(EmptyTrie) do |trie, key_value|
550
- trie.put(key_value.first, nil)
551
- end
552
- end
553
-
554
- private
555
-
556
- def new_trie(trie)
557
- if trie.empty?
558
- self.class.empty
559
- elsif trie.equal?(@trie)
560
- self
561
- else
562
- self.class.alloc(trie)
563
- end
161
+ def inspect
162
+ "{#{to_a.inspect[1..-2]}}"
564
163
  end
565
164
  end
566
165
 
567
- # The canonical empty `Set`. Returned by `Hamster.set` and `Set[]` when
568
- # invoked with no arguments; also returned by `Set.empty`. Prefer using this
569
- # one rather than creating many empty sets using `Set.new`.
570
- #
571
- EmptySet = Hamster::Set.empty
166
+ EmptySet = Hamster::Set.new
572
167
  end