@@ -69,7 +69,7 @@ local mtable = object 'mtable' {
69
69
70
70
-- backup original methods and metamethods
71
71
local mtable_mt = getmetatable(mtable)
72
- local var_get, var_val, raw_get in mtable
72
+ local var_get, var_val in mtable
73
73
local tbl_cpy, var_set = mtable.copy, mtable_mt.__newindex
74
74
75
75
-- identity -------------------------------------------------------------------o
370
370
-- build mtable ---------------------------------------------------------------o
371
371
372
372
-- finalize mtable
373
- local function finish_mtbl (tbl)
373
+ local function fini_mtbl (tbl)
374
374
-- clear cycle (if any)
375
375
tbl:raw_set('__cycle', nil)
376
376
381
381
-- mtable initialization
382
382
local function init_mm (tbl)
383
383
local nc = tbl:raw_len()
384
+
385
+ if nc > 0 then -- check if mtable needs __dat
384
386
local pdat = tbl.parent.__dat
385
387
nc = nc + pdat.nc
386
388
local data = table.new(nc, 9) -- columns (data)
@@ -393,19 +395,16 @@ local function init_mm (tbl)
393
395
data.ng = 0 -- #gens
394
396
data.rmax = 1 -- allocated rows (specialize after 1st row)
395
397
396
- -- disable inheritance
397
- -- tbl:set_final()
398
-
399
398
-- create columns
400
399
for i=0,nc do data[i] = {} end
401
400
402
401
-- process columns names
403
402
tblcpy(pdat.cidx, data.cidx)
404
403
data.cidx.is_selected, data.cidx[0] = 0, 'is_selected' -- case pdat.nc == 0
405
404
406
- local cref = raw_get( tbl, 'refcol')
405
+ local cref = tbl:raw_get 'refcol'
407
406
for i=pdat.nc+1,nc do
408
- local col = raw_get(tbl, i-pdat.nc) -- column key
407
+ local col = tbl: raw_get(i-pdat.nc) -- column key
409
408
if is_table(col) then -- cref: { key }
410
409
assert(is_rawtable(col) and is_nil(col[2]), "invalid reference column")
411
410
data.cref, col = i, col[1]
@@ -435,21 +434,24 @@ local function init_mm (tbl)
435
434
436
435
-- clear list of column names
437
436
tbl:clear_array()
437
+
438
438
-- set current date and time
439
439
tbl.date, tbl.time = os.date'%d/%m/%y', os.date'%H:%M:%S'
440
440
441
+ -- finalize
442
+ tbl.__dat = data
443
+ fini_mtbl(tbl)
444
+ end -- nc > 0
445
+
441
446
-- concat header names and column names to parent ones for I/O
442
- local hdrnam, colnam = raw_get( tbl, 'header'), raw_get( tbl, 'column')
447
+ local hdrnam, colnam = tbl:raw_get 'header', tbl:raw_get 'column'
443
448
if is_table(hdrnam) and #hdrnam > 0 then
444
449
tbl.header = tblcat(tbl.parent.header or {}, hdrnam)
445
450
end
446
451
if is_table(colnam) and #colnam > 0 then
447
452
tbl.column = tblcat(tbl.parent.column or {}, colnam)
448
453
end
449
454
450
- -- finalized
451
- tbl.__dat = data
452
- finish_mtbl(tbl)
453
455
return tbl
454
456
end
455
457
458
460
local function copy_mm (tbl, name_)
459
461
assert(not rawequal(tbl, mtable), "invalid argument #1 (cannot copy 'mtable')")
460
462
assert(is_mtable(tbl) , "invalid argument #1 (mtable expected)")
461
- local cpy = tbl_cpy(tbl,name_)
463
+ local cpy = tbl_cpy(tbl,name_)
464
+
465
+ -- check if copy needs to be further processed
466
+ if tbl:is_view() then return cpy end
467
+
462
468
local data = tbl.__dat
463
469
local nr, nc = data.nr, data.nc
464
470
local cdat = table.new(nc, 9) -- see init_mm
@@ -469,6 +475,7 @@ local function copy_mm (tbl, name_)
469
475
cdat.nc = nc -- #cols
470
476
cdat.ng = 0 -- #gens
471
477
cdat.rmax = nr -- allocated rows (no oversize with rmax)
478
+ cpy.__dat = cdat
472
479
473
480
tblcpy(data.cidx, cdat.cidx)
474
481
cdat.nvec = data.nvec == data.cidx and cdat.cidx or tblcpy(data.nvec)
@@ -477,8 +484,6 @@ local function copy_mm (tbl, name_)
477
484
cdat[i] = isa_matrix(col) and col:copy() or tblicpy(col, table.new(nr,0))
478
485
end
479
486
480
- cpy:raw_set('__dat', cdat)
481
-
482
487
return cpy:make_dict()
483
488
end
484
489
@@ -628,12 +633,17 @@ local function build_index (tbl, key_)
628
633
end
629
634
630
635
build_idx (data)
631
- finish_mtbl (tbl)
636
+ fini_mtbl (tbl)
632
637
return tbl
633
638
end
634
639
635
640
-- methods (readonly) ---------------------------------------------------------o
636
641
642
+ local function is_view (tbl)
643
+ assert(is_mtable(tbl), "invalid argument #1 (mtable expected)")
644
+ return is_nil(tbl:raw_get'__dat')
645
+ end
646
+
637
647
local function index (tbl, idx)
638
648
assert(is_mtable (tbl), "invalid argument #1 (mtable expected)")
639
649
assert(is_integer(idx), "invalid argument #2 (integer expected)")
@@ -1177,7 +1187,7 @@ local function remove (tbl, rng_, sel_)
1177
1187
end
1178
1188
data.nr = ni
1179
1189
1180
- return build_index( tbl)
1190
+ return tbl:make_dict( )
1181
1191
end
1182
1192
1183
1193
local function insert (tbl, rows, rng_, sel_)
@@ -1243,7 +1253,7 @@ local function insert (tbl, rows, rng_, sel_)
1243
1253
i = i-1
1244
1254
end
1245
1255
1246
- return build_index( tbl)
1256
+ return tbl:make_dict( )
1247
1257
end
1248
1258
1249
1259
local function sort (tbl, cmp, rng_, sel_)
@@ -1288,14 +1298,15 @@ local function sort (tbl, cmp, rng_, sel_)
1288
1298
end
1289
1299
assert(is_nil(next(idx_l)), "unexpected corrupted lookup indexes (sort)")
1290
1300
1291
- return build_index( tbl)
1301
+ return tbl:make_dict( )
1292
1302
end
1293
1303
1294
1304
-- special --------------------------------------------------------------------o
1295
1305
1296
1306
local function cycle (tbl, a)
1297
- assert(is_mtable(tbl) , "invalid argument #1 (mtable expected)")
1298
- assert(index_of(tbl, a), "invalid argument #2 (valid reference expected)")
1307
+ assert(is_mtable(tbl), "invalid argument #1 (mtable expected)")
1308
+ assert(is_nil(a) or index_of(tbl, a),
1309
+ "invalid argument #2 (valid reference expected)")
1299
1310
assert(not tbl:is_readonly(), "invalid write access to readonly mtable")
1300
1311
tbl:raw_set('__cycle', a)
1301
1312
return tbl
@@ -1626,12 +1637,9 @@ local function read (tbl, filnam_)
1626
1637
tbl:addrow(row)
1627
1638
end
1628
1639
1629
- -- build index with column 'name' (if any)
1630
- local cref = raw_get(tbl, 'refcol')
1631
- if cref then build_index(tbl, cref) end
1632
-
1633
1640
if is_string(filnam_) then file:close() end
1634
- return tbl
1641
+
1642
+ return tbl:make_dict()
1635
1643
end
1636
1644
1637
1645
-- members --------------------------------------------------------------------o
@@ -1689,6 +1697,9 @@ mtable :set_methods {
1689
1697
cycle = cycle,
1690
1698
iter = iter,
1691
1699
1700
+ -- ownership
1701
+ is_view = is_view,
1702
+
1692
1703
-- read/write
1693
1704
read = read,
1694
1705
write = write,
0 commit comments