diff libinterp/corefcn/sub2ind.cc @ 30902:972959edc3ff

Allow sub2ind() to accept indices outside the size of the input subscripts (bug #62184) * NEWS.8.md: Announce change in Matlab Compatibility section. * sub2ind.cc: Add '#include "utility"' for access to std::swap. * sub2ind.cc (Fsub2ind): Check nargout to figure out ndims of output. For special case of vector (1-dimension), put in code to guarantee a row vector output. Add BIST tests for bug #62184. Remove input validation BIST which no longer applies. * Array-util.cc (ind2sub): Remove input validation requiring index to be within range of subscript size. Adjust code to put all remaining elements in the final output dimension.
author John W. Eaton <jwe@octave.org>
date Tue, 05 Apr 2022 15:12:34 -0700
parents a8d61c30f41a
children e88a07dec498
line wrap: on
line diff
--- a/libinterp/corefcn/sub2ind.cc	Tue Apr 05 13:54:18 2022 -0700
+++ b/libinterp/corefcn/sub2ind.cc	Tue Apr 05 15:12:34 2022 -0700
@@ -27,6 +27,8 @@
 #  include "config.h"
 #endif
 
+#include <utility>
+
 #include "Array-util.h"
 #include "oct-locbuf.h"
 #include "quit.h"
@@ -260,12 +262,20 @@
 
   octave_value_list retval;
 
-  // Redimension to provided number of subscripts.
+  int nd = (nargout == 0) ? 1 : nargout;
+
   dim_vector dv = get_dim_vector (args(0), "ind2sub").redim (nargout);
 
+  // Redim for 1 will give us a column vector but we want a row vector.
+  if (nd == 1)
+    std::swap (dv(0), dv(1));
+
   try
     {
       retval = Array<octave_value> (ind2sub (dv, args(1).index_vector ()));
+
+      if (nd == 1)
+        retval(0) = retval(1);
     }
   catch (const index_exception& ie)
     {
@@ -310,8 +320,18 @@
 %! r = ind2sub ([2, 2, 2], 1:8);
 %! assert (r, 1:8);
 
+## Indexing beyond specified size (bug #62184)
+%!assert <*62184> (ind2sub (1, 2), 2)
+%!assert <*62184> (ind2sub ([3,3], 10), 10)
+%!test <*62184>
+%! [r,c] = ind2sub ([3,3], 10);
+%! assert ([r, c], [1, 4]);
+%!test <*62184>
+%! [r,c,p] = ind2sub ([3,3], 10);
+%! assert ([r, c, p], [1, 1, 2]);
+
+## Test input validation
 %!error <DIMS must contain integers> ind2sub ([2, -2], 3)
-%!error <index out of range> ind2sub ([2, 2, 2], 1:9)
 %!error <invalid index> ind2sub ([2, 2, 2], -1:8)
 */