view test/args.tst @ 32047:e3de59065cf1

inputParser.m: Re-architect internal data structures for 60% speed improvement. Key idea is to replace Parameter and Switch structs with name field containing a nested struct (def, val fields) with a struct array that has fields "name", "def", and "val". This makes it possible to eliminate for loops. * NEWS.9.md: Announce performance improvement. * inputParser.m: Declare "Parameter" and "Switch" properties as struct arrays. Add new private property "last_idx" which caches the last Parameter or Switch lookup. * inputParser.m (addRequired): Adjust input validation to use numel() now rather than numfields(). * inputParser.m (addOptional): Adjust input validation to use numel() now rather than numfields(). * inputParser.m (addParameter): Change code to add new Parameter to a struct array. * inputParser.m (addSwitch): Change code to add new Switch to a struct array. * inputParser.m (parse): Adjust initialization of internal variables ParameterNames and SwitchNames to match new data structure. Use last_idx to simplify call to validate_arg() for Parameters. * inputParser.m (validate_arg): Move creation of error message to code path when error has been found---No need to do it for every function call. Don't capture "exception" variable in try/catch as it is no longer used. * inputParser.m (is_argname): Cache "last_idx" if match was found. * inputParser.m (add_missing): Replace call to setdiff() with in-place code which can take advantage of implicit knowledge to eliminate calls to unique and input validation. Replace for loop with cell2struct/struct2cell combination.
author Rik <rik@octave.org>
date Fri, 21 Apr 2023 11:01:40 -0700
parents 597f3ee61a48
children 2e484f9f1f18
line wrap: on
line source

########################################################################
##
## Copyright (C) 2006-2023 The Octave Project Developers
##
## See the file COPYRIGHT.md in the top-level directory of this
## distribution or <https://octave.org/copyright/>.
##
## This file is part of Octave.
##
## Octave is free software: you can redistribute it and/or modify it
## under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## Octave is distributed in the hope that it will be useful, but
## WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with Octave; see the file COPYING.  If not, see
## <https://www.gnu.org/licenses/>.
##
########################################################################

########################################
## No inputs or no outputs

## no input or output arguments
%!function f ()
%!  assert (nargin, 0);
%!  assert (nargout, 0);
%!endfunction
%!test
%! f;

## one input with two possible inputs
%!function f (x, y)
%!  assert (nargin, 1);
%!  assert (nargout, 0);
%!endfunction
%!test
%! f (1);

## no inputs, one of multiple outputs
%!function [x, y] = f ()
%!  assert (nargin, 0);
%!  assert (nargout, 1);
%!  x = 2;
%!endfunction
%!test
%! assert (f (), 2);

## one of multiple inputs, one of multiple outputs
%!function [x, y] = f (a, b)
%!  assert (nargin, 1);
%!  assert (nargout, 1);
%!  x = a;
%!endfunction
%!test
%! assert (f (1), 1);

########################################
## Varargin, varargout

## varargin and varargout with no inputs or outputs
%!function [varargout] = f (varargin)
%!  assert (nargin, 0);
%!  assert (nargout, 0);
%!endfunction
%!test
%! f;

## varargin and varargout with one input
%!function [varargout] = f (x, varargin)
%!  assert (nargin, 1);
%!  assert (nargout, 0);
%!endfunction
%!test
%! f (1);

## varargin and varargout with one output
%!function [x, varargout] = f (varargin)
%!  assert (nargin, 0);
%!  assert (nargout, 1);
%!  x = 2;
%!endfunction
%!test
%! assert (f (), 2);

## varargin and varargout with one input and output
%!function [varargout] = f (varargin)
%!  assert (nargin, 1);
%!  assert (nargout, 1);
%!  varargout{1} = varargin{1};
%!endfunction
%!test
%! assert (f (1), 1);

## multiple inputs, multiple outputs, but not all of either
## WARNING: The original test did not assign the outputs, it just
## requested them, and I think that is supposed to be an error.  It also
## still has a non-assigned output argument.
%!function [x, y, z] = f (a, b, c, d, e)
%!  assert (nargin, 4);
%!  assert (nargout, 2);
%!  x = a;
%!  y = b;
%!endfunction
%!test
%! [s, t] = f (1, 2, 3, 4);
%! assert ([s t], [1 2]);

