comparison libinterp/octave-value/ov-classdef.cc @ 16695:2823f8e3da77 classdef

Add multi-level index assignment for object array. * libinterp/octave-value/ov-classdef.h (cdef_object::is): New method. * libinterp/octave-value/ov-classdef.cc (cdef_object_array::subsasgn): Support multi-level index assignment.
author Michael Goffioul <michael.goffioul@gmail.com>
date Thu, 23 May 2013 14:12:33 -0400
parents 50b37deadb66
children 665fa0f621cc
comparison
equal deleted inserted replaced
16694:50b37deadb66 16695:2823f8e3da77
1370 rhs_obj.class_name ().c_str (), 1370 rhs_obj.class_name ().c_str (),
1371 class_name ().c_str ()); 1371 class_name ().c_str ());
1372 } 1372 }
1373 } 1373 }
1374 else 1374 else
1375 ::error ("can't perform indexing operation on array of %s objects", 1375 {
1376 class_name ().c_str ()); 1376 const octave_value_list& ival = idx.front ();
1377
1378 bool is_scalar = true;
1379
1380 Array<idx_vector> iv (dim_vector (1, ival.length ()));
1381
1382 for (int i = 0; ! error_state && i < ival.length (); i++)
1383 {
1384 iv(i) = ival(i).index_vector ();
1385
1386 if (! error_state)
1387 {
1388 is_scalar = is_scalar && iv(i).is_scalar ();
1389
1390 if (! is_scalar)
1391 error ("subsasgn: invalid indexing for object array "
1392 "assignment, the index must reference a single "
1393 "object in the array.");
1394 }
1395 }
1396
1397 if (! error_state)
1398 {
1399 Array<cdef_object> a = array.index (iv, true);
1400
1401 if (a.numel () != 1)
1402 error ("subsasgn: invalid indexing for object array "
1403 "assignment");
1404
1405 if (! error_state)
1406 {
1407 cdef_object obj = a(0);
1408
1409 // If the object in 'a' is not valid, this means the index
1410 // was out-of-bound and we need to create a new object.
1411
1412 if (! obj.ok ())
1413 obj = get_class ().construct_object (octave_value_list ());
1414
1415 std::list<octave_value_list> next_idx (idx);
1416
1417 next_idx.erase (next_idx.begin ());
1418
1419 octave_value tmp = obj.subsasgn (type.substr (1), next_idx,
1420 rhs);
1421
1422 if (! error_state)
1423 {
1424 cdef_object robj = to_cdef (tmp);
1425
1426 if (robj.ok ()
1427 && ! robj.is_array ()
1428 && robj.get_class () == get_class ())
1429 {
1430 // Small optimization, when dealing with handle
1431 // objects, we don't need to re-assign the result
1432 // of subsasgn back into the array.
1433
1434 if (! robj.is (a(0)))
1435 {
1436 Array<cdef_object> rhs_a (dim_vector (1, 1),
1437 robj);
1438
1439 octave_idx_type n = array.numel ();
1440
1441 array.assign (iv, rhs_a);
1442
1443 if (array.numel () > n)
1444 fill_empty_values ();
1445 }
1446
1447 refcount++;
1448
1449 retval = to_ov (cdef_object (this));
1450 }
1451 else
1452 error ("subasgn: invalid assignment into array of %s "
1453 "objects", class_name ().c_str ());
1454 }
1455 }
1456 }
1457 }
1377 break; 1458 break;
1378 1459
1379 default: 1460 default:
1380 ::error ("can't perform indexing operation on array of %s objects", 1461 ::error ("can't perform indexing operation on array of %s objects",
1381 class_name ().c_str ()); 1462 class_name ().c_str ());