hamster 1.0.1.pre.rc2 → 1.0.1.pre.rc3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (482) hide show
  1. checksums.yaml +4 -4
  2. data/lib/hamster.rb +2 -2
  3. data/lib/hamster/core_ext.rb +0 -1
  4. data/lib/hamster/core_ext/enumerable.rb +17 -17
  5. data/lib/hamster/core_ext/io.rb +15 -17
  6. data/lib/hamster/deque.rb +229 -0
  7. data/lib/hamster/enumerable.rb +147 -105
  8. data/lib/hamster/experimental/mutable_queue.rb +2 -2
  9. data/lib/hamster/hash.rb +488 -82
  10. data/lib/hamster/immutable.rb +4 -0
  11. data/lib/hamster/list.rb +839 -196
  12. data/lib/hamster/read_copy_update.rb +1 -0
  13. data/lib/hamster/set.rb +317 -54
  14. data/lib/hamster/sorted_set.rb +1014 -0
  15. data/lib/hamster/trie.rb +67 -47
  16. data/lib/hamster/undefined.rb +1 -3
  17. data/lib/hamster/vector.rb +989 -76
  18. data/lib/hamster/version.rb +1 -1
  19. data/spec/{hamster → lib/hamster}/core_ext/array_spec.rb +1 -1
  20. data/spec/{hamster → lib/hamster}/core_ext/enumerable_spec.rb +4 -0
  21. data/spec/{hamster → lib/hamster}/core_ext/io_spec.rb +0 -0
  22. data/spec/lib/hamster/deque/clear_spec.rb +34 -0
  23. data/spec/lib/hamster/deque/construction_spec.rb +30 -0
  24. data/spec/lib/hamster/deque/copying_spec.rb +20 -0
  25. data/spec/lib/hamster/deque/dequeue_spec.rb +27 -0
  26. data/spec/lib/hamster/deque/empty_spec.rb +42 -0
  27. data/spec/{hamster/queue → lib/hamster/deque}/enqueue_spec.rb +7 -10
  28. data/spec/lib/hamster/deque/head_spec.rb +20 -0
  29. data/spec/lib/hamster/deque/inspect_spec.rb +24 -0
  30. data/spec/lib/hamster/deque/last_spec.rb +20 -0
  31. data/spec/lib/hamster/deque/marshal_spec.rb +34 -0
  32. data/spec/lib/hamster/deque/new_spec.rb +44 -0
  33. data/spec/lib/hamster/deque/pop_spec.rb +25 -0
  34. data/spec/lib/hamster/deque/random_modification_spec.rb +34 -0
  35. data/spec/{hamster/queue → lib/hamster/deque}/size_spec.rb +4 -9
  36. data/spec/lib/hamster/deque/to_a_spec.rb +27 -0
  37. data/spec/{hamster/queue → lib/hamster/deque}/to_ary_spec.rb +6 -6
  38. data/spec/lib/hamster/deque/to_list_spec.rb +26 -0
  39. data/spec/lib/hamster/deque/unshift_spec.rb +26 -0
  40. data/spec/{hamster → lib/hamster}/experimental/mutable_set/add_qm_spec.rb +0 -0
  41. data/spec/{hamster → lib/hamster}/experimental/mutable_set/add_spec.rb +0 -0
  42. data/spec/{hamster → lib/hamster}/experimental/mutable_set/delete_qm_spec.rb +0 -0
  43. data/spec/{hamster → lib/hamster}/experimental/mutable_set/delete_spec.rb +0 -0
  44. data/spec/{hamster → lib/hamster}/hash/all_spec.rb +10 -0
  45. data/spec/lib/hamster/hash/any_spec.rb +56 -0
  46. data/spec/lib/hamster/hash/assoc_spec.rb +52 -0
  47. data/spec/lib/hamster/hash/clear_spec.rb +43 -0
  48. data/spec/lib/hamster/hash/construction_spec.rb +39 -0
  49. data/spec/{hamster → lib/hamster}/hash/copying_spec.rb +2 -4
  50. data/spec/lib/hamster/hash/default_proc_spec.rb +73 -0
  51. data/spec/lib/hamster/hash/delete_spec.rb +40 -0
  52. data/spec/lib/hamster/hash/each_spec.rb +78 -0
  53. data/spec/lib/hamster/hash/each_with_index_spec.rb +30 -0
  54. data/spec/lib/hamster/hash/empty_spec.rb +46 -0
  55. data/spec/lib/hamster/hash/eql_spec.rb +70 -0
  56. data/spec/lib/hamster/hash/except_spec.rb +43 -0
  57. data/spec/lib/hamster/hash/fetch_spec.rb +58 -0
  58. data/spec/lib/hamster/hash/filter_spec.rb +58 -0
  59. data/spec/lib/hamster/hash/find_spec.rb +44 -0
  60. data/spec/lib/hamster/hash/flat_map_spec.rb +36 -0
  61. data/spec/lib/hamster/hash/flatten_spec.rb +99 -0
  62. data/spec/lib/hamster/hash/get_spec.rb +80 -0
  63. data/spec/lib/hamster/hash/has_key_spec.rb +32 -0
  64. data/spec/lib/hamster/hash/has_value_spec.rb +28 -0
  65. data/spec/{hamster → lib/hamster}/hash/hash_spec.rb +5 -12
  66. data/spec/{hamster → lib/hamster}/hash/immutable_spec.rb +0 -0
  67. data/spec/lib/hamster/hash/inspect_spec.rb +31 -0
  68. data/spec/lib/hamster/hash/invert_spec.rb +31 -0
  69. data/spec/lib/hamster/hash/key_spec.rb +28 -0
  70. data/spec/{hamster → lib/hamster}/hash/keys_spec.rb +3 -6
  71. data/spec/lib/hamster/hash/map_spec.rb +46 -0
  72. data/spec/{hamster → lib/hamster}/hash/marshal_spec.rb +3 -3
  73. data/spec/lib/hamster/hash/merge_spec.rb +77 -0
  74. data/spec/lib/hamster/hash/min_max_spec.rb +50 -0
  75. data/spec/lib/hamster/hash/new_spec.rb +71 -0
  76. data/spec/{hamster → lib/hamster}/hash/none_spec.rb +12 -14
  77. data/spec/lib/hamster/hash/partition_spec.rb +36 -0
  78. data/spec/lib/hamster/hash/pretty_print_spec.rb +35 -0
  79. data/spec/lib/hamster/hash/put_spec.rb +81 -0
  80. data/spec/lib/hamster/hash/reduce_spec.rb +36 -0
  81. data/spec/lib/hamster/hash/remove_spec.rb +62 -0
  82. data/spec/lib/hamster/hash/reverse_each_spec.rb +28 -0
  83. data/spec/lib/hamster/hash/sample_spec.rb +14 -0
  84. data/spec/{hamster → lib/hamster}/hash/size_spec.rb +2 -2
  85. data/spec/lib/hamster/hash/slice_spec.rb +45 -0
  86. data/spec/lib/hamster/hash/sort_spec.rb +27 -0
  87. data/spec/lib/hamster/hash/store_spec.rb +54 -0
  88. data/spec/lib/hamster/hash/take_spec.rb +36 -0
  89. data/spec/lib/hamster/hash/to_a_spec.rb +14 -0
  90. data/spec/lib/hamster/hash/to_hash_spec.rb +22 -0
  91. data/spec/{hamster → lib/hamster}/hash/uniq_spec.rb +2 -4
  92. data/spec/lib/hamster/hash/values_at_spec.rb +14 -0
  93. data/spec/lib/hamster/hash/values_spec.rb +25 -0
  94. data/spec/{hamster → lib/hamster}/immutable/copying_spec.rb +0 -0
  95. data/spec/{hamster → lib/hamster}/immutable/immutable_spec.rb +0 -0
  96. data/spec/{hamster → lib/hamster}/immutable/memoize_spec.rb +2 -2
  97. data/spec/{hamster → lib/hamster}/immutable/new_spec.rb +0 -0
  98. data/spec/{hamster → lib/hamster}/immutable/transform_spec.rb +0 -0
  99. data/spec/{hamster → lib/hamster}/immutable/transform_unless_spec.rb +0 -0
  100. data/spec/lib/hamster/list/add_spec.rb +20 -0
  101. data/spec/lib/hamster/list/all_spec.rb +60 -0
  102. data/spec/{hamster → lib/hamster}/list/any_spec.rb +12 -20
  103. data/spec/{hamster → lib/hamster}/list/append_spec.rb +9 -10
  104. data/spec/lib/hamster/list/at_spec.rb +30 -0
  105. data/spec/lib/hamster/list/break_spec.rb +70 -0
  106. data/spec/{hamster → lib/hamster}/list/cadr_spec.rb +5 -8
  107. data/spec/{hamster → lib/hamster}/list/chunk_spec.rb +5 -8
  108. data/spec/{hamster → lib/hamster}/list/clear_spec.rb +4 -7
  109. data/spec/lib/hamster/list/combination_spec.rb +34 -0
  110. data/spec/{hamster → lib/hamster}/list/compact_spec.rb +5 -8
  111. data/spec/lib/hamster/list/compare_spec.rb +31 -0
  112. data/spec/{hamster → lib/hamster}/list/cons_spec.rb +5 -9
  113. data/spec/lib/hamster/list/construction_spec.rb +118 -0
  114. data/spec/{hamster → lib/hamster}/list/copying_spec.rb +3 -7
  115. data/spec/lib/hamster/list/count_spec.rb +37 -0
  116. data/spec/lib/hamster/list/cycle_spec.rb +29 -0
  117. data/spec/lib/hamster/list/delete_at_spec.rb +19 -0
  118. data/spec/lib/hamster/list/delete_spec.rb +17 -0
  119. data/spec/{hamster → lib/hamster}/list/drop_spec.rb +5 -8
  120. data/spec/lib/hamster/list/drop_while_spec.rb +39 -0
  121. data/spec/lib/hamster/list/each_slice_spec.rb +52 -0
  122. data/spec/lib/hamster/list/each_spec.rb +43 -0
  123. data/spec/lib/hamster/list/each_with_index_spec.rb +29 -0
  124. data/spec/{hamster → lib/hamster}/list/elem_index_spec.rb +4 -14
  125. data/spec/{hamster → lib/hamster}/list/elem_indices_spec.rb +5 -9
  126. data/spec/{hamster → lib/hamster}/list/empty_spec.rb +4 -13
  127. data/spec/{hamster → lib/hamster}/list/eql_spec.rb +2 -8
  128. data/spec/lib/hamster/list/fill_spec.rb +50 -0
  129. data/spec/{hamster → lib/hamster}/list/filter_spec.rb +3 -2
  130. data/spec/{hamster → lib/hamster}/list/find_all_spec.rb +3 -2
  131. data/spec/{hamster → lib/hamster}/list/find_index_spec.rb +4 -14
  132. data/spec/{hamster → lib/hamster}/list/find_indices_spec.rb +11 -9
  133. data/spec/{hamster → lib/hamster}/list/find_spec.rb +10 -16
  134. data/spec/{hamster → lib/hamster}/list/flat_map_spec.rb +0 -0
  135. data/spec/{hamster → lib/hamster}/list/flatten_spec.rb +5 -8
  136. data/spec/{hamster → lib/hamster}/list/grep_spec.rb +9 -17
  137. data/spec/{hamster → lib/hamster}/list/group_by_spec.rb +8 -24
  138. data/spec/{hamster → lib/hamster}/list/hash_spec.rb +4 -12
  139. data/spec/{hamster → lib/hamster}/list/head_spec.rb +2 -7
  140. data/spec/{hamster → lib/hamster}/list/include_spec.rb +4 -13
  141. data/spec/{hamster → lib/hamster}/list/init_spec.rb +5 -9
  142. data/spec/lib/hamster/list/inits_spec.rb +29 -0
  143. data/spec/lib/hamster/list/insert_spec.rb +47 -0
  144. data/spec/lib/hamster/list/inspect_spec.rb +30 -0
  145. data/spec/{hamster → lib/hamster}/list/intersperse_spec.rb +5 -8
  146. data/spec/lib/hamster/list/join_spec.rb +64 -0
  147. data/spec/lib/hamster/list/last_spec.rb +24 -0
  148. data/spec/{hamster → lib/hamster}/list/map_spec.rb +11 -20
  149. data/spec/lib/hamster/list/maximum_spec.rb +42 -0
  150. data/spec/{hamster → lib/hamster}/list/merge_by_spec.rb +4 -13
  151. data/spec/{hamster → lib/hamster}/list/merge_spec.rb +0 -0
  152. data/spec/lib/hamster/list/minimum_spec.rb +42 -0
  153. data/spec/lib/hamster/list/multithreading_spec.rb +48 -0
  154. data/spec/{hamster → lib/hamster}/list/none_spec.rb +11 -21
  155. data/spec/{hamster → lib/hamster}/list/one_spec.rb +12 -22
  156. data/spec/lib/hamster/list/partition_spec.rb +116 -0
  157. data/spec/lib/hamster/list/permutation_spec.rb +56 -0
  158. data/spec/{hamster → lib/hamster}/list/pop_spec.rb +1 -1
  159. data/spec/lib/hamster/list/product_spec.rb +24 -0
  160. data/spec/lib/hamster/list/reduce_spec.rb +97 -0
  161. data/spec/{hamster → lib/hamster}/list/remove_spec.rb +9 -19
  162. data/spec/{hamster → lib/hamster}/list/reverse_spec.rb +7 -14
  163. data/spec/lib/hamster/list/rotate_spec.rb +37 -0
  164. data/spec/lib/hamster/list/sample_spec.rb +14 -0
  165. data/spec/{hamster → lib/hamster}/list/select_spec.rb +3 -2
  166. data/spec/{hamster → lib/hamster}/list/size_spec.rb +4 -13
  167. data/spec/lib/hamster/list/slice_spec.rb +230 -0
  168. data/spec/{hamster → lib/hamster}/list/sorting_spec.rb +10 -20
  169. data/spec/lib/hamster/list/span_spec.rb +77 -0
  170. data/spec/{hamster → lib/hamster}/list/split_at_spec.rb +13 -14
  171. data/spec/lib/hamster/list/subsequences_spec.rb +24 -0
  172. data/spec/lib/hamster/list/sum_spec.rb +24 -0
  173. data/spec/lib/hamster/list/tail_spec.rb +31 -0
  174. data/spec/lib/hamster/list/tails_spec.rb +29 -0
  175. data/spec/{hamster → lib/hamster}/list/take_spec.rb +5 -8
  176. data/spec/{hamster → lib/hamster}/list/take_while_spec.rb +11 -17
  177. data/spec/lib/hamster/list/to_a_spec.rb +40 -0
  178. data/spec/{hamster → lib/hamster}/list/to_ary_spec.rb +1 -3
  179. data/spec/{hamster → lib/hamster}/list/to_list_spec.rb +3 -7
  180. data/spec/{hamster → lib/hamster}/list/to_set_spec.rb +2 -10
  181. data/spec/lib/hamster/list/transpose_spec.rb +20 -0
  182. data/spec/{hamster → lib/hamster}/list/union_spec.rb +5 -12
  183. data/spec/{hamster → lib/hamster}/list/uniq_spec.rb +5 -8
  184. data/spec/{hamster → lib/hamster}/list/zip_spec.rb +2 -9
  185. data/spec/lib/hamster/set/add_spec.rb +76 -0
  186. data/spec/{hamster → lib/hamster}/set/all_spec.rb +18 -14
  187. data/spec/{hamster → lib/hamster}/set/any_spec.rb +19 -16
  188. data/spec/{hamster → lib/hamster}/set/clear_spec.rb +8 -11
  189. data/spec/{hamster → lib/hamster}/set/compact_spec.rb +4 -7
  190. data/spec/{hamster → lib/hamster}/set/construction_spec.rb +4 -8
  191. data/spec/{hamster → lib/hamster}/set/copying_spec.rb +3 -5
  192. data/spec/{hamster → lib/hamster}/set/count_spec.rb +11 -16
  193. data/spec/lib/hamster/set/delete_spec.rb +72 -0
  194. data/spec/lib/hamster/set/difference_spec.rb +50 -0
  195. data/spec/lib/hamster/set/disjoint_spec.rb +26 -0
  196. data/spec/lib/hamster/set/each_spec.rb +46 -0
  197. data/spec/lib/hamster/set/empty_spec.rb +47 -0
  198. data/spec/{hamster → lib/hamster}/set/eqeq_spec.rb +0 -0
  199. data/spec/{hamster → lib/hamster}/set/eql_spec.rb +7 -1
  200. data/spec/lib/hamster/set/exclusion_spec.rb +48 -0
  201. data/spec/lib/hamster/set/filter_spec.rb +74 -0
  202. data/spec/{hamster → lib/hamster}/set/find_spec.rb +7 -11
  203. data/spec/lib/hamster/set/flatten_spec.rb +47 -0
  204. data/spec/{hamster → lib/hamster}/set/foreach_spec.rb +5 -4
  205. data/spec/{hamster → lib/hamster}/set/grep_spec.rb +1 -1
  206. data/spec/lib/hamster/set/group_by_spec.rb +60 -0
  207. data/spec/lib/hamster/set/hash_spec.rb +23 -0
  208. data/spec/lib/hamster/set/head_spec.rb +31 -0
  209. data/spec/{hamster → lib/hamster}/set/immutable_spec.rb +0 -0
  210. data/spec/lib/hamster/set/include_spec.rb +61 -0
  211. data/spec/lib/hamster/set/inspect_spec.rb +48 -0
  212. data/spec/lib/hamster/set/intersect_spec.rb +26 -0
  213. data/spec/lib/hamster/set/intersection_spec.rb +53 -0
  214. data/spec/lib/hamster/set/join_spec.rb +65 -0
  215. data/spec/lib/hamster/set/map_spec.rb +60 -0
  216. data/spec/{hamster → lib/hamster}/set/marshal_spec.rb +3 -3
  217. data/spec/{hamster → lib/hamster}/set/maximum_spec.rb +6 -15
  218. data/spec/{hamster → lib/hamster}/set/minimum_spec.rb +6 -16
  219. data/spec/lib/hamster/set/new_spec.rb +54 -0
  220. data/spec/{hamster → lib/hamster}/set/none_spec.rb +15 -15
  221. data/spec/{hamster → lib/hamster}/set/one_spec.rb +14 -16
  222. data/spec/lib/hamster/set/partition_spec.rb +53 -0
  223. data/spec/{hamster → lib/hamster}/set/product_spec.rb +6 -6
  224. data/spec/lib/hamster/set/reduce_spec.rb +56 -0
  225. data/spec/lib/hamster/set/remove_spec.rb +51 -0
  226. data/spec/{hamster/set/each_spec.rb → lib/hamster/set/reverse_each_spec.rb} +8 -7
  227. data/spec/lib/hamster/set/sample_spec.rb +14 -0
  228. data/spec/{hamster → lib/hamster}/set/size_spec.rb +0 -1
  229. data/spec/{hamster → lib/hamster}/set/sorting_spec.rb +17 -13
  230. data/spec/lib/hamster/set/subset_spec.rb +52 -0
  231. data/spec/lib/hamster/set/sum_spec.rb +24 -0
  232. data/spec/lib/hamster/set/superset_spec.rb +52 -0
  233. data/spec/lib/hamster/set/to_a_spec.rb +31 -0
  234. data/spec/lib/hamster/set/to_list_spec.rb +37 -0
  235. data/spec/{hamster → lib/hamster}/set/to_set_spec.rb +2 -6
  236. data/spec/lib/hamster/set/union_spec.rb +55 -0
  237. data/spec/{hamster → lib/hamster}/set/uniq_spec.rb +2 -5
  238. data/spec/lib/hamster/sorted_set/above_spec.rb +52 -0
  239. data/spec/lib/hamster/sorted_set/add_spec.rb +63 -0
  240. data/spec/lib/hamster/sorted_set/at_spec.rb +25 -0
  241. data/spec/lib/hamster/sorted_set/below_spec.rb +52 -0
  242. data/spec/lib/hamster/sorted_set/between_spec.rb +52 -0
  243. data/spec/lib/hamster/sorted_set/clear_spec.rb +35 -0
  244. data/spec/lib/hamster/sorted_set/construction_spec.rb +29 -0
  245. data/spec/lib/hamster/sorted_set/delete_at_spec.rb +19 -0
  246. data/spec/lib/hamster/sorted_set/delete_spec.rb +81 -0
  247. data/spec/{hamster/set → lib/hamster/sorted_set}/difference_spec.rb +5 -9
  248. data/spec/lib/hamster/sorted_set/disjoint_spec.rb +26 -0
  249. data/spec/lib/hamster/sorted_set/drop_spec.rb +29 -0
  250. data/spec/lib/hamster/sorted_set/drop_while_spec.rb +35 -0
  251. data/spec/lib/hamster/sorted_set/each_spec.rb +31 -0
  252. data/spec/lib/hamster/sorted_set/empty_spec.rb +37 -0
  253. data/spec/lib/hamster/sorted_set/eql_spec.rb +121 -0
  254. data/spec/{hamster/set → lib/hamster/sorted_set}/exclusion_spec.rb +4 -9
  255. data/spec/lib/hamster/sorted_set/fetch_spec.rb +65 -0
  256. data/spec/lib/hamster/sorted_set/filter_spec.rb +62 -0
  257. data/spec/lib/hamster/sorted_set/find_index_spec.rb +33 -0
  258. data/spec/lib/hamster/sorted_set/first_spec.rb +21 -0
  259. data/spec/lib/hamster/sorted_set/from_spec.rb +52 -0
  260. data/spec/lib/hamster/sorted_set/group_by_spec.rb +58 -0
  261. data/spec/lib/hamster/sorted_set/include_spec.rb +24 -0
  262. data/spec/lib/hamster/sorted_set/inspect_spec.rb +38 -0
  263. data/spec/lib/hamster/sorted_set/intersect_spec.rb +26 -0
  264. data/spec/lib/hamster/sorted_set/intersection_spec.rb +29 -0
  265. data/spec/lib/hamster/sorted_set/last_spec.rb +37 -0
  266. data/spec/lib/hamster/sorted_set/map_spec.rb +36 -0
  267. data/spec/lib/hamster/sorted_set/marshal_spec.rb +37 -0
  268. data/spec/lib/hamster/sorted_set/minimum_spec.rb +22 -0
  269. data/spec/lib/hamster/sorted_set/new_spec.rb +52 -0
  270. data/spec/lib/hamster/sorted_set/reverse_each_spec.rb +29 -0
  271. data/spec/lib/hamster/sorted_set/sample_spec.rb +14 -0
  272. data/spec/lib/hamster/sorted_set/size_spec.rb +18 -0
  273. data/spec/lib/hamster/sorted_set/slice_spec.rb +241 -0
  274. data/spec/lib/hamster/sorted_set/sorting_spec.rb +45 -0
  275. data/spec/lib/hamster/sorted_set/subset_spec.rb +48 -0
  276. data/spec/lib/hamster/sorted_set/superset_spec.rb +48 -0
  277. data/spec/lib/hamster/sorted_set/take_spec.rb +26 -0
  278. data/spec/lib/hamster/sorted_set/take_while_spec.rb +34 -0
  279. data/spec/lib/hamster/sorted_set/to_set_spec.rb +19 -0
  280. data/spec/lib/hamster/sorted_set/union_spec.rb +28 -0
  281. data/spec/lib/hamster/sorted_set/up_to_spec.rb +52 -0
  282. data/spec/lib/hamster/sorted_set/values_at_spec.rb +34 -0
  283. data/spec/lib/hamster/vector/add_spec.rb +68 -0
  284. data/spec/{hamster → lib/hamster}/vector/any_spec.rb +0 -0
  285. data/spec/lib/hamster/vector/assoc_spec.rb +36 -0
  286. data/spec/lib/hamster/vector/bsearch_spec.rb +58 -0
  287. data/spec/lib/hamster/vector/clear_spec.rb +34 -0
  288. data/spec/lib/hamster/vector/combination_spec.rb +82 -0
  289. data/spec/lib/hamster/vector/compact_spec.rb +30 -0
  290. data/spec/lib/hamster/vector/compare_spec.rb +32 -0
  291. data/spec/lib/hamster/vector/concat_spec.rb +35 -0
  292. data/spec/{hamster → lib/hamster}/vector/copying_spec.rb +3 -6
  293. data/spec/lib/hamster/vector/count_spec.rb +18 -0
  294. data/spec/lib/hamster/vector/delete_at_spec.rb +54 -0
  295. data/spec/lib/hamster/vector/delete_spec.rb +31 -0
  296. data/spec/lib/hamster/vector/drop_spec.rb +35 -0
  297. data/spec/lib/hamster/vector/drop_while_spec.rb +55 -0
  298. data/spec/lib/hamster/vector/each_index_spec.rb +41 -0
  299. data/spec/lib/hamster/vector/each_spec.rb +47 -0
  300. data/spec/lib/hamster/vector/each_with_index_spec.rb +40 -0
  301. data/spec/lib/hamster/vector/empty_spec.rb +44 -0
  302. data/spec/lib/hamster/vector/eql_spec.rb +77 -0
  303. data/spec/lib/hamster/vector/exist_spec.rb +4 -4
  304. data/spec/lib/hamster/vector/exists_spec.rb +4 -4
  305. data/spec/lib/hamster/vector/fetch_spec.rb +65 -0
  306. data/spec/lib/hamster/vector/fill_spec.rb +89 -0
  307. data/spec/lib/hamster/vector/filter_spec.rb +64 -0
  308. data/spec/{hamster → lib/hamster}/vector/first_spec.rb +2 -6
  309. data/spec/lib/hamster/vector/flatten_spec.rb +44 -0
  310. data/spec/lib/hamster/vector/get_spec.rb +75 -0
  311. data/spec/lib/hamster/vector/group_by_spec.rb +58 -0
  312. data/spec/{hamster → lib/hamster}/vector/include_spec.rb +2 -6
  313. data/spec/lib/hamster/vector/insert_spec.rb +69 -0
  314. data/spec/lib/hamster/vector/inspect_spec.rb +50 -0
  315. data/spec/{hamster/set → lib/hamster/vector}/join_spec.rb +23 -18
  316. data/spec/{hamster → lib/hamster}/vector/last_spec.rb +12 -3
  317. data/spec/{hamster → lib/hamster}/vector/length_spec.rb +12 -3
  318. data/spec/lib/hamster/vector/ltlt_spec.rb +20 -2
  319. data/spec/lib/hamster/vector/map_spec.rb +52 -0
  320. data/spec/lib/hamster/vector/marshal_spec.rb +32 -0
  321. data/spec/lib/hamster/vector/maximum_spec.rb +36 -0
  322. data/spec/lib/hamster/vector/minimum_spec.rb +36 -0
  323. data/spec/lib/hamster/vector/multiply_spec.rb +48 -0
  324. data/spec/lib/hamster/vector/new_spec.rb +51 -0
  325. data/spec/lib/hamster/vector/partition_spec.rb +53 -0
  326. data/spec/lib/hamster/vector/permutation_spec.rb +92 -0
  327. data/spec/lib/hamster/vector/pop_spec.rb +27 -0
  328. data/spec/lib/hamster/vector/product_spec.rb +71 -0
  329. data/spec/lib/hamster/vector/reduce_spec.rb +108 -0
  330. data/spec/lib/hamster/vector/remove_spec.rb +44 -0
  331. data/spec/lib/hamster/vector/repeated_combination_spec.rb +78 -0
  332. data/spec/lib/hamster/vector/repeated_permutation_spec.rb +94 -0
  333. data/spec/lib/hamster/vector/reverse_each_spec.rb +32 -0
  334. data/spec/lib/hamster/vector/reverse_spec.rb +22 -0
  335. data/spec/lib/hamster/vector/rindex_spec.rb +37 -0
  336. data/spec/lib/hamster/vector/rotate_spec.rb +74 -0
  337. data/spec/lib/hamster/vector/sample_spec.rb +14 -0
  338. data/spec/{hamster → lib/hamster}/vector/set_spec.rb +48 -14
  339. data/spec/lib/hamster/vector/shift_spec.rb +28 -0
  340. data/spec/lib/hamster/vector/shuffle_spec.rb +44 -0
  341. data/spec/lib/hamster/vector/slice_spec.rb +241 -0
  342. data/spec/lib/hamster/vector/sorting_spec.rb +57 -0
  343. data/spec/{hamster/set → lib/hamster/vector}/sum_spec.rb +3 -9
  344. data/spec/lib/hamster/vector/take_spec.rb +29 -0
  345. data/spec/lib/hamster/vector/take_while_spec.rb +35 -0
  346. data/spec/{hamster → lib/hamster}/vector/to_a_spec.rb +11 -12
  347. data/spec/{hamster → lib/hamster}/vector/to_ary_spec.rb +0 -0
  348. data/spec/{hamster/set → lib/hamster/vector}/to_list_spec.rb +7 -12
  349. data/spec/lib/hamster/vector/to_set_spec.rb +23 -0
  350. data/spec/lib/hamster/vector/transpose_spec.rb +49 -0
  351. data/spec/lib/hamster/vector/uniq_spec.rb +56 -0
  352. data/spec/lib/hamster/vector/unshift_spec.rb +29 -0
  353. data/spec/lib/hamster/vector/values_at_spec.rb +34 -0
  354. data/spec/lib/hamster/vector/zip_spec.rb +58 -0
  355. data/spec/spec_helper.rb +34 -1
  356. metadata +684 -467
  357. data/lib/hamster/core_ext/enumerator.rb +0 -16
  358. data/lib/hamster/experimental/mutable_stack.rb +0 -30
  359. data/lib/hamster/groupable.rb +0 -12
  360. data/lib/hamster/queue.rb +0 -86
  361. data/lib/hamster/sorter.rb +0 -25
  362. data/lib/hamster/stack.rb +0 -77
  363. data/lib/hamster/tuple.rb +0 -24
  364. data/spec/hamster/core_ext/enumerator_spec.rb +0 -19
  365. data/spec/hamster/experimental/mutable_stack/pop_spec.rb +0 -35
  366. data/spec/hamster/experimental/mutable_stack/push_spec.rb +0 -21
  367. data/spec/hamster/hash/any_spec.rb +0 -52
  368. data/spec/hamster/hash/clear_spec.rb +0 -29
  369. data/spec/hamster/hash/construction_spec.rb +0 -27
  370. data/spec/hamster/hash/delete_spec.rb +0 -38
  371. data/spec/hamster/hash/each_spec.rb +0 -30
  372. data/spec/hamster/hash/empty_spec.rb +0 -27
  373. data/spec/hamster/hash/eql_spec.rb +0 -70
  374. data/spec/hamster/hash/except_spec.rb +0 -22
  375. data/spec/hamster/hash/fetch_spec.rb +0 -72
  376. data/spec/hamster/hash/filter_spec.rb +0 -48
  377. data/spec/hamster/hash/find_spec.rb +0 -45
  378. data/spec/hamster/hash/get_spec.rb +0 -55
  379. data/spec/hamster/hash/has_key_spec.rb +0 -26
  380. data/spec/hamster/hash/inspect_spec.rb +0 -24
  381. data/spec/hamster/hash/map_spec.rb +0 -49
  382. data/spec/hamster/hash/merge_spec.rb +0 -30
  383. data/spec/hamster/hash/new_spec.rb +0 -21
  384. data/spec/hamster/hash/put_spec.rb +0 -67
  385. data/spec/hamster/hash/reduce_spec.rb +0 -52
  386. data/spec/hamster/hash/remove_spec.rb +0 -48
  387. data/spec/hamster/hash/slice_spec.rb +0 -26
  388. data/spec/hamster/hash/values_spec.rb +0 -29
  389. data/spec/hamster/list/add_spec.rb +0 -11
  390. data/spec/hamster/list/all_spec.rb +0 -84
  391. data/spec/hamster/list/at_spec.rb +0 -37
  392. data/spec/hamster/list/break_spec.rb +0 -73
  393. data/spec/hamster/list/combinations_spec.rb +0 -41
  394. data/spec/hamster/list/construction_spec.rb +0 -137
  395. data/spec/hamster/list/count_spec.rb +0 -52
  396. data/spec/hamster/list/cycle_spec.rb +0 -36
  397. data/spec/hamster/list/drop_while_spec.rb +0 -47
  398. data/spec/hamster/list/each_slice_spec.rb +0 -64
  399. data/spec/hamster/list/each_spec.rb +0 -56
  400. data/spec/hamster/list/each_with_index_spec.rb +0 -33
  401. data/spec/hamster/list/inits_spec.rb +0 -34
  402. data/spec/hamster/list/inspect_spec.rb +0 -33
  403. data/spec/hamster/list/join_spec.rb +0 -64
  404. data/spec/hamster/list/last_spec.rb +0 -34
  405. data/spec/hamster/list/maximum_spec.rb +0 -58
  406. data/spec/hamster/list/minimum_spec.rb +0 -58
  407. data/spec/hamster/list/partition_spec.rb +0 -63
  408. data/spec/hamster/list/product_spec.rb +0 -34
  409. data/spec/hamster/list/reduce_spec.rb +0 -72
  410. data/spec/hamster/list/slice_spec.rb +0 -40
  411. data/spec/hamster/list/span_spec.rb +0 -75
  412. data/spec/hamster/list/sum_spec.rb +0 -34
  413. data/spec/hamster/list/tail_spec.rb +0 -38
  414. data/spec/hamster/list/tails_spec.rb +0 -34
  415. data/spec/hamster/list/to_a_spec.rb +0 -42
  416. data/spec/hamster/queue/clear_spec.rb +0 -28
  417. data/spec/hamster/queue/construction_spec.rb +0 -34
  418. data/spec/hamster/queue/dequeue_spec.rb +0 -30
  419. data/spec/hamster/queue/empty_spec.rb +0 -35
  420. data/spec/hamster/queue/head_spec.rb +0 -25
  421. data/spec/hamster/queue/inspect_spec.rb +0 -23
  422. data/spec/hamster/queue/to_a_spec.rb +0 -32
  423. data/spec/hamster/queue/to_list_spec.rb +0 -34
  424. data/spec/hamster/set/add_spec.rb +0 -40
  425. data/spec/hamster/set/delete_spec.rb +0 -38
  426. data/spec/hamster/set/empty_spec.rb +0 -25
  427. data/spec/hamster/set/filter_spec.rb +0 -72
  428. data/spec/hamster/set/flatten_spec.rb +0 -47
  429. data/spec/hamster/set/group_by_spec.rb +0 -56
  430. data/spec/hamster/set/hash_spec.rb +0 -20
  431. data/spec/hamster/set/head_spec.rb +0 -28
  432. data/spec/hamster/set/include_spec.rb +0 -27
  433. data/spec/hamster/set/inspect_spec.rb +0 -24
  434. data/spec/hamster/set/intersection_spec.rb +0 -36
  435. data/spec/hamster/set/map_spec.rb +0 -49
  436. data/spec/hamster/set/new_spec.rb +0 -21
  437. data/spec/hamster/set/partition_spec.rb +0 -59
  438. data/spec/hamster/set/reduce_spec.rb +0 -62
  439. data/spec/hamster/set/remove_spec.rb +0 -48
  440. data/spec/hamster/set/subset_spec.rb +0 -31
  441. data/spec/hamster/set/superset_spec.rb +0 -31
  442. data/spec/hamster/set/to_a_spec.rb +0 -32
  443. data/spec/hamster/set/union_spec.rb +0 -35
  444. data/spec/hamster/sorter/immutable_spec.rb +0 -9
  445. data/spec/hamster/stack/clear_spec.rb +0 -28
  446. data/spec/hamster/stack/construction_spec.rb +0 -34
  447. data/spec/hamster/stack/copying_spec.rb +0 -23
  448. data/spec/hamster/stack/empty_spec.rb +0 -23
  449. data/spec/hamster/stack/eql_spec.rb +0 -48
  450. data/spec/hamster/stack/immutable_spec.rb +0 -9
  451. data/spec/hamster/stack/inspect_spec.rb +0 -23
  452. data/spec/hamster/stack/peek_spec.rb +0 -30
  453. data/spec/hamster/stack/pop_spec.rb +0 -31
  454. data/spec/hamster/stack/push_spec.rb +0 -31
  455. data/spec/hamster/stack/size_spec.rb +0 -25
  456. data/spec/hamster/stack/to_a_spec.rb +0 -32
  457. data/spec/hamster/stack/to_ary.rb +0 -37
  458. data/spec/hamster/stack/to_list_spec.rb +0 -25
  459. data/spec/hamster/trie/remove_spec.rb +0 -117
  460. data/spec/hamster/tuple/construction_spec.rb +0 -30
  461. data/spec/hamster/tuple/copying_spec.rb +0 -17
  462. data/spec/hamster/tuple/eql_spec.rb +0 -78
  463. data/spec/hamster/tuple/first_spec.rb +0 -14
  464. data/spec/hamster/tuple/immutable_spec.rb +0 -9
  465. data/spec/hamster/tuple/inspect_spec.rb +0 -14
  466. data/spec/hamster/tuple/last_spec.rb +0 -14
  467. data/spec/hamster/tuple/to_a_spec.rb +0 -30
  468. data/spec/hamster/tuple/to_ary_spec.rb +0 -37
  469. data/spec/hamster/undefined/erase_spec.rb +0 -36
  470. data/spec/hamster/vector/add_spec.rb +0 -56
  471. data/spec/hamster/vector/clear_spec.rb +0 -28
  472. data/spec/hamster/vector/each_spec.rb +0 -35
  473. data/spec/hamster/vector/each_with_index_spec.rb +0 -33
  474. data/spec/hamster/vector/empty_spec.rb +0 -32
  475. data/spec/hamster/vector/eql_spec.rb +0 -53
  476. data/spec/hamster/vector/filter_spec.rb +0 -58
  477. data/spec/hamster/vector/get_spec.rb +0 -58
  478. data/spec/hamster/vector/inspect_spec.rb +0 -33
  479. data/spec/hamster/vector/map_spec.rb +0 -57
  480. data/spec/hamster/vector/new_spec.rb +0 -48
  481. data/spec/hamster/vector/reduce_spec.rb +0 -62
  482. data/spec/lib/hamster/vector/cons_spec.rb +0 -48
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a12201961b658581cc147e8a0c99fdc7003bf3b0
4
- data.tar.gz: 3f24be00255e640a0afcefd374f6e3d16e619e5c
3
+ metadata.gz: f3c8822d3a3758de0e490808c2012795a7a0de79
4
+ data.tar.gz: 1295b432e023a4c840d17fb9ca8a1500b97db0f0
5
5
  SHA512:
