function y = eml_colonhelper(makeColon, varargin)
    % MATLAB Code Generation Library Function
    %
    %   Copyright 2012-2016 The MathWorks, Inc.
    %#codegen
    
    % This function is called from colon.m and from colontype.m
    % In the 1st case, its job is to return a:b:c after figuring
    % out the output type and doing all the error checks.
    %
    % In the second case, the function is called by C++ code in
    % inference to do the type checking and insert range checks.
    % In that case, this function is inferred and then hoisted so
    % it gets executed before actual indexing takes place.
    
    coder.internal.prefer_const(makeColon);
    coder.internal.prefer_const(varargin);
    eml_allow_mx_inputs;
    
    nargs = numel(varargin);
    eml_invariant((nargs == 2) || (nargs == 3), 'fixed:coder:incorrectNumberOfInputs');
    
    if (nargs == 2)
        a = varargin{1};
        b = 1;
        c = varargin{2};
    else
        a = varargin{1};
        b = varargin{2};
        c = varargin{3};
    end
    
    for i = 1:numel(varargin)
        do_argcheck(varargin{i});
    end
    
    [Psigned, Py] = fi_colon_type_impl(a, b, c);
    
    if isfi(Psigned)
        eml_invariant(Psigned.WordLength <= 64, 'fixed:coder:colonBitWidthMax64');
    end
    
    % Check the validity of the inputs before casting them to another type that
    % may change them into whole numbers and limit their range.
    check_all_whole_number(a,b,c,Py);
    check_range(a, b, c, Py, Psigned);
    a = cast(a,'like',Psigned);
    b = cast(b,'like',Psigned);
    c = cast(c,'like',Psigned);
    
    if isfi(a)
        sia = storedInteger(a);
    else
        sia = a;
    end
    
    if coder.const(makeColon)
        if isfi(b)
            sib = storedInteger(b);
        else
            sib = b;
        end
        if isfi(c)
            sic = storedInteger(c);
        else
            sic = c;
        end
        y0 = sia:sib:sic;
    else
        y0 = sia;
    end
        
    y = cast(y0, 'like', Py);
    
end

function do_argcheck(J)
    % Codegen does not support non-scalar arguments to colon.
    eml_invariant(isscalar(J), 'Coder:toolbox:colon_7');
    x = isfi(J) && isscaledtype(J) && ~is_scaling_binary_point(J);
    eml_invariant(~x, 'fixed:fi:binaryPointOnlyMath','colon');
end

function b = is_scaling_binary_point(x)
    b = x.SlopeAdjustmentFactor==1 && x.Bias==0;
end

function check_all_whole_number(J,D,K,Py)
    if isfi(Py) && isfixed(Py)
        eml_invariant(isequal(floor(J),J) && ...
            isequal(floor(D),D) && ...
            isequal(floor(K),K), ...
            'fixed:fi:colonOperandsMustBeIntegerValued');
    end
end

function check_range(J, D, K, Py, Psigned)
    if isfi(Py) && isfixed(Py)
        % Verify the fixed-point operands J and K are in the range of the
        % output prototype Py, and the increment D is in the range of the
        % temporary signed prototype Psigned.
        [lower_bound0,upper_bound0] = range(Py);
        lower_bound = cast(lower_bound0,'like',Psigned);
        upper_bound = cast(upper_bound0,'like',Psigned);
        x = ~isempty(J) && (J<lower_bound || J>upper_bound) || ...
            ~isempty(K) && (K<lower_bound || K>upper_bound) || ...
            ~isempty(D) && (D<lowerbound(Psigned) || D>upperbound(Psigned));
        eml_invariant(~x, 'MATLAB:colon:OutOfRange');
    elseif isfi(Py) && issingle(Py) || isa(Py,'single')
        % If the type is single, then verify the operands are in range of
        % single.
        lower_bound = -realmax('single');
        upper_bound = realmax('single');
        x = ~isempty(J) && (J<lower_bound || J>upper_bound) || ...
            ~isempty(K) && (K<lower_bound || K>upper_bound) || ...
            ~isempty(D) && (D<lower_bound || D>upper_bound);
        eml_invariant(~x, 'MATLAB:colon:OutOfRange');
    end
end

% LocalWords: Py Psigned Fy colontype is_fi fi