30#define TAB_RW (TAB_R | TAB_W)
33#define aux_getn(L,n,w) (checktab(L, n, (w) | TAB_L), luaL_len(L, n))
36static int checkfield (
lua_State *L,
const char *key,
int n) {
37 lua_pushstring(L, key);
38 return (lua_rawget(L, -n) != LUA_TNIL);
46static void checktab (
lua_State *L,
int arg,
int what) {
47 if (lua_type(L, arg) != LUA_TTABLE) {
49 if (lua_getmetatable(L, arg) &&
50 (!(what & TAB_R) || checkfield(L,
"__index", ++n)) &&
51 (!(what & TAB_W) || checkfield(L,
"__newindex", ++n)) &&
52 (!(what & TAB_L) || checkfield(L,
"__len", ++n))) {
56 luaL_checktype(L, arg, LUA_TTABLE);
63 lua_Integer e = aux_getn(L, 1, TAB_RW);
64 e = luaL_intop(+, e, 1);
65 switch (lua_gettop(L)) {
72 pos = luaL_checkinteger(L, 2);
74 luaL_argcheck(L, (lua_Unsigned)pos - 1u < (lua_Unsigned)e, 2,
75 "position out of bounds");
76 for (i = e; i > pos; i--) {
77 lua_geti(L, 1, i - 1);
83 return luaL_error(L,
"wrong number of arguments to 'insert'");
92 lua_Integer size = aux_getn(L, 1, TAB_RW);
93 lua_Integer pos = luaL_optinteger(L, 2, size);
96 luaL_argcheck(L, (lua_Unsigned)pos - 1u <= (lua_Unsigned)size, 2,
97 "position out of bounds");
99 for ( ; pos < size; pos++) {
100 lua_geti(L, 1, pos + 1);
116 lua_Integer f = luaL_checkinteger(L, 2);
117 lua_Integer e = luaL_checkinteger(L, 3);
118 lua_Integer t = luaL_checkinteger(L, 4);
119 int tt = !lua_isnoneornil(L, 5) ? 5 : 1;
120 checktab(L, 1, TAB_R);
121 checktab(L, tt, TAB_W);
124 luaL_argcheck(L, f > 0 || e < LUA_MAXINTEGER + f, 3,
125 "too many elements to move");
127 luaL_argcheck(L, t <= LUA_MAXINTEGER - n + 1, 4,
128 "destination wrap around");
129 if (t > e || t <= f || (tt != 1 && !lua_compare(L, 1, tt, LUA_OPEQ))) {
130 for (i = 0; i < n; i++) {
131 lua_geti(L, 1, f + i);
132 lua_seti(L, tt, t + i);
136 for (i = n - 1; i >= 0; i--) {
137 lua_geti(L, 1, f + i);
138 lua_seti(L, tt, t + i);
142 lua_pushvalue(L, tt);
149 if (l_unlikely(!lua_isstring(L, -1)))
150 luaL_error(L,
"invalid value (%s) at index %I in table for 'concat'",
151 luaL_typename(L, -1), (LUAI_UACINT)i);
158 lua_Integer last = aux_getn(L, 1, TAB_R);
160 const char *sep = luaL_optlstring(L, 2,
"", &lsep);
161 lua_Integer i = luaL_optinteger(L, 3, 1);
162 last = luaL_optinteger(L, 4, last);
163 luaL_buffinit(L, &b);
164 for (; i < last; i++) {
166 luaL_addlstring(&b, sep, lsep);
183 int n = lua_gettop(L);
184 lua_createtable(L, n, 1);
186 for (i = n; i >= 1; i--)
188 lua_pushinteger(L, n);
189 lua_setfield(L, 1,
"n");
196 lua_Integer i = luaL_optinteger(L, 2, 1);
197 lua_Integer e = luaL_opt(L, luaL_checkinteger, 3, luaL_len(L, 1));
199 n = (lua_Unsigned)e - i;
200 if (l_unlikely(n >= (
unsigned int)INT_MAX ||
201 !lua_checkstack(L, (
int)(++n))))
202 return luaL_error(L,
"too many results to unpack");
224typedef unsigned int IdxT;
233#if !defined(l_randomizePivot)
238#define sof(e) (sizeof(e) / sizeof(unsigned int))
246static unsigned int l_randomizePivot (
void) {
248 time_t t = time(NULL);
249 unsigned int buff[sof(c) + sof(t)];
250 unsigned int i, rnd = 0;
251 memcpy(buff, &c, sof(c) *
sizeof(
unsigned int));
252 memcpy(buff + sof(c), &t, sof(t) *
sizeof(
unsigned int));
253 for (i = 0; i < sof(buff); i++)
265static void set2 (
lua_State *L, IdxT i, IdxT j) {
275static int sort_comp (
lua_State *L,
int a,
int b) {
277 return lua_compare(L, a, b, LUA_OPLT);
281 lua_pushvalue(L, a-1);
282 lua_pushvalue(L, b-2);
284 res = lua_toboolean(L, -1);
298static IdxT partition (
lua_State *L, IdxT lo, IdxT up) {
304 while ((
void)lua_geti(L, 1, ++i), sort_comp(L, -1, -2)) {
305 if (l_unlikely(i == up - 1))
306 luaL_error(L,
"invalid order function for sorting");
311 while ((
void)lua_geti(L, 1, --j), sort_comp(L, -3, -1)) {
312 if (l_unlikely(j < i))
313 luaL_error(L,
"invalid order function for sorting");
334static IdxT choosePivot (IdxT lo, IdxT up,
unsigned int rnd) {
335 IdxT r4 = (up - lo) / 4;
336 IdxT p = rnd % (r4 * 2) + (lo + r4);
337 lua_assert(lo + r4 <= p && p <= up - r4);
345static void auxsort (
lua_State *L, IdxT lo, IdxT up,
353 if (sort_comp(L, -1, -2))
359 if (up - lo < RANLIMIT || rnd == 0)
362 p = choosePivot(lo, up, rnd);
365 if (sort_comp(L, -2, -1))
370 if (sort_comp(L, -1, -2))
378 lua_pushvalue(L, -1);
379 lua_geti(L, 1, up - 1);
381 p = partition(L, lo, up);
383 if (p - lo < up - p) {
384 auxsort(L, lo, p - 1, rnd);
389 auxsort(L, p + 1, up, rnd);
393 if ((up - lo) / 128 > n)
394 rnd = l_randomizePivot();
400 lua_Integer n = aux_getn(L, 1, TAB_RW);
402 luaL_argcheck(L, n < INT_MAX, 1,
"array too big");
403 if (!lua_isnoneornil(L, 2))
404 luaL_checktype(L, 2, LUA_TFUNCTION);
406 auxsort(L, 1, (IdxT)n, 0);
414static const luaL_Reg tab_funcs[] = {
426LUAMOD_API
int luaopen_table (
lua_State *L) {
427 luaL_newlib(L, tab_funcs);