function [LP, codistr] = hCatImpl(obj, catdim, codistrs, LPs, templ, targetSize)
; %#ok<NOSEM> % Undocumented
%   Implementation of hCatImpl for codistributor1d.  

%   Copyright 2009-2023 The MathWorks, Inc.
    
% Since hCatCheck has returned true, we can trivially concatenate the local
% parts to form the resulting array.  
% First, convert the replicated arrays into the corresponding local parts.
isReplicated = cellfun(@isempty, codistrs);
LPs(isReplicated) = cellfun(@(lp) iConvertToLocalPart(obj, lp), ...
                            LPs(isReplicated), ...
                            "UniformOutput", false);

codistr = codistributor1d(obj.Dimension, obj.Partition, targetSize);

% Table and timetable don't support linear indexing. Therefore, we directly
% define LP. Tables cannot be combined with other objects, therefore the 
% pre-allocation is not necessary.
if istable(templ) || istimetable(templ)
    LP = cat(catdim, LPs{:});
else
    % Pre-allocate LP to ensure the result has the correct attributes,
    % e.g., sparsity, data type.
    LP = distributedutil.Allocator.create(codistr.hLocalSize(), templ);    
    % Subsasgn maintains sparsity
    if ~isempty(LP)
        % Avoid cat on empty results, this will prevent cases like:
        % datetime + string (only allowed when string is a 1x1 scalar)
        LP(:) = cat(catdim, LPs{:});
    end
end
end % End of hCatImpl.

function LP = iConvertToLocalPart(obj, X)
    codistr =  codistributor1d(obj.Dimension, obj.Partition, size(X));
    srcWorker = 0;
    LP = codistr.hBuildFromReplicatedImpl(srcWorker, X);
end % End of iConvertToLocalPart.
