hamster 0.4.3 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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