summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArtur Plysyuk <ifuelen@gmail.com>2023-02-08 22:18:37 +0200
committerGitHub <noreply@github.com>2023-02-08 21:18:37 +0100
commit4a236dc231ad4f4576cb600956f7fec8dd47c257 (patch)
treefc0863f909a93610e5a4540708b01bdc952ff24e
parentb5d883c8bbd44dcbdee6ca6f8dc5f37acbb899dc (diff)
downloadelixir-4a236dc231ad4f4576cb600956f7fec8dd47c257.tar.gz
Optimize Enum.to_list for ranges (#12384)
Closes #12383
-rw-r--r--lib/elixir/lib/enum.ex1
-rw-r--r--lib/elixir/lib/range.ex20
2 files changed, 21 insertions, 0 deletions
diff --git a/lib/elixir/lib/enum.ex b/lib/elixir/lib/enum.ex
index bcea77bca..d9bcde75f 100644
--- a/lib/elixir/lib/enum.ex
+++ b/lib/elixir/lib/enum.ex
@@ -3675,6 +3675,7 @@ defmodule Enum do
"""
@spec to_list(t) :: [element]
def to_list(enumerable) when is_list(enumerable), do: enumerable
+ def to_list(%{__struct__: Range} = range), do: Range.to_list(range)
def to_list(%_{} = enumerable), do: reverse(enumerable) |> :lists.reverse()
def to_list(%{} = enumerable), do: Map.to_list(enumerable)
def to_list(enumerable), do: reverse(enumerable) |> :lists.reverse()
diff --git a/lib/elixir/lib/range.ex b/lib/elixir/lib/range.ex
index 23af606af..7bde6701f 100644
--- a/lib/elixir/lib/range.ex
+++ b/lib/elixir/lib/range.ex
@@ -390,6 +390,26 @@ defmodule Range do
end
@doc """
+ Converts a range to a list.
+ """
+ @doc since: "1.15.0"
+ def to_list(first..last//step)
+ when step > 0 and first <= last
+ when step < 0 and first >= last do
+ :lists.seq(first, last, step)
+ end
+
+ def to_list(_first.._last//_step) do
+ []
+ end
+
+ # TODO: Remove me on v2.0
+ def to_list(%{__struct__: Range, first: first, last: last}) do
+ step = if first <= last, do: 1, else: -1
+ :lists.seq(first, last, step)
+ end
+
+ @doc """
Checks if two ranges are disjoint.
## Examples