Mercurial > hg > octave-nkf
changeset 14905:05bf75eaea2a
maint: periodic merge of default to jit
author | Max Brister <max@2bass.com> |
---|---|
date | Tue, 15 May 2012 18:43:18 -0600 |
parents | 3513df68d580 (current diff) e3d03b48ecb5 (diff) |
children | 3f81e8b42955 |
files | |
diffstat | 6 files changed, 350 insertions(+), 306 deletions(-) [+] |
line wrap: on
line diff
--- a/scripts/general/bitset.m +++ b/scripts/general/bitset.m @@ -1,4 +1,5 @@ ## Copyright (C) 2004-2012 David Bateman +## Copyright (C) 2012 Jordi GutiƩrrez Hermoso ## ## This file is part of Octave. ## @@ -21,7 +22,8 @@ ## @deftypefnx {Function File} {@var{C} =} bitset (@var{A}, @var{n}, @var{val}) ## Set or reset bit(s) @var{n} of unsigned integers in @var{A}. ## @var{val} = 0 resets and @var{val} = 1 sets the bits. -## The lowest significant bit is: @var{n} = 1 +## The lowest significant bit is: @var{n} = 1. All variables must be the +## same size or scalars. ## ## @example ## @group @@ -32,65 +34,54 @@ ## @seealso{bitand, bitor, bitxor, bitget, bitcmp, bitshift, bitmax} ## @end deftypefn -## Liberally based on the version by Kai Habel from octave-forge - -function C = bitset (A, n, val) +function A = bitset (A, n, val) if (nargin < 2 || nargin > 3) print_usage (); endif + sz = size (A); + if (nargin == 2) - val = 1; + val = true (sz); endif - if (isa (A, "double")) - Bmax = bitmax; - Amax = log2 (Bmax) + 1; - _conv = @double; + cl = class (A); + + if (isfloat (A) && isreal (A)) + Bmax = bitmax (cl); + Amax = log2 (Bmax); + elseif (isinteger (A)) + Bmax = intmax (cl); + ## FIXME: Better way to get number of bits than regexping? + Amax = str2num (nthargout (4, @regexp, cl, '\d{1,2}'){1}); else - if (isa (A, "uint8")) - Amax = 8; - _conv = @uint8; - elseif (isa (A, "uint16")) - Amax = 16; - _conv = @uint16; - elseif (isa (A, "uint32")) - Amax = 32; - _conv = @uint32; - elseif (isa (A, "uint64")) - Amax = 64; - _conv = @uint64; - elseif (isa (A, "int8")) - Amax = 8; - _conv = @int8; - elseif (isa (A, "int16")) - Amax = 16; - _conv = @int16; - elseif (isa (A, "int32")) - Amax = 32; - _conv = @int32; - elseif (isa (A, "int64")) - Amax = 64; - _conv = @int64; - else - error ("bitset: invalid class %s", class (A)); - endif - Bmax = intmax (class (A)); + error ("bitset: invalid class %s", cl); endif - m = double (n(:)); - if (any (m < 1) || any (m > Amax)) + if (any ((n < 1)(:)) || any ((n > Amax)(:))) error ("bitset: N must be in the range [1,%d]", Amax); endif - mask = bitshift (_conv (1), uint8 (n) - uint8 (1)); - C = bitxor (A, bitand (A, mask)); + mask = bitshift (cast (1, cl), uint8 (n) - uint8 (1)); + + on = logical (val); + off = !on; - if (val) - C = bitor (A, mask); + if (isscalar (mask)) + onmask = mask; + offmask = mask; + else + if (! size_equal (A, n)) + error ("bitset: N must be scalar or the same size as A"); + endif + onmask = mask(on); + offmask = mask(off); endif + A(on) = bitor (A(on), onmask); + A(off) = bitand (A(off), bitcmp (offmask)); + endfunction @@ -104,6 +95,9 @@ %! endfor %! endfor +## Bug #36458 +%!assert (bitset(uint8 ([1, 2;3 4]), 1, [0 1; 0 1]), uint8 ([0, 3; 2 5])) + %!error bitset (0, 0) %!error bitset (0, 55) %!error bitset (int8 (0), 9)
--- a/scripts/help/doc.m +++ b/scripts/help/doc.m @@ -86,7 +86,7 @@ have_fname = ! isempty (fname); if (have_fname) - status = system (sprintf ("%s --index-search %s", cmd, fname)); + status = system (sprintf ("%s --index-search \"%s\"", cmd, fname)); endif if (! (have_fname && status == 0))
--- a/src/bitfcns.cc +++ b/src/bitfcns.cc @@ -42,224 +42,248 @@ #include "ov-re-mat.h" #include "ov-bool.h" -// FIXME -- could probably eliminate some code duplication by -// clever use of templates. +#include <functional> + +template <typename OP, typename T> +octave_value +bitopxx(const OP& op, const std::string& fname, + const Array<T>& x, const Array<T>& y) +{ + int nelx = x.numel (); + int nely = y.numel (); + + bool is_scalar_op = (nelx == 1 || nely == 1); + + dim_vector dvx = x.dims (); + dim_vector dvy = y.dims (); + + bool is_array_op = (dvx == dvy); + + octave_value retval; + if (is_array_op || is_scalar_op) + { + Array<T> result; + + if (nelx != 1) + result.resize (dvx); + else + result.resize (dvy); + + for (int i = 0; i < nelx; i++) + if (is_scalar_op) + for (int k = 0; k < nely; k++) + result(i+k) = op(x(i), y(k)); + else + result(i) = op(x(i), y(i)); + + retval = result; + } + else + error ("%s: size of X and Y must match, or one operand must be a scalar", + fname.c_str()); + + return retval; +} -#define BITOPX(OP, FNAME, RET) \ - { \ - int nelx = x.numel (); \ - int nely = y.numel (); \ - \ - bool is_scalar_op = (nelx == 1 || nely == 1); \ - \ - dim_vector dvx = x.dims (); \ - dim_vector dvy = y.dims (); \ - \ - bool is_array_op = (dvx == dvy); \ - \ - if (is_array_op || is_scalar_op) \ - { \ - RET result; \ - \ - if (nelx != 1) \ - result.resize (dvx); \ - else \ - result.resize (dvy); \ - \ - for (int i = 0; i < nelx; i++) \ - if (is_scalar_op) \ - for (int k = 0; k < nely; k++) \ - result(i+k) = x(i) OP y(k); \ - else \ - result(i) = x(i) OP y(i); \ - \ - retval = result; \ - } \ - else \ - error ("%s: size of X and Y must match, or one operand must be a scalar", FNAME); \ - } +// Trampoline function, instantiates the proper template above, with +// reflective information hardwired. We can't hardwire this information +// in Fbitxxx DEFUNs below, because at that moment, we still don't have +// information about which integer types we need to instantiate. +template<typename T> +octave_value +bitopx(const std::string& fname, const Array<T>& x, const Array<T>& y) +{ + if (fname == "bitand") + return bitopxx (std::bit_and<T>(), fname, x, y); + if (fname == "bitor") + return bitopxx (std::bit_or<T>(), fname, x, y); + + //else (fname == "bitxor") + return bitopxx (std::bit_xor<T>(), fname, x, y); +} + +octave_value +bitop(const std::string& fname, const octave_value_list& args) +{ + octave_value retval; + + int nargin = args.length (); + + if (nargin == 2) + { + if ((args(0).class_name () == octave_scalar::static_class_name ()) + || (args(0).class_name () == octave_bool::static_class_name ()) + || (args(1).class_name () == octave_scalar::static_class_name ()) + || (args(1).class_name () == octave_bool::static_class_name ())) + { + bool arg0_is_int = (args(0).class_name () != + octave_scalar::static_class_name () && + args(0).class_name () != + octave_bool::static_class_name ()); + bool arg1_is_int = (args(1).class_name () != + octave_scalar::static_class_name () && + args(1).class_name () != + octave_bool::static_class_name ()); + + if (! (arg0_is_int || arg1_is_int)) + { + uint64NDArray x (args(0).array_value ()); + uint64NDArray y (args(1).array_value ()); + if (! error_state) + retval = bitopx (fname, x, y).array_value(); + } + else + { + int p = (arg0_is_int ? 1 : 0); + int q = (arg0_is_int ? 0 : 1); + + NDArray dx = args(p).array_value (); -#define BITOP(OP, FNAME) \ - \ - octave_value retval; \ - \ - int nargin = args.length (); \ - \ - if (nargin == 2) \ - { \ - if ((args(0).class_name () == octave_scalar::static_class_name ()) \ - || (args(0).class_name () == octave_bool::static_class_name ()) \ - || (args(1).class_name () == octave_scalar::static_class_name ()) \ - || (args(1).class_name () == octave_bool::static_class_name ())) \ - { \ - bool arg0_is_int = (args(0).class_name () != \ - octave_scalar::static_class_name () && \ - args(0).class_name () != \ - octave_bool::static_class_name ()); \ - bool arg1_is_int = (args(1).class_name () != \ - octave_scalar::static_class_name () && \ - args(1).class_name () != \ - octave_bool::static_class_name ()); \ - \ - if (! (arg0_is_int || arg1_is_int)) \ - { \ - uint64NDArray x (args(0).array_value ()); \ - uint64NDArray y (args(1).array_value ()); \ - if (! error_state) \ - BITOPX (OP, FNAME, uint64NDArray); \ - retval = retval.array_value (); \ - } \ - else \ - { \ - int p = (arg0_is_int ? 1 : 0); \ - int q = (arg0_is_int ? 0 : 1); \ - \ - NDArray dx = args(p).array_value (); \ - \ - if (args(q).type_id () == octave_uint64_matrix::static_type_id () \ - || args(q).type_id () == octave_uint64_scalar::static_type_id ()) \ - { \ - uint64NDArray x (dx); \ - uint64NDArray y = args(q).uint64_array_value (); \ - if (! error_state) \ - BITOPX (OP, FNAME, uint64NDArray); \ - } \ - else if (args(q).type_id () == octave_uint32_matrix::static_type_id () \ - || args(q).type_id () == octave_uint32_scalar::static_type_id ()) \ - { \ - uint32NDArray x (dx); \ - uint32NDArray y = args(q).uint32_array_value (); \ - if (! error_state) \ - BITOPX (OP, FNAME, uint32NDArray); \ - } \ - else if (args(q).type_id () == octave_uint16_matrix::static_type_id () \ - || args(q).type_id () == octave_uint16_scalar::static_type_id ()) \ - { \ - uint16NDArray x (dx); \ - uint16NDArray y = args(q).uint16_array_value (); \ - if (! error_state) \ - BITOPX (OP, FNAME, uint16NDArray); \ - } \ - else if (args(q).type_id () == octave_uint8_matrix::static_type_id () \ - || args(q).type_id () == octave_uint8_scalar::static_type_id ()) \ - { \ - uint8NDArray x (dx); \ - uint8NDArray y = args(q).uint8_array_value (); \ - if (! error_state) \ - BITOPX (OP, FNAME, uint8NDArray); \ - } \ - else if (args(q).type_id () == octave_int64_matrix::static_type_id () \ - || args(q).type_id () == octave_int64_scalar::static_type_id ()) \ - { \ - int64NDArray x (dx); \ - int64NDArray y = args(q).int64_array_value (); \ - if (! error_state) \ - BITOPX (OP, FNAME, int64NDArray); \ - } \ - else if (args(q).type_id () == octave_int32_matrix::static_type_id () \ - || args(q).type_id () == octave_int32_scalar::static_type_id ()) \ - { \ - int32NDArray x (dx); \ - int32NDArray y = args(q).int32_array_value (); \ - if (! error_state) \ - BITOPX (OP, FNAME, int32NDArray); \ - } \ - else if (args(q).type_id () == octave_int16_matrix::static_type_id () \ - || args(q).type_id () == octave_int16_scalar::static_type_id ()) \ - { \ - int16NDArray x (dx); \ - int16NDArray y = args(q).int16_array_value (); \ - if (! error_state) \ - BITOPX (OP, FNAME, int16NDArray); \ - } \ - else if (args(q).type_id () == octave_int8_matrix::static_type_id () \ - || args(q).type_id () == octave_int8_scalar::static_type_id ()) \ - { \ - int8NDArray x (dx); \ - int8NDArray y = args(q).int8_array_value (); \ - if (! error_state) \ - BITOPX (OP, FNAME, int8NDArray); \ - } \ - else \ - error ("%s: invalid operand type", FNAME); \ - } \ - } \ - else if (args(0).class_name () == args(1).class_name ()) \ - { \ - if (args(0).type_id () == octave_uint64_matrix::static_type_id () \ - || args(0).type_id () == octave_uint64_scalar::static_type_id ()) \ - { \ - uint64NDArray x = args(0).uint64_array_value (); \ - uint64NDArray y = args(1).uint64_array_value (); \ - if (! error_state) \ - BITOPX (OP, FNAME, uint64NDArray); \ - } \ - else if (args(0).type_id () == octave_uint32_matrix::static_type_id () \ - || args(0).type_id () == octave_uint32_scalar::static_type_id ()) \ - { \ - uint32NDArray x = args(0).uint32_array_value (); \ - uint32NDArray y = args(1).uint32_array_value (); \ - if (! error_state) \ - BITOPX (OP, FNAME, uint32NDArray); \ - } \ - else if (args(0).type_id () == octave_uint16_matrix::static_type_id () \ - || args(0).type_id () == octave_uint16_scalar::static_type_id ()) \ - { \ - uint16NDArray x = args(0).uint16_array_value (); \ - uint16NDArray y = args(1).uint16_array_value (); \ - if (! error_state) \ - BITOPX (OP, FNAME, uint16NDArray); \ - } \ - else if (args(0).type_id () == octave_uint8_matrix::static_type_id () \ - || args(0).type_id () == octave_uint8_scalar::static_type_id ()) \ - { \ - uint8NDArray x = args(0).uint8_array_value (); \ - uint8NDArray y = args(1).uint8_array_value (); \ - if (! error_state) \ - BITOPX (OP, FNAME, uint8NDArray); \ - } \ - else if (args(0).type_id () == octave_int64_matrix::static_type_id () \ - || args(0).type_id () == octave_int64_scalar::static_type_id ()) \ - { \ - int64NDArray x = args(0).int64_array_value (); \ - int64NDArray y = args(1).int64_array_value (); \ - if (! error_state) \ - BITOPX (OP, FNAME, int64NDArray); \ - } \ - else if (args(0).type_id () == octave_int32_matrix::static_type_id () \ - || args(0).type_id () == octave_int32_scalar::static_type_id ()) \ - { \ - int32NDArray x = args(0).int32_array_value (); \ - int32NDArray y = args(1).int32_array_value (); \ - if (! error_state) \ - BITOPX (OP, FNAME, int32NDArray); \ - } \ - else if (args(0).type_id () == octave_int16_matrix::static_type_id () \ - || args(0).type_id () == octave_int16_scalar::static_type_id ()) \ - { \ - int16NDArray x = args(0).int16_array_value (); \ - int16NDArray y = args(1).int16_array_value (); \ - if (! error_state) \ - BITOPX (OP, FNAME, int16NDArray); \ - } \ - else if (args(0).type_id () == octave_int8_matrix::static_type_id () \ - || args(0).type_id () == octave_int8_scalar::static_type_id ()) \ - { \ - int8NDArray x = args(0).int8_array_value (); \ - int8NDArray y = args(1).int8_array_value (); \ - if (! error_state) \ - BITOPX (OP, FNAME, int8NDArray); \ - } \ - else \ - error ("%s: invalid operand type", FNAME); \ - } \ - else \ - error ("%s: must have matching operand types", FNAME); \ - } \ - else \ - print_usage (); \ - \ - return retval + if (args(q).type_id () == octave_uint64_matrix::static_type_id () + || args(q).type_id () == octave_uint64_scalar::static_type_id ()) + { + uint64NDArray x (dx); + uint64NDArray y = args(q).uint64_array_value (); + if (! error_state) + retval = bitopx (fname, x, y); + } + else if (args(q).type_id () == octave_uint32_matrix::static_type_id () + || args(q).type_id () == octave_uint32_scalar::static_type_id ()) + { + uint32NDArray x (dx); + uint32NDArray y = args(q).uint32_array_value (); + if (! error_state) + retval = bitopx (fname, x, y); + } + else if (args(q).type_id () == octave_uint16_matrix::static_type_id () + || args(q).type_id () == octave_uint16_scalar::static_type_id ()) + { + uint16NDArray x (dx); + uint16NDArray y = args(q).uint16_array_value (); + if (! error_state) + retval = bitopx (fname, x, y); + } + else if (args(q).type_id () == octave_uint8_matrix::static_type_id () + || args(q).type_id () == octave_uint8_scalar::static_type_id ()) + { + uint8NDArray x (dx); + uint8NDArray y = args(q).uint8_array_value (); + if (! error_state) + retval = bitopx (fname, x, y); + } + else if (args(q).type_id () == octave_int64_matrix::static_type_id () + || args(q).type_id () == octave_int64_scalar::static_type_id ()) + { + int64NDArray x (dx); + int64NDArray y = args(q).int64_array_value (); + if (! error_state) + retval = bitopx (fname, x, y); + } + else if (args(q).type_id () == octave_int32_matrix::static_type_id () + || args(q).type_id () == octave_int32_scalar::static_type_id ()) + { + int32NDArray x (dx); + int32NDArray y = args(q).int32_array_value (); + if (! error_state) + retval = bitopx (fname, x, y); + } + else if (args(q).type_id () == octave_int16_matrix::static_type_id () + || args(q).type_id () == octave_int16_scalar::static_type_id ()) + { + int16NDArray x (dx); + int16NDArray y = args(q).int16_array_value (); + if (! error_state) + retval = bitopx (fname, x, y); + } + else if (args(q).type_id () == octave_int8_matrix::static_type_id () + || args(q).type_id () == octave_int8_scalar::static_type_id ()) + { + int8NDArray x (dx); + int8NDArray y = args(q).int8_array_value (); + if (! error_state) + retval = bitopx (fname, x, y); + } + else + error ("%s: invalid operand type", fname.c_str()); + } + } + else if (args(0).class_name () == args(1).class_name ()) + { + if (args(0).type_id () == octave_uint64_matrix::static_type_id () + || args(0).type_id () == octave_uint64_scalar::static_type_id ()) + { + uint64NDArray x = args(0).uint64_array_value (); + uint64NDArray y = args(1).uint64_array_value (); + if (! error_state) + retval = bitopx (fname, x, y); + } + else if (args(0).type_id () == octave_uint32_matrix::static_type_id () + || args(0).type_id () == octave_uint32_scalar::static_type_id ()) + { + uint32NDArray x = args(0).uint32_array_value (); + uint32NDArray y = args(1).uint32_array_value (); + if (! error_state) + retval = bitopx (fname, x, y); + } + else if (args(0).type_id () == octave_uint16_matrix::static_type_id () + || args(0).type_id () == octave_uint16_scalar::static_type_id ()) + { + uint16NDArray x = args(0).uint16_array_value (); + uint16NDArray y = args(1).uint16_array_value (); + if (! error_state) + retval = bitopx (fname, x, y); + } + else if (args(0).type_id () == octave_uint8_matrix::static_type_id () + || args(0).type_id () == octave_uint8_scalar::static_type_id ()) + { + uint8NDArray x = args(0).uint8_array_value (); + uint8NDArray y = args(1).uint8_array_value (); + if (! error_state) + retval = bitopx (fname, x, y); + } + else if (args(0).type_id () == octave_int64_matrix::static_type_id () + || args(0).type_id () == octave_int64_scalar::static_type_id ()) + { + int64NDArray x = args(0).int64_array_value (); + int64NDArray y = args(1).int64_array_value (); + if (! error_state) + retval = bitopx (fname, x, y); + } + else if (args(0).type_id () == octave_int32_matrix::static_type_id () + || args(0).type_id () == octave_int32_scalar::static_type_id ()) + { + int32NDArray x = args(0).int32_array_value (); + int32NDArray y = args(1).int32_array_value (); + if (! error_state) + retval = bitopx (fname, x, y); + } + else if (args(0).type_id () == octave_int16_matrix::static_type_id () + || args(0).type_id () == octave_int16_scalar::static_type_id ()) + { + int16NDArray x = args(0).int16_array_value (); + int16NDArray y = args(1).int16_array_value (); + if (! error_state) + retval = bitopx (fname, x, y); + } + else if (args(0).type_id () == octave_int8_matrix::static_type_id () + || args(0).type_id () == octave_int8_scalar::static_type_id ()) + { + int8NDArray x = args(0).int8_array_value (); + int8NDArray y = args(1).int8_array_value (); + if (! error_state) + retval = bitopx (fname, x, y); + } + else + error ("%s: invalid operand type", fname.c_str()); + } + else + error ("%s: must have matching operand types", fname.c_str()); + } + else + print_usage (); + + return retval; +} DEFUN (bitand, args, , "-*- texinfo -*-\n\ @@ -269,7 +293,7 @@ @seealso{bitor, bitxor, bitset, bitget, bitcmp, bitshift, bitmax}\n\ @end deftypefn") { - BITOP (&, "bitand"); + return bitop ("bitand", args); } DEFUN (bitor, args, , @@ -280,7 +304,7 @@ @seealso{bitor, bitxor, bitset, bitget, bitcmp, bitshift, bitmax}\n\ @end deftypefn") { - BITOP (|, "bitor"); + return bitop ("bitor", args); } DEFUN (bitxor, args, , @@ -291,7 +315,7 @@ @seealso{bitand, bitor, bitset, bitget, bitcmp, bitshift, bitmax}\n\ @end deftypefn") { - BITOP (^, "bitxor"); + return bitop ("bitxor", args); } static int64_t
--- a/src/data.cc +++ b/src/data.cc @@ -5648,10 +5648,14 @@ DEFUN (tic, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} tic ()\n\ +@deftypefnx {Built-in Function} {@var{id} =} tic ()\n\ @deftypefnx {Built-in Function} {} toc ()\n\ +@deftypefnx {Built-in Function} {} toc (@var{id})\n\ +@deftypefnx {Built-in Function} {@var{val} =} toc (@dots{})\n\ Set or check a wall-clock timer. Calling @code{tic} without an\n\ -output argument sets the timer. Subsequent calls to @code{toc}\n\ -return the number of seconds since the timer was set. For example,\n\ +output argument sets the internal timer state. Subsequent calls\n\ +to @code{toc} return the number of seconds since the timer was set.\n\ +For example,\n\ \n\ @example\n\ @group\n\ @@ -5665,38 +5669,23 @@ will set the variable @code{elapsed_time} to the number of seconds since\n\ the most recent call to the function @code{tic}.\n\ \n\ -If called with one output argument then this function returns a scalar\n\ -of type @code{uint64} and the wall-clock timer is not started.\n\ +If called with one output argument, @code{tic} returns a scalar\n\ +of type @code{uint64} that may be later passed to @code{toc}.\n\ \n\ @example\n\ @group\n\ -t = tic; sleep (5); (double (tic ()) - double (t)) * 1e-6\n\ - @result{} 5\n\ +id = tic; sleep (5); toc (id)\n\ + @result{} 5.0010\n\ @end group\n\ @end example\n\ \n\ -Nested timing with @code{tic} and @code{toc} is not supported.\n\ -Therefore @code{toc} will always return the elapsed time from the most\n\ -recent call to @code{tic}.\n\ +Calling @code{tic} and @code{toc} this way allows nested timing calls.\n\ \n\ If you are more interested in the CPU time that your process used, you\n\ should use the @code{cputime} function instead. The @code{tic} and\n\ @code{toc} functions report the actual wall clock time that elapsed\n\ between the calls. This may include time spent processing other jobs or\n\ -doing nothing at all. For example:\n\ -\n\ -@example\n\ -@group\n\ -tic (); sleep (5); toc ()\n\ - @result{} 5\n\ -t = cputime (); sleep (5); cputime () - t\n\ - @result{} 0\n\ -@end group\n\ -@end example\n\ -\n\ -@noindent\n\ -(This example also illustrates that the CPU timer may have a fairly\n\ -coarse resolution.)\n\ +doing nothing at all.\n\ @end deftypefn") { octave_value retval; @@ -5711,7 +5700,13 @@ double tmp = now.double_value (); if (nargout > 0) - retval = static_cast<octave_uint64> (1e6 * tmp); + { + double ip = 0.0; + double frac = modf (tmp, &ip); + uint64_t microsecs = static_cast<uint64_t> (CLOCKS_PER_SEC * frac); + microsecs += CLOCKS_PER_SEC * static_cast<uint64_t> (ip); + retval = octave_uint64 (microsecs); + } else tic_toc_timestamp = tmp; @@ -5721,6 +5716,8 @@ DEFUN (toc, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} toc ()\n\ +@deftypefnx {Built-in Function} {} toc (@var{id})\n\ +@deftypefnx {Built-in Function} {@var{val} = } toc (@dots{})\n\ See tic.\n\ @end deftypefn") { @@ -5728,30 +5725,59 @@ int nargin = args.length (); - if (nargin != 0) - warning ("tic: ignoring extra arguments"); - - if (tic_toc_timestamp < 0) - { - warning ("toc called before timer set"); - if (nargout > 0) - retval = Matrix (); - } + double start_time = tic_toc_timestamp; + + if (nargin > 1) + print_usage (); else { - octave_time now; - - double tmp = now.double_value () - tic_toc_timestamp; - - if (nargout > 0) - retval = tmp; - else - octave_stdout << "Elapsed time is " << tmp << " seconds.\n"; + if (nargin == 1) + { + octave_uint64 id = args(0).uint64_scalar_value (); + + if (! error_state) + { + uint64_t val = id.value (); + + start_time + = (static_cast<double> (val / CLOCKS_PER_SEC) + + static_cast<double> (val % CLOCKS_PER_SEC) / CLOCKS_PER_SEC); + + // FIXME -- should we also check to see whether the start + // time is after the beginning of this Octave session? + } + else + error ("toc: invalid ID"); + } + + if (! error_state) + { + if (start_time < 0) + error ("toc called before timer set"); + else + { + octave_time now; + + double tmp = now.double_value () - start_time; + + if (nargout > 0) + retval = tmp; + else + octave_stdout << "Elapsed time is " << tmp << " seconds.\n"; + } + } } return retval; } +/* +%!shared id +%! id = tic (); +%!assert (isa (id, "uint64")); +%!assert (isa (toc (id), "double")); +*/ + DEFUN (cputime, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {[@var{total}, @var{user}, @var{system}] =} cputime ();\n\