Comparison

util-src/table.c @ 12402:8deb401a21f6

util.table: Backport table.move() from Lua 5.4 One difference is that 5.4 accepts "table-like" values (for this and other table.*() functions), but that would require additional backporting work.
author Matthew Wild <mwild1@gmail.com>
date Fri, 18 Mar 2022 15:21:25 +0000
parent 7969:1c6a07606309
child 12405:308ed64dc69b
comparison
equal deleted inserted replaced
12401:c029ddcad258 12402:8deb401a21f6
1 #include <lua.h> 1 #include <lua.h>
2 #include <lauxlib.h> 2 #include <lauxlib.h>
3
4 #ifndef LUA_MAXINTEGER
5 #include <stdint.h>
6 #define LUA_MAXINTEGER PTRDIFF_MAX
7 #endif
3 8
4 static int Lcreate_table(lua_State *L) { 9 static int Lcreate_table(lua_State *L) {
5 lua_createtable(L, luaL_checkinteger(L, 1), luaL_checkinteger(L, 2)); 10 lua_createtable(L, luaL_checkinteger(L, 1), luaL_checkinteger(L, 2));
6 return 1; 11 return 1;
7 } 12 }
8 13
14 /* COMPAT: w/ Lua pre-5.4 */
9 static int Lpack(lua_State *L) { 15 static int Lpack(lua_State *L) {
10 unsigned int n_args = lua_gettop(L); 16 unsigned int n_args = lua_gettop(L);
11 lua_createtable(L, n_args, 1); 17 lua_createtable(L, n_args, 1);
12 lua_insert(L, 1); 18 lua_insert(L, 1);
13 19
18 lua_pushinteger(L, n_args); 24 lua_pushinteger(L, n_args);
19 lua_setfield(L, -2, "n"); 25 lua_setfield(L, -2, "n");
20 return 1; 26 return 1;
21 } 27 }
22 28
29 /* COMPAT: w/ Lua pre-5.4 */
30 static int Lmove (lua_State *L) {
31 lua_Integer f = luaL_checkinteger(L, 2);
32 lua_Integer e = luaL_checkinteger(L, 3);
33 lua_Integer t = luaL_checkinteger(L, 4);
34
35 int tt = !lua_isnoneornil(L, 5) ? 5 : 1; /* destination table */
36 luaL_checktype(L, 1, LUA_TTABLE);
37 luaL_checktype(L, tt, LUA_TTABLE);
38
39 if (e >= f) { /* otherwise, nothing to move */
40 lua_Integer n, i;
41 luaL_argcheck(L, f > 0 || e < LUA_MAXINTEGER + f, 3,
42 "too many elements to move");
43 n = e - f + 1; /* number of elements to move */
44 luaL_argcheck(L, t <= LUA_MAXINTEGER - n + 1, 4,
45 "destination wrap around");
46 if (t > e || t <= f || (tt != 1 && !lua_compare(L, 1, tt, LUA_OPEQ))) {
47 for (i = 0; i < n; i++) {
48 lua_rawgeti(L, 1, f + i);
49 lua_rawseti(L, tt, t + i);
50 }
51 } else {
52 for (i = n - 1; i >= 0; i--) {
53 lua_rawgeti(L, 1, f + i);
54 lua_rawseti(L, tt, t + i);
55 }
56 }
57 }
58
59 lua_pushvalue(L, tt); /* return destination table */
60 return 1;
61 }
62
23 int luaopen_util_table(lua_State *L) { 63 int luaopen_util_table(lua_State *L) {
24 #if (LUA_VERSION_NUM > 501) 64 #if (LUA_VERSION_NUM > 501)
25 luaL_checkversion(L); 65 luaL_checkversion(L);
26 #endif 66 #endif
27 lua_createtable(L, 0, 2); 67 lua_createtable(L, 0, 2);
28 lua_pushcfunction(L, Lcreate_table); 68 lua_pushcfunction(L, Lcreate_table);
29 lua_setfield(L, -2, "create"); 69 lua_setfield(L, -2, "create");
30 lua_pushcfunction(L, Lpack); 70 lua_pushcfunction(L, Lpack);
31 lua_setfield(L, -2, "pack"); 71 lua_setfield(L, -2, "pack");
72 lua_pushcfunction(L, Lmove);
73 lua_setfield(L, -2, "move");
32 return 1; 74 return 1;
33 } 75 }