## Fully used varargin and varargout
%!function [varargout] = f (varargin)
%!  assert (nargin, 3);
%!  assert (nargout, 4);
%!  varargout{1} = varargin{1};
%!  varargout{2} = varargin{2};
%!  varargout{3} = varargin{3};
%!  varargout{4} = 4;
%!endfunction
%!test
%! [s, t, u, v] = f (1, 2, 3);
%! assert ([s t u v], [1 2 3 4]);

## Wrapper functions
%!function [x, y, z] = f (varargin)
%!  assert (nargin, 0);
%!  assert (nargout, 0);
%!  x = 3;
%!  y = 2;
%!  z = 1;
%!endfunction
%!function varargout = wrapper_1 (varargin)
%!  assert (nargout, 0);
%!  [varargout{1:nargout}] = f ();
%!endfunction
%!function varargout = wrapper_2 (varargin)
%!  assert (nargout, 0);
%!  varargout = cell (1, nargout);
%!  [varargout{1:nargout}] = f ();
%!endfunction
%!function varargout = wrapper_3 (varargin)
%!  assert (nargout, 0);
%!  varargout = cell (1, nargout);
%!  [varargout{:}] = f ();
%!endfunction
%!test
%! wrapper_1 ();
%! assert (ans, 3);
%! wrapper_2 ();
%! assert (ans, 3);
%! wrapper_3 ();
%! assert (ans, 3);

## Test default arguments
## numeric
%!function f (x = 0)
%!  assert (x, 0);
%!endfunction
%!test
%! f()

## numeric vector (spaces)
%!function f (x = [0 1 2])
%!  assert (x, [0 1 2]);
%!endfunction
%!test
%! f()

## numeric vector (range)
%!function f (x = 1:3)
%!  assert (x, 1:3);
%!endfunction
%!test
%! f()

## numeric vector (commas)
%!function f (x = [0,1,2])
%!  assert (x, [0 1 2]);
%!endfunction
%!test
%! f()

## numeric vector (commas and spaces)
%!function f (x = [0, 1, 2])
%!  assert (x, [0 1 2]);
%!endfunction
%!test
%! f()

## numeric matrix
%!function f (x = [0, 1, 2;3, 4, 5])
%!  assert (x, [0 1 2;3 4 5]);
%!endfunction
%!test
%! f()

## empty cell
%!function f (x = {})
%!  assert (x, {});
%!endfunction
%!test
%! f()

## full cell
%!function f (x = {1})
%!  assert (x, {1});
%!endfunction
%!test
%! f()

## many cells
%!function f (x = {1 'a' "b" 2.0 struct("a", 3)})
%!  assert (x, {1 'a' "b" 2.0 struct("a", 3)});
%!endfunction
%!test
%! f()

## struct
%!function f (x = struct ("a", 3))
%!  assert (x, struct ("a", 3));
%!endfunction
%!test
%! f()

## char (double quotes)
%!function f (x = "a")
%!  assert (x, "a");
%!endfunction
%!test
%! f()

## char (single quotes)
%!function f (x = 'a')
%!  assert (x, "a");
%!endfunction
%!test
%! f()

## char (string, double quotes)
%!function f (x = "abc123")
%!  assert (x, "abc123");
%!endfunction
%!test
%! f()

## char (string, double quotes, punctuation)
%!function f (x = "abc123`1234567890-=~!@#$%^&*()_+[]{}|;':\",./<>?\\")
%!  assert (x, "abc123`1234567890-=~!@#$%^&*()_+[]{}|;':\",./<>?\\");
%!endfunction
%!test
%! f()

## Function handle (builtin)
%!function f (x = @sin)
%!  finfo = functions (x);
%!  fname = finfo.function;
%!  assert (is_function_handle (x) && strcmp (fname, "sin"));
%!endfunction
%!test
%! f()

## Function handle (anonymous)
%!function f (x = @(x) x.^2)
%!  finfo = functions (x);
%!  ftype = finfo.type;
%!  assert (is_function_handle (x) && strcmp (ftype, "anonymous"));
%!endfunction
%!test
%! f()