changeset 8579:7e0f36dfefbe

implement octave_value_list using Array
author Jaroslav Hajek <highegg@gmail.com>
date Fri, 23 Jan 2009 09:57:19 +0100
parents 4b6558abe675
children 188d38a553c7
files liboctave/Array2.h liboctave/ArrayN.h liboctave/ChangeLog src/Cell.cc src/Cell.h src/ChangeLog src/gripes.cc src/gripes.h src/oct-obj.cc src/oct-obj.h src/ov-cell.cc src/ov-cs-list.cc src/ov-struct.cc src/pt-idx.cc
diffstat 14 files changed, 103 insertions(+), 164 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/Array2.h	Thu Jan 22 21:41:05 2009 -0500
+++ b/liboctave/Array2.h	Fri Jan 23 09:57:19 2009 +0100
@@ -116,14 +116,14 @@
       return Array2<T> (tmp, tmp.rows (), tmp.columns ());
     }
 
-  Array2<T> index (const idx_vector& i, int resize_ok = 0,
+  Array2<T> index (const idx_vector& i, bool resize_ok = false,
 		   const T& rfv = Array<T>::resize_fill_value ()) const
     {
       Array<T> tmp = Array<T>::index (i, resize_ok, rfv);
       return Array2<T> (tmp, tmp.rows (), tmp.columns ());
     }
 
-  Array2<T> index (const idx_vector& i, const idx_vector& j, int resize_ok = 0,
+  Array2<T> index (const idx_vector& i, const idx_vector& j, bool resize_ok = false,
 		   const T& rfv = Array<T>::resize_fill_value ()) const
     {
       Array<T> tmp = Array<T>::index (i, j, resize_ok, rfv);
--- a/liboctave/ArrayN.h	Thu Jan 22 21:41:05 2009 -0500
+++ b/liboctave/ArrayN.h	Fri Jan 23 09:57:19 2009 +0100
@@ -110,21 +110,21 @@
     return *this;
   }
 
-  ArrayN<T> index (idx_vector& i, int resize_ok = 0,
+  ArrayN<T> index (const idx_vector& i, bool resize_ok = false,
 		   const T& rfv = Array<T>::resize_fill_value ()) const
     {
       Array<T> tmp = Array<T>::index (i, resize_ok, rfv);
       return ArrayN<T> (tmp, tmp.dims ());
     }
 
-  ArrayN<T> index (idx_vector& i, idx_vector& j, int resize_ok = 0,
+  ArrayN<T> index (const idx_vector& i, const idx_vector& j, bool resize_ok = false,
 		   const T& rfv = Array<T>::resize_fill_value ()) const
     {
       Array<T> tmp = Array<T>::index (i, j, resize_ok, rfv);
       return ArrayN<T> (tmp, tmp.dims ());
     }
 
-  ArrayN<T> index (Array<idx_vector>& ra_idx, int resize_ok = 0,
+  ArrayN<T> index (const Array<idx_vector>& ra_idx, bool resize_ok = false,
 		   const T& rfv = Array<T>::resize_fill_value ()) const
     {
       Array<T> tmp = Array<T>::index (ra_idx, resize_ok, rfv);
--- a/liboctave/ChangeLog	Thu Jan 22 21:41:05 2009 -0500
+++ b/liboctave/ChangeLog	Fri Jan 23 09:57:19 2009 +0100
@@ -1,3 +1,9 @@
+2009-01-22  Jaroslav Hajek  <highegg@gmail.com>
+
+	* Array2.h (Array2<T>::index): Declare resize_ok as bool.
+	* ArrayN.h (ArrayN<T>::index): Dtto. Declare index vectors as const
+	refs.
+
 2009-01-22  Jaroslav Hajek  <highegg@gmail.com>
 
 	* Range.cc (sort_internal): Add missing test.
--- a/src/Cell.cc	Thu Jan 22 21:41:05 2009 -0500
+++ b/src/Cell.cc	Fri Jan 23 09:57:19 2009 +0100
@@ -29,6 +29,12 @@
 #include "Cell.h"
 #include "error.h"
 #include "gripes.h"
+#include "oct-obj.h"
+
+Cell::Cell (const octave_value_list& ovl)
+  : ArrayN<octave_value> (ovl.cell_value ())
+{
+}
 
 Cell::Cell (const string_vector& sv, bool trim)
   : ArrayN<octave_value> ()
--- a/src/Cell.h	Thu Jan 22 21:41:05 2009 -0500
+++ b/src/Cell.h	Fri Jan 23 09:57:19 2009 +0100
@@ -28,8 +28,9 @@
 #include "ArrayN.h"
 #include "oct-alloc.h"
 #include "str-vec.h"
+#include "ov.h"
 
-#include "oct-obj.h"
+class octave_value_list;
 
 class
 OCTINTERP_API
@@ -43,12 +44,7 @@
   Cell (const octave_value& val)
     : ArrayN<octave_value> (dim_vector (1, 1), val) { }
 
-  Cell (const octave_value_list& ovl)
-    : ArrayN<octave_value> (dim_vector (1, ovl.length ()))
-    {
-      for (octave_idx_type i = 0; i < ovl.length (); i++)
-	elem (i) = ovl (i);
-    }
+  Cell (const octave_value_list& ovl);
 
   Cell (octave_idx_type n, octave_idx_type m,
 	const octave_value& val = resize_fill_value ())
@@ -77,15 +73,15 @@
 
   Cell index (const octave_value_list& idx, bool resize_ok = false) const;
 
-  Cell index (idx_vector& i, int resize_ok = 0,
+  Cell index (const idx_vector& i, bool resize_ok = 0,
 	      const octave_value& rfv = resize_fill_value ()) const
     { return Cell (ArrayN<octave_value>::index (i, resize_ok, rfv)); }
 
-  Cell index (idx_vector& i, idx_vector& j, int resize_ok = 0,
+  Cell index (const idx_vector& i, idx_vector& j, bool resize_ok = 0,
 	      const octave_value& rfv = resize_fill_value ()) const
     { return Cell (ArrayN<octave_value>::index (i, j, resize_ok, rfv)); }
 
-  Cell index (Array<idx_vector>& ra_idx, int resize_ok = 0,
+  Cell index (const Array<idx_vector>& ra_idx, bool resize_ok = 0,
 	      const octave_value& rfv = resize_fill_value ()) const
     { return Cell (ArrayN<octave_value>::index (ra_idx, resize_ok, rfv)); }
 
--- a/src/ChangeLog	Thu Jan 22 21:41:05 2009 -0500
+++ b/src/ChangeLog	Fri Jan 23 09:57:19 2009 +0100
@@ -1,3 +1,22 @@
+2009-01-23  Jaroslav Hajek  <highegg@gmail.com>
+
+	* gripes.cc (gripe_indexed_cs_list, gripe_invalid_inquiry_subscript):
+	New functions.
+	* gripes.h: Declare them.
+	* pt-idx.cc: Remove definitions of the above funcs.
+	* ov-cell.cc (octave_cell::subsasgn): Remove dead branch.
+	* ov-struct.cc (octave_struct::subsasgn): Remove dead branch.
+	* ov-cs-list.cc (octave_cs_list::octave_cs_list (const Cell&)):
+	Optimize.
+
+2009-01-22  Jaroslav Hajek  <highegg@gmail.com>
+
+	* Cell.h (Cell::Cell (octave_value_list)): Only declare.
+	(Cell::index (*)): Change resize_ok type to bool.
+	* Cell.cc (Cell::Cell (octave_value_list)): Redefine.
+	* oct-obj.h, oct-obj.cc: Change octave_value_list::data to
+	Cell variable, reflect changes.
+
 2009-01-22  John W. Eaton  <jwe@octave.org>
 
 	* help.cc (do_which (std::ostream&, const std::string&), Fwhich):
--- a/src/gripes.cc	Thu Jan 22 21:41:05 2009 -0500
+++ b/src/gripes.cc	Fri Jan 23 09:57:19 2009 +0100
@@ -251,6 +251,18 @@
                    srctype, desttype);
 }
 
+void
+gripe_invalid_inquiry_subscript (void)
+{
+  error ("invalid dimension inquiry of a non-existent value");
+}
+
+void
+gripe_indexed_cs_list (void)
+{
+  error ("a cs-list cannot be further indexed");
+}
+
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
--- a/src/gripes.h	Thu Jan 22 21:41:05 2009 -0500
+++ b/src/gripes.h	Fri Jan 23 09:57:19 2009 +0100
@@ -131,6 +131,12 @@
 extern OCTINTERP_API void
 gripe_library_execution_error (void);
 
+extern OCTINTERP_API void
+gripe_invalid_inquiry_subscript (void);
+
+extern OCTINTERP_API void
+gripe_indexed_cs_list (void);
+
 #endif
 
 /*
--- a/src/oct-obj.cc	Thu Jan 22 21:41:05 2009 -0500
+++ b/src/oct-obj.cc	Fri Jan 23 09:57:19 2009 +0100
@@ -29,32 +29,9 @@
 #include "oct-obj.h"
 #include "Cell.h"
 
-octave_value_list::octave_value_list (const Cell& tc)
-  : data (tc.numel ())
-{
-  for (octave_idx_type i = 0; i < tc.numel (); i++)
-    data[i] = tc(i);
-}
-
 octave_allocator
 octave_value_list::allocator (sizeof (octave_value_list));
 
-void
-octave_value_list::resize (octave_idx_type n, const octave_value& val)
-{
-  octave_idx_type len = length ();
-
-  if (n > len)
-    {
-      data.resize (n);
-
-      for (octave_idx_type i = len; i < n; i++)
-	data[i] = val;
-    }
-  else if (n < len)
-    data.resize (n);
-}
-
 octave_value_list&
 octave_value_list::prepend (const octave_value& val)
 {
@@ -247,8 +224,15 @@
 octave_value_list::make_storable_values (void)
 {
   octave_idx_type len = length ();
+  const Array<octave_value>& cdata = data;
+
   for (octave_idx_type i = 0; i < len; i++)
-    data[i].make_storable_value ();
+    {
+      // This is optimized so that we don't force a copy unless necessary.
+      octave_value tmp = cdata(i).storable_value ();
+      if (! tmp.is_copy_of (cdata (i)))
+        data(i) = tmp;
+    }
 }
 
 /*
--- a/src/oct-obj.h	Thu Jan 22 21:41:05 2009 -0500
+++ b/src/oct-obj.h	Fri Jan 23 09:57:19 2009 +0100
@@ -29,9 +29,10 @@
 
 #include "oct-alloc.h"
 #include "str-vec.h"
+#include "Array.h"
 
 #include "ov.h"
-class Cell;
+#include "Cell.h"
 
 class
 OCTINTERP_API
@@ -43,12 +44,16 @@
     : data () { }
 
   octave_value_list (octave_idx_type n, const octave_value& val)
-    : data (n, val) { }
+    : data (dim_vector (1, n), val) { }
 
   octave_value_list (const octave_value& tc)
     : data (1, tc) { }
 
-  octave_value_list (const Cell& tc);
+  octave_value_list (const Array<octave_value>& d)
+    : data (d.reshape (dim_vector (1, d.numel ()))) { }
+
+  octave_value_list (const Cell& tc)
+    : data (tc.reshape (dim_vector (1, tc.numel ()))) { }
 
   octave_value_list (const octave_value_list& obj)
     : data (obj.data), names (obj.names) { }
@@ -86,19 +91,24 @@
       return *this;
     }
 
+  Array<octave_value> array_value (void) const { return data; }
+
+  Cell cell_value (void) const { return array_value (); }
+
   // Assignment will resize on range errors.
 
   octave_value& operator () (octave_idx_type n) { return elem (n); }
 
   octave_value operator () (octave_idx_type n) const { return elem (n); }
 
-  octave_idx_type length (void) const { return data.size (); }
+  octave_idx_type length (void) const { return data.length (); }
 
   bool empty (void) const { return length () == 0; }
 
   void resize (octave_idx_type n) { data.resize (n); }
 
-  void resize (octave_idx_type n, const octave_value& val);
+  void resize (octave_idx_type n, const octave_value& val)
+    { data.resize (n, val); }
 
   octave_value_list& prepend (const octave_value& val);
 
@@ -109,6 +119,10 @@
   octave_value_list& reverse (void);
 
   octave_value_list
+  slice (octave_idx_type offset, octave_idx_type len) const
+    { return data.index (idx_vector (offset, offset + len)); }
+
+  octave_value_list
   splice (octave_idx_type offset, octave_idx_type len,
 	  const octave_value_list& lst = octave_value_list ()) const;
 
@@ -130,7 +144,7 @@
 
   static octave_allocator allocator;
 
-  std::vector<octave_value> data;
+  Array<octave_value> data;
 
   // This list of strings can be used to tag each element of data with
   // a name.  By default, it is empty.
@@ -152,26 +166,16 @@
 
   octave_value_list (octave_idx_type n);
 
-  octave_value_list (const Array<octave_value>& d);
-
   octave_value& elem (octave_idx_type n)
     {
-      static Matrix empty_matrix;
+      if (n >= length ())
+	resize (n + 1);
 
-      if (n >= length ())
-	resize (n+1, empty_matrix);
-
-      return data[n];
+      return data(n);
     }
 
   octave_value elem (octave_idx_type n) const
-    {
-#if defined (BOUNDS_CHECKING)
-      return data.at (n);
-#else
-      return data[n];
-#endif
-    }
+    { return data(n); }
 };
 
 #endif
--- a/src/ov-cell.cc	Thu Jan 22 21:41:05 2009 -0500
+++ b/src/ov-cell.cc	Fri Jan 23 09:57:19 2009 +0100
@@ -48,6 +48,7 @@
 #include "ov-scalar.h"
 #include "pr-output.h"
 #include "ov-scalar.h"
+#include "gripes.h"
 
 #include "ls-oct-ascii.h"
 #include "ls-oct-binary.h"
@@ -140,7 +141,7 @@
 	    if (tcell.length () == 1)
 	      retval = tcell(0,0);
 	    else
-              retval = octave_value (octave_value_list (tcell), auto_add);
+              retval = octave_value (octave_value_list (tcell), true);
 	  }
       }
       break;
@@ -227,40 +228,12 @@
 
                 std::string next_type = type.substr (1);
 
-                if (rhs.is_cs_list ())
-                  {
-                    const octave_value_list rhsl = rhs.list_value ();
-                    if (tmpc.numel () == rhsl.length ())
-                      {
-                        for (octave_idx_type k = 0; k < tmpc.numel () && ! error_state; k++)
-                          {
-                            octave_value tmp = tmpc (k);
-                            if (! tmp.is_defined () || tmp.is_zero_by_zero ())
-                              {
-                                tmp = octave_value::empty_conv (next_type, rhs);
-                                tmp.make_unique (); // probably a no-op.
-                              }
-                            else
-                              // optimization: ignore the copy still stored inside our array and in tmpc.
-                              tmp.make_unique (2);
-
-                            tmpc(k) = tmp.subsasgn (next_type, next_idx, rhsl(k));
-                          }
-
-                        t_rhs = octave_value (octave_value_list (tmpc), true);
-                      }
-                    else
-                      error ("invalid cs-list length in assignment");
-                  }
-                else if (tmpc.numel () == 1)
+                if (tmpc.numel () == 1)
 		  {
 		    octave_value tmp = tmpc(0);
 
 		    if (! tmp.is_defined () || tmp.is_zero_by_zero ())
-                      {
-                        tmp = octave_value::empty_conv (type.substr (1), rhs);
-                        tmp.make_unique (); // probably a no-op.
-                      }
+                      tmp = octave_value::empty_conv (type.substr (1), rhs);
                     else
                       // optimization: ignore the copy still stored inside our array and in tmpc.
                       tmp.make_unique (2);
@@ -269,7 +242,7 @@
 		      t_rhs = tmp.subsasgn (next_type, next_idx, rhs);
 		  }
                 else
-                  error ("invalid assignment to cs-list outside multiple assignment.");
+                  gripe_indexed_cs_list ();
 	      }
 	  }
 	  break;
--- a/src/ov-cs-list.cc	Thu Jan 22 21:41:05 2009 -0500
+++ b/src/ov-cs-list.cc	Fri Jan 23 09:57:19 2009 +0100
@@ -39,14 +39,8 @@
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_cs_list, "cs-list", "cs-list");
 
 octave_cs_list::octave_cs_list (const Cell& c)
-  : octave_base_value (), lst ()
+  : octave_base_value (), lst (c)
 {
-  octave_idx_type n = c.length ();
-
-  lst.resize (n);
-
-  for (octave_idx_type i = 0; i < n; i++)
-    lst(i) = c(i);
 }
 
 /*
--- a/src/ov-struct.cc	Thu Jan 22 21:41:05 2009 -0500
+++ b/src/ov-struct.cc	Fri Jan 23 09:57:19 2009 +0100
@@ -301,32 +301,7 @@
                 // FIXME: better code reuse? cf. octave_cell::subsasgn and the case below.
 		if (! error_state)
 		  {
-                    if (rhs.is_cs_list ())
-                      {
-                        octave_value_list rhsl = rhs.list_value ();
-                        if (tmpc.numel () == rhsl.length ())
-                          {
-                            for (octave_idx_type k = 0; k < tmpc.numel () && ! error_state; k++)
-                              {
-                                octave_value tmp = tmpc (k);
-                                if (! tmp.is_defined () || tmp.is_zero_by_zero ())
-                                  {
-                                    tmp = octave_value::empty_conv (next_type, rhs);
-                                    tmp.make_unique (); // probably a no-op.
-                                  }
-                                else
-                                  // optimization: ignore the copy still stored inside our map and in tmpc.
-                                  tmp.make_unique (2);
-
-                                tmpc(k) = tmp.subsasgn (next_type, next_idx, rhsl(k));
-                              }
-
-                            t_rhs = octave_value (octave_value_list (tmpc), true);
-                          }
-                        else
-                          error ("invalid cs-list length in assignment");
-                      }
-                    else if (tmpc.numel () == 1)
+                    if (tmpc.numel () == 1)
                       {
                         octave_value tmp = tmpc(0);
 
@@ -343,7 +318,7 @@
                           t_rhs = tmp.subsasgn (next_type, next_idx, rhs);
                       }
                     else
-                      error ("invalid assignment to cs-list outside multiple assignment.");
+                      gripe_indexed_cs_list ();
 		  }
 	      }
 	    else
@@ -373,32 +348,7 @@
             // FIXME: better code reuse?
             if (! error_state)
               {
-                if (rhs.is_cs_list ())
-                  {
-                    octave_value_list rhsl = rhs.list_value ();
-                    if (tmpc.numel () == rhsl.length ())
-                      {
-                        for (octave_idx_type k = 0; k < tmpc.numel () && ! error_state; k++)
-                          {
-                            octave_value tmp = tmpc (k);
-                            if (! tmp.is_defined () || tmp.is_zero_by_zero ())
-                              {
-                                tmp = octave_value::empty_conv (next_type, rhs);
-                                tmp.make_unique (); // probably a no-op.
-                              }
-                            else
-                              // optimization: ignore the copy still stored inside our map.
-                              tmp.make_unique (1);
-
-                            tmpc(k) = tmp.subsasgn (next_type, next_idx, rhsl(k));
-                          }
-
-                        t_rhs = octave_value (octave_value_list (tmpc), true);
-                      }
-                    else
-                      error ("invalid cs-list length in assignment");
-                  }
-                else if (tmpc.numel () == 1)
+                if (tmpc.numel () == 1)
                   {
                     octave_value tmp = tmpc(0);
 
@@ -415,7 +365,7 @@
                       t_rhs = tmp.subsasgn (next_type, next_idx, rhs);
                   }
                 else
-                  error ("invalid assignment to cs-list outside multiple assignment.");
+                  gripe_indexed_cs_list ();
               }
 	  }
 	  break;
--- a/src/pt-idx.cc	Thu Jan 22 21:41:05 2009 -0500
+++ b/src/pt-idx.cc	Fri Jan 23 09:57:19 2009 +0100
@@ -39,6 +39,7 @@
 #include "pt-walk.h"
 #include "utils.h"
 #include "variables.h"
+#include "gripes.h"
 
 // Index expressions.
 
@@ -263,18 +264,6 @@
   return m;
 }
 
-static void
-gripe_invalid_inquiry_subscript (void)
-{
-  error ("invalid dimension inquiry of a non-existent value");
-}
-
-static void
-gripe_indexed_cs_list (void)
-{
-  error ("a cs-list cannot be further indexed");
-}
-
 octave_value_list
 tree_index_expression::rvalue (int nargout)
 {