6
- metadata.gz: abd019d8bcc64d60d75d734a8ee0e08e549ab3662b2e1638f25afb331a3fa7981b0f45f571625bc61f2a36b17bbce44c0a862aa4586f95f9949949ddc26dc1c0
7
- data.tar.gz: 283b36da83e8dda6ab822e430eb2503d7abdf7be6cb142e0c217052acbd2cafcac52c0833e2a156018436cf6cb86b947c7c10a76a5dcfa4b9ab8247a88d6d35d
6
+ metadata.gz: 91e4df28a78d5aea2d423e03f8c6be123abae2f17ef67c7b6481ccaa20dc309d61b3d2ee864901cf9446fcb5d637ed5330f7622457de8ba0c74346089d06fec7
7
+ data.tar.gz: e379456f35778c21b8e37ea1525d20f520c5323acade1568a74deff7b950765d70acd4ad8e6889acf22421615bb75953e6631bc8372918460b6bbf991d511487
@@ -1,10 +1,10 @@
1
1
  require "hamster/core_ext"
2
2
  require "hamster/immutable"
3
3
  require "hamster/list"
4
- require "hamster/stack"
5
- require "hamster/queue"
4
+ require "hamster/deque"
6
5
  require "hamster/hash"
7
6
  require "hamster/set"
