comparison src/ov-class.cc @ 9151:d8f9588c6ba1

object exemplars
author John W. Eaton <jwe@octave.org>
date Thu, 23 Apr 2009 16:05:52 -0400
parents 69e6bbfef8c2
children b2b8ed43b922
comparison
equal deleted inserted replaced
9150:e716cafee800 9151:d8f9588c6ba1
1282 || fcn->is_class_constructor () 1282 || fcn->is_class_constructor ()
1283 || fcn->is_private_function_of_class (class_name ())) 1283 || fcn->is_private_function_of_class (class_name ()))
1284 && fcn->dispatch_class () == class_name ()); 1284 && fcn->dispatch_class () == class_name ());
1285 } 1285 }
1286 1286
1287 octave_class::exemplar_info::exemplar_info (const octave_value& obj)
1288 : field_names (), parent_class_names ()
1289 {
1290 if (obj.is_object ())
1291 {
1292 Octave_map m = obj.map_value ();
1293 field_names = m.keys ();
1294
1295 parent_class_names = obj.parent_class_name_list ();
1296 }
1297 else
1298 error ("invalid call to exmplar_info constructor");
1299 }
1300
1301
1302 // A map from class names to lists of fields.
1303 std::map<std::string, octave_class::exemplar_info> octave_class::exemplar_map;
1304
1305 bool
1306 octave_class::exemplar_info::compare (const octave_value& obj) const
1307 {
1308 bool retval = true;
1309
1310 if (obj.is_object ())
1311 {
1312 if (nfields () == obj.nfields ())
1313 {
1314 Octave_map obj_map = obj.map_value ();
1315 string_vector obj_fnames = obj_map.keys ();
1316 string_vector fnames = fields ();
1317
1318 for (octave_idx_type i = 0; i < nfields (); i++)
1319 {
1320 if (obj_fnames[i] != fnames[i])
1321 {
1322 retval = false;
1323 error ("mismatch in field names");
1324 break;
1325 }
1326 }
1327
1328 if (nparents () == obj.nparents ())
1329 {
1330 std::list<std::string> obj_parents
1331 = obj.parent_class_name_list ();
1332 std::list<std::string> pnames = parents ();
1333
1334 std::list<std::string>::const_iterator p = obj_parents.begin ();
1335 std::list<std::string>::const_iterator q = pnames.begin ();
1336
1337 while (p != obj_parents.end ())
1338 {
1339 if (*p++ != *q++)
1340 {
1341 retval = false;
1342 error ("mismatch in parent classes");
1343 break;
1344 }
1345 }
1346 }
1347 else
1348 {
1349 retval = false;
1350 error ("mismatch in number of parent classes");
1351 }
1352 }
1353 else
1354 {
1355 retval = false;
1356 error ("mismatch in number of fields");
1357 }
1358 }
1359 else
1360 {
1361 retval = false;
1362 error ("inavlid comparison of class exemplar to non-class object");
1363 }
1364
1365 return retval;
1366 }
1367
1287 DEFUN (class, args, , 1368 DEFUN (class, args, ,
1288 "-*- texinfo -*-\n\ 1369 "-*- texinfo -*-\n\
1289 @deftypefn {Built-in Function} {} class (@var{expr})\n\ 1370 @deftypefn {Built-in Function} {} class (@var{expr})\n\
1290 @deftypefnx {Built-in Function} {} class (@var{s}, @var{id})\n\ 1371 @deftypefnx {Built-in Function} {} class (@var{s}, @var{id})\n\
1291 @deftypefnx {Built-in Function} {} class (@var{s}, @var{id}, @var{p}, @dots{})\n\ 1372 @deftypefnx {Built-in Function} {} class (@var{s}, @var{id}, @var{p}, @dots{})\n\
1322 else 1403 else
1323 { 1404 {
1324 octave_value_list parents = args.slice (2, nargin-2); 1405 octave_value_list parents = args.slice (2, nargin-2);
1325 1406
1326 retval = octave_value (new octave_class (m, id, parents)); 1407 retval = octave_value (new octave_class (m, id, parents));
1408 }
1409
1410 if (! error_state)
1411 {
1412 octave_class::exemplar_const_iterator it
1413 = octave_class::exemplar_map.find (id);
1414
1415 if (it == octave_class::exemplar_map.end ())
1416 octave_class::exemplar_map[id]
1417 = octave_class::exemplar_info (retval);
1418 else if (! it->second.compare (retval))
1419 error ("class: object of class `%s' does not match previously constructed objects", id.c_str ());
1327 } 1420 }
1328 } 1421 }
1329 else 1422 else
1330 error ("class: invalid call from outside class constructor"); 1423 error ("class: invalid call from outside class constructor");
1331 } 1424 }