Browse Source

refactored to use the Enumerable protocol for enumerating over leaves

pull/2/head
Sean Copenhaver 11 years ago
parent
commit
a321df129e
  1. 65
      lib/rope.ex

65
lib/rope.ex

@ -123,7 +123,8 @@ defmodule Rope do
@doc """
Rebalance the rope explicitly to help keep insert, remove, etc
efficient.
efficient. This is a pretty greedy rebalancing and should produce
a fully balanced rope.
"""
@spec rebalance(rope) :: rope
def rebalance(nil) do
@ -131,7 +132,10 @@ defmodule Rope do
end
def rebalance(rope) when is_record(rope, Rope) do
leaves = flatten([], rope)
leaves = rope
|> Enum.reduce([], fn(leaf, acc) -> [leaf | acc] end)
|> Enum.reverse
rebuild_rope([], leaves)
end
@ -221,7 +225,7 @@ defmodule Rope do
"""
@spec to_binary(rope) :: binary
def to_binary(rope) do
flatten([], rope)
rope
|> Stream.map(fn(rleaf(value: value)) -> value end)
|> Enum.join
end
@ -264,7 +268,7 @@ defmodule Rope do
leftRope |> concat(replacement) |> concat(rightRope)
end
def do_replace_all(rope, pattern, replacement) do
defp do_replace_all(rope, pattern, replacement) do
termLen = String.length(pattern)
indexes = find_all(rope, pattern)
@ -283,7 +287,6 @@ defmodule Rope do
rebuild_rope [], subropes
end
defp do_reduce_while(enumerable, acc, whiler, reducer) do
try do
Enum.reduce(enumerable, acc, fn(el, acc) ->
@ -316,29 +319,51 @@ defmodule Rope do
rebuild_rope([], subropes)
end
defp flatten(leaves, rnode(right: right, left: left)) do
leaves
|> flatten(right)
|> flatten(left)
defimpl Binary.Chars, for: Rope do
def to_binary(rope) do
Rope.to_binary(rope)
end
end
defp flatten(leaves, rleaf(length: len) = rope) do
case len do
0 -> leaves
n when n > 0 ->
[ rope | leaves ]
defimpl Enumerable, for: Rope do
def count(rope) do
Rope.reduce_leaves(rope, 0, fn(leaf, acc) -> acc + 1 end)
end
def member?(rope, value) do
try do
Rope.reduce_leaves(rope, false,
fn(leaf, false) ->
if leaf == value do
#yeah yeah, it's an error for control flow
throw :found
end
false
end)
catch
:throw, :found -> true
end
end
def reduce(rope, acc, fun) do
Rope.reduce_leaves(rope, acc, fun)
end
end
defp flatten(leaves, nil) do
leaves
@doc false
def reduce_leaves(rnode(right: right, left: left), acc, fun) do
acc = reduce_leaves(left, acc, fun)
reduce_leaves(right, acc, fun)
end
def reduce_leaves(rleaf() = leaf, acc, fun) do
fun.(leaf, acc)
end
defimpl Binary.Chars, for: Rope do
def to_binary(rope) do
Rope.to_binary(rope)
end
def reduce_leaves(nil, acc, fun) do
acc
end

Loading…
Cancel
Save