8
7
  require "hamster/vector"
8
+ require "hamster/sorted_set"
9
9
  require "hamster/mutable_hash"
10
10
  require "hamster/version"
@@ -1,3 +1,2 @@
1
1
  require "hamster/core_ext/enumerable"
2
- require "hamster/core_ext/enumerator"
3
2
  require "hamster/core_ext/io"
@@ -1,21 +1,21 @@
1
1
  require "hamster/list"
2
2
 
3
- module Hamster
4
- module CoreExt
5
- module Enumerable
6
- def self.included(base)
7
- base.class_eval do
8
- def to_list
9
- list = EmptyList
10
- reverse_each { |item| list = list.cons(item) }
11
- list
12
- end
13
- end
14
- end
3
+ # Ruby's built-in `Enumerable` module.
4
+ # @see http://www.ruby-doc.org/core/Enumerable.html
5
+ module Enumerable
6
+ # Return a new {Hamster::List} populated with the items in this `Enumerable` object.
7
+ # @return [List]
8
+ def to_list
9
+ # use destructive operations to build up a new list, like Common Lisp's NCONC
10
+ # this is a very fast way to build up a linked list
11
+ list = tail = Hamster::Cons.allocate
12
+ each do |item|
13
+ new_node = Hamster::Cons.allocate
14
+ new_node.instance_variable_set(:@head, item)
15
+ tail.instance_variable_set(:@tail, new_node)
16
+ tail = new_node
15
17
  end
