function binaryRelopValidator(mFun,A,B)
%MATLAB Code Generation Private Function
%
%   Copyright 2016-2017 The MathWorks, Inc.
%#codegen

coder.internal.allowEnumInputs;
coder.internal.prefer_const(mFun,A,B);
relop =  coder.const(getRelop(mFun));
coder.internal.assert(isscalar(B), ...
    'MATLAB:validators:mustBeScalar',mFun);
coder.internal.assert(isNumericOrLogical(A), ...
    'MATLAB:validators:mustBeNumericOrLogical');
coder.internal.assert(isreal(A) && isreal(B), ...
    'MATLAB:validators:mustBeReal');
MATLABErrorID = coder.const(['MATLAB:validators:',mFun]);
coder.internal.assert(checkAllBinary(relop,A,B), ...
    MATLABErrorID,createPrintableScalar(B));

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

function relop = getRelop(mFun)
coder.internal.prefer_const(mFun);
switch mFun
    case 'mustBeGreaterThan'
        relop = @gt;
    case 'mustBeGreaterThanOrEqual'
        relop = @ge;
    case 'mustBeLessThan'
        relop = @lt;
    case 'mustBeLessThanOrEqual'
        relop = @le;
end

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

function p = checkAllBinary(relop,x,scalar)

ONE = coder.internal.indexInt(1);
p = true;
if issparse(x)
    m = coder.internal.indexInt(size(x,1));
    n = coder.internal.indexInt(size(x,2));
    nz = coder.internal.indexInt(nnz(x));
    if coder.internal.indexDivide(nz,m) < n % i.e., nz < m*n
        xZERO = zeros('like',nonzeros(x));
        p = relop(xZERO,scalar);
    else
        p = true;
    end
    p = p && checkAllBinary(relop,nonzeros(x),scalar);
elseif coder.internal.avoidArrayFlattening
    if coder.isRowMajor
        firstDim = ONE;
    else
        firstDim = coder.internal.indexInt(coder.internal.ndims(x));
    end
    p = genLoops(p,relop,x,scalar,firstDim);
else
    n = coder.internal.indexInt(numel(x));
    for k = ONE:n
        p = p && relop(x(k),scalar);
    end
end

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

function p = genLoops(p,pfunBinary,x,scalar,dim,varargin)

coder.inline('always');
coder.internal.prefer_const(dim);
ONE = coder.internal.indexInt(1);
ND = coder.internal.indexInt(coder.internal.ndims(x));
if dim >= ONE && dim <= ND
    if coder.isRowMajor
        for k = 1:coder.internal.indexInt(size(x,dim))
            p = genLoops(p,pfunBinary,x,scalar,dim + ONE,varargin{:},k);
        end
    else
        for k = 1:coder.internal.indexInt(size(x,dim))
            p = genLoops(p,pfunBinary,x,scalar,dim - ONE,k,varargin{:});
        end
    end
else
    p = p && pfunBinary(x(varargin{:}),scalar);
end

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