gusucode.com > bigdata 工具箱 matlab源码程序 > bigdata/@tall/private/funfunCommon.m

    function varargout = funfunCommon(funfun, userfun, validTypes, varargin)
%funfunCommon Common implementation for arrayfun and cellfun
%   VARARGOUT = funfunCommon(FUNFUN, USERFUN, VALIDTYPES, ARGS...) calls
%   FUNFUN(USERFUN,ARGS...). FUNFUN is expected to be @cellfun or
%   @arrayfun. USERFUN is the user-supplied function handle (or char-vector).
%   VALIDTYPES is a cell array of valid types for the data arguments, or
%   {} if no list of valid types is known.

%   Copyright 2016 The MathWorks, Inc.

funfunName = func2str(funfun);
FUNFUNNAME = upper(funfunName);

if ~isa(userfun, 'function_handle')
    iThrowFunfunError(funfunName, 'MATLAB:iteratorClass:funArgNotHandle');
end

% ErrorHandler is not supported - error if set
[errHandler, otherArgs] = iStripPVPair('ErrorHandler', [], varargin);
if ~isempty(errHandler)
    error(message('MATLAB:bigdata:array:FunFunErrorHandlerNotSupported', FUNFUNNAME));
end

% Extract and validate UniformOutput flag.
defaultUniformOutput = true;
[isUniform, otherArgs] = iStripPVPair('UniformOutput', defaultUniformOutput, otherArgs);
if ~islogical(isUniform) || ~isscalar(isUniform)
    iThrowFunfunError(funfunName, 'MATLAB:iteratorClass:NotAParameterPair', ...
                      length(otherArgs) + 3, 'logical', 'UniformOutput');
end

for idx = 1:numel(otherArgs)
    if ~istall(otherArgs{idx})
        error(message('MATLAB:bigdata:array:AllArgsTall', FUNFUNNAME));
    end
    
    if ~isempty(validTypes)
        % otherArgs start at position 2.
        otherArgs{idx} = tall.validateType(otherArgs{idx}, funfunName, validTypes, 1 + idx);
    end
end

[varargout{1:nargout}] = elementfun(@(varargin) iCallFunFun(funfun, userfun, varargin{:}, ...
                                                  'UniformOutput', isUniform), ...
                                    otherArgs{:});
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% iCallFunFun - wrap call to funfun, ensuring that the output type is allowed
function varargout = iCallFunFun(funfun, userfun, varargin)
[varargout{1:nargout}] = funfun(userfun, varargin{:});
outTypes = cellfun(@class, varargout, 'UniformOutput', false);
allowedTypes = matlab.bigdata.internal.adaptors.getAllowedTypes();
if any(~ismember(outTypes, allowedTypes))
    % Got disallowed types
    forbiddenTypes = setdiff(outTypes, allowedTypes);
    iThrowFunfunError(func2str(funfun), ...
        'MATLAB:iteratorClass:UnimplementedOutputArrayType', ...
        forbiddenTypes{1});
end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Throw a cellfun/arrayfun error. iteratorClassID should be a message from the
% MATLAB:iteratorClass catalog.
function iThrowFunfunError(funfunName, iteratorClassID, varargin)
msgStr = getString(message(iteratorClassID, varargin{:}));
funfunID = strrep(iteratorClassID, 'iteratorClass', funfunName);
error(funfunID, '%s', msgStr);
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [value, remainingArgs] = iStripPVPair(propName, defaultValue, args)

% Here, we happen to know that the property arguments to all funfuns are unique,
% so we only need to check to see if the putative property name starts with the
% correct sequence of characters.

if length(args) > 2 && ...
        ((isstring(args{end-1}) && isscalar(args{end-1})) || ischar(args{end-1})) && ...
        iMatches(args{end-1}, propName)
    value = args{end};
    remainingArgs = args(1:end-2);
else
    value = defaultValue;
    remainingArgs = args;
end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% TRUE if name (as char or string) matches propName
function tf = iMatches(name, propName)
if isstring(name)
    name = char(name);
end
tf = strncmpi(name, propName, numel(name));
end