18
+ tail.instance_variable_set(:@tail, Hamster::EmptyList)
19
+ list.tail
16
20
  end
17
- end
18
-
19
- module Enumerable
20
- include Hamster::CoreExt::Enumerable
21
- end
21
+ end
@@ -1,23 +1,21 @@
1
1
  require "hamster/list"
2
- require "English"
3
2
 
4
- module Hamster
5
- module CoreExt
6
- module IO
7
- def to_list(sep = $INPUT_RECORD_SEPARATOR)
8
- Stream.new do
9
- line = gets(sep)
10
- if line
11
- Sequence.new(line, to_list)
12
- else
13
- EmptyList
14
- end
15
- end
3
+ # Ruby's built-in `IO` class.
4
+ # @see http://www.ruby-doc.org/core/IO.html
5
+ class IO
6
+ # Return a lazy list of "records" read from this IO stream.
7
+ # "Records" are delimited by `$/`, the global input record separator string.
8
+ # By default, it is `"\n"`, a newline.
9
+ #
10
+ # @return [List]
11
+ def to_list(sep = $/) # global input record separator
12
+ Hamster::LazyList.new do
13
+ line = gets(sep)
14
+ if line
15
+ Hamster::Cons.new(line, to_list)
16
+ else
17
+ EmptyList
16
18
  end
