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 // TODO: do the immutable/const initialization *properly* 26 T getArray(T)(lua_State* L, int idx) if (isArray!T) 27 { 28 alias ElemType = ElementType!T; 29 auto len = lua_objlen(L, idx); 30 31 static if(isStaticArray!T) 32 { 33 if(len != T.length) 34 luaL_error(L, "Incorrect number of array elements: %d, expected: %d", len, T.length); 35 36 Unqual!ElemType[T.length] arr; 37 } 38 else 39 auto arr = new Unqual!ElemType[len]; 40 41 foreach(i; 0 .. len) 42 { 43 lua_pushinteger(L, i + 1); 44 lua_gettable(L, idx < 0? idx - 1 : idx); 45 arr[i] = popValue!ElemType(L); 46 } 47 48 return cast(T)arr; 49 } 50 51 void fillStaticArray(T)(lua_State* L, ref T arr) if(isStaticArray!T) 52 { 53 foreach(i, ref elem; arr) 54 { 55 elem = getValue!(typeof(elem))(L, cast(int)(-arr.length + i)); 56 } 57 } 58 59 void pushStaticArray(T)(lua_State* L, ref T arr) if(isStaticArray!T) 60 { 61 foreach(elem; arr) 62 pushValue(L, elem); 63 } 64 65 version(unittest) import luad.testing; 66 67 unittest 68 { 69 lua_State* L = luaL_newstate(); 70 scope(success) lua_close(L); 71 luaL_openlibs(L); 72 73 { 74 int[] arr = [1, 2, 3]; 75 pushValue(L, arr); 76 assert(lua_istable(L, -1)); 77 lua_setglobal(L, "array"); 78 79 unittest_lua(L, ` 80 for i, expected in pairs{1, 2, 3} do 81 local value = array[i] 82 assert(value == expected, 83 ("bad array index: '%s' = '%s' (expected '%s')"):format(i, value, expected) 84 ) 85 end 86 `); 87 } 88 89 { 90 unittest_lua(L, `array = {"hello", "from", "lua"}`); 91 92 lua_getglobal(L, "array"); 93 string[] arr = popValue!(string[])(L); 94 assert(arr[0] == "hello"); 95 assert(arr[1] == "from"); 96 assert(arr[2] == "lua"); 97 } 98 }