hamster 0.4.3 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/hamster.rb +11 -9
- data/lib/hamster/core_ext.rb +2 -3
- data/lib/hamster/core_ext/enumerable.rb +18 -27
- data/lib/hamster/core_ext/io.rb +16 -25
- data/lib/hamster/deque.rb +252 -0
- data/lib/hamster/enumerable.rb +123 -112
- data/lib/hamster/experimental/mutable_queue.rb +5 -14
- data/lib/hamster/experimental/mutable_set.rb +7 -14
- data/lib/hamster/hash.rb +732 -102
- data/lib/hamster/immutable.rb +4 -10
- data/lib/hamster/list.rb +1155 -215
- data/lib/hamster/{experimental/mutable_hash.rb → mutable_hash.rb} +11 -14
- data/lib/hamster/nested.rb +36 -0
- data/lib/hamster/{experimental/read_copy_update.rb → read_copy_update.rb} +10 -8
- data/lib/hamster/set.rb +488 -90
- data/lib/hamster/sorted_set.rb +1397 -0
- data/lib/hamster/trie.rb +210 -65
- data/lib/hamster/undefined.rb +1 -7
- data/lib/hamster/vector.rb +1329 -83
- data/lib/hamster/version.rb +1 -3
- data/spec/{hamster/core_ext → fixtures}/io_spec.txt +0 -0
- data/spec/lib/hamster/core_ext/array_spec.rb +14 -0
- data/spec/lib/hamster/core_ext/enumerable_spec.rb +30 -0
- data/spec/lib/hamster/core_ext/io_spec.rb +29 -0
- data/spec/lib/hamster/deque/clear_spec.rb +34 -0
- data/spec/lib/hamster/deque/construction_spec.rb +30 -0
- data/spec/lib/hamster/deque/copying_spec.rb +20 -0
- data/spec/lib/hamster/deque/dequeue_spec.rb +35 -0
- data/spec/lib/hamster/deque/empty_spec.rb +40 -0
- data/spec/lib/hamster/deque/enqueue_spec.rb +28 -0
- data/spec/lib/hamster/deque/first_spec.rb +18 -0
- data/spec/lib/hamster/deque/inspect_spec.rb +24 -0
- data/spec/lib/hamster/deque/last_spec.rb +18 -0
- data/spec/lib/hamster/deque/marshal_spec.rb +34 -0
- data/spec/lib/hamster/deque/new_spec.rb +44 -0
- data/spec/lib/hamster/deque/pop_spec.rb +33 -0
- data/spec/lib/hamster/deque/pretty_print_spec.rb +24 -0
- data/spec/lib/hamster/deque/random_modification_spec.rb +34 -0
- data/spec/lib/hamster/deque/size_spec.rb +20 -0
- data/spec/lib/hamster/deque/to_a_spec.rb +27 -0
- data/spec/lib/hamster/deque/to_ary_spec.rb +36 -0
- data/spec/lib/hamster/deque/to_list_spec.rb +26 -0
- data/spec/lib/hamster/deque/unshift_spec.rb +26 -0
- data/spec/lib/hamster/experimental/mutable_set/add_qm_spec.rb +39 -0
- data/spec/lib/hamster/experimental/mutable_set/add_spec.rb +37 -0
- data/spec/lib/hamster/experimental/mutable_set/delete_qm_spec.rb +38 -0
- data/spec/lib/hamster/experimental/mutable_set/delete_spec.rb +37 -0
- data/spec/lib/hamster/hash/all_spec.rb +54 -0
- data/spec/lib/hamster/hash/any_spec.rb +54 -0
- data/spec/lib/hamster/hash/assoc_spec.rb +52 -0
- data/spec/lib/hamster/hash/clear_spec.rb +43 -0
- data/spec/lib/hamster/hash/construction_spec.rb +39 -0
- data/spec/lib/hamster/hash/copying_spec.rb +14 -0
- data/spec/lib/hamster/hash/default_proc_spec.rb +73 -0
- data/spec/lib/hamster/hash/delete_spec.rb +40 -0
- data/spec/lib/hamster/hash/each_spec.rb +78 -0
- data/spec/lib/hamster/hash/each_with_index_spec.rb +30 -0
- data/spec/lib/hamster/hash/empty_spec.rb +44 -0
- data/spec/lib/hamster/hash/eql_spec.rb +70 -0
- data/spec/lib/hamster/hash/except_spec.rb +43 -0
- data/spec/lib/hamster/hash/fetch_spec.rb +58 -0
- data/spec/lib/hamster/hash/find_spec.rb +44 -0
- data/spec/lib/hamster/hash/flat_map_spec.rb +36 -0
- data/spec/lib/hamster/hash/flatten_spec.rb +99 -0
- data/spec/lib/hamster/hash/get_spec.rb +80 -0
- data/spec/lib/hamster/hash/has_key_spec.rb +32 -0
- data/spec/lib/hamster/hash/has_value_spec.rb +28 -0
- data/spec/lib/hamster/hash/hash_spec.rb +30 -0
- data/spec/{hamster → lib/hamster}/hash/immutable_spec.rb +3 -6
- data/spec/lib/hamster/hash/inspect_spec.rb +31 -0
- data/spec/lib/hamster/hash/invert_spec.rb +31 -0
- data/spec/lib/hamster/hash/key_spec.rb +28 -0
- data/spec/lib/hamster/hash/keys_spec.rb +17 -0
- data/spec/lib/hamster/hash/map_spec.rb +46 -0
- data/spec/lib/hamster/hash/marshal_spec.rb +29 -0
- data/spec/lib/hamster/hash/merge_spec.rb +83 -0
- data/spec/lib/hamster/hash/min_max_spec.rb +46 -0
- data/spec/lib/hamster/hash/new_spec.rb +71 -0
- data/spec/lib/hamster/hash/none_spec.rb +49 -0
- data/spec/lib/hamster/hash/partition_spec.rb +36 -0
- data/spec/lib/hamster/hash/pretty_print_spec.rb +35 -0
- data/spec/lib/hamster/hash/put_spec.rb +103 -0
- data/spec/lib/hamster/hash/reduce_spec.rb +36 -0
- data/spec/lib/hamster/hash/reject_spec.rb +62 -0
- data/spec/lib/hamster/hash/reverse_each_spec.rb +28 -0
- data/spec/lib/hamster/hash/sample_spec.rb +14 -0
- data/spec/lib/hamster/hash/select_spec.rb +58 -0
- data/spec/{hamster → lib/hamster}/hash/size_spec.rb +9 -18
- data/spec/lib/hamster/hash/slice_spec.rb +45 -0
- data/spec/lib/hamster/hash/sort_spec.rb +27 -0
- data/spec/lib/hamster/hash/store_spec.rb +76 -0
- data/spec/lib/hamster/hash/take_spec.rb +36 -0
- data/spec/lib/hamster/hash/to_a_spec.rb +14 -0
- data/spec/lib/hamster/hash/to_hash_spec.rb +22 -0
- data/spec/lib/hamster/hash/update_in_spec.rb +80 -0
- data/spec/lib/hamster/hash/values_at_spec.rb +14 -0
- data/spec/lib/hamster/hash/values_spec.rb +25 -0
- data/spec/{hamster → lib/hamster}/immutable/copying_spec.rb +3 -10
- data/spec/{hamster → lib/hamster}/immutable/immutable_spec.rb +3 -16
- data/spec/lib/hamster/immutable/memoize_spec.rb +56 -0
- data/spec/lib/hamster/immutable/new_spec.rb +14 -0
- data/spec/lib/hamster/immutable/transform_spec.rb +26 -0
- data/spec/lib/hamster/immutable/transform_unless_spec.rb +44 -0
- data/spec/lib/hamster/list/add_spec.rb +26 -0
- data/spec/lib/hamster/list/all_spec.rb +58 -0
- data/spec/lib/hamster/list/any_spec.rb +50 -0
- data/spec/lib/hamster/list/append_spec.rb +39 -0
- data/spec/lib/hamster/list/at_spec.rb +30 -0
- data/spec/lib/hamster/list/break_spec.rb +70 -0
- data/spec/lib/hamster/list/cadr_spec.rb +39 -0
- data/spec/lib/hamster/list/chunk_spec.rb +29 -0
- data/spec/lib/hamster/list/clear_spec.rb +25 -0
- data/spec/lib/hamster/list/combination_spec.rb +34 -0
- data/spec/lib/hamster/list/compact_spec.rb +35 -0
- data/spec/lib/hamster/list/compare_spec.rb +31 -0
- data/spec/lib/hamster/list/cons_spec.rb +26 -0
- data/spec/lib/hamster/list/construction_spec.rb +111 -0
- data/spec/lib/hamster/list/copying_spec.rb +20 -0
- data/spec/lib/hamster/list/count_spec.rb +37 -0
- data/spec/lib/hamster/list/cycle_spec.rb +29 -0
- data/spec/lib/hamster/list/delete_at_spec.rb +19 -0
- data/spec/lib/hamster/list/delete_spec.rb +17 -0
- data/spec/lib/hamster/list/drop_spec.rb +31 -0
- data/spec/lib/hamster/list/drop_while_spec.rb +39 -0
- data/spec/lib/hamster/list/each_slice_spec.rb +52 -0
- data/spec/lib/hamster/list/each_spec.rb +41 -0
- data/spec/lib/hamster/list/each_with_index_spec.rb +29 -0
- data/spec/lib/hamster/list/empty_spec.rb +24 -0
- data/spec/lib/hamster/list/eql_spec.rb +62 -0
- data/spec/lib/hamster/list/fill_spec.rb +50 -0
- data/spec/lib/hamster/list/find_all_spec.rb +71 -0
- data/spec/{hamster → lib/hamster}/list/find_index_spec.rb +7 -29
- data/spec/{hamster → lib/hamster}/list/find_spec.rb +13 -35
- data/spec/lib/hamster/list/flat_map_spec.rb +52 -0
- data/spec/lib/hamster/list/flatten_spec.rb +31 -0
- data/spec/lib/hamster/list/grep_spec.rb +47 -0
- data/spec/lib/hamster/list/group_by_spec.rb +42 -0
- data/spec/lib/hamster/list/hash_spec.rb +22 -0
- data/spec/{hamster → lib/hamster}/list/head_spec.rb +6 -21
- data/spec/{hamster → lib/hamster}/list/include_spec.rb +8 -29
- data/spec/lib/hamster/list/index_spec.rb +34 -0
- data/spec/lib/hamster/list/indices_spec.rb +62 -0
- data/spec/lib/hamster/list/init_spec.rb +29 -0
- data/spec/lib/hamster/list/inits_spec.rb +29 -0
- data/spec/lib/hamster/list/insert_spec.rb +47 -0
- data/spec/lib/hamster/list/inspect_spec.rb +30 -0
- data/spec/lib/hamster/list/intersperse_spec.rb +29 -0
- data/spec/lib/hamster/list/join_spec.rb +64 -0
- data/spec/lib/hamster/list/last_spec.rb +24 -0
- data/spec/lib/hamster/list/ltlt_spec.rb +20 -0
- data/spec/lib/hamster/list/map_spec.rb +46 -0
- data/spec/lib/hamster/list/maximum_spec.rb +40 -0
- data/spec/{hamster → lib/hamster}/list/merge_by_spec.rb +9 -36
- data/spec/{hamster → lib/hamster}/list/merge_spec.rb +5 -24
- data/spec/lib/hamster/list/minimum_spec.rb +40 -0
- data/spec/lib/hamster/list/multithreading_spec.rb +48 -0
- data/spec/{hamster → lib/hamster}/list/none_spec.rb +14 -41
- data/spec/{hamster → lib/hamster}/list/one_spec.rb +15 -40
- data/spec/lib/hamster/list/partition_spec.rb +116 -0
- data/spec/lib/hamster/list/permutation_spec.rb +56 -0
- data/spec/lib/hamster/list/pop_spec.rb +26 -0
- data/spec/lib/hamster/list/product_spec.rb +24 -0
- data/spec/lib/hamster/list/reduce_spec.rb +54 -0
- data/spec/lib/hamster/list/reject_spec.rb +46 -0
- data/spec/lib/hamster/list/reverse_spec.rb +35 -0
- data/spec/lib/hamster/list/rotate_spec.rb +37 -0
- data/spec/lib/hamster/list/sample_spec.rb +14 -0
- data/spec/lib/hamster/list/select_spec.rb +71 -0
- data/spec/lib/hamster/list/size_spec.rb +26 -0
- data/spec/lib/hamster/list/slice_spec.rb +230 -0
- data/spec/lib/hamster/list/sorting_spec.rb +47 -0
- data/spec/lib/hamster/list/span_spec.rb +77 -0
- data/spec/lib/hamster/list/split_at_spec.rb +44 -0
- data/spec/lib/hamster/list/subsequences_spec.rb +24 -0
- data/spec/lib/hamster/list/sum_spec.rb +24 -0
- data/spec/lib/hamster/list/tail_spec.rb +31 -0
- data/spec/lib/hamster/list/tails_spec.rb +29 -0
- data/spec/lib/hamster/list/take_spec.rb +31 -0
- data/spec/lib/hamster/list/take_while_spec.rb +47 -0
- data/spec/lib/hamster/list/to_a_spec.rb +40 -0
- data/spec/lib/hamster/list/to_ary_spec.rb +42 -0
- data/spec/lib/hamster/list/to_list_spec.rb +20 -0
- data/spec/lib/hamster/list/to_set_spec.rb +19 -0
- data/spec/lib/hamster/list/transpose_spec.rb +20 -0
- data/spec/lib/hamster/list/union_spec.rb +32 -0
- data/spec/lib/hamster/list/uniq_spec.rb +30 -0
- data/spec/lib/hamster/list/zip_spec.rb +24 -0
- data/spec/lib/hamster/nested/construction_spec.rb +44 -0
- data/spec/lib/hamster/set/add_spec.rb +76 -0
- data/spec/lib/hamster/set/all_spec.rb +52 -0
- data/spec/lib/hamster/set/any_spec.rb +52 -0
- data/spec/lib/hamster/set/clear_spec.rb +34 -0
- data/spec/{hamster → lib/hamster}/set/compact_spec.rb +9 -20
- data/spec/lib/hamster/set/construction_spec.rb +19 -0
- data/spec/lib/hamster/set/copying_spec.rb +14 -0
- data/spec/lib/hamster/set/count_spec.rb +37 -0
- data/spec/lib/hamster/set/delete_spec.rb +72 -0
- data/spec/lib/hamster/set/difference_spec.rb +50 -0
- data/spec/lib/hamster/set/disjoint_spec.rb +26 -0
- data/spec/lib/hamster/set/each_spec.rb +46 -0
- data/spec/lib/hamster/set/empty_spec.rb +45 -0
- data/spec/lib/hamster/set/eqeq_spec.rb +104 -0
- data/spec/lib/hamster/set/eql_spec.rb +110 -0
- data/spec/lib/hamster/set/exclusion_spec.rb +48 -0
- data/spec/{hamster → lib/hamster}/set/find_spec.rb +10 -27
- data/spec/lib/hamster/set/first_spec.rb +29 -0
- data/spec/lib/hamster/set/flatten_spec.rb +47 -0
- data/spec/lib/hamster/set/grep_spec.rb +58 -0
- data/spec/lib/hamster/set/group_by_spec.rb +60 -0
- data/spec/lib/hamster/set/hash_spec.rb +23 -0
- data/spec/{hamster → lib/hamster}/set/immutable_spec.rb +4 -7
- data/spec/lib/hamster/set/include_spec.rb +61 -0
- data/spec/lib/hamster/set/inspect_spec.rb +48 -0
- data/spec/lib/hamster/set/intersect_spec.rb +26 -0
- data/spec/lib/hamster/set/intersection_spec.rb +53 -0
- data/spec/lib/hamster/set/join_spec.rb +65 -0
- data/spec/lib/hamster/set/map_spec.rb +60 -0
- data/spec/lib/hamster/set/marshal_spec.rb +29 -0
- data/spec/lib/hamster/set/maximum_spec.rb +37 -0
- data/spec/lib/hamster/set/minimum_spec.rb +37 -0
- data/spec/lib/hamster/set/new_spec.rb +54 -0
- data/spec/{hamster → lib/hamster}/set/none_spec.rb +17 -32
- data/spec/{hamster → lib/hamster}/set/one_spec.rb +16 -31
- data/spec/lib/hamster/set/partition_spec.rb +53 -0
- data/spec/lib/hamster/set/product_spec.rb +24 -0
- data/spec/lib/hamster/set/reduce_spec.rb +56 -0
- data/spec/lib/hamster/set/reject_spec.rb +51 -0
- data/spec/lib/hamster/set/reverse_each_spec.rb +39 -0
- data/spec/lib/hamster/set/sample_spec.rb +14 -0
- data/spec/lib/hamster/set/select_spec.rb +74 -0
- data/spec/{hamster → lib/hamster}/set/size_spec.rb +4 -13
- data/spec/lib/hamster/set/sorting_spec.rb +49 -0
- data/spec/lib/hamster/set/subset_spec.rb +52 -0
- data/spec/lib/hamster/set/sum_spec.rb +24 -0
- data/spec/lib/hamster/set/superset_spec.rb +52 -0
- data/spec/lib/hamster/set/to_a_spec.rb +31 -0
- data/spec/lib/hamster/set/to_list_spec.rb +37 -0
- data/spec/lib/hamster/set/to_set_spec.rb +20 -0
- data/spec/lib/hamster/set/union_spec.rb +64 -0
- data/spec/lib/hamster/sorted_set/above_spec.rb +52 -0
- data/spec/lib/hamster/sorted_set/add_spec.rb +63 -0
- data/spec/lib/hamster/sorted_set/at_spec.rb +25 -0
- data/spec/lib/hamster/sorted_set/below_spec.rb +52 -0
- data/spec/lib/hamster/sorted_set/between_spec.rb +52 -0
- data/spec/lib/hamster/sorted_set/clear_spec.rb +44 -0
- data/spec/lib/hamster/sorted_set/construction_spec.rb +29 -0
- data/spec/lib/hamster/sorted_set/delete_at_spec.rb +19 -0
- data/spec/lib/hamster/sorted_set/delete_spec.rb +90 -0
- data/spec/lib/hamster/sorted_set/difference_spec.rb +23 -0
- data/spec/lib/hamster/sorted_set/disjoint_spec.rb +26 -0
- data/spec/lib/hamster/sorted_set/drop_spec.rb +56 -0
- data/spec/lib/hamster/sorted_set/drop_while_spec.rb +35 -0
- data/spec/lib/hamster/sorted_set/each_spec.rb +29 -0
- data/spec/lib/hamster/sorted_set/empty_spec.rb +35 -0
- data/spec/lib/hamster/sorted_set/eql_spec.rb +121 -0
- data/spec/lib/hamster/sorted_set/exclusion_spec.rb +23 -0
- data/spec/lib/hamster/sorted_set/fetch_spec.rb +65 -0
- data/spec/lib/hamster/sorted_set/find_index_spec.rb +41 -0
- data/spec/lib/hamster/sorted_set/first_spec.rb +19 -0
- data/spec/lib/hamster/sorted_set/from_spec.rb +52 -0
- data/spec/lib/hamster/sorted_set/group_by_spec.rb +58 -0
- data/spec/lib/hamster/sorted_set/include_spec.rb +24 -0
- data/spec/lib/hamster/sorted_set/inspect_spec.rb +38 -0
- data/spec/lib/hamster/sorted_set/intersect_spec.rb +26 -0
- data/spec/lib/hamster/sorted_set/intersection_spec.rb +29 -0
- data/spec/lib/hamster/sorted_set/last_spec.rb +37 -0
- data/spec/lib/hamster/sorted_set/map_spec.rb +36 -0
- data/spec/lib/hamster/sorted_set/marshal_spec.rb +37 -0
- data/spec/lib/hamster/sorted_set/maximum_spec.rb +37 -0
- data/spec/lib/hamster/sorted_set/minimum_spec.rb +20 -0
- data/spec/lib/hamster/sorted_set/new_spec.rb +52 -0
- data/spec/lib/hamster/sorted_set/reverse_each_spec.rb +29 -0
- data/spec/lib/hamster/sorted_set/sample_spec.rb +14 -0
- data/spec/lib/hamster/sorted_set/select_spec.rb +62 -0
- data/spec/{hamster/vector → lib/hamster/sorted_set}/size_spec.rb +6 -15
- data/spec/lib/hamster/sorted_set/slice_spec.rb +257 -0
- data/spec/lib/hamster/sorted_set/sorting_spec.rb +45 -0
- data/spec/lib/hamster/sorted_set/subset_spec.rb +48 -0
- data/spec/lib/hamster/sorted_set/superset_spec.rb +48 -0
- data/spec/lib/hamster/sorted_set/take_spec.rb +55 -0
- data/spec/lib/hamster/sorted_set/take_while_spec.rb +34 -0
- data/spec/lib/hamster/sorted_set/to_set_spec.rb +19 -0
- data/spec/lib/hamster/sorted_set/union_spec.rb +28 -0
- data/spec/lib/hamster/sorted_set/up_to_spec.rb +52 -0
- data/spec/lib/hamster/sorted_set/values_at_spec.rb +34 -0
- data/spec/lib/hamster/vector/add_spec.rb +68 -0
- data/spec/lib/hamster/vector/any_spec.rb +70 -0
- data/spec/lib/hamster/vector/assoc_spec.rb +36 -0
- data/spec/lib/hamster/vector/bsearch_spec.rb +58 -0
- data/spec/lib/hamster/vector/clear_spec.rb +34 -0
- data/spec/lib/hamster/vector/combination_spec.rb +82 -0
- data/spec/lib/hamster/vector/compact_spec.rb +30 -0
- data/spec/lib/hamster/vector/compare_spec.rb +32 -0
- data/spec/lib/hamster/vector/concat_spec.rb +35 -0
- data/spec/lib/hamster/vector/copying_spec.rb +21 -0
- data/spec/lib/hamster/vector/count_spec.rb +18 -0
- data/spec/lib/hamster/vector/delete_at_spec.rb +54 -0
- data/spec/lib/hamster/vector/delete_spec.rb +31 -0
- data/spec/lib/hamster/vector/drop_spec.rb +42 -0
- data/spec/lib/hamster/vector/drop_while_spec.rb +55 -0
- data/spec/lib/hamster/vector/each_index_spec.rb +41 -0
- data/spec/lib/hamster/vector/each_spec.rb +45 -0
- data/spec/lib/hamster/vector/each_with_index_spec.rb +40 -0
- data/spec/lib/hamster/vector/empty_spec.rb +42 -0
- data/spec/lib/hamster/vector/eql_spec.rb +77 -0
- data/spec/lib/hamster/vector/fetch_spec.rb +65 -0
- data/spec/lib/hamster/vector/fill_spec.rb +89 -0
- data/spec/lib/hamster/vector/first_spec.rb +19 -0
- data/spec/lib/hamster/vector/flat_map_spec.rb +51 -0
- data/spec/lib/hamster/vector/flatten_spec.rb +44 -0
- data/spec/lib/hamster/vector/get_spec.rb +75 -0
- data/spec/lib/hamster/vector/group_by_spec.rb +58 -0
- data/spec/{hamster → lib/hamster}/vector/include_spec.rb +6 -20
- data/spec/lib/hamster/vector/insert_spec.rb +69 -0
- data/spec/lib/hamster/vector/inspect_spec.rb +50 -0
- data/spec/{hamster/set → lib/hamster/vector}/join_spec.rb +24 -34
- data/spec/lib/hamster/vector/last_spec.rb +46 -0
- data/spec/lib/hamster/vector/length_spec.rb +46 -0
- data/spec/lib/hamster/vector/ltlt_spec.rb +66 -0
- data/spec/lib/hamster/vector/map_spec.rb +52 -0
- data/spec/lib/hamster/vector/marshal_spec.rb +32 -0
- data/spec/lib/hamster/vector/maximum_spec.rb +34 -0
- data/spec/lib/hamster/vector/minimum_spec.rb +34 -0
- data/spec/lib/hamster/vector/multiply_spec.rb +48 -0
- data/spec/lib/hamster/vector/new_spec.rb +51 -0
- data/spec/lib/hamster/vector/partition_spec.rb +53 -0
- data/spec/lib/hamster/vector/permutation_spec.rb +92 -0
- data/spec/lib/hamster/vector/pop_spec.rb +27 -0
- data/spec/lib/hamster/vector/product_spec.rb +71 -0
- data/spec/{hamster → lib/hamster}/vector/reduce_spec.rb +18 -49
- data/spec/lib/hamster/vector/reject_spec.rb +44 -0
- data/spec/lib/hamster/vector/repeated_combination_spec.rb +78 -0
- data/spec/lib/hamster/vector/repeated_permutation_spec.rb +94 -0
- data/spec/lib/hamster/vector/reverse_each_spec.rb +32 -0
- data/spec/lib/hamster/vector/reverse_spec.rb +22 -0
- data/spec/lib/hamster/vector/rindex_spec.rb +37 -0
- data/spec/lib/hamster/vector/rotate_spec.rb +74 -0
- data/spec/lib/hamster/vector/sample_spec.rb +14 -0
- data/spec/lib/hamster/vector/select_spec.rb +64 -0
- data/spec/lib/hamster/vector/set_spec.rb +175 -0
- data/spec/lib/hamster/vector/shift_spec.rb +28 -0
- data/spec/lib/hamster/vector/shuffle_spec.rb +44 -0
- data/spec/lib/hamster/vector/slice_spec.rb +241 -0
- data/spec/lib/hamster/vector/sorting_spec.rb +57 -0
- data/spec/{hamster/set → lib/hamster/vector}/sum_spec.rb +5 -19
- data/spec/lib/hamster/vector/take_spec.rb +43 -0
- data/spec/lib/hamster/vector/take_while_spec.rb +35 -0
- data/spec/lib/hamster/vector/to_a_spec.rb +42 -0
- data/spec/lib/hamster/vector/to_ary_spec.rb +35 -0
- data/spec/lib/hamster/vector/to_list_spec.rb +32 -0
- data/spec/lib/hamster/vector/to_set_spec.rb +23 -0
- data/spec/lib/hamster/vector/transpose_spec.rb +49 -0
- data/spec/lib/hamster/vector/uniq_spec.rb +56 -0
- data/spec/lib/hamster/vector/unshift_spec.rb +29 -0
- data/spec/lib/hamster/vector/update_in_spec.rb +83 -0
- data/spec/lib/hamster/vector/values_at_spec.rb +34 -0
- data/spec/lib/hamster/vector/zip_spec.rb +58 -0
- data/spec/spec_helper.rb +45 -13
- metadata +807 -458
- data/History.rdoc +0 -419
- data/LICENSE +0 -20
- data/README.rdoc +0 -236
- data/Rakefile +0 -5
- data/lib/hamster/core_ext/enumerator.rb +0 -30
- data/lib/hamster/experimental/mutable_stack.rb +0 -35
- data/lib/hamster/queue.rb +0 -93
- data/lib/hamster/sorter.rb +0 -32
- data/lib/hamster/stack.rb +0 -82
- data/lib/hamster/tuple.rb +0 -45
- data/spec/hamster/core_ext/array_spec.rb +0 -20
- data/spec/hamster/core_ext/coverage/assets/0.4.4/app.js +0 -66
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/blank.gif +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_close.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_loading.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_nav_left.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_nav_right.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_shadow_e.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_shadow_n.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_shadow_ne.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_shadow_nw.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_shadow_s.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_shadow_se.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_shadow_sw.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_shadow_w.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_title_left.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_title_main.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_title_over.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_title_right.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancybox-x.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancybox-y.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancybox.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/jquery.fancybox-1.3.1.css +0 -363
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/jquery.fancybox-1.3.1.pack.js +0 -44
- data/spec/hamster/core_ext/coverage/assets/0.4.4/favicon.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/jquery-1.4.2.min.js +0 -155
- data/spec/hamster/core_ext/coverage/assets/0.4.4/jquery.dataTables.min.js +0 -152
- data/spec/hamster/core_ext/coverage/assets/0.4.4/jquery.timeago.js +0 -141
- data/spec/hamster/core_ext/coverage/assets/0.4.4/jquery.url.js +0 -174
- data/spec/hamster/core_ext/coverage/assets/0.4.4/loading.gif +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/magnify.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/jquery-ui-1.8.4.custom.css +0 -295
- data/spec/hamster/core_ext/coverage/assets/0.4.4/stylesheet.css +0 -341
- data/spec/hamster/core_ext/coverage/covered_percent +0 -1
- data/spec/hamster/core_ext/coverage/index.html +0 -71
- data/spec/hamster/core_ext/coverage/resultset.yml +0 -10
- data/spec/hamster/core_ext/enumerable_spec.rb +0 -34
- data/spec/hamster/core_ext/enumerator_spec.rb +0 -25
- data/spec/hamster/core_ext/io_spec.rb +0 -29
- data/spec/hamster/experimental/mutable_set/add?_spec.rb +0 -47
- data/spec/hamster/experimental/mutable_set/add_spec.rb +0 -51
- data/spec/hamster/experimental/mutable_set/delete?_spec.rb +0 -47
- data/spec/hamster/experimental/mutable_set/delete_spec.rb +0 -47
- data/spec/hamster/experimental/mutable_stack/pop_spec.rb +0 -41
- data/spec/hamster/experimental/mutable_stack/push_spec.rb +0 -41
- data/spec/hamster/hash/all_spec.rb +0 -59
- data/spec/hamster/hash/any_spec.rb +0 -68
- data/spec/hamster/hash/clear_spec.rb +0 -36
- data/spec/hamster/hash/construction_spec.rb +0 -35
- data/spec/hamster/hash/copying_spec.rb +0 -23
- data/spec/hamster/hash/delete_spec.rb +0 -47
- data/spec/hamster/hash/each_spec.rb +0 -41
- data/spec/hamster/hash/empty_spec.rb +0 -27
- data/spec/hamster/hash/eql_spec.rb +0 -62
- data/spec/hamster/hash/except_spec.rb +0 -31
- data/spec/hamster/hash/fetch_spec.rb +0 -95
- data/spec/hamster/hash/filter_spec.rb +0 -63
- data/spec/hamster/hash/find_spec.rb +0 -58
- data/spec/hamster/hash/get_spec.rb +0 -68
- data/spec/hamster/hash/has_key_spec.rb +0 -35
- data/spec/hamster/hash/hash_spec.rb +0 -54
- data/spec/hamster/hash/inspect_spec.rb +0 -32
- data/spec/hamster/hash/keys_spec.rb +0 -21
- data/spec/hamster/hash/map_spec.rb +0 -64
- data/spec/hamster/hash/merge_spec.rb +0 -36
- data/spec/hamster/hash/none_spec.rb +0 -64
- data/spec/hamster/hash/put_spec.rb +0 -65
- data/spec/hamster/hash/reduce_spec.rb +0 -60
- data/spec/hamster/hash/remove_spec.rb +0 -63
- data/spec/hamster/hash/slice_spec.rb +0 -31
- data/spec/hamster/hash/uniq_spec.rb +0 -23
- data/spec/hamster/hash/values_spec.rb +0 -34
- data/spec/hamster/immutable/memoize_spec.rb +0 -64
- data/spec/hamster/immutable/new_spec.rb +0 -28
- data/spec/hamster/immutable/transform_spec.rb +0 -31
- data/spec/hamster/immutable/transform_unless_spec.rb +0 -55
- data/spec/hamster/list/all_spec.rb +0 -111
- data/spec/hamster/list/any_spec.rb +0 -79
- data/spec/hamster/list/append_spec.rb +0 -50
- data/spec/hamster/list/at_spec.rb +0 -49
- data/spec/hamster/list/break_spec.rb +0 -85
- data/spec/hamster/list/cadr_spec.rb +0 -50
- data/spec/hamster/list/chunk_spec.rb +0 -40
- data/spec/hamster/list/clear_spec.rb +0 -36
- data/spec/hamster/list/combinations_spec.rb +0 -51
- data/spec/hamster/list/compact_spec.rb +0 -46
- data/spec/hamster/list/cons_spec.rb +0 -41
- data/spec/hamster/list/construction_spec.rb +0 -140
- data/spec/hamster/list/copying_spec.rb +0 -32
- data/spec/hamster/list/count_spec.rb +0 -66
- data/spec/hamster/list/coverage/assets/0.4.4/app.js +0 -66
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/blank.gif +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_close.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_loading.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_nav_left.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_nav_right.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_shadow_e.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_shadow_n.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_shadow_ne.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_shadow_nw.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_shadow_s.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_shadow_se.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_shadow_sw.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_shadow_w.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_title_left.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_title_main.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_title_over.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_title_right.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancybox-x.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancybox-y.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancybox.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/jquery.fancybox-1.3.1.css +0 -363
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/jquery.fancybox-1.3.1.pack.js +0 -44
- data/spec/hamster/list/coverage/assets/0.4.4/favicon.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/jquery-1.4.2.min.js +0 -155
- data/spec/hamster/list/coverage/assets/0.4.4/jquery.dataTables.min.js +0 -152
- data/spec/hamster/list/coverage/assets/0.4.4/jquery.timeago.js +0 -141
- data/spec/hamster/list/coverage/assets/0.4.4/jquery.url.js +0 -174
- data/spec/hamster/list/coverage/assets/0.4.4/loading.gif +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/magnify.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/smoothness/jquery-ui-1.8.4.custom.css +0 -295
- data/spec/hamster/list/coverage/assets/0.4.4/stylesheet.css +0 -341
- data/spec/hamster/list/coverage/covered_percent +0 -1
- data/spec/hamster/list/coverage/index.html +0 -71
- data/spec/hamster/list/coverage/resultset.yml +0 -225
- data/spec/hamster/list/cycle_spec.rb +0 -45
- data/spec/hamster/list/drop_spec.rb +0 -42
- data/spec/hamster/list/drop_while_spec.rb +0 -59
- data/spec/hamster/list/each_slice_spec.rb +0 -80
- data/spec/hamster/list/each_spec.rb +0 -72
- data/spec/hamster/list/each_with_index_spec.rb +0 -42
- data/spec/hamster/list/elem_index_spec.rb +0 -58
- data/spec/hamster/list/elem_indices_spec.rb +0 -45
- data/spec/hamster/list/empty_spec.rb +0 -47
- data/spec/hamster/list/eql_spec.rb +0 -78
- data/spec/hamster/list/filter_spec.rb +0 -61
- data/spec/hamster/list/find_indices_spec.rb +0 -45
- data/spec/hamster/list/flatten_spec.rb +0 -42
- data/spec/hamster/list/grep_spec.rb +0 -70
- data/spec/hamster/list/group_by_spec.rb +0 -77
- data/spec/hamster/list/hash_spec.rb +0 -43
- data/spec/hamster/list/init_spec.rb +0 -40
- data/spec/hamster/list/inits_spec.rb +0 -42
- data/spec/hamster/list/inspect_spec.rb +0 -43
- data/spec/hamster/list/intersperse_spec.rb +0 -40
- data/spec/hamster/list/join_spec.rb +0 -81
- data/spec/hamster/list/last_spec.rb +0 -44
- data/spec/hamster/list/map_spec.rb +0 -69
- data/spec/hamster/list/maximum_spec.rb +0 -77
- data/spec/hamster/list/minimum_spec.rb +0 -77
- data/spec/hamster/list/partition_spec.rb +0 -75
- data/spec/hamster/list/product_spec.rb +0 -44
- data/spec/hamster/list/reduce_spec.rb +0 -99
- data/spec/hamster/list/remove_spec.rb +0 -67
- data/spec/hamster/list/reverse_spec.rb +0 -52
- data/spec/hamster/list/size_spec.rb +0 -47
- data/spec/hamster/list/slice_spec.rb +0 -50
- data/spec/hamster/list/sorting_spec.rb +0 -70
- data/spec/hamster/list/span_spec.rb +0 -86
- data/spec/hamster/list/split_at_spec.rb +0 -53
- data/spec/hamster/list/sum_spec.rb +0 -44
- data/spec/hamster/list/tail_spec.rb +0 -48
- data/spec/hamster/list/tails_spec.rb +0 -42
- data/spec/hamster/list/take_spec.rb +0 -42
- data/spec/hamster/list/take_while_spec.rb +0 -62
- data/spec/hamster/list/to_a_spec.rb +0 -54
- data/spec/hamster/list/to_ary_spec.rb +0 -56
- data/spec/hamster/list/to_list_spec.rb +0 -32
- data/spec/hamster/list/to_set_spec.rb +0 -33
- data/spec/hamster/list/union_spec.rb +0 -49
- data/spec/hamster/list/uniq_spec.rb +0 -45
- data/spec/hamster/list/zip_spec.rb +0 -39
- data/spec/hamster/queue/clear_spec.rb +0 -36
- data/spec/hamster/queue/construction_spec.rb +0 -43
- data/spec/hamster/queue/dequeue_spec.rb +0 -40
- data/spec/hamster/queue/empty_spec.rb +0 -47
- data/spec/hamster/queue/enqueue_spec.rb +0 -41
- data/spec/hamster/queue/head_spec.rb +0 -35
- data/spec/hamster/queue/inspect_spec.rb +0 -31
- data/spec/hamster/queue/size_spec.rb +0 -35
- data/spec/hamster/queue/to_a_spec.rb +0 -42
- data/spec/hamster/queue/to_ary_spec.rb +0 -44
- data/spec/hamster/queue/to_list_spec.rb +0 -44
- data/spec/hamster/set/add_spec.rb +0 -51
- data/spec/hamster/set/all_spec.rb +0 -67
- data/spec/hamster/set/any_spec.rb +0 -67
- data/spec/hamster/set/clear_spec.rb +0 -36
- data/spec/hamster/set/construction_spec.rb +0 -31
- data/spec/hamster/set/copying_spec.rb +0 -23
- data/spec/hamster/set/count_spec.rb +0 -54
- data/spec/hamster/set/coverage/assets/0.4.4/app.js +0 -66
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/blank.gif +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_close.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_loading.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_nav_left.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_nav_right.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_shadow_e.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_shadow_n.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_shadow_ne.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_shadow_nw.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_shadow_s.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_shadow_se.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_shadow_sw.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_shadow_w.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_title_left.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_title_main.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_title_over.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_title_right.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancybox-x.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancybox-y.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancybox.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/jquery.fancybox-1.3.1.css +0 -363
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/jquery.fancybox-1.3.1.pack.js +0 -44
- data/spec/hamster/set/coverage/assets/0.4.4/favicon.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/jquery-1.4.2.min.js +0 -155
- data/spec/hamster/set/coverage/assets/0.4.4/jquery.dataTables.min.js +0 -152
- data/spec/hamster/set/coverage/assets/0.4.4/jquery.timeago.js +0 -141
- data/spec/hamster/set/coverage/assets/0.4.4/jquery.url.js +0 -174
- data/spec/hamster/set/coverage/assets/0.4.4/loading.gif +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/magnify.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/smoothness/jquery-ui-1.8.4.custom.css +0 -295
- data/spec/hamster/set/coverage/assets/0.4.4/stylesheet.css +0 -341
- data/spec/hamster/set/coverage/covered_percent +0 -1
- data/spec/hamster/set/coverage/index.html +0 -71
- data/spec/hamster/set/coverage/resultset.yml +0 -13
- data/spec/hamster/set/delete_spec.rb +0 -47
- data/spec/hamster/set/difference_spec.rb +0 -37
- data/spec/hamster/set/each_spec.rb +0 -42
- data/spec/hamster/set/empty_spec.rb +0 -35
- data/spec/hamster/set/eql_spec.rb +0 -62
- data/spec/hamster/set/exclusion_spec.rb +0 -38
- data/spec/hamster/set/filter_spec.rb +0 -79
- data/spec/hamster/set/flatten_spec.rb +0 -49
- data/spec/hamster/set/grep_spec.rb +0 -62
- data/spec/hamster/set/group_by_spec.rb +0 -65
- data/spec/hamster/set/hash_spec.rb +0 -31
- data/spec/hamster/set/head_spec.rb +0 -39
- data/spec/hamster/set/include_spec.rb +0 -35
- data/spec/hamster/set/inspect_spec.rb +0 -32
- data/spec/hamster/set/intersection_spec.rb +0 -46
- data/spec/hamster/set/map_spec.rb +0 -64
- data/spec/hamster/set/maximum_spec.rb +0 -65
- data/spec/hamster/set/minimum_spec.rb +0 -65
- data/spec/hamster/set/partition_spec.rb +0 -71
- data/spec/hamster/set/product_spec.rb +0 -32
- data/spec/hamster/set/reduce_spec.rb +0 -87
- data/spec/hamster/set/remove_spec.rb +0 -63
- data/spec/hamster/set/sorting_spec.rb +0 -58
- data/spec/hamster/set/subset_spec.rb +0 -39
- data/spec/hamster/set/superset_spec.rb +0 -39
- data/spec/hamster/set/to_a_spec.rb +0 -42
- data/spec/hamster/set/to_list_spec.rb +0 -47
- data/spec/hamster/set/to_set_spec.rb +0 -32
- data/spec/hamster/set/union_spec.rb +0 -45
- data/spec/hamster/set/uniq_spec.rb +0 -23
- data/spec/hamster/sorter/coverage/assets/0.4.4/app.js +0 -66
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/blank.gif +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_close.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_loading.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_nav_left.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_nav_right.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_shadow_e.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_shadow_n.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_shadow_ne.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_shadow_nw.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_shadow_s.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_shadow_se.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_shadow_sw.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_shadow_w.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_title_left.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_title_main.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_title_over.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_title_right.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancybox-x.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancybox-y.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancybox.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/jquery.fancybox-1.3.1.css +0 -363
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/jquery.fancybox-1.3.1.pack.js +0 -44
- data/spec/hamster/sorter/coverage/assets/0.4.4/favicon.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/jquery-1.4.2.min.js +0 -155
- data/spec/hamster/sorter/coverage/assets/0.4.4/jquery.dataTables.min.js +0 -152
- data/spec/hamster/sorter/coverage/assets/0.4.4/jquery.timeago.js +0 -141
- data/spec/hamster/sorter/coverage/assets/0.4.4/jquery.url.js +0 -174
- data/spec/hamster/sorter/coverage/assets/0.4.4/loading.gif +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/magnify.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/jquery-ui-1.8.4.custom.css +0 -295
- data/spec/hamster/sorter/coverage/assets/0.4.4/stylesheet.css +0 -341
- data/spec/hamster/sorter/coverage/covered_percent +0 -1
- data/spec/hamster/sorter/coverage/index.html +0 -71
- data/spec/hamster/sorter/coverage/resultset.yml +0 -22
- data/spec/hamster/sorter/immutable_spec.rb +0 -12
- data/spec/hamster/stack/clear_spec.rb +0 -36
- data/spec/hamster/stack/construction_spec.rb +0 -43
- data/spec/hamster/stack/copying_spec.rb +0 -31
- data/spec/hamster/stack/empty_spec.rb +0 -31
- data/spec/hamster/stack/eql_spec.rb +0 -60
- data/spec/hamster/stack/immutable_spec.rb +0 -12
- data/spec/hamster/stack/inspect_spec.rb +0 -31
- data/spec/hamster/stack/peek_spec.rb +0 -40
- data/spec/hamster/stack/pop_spec.rb +0 -41
- data/spec/hamster/stack/push_spec.rb +0 -41
- data/spec/hamster/stack/size_spec.rb +0 -35
- data/spec/hamster/stack/to_a_spec.rb +0 -42
- data/spec/hamster/stack/to_ary.rb +0 -44
- data/spec/hamster/stack/to_list_spec.rb +0 -33
- data/spec/hamster/trie/remove_spec.rb +0 -117
- data/spec/hamster/tuple/copying_spec.rb +0 -24
- data/spec/hamster/tuple/eql_spec.rb +0 -61
- data/spec/hamster/tuple/first_spec.rb +0 -19
- data/spec/hamster/tuple/immutable_spec.rb +0 -12
- data/spec/hamster/tuple/inspect_spec.rb +0 -19
- data/spec/hamster/tuple/last_spec.rb +0 -19
- data/spec/hamster/tuple/to_a_spec.rb +0 -38
- data/spec/hamster/tuple/to_ary_spec.rb +0 -44
- data/spec/hamster/undefined/erase_spec.rb +0 -47
- data/spec/hamster/vector/add_spec.rb +0 -41
- data/spec/hamster/vector/any_spec.rb +0 -67
- data/spec/hamster/vector/clear_spec.rb +0 -36
- data/spec/hamster/vector/copying_spec.rb +0 -32
- data/spec/hamster/vector/each_spec.rb +0 -46
- data/spec/hamster/vector/each_with_index_spec.rb +0 -42
- data/spec/hamster/vector/empty_spec.rb +0 -35
- data/spec/hamster/vector/eql_spec.rb +0 -65
- data/spec/hamster/vector/filter_spec.rb +0 -63
- data/spec/hamster/vector/first_spec.rb +0 -35
- data/spec/hamster/vector/get_spec.rb +0 -81
- data/spec/hamster/vector/inspect_spec.rb +0 -31
- data/spec/hamster/vector/last_spec.rb +0 -32
- data/spec/hamster/vector/map_spec.rb +0 -64
- data/spec/hamster/vector/set_spec.rb +0 -153
- data/spec/hamster/vector/to_a_spec.rb +0 -42
- data/spec/hamster/vector/to_ary_spec.rb +0 -44
- data/tasks/bundler.rb +0 -2
- data/tasks/publish.rb +0 -12
- 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
|