17
19
  end
18
20
  end
19
21
  end
20
-
21
- class IO
22
- include Hamster::CoreExt::IO
23
- end
@@ -0,0 +1,229 @@
1
+ require "forwardable"
2
+ require "hamster/immutable"
3
+ require "hamster/list"
4
+
5
+ module Hamster
6
+ def self.deque(*items)
7
+ items.empty? ? EmptyDeque : Deque.new(items)
8
+ end
9
+
10
+ # A `Deque` (or double-ended queue) is an ordered, sequential collection of objects,
11
+ # which allows elements to be efficiently added and removed at the front and end of
12
+ # the sequence. Retrieving the elements at the front and end is also efficient. This
13
+ # makes `Deque` perfect for use as an immutable queue *or* stack.
14
+ #
15
+ # A `Deque` differs from a {Vector} in that vectors allow indexed access to any
16
+ # element in the collection. `Deque`s only allow access to the first and last
17
+ # element. But adding and removing from the ends of a `Deque` is faster than
18
+ # adding and removing from the ends of a {Vector}.
19
+ #
20
+ # To create a new `Deque`:
21
+ #
22
+ # Hamster.deque('a', 'b', 'c')
23
+ # Hamster::Deque.new([:first, :second, :third])
24
+ # Hamster::Deque[1, 2, 3, 4, 5]
25
+ #
26
+ # Or you can start with an empty deque and build it up:
27
+ #
28
+ # Hamster::Deque.empty.push('b').push('c').unshift('a')
29
+ #
30
+ # Like all Hamster collections, `Deque` is immutable. The 4 basic operations which
31
+ # "modify" deques ({#push}, {#pop}, {#shift}, and {#unshift}) all return a new
32
+ # collection and leave the existing one unchanged.
33
+ #
34
+ # @example
35
+ # deque = Hamster::Deque.empty # => Hamster::Deque[]
36
+ # deque = deque.push('a').push('b').push('c') # => Hamster::Deque['a', 'b', 'c']
37
+ # deque.first # => 'a'
38
+ # deque.last # => 'c'
39
+ # deque = deque.shift # => Hamster::Deque['b', 'c']
40
+ #
41
+ # @see http://en.wikipedia.org/wiki/Deque "Deque" on Wikipedia
42
+ #
43
+ class Deque
44
+ extend Forwardable
45
+ include Immutable
46
+
47
+ class << self
48
+ # Create a new `Deque` populated with the given items.
49
+ # @return [Deque]
50
+ def [](*items)
51
+ items.empty? ? empty : new(items)
52
+ end
53
+
54
+ # Return an empty `Deque`. If used on a subclass, returns an empty instance
55
+ # of that class.
56
+ #
57
+ # @return [Deque]
58
+ def empty
59
+ @empty ||= self.new
60
+ end
61
+
62
+ # "Raw" allocation of a new `Deque`. Used internally to create a new
63
+ # instance quickly after consing onto the front/rear lists or taking their
64
+ # tails.
65
+ #
66
+ # @return [Deque]
67
+ # @private
68
+ def alloc(front, rear)
69
+ result = allocate
70
+ result.instance_variable_set(:@front, front)
71
+ result.instance_variable_set(:@rear, rear)
72
+ result
73
+ end
74
+ end
75
+
76
+ def initialize(items=[])
77
+ @front = items.to_list
78
+ @rear = EmptyList
79
+ end
80
+
81
+ # Return `true` if this `Deque` contains no items.
82
+ # @return [Boolean]
83
+ def empty?
84
+ @front.empty? && @rear.empty?
85
+ end
86
+ def_delegator :self, :empty?, :null?
87
+
88
+ # Return the number of items in this `Deque`.
89
+ # @return [Integer]
90
+ def size
91
+ @front.size + @rear.size
92
+ end
93
+ def_delegator :self, :size, :length
94
+
95
+ # Return the first item in the `Deque`. If the deque is empty, return `nil`.
96
+ # @return [Object]
97
+ def first
98
+ return @front.head unless @front.empty?
99
+ @rear.last # memoize?
100
+ end
101
+ def_delegator :self, :first, :head
102
+ def_delegator :self, :first, :front
103
+
104
+ # Return the last item in the `Deque`. If the deque is empty, return `nil`.
105
+ # @return [Object]
106
+ def last
107
+ return @rear.head unless @rear.empty?
108
+ @front.last # memoize?
109
+ end
110
+ def_delegator :self, :last, :peek
111
+
112
+ # Return a new `Deque` with `item` added at the end.
113
+ # @param item [Object] The item to add
114
+ # @return [Deque]
115
+ def push(item)
116
+ self.class.alloc(@front, @rear.cons(item))
117
+ end
118
+ def_delegator :self, :push, :enqueue
119
+ def_delegator :self, :push, :<<
120
+ def_delegator :self, :push, :add
121
+ def_delegator :self, :push, :conj
122
+ def_delegator :self, :push, :conjoin
123
+
124
+ # Return a new `Deque` with the last item removed.
125
+ # @return [Deque]
126
+ def pop
127
+ front, rear = @front, @rear
128
+
129
+ if rear.empty?
130
+ return EmptyDeque if front.empty?
131
+ front, rear = EmptyList, front.reverse
132
+ end
133
+
134
+ self.class.alloc(front, rear.tail)
135
+ end
136
+
137
+ # Return a new `Deque` with `item` added at the front.
138
+ # @param item [Object] The item to add
139
+ # @return [Deque]
140
+ def unshift(item)
141
+ self.class.alloc(@front.cons(item), @rear)
142
+ end
143
+
144
+ # Return a new `Deque` with the first item removed.
145
+ # @return [Deque]
146
+ def shift
147
+ front, rear = @front, @rear
148
+
149
+ if front.empty?
150
+ return EmptyDeque if rear.empty?
151
+ front, rear = rear.reverse, EmptyList
152
+ end
153
+
154
+ self.class.alloc(front.tail, rear)
155
+ end
156
+ def_delegator :self, :shift, :dequeue
157
+ def_delegator :self, :shift, :tail
158
+
159
+ # Return an empty `Deque` instance, of the same class as this one. Useful if you
160
+ # have multiple subclasses of `Deque` and want to treat them polymorphically.
161
+ #
162
+ # @return [Deque]
163
+ def clear
164
+ self.class.empty
165
+ end
166
+
167
+ # Return true if `other` has the same type and contents as this `Deque`.
168
+ #
169
+ # @param other [Object] The collection to compare with
170
+ # @return [Boolean]
171
+ def eql?(other)
172
+ return true if other.equal?(self)
173
+ instance_of?(other.class) && to_ary.eql?(other.to_ary)
174
+ end
175
+ def_delegator :self, :eql?, :==
176
+
177
+ # Return an `Array` with the same elements, in the same order.
178
+ # @return [Array]
179
+ def to_a
180
+ @front.to_a.concat(@rear.to_a.tap { |a| a.reverse! })
181
+ end
182
+ def_delegator :self, :to_a, :entries
183
+ def_delegator :self, :to_a, :to_ary
184
+
185
+ # Return a {List} with the same elements, in the same order.
186
+ # @return [Hamster::List]
187
+ def to_list
188
+ @front.append(@rear.reverse)
189
+ end
190
+
191
+ # Return the contents of this `Deque` as a programmer-readable `String`. If all the
192
+ # items in the deque are serializable as Ruby literal strings, the returned string can
193
+ # be passed to `eval` to reconstitute an equivalent `Deque`.
194
+ #
195
+ # @return [String]
196
+ def inspect
197
+ result = "#{self.class}["
198
+ i = 0
199
+ @front.each { |obj| result << ', ' if i > 0; result << obj.inspect; i += 1 }
200
+ @rear.to_a.tap { |a| a.reverse! }.each { |obj| result << ', ' if i > 0; result << obj.inspect; i += 1 }
201
+ result << "]"
202
+ end
203
+
204
+ # @private
205
+ def pretty_print(pp)
206
+ pp.group(1, "#{self.class}[", "]") do
207
+ pp.breakable ''
208
+ pp.seplist(self.to_a) { |obj| obj.pretty_print(pp) }
209
+ end
210
+ end
211
+
212
+ # @return [::Array]
213
+ # @private
214
+ def marshal_dump
215
+ to_a
216
+ end
217
+
218
+ # @private
219
+ def marshal_load(array)
220
+ initialize(array)
221
+ end
222
+ end
223
+
224
+ # The canonical empty `Deque`. Returned by `Hamster.deque` and `Deque[]` when
225
+ # invoked with no arguments; also returned by `Deque.empty`. Prefer using this
226
+ # one rather than creating many empty deques using `Deque.new`.
227
+ #
228
+ EmptyDeque = Hamster::Deque.empty
229
+ end
@@ -1,136 +1,178 @@
1
1
  require "forwardable"
