Mercurial > forge
changeset 1242:00c9d2c0a105 octave-forge
Add struct() for octave versions which can support it (2.1.52 and up)
author | pkienzle |
---|---|
date | Wed, 28 Jan 2004 22:48:49 +0000 |
parents | a54d2a8ea2e9 |
children | bc93502febc2 |
files | main/struct/Makefile main/struct/struct.cc |
diffstat | 2 files changed, 127 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/main/struct/Makefile Wed Jan 28 22:40:04 2004 +0000 +++ b/main/struct/Makefile Wed Jan 28 22:48:49 2004 +0000 @@ -1,5 +1,10 @@ include ../../Makeconf -all: getfield.oct setfield.oct +# struct.cc hasn't been back-ported +ifeq ($(HAVE_OCTAVE_MAP_INDEX),) +STRUCT=struct.oct +endif + +all: getfield.oct setfield.oct $(STRUCT) clean: ; -$(RM) *.o core octave-core *.oct *~
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/struct/struct.cc Wed Jan 28 22:48:49 2004 +0000 @@ -0,0 +1,121 @@ +#include <octave/oct.h> +#include <octave/oct-map.h> + +static bool +scalar (const dim_vector& dims) +{ + return dims.length () == 2 && dims (0) == 1 && dims (1) == 1; +} + +/* +%!shared x +%! x(1).a=1; x(2).a=2; x(1).b=3; x(2).b=3; +%!assert(struct('a',1,'b',3),x(1)) +%!assert(struct('a',{},'b',{}),x([])) +%!assert(struct('a',{1,2},'b',{3,3}),x) +%!assert(struct('a',{1,2},'b',3),x) +%!assert(struct('a',{1,2},'b',{3}),x) +%!assert(struct('b',3,'a',{1,2}),x) +%!assert(struct('b',{3},'a',{1,2}),x) + */ + +DEFUN_DLD (struct, args, , "\ +struct('field',value,'field',value,...)\n\n\ + Create a structure and initialize its value.\n\n\ +struct('field',{values},'field',{values},...)\n\n\ + Create a structure array and initialize its values. The dimensions\n\ + of each array of values must match. Singleton cells and non-cell values\n\ + are repeated so that they fill the entire array.\n\n\ +struct('field',{},'field',{},...)\n\n\ + Create an empty structure array.") +{ + octave_value_list retval; + int nargin = args.length (); + + // Check that there is an even number of args + if (nargin == 0 || nargin%2 == 1) + { + print_usage ("struct"); + return retval; + } + + // Check that every second arg is a field name + for (int i=0; i < nargin; i+=2) + { + if (!args (i).is_string ()) + { + error ("struct expects alternating 'field',value pairs"); + return retval; + } + } + + // Check that the dimensions of the fields correspond + dim_vector dims (args (1).is_cell () ? args (1).dims () : dim_vector (1,1)); + // std::cout << "initial dims = " << dims.str() << std::endl; + for (int i=3; i < nargin; i+=2) + { + if (args (i).is_cell ()) + { + if (scalar (dims)) + { + dims = args (i).dims (); + // std::cout << "scalar dims, using " << dims.str() << std::endl; + } + else + { + dim_vector testdim (args (i).dims ()); + if (!scalar (testdim) && dims != testdim) + { + error ("dimensions must match for all fields"); + return retval; + } + //std::cout<<dims.str()<<" matches "<<testdim.str()<<std::endl; + } + } + // else std::cout << dims.str() << " matches scalar" << std::endl; + } + + // Create the return value + // Octave_map(dim_vector) doesn't exist, so emulate one using the + // the first field name and a dummy cell array. + Octave_map map (args (0).string_value (), Cell (dims)); + // Octave_map map; + + for (int i=0; i < nargin; i+=2) + { + // Get key + std::string key (args (i).string_value ()); + if (error_state) return retval; // error converting to string + + // Value may be v, { v }, or { v1, v2, ... } + // In the first two cases, we need to create a cell array of + // the appropriate dimensions filled with v. In the last case, + // the cell array has already been determined to be of the + // correct dimensions. + if (args (i+1).is_cell ()) + { + const Cell c (args (i+1).cell_value ()); + if (error_state) return retval; // error converting to cell + if (scalar (c.dims ())) + { + // std::cout << "struct: assigning {scalar} "; + // c(0).print (std::cout); + map.assign (key, Cell (dims, c (0))); + } + else + { + //std::cout << "assigning {vector} "; args(i+1).print(std::cout); + map.assign (key, c); + } + } + else + { + // std::cout << "assigning scalar "; args(i+1).print(std::cout); + map.assign (key, Cell (dims, args (i+1))); + } + + if (error_state) return retval; // error from assign + } + + return octave_value (map); +}