changeset 5881:70b3f8f1a793

[project @ 2006-07-08 03:54:17 by jwe]
author jwe
date Sat, 08 Jul 2006 03:56:46 +0000
parents 84ca47e311b3
children ef3127d910bc
files scripts/ChangeLog scripts/miscellaneous/orderfields.m scripts/miscellaneous/setfield.m src/ChangeLog src/oct-map.cc src/oct-map.h src/ov-base.h src/ov-bool.h src/ov.h
diffstat 9 files changed, 144 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/ChangeLog
+++ b/scripts/ChangeLog
@@ -1,3 +1,7 @@
+2006-07-07  John W. Eaton  <jwe@octave.org>
+
+	* miscellaneous/orderfields.m: New file.
+
 2006-06-30  John W. Eaton  <jwe@octave.org>
 
 	* time/datevec.m: Make another attempt to account for precision of
new file mode 100644
--- /dev/null
+++ b/scripts/miscellaneous/orderfields.m
@@ -0,0 +1,96 @@
+## Copyright (C) 2006  Paul Kienzle
+##
+## 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 2, 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, write to the Free
+## Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+## 02110-1301, USA.
+
+## -*- texinfo -*-
+## @deftypefn {Built-in Function} {[@var{t}, @var{p}] =} orderfields (@var{s1}, @var{s2})
+## Return a struct with fields arranged alphabetically or as specified
+## by @var{s2} and a corresponding permutation vector.
+##
+## Given one struct, arrange field names in @var{s1} alphabetically.
+##
+## Given two structs, arrange field names in @var{s1} as they appear
+## in @var{s2}.  The second argument may also specify the order in
+## a permutation vector or a cell array of strings.
+##
+## @seealso{getfield, rmfield, isfield, isstruct, fieldnames, struct}
+## @end deftypefn
+
+## Author: Paul Kienzle <pkienzle@users.sf.net>
+## Adapted-By: jwe
+
+function [t, p] = orderfields (s1, s2)
+
+  if (nargin == 1 || nargin == 2)
+    if (! isstruct (s1))
+      error ("orderfields: expecting argument to be a struct");
+    endif
+  else
+    print_usage ();
+  endif
+
+  if (nargin == 1)
+    ## One structure: return the fields in alphabetical order.
+    if (isstruct(s1))
+      names = sort (fieldnames (s1));
+    endif
+  elseif (nargin == 2)
+    if (isstruct(s2))
+      ## Two structures: return the fields in the order of s2.
+      names = fieldnames (s2);
+      if (! isequal (sort (fieldnames (s1)), sort (names)))
+	error ("orderfields: s1 and s2 do not have same fields");
+      endif
+    elseif (iscellstr (s2))
+      ## A structure and a list of fields: order by the list of fields.
+      t1 = sort (fieldnames (s1));
+      t2 = sort (s2(:));
+      if (! isequal (t1, t2))
+	error ("orderfields: invalid cell array of field names");
+      endif
+      names = s2;
+    elseif (isvector (s2))
+      ## A structure and a permutation vector: permute the order of s1.
+      names = fieldnames (s1);
+      t1 = sort (s2);
+      t1 = t1(:)';
+      t2 = 1:length (names);
+      if (! isequal (t1, t2))
+	error ("orderfields: invalid permutation vector");
+      endif
+      names = names(s2);
+    endif
+  endif
+
+  ## Find permutation vector which converts the original name order
+  ## into the new name order.  Note: could save a couple of sorts
+  ## in some cases, but performance isn't critical.
+
+  if (nargout == 2)
+    [oldel, oldidx] = sort (fieldnames (s1));
+    [newel, newidx] = sort (names);
+    p = oldidx(newidx);
+  endif
+
+  ## Permute the names in the structure.
+  for i = 1:length (names)
+    el = names(i);
+    t(:).(el) = s1(:).(el);
+  endfor
+
+endfunction
--- a/scripts/miscellaneous/setfield.m
+++ b/scripts/miscellaneous/setfield.m
@@ -18,8 +18,8 @@
 ## 02110-1301, USA.
 
 ## -*- texinfo -*-