2
- require "hamster/undefined"
3
- require "hamster/tuple"
4
2
 
5
3
  module Hamster
4
+ # Helper module for Hamster's sequential collections
5
+ #
6
+ # Classes including `Hamster::Enumerable` must implement `#each` (just like `::Enumerable`).
7
+ #
8
+ # They must also implement:
9
+ #
10
+ # - `#filter`, which takes a block, and returns an instance of the same class
11
+ # with only the items for which the block returns a true value
12
+ # - `#reverse` (or else undef `#foldr`, or provide another definition for it)
13
+ #
6
14
  module Enumerable
7
15
  extend Forwardable
16
+ include ::Enumerable
8
17
 
9
- def each
10
- fail NoMethodError, "undefined method `each' for #{self.class.name}"
11
- end
12
- def_delegator :self, :each, :foreach
13
-
14
- def filter
15
- fail NoMethodError, "undefined method `filter' for #{self.class.name}"
16
- end
17
- def_delegator :self, :filter, :select
18
- def_delegator :self, :filter, :find_all
19
-
20
- def each_with_index(&block)
21
- return self unless block_given?
22
- reduce(0) do |index, item|
23
- yield(item, index)
24
- index + 1
25
- end
26
- nil
18
+ # Return a new collection with all the elements for which the block returns false.
19
+ def remove
20
+ return enum_for(:remove) if not block_given?
21
+ filter { |item| !yield(item) }
27
22
  end
