hamster 0.4.3 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (757) hide show
  1. checksums.yaml +7 -0
  2. data/lib/hamster.rb +11 -9
  3. data/lib/hamster/core_ext.rb +2 -3
  4. data/lib/hamster/core_ext/enumerable.rb +18 -27
  5. data/lib/hamster/core_ext/io.rb +16 -25
  6. data/lib/hamster/deque.rb +252 -0
  7. data/lib/hamster/enumerable.rb +123 -112
  8. data/lib/hamster/experimental/mutable_queue.rb +5 -14
  9. data/lib/hamster/experimental/mutable_set.rb +7 -14
  10. data/lib/hamster/hash.rb +732 -102
  11. data/lib/hamster/immutable.rb +4 -10
  12. data/lib/hamster/list.rb +1155 -215
  13. data/lib/hamster/{experimental/mutable_hash.rb → mutable_hash.rb} +11 -14
  14. data/lib/hamster/nested.rb +36 -0
  15. data/lib/hamster/{experimental/read_copy_update.rb → read_copy_update.rb} +10 -8
  16. data/lib/hamster/set.rb +488 -90
  17. data/lib/hamster/sorted_set.rb +1397 -0
  18. data/lib/hamster/trie.rb +210 -65
  19. data/lib/hamster/undefined.rb +1 -7
  20. data/lib/hamster/vector.rb +1329 -83
  21. data/lib/hamster/version.rb +1 -3
  22. data/spec/{hamster/core_ext → fixtures}/io_spec.txt +0 -0
  23. data/spec/lib/hamster/core_ext/array_spec.rb +14 -0
  24. data/spec/lib/hamster/core_ext/enumerable_spec.rb +30 -0
  25. data/spec/lib/hamster/core_ext/io_spec.rb +29 -0
  26. data/spec/lib/hamster/deque/clear_spec.rb +34 -0
  27. data/spec/lib/hamster/deque/construction_spec.rb +30 -0
  28. data/spec/lib/hamster/deque/copying_spec.rb +20 -0
  29. data/spec/lib/hamster/deque/dequeue_spec.rb +35 -0
  30. data/spec/lib/hamster/deque/empty_spec.rb +40 -0
  31. data/spec/lib/hamster/deque/enqueue_spec.rb +28 -0
  32. data/spec/lib/hamster/deque/first_spec.rb +18 -0
  33. data/spec/lib/hamster/deque/inspect_spec.rb +24 -0
  34. data/spec/lib/hamster/deque/last_spec.rb +18 -0
  35. data/spec/lib/hamster/deque/marshal_spec.rb +34 -0
  36. data/spec/lib/hamster/deque/new_spec.rb +44 -0
  37. data/spec/lib/hamster/deque/pop_spec.rb +33 -0
  38. data/spec/lib/hamster/deque/pretty_print_spec.rb +24 -0
  39. data/spec/lib/hamster/deque/random_modification_spec.rb +34 -0
  40. data/spec/lib/hamster/deque/size_spec.rb +20 -0
  41. data/spec/lib/hamster/deque/to_a_spec.rb +27 -0
  42. data/spec/lib/hamster/deque/to_ary_spec.rb +36 -0
  43. data/spec/lib/hamster/deque/to_list_spec.rb +26 -0
  44. data/spec/lib/hamster/deque/unshift_spec.rb +26 -0
  45. data/spec/lib/hamster/experimental/mutable_set/add_qm_spec.rb +39 -0
  46. data/spec/lib/hamster/experimental/mutable_set/add_spec.rb +37 -0
  47. data/spec/lib/hamster/experimental/mutable_set/delete_qm_spec.rb +38 -0
  48. data/spec/lib/hamster/experimental/mutable_set/delete_spec.rb +37 -0
  49. data/spec/lib/hamster/hash/all_spec.rb +54 -0
  50. data/spec/lib/hamster/hash/any_spec.rb +54 -0
  51. data/spec/lib/hamster/hash/assoc_spec.rb +52 -0
  52. data/spec/lib/hamster/hash/clear_spec.rb +43 -0
  53. data/spec/lib/hamster/hash/construction_spec.rb +39 -0
  54. data/spec/lib/hamster/hash/copying_spec.rb +14 -0
  55. data/spec/lib/hamster/hash/default_proc_spec.rb +73 -0
  56. data/spec/lib/hamster/hash/delete_spec.rb +40 -0
  57. data/spec/lib/hamster/hash/each_spec.rb +78 -0
  58. data/spec/lib/hamster/hash/each_with_index_spec.rb +30 -0
  59. data/spec/lib/hamster/hash/empty_spec.rb +44 -0
  60. data/spec/lib/hamster/hash/eql_spec.rb +70 -0
  61. data/spec/lib/hamster/hash/except_spec.rb +43 -0
  62. data/spec/lib/hamster/hash/fetch_spec.rb +58 -0
  63. data/spec/lib/hamster/hash/find_spec.rb +44 -0
  64. data/spec/lib/hamster/hash/flat_map_spec.rb +36 -0
  65. data/spec/lib/hamster/hash/flatten_spec.rb +99 -0
  66. data/spec/lib/hamster/hash/get_spec.rb +80 -0
  67. data/spec/lib/hamster/hash/has_key_spec.rb +32 -0
  68. data/spec/lib/hamster/hash/has_value_spec.rb +28 -0
  69. data/spec/lib/hamster/hash/hash_spec.rb +30 -0
  70. data/spec/{hamster → lib/hamster}/hash/immutable_spec.rb +3 -6
  71. data/spec/lib/hamster/hash/inspect_spec.rb +31 -0
  72. data/spec/lib/hamster/hash/invert_spec.rb +31 -0
  73. data/spec/lib/hamster/hash/key_spec.rb +28 -0
  74. data/spec/lib/hamster/hash/keys_spec.rb +17 -0
  75. data/spec/lib/hamster/hash/map_spec.rb +46 -0
  76. data/spec/lib/hamster/hash/marshal_spec.rb +29 -0
  77. data/spec/lib/hamster/hash/merge_spec.rb +83 -0
  78. data/spec/lib/hamster/hash/min_max_spec.rb +46 -0
  79. data/spec/lib/hamster/hash/new_spec.rb +71 -0
  80. data/spec/lib/hamster/hash/none_spec.rb +49 -0
  81. data/spec/lib/hamster/hash/partition_spec.rb +36 -0
  82. data/spec/lib/hamster/hash/pretty_print_spec.rb +35 -0
  83. data/spec/lib/hamster/hash/put_spec.rb +103 -0
  84. data/spec/lib/hamster/hash/reduce_spec.rb +36 -0
  85. data/spec/lib/hamster/hash/reject_spec.rb +62 -0
  86. data/spec/lib/hamster/hash/reverse_each_spec.rb +28 -0
  87. data/spec/lib/hamster/hash/sample_spec.rb +14 -0
  88. data/spec/lib/hamster/hash/select_spec.rb +58 -0
  89. data/spec/{hamster → lib/hamster}/hash/size_spec.rb +9 -18
  90. data/spec/lib/hamster/hash/slice_spec.rb +45 -0
  91. data/spec/lib/hamster/hash/sort_spec.rb +27 -0
  92. data/spec/lib/hamster/hash/store_spec.rb +76 -0
  93. data/spec/lib/hamster/hash/take_spec.rb +36 -0
  94. data/spec/lib/hamster/hash/to_a_spec.rb +14 -0
  95. data/spec/lib/hamster/hash/to_hash_spec.rb +22 -0
  96. data/spec/lib/hamster/hash/update_in_spec.rb +80 -0
  97. data/spec/lib/hamster/hash/values_at_spec.rb +14 -0
  98. data/spec/lib/hamster/hash/values_spec.rb +25 -0
  99. data/spec/{hamster → lib/hamster}/immutable/copying_spec.rb +3 -10
  100. data/spec/{hamster → lib/hamster}/immutable/immutable_spec.rb +3 -16
  101. data/spec/lib/hamster/immutable/memoize_spec.rb +56 -0
  102. data/spec/lib/hamster/immutable/new_spec.rb +14 -0
  103. data/spec/lib/hamster/immutable/transform_spec.rb +26 -0
  104. data/spec/lib/hamster/immutable/transform_unless_spec.rb +44 -0
  105. data/spec/lib/hamster/list/add_spec.rb +26 -0
  106. data/spec/lib/hamster/list/all_spec.rb +58 -0
  107. data/spec/lib/hamster/list/any_spec.rb +50 -0
  108. data/spec/lib/hamster/list/append_spec.rb +39 -0
  109. data/spec/lib/hamster/list/at_spec.rb +30 -0
  110. data/spec/lib/hamster/list/break_spec.rb +70 -0
  111. data/spec/lib/hamster/list/cadr_spec.rb +39 -0
  112. data/spec/lib/hamster/list/chunk_spec.rb +29 -0
  113. data/spec/lib/hamster/list/clear_spec.rb +25 -0
  114. data/spec/lib/hamster/list/combination_spec.rb +34 -0
  115. data/spec/lib/hamster/list/compact_spec.rb +35 -0
  116. data/spec/lib/hamster/list/compare_spec.rb +31 -0
  117. data/spec/lib/hamster/list/cons_spec.rb +26 -0
  118. data/spec/lib/hamster/list/construction_spec.rb +111 -0
  119. data/spec/lib/hamster/list/copying_spec.rb +20 -0
  120. data/spec/lib/hamster/list/count_spec.rb +37 -0
  121. data/spec/lib/hamster/list/cycle_spec.rb +29 -0
  122. data/spec/lib/hamster/list/delete_at_spec.rb +19 -0
  123. data/spec/lib/hamster/list/delete_spec.rb +17 -0
  124. data/spec/lib/hamster/list/drop_spec.rb +31 -0
  125. data/spec/lib/hamster/list/drop_while_spec.rb +39 -0
  126. data/spec/lib/hamster/list/each_slice_spec.rb +52 -0
  127. data/spec/lib/hamster/list/each_spec.rb +41 -0
  128. data/spec/lib/hamster/list/each_with_index_spec.rb +29 -0
  129. data/spec/lib/hamster/list/empty_spec.rb +24 -0
  130. data/spec/lib/hamster/list/eql_spec.rb +62 -0
  131. data/spec/lib/hamster/list/fill_spec.rb +50 -0
  132. data/spec/lib/hamster/list/find_all_spec.rb +71 -0
  133. data/spec/{hamster → lib/hamster}/list/find_index_spec.rb +7 -29
  134. data/spec/{hamster → lib/hamster}/list/find_spec.rb +13 -35
  135. data/spec/lib/hamster/list/flat_map_spec.rb +52 -0
  136. data/spec/lib/hamster/list/flatten_spec.rb +31 -0
  137. data/spec/lib/hamster/list/grep_spec.rb +47 -0
  138. data/spec/lib/hamster/list/group_by_spec.rb +42 -0
  139. data/spec/lib/hamster/list/hash_spec.rb +22 -0
  140. data/spec/{hamster → lib/hamster}/list/head_spec.rb +6 -21
  141. data/spec/{hamster → lib/hamster}/list/include_spec.rb +8 -29
  142. data/spec/lib/hamster/list/index_spec.rb +34 -0
  143. data/spec/lib/hamster/list/indices_spec.rb +62 -0
  144. data/spec/lib/hamster/list/init_spec.rb +29 -0
  145. data/spec/lib/hamster/list/inits_spec.rb +29 -0
  146. data/spec/lib/hamster/list/insert_spec.rb +47 -0
  147. data/spec/lib/hamster/list/inspect_spec.rb +30 -0
  148. data/spec/lib/hamster/list/intersperse_spec.rb +29 -0
  149. data/spec/lib/hamster/list/join_spec.rb +64 -0
  150. data/spec/lib/hamster/list/last_spec.rb +24 -0
  151. data/spec/lib/hamster/list/ltlt_spec.rb +20 -0
  152. data/spec/lib/hamster/list/map_spec.rb +46 -0
  153. data/spec/lib/hamster/list/maximum_spec.rb +40 -0
  154. data/spec/{hamster → lib/hamster}/list/merge_by_spec.rb +9 -36
  155. data/spec/{hamster → lib/hamster}/list/merge_spec.rb +5 -24
  156. data/spec/lib/hamster/list/minimum_spec.rb +40 -0
  157. data/spec/lib/hamster/list/multithreading_spec.rb +48 -0
  158. data/spec/{hamster → lib/hamster}/list/none_spec.rb +14 -41
  159. data/spec/{hamster → lib/hamster}/list/one_spec.rb +15 -40
  160. data/spec/lib/hamster/list/partition_spec.rb +116 -0
  161. data/spec/lib/hamster/list/permutation_spec.rb +56 -0
  162. data/spec/lib/hamster/list/pop_spec.rb +26 -0
  163. data/spec/lib/hamster/list/product_spec.rb +24 -0
  164. data/spec/lib/hamster/list/reduce_spec.rb +54 -0
  165. data/spec/lib/hamster/list/reject_spec.rb +46 -0
  166. data/spec/lib/hamster/list/reverse_spec.rb +35 -0
  167. data/spec/lib/hamster/list/rotate_spec.rb +37 -0
  168. data/spec/lib/hamster/list/sample_spec.rb +14 -0
  169. data/spec/lib/hamster/list/select_spec.rb +71 -0
  170. data/spec/lib/hamster/list/size_spec.rb +26 -0
  171. data/spec/lib/hamster/list/slice_spec.rb +230 -0
  172. data/spec/lib/hamster/list/sorting_spec.rb +47 -0
  173. data/spec/lib/hamster/list/span_spec.rb +77 -0
  174. data/spec/lib/hamster/list/split_at_spec.rb +44 -0
  175. data/spec/lib/hamster/list/subsequences_spec.rb +24 -0
  176. data/spec/lib/hamster/list/sum_spec.rb +24 -0
  177. data/spec/lib/hamster/list/tail_spec.rb +31 -0
  178. data/spec/lib/hamster/list/tails_spec.rb +29 -0
  179. data/spec/lib/hamster/list/take_spec.rb +31 -0
  180. data/spec/lib/hamster/list/take_while_spec.rb +47 -0
  181. data/spec/lib/hamster/list/to_a_spec.rb +40 -0
  182. data/spec/lib/hamster/list/to_ary_spec.rb +42 -0
  183. data/spec/lib/hamster/list/to_list_spec.rb +20 -0
  184. data/spec/lib/hamster/list/to_set_spec.rb +19 -0
  185. data/spec/lib/hamster/list/transpose_spec.rb +20 -0
  186. data/spec/lib/hamster/list/union_spec.rb +32 -0
  187. data/spec/lib/hamster/list/uniq_spec.rb +30 -0
  188. data/spec/lib/hamster/list/zip_spec.rb +24 -0
  189. data/spec/lib/hamster/nested/construction_spec.rb +44 -0
  190. data/spec/lib/hamster/set/add_spec.rb +76 -0
  191. data/spec/lib/hamster/set/all_spec.rb +52 -0
  192. data/spec/lib/hamster/set/any_spec.rb +52 -0
  193. data/spec/lib/hamster/set/clear_spec.rb +34 -0
  194. data/spec/{hamster → lib/hamster}/set/compact_spec.rb +9 -20
  195. data/spec/lib/hamster/set/construction_spec.rb +19 -0
  196. data/spec/lib/hamster/set/copying_spec.rb +14 -0
  197. data/spec/lib/hamster/set/count_spec.rb +37 -0
  198. data/spec/lib/hamster/set/delete_spec.rb +72 -0
  199. data/spec/lib/hamster/set/difference_spec.rb +50 -0
  200. data/spec/lib/hamster/set/disjoint_spec.rb +26 -0
  201. data/spec/lib/hamster/set/each_spec.rb +46 -0
  202. data/spec/lib/hamster/set/empty_spec.rb +45 -0
  203. data/spec/lib/hamster/set/eqeq_spec.rb +104 -0
  204. data/spec/lib/hamster/set/eql_spec.rb +110 -0
  205. data/spec/lib/hamster/set/exclusion_spec.rb +48 -0
  206. data/spec/{hamster → lib/hamster}/set/find_spec.rb +10 -27
  207. data/spec/lib/hamster/set/first_spec.rb +29 -0
  208. data/spec/lib/hamster/set/flatten_spec.rb +47 -0
  209. data/spec/lib/hamster/set/grep_spec.rb +58 -0
  210. data/spec/lib/hamster/set/group_by_spec.rb +60 -0
  211. data/spec/lib/hamster/set/hash_spec.rb +23 -0
  212. data/spec/{hamster → lib/hamster}/set/immutable_spec.rb +4 -7
  213. data/spec/lib/hamster/set/include_spec.rb +61 -0
  214. data/spec/lib/hamster/set/inspect_spec.rb +48 -0
  215. data/spec/lib/hamster/set/intersect_spec.rb +26 -0
  216. data/spec/lib/hamster/set/intersection_spec.rb +53 -0
  217. data/spec/lib/hamster/set/join_spec.rb +65 -0
  218. data/spec/lib/hamster/set/map_spec.rb +60 -0
  219. data/spec/lib/hamster/set/marshal_spec.rb +29 -0
  220. data/spec/lib/hamster/set/maximum_spec.rb +37 -0
  221. data/spec/lib/hamster/set/minimum_spec.rb +37 -0
  222. data/spec/lib/hamster/set/new_spec.rb +54 -0
  223. data/spec/{hamster → lib/hamster}/set/none_spec.rb +17 -32
  224. data/spec/{hamster → lib/hamster}/set/one_spec.rb +16 -31
  225. data/spec/lib/hamster/set/partition_spec.rb +53 -0
  226. data/spec/lib/hamster/set/product_spec.rb +24 -0
  227. data/spec/lib/hamster/set/reduce_spec.rb +56 -0
  228. data/spec/lib/hamster/set/reject_spec.rb +51 -0
  229. data/spec/lib/hamster/set/reverse_each_spec.rb +39 -0
  230. data/spec/lib/hamster/set/sample_spec.rb +14 -0
  231. data/spec/lib/hamster/set/select_spec.rb +74 -0
  232. data/spec/{hamster → lib/hamster}/set/size_spec.rb +4 -13
  233. data/spec/lib/hamster/set/sorting_spec.rb +49 -0
  234. data/spec/lib/hamster/set/subset_spec.rb +52 -0
  235. data/spec/lib/hamster/set/sum_spec.rb +24 -0
  236. data/spec/lib/hamster/set/superset_spec.rb +52 -0
  237. data/spec/lib/hamster/set/to_a_spec.rb +31 -0
  238. data/spec/lib/hamster/set/to_list_spec.rb +37 -0
  239. data/spec/lib/hamster/set/to_set_spec.rb +20 -0
  240. data/spec/lib/hamster/set/union_spec.rb +64 -0
  241. data/spec/lib/hamster/sorted_set/above_spec.rb +52 -0
  242. data/spec/lib/hamster/sorted_set/add_spec.rb +63 -0
  243. data/spec/lib/hamster/sorted_set/at_spec.rb +25 -0
  244. data/spec/lib/hamster/sorted_set/below_spec.rb +52 -0
  245. data/spec/lib/hamster/sorted_set/between_spec.rb +52 -0
  246. data/spec/lib/hamster/sorted_set/clear_spec.rb +44 -0
  247. data/spec/lib/hamster/sorted_set/construction_spec.rb +29 -0
  248. data/spec/lib/hamster/sorted_set/delete_at_spec.rb +19 -0
  249. data/spec/lib/hamster/sorted_set/delete_spec.rb +90 -0
  250. data/spec/lib/hamster/sorted_set/difference_spec.rb +23 -0
  251. data/spec/lib/hamster/sorted_set/disjoint_spec.rb +26 -0
  252. data/spec/lib/hamster/sorted_set/drop_spec.rb +56 -0
  253. data/spec/lib/hamster/sorted_set/drop_while_spec.rb +35 -0
  254. data/spec/lib/hamster/sorted_set/each_spec.rb +29 -0
  255. data/spec/lib/hamster/sorted_set/empty_spec.rb +35 -0
  256. data/spec/lib/hamster/sorted_set/eql_spec.rb +121 -0
  257. data/spec/lib/hamster/sorted_set/exclusion_spec.rb +23 -0
  258. data/spec/lib/hamster/sorted_set/fetch_spec.rb +65 -0
  259. data/spec/lib/hamster/sorted_set/find_index_spec.rb +41 -0
  260. data/spec/lib/hamster/sorted_set/first_spec.rb +19 -0
  261. data/spec/lib/hamster/sorted_set/from_spec.rb +52 -0
  262. data/spec/lib/hamster/sorted_set/group_by_spec.rb +58 -0
  263. data/spec/lib/hamster/sorted_set/include_spec.rb +24 -0
  264. data/spec/lib/hamster/sorted_set/inspect_spec.rb +38 -0
  265. data/spec/lib/hamster/sorted_set/intersect_spec.rb +26 -0
  266. data/spec/lib/hamster/sorted_set/intersection_spec.rb +29 -0
  267. data/spec/lib/hamster/sorted_set/last_spec.rb +37 -0
  268. data/spec/lib/hamster/sorted_set/map_spec.rb +36 -0
  269. data/spec/lib/hamster/sorted_set/marshal_spec.rb +37 -0
  270. data/spec/lib/hamster/sorted_set/maximum_spec.rb +37 -0
  271. data/spec/lib/hamster/sorted_set/minimum_spec.rb +20 -0
  272. data/spec/lib/hamster/sorted_set/new_spec.rb +52 -0
  273. data/spec/lib/hamster/sorted_set/reverse_each_spec.rb +29 -0
  274. data/spec/lib/hamster/sorted_set/sample_spec.rb +14 -0
  275. data/spec/lib/hamster/sorted_set/select_spec.rb +62 -0
  276. data/spec/{hamster/vector → lib/hamster/sorted_set}/size_spec.rb +6 -15
  277. data/spec/lib/hamster/sorted_set/slice_spec.rb +257 -0
  278. data/spec/lib/hamster/sorted_set/sorting_spec.rb +45 -0
  279. data/spec/lib/hamster/sorted_set/subset_spec.rb +48 -0
  280. data/spec/lib/hamster/sorted_set/superset_spec.rb +48 -0
  281. data/spec/lib/hamster/sorted_set/take_spec.rb +55 -0
  282. data/spec/lib/hamster/sorted_set/take_while_spec.rb +34 -0
  283. data/spec/lib/hamster/sorted_set/to_set_spec.rb +19 -0
  284. data/spec/lib/hamster/sorted_set/union_spec.rb +28 -0
  285. data/spec/lib/hamster/sorted_set/up_to_spec.rb +52 -0
  286. data/spec/lib/hamster/sorted_set/values_at_spec.rb +34 -0
  287. data/spec/lib/hamster/vector/add_spec.rb +68 -0
  288. data/spec/lib/hamster/vector/any_spec.rb +70 -0
  289. data/spec/lib/hamster/vector/assoc_spec.rb +36 -0
  290. data/spec/lib/hamster/vector/bsearch_spec.rb +58 -0
  291. data/spec/lib/hamster/vector/clear_spec.rb +34 -0
  292. data/spec/lib/hamster/vector/combination_spec.rb +82 -0
  293. data/spec/lib/hamster/vector/compact_spec.rb +30 -0
  294. data/spec/lib/hamster/vector/compare_spec.rb +32 -0
  295. data/spec/lib/hamster/vector/concat_spec.rb +35 -0
  296. data/spec/lib/hamster/vector/copying_spec.rb +21 -0
  297. data/spec/lib/hamster/vector/count_spec.rb +18 -0
  298. data/spec/lib/hamster/vector/delete_at_spec.rb +54 -0
  299. data/spec/lib/hamster/vector/delete_spec.rb +31 -0
  300. data/spec/lib/hamster/vector/drop_spec.rb +42 -0
  301. data/spec/lib/hamster/vector/drop_while_spec.rb +55 -0
  302. data/spec/lib/hamster/vector/each_index_spec.rb +41 -0
  303. data/spec/lib/hamster/vector/each_spec.rb +45 -0
  304. data/spec/lib/hamster/vector/each_with_index_spec.rb +40 -0
  305. data/spec/lib/hamster/vector/empty_spec.rb +42 -0
  306. data/spec/lib/hamster/vector/eql_spec.rb +77 -0
  307. data/spec/lib/hamster/vector/fetch_spec.rb +65 -0
  308. data/spec/lib/hamster/vector/fill_spec.rb +89 -0
  309. data/spec/lib/hamster/vector/first_spec.rb +19 -0
  310. data/spec/lib/hamster/vector/flat_map_spec.rb +51 -0
  311. data/spec/lib/hamster/vector/flatten_spec.rb +44 -0
  312. data/spec/lib/hamster/vector/get_spec.rb +75 -0
  313. data/spec/lib/hamster/vector/group_by_spec.rb +58 -0
  314. data/spec/{hamster → lib/hamster}/vector/include_spec.rb +6 -20
  315. data/spec/lib/hamster/vector/insert_spec.rb +69 -0
  316. data/spec/lib/hamster/vector/inspect_spec.rb +50 -0
  317. data/spec/{hamster/set → lib/hamster/vector}/join_spec.rb +24 -34
  318. data/spec/lib/hamster/vector/last_spec.rb +46 -0
  319. data/spec/lib/hamster/vector/length_spec.rb +46 -0
  320. data/spec/lib/hamster/vector/ltlt_spec.rb +66 -0
  321. data/spec/lib/hamster/vector/map_spec.rb +52 -0
  322. data/spec/lib/hamster/vector/marshal_spec.rb +32 -0
  323. data/spec/lib/hamster/vector/maximum_spec.rb +34 -0
  324. data/spec/lib/hamster/vector/minimum_spec.rb +34 -0
  325. data/spec/lib/hamster/vector/multiply_spec.rb +48 -0
  326. data/spec/lib/hamster/vector/new_spec.rb +51 -0
  327. data/spec/lib/hamster/vector/partition_spec.rb +53 -0
  328. data/spec/lib/hamster/vector/permutation_spec.rb +92 -0
  329. data/spec/lib/hamster/vector/pop_spec.rb +27 -0
  330. data/spec/lib/hamster/vector/product_spec.rb +71 -0
  331. data/spec/{hamster → lib/hamster}/vector/reduce_spec.rb +18 -49
  332. data/spec/lib/hamster/vector/reject_spec.rb +44 -0
  333. data/spec/lib/hamster/vector/repeated_combination_spec.rb +78 -0
  334. data/spec/lib/hamster/vector/repeated_permutation_spec.rb +94 -0
  335. data/spec/lib/hamster/vector/reverse_each_spec.rb +32 -0
  336. data/spec/lib/hamster/vector/reverse_spec.rb +22 -0
  337. data/spec/lib/hamster/vector/rindex_spec.rb +37 -0
  338. data/spec/lib/hamster/vector/rotate_spec.rb +74 -0
  339. data/spec/lib/hamster/vector/sample_spec.rb +14 -0
  340. data/spec/lib/hamster/vector/select_spec.rb +64 -0
  341. data/spec/lib/hamster/vector/set_spec.rb +175 -0
  342. data/spec/lib/hamster/vector/shift_spec.rb +28 -0
  343. data/spec/lib/hamster/vector/shuffle_spec.rb +44 -0
  344. data/spec/lib/hamster/vector/slice_spec.rb +241 -0
  345. data/spec/lib/hamster/vector/sorting_spec.rb +57 -0
  346. data/spec/{hamster/set → lib/hamster/vector}/sum_spec.rb +5 -19
  347. data/spec/lib/hamster/vector/take_spec.rb +43 -0
  348. data/spec/lib/hamster/vector/take_while_spec.rb +35 -0
  349. data/spec/lib/hamster/vector/to_a_spec.rb +42 -0
  350. data/spec/lib/hamster/vector/to_ary_spec.rb +35 -0
  351. data/spec/lib/hamster/vector/to_list_spec.rb +32 -0
  352. data/spec/lib/hamster/vector/to_set_spec.rb +23 -0
  353. data/spec/lib/hamster/vector/transpose_spec.rb +49 -0
  354. data/spec/lib/hamster/vector/uniq_spec.rb +56 -0
  355. data/spec/lib/hamster/vector/unshift_spec.rb +29 -0
  356. data/spec/lib/hamster/vector/update_in_spec.rb +83 -0
  357. data/spec/lib/hamster/vector/values_at_spec.rb +34 -0
  358. data/spec/lib/hamster/vector/zip_spec.rb +58 -0
  359. data/spec/spec_helper.rb +45 -13
  360. metadata +807 -458
  361. data/History.rdoc +0 -419
  362. data/LICENSE +0 -20
  363. data/README.rdoc +0 -236
  364. data/Rakefile +0 -5
  365. data/lib/hamster/core_ext/enumerator.rb +0 -30
  366. data/lib/hamster/experimental/mutable_stack.rb +0 -35
  367. data/lib/hamster/queue.rb +0 -93
  368. data/lib/hamster/sorter.rb +0 -32
  369. data/lib/hamster/stack.rb +0 -82
  370. data/lib/hamster/tuple.rb +0 -45
  371. data/spec/hamster/core_ext/array_spec.rb +0 -20
  372. data/spec/hamster/core_ext/coverage/assets/0.4.4/app.js +0 -66
  373. data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/blank.gif +0 -0
  374. data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_close.png +0 -0
  375. data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_loading.png +0 -0
  376. data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_nav_left.png +0 -0
  377. data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_nav_right.png +0 -0
  378. data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_shadow_e.png +0 -0
  379. data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_shadow_n.png +0 -0
  380. data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_shadow_ne.png +0 -0
  381. data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_shadow_nw.png +0 -0
  382. data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_shadow_s.png +0 -0
  383. data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_shadow_se.png +0 -0
  384. data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_shadow_sw.png +0 -0
  385. data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_shadow_w.png +0 -0
  386. data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_title_left.png +0 -0
  387. data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_title_main.png +0 -0
  388. data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_title_over.png +0 -0
  389. data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_title_right.png +0 -0
  390. data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancybox-x.png +0 -0
  391. data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancybox-y.png +0 -0
  392. data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancybox.png +0 -0
  393. data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/jquery.fancybox-1.3.1.css +0 -363
  394. data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/jquery.fancybox-1.3.1.pack.js +0 -44
  395. data/spec/hamster/core_ext/coverage/assets/0.4.4/favicon.png +0 -0
  396. data/spec/hamster/core_ext/coverage/assets/0.4.4/jquery-1.4.2.min.js +0 -155
  397. data/spec/hamster/core_ext/coverage/assets/0.4.4/jquery.dataTables.min.js +0 -152
  398. data/spec/hamster/core_ext/coverage/assets/0.4.4/jquery.timeago.js +0 -141
  399. data/spec/hamster/core_ext/coverage/assets/0.4.4/jquery.url.js +0 -174
  400. data/spec/hamster/core_ext/coverage/assets/0.4.4/loading.gif +0 -0
  401. data/spec/hamster/core_ext/coverage/assets/0.4.4/magnify.png +0 -0
  402. data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  403. data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  404. data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  405. data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  406. data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  407. data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  408. data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  409. data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  410. data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-icons_222222_256x240.png +0 -0
  411. data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  412. data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-icons_454545_256x240.png +0 -0
  413. data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-icons_888888_256x240.png +0 -0
  414. data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  415. data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/jquery-ui-1.8.4.custom.css +0 -295
  416. data/spec/hamster/core_ext/coverage/assets/0.4.4/stylesheet.css +0 -341
  417. data/spec/hamster/core_ext/coverage/covered_percent +0 -1
  418. data/spec/hamster/core_ext/coverage/index.html +0 -71
  419. data/spec/hamster/core_ext/coverage/resultset.yml +0 -10
  420. data/spec/hamster/core_ext/enumerable_spec.rb +0 -34
  421. data/spec/hamster/core_ext/enumerator_spec.rb +0 -25
  422. data/spec/hamster/core_ext/io_spec.rb +0 -29
  423. data/spec/hamster/experimental/mutable_set/add?_spec.rb +0 -47
  424. data/spec/hamster/experimental/mutable_set/add_spec.rb +0 -51
  425. data/spec/hamster/experimental/mutable_set/delete?_spec.rb +0 -47
  426. data/spec/hamster/experimental/mutable_set/delete_spec.rb +0 -47
  427. data/spec/hamster/experimental/mutable_stack/pop_spec.rb +0 -41
  428. data/spec/hamster/experimental/mutable_stack/push_spec.rb +0 -41
  429. data/spec/hamster/hash/all_spec.rb +0 -59
  430. data/spec/hamster/hash/any_spec.rb +0 -68
  431. data/spec/hamster/hash/clear_spec.rb +0 -36
  432. data/spec/hamster/hash/construction_spec.rb +0 -35
  433. data/spec/hamster/hash/copying_spec.rb +0 -23
  434. data/spec/hamster/hash/delete_spec.rb +0 -47
  435. data/spec/hamster/hash/each_spec.rb +0 -41
  436. data/spec/hamster/hash/empty_spec.rb +0 -27
  437. data/spec/hamster/hash/eql_spec.rb +0 -62
  438. data/spec/hamster/hash/except_spec.rb +0 -31
  439. data/spec/hamster/hash/fetch_spec.rb +0 -95
  440. data/spec/hamster/hash/filter_spec.rb +0 -63
  441. data/spec/hamster/hash/find_spec.rb +0 -58
  442. data/spec/hamster/hash/get_spec.rb +0 -68
  443. data/spec/hamster/hash/has_key_spec.rb +0 -35
  444. data/spec/hamster/hash/hash_spec.rb +0 -54
  445. data/spec/hamster/hash/inspect_spec.rb +0 -32
  446. data/spec/hamster/hash/keys_spec.rb +0 -21
  447. data/spec/hamster/hash/map_spec.rb +0 -64
  448. data/spec/hamster/hash/merge_spec.rb +0 -36
  449. data/spec/hamster/hash/none_spec.rb +0 -64
  450. data/spec/hamster/hash/put_spec.rb +0 -65
  451. data/spec/hamster/hash/reduce_spec.rb +0 -60
  452. data/spec/hamster/hash/remove_spec.rb +0 -63
  453. data/spec/hamster/hash/slice_spec.rb +0 -31
  454. data/spec/hamster/hash/uniq_spec.rb +0 -23
  455. data/spec/hamster/hash/values_spec.rb +0 -34
  456. data/spec/hamster/immutable/memoize_spec.rb +0 -64
  457. data/spec/hamster/immutable/new_spec.rb +0 -28
  458. data/spec/hamster/immutable/transform_spec.rb +0 -31
  459. data/spec/hamster/immutable/transform_unless_spec.rb +0 -55
  460. data/spec/hamster/list/all_spec.rb +0 -111
  461. data/spec/hamster/list/any_spec.rb +0 -79
  462. data/spec/hamster/list/append_spec.rb +0 -50
  463. data/spec/hamster/list/at_spec.rb +0 -49
  464. data/spec/hamster/list/break_spec.rb +0 -85
  465. data/spec/hamster/list/cadr_spec.rb +0 -50
  466. data/spec/hamster/list/chunk_spec.rb +0 -40
  467. data/spec/hamster/list/clear_spec.rb +0 -36
  468. data/spec/hamster/list/combinations_spec.rb +0 -51
  469. data/spec/hamster/list/compact_spec.rb +0 -46
  470. data/spec/hamster/list/cons_spec.rb +0 -41
  471. data/spec/hamster/list/construction_spec.rb +0 -140
  472. data/spec/hamster/list/copying_spec.rb +0 -32
  473. data/spec/hamster/list/count_spec.rb +0 -66
  474. data/spec/hamster/list/coverage/assets/0.4.4/app.js +0 -66
  475. data/spec/hamster/list/coverage/assets/0.4.4/fancybox/blank.gif +0 -0
  476. data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_close.png +0 -0
  477. data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_loading.png +0 -0
  478. data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_nav_left.png +0 -0
  479. data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_nav_right.png +0 -0
  480. data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_shadow_e.png +0 -0
  481. data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_shadow_n.png +0 -0
  482. data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_shadow_ne.png +0 -0
  483. data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_shadow_nw.png +0 -0
  484. data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_shadow_s.png +0 -0
  485. data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_shadow_se.png +0 -0
  486. data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_shadow_sw.png +0 -0
  487. data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_shadow_w.png +0 -0
  488. data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_title_left.png +0 -0
  489. data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_title_main.png +0 -0
  490. data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_title_over.png +0 -0
  491. data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_title_right.png +0 -0
  492. data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancybox-x.png +0 -0
  493. data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancybox-y.png +0 -0
  494. data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancybox.png +0 -0
  495. data/spec/hamster/list/coverage/assets/0.4.4/fancybox/jquery.fancybox-1.3.1.css +0 -363
  496. data/spec/hamster/list/coverage/assets/0.4.4/fancybox/jquery.fancybox-1.3.1.pack.js +0 -44
  497. data/spec/hamster/list/coverage/assets/0.4.4/favicon.png +0 -0
  498. data/spec/hamster/list/coverage/assets/0.4.4/jquery-1.4.2.min.js +0 -155
  499. data/spec/hamster/list/coverage/assets/0.4.4/jquery.dataTables.min.js +0 -152
  500. data/spec/hamster/list/coverage/assets/0.4.4/jquery.timeago.js +0 -141
  501. data/spec/hamster/list/coverage/assets/0.4.4/jquery.url.js +0 -174
  502. data/spec/hamster/list/coverage/assets/0.4.4/loading.gif +0 -0
  503. data/spec/hamster/list/coverage/assets/0.4.4/magnify.png +0 -0
  504. data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  505. data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  506. data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  507. data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  508. data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  509. data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  510. data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  511. data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  512. data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-icons_222222_256x240.png +0 -0
  513. data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  514. data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-icons_454545_256x240.png +0 -0
  515. data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-icons_888888_256x240.png +0 -0
  516. data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  517. data/spec/hamster/list/coverage/assets/0.4.4/smoothness/jquery-ui-1.8.4.custom.css +0 -295
  518. data/spec/hamster/list/coverage/assets/0.4.4/stylesheet.css +0 -341
  519. data/spec/hamster/list/coverage/covered_percent +0 -1
  520. data/spec/hamster/list/coverage/index.html +0 -71
  521. data/spec/hamster/list/coverage/resultset.yml +0 -225
  522. data/spec/hamster/list/cycle_spec.rb +0 -45
  523. data/spec/hamster/list/drop_spec.rb +0 -42
  524. data/spec/hamster/list/drop_while_spec.rb +0 -59
  525. data/spec/hamster/list/each_slice_spec.rb +0 -80
  526. data/spec/hamster/list/each_spec.rb +0 -72
  527. data/spec/hamster/list/each_with_index_spec.rb +0 -42
  528. data/spec/hamster/list/elem_index_spec.rb +0 -58
  529. data/spec/hamster/list/elem_indices_spec.rb +0 -45
  530. data/spec/hamster/list/empty_spec.rb +0 -47
  531. data/spec/hamster/list/eql_spec.rb +0 -78
  532. data/spec/hamster/list/filter_spec.rb +0 -61
  533. data/spec/hamster/list/find_indices_spec.rb +0 -45
  534. data/spec/hamster/list/flatten_spec.rb +0 -42
  535. data/spec/hamster/list/grep_spec.rb +0 -70
  536. data/spec/hamster/list/group_by_spec.rb +0 -77
  537. data/spec/hamster/list/hash_spec.rb +0 -43
  538. data/spec/hamster/list/init_spec.rb +0 -40
  539. data/spec/hamster/list/inits_spec.rb +0 -42
  540. data/spec/hamster/list/inspect_spec.rb +0 -43
  541. data/spec/hamster/list/intersperse_spec.rb +0 -40
  542. data/spec/hamster/list/join_spec.rb +0 -81
  543. data/spec/hamster/list/last_spec.rb +0 -44
  544. data/spec/hamster/list/map_spec.rb +0 -69
  545. data/spec/hamster/list/maximum_spec.rb +0 -77
  546. data/spec/hamster/list/minimum_spec.rb +0 -77
  547. data/spec/hamster/list/partition_spec.rb +0 -75
  548. data/spec/hamster/list/product_spec.rb +0 -44
  549. data/spec/hamster/list/reduce_spec.rb +0 -99
  550. data/spec/hamster/list/remove_spec.rb +0 -67
  551. data/spec/hamster/list/reverse_spec.rb +0 -52
  552. data/spec/hamster/list/size_spec.rb +0 -47
  553. data/spec/hamster/list/slice_spec.rb +0 -50
  554. data/spec/hamster/list/sorting_spec.rb +0 -70
  555. data/spec/hamster/list/span_spec.rb +0 -86
  556. data/spec/hamster/list/split_at_spec.rb +0 -53
  557. data/spec/hamster/list/sum_spec.rb +0 -44
  558. data/spec/hamster/list/tail_spec.rb +0 -48
  559. data/spec/hamster/list/tails_spec.rb +0 -42
  560. data/spec/hamster/list/take_spec.rb +0 -42
  561. data/spec/hamster/list/take_while_spec.rb +0 -62
  562. data/spec/hamster/list/to_a_spec.rb +0 -54
  563. data/spec/hamster/list/to_ary_spec.rb +0 -56
  564. data/spec/hamster/list/to_list_spec.rb +0 -32
  565. data/spec/hamster/list/to_set_spec.rb +0 -33
  566. data/spec/hamster/list/union_spec.rb +0 -49
  567. data/spec/hamster/list/uniq_spec.rb +0 -45
  568. data/spec/hamster/list/zip_spec.rb +0 -39
  569. data/spec/hamster/queue/clear_spec.rb +0 -36
  570. data/spec/hamster/queue/construction_spec.rb +0 -43
  571. data/spec/hamster/queue/dequeue_spec.rb +0 -40
  572. data/spec/hamster/queue/empty_spec.rb +0 -47
  573. data/spec/hamster/queue/enqueue_spec.rb +0 -41
  574. data/spec/hamster/queue/head_spec.rb +0 -35
  575. data/spec/hamster/queue/inspect_spec.rb +0 -31
  576. data/spec/hamster/queue/size_spec.rb +0 -35
  577. data/spec/hamster/queue/to_a_spec.rb +0 -42
  578. data/spec/hamster/queue/to_ary_spec.rb +0 -44
  579. data/spec/hamster/queue/to_list_spec.rb +0 -44
  580. data/spec/hamster/set/add_spec.rb +0 -51
  581. data/spec/hamster/set/all_spec.rb +0 -67
  582. data/spec/hamster/set/any_spec.rb +0 -67
  583. data/spec/hamster/set/clear_spec.rb +0 -36
  584. data/spec/hamster/set/construction_spec.rb +0 -31
  585. data/spec/hamster/set/copying_spec.rb +0 -23
  586. data/spec/hamster/set/count_spec.rb +0 -54
  587. data/spec/hamster/set/coverage/assets/0.4.4/app.js +0 -66
  588. data/spec/hamster/set/coverage/assets/0.4.4/fancybox/blank.gif +0 -0
  589. data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_close.png +0 -0
  590. data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_loading.png +0 -0
  591. data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_nav_left.png +0 -0
  592. data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_nav_right.png +0 -0
  593. data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_shadow_e.png +0 -0
  594. data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_shadow_n.png +0 -0
  595. data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_shadow_ne.png +0 -0
  596. data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_shadow_nw.png +0 -0
  597. data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_shadow_s.png +0 -0
  598. data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_shadow_se.png +0 -0
  599. data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_shadow_sw.png +0 -0
  600. data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_shadow_w.png +0 -0
  601. data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_title_left.png +0 -0
  602. data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_title_main.png +0 -0
  603. data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_title_over.png +0 -0
  604. data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_title_right.png +0 -0
  605. data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancybox-x.png +0 -0
  606. data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancybox-y.png +0 -0
  607. data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancybox.png +0 -0
  608. data/spec/hamster/set/coverage/assets/0.4.4/fancybox/jquery.fancybox-1.3.1.css +0 -363
  609. data/spec/hamster/set/coverage/assets/0.4.4/fancybox/jquery.fancybox-1.3.1.pack.js +0 -44
  610. data/spec/hamster/set/coverage/assets/0.4.4/favicon.png +0 -0
  611. data/spec/hamster/set/coverage/assets/0.4.4/jquery-1.4.2.min.js +0 -155
  612. data/spec/hamster/set/coverage/assets/0.4.4/jquery.dataTables.min.js +0 -152
  613. data/spec/hamster/set/coverage/assets/0.4.4/jquery.timeago.js +0 -141
  614. data/spec/hamster/set/coverage/assets/0.4.4/jquery.url.js +0 -174
  615. data/spec/hamster/set/coverage/assets/0.4.4/loading.gif +0 -0
  616. data/spec/hamster/set/coverage/assets/0.4.4/magnify.png +0 -0
  617. data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  618. data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  619. data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  620. data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  621. data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  622. data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  623. data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  624. data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  625. data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-icons_222222_256x240.png +0 -0
  626. data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  627. data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-icons_454545_256x240.png +0 -0
  628. data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-icons_888888_256x240.png +0 -0
  629. data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  630. data/spec/hamster/set/coverage/assets/0.4.4/smoothness/jquery-ui-1.8.4.custom.css +0 -295
  631. data/spec/hamster/set/coverage/assets/0.4.4/stylesheet.css +0 -341
  632. data/spec/hamster/set/coverage/covered_percent +0 -1
  633. data/spec/hamster/set/coverage/index.html +0 -71
  634. data/spec/hamster/set/coverage/resultset.yml +0 -13
  635. data/spec/hamster/set/delete_spec.rb +0 -47
  636. data/spec/hamster/set/difference_spec.rb +0 -37
  637. data/spec/hamster/set/each_spec.rb +0 -42
  638. data/spec/hamster/set/empty_spec.rb +0 -35
  639. data/spec/hamster/set/eql_spec.rb +0 -62
  640. data/spec/hamster/set/exclusion_spec.rb +0 -38
  641. data/spec/hamster/set/filter_spec.rb +0 -79
  642. data/spec/hamster/set/flatten_spec.rb +0 -49
  643. data/spec/hamster/set/grep_spec.rb +0 -62
  644. data/spec/hamster/set/group_by_spec.rb +0 -65
  645. data/spec/hamster/set/hash_spec.rb +0 -31
  646. data/spec/hamster/set/head_spec.rb +0 -39
  647. data/spec/hamster/set/include_spec.rb +0 -35
  648. data/spec/hamster/set/inspect_spec.rb +0 -32
  649. data/spec/hamster/set/intersection_spec.rb +0 -46
  650. data/spec/hamster/set/map_spec.rb +0 -64
  651. data/spec/hamster/set/maximum_spec.rb +0 -65
  652. data/spec/hamster/set/minimum_spec.rb +0 -65
  653. data/spec/hamster/set/partition_spec.rb +0 -71
  654. data/spec/hamster/set/product_spec.rb +0 -32
  655. data/spec/hamster/set/reduce_spec.rb +0 -87
  656. data/spec/hamster/set/remove_spec.rb +0 -63
  657. data/spec/hamster/set/sorting_spec.rb +0 -58
  658. data/spec/hamster/set/subset_spec.rb +0 -39
  659. data/spec/hamster/set/superset_spec.rb +0 -39
  660. data/spec/hamster/set/to_a_spec.rb +0 -42
  661. data/spec/hamster/set/to_list_spec.rb +0 -47
  662. data/spec/hamster/set/to_set_spec.rb +0 -32
  663. data/spec/hamster/set/union_spec.rb +0 -45
  664. data/spec/hamster/set/uniq_spec.rb +0 -23
  665. data/spec/hamster/sorter/coverage/assets/0.4.4/app.js +0 -66
  666. data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/blank.gif +0 -0
  667. data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_close.png +0 -0
  668. data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_loading.png +0 -0
  669. data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_nav_left.png +0 -0
  670. data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_nav_right.png +0 -0
  671. data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_shadow_e.png +0 -0
  672. data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_shadow_n.png +0 -0
  673. data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_shadow_ne.png +0 -0
  674. data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_shadow_nw.png +0 -0
  675. data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_shadow_s.png +0 -0
  676. data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_shadow_se.png +0 -0
  677. data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_shadow_sw.png +0 -0
  678. data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_shadow_w.png +0 -0
  679. data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_title_left.png +0 -0
  680. data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_title_main.png +0 -0
  681. data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_title_over.png +0 -0
  682. data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_title_right.png +0 -0
  683. data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancybox-x.png +0 -0
  684. data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancybox-y.png +0 -0
  685. data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancybox.png +0 -0
  686. data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/jquery.fancybox-1.3.1.css +0 -363
  687. data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/jquery.fancybox-1.3.1.pack.js +0 -44
  688. data/spec/hamster/sorter/coverage/assets/0.4.4/favicon.png +0 -0
  689. data/spec/hamster/sorter/coverage/assets/0.4.4/jquery-1.4.2.min.js +0 -155
  690. data/spec/hamster/sorter/coverage/assets/0.4.4/jquery.dataTables.min.js +0 -152
  691. data/spec/hamster/sorter/coverage/assets/0.4.4/jquery.timeago.js +0 -141
  692. data/spec/hamster/sorter/coverage/assets/0.4.4/jquery.url.js +0 -174
  693. data/spec/hamster/sorter/coverage/assets/0.4.4/loading.gif +0 -0
  694. data/spec/hamster/sorter/coverage/assets/0.4.4/magnify.png +0 -0
  695. data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  696. data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  697. data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  698. data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  699. data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  700. data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  701. data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  702. data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  703. data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-icons_222222_256x240.png +0 -0
  704. data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  705. data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-icons_454545_256x240.png +0 -0
  706. data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-icons_888888_256x240.png +0 -0
  707. data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  708. data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/jquery-ui-1.8.4.custom.css +0 -295
  709. data/spec/hamster/sorter/coverage/assets/0.4.4/stylesheet.css +0 -341
  710. data/spec/hamster/sorter/coverage/covered_percent +0 -1
  711. data/spec/hamster/sorter/coverage/index.html +0 -71
  712. data/spec/hamster/sorter/coverage/resultset.yml +0 -22
  713. data/spec/hamster/sorter/immutable_spec.rb +0 -12
  714. data/spec/hamster/stack/clear_spec.rb +0 -36
  715. data/spec/hamster/stack/construction_spec.rb +0 -43
  716. data/spec/hamster/stack/copying_spec.rb +0 -31
  717. data/spec/hamster/stack/empty_spec.rb +0 -31
  718. data/spec/hamster/stack/eql_spec.rb +0 -60
  719. data/spec/hamster/stack/immutable_spec.rb +0 -12
  720. data/spec/hamster/stack/inspect_spec.rb +0 -31
  721. data/spec/hamster/stack/peek_spec.rb +0 -40
  722. data/spec/hamster/stack/pop_spec.rb +0 -41
  723. data/spec/hamster/stack/push_spec.rb +0 -41
  724. data/spec/hamster/stack/size_spec.rb +0 -35
  725. data/spec/hamster/stack/to_a_spec.rb +0 -42
  726. data/spec/hamster/stack/to_ary.rb +0 -44
  727. data/spec/hamster/stack/to_list_spec.rb +0 -33
  728. data/spec/hamster/trie/remove_spec.rb +0 -117
  729. data/spec/hamster/tuple/copying_spec.rb +0 -24
  730. data/spec/hamster/tuple/eql_spec.rb +0 -61
  731. data/spec/hamster/tuple/first_spec.rb +0 -19
  732. data/spec/hamster/tuple/immutable_spec.rb +0 -12
  733. data/spec/hamster/tuple/inspect_spec.rb +0 -19
  734. data/spec/hamster/tuple/last_spec.rb +0 -19
  735. data/spec/hamster/tuple/to_a_spec.rb +0 -38
  736. data/spec/hamster/tuple/to_ary_spec.rb +0 -44
  737. data/spec/hamster/undefined/erase_spec.rb +0 -47
  738. data/spec/hamster/vector/add_spec.rb +0 -41
  739. data/spec/hamster/vector/any_spec.rb +0 -67
  740. data/spec/hamster/vector/clear_spec.rb +0 -36
  741. data/spec/hamster/vector/copying_spec.rb +0 -32
  742. data/spec/hamster/vector/each_spec.rb +0 -46
  743. data/spec/hamster/vector/each_with_index_spec.rb +0 -42
  744. data/spec/hamster/vector/empty_spec.rb +0 -35
  745. data/spec/hamster/vector/eql_spec.rb +0 -65
  746. data/spec/hamster/vector/filter_spec.rb +0 -63
  747. data/spec/hamster/vector/first_spec.rb +0 -35
  748. data/spec/hamster/vector/get_spec.rb +0 -81
  749. data/spec/hamster/vector/inspect_spec.rb +0 -31
  750. data/spec/hamster/vector/last_spec.rb +0 -32
  751. data/spec/hamster/vector/map_spec.rb +0 -64
  752. data/spec/hamster/vector/set_spec.rb +0 -153
  753. data/spec/hamster/vector/to_a_spec.rb +0 -42
  754. data/spec/hamster/vector/to_ary_spec.rb +0 -44
  755. data/tasks/bundler.rb +0 -2
  756. data/tasks/publish.rb +0 -12
  757. data/tasks/spec.rb +0 -13
