www.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