-## @deftypefn {Built-in Function} {} [@var{k1},..., @var{v1}] =
-## @code{setfield (@var{s}, 'k1',..., 'v1')} sets field members in a structure
+## @deftypefn {Built-in Function} {[@var{k1},..., @var{v1}] =} setfield (@var{s}, @var{k1}, @var{v1}, @dots{})
+## Set field members in a structure.
 ##
 ## @example
 ## @group
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,19 @@
+2006-07-07  John W. Eaton  <jwe@octave.org>
+
+	* ov.h (octave_value::is_bool_scalar): New function.
+	* ov-base.h (octave_base_value::is_bool_scalar): New function.
+	* ov-bool.h (octave_bool::is_bool_scalar): New function.
+
+	* oct-map.cc (Octave_map::keys): Use assert.
+	(Octave_map::assign): Avoid inserting new key in map unless
+	assignment to cell succeeds.
+
+	* oct-map.h (Octave_map::del): Only touch key_list if map contains key.
+	Assert that key_list contains key.
+
+	* oct-map.h (Octave_map::maybe_add_to_key_list): For efficiency,
+	check map, not key_list.  From Paul Kienzle  <pkienzle@users.sf.net>.
+
 2006-07-06  John W. Eaton  <jwe@octave.org>
 
 	* DLD-FUNCTIONS/__glpk__.cc (F__glpk__): Declare mrowsc volatile.
--- a/src/oct-map.cc
+++ b/src/oct-map.cc
@@ -98,6 +98,8 @@
       abort ();
     }
 
+  assert (length () == key_list.size ());
+
   return string_vector (key_list);
 }
 
@@ -183,9 +185,9 @@
 
   if (length() == rb.length())
     {
-      for (Octave_map::const_iterator pa = begin (); pa != end (); pa++)
+      for (const_iterator pa = begin (); pa != end (); pa++)
 	{
-	  Octave_map::const_iterator pb = rb.seek (key(pa));
+	  const_iterator pb = rb.seek (key(pa));
 
 	  if (pb == rb.end ())
 	    {
@@ -240,7 +242,7 @@
 	{
 	  std::string k = t_keys[i];
 
-	  map[k] = contents (k).assign (idx, Cell());
+	  map[k] = contents(k).assign (idx, Cell());
 
 	  if (error_state)
 	    break;
@@ -314,7 +316,10 @@
 Octave_map::assign (const octave_value_list& idx, const std::string& k,
 		    const Cell& rhs)
 {
-  Cell tmp = map[k];
+  Cell tmp;
+
+  if (contains (k))
+    tmp = map[k];
 
   octave_value fill_value = Matrix ();
 
--- a/src/oct-map.h
+++ b/src/oct-map.h
@@ -93,12 +93,17 @@
   void del (const std::string& k)
     {
       iterator p = map.find (k);
+
       if (p != map.end ())
-	map.erase (p);
+	{
+	  map.erase (p);
 
-      key_list_iterator q = find (key_list.begin (), key_list.end (), k);
-      if (q != key_list.end ())
-	key_list.erase (q);
+	  key_list_iterator q = find (key_list.begin (), key_list.end (), k);
+
+	  assert (q != key_list.end ());
+
+	  key_list.erase (q);
+	}
     }
 
   iterator begin (void) { return iterator (map.begin ()); }
@@ -178,9 +183,7 @@
 
   void maybe_add_to_key_list (const std::string& k)
   {
-    key_list_iterator p = find (key_list.begin (), key_list.end (), k);
-
-    if (p == key_list.end ())
+    if (! contains (k))
       key_list.push_back (k);
   }
 };
--- a/src/ov-base.h
+++ b/src/ov-base.h
@@ -204,6 +204,8 @@
 
   virtual bool is_complex_matrix (void) const { return false; }
 
+  virtual bool is_bool_scalar (void) const { return false; }
+
   virtual bool is_bool_matrix (void) const { return false; }
 
   virtual bool is_char_matrix (void) const { return false; }
--- a/src/ov-bool.h
+++ b/src/ov-bool.h
@@ -73,6 +73,8 @@
 
   bool is_real_scalar (void) const { return true; }
 
+  bool is_bool_scalar (void) const { return true; }
+
   bool is_bool_type (void) const { return true; }
 
   bool is_real_type (void) const { return true; }
--- a/src/ov.h
+++ b/src/ov.h
@@ -400,6 +400,9 @@
   bool is_complex_matrix (void) const
     { return rep->is_complex_matrix (); }
 
+  bool is_bool_scalar (void) const
+    { return rep->is_bool_scalar (); }
+
   bool is_bool_matrix (void) const
     { return rep->is_bool_matrix (); }