@@ -0,0 +1,1397 @@
1
+ require "hamster/immutable"
2
+ require "hamster/enumerable"
3
+ require "hamster/hash"
4
+
5
+ module Hamster
6
+ # Create a new `SortedSet` populated with the given items. If a block is provided,
7
+ # it will determine the sort order of the set. Such a block can accept either 1
8
+ # parameter (and will be used to derived sort keys, like a `Enumerable#sort_by`
9
+ # block) or 2 parameters (and will act as a comparator, like a `Enumerable#sort`
10
+ # block).
11
+ #
12
+ # @return [SortedSet]
13
+ def self.sorted_set(*items, &block)
14
+ (items.empty? && block.nil?) ? EmptySortedSet : SortedSet.new(items, &block)
15
+ end
16
+
17
+ # A `SortedSet` is a collection of ordered values with no duplicates. Unlike a
18
+ # {Vector}, in which items can appear in any arbitrary order, a `SortedSet` always
19
+ # keeps items either in their natural order, or in an order defined by a comparator
20
+ # block which is provided at initialization time.
21
+ #
22
+ # `SortedSet` uses `#<=>` (or its comparator block) to determine which items are
23
+ # equivalent. If the comparator indicates that an existing item and a new item are
24
+ # equal, any attempt to insert the new item will have no effect.
25
+ #
26
+ # This means that *all* the items inserted into any one `SortedSet` must all be
27
+ # comparable. For example, you cannot put `String`s and `Integer`s in the same
28
+ # `SortedSet`. This is unlike {Set}, which can store items of any type, as long
29
+ # as they all support `#hash` and `#eql?`.
30
+ #
31
+ # A `SortedSet` can be created in any of the following ways:
32
+ #
33
+ # Hamster.sorted_set('Tom', 'Dick', 'Harry')
34
+ # Hamster::SortedSet.new([1, 2, 3]) # any Enumerable can be used to initialize
35
+ # Hamster::SortedSet['A', 'B', 'C', 'D']
36
+ #
37
+ # Or if you want to use a custom ordering:
38
+ #
39
+ # Hamster.sorted_set('Tom', 'Dick', 'Harry') { |a, b| a.reverse <=> b.reverse }
40
+ # Hamster.sorted_set('Tom', 'Dick', 'Harry') { |str| str.reverse }
41
+ # Hamster::SortedSet.new([1,2,3]) { |a, b| -a <=> -b }
42
+ # Hamster::SortedSet.new([1, 2, 3]) { |num| -num }
43
+ #
44
+ # As you can see, `SortedSet` can use a 2-parameter block which returns 0, 1, or -1
45
+ # as a comparator (like `Array#sort`), *or* use a 1-parameter block to derive sort
46
+ # keys (like `Array#sort_by`) which will be compared using `#<=>`.
47
+ #
48
+ # Like all Hamster collections, `SortedSet`s are immutable. Any operation which you
49
+ # might expect to "modify" a `SortedSet` will actually return a new collection and
50
+ # leave the existing one unchanged.
51
+ #
52
+ # `SortedSet` supports the same basic set-theoretic operations as {Set}, including
53
+ # {#union}, {#intersection}, {#difference}, and {#exclusion}, as well as {#subset?},
54
+ # {#superset?}, and so on. Unlike {Set}, it does not define comparison operators like
55
+ # {#>} or {#<} as aliases for the superset/subset predicates. Instead, these comparison
56
+ # operators do a item-by-item comparison between the `SortedSet` and another sequential
57
+ # collection. (See `Array#<=>` for details.)
58
+ #
59
+ # Additionally, since `SortedSet`s are ordered, they also support indexed retrieval
60
+ # of items (or slices of items) using {#at} or {#[]}. Like {Vector} (or `Array`),
61
+ # negative indices count back from the end of the `SortedSet`.
62
+ #
63
+ # Getting the {#max} or {#min} item from a `SortedSet`, as defined by its comparator,
64
+ # is very efficient.
65
+ #
66
+ class SortedSet
67
+ include Immutable
68
+ include Enumerable
69
+
70
+ class << self
71
+ # Create a new `SortedSet` populated with the given items. This method does not
72
+ # accept a comparator block.
73
+ #
74
+ # @return [SortedSet]
75
+ def [](*items)
76
+ new(items)
77
+ end
78
+
79
+ # Return an empty `SortedSet`. If used on a subclass, returns an empty instance
80
+ # of that class.
81
+ #
82
+ # @return [SortedSet]
83
+ def empty
84
+ @empty ||= self.alloc(PlainAVLNode::EmptyNode)
85
+ end
86
+
87
+ # "Raw" allocation of a new `SortedSet`. Used internally to create a new
88
+ # instance quickly after obtaining a modified binary tree.
89
+ #
90
+ # @return [Set]
91
+ # @private
92
+ def alloc(node)
93
+ result = allocate
94
+ result.instance_variable_set(:@node, node)
95
+ result
96
+ end
97
+ end
98
+
99
+ def initialize(items=[], &block)
100
+ items = items.to_a
101
+ if block
102
+ comparator = if block.arity == 1
103
+ lambda { |a,b| block.call(a) <=> block.call(b) }
104
+ else
105
+ block
106
+ end
107
+ items = items.sort(&comparator)
108
+ @node = AVLNode.from_items(items, comparator)
109
+ else
110
+ @node = PlainAVLNode.from_items(items.sort)
111
+ end
112
+ end
113
+
114
+ # Return `true` if this `SortedSet` contains no items.
115
+ #
116
+ # @return [Boolean]
117
+ def empty?
118
+ @node.empty?
119
+ end
120
+
121
+ # Return the number of items in this `SortedSet`.
122
+ #
123
+ # @example
124
+ # Hamster::SortedSet["A", "B", "C"].size # => 3
125
+ #
126
+ # @return [Integer]
127
+ def size
128
+ @node.size
129
+ end
130
+ alias :length :size
131
+
132
+ # Return a new `SortedSet` with `item` added. If `item` is already in the set,
133
+ # return `self`.
134
+ #
135
+ # @example
136
+ # Hamster::SortedSet["Dog", "Lion"].add("Elephant")
137
+ # # => Hamster::SortedSet["Dog", "Elephant", "Lion"]
138
+ #
139
+ # @param item [Object] The object to add
140
+ # @return [SortedSet]
141
+ def add(item)
142
+ catch :present do
143
+ node = @node.insert(item)
144
+ return self.class.alloc(node)
145
+ end
146
+ self
147
+ end
148
+ alias :<< :add
149
+
150
+ # If `item` is not a member of this `SortedSet`, return a new `SortedSet` with
151
+ # `item` added. Otherwise, return `false`.
152
+ #
153
+ # @example
154
+ # Hamster::SortedSet["Dog", "Lion"].add?("Elephant")
155
+ # # => Hamster::SortedSet["Dog", "Elephant", "Lion"]
156
+ # Hamster::SortedSet["Dog", "Lion"].add?("Lion")
157
+ # # => false
158
+ #
159
+ # @param item [Object] The object to add
160
+ # @return [SortedSet, false]
161
+ def add?(item)
162
+ !include?(item) && add(item)
163
+ end
164
+
165
+ # Return a new `SortedSet` with `item` removed. If `item` is not a member of the set,
166
+ # return `self`.
167
+ #
168
+ # @example
169
+ # Hamster::SortedSet["A", "B", "C"].delete("B")
170
+ # # => Hamster::SortedSet["A", "C"]
171
+ #
172
+ # @param item [Object] The object to remove
173
+ # @return [SortedSet]
174
+ def delete(item)
175
+ catch :not_present do
176
+ node = @node.delete(item)
177
+ if node.empty? && node.natural_order?
178
+ return self.class.empty
179
+ else
180
+ return self.class.alloc(node)
181
+ end
182
+ end
183
+ self
184
+ end
185
+
186
+ # If `item` is a member of this `SortedSet`, return a new `SortedSet` with
187
+ # `item` removed. Otherwise, return `false`.
188
+ #
189
+ # @example
190
+ # Hamster::SortedSet["A", "B", "C"].delete?("B")
191
+ # # => Hamster::SortedSet["A", "C"]
192
+ # Hamster::SortedSet["A", "B", "C"].delete?("Z")
193
+ # # => false
194
+ #
195
+ # @param item [Object] The object to remove
196
+ # @return [SortedSet, false]
197
+ def delete?(item)
198
+ include?(item) && delete(item)
199
+ end
200
+
201
+ # Return a new `SortedSet` with the item at `index` removed. If the given `index`
202
+ # does not exist (if it is too high or too low), return `self`.
203
+ #
204
+ # @example
205
+ # Hamster::SortedSet["A", "B", "C", "D"].delete_at(2)
206
+ # # => Hamster::SortedSet["A", "B", "D"]
207
+ #
208
+ # @param index [Integer] The index to remove
209
+ # @return [SortedSet]
210
+ def delete_at(index)
211
+ (item = at(index)) ? delete(item) : self
212
+ end
213
+
214
+ # Retrieve the item at `index`. If there is none (either the provided index
215
+ # is too high or too low), return `nil`.
216
+ #
217
+ # @example
218
+ # s = Hamster::SortedSet["A", "B", "C", "D", "E", "F"]
219
+ # s.at(2) # => "C"
220
+ # s.at(-2) # => "E"
221
+ # s.at(6) # => nil
222
+ #
223
+ # @param index [Integer] The index to retrieve
224
+ # @return [Object]
225
+ def at(index)
226
+ index += @node.size if index < 0
227
+ return nil if index >= @node.size || index < 0
228
+ @node.at(index)
229
+ end
230
+
231
+ # Retrieve the value at `index`, or use the provided default value or block,
232
+ # or otherwise raise an `IndexError`.
233
+ #
234
+ # @overload fetch(index)
235
+ # Retrieve the value at the given index, or raise an `IndexError` if it is
236
+ # not found.
237
+ # @param index [Integer] The index to look up
238
+ # @overload fetch(index) { |index| ... }
239
+ # Retrieve the value at the given index, or call the optional
240
+ # code block (with the non-existent index) and get its return value.
241
+ # @yield [index] The index which does not exist
242
+ # @yieldreturn [Object] Object to return instead
243
+ # @param index [Integer] The index to look up
244
+ # @overload fetch(index, default)
245
+ # Retrieve the value at the given index, or else return the provided
246
+ # `default` value.
247
+ # @param index [Integer] The index to look up
248
+ # @param default [Object] Object to return if the key is not found
249
+ #
250
+ # @example
251
+ # s = Hamster::SortedSet["A", "B", "C", "D"]
252
+ # s.fetch(2) # => "C"
253
+ # s.fetch(-1) # => "D"
254
+ # s.fetch(4) # => IndexError: index 4 outside of sorted set bounds
255
+ # # With default value:
256
+ # s.fetch(2, "Z") # => "C"
257
+ # s.fetch(4, "Z") # => "Z"
258
+ # # With block:
259
+ # s.fetch(2) { |i| i * i } # => "C"
260
+ # s.fetch(4) { |i| i * i } # => 16
261
+ #
262
+ # @return [Object]
263
+ def fetch(index, default = (missing_default = true))
264
+ if index >= -@node.size && index < @node.size
265
+ at(index)
266
+ elsif block_given?
267
+ yield(index)
268
+ elsif !missing_default
269
+ default
270
+ else
271
+ raise IndexError, "index #{index} outside of sorted set bounds"
272
+ end
273
+ end
274
+
275
+ # Element reference. Return the item at a specific index, or a specified,
276
+ # contiguous range of items (as a new `SortedSet`).
277
+ #
278
+ # @overload set[index]
279
+ # Return the item at `index`.
280
+ # @param index [Integer] The index to retrieve.
281
+ # @overload set[start, length]
282
+ # Return a subset starting at index `start` and continuing for `length` elements.
283
+ # @param start [Integer] The index to start retrieving items from.
284
+ # @param length [Integer] The number of items to retrieve.
285
+ # @overload set[range]
286
+ # Return a subset specified by the given `range` of indices.
287
+ # @param range [Range] The range of indices to retrieve.
288
+ #
289
+ # @example
290
+ # s = Hamster::SortedSet["A", "B", "C", "D", "E", "F"]
291
+ # s[2] # => "C"
292
+ # s[-1] # => "D"
293
+ # s[6] # => nil
294
+ # s[2, 2] # => Hamster::SortedSet["C", "D"]
295
+ # s[2..3] # => Hamster::SortedSet["C", "D"]
296
+ #
297
+ # @return [Object]
298
+ def [](arg, length = (missing_length = true))
299
+ if missing_length
300
+ if arg.is_a?(Range)
301
+ from, to = arg.begin, arg.end
302
+ from += @node.size if from < 0
303
+ to += @node.size if to < 0
304
+ to += 1 if !arg.exclude_end?
305
+ length = to - from
306
+ length = 0 if length < 0
307
+ subsequence(from, length)
308
+ else
309
+ at(arg)
310
+ end
311
+ else
312
+ arg += @node.size if arg < 0
313
+ subsequence(arg, length)
314
+ end
315
+ end
316
+ alias :slice :[]
317
+
318
+ # Return a new `SortedSet` with only the elements at the given `indices`.
319
+ # If any of the `indices` do not exist, they will be skipped.
320
+ #
321
+ # @example
322
+ # s = Hamster::SortedSet["A", "B", "C", "D", "E", "F"]
323
+ # s.values_at(2, 4, 5) # => Hamster::SortedSet["C", "E", "F"]
324
+ #
325
+ # @param indices [Array] The indices to retrieve and gather into a new `SortedSet`
326
+ # @return [SortedSet]
327
+ def values_at(*indices)
328
+ indices.select! { |i| i >= -@node.size && i < @node.size }
329
+ self.class.new(indices.map! { |i| at(i) })
330
+ end
331
+
332
+ # Call the given block once for each item in the set, passing each
333
+ # item from first to last successively to the block.
334
+ #
335
+ # @example
336
+ # Hamster::SortedSet["A", "B", "C"].each { |e| puts "Element: #{e}" }
337
+ #
338
+ # Element: A
339
+ # Element: B
340
+ # Element: C
341
+ # # => Hamster::SortedSet["A", "B", "C"]
342
+ #
343
+ # @return [self]
344
+ def each(&block)
345
+ return @node.to_enum if not block_given?
346
+ @node.each(&block)
347
+ self
348
+ end
349
+
350
+ # Call the given block once for each item in the set, passing each
351
+ # item starting from the last, and counting back to the first, successively to
352
+ # the block.
353
+ #
354
+ # @example
355
+ # Hamster::SortedSet["A", "B", "C"].reverse_each { |e| puts "Element: #{e}" }
356
+ #
357
+ # Element: C
358
+ # Element: B
359
+ # Element: A
360
+ # # => Hamster::SortedSet["A", "B", "C"]
361
+ #
362
+ # @return [self]
363
+ def reverse_each(&block)
364
+ return @node.enum_for(:reverse_each) if not block_given?
365
+ @node.reverse_each(&block)
366
+ self
367
+ end
368
+
369
+ # Return the "lowest" element in this set, as determined by its sort order.
370
+ # Or, if a block is provided, use the block as a comparator to find the
371
+ # "lowest" element. (See `Enumerable#min`.)
372
+ #
373
+ # @example
374
+ # Hamster::SortedSet["A", "B", "C"].min # => "A"
375
+ #
376
+ # @return [Object]
377
+ def min
378
+ block_given? ? super : @node.min
379
+ end
380
+
381
+ # Return the "lowest" element in this set, as determined by its sort order.
382
+ # @return [Object]
383
+ def first
384
+ @node.min
385
+ end
386
+
387
+ # Return the "highest" element in this set, as determined by its sort order.
388
+ # Or, if a block is provided, use the block as a comparator to find the
389
+ # "highest" element. (See `Enumerable#max`.)
390
+ #
391
+ # @example
392
+ # Hamster::SortedSet["A", "B", "C"].max # => "C"
393
+ #
394
+ # @return [Object]
395
+ def max
396
+ block_given? ? super : @node.max
397
+ end
398
+
399
+ # Return the "highest" element in this set, as determined by its sort order.
400
+ # @return [Object]
401
+ def last
402
+ @node.max
403
+ end
404
+
405
+ # Return a new `SortedSet` containing all elements for which the given block returns
406
+ # true.
407
+ #
408
+ # @example
409
+ # Hamster::SortedSet["Bird", "Cow", "Elephant"].select { |e| e.size >= 4 }
410
+ # # => Hamster::SortedSet["Bird", "Elephant"]
411
+ #
412
+ # @return [SortedSet]
413
+ def select
414
+ return enum_for(:select) unless block_given?
415
+ items_to_delete = []
416
+ each { |item| items_to_delete << item unless yield(item) }
417
+ derive_new_sorted_set(@node.bulk_delete(items_to_delete))
418
+ end
419
+ alias :find_all :select
420
+ alias :keep_if :select
421
+
422
+ # Invoke the given block once for each item in the set, and return a new
423
+ # `SortedSet` containing the values returned by the block.
424
+ #
425
+ # @example
426
+ # Hamster::SortedSet[1, 2, 3].map { |e| -(e * e) }
427
+ # # => Hamster::SortedSet[-9, -4, -1]
428
+ #
429
+ # @return [SortedSet]
430
+ def map
431
+ return enum_for(:map) if not block_given?
432
+ return self if empty?
433
+ self.class.alloc(@node.from_items(super))
434
+ end
435
+ alias :collect :map
436
+
437
+ # Return `true` if the given item is present in this `SortedSet`. More precisely,
438
+ # return `true` if an object which compares as "equal" using this set's
439
+ # comparator is present.
440
+ #
441
+ # @example
442
+ # Hamster::SortedSet["A", "B", "C"].include?("B") # => true
443
+ #
444
+ # @param item [Object] The object to check for
445
+ # @return [Boolean]
446
+ def include?(item)
447
+ @node.include?(item)
448
+ end
449
+ alias :member? :include?
450
+
451
+ # Return a new `SortedSet` with the same items, but a sort order determined by
452
+ # the given block.
453
+ #
454
+ # @example
455
+ # Hamster::SortedSet["Bird", "Cow", "Elephant"].sort { |a, b| a.size <=> b.size }
456
+ # # => Hamster::SortedSet["Cow", "Bird", "Elephant"]
457
+ # Hamster::SortedSet["Bird", "Cow", "Elephant"].sort_by { |e| e.size }
458
+ # # => Hamster::SortedSet["Cow", "Bird", "Elephant"]
459
+ #
460
+ # @return [SortedSet]
461
+ def sort(&block)
462
+ if block
463
+ self.class.new(self.to_a, &block)
464
+ else
465
+ self.class.new(self.to_a.sort)
466
+ end
467
+ end
468
+ alias :sort_by :sort
469
+
470
+ # Find the index of a given object or an element that satisfies the given
471
+ # block.
472
+ #
473
+ # @overload find_index(obj)
474
+ # Return the index of the first object in this set which is equal to
475
+ # `obj`. Rather than using `#==`, we use `#<=>` (or our comparator block)
476
+ # for comparisons. This means we can find the index in O(log N) time,
477
+ # rather than O(N).
478
+ # @param obj [Object] The object to search for
479
+ # @overload find_index { |element| ... }
480
+ # Return the index of the first object in this sorted set for which the
481
+ # block returns to true. This is takes O(N) time.
482
+ # @yield [Object] An element in the sorted set
483
+ # @yieldreturn [Boolean] True if this is element matches
484
+ #
485
+ # @example
486
+ # s = Hamster::SortedSet[2, 4, 6, 8, 10]
487
+ # s.find_index(8) # => 3
488
+ # s.find_index { |e| e > 7 } # => 3
489
+ #
490
+ # @return [Integer] The index of the object, or `nil` if not found.
491
+ def find_index(obj = (missing_obj = true), &block)
492
+ if !missing_obj
493
+ # Enumerable provides a default implementation, but this is more efficient
494
+ node = @node
495
+ index = node.left.size
496
+ while !node.empty?
497
+ direction = node.direction(obj)
498
+ if direction > 0
499
+ node = node.right
500
+ index += (node.left.size + 1)
501
+ elsif direction < 0
502
+ node = node.left
503
+ index -= (node.right.size + 1)
504
+ else
505
+ return index
506
+ end
507
+ end
508
+ nil
509
+ else
510
+ super(&block)
511
+ end
512
+ end
513
+ alias :index :find_index
514
+
515
+ # Drop the first `n` elements and return the rest in a new `SortedSet`.
516
+ #
517
+ # @example
518
+ # Hamster::SortedSet["A", "B", "C", "D", "E", "F"].drop(2)
519
+ # # => Hamster::SortedSet["C", "D", "E", "F"]
520
+ #
521
+ # @param n [Integer] The number of elements to remove
522
+ # @return [SortedSet]
523
+ def drop(n)
524
+ derive_new_sorted_set(@node.drop(n))
525
+ end
526
+
527
+ # Return only the first `n` elements in a new `SortedSet`.
528
+ #
529
+ # @example
530
+ # Hamster::SortedSet["A", "B", "C", "D", "E", "F"].take(4)
531
+ # # => Hamster::SortedSet["A", "B", "C", "D"]
532
+ #
533
+ # @param n [Integer] The number of elements to retain
534
+ # @return [SortedSet]
535
+ def take(n)
536
+ derive_new_sorted_set(@node.take(n))
537
+ end
538
+
539
+ # Drop elements up to, but not including, the first element for which the
540
+ # block returns `nil` or `false`. Gather the remaining elements into a new
541
+ # `SortedSet`. If no block is given, an `Enumerator` is returned instead.
542
+ #
543
+ # @example
544
+ # Hamster::SortedSet[2, 4, 6, 7, 8, 9].drop_while { |e| e.even? }
545
+ # # => Hamster::SortedSet[7, 8, 9]
546
+ #
547
+ # @return [SortedSet, Enumerator]
548
+ def drop_while
549
+ return enum_for(:drop_while) if not block_given?
550
+ n = 0
551
+ each do |item|
552
+ break unless yield item
553
+ n += 1
554
+ end
555
+ drop(n)
556
+ end
557
+
558
+ # Gather elements up to, but not including, the first element for which the
559
+ # block returns `nil` or `false`, and return them in a new `SortedSet`. If no block
560
+ # is given, an `Enumerator` is returned instead.
561
+ #
562
+ # @example
563
+ # Hamster::SortedSet[2, 4, 6, 7, 8, 9].take_while { |e| e.even? }
564
+ # # => Hamster::SortedSet[2, 4, 6]
565
+ #
566
+ # @return [SortedSet, Enumerator]
567
+ def take_while
568
+ return enum_for(:take_while) if not block_given?
569
+ n = 0
570
+ each do |item|
571
+ break unless yield item
572
+ n += 1
573
+ end
574
+ take(n)
575
+ end
576
+
577
+ # Return a new `SortedSet` which contains all the members of both this set and `other`.
578
+ # `other` can be any `Enumerable` object.
579
+ #
580
+ # @example
581
+ # Hamster::SortedSet[1, 2] | Hamster::SortedSet[2, 3]
582
+ # # => Hamster::SortedSet[1, 2, 3]
583
+ #
584
+ # @param other [Enumerable] The collection to merge with
585
+ # @return [SortedSet]
586
+ def union(other)
587
+ self.class.alloc(@node.bulk_insert(other))
588
+ end
589
+ alias :| :union
590
+ alias :+ :union
591
+ alias :merge :union
592
+
593
+ # Return a new `SortedSet` which contains all the items which are members of both
594
+ # this set and `other`. `other` can be any `Enumerable` object.
595
+ #
596
+ # @example
597
+ # Hamster::SortedSet[1, 2] & Hamster::SortedSet[2, 3]
598
+ # # => Hamster::SortedSet[2]
599
+ #
600
+ # @param other [Enumerable] The collection to intersect with
601
+ # @return [SortedSet]
602
+ def intersection(other)
603
+ self.class.alloc(@node.keep_only(other))
604
+ end
605
+ alias :& :intersection
606
+
607
+ # Return a new `SortedSet` with all the items in `other` removed. `other` can be
608
+ # any `Enumerable` object.
609
+ #
610
+ # @example
611
+ # Hamster::SortedSet[1, 2] - Hamster::SortedSet[2, 3]
612
+ # # => Hamster::SortedSet[1]
613
+ #
614
+ # @param other [Enumerable] The collection to subtract from this set
615
+ # @return [SortedSet]
616
+ def difference(other)
617
+ self.class.alloc(@node.bulk_delete(other))
618
+ end
619
+ alias :subtract :difference
620
+ alias :- :difference
621
+
622
+ # Return a new `SortedSet` with all the items which are members of this
623
+ # set or of `other`, but not both. `other` can be any `Enumerable` object.
624
+ #
625
+ # @example
626
+ # Hamster::SortedSet[1, 2] ^ Hamster::SortedSet[2, 3]
627
+ # # => Hamster::SortedSet[1, 3]
628
+ #
629
+ # @param other [Enumerable] The collection to take the exclusive disjunction of
630
+ # @return [SortedSet]
631
+ def exclusion(other)
632
+ ((self | other) - (self & other))
633
+ end
634
+ alias :^ :exclusion
635
+
636
+ # Return `true` if all items in this set are also in `other`.
637
+ #
638
+ # @example
639
+ # Hamster::SortedSet[2, 3].subset?(Hamster::SortedSet[1, 2, 3]) # => true
640
+ #
641
+ # @param other [Enumerable]
642
+ # @return [Boolean]
643
+ def subset?(other)
644
+ return false if other.size < size
645
+ all? { |item| other.include?(item) }
646
+ end
647
+
648
+ # Return `true` if all items in `other` are also in this set.
649
+ #
650
+ # @example
651
+ # Hamster::SortedSet[1, 2, 3].superset?(Hamster::SortedSet[2, 3]) # => true
652
+ #
653
+ # @param other [Enumerable]
654
+ # @return [Boolean]
655
+ def superset?(other)
656
+ other.subset?(self)
657
+ end
658
+
659
+ # Returns `true` if `other` contains all the items in this set, plus at least
660
+ # one item which is not in this set.
661
+ #
662
+ # @example
663
+ # Hamster::SortedSet[2, 3].proper_subset?(Hamster::SortedSet[1, 2, 3]) # => true
664
+ # Hamster::SortedSet[1, 2, 3].proper_subset?(Hamster::SortedSet[1, 2, 3]) # => false
665
+ #
666
+ # @param other [Enumerable]
667
+ # @return [Boolean]
668
+ def proper_subset?(other)
669
+ return false if other.size <= size
670
+ all? { |item| other.include?(item) }
671
+ end
672
+
673
+ # Returns `true` if this set contains all the items in `other`, plus at least
674
+ # one item which is not in `other`.
675
+ #
676
+ # @example
677
+ # Hamster::SortedSet[1, 2, 3].proper_superset?(Hamster::SortedSet[2, 3]) # => true
678
+ # Hamster::SortedSet[1, 2, 3].proper_superset?(Hamster::SortedSet[1, 2, 3]) # => false
679
+ #
680
+ # @param other [Enumerable]
681
+ # @return [Boolean]
682
+ def proper_superset?(other)
683
+ other.proper_subset?(self)
684
+ end
685
+
686
+ # Return `true` if this set and `other` do not share any items.
687
+ #
688
+ # @example
689
+ # Hamster::SortedSet[1, 2].disjoint?(Hamster::SortedSet[3, 4]) # => true
690
+ #
691
+ # @param other [Enumerable]
692
+ # @return [Boolean]
693
+ def disjoint?(other)
694
+ if size < other.size
695
+ each { |item| return false if other.include?(item) }
696
+ else
697
+ other.each { |item| return false if include?(item) }
698
+ end
699
+ true
700
+ end
701
+
702
+ # Return `true` if this set and `other` have at least one item in common.
703
+ #
704
+ # @example
705
+ # Hamster::SortedSet[1, 2].intersect?(Hamster::SortedSet[2, 3]) # => true
706
+ #
707
+ # @param other [Enumerable]
708
+ # @return [Boolean]
709
+ def intersect?(other)
710
+ !disjoint?(other)
711
+ end
712
+
713
+ alias :group :group_by
714
+ alias :classify :group_by
715
+
716
+ # With a block, yield all the items which are greater than `item` (as defined
717
+ # by the set's comparator). Otherwise, return them as a new `SortedSet`.
718
+ #
719
+ # @example
720
+ # s = Hamster::SortedSet[2, 4, 6, 8, 10]
721
+ # s.above(6)
722
+ # # => Hamster::SortedSet[8, 10]
723
+ #
724
+ # s.above(6) { |e| puts "Element: #{e}" }
725
+ #
726
+ # Element: 8
727
+ # Element: 10
728
+ # # => nil
729
+ #
730
+ # @param item [Object]
731
+ def above(item, &block)
732
+ if block_given?
733
+ @node.each_greater(item, false, &block)
734
+ else
735
+ self.class.alloc(@node.suffix(item, false))
736
+ end
737
+ end
738
+
739
+ # With a block, yield all the items which are less than `item` (as defined
740
+ # by the set's comparator). Otherwise, return them as a new `SortedSet`.
741
+ #
742
+ # @example
743
+ # s = Hamster::SortedSet[2, 4, 6, 8, 10]
744
+ # s.below(6)
745
+ # # => Hamster::SortedSet[2, 4]
746
+ #
747
+ # s.below(6) { |e| puts "Element: #{e}" }
748
+ #
749
+ # Element: 2
750
+ # Element: 4
751
+ # # => nil
752
+ #
753
+ # @param item [Object]
754
+ def below(item, &block)
755
+ if block_given?
756
+ @node.each_less(item, false, &block)
757
+ else
758
+ self.class.alloc(@node.prefix(item, false))
759
+ end
760
+ end
761
+
762
+ # With a block, yield all the items which are equal or greater than `item`
763
+ # (as determined by the set's comparator). Otherwise, return them as a new
764
+ # `SortedSet`.
765
+ #
766
+ # @example
767
+ # s = Hamster::SortedSet[2, 4, 6, 8, 10]
768
+ # s.from(6)
769
+ # # => Hamster::SortedSet[6, 8, 10]
770
+ #
771
+ # s.from(6) { |e| puts "Element: #{e}" }
772
+ #
773
+ # Element: 6
774
+ # Element: 8
775
+ # Element: 10
776
+ # # => nil
777
+ #
778
+ # @param item [Object]
779
+ def from(item, &block)
780
+ if block_given?
781
+ @node.each_greater(item, true, &block)
782
+ else
783
+ self.class.alloc(@node.suffix(item, true))
784
+ end
785
+ end
786
+
787
+ # With a block, yield all the items which are equal or less than `item` (as
788
+ # defined by the set's comparator). Otherwise, return them as a new
789
+ # `SortedSet`.
790
+ #
791
+ # @example
792
+ # s = Hamster::SortedSet[2, 4, 6, 8, 10]
793
+ # s.up_to(6)
794
+ # # => Hamster::SortedSet[2, 4, 6]
795
+ #
796
+ # s.up_to(6) { |e| puts "Element: #{e}" }
797
+ #
798
+ # Element: 2
799
+ # Element: 4
800
+ # Element: 6
801
+ # # => nil
802
+ #
803
+ # @param item [Object]
804
+ def up_to(item, &block)
805
+ if block_given?
806
+ @node.each_less(item, true, &block)
807
+ else
808
+ self.class.alloc(@node.prefix(item, true))
809
+ end
810
+ end
811
+
812
+ # With a block, yield all the items which are equal or higher than `from` and
813
+ # equal or less than `to` (as determined by the set's comparator). Otherwise,
814
+ # return the specified range of items as a new `SortedSet`.
815
+ #
816
+ # @example
817
+ # s = Hamster::SortedSet[2, 4, 6, 7, 8, 9]
818
+ # s.between(5, 8)
819
+ # # => Hamster::SortedSet[6, 7, 8]
820
+ #
821
+ # s.between(5, 8) { |e| puts "Element: #{e}" }
822
+ #
823
+ # Element: 6
824
+ # Element: 7
825
+ # Element: 8
826
+ # # => nil
827
+ #
828
+ # @param from [Object]
829
+ # @param to [Object]
830
+ def between(from, to, &block)
831
+ if block_given?
832
+ @node.each_between(from, to, &block)
833
+ else
834
+ self.class.alloc(@node.between(from, to))
835
+ end
836
+ end
837
+
838
+ # Return a randomly chosen item from this set. If the set is empty, return `nil`.
839
+ #
840
+ # @example
841
+ # Hamster::SortedSet[1, 2, 3, 4, 5].sample # => 2
842
+ #
843
+ # @return [Object]
844
+ def sample
845
+ @node.at(rand(@node.size))
846
+ end
847
+
848
+ # Return an empty `SortedSet` instance, of the same class as this one. Useful if you
849
+ # have multiple subclasses of `SortedSet` and want to treat them polymorphically.
850
+ #
851
+ # @return [SortedSet]
852
+ def clear
853
+ if @node.natural_order?
854
+ self.class.empty
855
+ else
856
+ self.class.alloc(@node.clear)
857
+ end
858
+ end
859
+
860
+ # Return true if `other` has the same type and contents as this `SortedSet`.
861
+ #
862
+ # @param other [Object] The object to compare with
863
+ # @return [Boolean]
864
+ def eql?(other)
865
+ return true if other.equal?(self)
866
+ return false if not instance_of?(other.class)
867
+ return false if size != other.size
868
+ a, b = self.to_enum, other.to_enum
869
+ while true
870
+ return false if !a.next.eql?(b.next)
871
+ end
872
+ rescue StopIteration
873
+ true
874
+ end
875
+
876
+ # See `Object#hash`.
877
+ # @return [Integer]
878
+ def hash
879
+ reduce(0) { |hash, item| (hash << 5) - hash + item.hash }
880
+ end
881
+
882
+ # @return [::Array]
883
+ # @private
884
+ def marshal_dump
885
+ if @node.natural_order?
886
+ to_a
887
+ else
888
+ raise TypeError, "can't dump SortedSet with custom sort order"
889
+ end
890
+ end
891
+
892
+ # @private
893
+ def marshal_load(array)
894
+ initialize(array)
895
+ end
896
+
897
+ private
898
+
899
+ def subsequence(from, length)
900
+ return nil if from > @node.size || from < 0 || length < 0
901
+ length = @node.size - from if @node.size < from + length
902
+ if length == 0
903
+ if @node.natural_order?
904
+ return self.class.empty
905
+ else
906
+ return self.class.alloc(@node.clear)
907
+ end
908
+ end
909
+ self.class.alloc(@node.slice(from, length))
910
+ end
911
+
912
+ # Return a new `SortedSet` which is derived from this one, using a modified
913
+ # {AVLNode}. The new `SortedSet` will retain the existing comparator, if
914
+ # there is one.
915
+ def derive_new_sorted_set(node)
916
+ if node.equal?(@node)
917
+ self
918
+ elsif node.empty?
919
+ clear
920
+ else
921
+ self.class.alloc(node)
922
+ end
923
+ end
924
+
925
+ # @private
926
+ class AVLNode
927
+ def self.from_items(items, comparator, from = 0, to = items.size-1) # items must be sorted
928
+ size = to - from + 1
929
+ if size >= 3
930
+ middle = (to + from) / 2
931
+ AVLNode.new(items[middle], comparator, AVLNode.from_items(items, comparator, from, middle-1), AVLNode.from_items(items, comparator, middle+1, to))
932
+ elsif size == 2
933
+ empty = AVLNode::Empty.new(comparator)
934
+ AVLNode.new(items[from], comparator, empty, AVLNode.new(items[from+1], comparator, empty, empty))
935
+ elsif size == 1
936
+ empty = AVLNode::Empty.new(comparator)
937
+ AVLNode.new(items[from], comparator, empty, empty)
938
+ elsif size == 0
939
+ AVLNode::Empty.new(comparator)
940
+ end
941
+ end
942
+
943
+ def initialize(item, comparator, left, right)
944
+ @item, @comparator, @left, @right = item, comparator, left, right
945
+ @height = ((right.height > left.height) ? right.height : left.height) + 1
946
+ @size = right.size + left.size + 1
947
+ end
948
+ attr_reader :item, :left, :right, :height, :size
949
+
950
+ def from_items(items)
951
+ AVLNode.from_items(items.sort(&@comparator), @comparator)
952
+ end
953
+
954
+ def natural_order?
955
+ false
956
+ end
957
+
958
+ def empty?
959
+ false
960
+ end
961
+
962
+ def clear
963
+ AVLNode::Empty.new(@comparator)
964
+ end
965
+
966
+ def derive(item, left, right)
967
+ AVLNode.new(item, @comparator, left, right)
968
+ end
969
+
970
+ def insert(item)
971
+ dir = direction(item)
972
+ if dir == 0
973
+ throw :present
974
+ elsif dir > 0
975
+ rebalance_right(@left, @right.insert(item))
976
+ else
977
+ rebalance_left(@left.insert(item), @right)
978
+ end
979
+ end
980
+
981
+ def bulk_insert(items)
982
+ return self if items.empty?
983
+ if items.size == 1
984
+ catch :present do
985
+ return insert(items.first)
986
+ end
987
+ return self
988
+ end
989
+ left, right = partition(items)
990
+
991
+ if right.size > left.size
992
+ rebalance_right(@left.bulk_insert(left), @right.bulk_insert(right))
993
+ else
994
+ rebalance_left(@left.bulk_insert(left), @right.bulk_insert(right))
995
+ end
996
+ end
997
+
998
+ def delete(item)
999
+ dir = direction(item)
1000
+ if dir == 0
1001
+ if @right.empty?
1002
+ return @left # replace this node with its only child
1003
+ elsif @left.empty?
1004
+ return @right # likewise
1005
+ end
1006
+
1007
+ if balance > 0
1008
+ # tree is leaning to the left. replace with highest node on that side
1009
+ replace_with = @left.max
1010
+ derive(replace_with, @left.delete(replace_with), @right)
1011
+ else
1012
+ # tree is leaning to the right. replace with lowest node on that side
1013
+ replace_with = @right.min
1014
+ derive(replace_with, @left, @right.delete(replace_with))
1015
+ end
1016
+ elsif dir > 0
1017
+ rebalance_left(@left, @right.delete(item))
1018
+ else
1019
+ rebalance_right(@left.delete(item), @right)
1020
+ end
1021
+ end
1022
+
1023
+ def bulk_delete(items)
1024
+ return self if items.empty?
1025
+ if items.size == 1
1026
+ catch :not_present do
1027
+ return delete(items.first)
1028
+ end
1029
+ return self
1030
+ end
1031
+
1032
+ left, right, keep_item = [], [], true
1033
+ items.each do |item|
1034
+ dir = direction(item)
1035
+ if dir > 0
1036
+ right << item
1037
+ elsif dir < 0
1038
+ left << item
1039
+ else
1040
+ keep_item = false
1041
+ end
1042
+ end
1043
+
1044
+ left = @left.bulk_delete(left)
1045
+ right = @right.bulk_delete(right)
1046
+ finish_removal(keep_item, left, right)
1047
+ end
1048
+
1049
+ def keep_only(items)
1050
+ return clear if items.empty?
1051
+
1052
+ left, right, keep_item = [], [], false
1053
+ items.each do |item|
1054
+ dir = direction(item)
1055
+ if dir > 0
1056
+ right << item
1057
+ elsif dir < 0
1058
+ left << item
1059
+ else
1060
+ keep_item = true
1061
+ end
1062
+ end
1063
+
1064
+ left = @left.keep_only(left)
1065
+ right = @right.keep_only(right)
1066
+ finish_removal(keep_item, left, right)
1067
+ end
1068
+
1069
+ def finish_removal(keep_item, left, right)
1070
+ # deletion of items may have occurred on left and right sides
1071
+ # now we may also need to delete the current item
1072
+ if keep_item
1073
+ rebalance(left, right) # no need to delete the current item
1074
+ elsif left.empty?
1075
+ right
1076
+ elsif right.empty?
1077
+ left
1078
+ elsif left.height > right.height
1079
+ replace_with = left.max
1080
+ derive(replace_with, left.delete(replace_with), right)
1081
+ else
1082
+ replace_with = right.min
1083
+ derive(replace_with, left, right.delete(replace_with))
1084
+ end
1085
+ end
1086
+
1087
+ def prefix(item, inclusive)
1088
+ dir = direction(item)
1089
+ if dir > 0 || (inclusive && dir == 0)
1090
+ rebalance_left(@left, @right.prefix(item, inclusive))
1091
+ else
1092
+ @left.prefix(item, inclusive)
1093
+ end
1094
+ end
1095
+
1096
+ def suffix(item, inclusive)
1097
+ dir = direction(item)
1098
+ if dir < 0 || (inclusive && dir == 0)
1099
+ rebalance_right(@left.suffix(item, inclusive), @right)
1100
+ else
1101
+ @right.suffix(item, inclusive)
1102
+ end
1103
+ end
1104
+
1105
+ def between(from, to)
1106
+ if direction(from) > 0 # all on the right
1107
+ @right.between(from, to)
1108
+ elsif direction(to) < 0 # all on the left
1109
+ @left.between(from, to)
1110
+ else
1111
+ left = @left.suffix(from, true)
1112
+ right = @right.prefix(to, true)
1113
+ rebalance(left, right)
1114
+ end
1115
+ end
1116
+
1117
+ def each_less(item, inclusive, &block)
1118
+ dir = direction(item)
1119
+ if dir > 0 || (inclusive && dir == 0)
1120
+ @left.each(&block)
1121
+ yield @item
1122
+ @right.each_less(item, inclusive, &block)
1123
+ else
1124
+ @left.each_less(item, inclusive, &block)
1125
+ end
1126
+ end
1127
+
1128
+ def each_greater(item, inclusive, &block)
1129
+ dir = direction(item)
1130
+ if dir < 0 || (inclusive && dir == 0)
1131
+ @left.each_greater(item, inclusive, &block)
1132
+ yield @item
1133
+ @right.each(&block)
1134
+ else
1135
+ @right.each_greater(item, inclusive, &block)
1136
+ end
1137
+ end
1138
+
1139
+ def each_between(from, to, &block)
1140
+ if direction(from) > 0 # all on the right
1141
+ @right.each_between(from, to, &block)
1142
+ elsif direction(to) < 0 # all on the left
1143
+ @left.each_between(from, to, &block)
1144
+ else
1145
+ @left.each_greater(from, true, &block)
1146
+ yield @item
1147
+ @right.each_less(to, true, &block)
1148
+ end
1149
+ end
1150
+
1151
+ def each(&block)
1152
+ @left.each(&block)
1153
+ yield @item
1154
+ @right.each(&block)
1155
+ end
1156
+
1157
+ def reverse_each(&block)
1158
+ @right.reverse_each(&block)
1159
+ yield @item
1160
+ @left.reverse_each(&block)
1161
+ end
1162
+
1163
+ def drop(n)
1164
+ if n >= @size
1165
+ clear
1166
+ elsif n <= 0
1167
+ self
1168
+ elsif @left.size >= n
1169
+ rebalance_right(@left.drop(n), @right)
1170
+ elsif @left.size + 1 == n
1171
+ @right
1172
+ else
1173
+ @right.drop(n - @left.size - 1)
1174
+ end
1175
+ end
1176
+
1177
+ def take(n)
1178
+ if n >= @size
1179
+ self
1180
+ elsif n <= 0
1181
+ clear
1182
+ elsif @left.size >= n
1183
+ @left.take(n)
1184
+ else
1185
+ rebalance_left(@left, @right.take(n - @left.size - 1))
1186
+ end
1187
+ end
1188
+
1189
+ def include?(item)
1190
+ dir = direction(item)
1191
+ if dir == 0
1192
+ true
1193
+ elsif dir > 0
1194
+ @right.include?(item)
1195
+ else
1196
+ @left.include?(item)
1197
+ end
1198
+ end
1199
+
1200
+ def at(index)
1201
+ if index < @left.size
1202
+ @left.at(index)
1203
+ elsif index > @left.size
1204
+ @right.at(index - @left.size - 1)
1205
+ else
1206
+ @item
1207
+ end
1208
+ end
1209
+
1210
+ def max
1211
+ @right.empty? ? @item : @right.max
1212
+ end
1213
+
1214
+ def min
1215
+ @left.empty? ? @item : @left.min
1216
+ end
1217
+
1218
+ def balance
1219
+ @left.height - @right.height
1220
+ end
1221
+
1222
+ def slice(from, length)
1223
+ if length <= 0
1224
+ clear
1225
+ elsif from + length <= @left.size
1226
+ @left.slice(from, length)
1227
+ elsif from > @left.size
1228
+ @right.slice(from - @left.size - 1, length)
1229
+ else
1230
+ left = @left.slice(from, @left.size - from)
1231
+ right = @right.slice(0, from + length - @left.size - 1)
1232
+ rebalance(left, right)
1233
+ end
1234
+ end
1235
+
1236
+ def partition(items)
1237
+ left, right = [], []
1238
+ items.each do |item|
1239
+ dir = direction(item)
1240
+ if dir > 0
1241
+ right << item
1242
+ elsif dir < 0
1243
+ left << item
1244
+ end
1245
+ end
1246
+ [left, right]
1247
+ end
1248
+
1249
+ def rebalance(left, right)
1250
+ if left.height > right.height
1251
+ rebalance_left(left, right)
1252
+ else
1253
+ rebalance_right(left, right)
1254
+ end
1255
+ end
1256
+
1257
+ def rebalance_left(left, right)
1258
+ # the tree might be unbalanced to the left (paths on the left too long)
1259
+ balance = left.height - right.height
1260
+ if balance >= 2
1261
+ if left.balance > 0
1262
+ # single right rotation
1263
+ derive(left.item, left.left, derive(@item, left.right, right))
1264
+ else
1265
+ # left rotation, then right
1266
+ derive(left.right.item, derive(left.item, left.left, left.right.left), derive(@item, left.right.right, right))
1267
+ end
1268
+ else
1269
+ derive(@item, left, right)
1270
+ end
1271
+ end
1272
+
1273
+ def rebalance_right(left, right)
1274
+ # the tree might be unbalanced to the right (paths on the right too long)
1275
+ balance = left.height - right.height
1276
+ if balance <= -2
1277
+ if right.balance > 0
1278
+ # right rotation, then left
1279
+ derive(right.left.item, derive(@item, left, right.left.left), derive(right.item, right.left.right, right.right))
1280
+ else
1281
+ # single left rotation
1282
+ derive(right.item, derive(@item, left, right.left), right.right)
1283
+ end
1284
+ else
1285
+ derive(@item, left, right)
1286
+ end
1287
+ end
1288
+
1289
+ def direction(item)
1290
+ @comparator.call(item, @item)
1291
+ end
1292
+
1293
+ # @private
1294
+ class Empty
1295
+ def initialize(comparator); @comparator = comparator; end
1296
+ def natural_order?; false; end
1297
+ def left; self; end
1298
+ def right; self; end
1299
+ def height; 0; end
1300
+ def size; 0; end
1301
+ def min; nil; end
1302
+ def max; nil; end
1303
+ def each; end
1304
+ def reverse_each; end
1305
+ def at(index); nil; end
1306
+ def insert(item)
1307
+ AVLNode.new(item, @comparator, self, self)
1308
+ end
1309
+ def bulk_insert(items)
1310
+ items = items.to_a if !items.is_a?(Array)
1311
+ AVLNode.from_items(items.sort(&@comparator), @comparator)
1312
+ end
1313
+ def bulk_delete(items); self; end
1314
+ def keep_only(items); self; end
1315
+ def delete(item); throw :not_present; end
1316
+ def include?(item); false; end
1317
+ def prefix(item, inclusive); self; end
1318
+ def suffix(item, inclusive); self; end
1319
+ def between(from, to); self; end
1320
+ def each_greater(item, inclusive); end
1321
+ def each_less(item, inclusive); end
1322
+ def each_between(item, inclusive); end
1323
+ def drop(n); self; end
1324
+ def take(n); self; end
1325
+ def empty?; true; end
1326
+ def slice(from, length); self; end
1327
+ end
1328
+ end
1329
+
1330
+ # @private
1331
+ # AVL node which does not use a comparator function; it keeps items sorted
1332
+ # in their natural order
1333
+ class PlainAVLNode < AVLNode
1334
+ def self.from_items(items, from = 0, to = items.size-1) # items must be sorted
1335
+ size = to - from + 1
1336
+ if size >= 3
1337
+ middle = (to + from) / 2
1338
+ PlainAVLNode.new(items[middle], PlainAVLNode.from_items(items, from, middle-1), PlainAVLNode.from_items(items, middle+1, to))
1339
+ elsif size == 2
1340
+ PlainAVLNode.new(items[from], PlainAVLNode::EmptyNode, PlainAVLNode.new(items[from+1], PlainAVLNode::EmptyNode, PlainAVLNode::EmptyNode))
1341
+ elsif size == 1
1342
+ PlainAVLNode.new(items[from], PlainAVLNode::EmptyNode, PlainAVLNode::EmptyNode)
1343
+ elsif size == 0
1344
+ PlainAVLNode::EmptyNode
1345
+ end
1346
+ end
1347
+
1348
+ def initialize(item, left, right)
1349
+ @item, @left, @right = item, left, right
1350
+ @height = ((right.height > left.height) ? right.height : left.height) + 1
1351
+ @size = right.size + left.size + 1
1352
+ end
1353
+ attr_reader :item, :left, :right, :height, :size
1354
+
1355
+ def from_items(items)
1356
+ PlainAVLNode.from_items(items.sort)
1357
+ end
1358
+
1359
+ def natural_order?
1360
+ true
1361
+ end
1362
+
1363
+ def clear
1364
+ PlainAVLNode::EmptyNode
1365
+ end
1366
+
1367
+ def derive(item, left, right)
1368
+ PlainAVLNode.new(item, left, right)
1369
+ end
1370
+
1371
+ def direction(item)
1372
+ item <=> @item
1373
+ end
1374
+
1375
+ # @private
1376
+ class Empty < AVLNode::Empty
1377
+ def initialize; end
1378
+ def natural_order?; true; end
1379
+ def insert(item)
1380
+ PlainAVLNode.new(item, self, self)
1381
+ end
1382
+ def bulk_insert(items)
1383
+ items = items.to_a if !items.is_a?(Array)
1384
+ PlainAVLNode.from_items(items.sort)
1385
+ end
1386
+ end
1387
+
1388
+ EmptyNode = PlainAVLNode::Empty.new
1389
+ end
1390
+ end
1391
+
1392
+ # The canonical empty `SortedSet`. Returned by `Hamster.sorted_set` and `SortedSet[]`
1393
+ # when invoked with no arguments; also returned by `SortedSet.empty`. Prefer using
1394
+ # this one rather than creating many empty sorted sets using `SortedSet.new`.
1395
+ #
1396
+ EmptySortedSet = Hamster::SortedSet.empty
1397
+ end