changeset 9705:5acd99c3e794

avoid recursive overloaded calls in builtin numel
author Jaroslav Hajek <highegg@gmail.com>
date Thu, 08 Oct 2009 08:03:59 +0200
parents bb413c0d0d6d
children 71160b139b07
files src/ChangeLog src/data.cc src/ov-base.cc src/utils.cc src/utils.h
diffstat 5 files changed, 53 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Wed Oct 07 14:34:53 2009 -0400
+++ b/src/ChangeLog	Thu Oct 08 08:03:59 2009 +0200
@@ -1,3 +1,11 @@
+2009-10-08  Jaroslav Hajek  <highegg@gmail.com>
+
+	* utils.cc (dims_to_numel): New function.
+	* utils.h: Declare it.
+	* ov-base.cc (octave_base_value::numel (const octave_value_list&)):
+	Use it here.
+	* data.cc (Fnumel): Also here.
+
 2009-10-07  John W. Eaton  <jwe@octave.org>
 
 	* variables.cc (get_dims_str): New function.
--- a/src/data.cc	Wed Oct 07 14:34:53 2009 -0400
+++ b/src/data.cc	Thu Oct 08 08:03:59 2009 +0200
@@ -2331,19 +2331,28 @@
 DEFUN (numel, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} numel (@var{a})\n\
+@deftypefnx {Built-in Function} {} numel (@var{a}, @var{idx1}, @var{idx2}, @dots{})\n\
 Returns the number of elements in the object @var{a}.\n\
+Optionally, if indices @var{idx1}, @var{idx2}, @dots{} are supplied,\n\
+return the number of elements that would result from the indexing\n\
+@example\n\
+  @var{a}(@var{idx1}, @var{idx2}, @dots{})\n\
+@end example\n\
+This method is also called when an object appears as lvalue with cs-list\n\
+indexing, i.e. @code{object@{@dots{}@}} or @code{object(@dots{}).field}.\n\
 @seealso{size}\n\
 @end deftypefn")
 {
   octave_value retval;
   octave_idx_type nargin = args.length ();
 
-  if (nargin >= 1)
+  if (nargin == 1)
+    retval = args(0).numel ();
+  else if (nargin > 1)
     {
-      octave_idx_type numel = args(0).numel (args.slice (1, nargin-1));
-
-      if (! error_state)
-	  retval = numel;
+      // Don't use numel (const octave_value_list&) here as that corresponds to
+      // an overloaded call, not to builtin!
+      retval = dims_to_numel (args(0).dims (), args.slice (1, nargin-1));
     }
   else
     print_usage ();
--- a/src/ov-base.cc	Wed Oct 07 14:34:53 2009 -0400
+++ b/src/ov-base.cc	Thu Oct 08 08:03:59 2009 +0200
@@ -89,26 +89,7 @@
 octave_idx_type
 octave_base_value::numel (const octave_value_list& idx)
 {
-  octave_idx_type retval;
-
-  octave_idx_type len = idx.length ();
-
-  if (len == 0)
-    retval = numel ();
-  else
-    {
-      const dim_vector dv = dims ().redim (len);
-      retval = 1;
-      for (octave_idx_type i = 0; i < len; i++)
-        {
-          if (idx(i).is_magic_colon ())
-            retval *= dv(i);
-          else
-            retval *= idx(i).numel ();
-        }
-    }
-
-  return retval;
+  return dims_to_numel (dims (), idx);
 }
 
 octave_value
--- a/src/utils.cc	Wed Oct 07 14:34:53 2009 -0400
+++ b/src/utils.cc	Thu Oct 08 08:03:59 2009 +0200
@@ -1000,6 +1000,31 @@
     check_dimensions (nr, nc, warn_for); // May set error_state.
 }
 
+octave_idx_type
+dims_to_numel (const dim_vector& dims, const octave_value_list& idx)
+{
+  octave_idx_type retval;
+
+  octave_idx_type len = idx.length ();
+
+  if (len == 0)
+    retval = dims.numel ();
+  else
+    {
+      const dim_vector dv = dims.redim (len);
+      retval = 1;
+      for (octave_idx_type i = 0; i < len; i++)
+        {
+          if (idx(i).is_magic_colon ())
+            retval *= dv(i);
+          else
+            retval *= idx(i).numel ();
+        }
+    }
+
+  return retval;
+}
+
 Matrix
 identity_matrix (octave_idx_type nr, octave_idx_type nc)
 {
--- a/src/utils.h	Wed Oct 07 14:34:53 2009 -0400
+++ b/src/utils.h	Thu Oct 08 08:03:59 2009 +0200
@@ -92,6 +92,11 @@
 get_dimensions (const octave_value& a,const char *warn_for,
 		octave_idx_type& nr, octave_idx_type& nc);
 
+extern OCTINTERP_API octave_idx_type
+dims_to_numel (const dim_vector& dims, const octave_value_list& idx);
+
+
+
 extern OCTINTERP_API Matrix
 identity_matrix (octave_idx_type nr, octave_idx_type nc);