function y = varstd(op,x,varargin)
%MATLAB Code Generation Library Function

%   Copyright 2002-2023 The MathWorks, Inc.
%#codegen

narginchk(2,5);
coder.internal.prefer_const(op,varargin);
if ischar(x)
    y = varstd(op,double(x),varargin{:});
    return
end
ONE = coder.internal.indexInt(1);
rxzero = zeros('like',real(x));
coder.internal.assert(isa(x,'float'), ...
    'Coder:toolbox:unsupportedClass',op,class(x));
nv = length(varargin);
if nv > 0 && coder.internal.isCharOrScalarString(varargin{end})
    coder.internal.assert(coder.internal.isConst(varargin{end}), ...
        'Coder:toolbox:OptionInputsMustBeConstant',op);
    matchParam = @coder.internal.matchStringParameter;
    omitnan = matchParam(varargin{end},'omitnan') || matchParam(varargin{end},'omitmissing');
    includenan = matchParam(varargin{end},'includenan') || matchParam(varargin{end},'includemissing');
    VDIM = nv < 3 && coder.internal.isConst(varargin{end}) && ...
        matchParam(varargin{end},'all');
    coder.internal.assert(omitnan || includenan || VDIM, ...
        'MATLAB:var:unknownFlag');
    if omitnan || includenan
        nvleft = nv - 1;
    else
        nvleft = nv;
    end
else
    omitnan = false;
    nvleft = nv;
    VDIM = false;
end
if nvleft == 0 || nvleft == 1
    % DIM is not supplied.
    % nvleft == 0 --> W is not supplied.
    % nvleft == 1 --> W is varargin{1}.
    if coder.internal.isConst(size(x)) && isequal(x,[]) % Special case.
        y = coder.internal.nan(class(x));
        return
    end
    coder.internal.assert(coder.internal.isConst(size(x)) || ~isequal(x,[]), ...
        'Coder:toolbox:var_specialEmpty');
    DIM = coder.internal.constNonSingletonDim(x);
    coder.internal.assert(coder.internal.isConst(size(x,DIM)) || ...
        isscalar(x) || ...
        size(x,DIM) ~= 1, ...
        'Coder:toolbox:autoDimIncompatibility');
else % nv == 2
    % Both W and DIM are supplied.
    coder.internal.assert(coder.internal.isConst(varargin{2}), ...
        'Coder:toolbox:dimNotConst');
    DIM = varargin{2};
    VDIM = coder.internal.isVectorDim(DIM);
end
if nvleft == 0 || ...
        (coder.internal.isConst(size(varargin{1})) && isempty(varargin{1}))
    w = rxzero;
elseif ischar(varargin{1})
    w = cast(varargin{1}(:),'like',rxzero);
else
    w = varargin{1}(:);
    coder.internal.assert(isa(w,'float'), ...
        'Coder:toolbox:unsupportedClass','var',class(w));
end
if VDIM
    % Handle vector DIM inputs.
    coder.internal.assert(coder.internal.isConstTrue(isscalar(w)) && ...
        (w == 0 || w == 1), ...
        'MATLAB:var:vecWgtWithVecDIM');
    if omitnan
        fx = @(x)varstd(op,x,w,ONE,'o');
        y = coder.internal.applyToMultipleDims(fx,x,DIM);
    else
        fx = @(x)varstd(op,x,w,ONE,'i');
        y = coder.internal.applyToMultipleDims(fx,x,DIM);
    end
    return
end
% Scalar DIM from here on.
coder.internal.assertValidDim(DIM);
n = coder.internal.indexInt(size(x,DIM));
if coder.internal.isConstTrue(isscalar(w))
    % Unweighted variance
    coder.internal.assert(w == 0 || w == 1,'MATLAB:var:invalidWgts');
    ytype = zeros('like',real(x));
else
    coder.internal.assert(numel(w) == n,'MATLAB:var:invalidSizeWgts');
    coder.internal.assert(isreal(w),'MATLAB:var:invalidWgts');
    ytype = zeros('like',coder.internal.scalarEg(real(x),w));
    for k = 1:n
        if w(k) < 0
            coder.internal.error('MATLAB:var:invalidWgts');
        end
    end
end
ONE = coder.internal.indexInt(1);
npages = coder.internal.prodsize(x,'above',DIM);
if coder.internal.isConstTrue(isvector(x)) && ...
        DIM == coder.internal.constNonSingletonDim(x)
    y = vvarstd(op,x(:),omitnan,n,w);
elseif DIM == 1 && ~coder.isRowMajor && ...
        coder.internal.useParforConst(mfilename,npages)
    ysize = size(x);
    ysize(1) = 1;
    y = coder.nullcopy(zeros(ysize,'like',ytype));
    parfor j = 1:npages
        y(:,j) = vvarstd(op,x(:,j),omitnan,n,w);
    end
else
    vectorstd = @(x)vvarstd(op,x,omitnan,n,w);
    y = coder.internal.applyVectorFunction(vectorstd,x,DIM,ONE,ytype);
end