28
23
 
29
- def reduce(memo = Undefined)
30
- each do |item|
31
- memo = memo.equal?(Undefined) ? item : yield(memo, item)
32
- end if block_given?
33
- Undefined.erase(memo)
24
+ # Return a new collection with all `nil` elements removed.
25
+ def compact
26
+ filter { |item| !item.nil? }
34
27
  end
35
- def_delegator :self, :reduce, :inject
36
- def_delegator :self, :reduce, :fold
37
- def_delegator :self, :reduce, :foldr
38
28
 
39
- def partition(&block)
40
- return self unless block_given?
41
- Tuple.new(filter(&block), remove(&block))
29
+ # Search the collection for elements which are `#===` to `item`. Yield them to
30
+ # the optional code block if provided, and return them as a new collection.
31
+ def grep(pattern, &block)
32
+ result = filter { |item| pattern === item }
33
+ result = result.map(&block) if block_given?
34
+ result
42
35
  end
43
36
 
44
- def find
45
- return nil unless block_given?
46
- each { |item| return item if yield(item) }
37
+ # Yield all integers from 0 up to, but not including, the number of items in
38
+ # this collection. For collections which provide indexed access, these are all
39
+ # the valid, non-negative indices into the collection.
40
+ def each_index(&block)
41
+ return enum_for(:each_index) unless block_given?
42
+ 0.upto(size-1, &block)
43
+ self
47
44
  end
