function c = bitget(a,bit,assumedtype)
%MATLAB Code Generation Library Function

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

coder.internal.allowEnumInputs;
coder.internal.assert(nargin >= 2,'MATLAB:minrhs');
coder.internal.prefer_const(bit);
if nargin == 3
    coder.internal.prefer_const(assumedtype);
    coder.internal.assert(coder.internal.isConst(assumedtype), ...
        'Coder:toolbox:TrailingStringInputMustBeConstant');
end

% Handle Simulink size propagation.
if coder.internal.isAmbiguousTypes
    c = coder.internal.scalexpAlloc(0,a,bit);
    c(:) = 0;
    return
end

% Constant-fold with an extrinsic call.
if ~coder.target('MATLAB') && ...
        coder.internal.isConst(a) && ...
        coder.internal.isConst(bit)
    if nargin == 2
        c = coder.const(feval('bitget',a,bit));
    else
        c = coder.const(feval('bitget',a,bit,assumedtype));
    end
    return
end

% Validate input types.
coder.internal.assert(isreal(a) && isreal(bit), ...
    'MATLAB:bitget:complexArgs');
coder.internal.assert(isinteger(a) || isa(a,'double'), ...
    'Coder:toolbox:unsupportedClass','bitget',class(a));

% Determine the assumed and output classes.
outputcls = coder.internal.builtinClass(a);
if nargin == 3
    coder.internal.assert(coder.internal.isIntegerClass(assumedtype), ...
        'MATLAB:bitget:unknownTypeString');
    assumedcls = char(assumedtype);
    coder.internal.assert(isa(a,'double') || isa(a,assumedcls), ...
        'MATLAB:bitget:invalidTypeString');
elseif isinteger(a)
    assumedcls = outputcls;
else
    assumedcls = 'uint64';
end

% Validate bit values.
nbits = coder.internal.int_nbits(assumedcls);
IONE = coder.internal.indexInt(1);
coder.internal.assert(all_in_integer_range(bit,IONE,nbits), ...
    'MATLAB:bitSetGet:BITOutOfRange');

% Validate double values, if any.
if ~isa(a,assumedcls)
    coder.internal.assert( ...
        all_in_integer_range(a,intmin(assumedcls),intmax(assumedcls)), ...
        'MATLAB:bitget:outOfRange');
end

% Perform the operation.
if coder.target('hdl')
    coder.inline('always');
    c = coder.internal.scalexpAlloc(zeros(outputcls),a,bit);
    for k = 1:numel(c)
        c(k) = bitget_scalar( ...
            coder.internal.scalexpSubsref(a,k), ...
            coder.internal.scalexpSubsref(bit,k), ...
            assumedcls,outputcls);
    end
elseif coder.internal.isConstTrue(isscalar(a)) && ...
        coder.internal.isConstTrue(isscalar(bit))
    coder.inline('always');
    c = bitget_scalar(a(1),bit(1),assumedcls,outputcls);
else
    f = @(a,bit)bitget_scalar(a,bit,assumedcls,outputcls);
    c = coder.internal.sxfun('bitget',f,a,bit);
end

%--------------------------------------------------------------------------

function c = bitget_scalar(a,bit,assumedcls,outputcls)

coder.internal.prefer_const(assumedcls,outputcls);
coder.inline('always');
atmp = cast(a,coder.internal.builtinClass(a));
a1 = eml_cast(atmp,assumedcls,'to zero','spill');
btmp = cast(bit,coder.internal.builtinClass(bit));
if isfloat(btmp)
    b1 = eml_cast(btmp,'uint8','to zero','spill');
    bm1 = eml_minus(b1,1,'uint8','spill');
else
    bm1 = eml_minus(btmp,1,class(btmp),'spill');
end
if coder.target('HDL')
    c = cast(eml_bitslice(a1,bm1,bm1) ~= 0,outputcls);
else
    c = cast(eml_bitand(a1,eml_lshift(ones(assumedcls),bm1)) ~= 0,outputcls);
end

%--------------------------------------------------------------------------
