function r = rand(varargin)
%MATLAB Code Generation Library Function

%   Limitations:
%   Does not support the swb2712 (rand(''state'')) generator.

%   Does not support dispatching to a static RAND method of a user-defined
%   class, i.e. rand(m,n,'myclass') will not dispatch to myclass.rand(m,n).

%   Copyright 2005-2016 The MathWorks, Inc.
%#codegen

coder.internal.prefer_const(varargin);
EXTRINSIC = eml_is_rand_extrinsic;
if nargin > 0 && coder.internal.isCharOrScalarString(varargin{1}) && isLegacyCommand(varargin{1})
    % Handle legacy seed-related tasks and return.
    eml_invariant(nargin <= 2, ...
        'Coder:toolbox:rand_1', ...
        'IfNotConst','Fail');
    eml_invariant(nargin == 1 || nargout == 0, ...
        'Coder:toolbox:rand_2', ...
        'IfNotConst','Fail');
    eml_invariant(nargin == 1 || coder.internal.isBuiltInNumeric(varargin{2}), ...
        'Coder:toolbox:rand_3', ...
        'IfNotConst','Fail');
    eml_invariant(eml_is_const(varargin{1}), ...
        'Coder:toolbox:rand_4', ...
        'IfNotConst','Fail');
    eml_invariant(~strcmp(varargin{1},'state'), ...
        'Coder:toolbox:rand_5', ...
        'IfNotConst','Fail');
    if strcmp(varargin{1},'twister')
        if nargin == 1
            if EXTRINSIC
                r = coder.nullcopy(coder.const(feval('rand', 'twister')));
                r = feval('rand', varargin{:});
            else
                r = eml_rand_mt19937ar_stateful('state');
            end
        else
            eml_invariant(eml_is_const(size(varargin{2})), ...
                'Coder:toolbox:rand_6', ...
                'IfNotConst','Fail');
            if EXTRINSIC
                feval('rand', varargin{:});
            elseif coder.const(isscalar(varargin{2}))
                eml_rand_mt19937ar_stateful('seed',varargin{2});
                eml_rand('method',eml_rand_str2id('mt19937ar'));
            else
                eml_rand_mt19937ar_stateful('state',varargin{2});
                eml_rand('method',eml_rand_str2id('mt19937ar'));
            end
        end
    elseif strcmp(varargin{1},'seed')
        if nargin == 1
            if EXTRINSIC
                r = 0;
                r = feval('rand', varargin{:});
            else
                [~,r] = eml_rand_mcg16807('state_to_seed', ...
                    eml_rand_mcg16807_stateful('state'));
            end
        else
            if EXTRINSIC
                feval('rand', varargin{:});
            else
                eml_rand_mcg16807_stateful('seed',varargin{2});
                eml_rand('method',eml_rand_str2id('mcg16807'));
            end
        end
    else
        eml_invariant(false, ...
            'Coder:toolbox:rand_8', ...
            'IfNotConst','Fail');
    end
    return
end

% Handle any 'like' syntax
if nargin >= 2 && coder.internal.isCharOrScalarString(varargin{end-1})
    eml_invariant(eml_is_const(varargin{end-1}), ...
                          'Coder:toolbox:RandLikeConst', ...
                          'IfNotConst', 'Fail');
    eml_invariant(strcmpi(varargin{end-1}, 'like'), ...
                          'MATLAB:rand:inputType', ...
                          'IfNotConst', 'Fail');
    egArg = varargin{end};
    if coder.internal.isBuiltInNumeric(egArg) || ~isobject(egArg)
        eml_invariant(coder.internal.isFloatClass(class(egArg)), ...
                              'MATLAB:rand:invalidPrototype', ...
                              'IfNotConst', 'Fail');
        eml_invariant(isreal(egArg), ...
                              'MATLAB:rand:complexOrSparsePrototype', ...
                              'IfNotConst', 'Fail');
        r = rand(varargin{1:end-2}, class(egArg));
    else
        r = randLike(egArg, varargin{1:end-2});
    end
elseif EXTRINSIC
        r = coder.nullcopy(zeros(varargin{:}));
        if ~isempty(r)
            if (isa(r,'double'))
                coder.ceval('-jit','emlrtRandu',coder.wref(r(1)),coder.internal.indexInt(numel(r)));
            else %if (isa(r,'single'))
                 % Batch process converting double values to singles in chunks of 128.  This
                 % needs to be done since emlrtRandu requires a double buffer.  Round
                 % floats inward away from 0 and 1 when casting

                r = eml_rand_batch_call(r,'emlrtRandu',true);
            end
        end
else
    coder.inline('never');
    r = eml_rand('generate_uniform',varargin{:});
end
