Repository: JuliaLang/julia
File: base/abstractarray.jl (Julia)

Code before:
map(f, ::AbstractSet) = error("map is not defined on sets")

## 2 argument
function map!(f::F, dest::AbstractArray, A::AbstractArray, B::AbstractArray) where F
    IL = IndexLinear()
    inds = intersect(eachindex(IL, A), eachindex(IL, B))
    @boundscheck checkbounds(dest, inds)
    for i = inds
        dest[i] = f(A[i], B[i])
    end
    return dest
end

## N argument

@inline ith_all(i, ::Tuple{}) = ()
function ith_all(i, as)
    @_propagate_inbounds_meta
    return (as[1][i], ith_all(i, tail(as))...)
end

function map_n!(f::F, dest::AbstractArray, As) where F
    inds = mapreduce(Fix1(eachindex, IndexLinear()), intersect, As)
    @boundscheck checkbounds(dest, inds)
    for i = inds
        dest[i] = f(ith_all(i, As)...)
    end
    return dest
end

"""
    map!(function, destination, collection...)

Like [`map`](@ref), but stores the result in `destination` rather than a new
collection. `destination` must be at least as large as the smallest collection.

$(_DOCS_ALIASING_WARNING)

See also: [`map`](@ref), [`foreach`](@ref), [`zip`](@ref), [`copyto!`](@ref).

# Examples
```jldoctest
julia> a = zeros(3);

julia> map!(x -> x * 2, a, [1, 2, 3]);

julia> a
3-element Vector{Float64}:
 2.0
 4.0
 6.0

Review comment (suggestion):
```suggestion
    length(dest) < minimum(length, As) && throw(ArgumentError("destination is smaller than the smallest mapped argument"))
    idxs1 = LinearIndices(As[1])
    if LinearIndices(dest) == idxs1 && all(x -> LinearIndices(x) == idxs1, As)
        for i in idxs1
            @inbounds as = ith_all(i, As)
            val = f(as...)
            @inbounds dest[i] = val
        end
    else
       for (i, Is...) in zip(eachindex(dest), map(eachindex, As)...)
           as = ntuple(j->getindex(As[j], Is[j]), length(As))
           val = f(as...)
           dest[i] = val
        end
```

Code after:
map(f, ::AbstractSet) = error("map is not defined on sets")

## 2 argument
function map!(f::F, dest::AbstractArray, A::AbstractArray, B::AbstractArray) where F
    for (i, j, k) in zip(eachindex(dest), eachindex(A), eachindex(B))
        @inbounds a, b = A[j], B[k]
        val = f(a, b)
        @inbounds dest[i] = val
    end
    return dest
end

## N argument

@inline ith_all(i, ::Tuple{}) = ()
function ith_all(i, as)
    @_propagate_inbounds_meta
    return (as[1][i], ith_all(i, tail(as))...)
end

function map_n!(f::F, dest::AbstractArray, As) where F
    idxs = LinearIndices(dest)
    if all(x -> LinearIndices(x) == idxs, As)
        for i in idxs
            @inbounds as = ith_all(i, As)
            val = f(as...)
            @inbounds dest[i] = val
        end
    else
        for (i, Is...) in zip(eachindex(dest), map(eachindex, As)...)
            as = ntuple(j->getindex(As[j], Is[j]), length(As))
            val = f(as...)
            dest[i] = val
        end
    end
    return dest
end

"""
    map!(function, destination, collection...)

Like [`map`](@ref), but stores the result in `destination` rather than a new
collection. `destination` must be at least as large as the smallest collection.

$(_DOCS_ALIASING_WARNING)

See also: [`map`](@ref), [`foreach`](@ref), [`zip`](@ref), [`copyto!`](@ref).

# Examples
```jldoctest
julia> a = zeros(3);