48
- def_delegator :self, :find, :detect
49
45
 
50
- def include?(object)
51
- any? { |item| item == object }
52
- end
53
- def_delegator :self, :include?, :member?
54
- def_delegator :self, :include?, :contains?
55
- def_delegator :self, :include?, :elem?
56
-
57
- def any?
58
- return any? { |item| item } unless block_given?
59
- each { |item| return true if yield(item) }
60
- false
46
+ # Multiply all the items (presumably numeric) in this collection together.
47
+ def product
48
+ reduce(1, &:*)
61
49
  end
62
- def_delegator :self, :any?, :exist?
63
- def_delegator :self, :any?, :exists?
64
50
 
65
- def all?
66
- return all? { |item| item } unless block_given?
67
- each { |item| return false unless yield(item) }
68
- true
51
+ # Add up all the items (presumably numeric) in this collection.
52
+ def sum
53
+ reduce(0, &:+)
69
54
  end
70
- def_delegator :self, :all?, :forall?
71
55
 
72
- def none?
73
- return none? { |item| item } unless block_given?
74
- each { |item| return false if yield(item) }
75
- true
76
- end
77
-
78
- def one?
79
- return one? { |item| !!item } unless block_given?
80
- reduce(false) do |previously_matched, item|
81
- if yield(item)
82
- return false if previously_matched
83
- true
84
- else
85
- previously_matched
86
- end
56
+ # Return 2 collections, the first containing all the elements for which the block
57
+ # evaluates to true, the second containing the rest.
58
+ def partition
59
+ return enum_for(:partition) if not block_given?
60
+ a,b = super
61
+ [self.class.new(a), self.class.new(b)].freeze
62
+ end
63
+
64
+ # Combines all elements by applying a binary operation, like `#reduce`, but unlike
65
+ # `#reduce`, do so from starting from the last element to the first. In other words,
66
+ # the order in which elements are yielded is the opposite of `#reduce`.
67
+ def foldr(*args, &block)
68
+ reverse.reduce(*args, &block)
69
+ end
70
+
71
+ # Groups the collection into sub-collections by the result of yielding them to
72
+ # the block. Returns a {Hash} where the keys are return values from the block,
73
+ # and the values are sub-collections. All the sub-collections are built up from
74
+ # `empty_group`, which should respond to `#conj` by returning a new collection
75
+ # with an added element.
76
+ def group_by_with(empty_group, &block)
77
+ block ||= lambda { |item| item }
78
+ reduce(EmptyHash) do |hash, item|
79
+ key = block.call(item)
80
+ group = hash.get(key) || empty_group
81
+ hash.put(key, group.conj(item))
87
82
  end
88
83
  end
89
-
90
- def minimum(&block)
91
- return minimum { |minimum, item| item <=> minimum } unless block_given?
92
- reduce { |minimum, item| yield(minimum, item) < 0 ? item : minimum }
93
- end
94
- def_delegator :self, :minimum, :min
95
-
96
- def maximum(&block)
97
- return maximum { |maximum, item| item <=> maximum } unless block_given?
98
- reduce { |maximum, item| yield(maximum, item) > 0 ? item : maximum }
99
- end
100
- def_delegator :self, :maximum, :max
101
-
102
- def grep(pattern, &block)
103
- filter { |item| pattern === item }.map(&block)
84
+ protected :group_by_with
85
+
86
+ # Groups the collection into sub-collections by the result of yielding them to
87
+ # the block. Returns a {Hash} where the keys are return values from the block,
88
+ # and the values are sub-collections (of the same type as this one).
89
+ def group_by(&block)
90
+ group_by_with(self.class.empty, &block)
91
+ end
92
+
93
+ # Compare with `other`, and return 0, 1, or -1 if it is (respectively) equal to,
94
+ # greater than, or less than this collection.
95
+ def <=>(other)
96
+ return 0 if self.equal?(other)
97
+ enum1, enum2 = self.to_enum, other.to_enum
98
+ loop do
99
+ item1 = enum1.next
100
+ item2 = enum2.next
101
+ comp = (item1 <=> item2)
102
+ return comp if comp != 0
103
+ end
104
+ size1, size2 = self.size, other.size
105
+ return 0 if size1 == size2
106
+ size1 > size2 ? 1 : -1
107
+ end
108
+
109
+ # Return true if `other` contains the same elements, in the same order.
110
+ # @return [Boolean]
111
+ def ==(other)
112
+ self.eql?(other) || other.respond_to?(:to_ary) && to_ary.eql?(other.to_ary)
113
+ end
114
+
115
+ # Convert all the elements into strings and join them together, separated by
116
+ # `separator`. By default, the `separator` is `$,`, the global default string
117
+ # separator, which is normally `nil`.
118
+ def join(separator = $,)
119
+ result = ""
120
+ if separator
121
+ each_with_index { |obj, i| result << separator if i > 0; result << obj.to_s }
122
+ else
123
+ each { |obj| result << obj.to_s }
124
+ end
125
+ result
104
126
  end
105
127
 
106
- def count(&block)
107
- return size unless block_given?
108
- reduce(0) { |count, item| yield(item) ? count + 1 : count }
128
+ # Convert this collection to a {Set}.
129
+ def to_set
130
+ Set.new(self)
109
131
  end
110
132
 
111
- def product
112
- reduce(1, &:*)
133
+ # Convert this collection to a programmer-readable `String` representation.
134
+ def inspect
135
+ result = "#{self.class}["
136
+ each_with_index { |obj, i| result << ', ' if i > 0; result << obj.inspect }
137
+ result << "]"
113
138
  end
114
139
 
115
- def sum
116
- reduce(0, &:+)
140
+ # @private
141
+ def pretty_print(pp)
142
+ pp.group(1, "#{self.class}[", "]") do
143
+ pp.breakable ''
144
+ pp.seplist(self) { |obj| obj.pretty_print(pp) }
145
+ end
117
146
  end
118
147
 
119
- def remove
120
- return self unless block_given?
121
- filter { |item| !yield(item) }
122
- end
123
- def_delegator :self, :remove, :reject
148
+ def_delegator :self, :each, :foreach
149
+ def_delegator :self, :all?, :forall?
150
+ def_delegator :self, :any?, :exist?
151
+ def_delegator :self, :any?, :exists?
152
+ def_delegator :self, :to_a, :to_ary
153
+ def_delegator :self, :filter, :find_all
154
+ def_delegator :self, :filter, :select # make it return a Hamster collection (and possibly make it lazy)
155
+ def_delegator :self, :filter, :keep_if
156
+ def_delegator :self, :include?, :contains?
157
+ def_delegator :self, :include?, :elem?
158
+ def_delegator :self, :max, :maximum
159
+ def_delegator :self, :min, :minimum
160
+ def_delegator :self, :remove, :reject # make it return a Hamster collection (and possibly make it lazy)
124
161
  def_delegator :self, :remove, :delete_if
125
-
126
- def compact
127
- remove(&:nil?)
128
- end
129
-
130
- def to_a
131
- reduce([]) { |a, item| a << item }
162
+ def_delegator :self, :reduce, :fold
163
+ def_delegator :self, :find_index, :index
164
+ def_delegator :self, :find_index, :elem_index
165
+
166
+ ## Compatibility fixes
167
+
168
+ if RUBY_ENGINE == 'rbx'
169
+ # Rubinius implements Enumerable#sort_by using Enumerable#map
170
+ # Because we do our own, custom implementations of #map, that doesn't work well
171
+ # @private
172
+ def sort_by(&block)
173
+ result = to_a
174
+ result.frozen? ? result.sort_by(&block) : result.sort_by!(&block)
175
+ end
132
176
  end
133
- def_delegator :self, :to_a, :entries
134
- def_delegator :self, :to_a, :to_ary
135
177
  end
136
- end
178
+ end