%#codegen

function out = cast_likex(value, prototype)
    coder.inline('always');    
    
    if coder.target('matlab')
        out = cast_likex_impl_m(value, prototype);
    else
        eml_prefer_const(value);
        eml_prefer_const(prototype);
        out = cast_likex_impl_codegen(value, prototype);
    end
end


function out = cast_likex_impl_m(value, prototype)
    if isstruct(value)
        out = value;
        fields = fieldnames(value);
        for ii=1:numel(fields)
            fieldname = fields{ii};
            fieldprototype = prototype.(fieldname);
            for jj=1:numel(value)
                fieldvalue = value(jj).(fieldname);
                out(jj).(fieldname) = cast_likex_impl_m(fieldvalue, fieldprototype);
            end
        end
    else
        out = cast(value, 'like', prototype);
    end
end

function out = cast_likex_impl_codegen(value, prototype)
    coder.inline('always');
    eml_prefer_const(value);
    eml_prefer_const(prototype);
        
    if isstruct(value)
        % Use temporary S to make this codegen compatible.
        nFields = eml_numfields(value);
        if nFields > 0
            for ii=coder.unroll(0:nFields-1)
                fieldname = eml_getfieldname(value, ii);
                fieldvalue = value(1).(fieldname);

                if isfield(prototype, fieldname)
                    fieldprototype = prototype.(fieldname);                
                    if isstruct(fieldvalue)
                       S.(fieldname) = cast_likex_impl_codegen(fieldvalue, fieldprototype);
                    else
                       S.(fieldname) = cast(fieldvalue, 'like', fieldprototype);
                    end
                else
                    S.(fieldname) = fieldvalue;
                end
            end
            out = coder.nullcopy(repmat(S, size(value)));
            for ii=coder.unroll(0:nFields-1)
                fieldname = eml_getfieldname(value, ii);
                for jj=1:numel(value)
                    fieldvalue = value(jj).(fieldname);
                    if isfield(prototype, fieldname)
                        fieldprototype = prototype.(fieldname);                
                        if isstruct(fieldvalue)
                           out(jj).(fieldname) = cast_likex_impl_codegen(fieldvalue, fieldprototype);
                        else
                           out(jj).(fieldname) = cast(fieldvalue, 'like', fieldprototype);
                        end
                    else
                        out(jj).(fieldname) = fieldvalue;
                    end
                end
            end            
        else
            out = value;
        end
    else
        out = cast(value, 'like', prototype);
    end
end
