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 }