1 /**
2 Internal module for pushing and getting _arrays.
3 All _arrays with LuaD compatible element types are supported.
4 */
5 module luad.conversions.arrays;
6 
7 import std.traits;
8 import std.range : ElementType;
9 
10 import luad.c.all;
11 import luad.stack;
12 
13 void pushArray(T)(lua_State* L, ref T arr) if (isArray!T)
14 {
15 	assert(arr.length <= int.max, "lua_createtable only supports int.max many elements");
16 	lua_createtable(L, cast(int) arr.length, 0);
17 	foreach(i, v; arr)
18 	{
19 		pushValue(L, i + 1); //Lua tables start at 1, not 0
20 		pushValue(L, v);
21 		lua_rawset(L, -3);
22 	}
23 }
24 
25 T getArray(T)(lua_State* L, int idx) if (isArray!T)
26 {
27 	alias ElementType!T ElemType;
28 	auto len = lua_objlen(L, idx);
29 
30 	auto arr = new ElemType[len];
31 	foreach(i; 0 .. len)
32 	{
33 		lua_pushinteger(L, i + 1);
34 		lua_gettable(L, idx < 0? idx - 1 : idx);
35 		arr[i] = popValue!ElemType(L);
36 	}
37 
38 	return arr;
39 }
40 
41 void fillStaticArray(T)(lua_State* L, ref T arr) if(isStaticArray!T)
42 {
43 	foreach(i, ref elem; arr)
44 	{
45 		elem = getValue!(typeof(elem))(L, cast(int)(-arr.length + i));
46 	}
47 }
48 
49 void pushStaticArray(T)(lua_State* L, ref T arr) if(isStaticArray!T)
50 {
51 	foreach(elem; arr)
52 		pushValue(L, elem);
53 }
54 
55 version(unittest) import luad.testing;
56 
57 unittest
58 {
59 	lua_State* L = luaL_newstate();
60 	scope(success) lua_close(L);
61 	luaL_openlibs(L);
62 
63 	{
64 		int[] arr = [1, 2, 3];
65 		pushValue(L, arr);
66 		assert(lua_istable(L, -1));
67 		lua_setglobal(L, "array");
68 
69 		unittest_lua(L, `
70 			for i, expected in pairs{1, 2, 3} do
71 				local value = array[i]
72 				assert(value == expected,
73 					("bad array index: '%s' = '%s' (expected '%s')"):format(i, value, expected)
74 				)
75 			end
76 		`);
77 	}
78 
79 	{
80 		unittest_lua(L, `array = {"hello", "from", "lua"}`);
81 
82 		lua_getglobal(L, "array");
83 		string[] arr = popValue!(string[])(L);
84 		assert(arr[0] == "hello");
85 		assert(arr[1] == "from");
86 		assert(arr[2] == "lua");
87 	}
88 }