@@ -5,7 +5,8 @@ module Sort
55using Base. Order
66
77using Base: copymutable, midpoint, require_one_based_indexing, uinttype,
8- sub_with_overflow, add_with_overflow, OneTo, BitSigned, BitIntegerType, top_set_bit
8+ sub_with_overflow, add_with_overflow, OneTo, BitSigned, BitIntegerType, top_set_bit,
9+ IteratorSize, HasShape, IsInfinite, tail
910
1011import Base:
1112 sort,
@@ -1383,6 +1384,11 @@ end
13831384
13841385Variant of [`sort!`](@ref) that returns a sorted copy of `v` leaving `v` itself unmodified.
13851386
1387+ Uses `Base.copymutable` to support immutable collections and iterables.
1388+
1389+ !!! compat "Julia 1.10"
1390+ `sort` of arbitrary iterables requires at least Julia 1.10.
1391+
13861392# Examples
13871393```jldoctest
13881394julia> v = [3, 1, 2];
@@ -1400,7 +1406,39 @@ julia> v
14001406 2
14011407```
14021408"""
1403- sort (v:: AbstractVector ; kws... ) = sort! (copymutable (v); kws... )
1409+ function sort (v; kws... )
1410+ size = IteratorSize (v)
1411+ size == HasShape {0} () && throw (ArgumentError (" $v cannot be sorted" ))
1412+ size == IsInfinite () && throw (ArgumentError (" infinite iterator $v cannot be sorted" ))
1413+ sort! (copymutable (v); kws... )
1414+ end
1415+ sort (v:: AbstractVector ; kws... ) = sort! (copymutable (v); kws... ) # for method disambiguation
1416+ sort (:: AbstractString ; kws... ) =
1417+ throw (ArgumentError (" sort(::AbstractString) is not supported" ))
1418+ sort (:: Tuple ; kws... ) =
1419+ throw (ArgumentError (" sort(::Tuple) is only supported for NTuples" ))
1420+
1421+ function sort (x:: NTuple{N} ; lt:: Function = isless, by:: Function = identity,
1422+ rev:: Union{Bool,Nothing} = nothing , order:: Ordering = Forward) where N
1423+ o = ord (lt,by,rev,order)
1424+ if N > 9
1425+ v = sort! (copymutable (x), DEFAULT_STABLE, o)
1426+ tuple ((v[i] for i in 1 : N). .. )
1427+ else
1428+ _sort (x, o)
1429+ end
1430+ end
1431+ _sort (x:: Union{NTuple{0}, NTuple{1}} , o:: Ordering ) = x
1432+ function _sort (x:: NTuple , o:: Ordering )
1433+ a, b = Base. IteratorsMD. split (x, Val (length (x)>> 1 ))
1434+ merge (_sort (a, o), _sort (b, o), o)
1435+ end
1436+ merge (x:: NTuple , y:: NTuple{0} , o:: Ordering ) = x
1437+ merge (x:: NTuple{0} , y:: NTuple , o:: Ordering ) = y
1438+ merge (x:: NTuple{0} , y:: NTuple{0} , o:: Ordering ) = x # Method ambiguity
1439+ merge (x:: NTuple , y:: NTuple , o:: Ordering ) =
1440+ (lt (o, y[1 ], x[1 ]) ? (y[1 ], merge (x, tail (y), o)... ) : (x[1 ], merge (tail (x), y, o)... ))
1441+
14041442
14051443# # partialsortperm: the permutation to sort the first k elements of an array ##
14061444
0 commit comments