# Integration Luwra does not provide a standalone version of Lua nor does it isolate its features. This means that all functions and classes can operate on [lua_State][lua-state] (or the alias [State][luwra-state]). Doing this allows you to integrate Luwra however you like. # Stack Interaction A fundamental aspect of this is the abstract template [Value][luwra-value]. Every type which can be pushed onto or read from the stack has a specialization of it. Useful implementations are provided out of the box: C++ type | Pushable | Readable | Lua type ---------------------------------------|----------|----------|---------------------------- bool | yes | yes | boolean signed char | yes | yes | number (integer since 5.3) signed short | yes | yes | number (integer since 5.3) signed int | yes | yes | number (integer since 5.3) signed long int | yes | yes | number (integer since 5.3) signed long long int | yes | yes | number (integer since 5.3) unsigned char | yes | yes | number (integer since 5.3) unsigned short | yes | yes | number (integer since 5.3) unsigned int | yes | yes | number (integer since 5.3) unsigned long int | yes | yes | number (integer since 5.3) unsigned long long int | yes | yes | number (integer since 5.3) float | yes | yes | number double | yes | yes | number long double | yes | yes | number const char* | yes | yes | string std::string | yes | yes | string std::nullptr_t | yes | yes | nil std::tuple<T...> | yes | no | *depends on the tuple contents* std::vector<T> | yes | yes | table std::list<T> | yes | yes | table std::map<K, V> | yes | yes | table [lua_CFunction][lua-cfunction] | yes | no | function, table or userdata [NativeFunction][luwra-nativefunction] | yes | yes | function [Table][luwra-table] | yes | yes | table **Note:** Some numeric types have a different size than their matching Lua type - they will be truncated during push or read operations. ## Extending supported types If you are missing a type that cannot be used as a [user type](/user-types), you can add a specialization of [Value][luwra-value]. All you need to do is modify the following snippet for your type `T`. ```c++ namespace luwra { template <> struct Value { static inline T read(State* state, int index) { return /* Return the instance of T that you have read at the given index */; } static inline size_t push(State* state, const T& value) { // Push the given value on top of the stack return /* Return how many values you have pushed onto the stack */; } }; } ``` ## Pushing C++ values When pushing values onto the stack you can either use [Value<T>::push][luwra-value-push] or the more convenient [push][luwra-push]. ```c++ // Push an integer luwra::push(lua, 1338); // Push a number luwra::push(lua, 13.37); // Push a boolean luwra::push(lua, false); // Push a string luwra::push(lua, "Hello World"); // Push a table luwra::push(lua, luwra::MemberMap { {"one", 1}, {1, "one"}, {"nested", luwra::MemberMap { {"more", "fields"} }} }); ``` **Note:** `luwra::MemberMap` is an alias for `std:map`. Its keys and values are constructible using any pushable type. This produces the following stack layout: Absolute Position | Relative Position | Value ------------------|-------------------|------ 1 | -5 | `1338` 2 | -4 | `13.37` 3 | -3 | `false` 4 | -2 | `"Hello World"` 5 | -1 | `{one = 1, [1] = "one", nested = {more = "fields"}}` It is possible to provide a template parameter to `push` to enforce pushing a specific type. In most cases you are probably better off by letting the compiler infer the template parameter. ## Reading Lua values Simple retrieval of Lua values is done using [read<T>][luwra-read]. Consider the stack layout from the previous example. This is how you would retrieve a value from the stack. ```c++ // Retrieve the integer at position 1 int value = luwra::read(lua, 1); // Similiar with a relative index int value = luwra::read(lua, -5); ``` ## Read and type errors What happens when a value mismatches the expected type or cannot be converted to it? Most [Value][luwra-value] specializations use Lua's `luaL_check*` functions to retrieve the values from the stack. This means that no exceptions will be thrown - instead the error handling is delegated to the Lua VM. Have a look at the [error handling documentation][lua-errorhandling] for more information. # Globals In order to conveniently register values in the global namespace, Luwra provides [setGlobal][luwra-setglobal] and [getGlobal][luwra-global]. ```c++ // Register in the global namespace luwra::setGlobal(lua, "almostPi", 3.14); // Retrieve from globals double almostPi = luwra::getGlobal(lua, "almostPi"); ``` [lua-state]: http://www.lua.org/manual/5.3/manual.html#lua_State [lua-cfunction]: http://www.lua.org/manual/5.3/manual.html#lua_CFunction [lua-errorhandling]: http://www.lua.org/manual/5.3/manual.html#4.6 [luwra-state]: /reference/namespaceluwra.html#a2c037b44385367826eb4e931b5b8197d [luwra-value]: /reference/structluwra_1_1Value.html [luwra-nativefunction]: /reference/structluwra_1_1NativeFunction_3_01R_07A_8_8_8_08_4.html [luwra-table]: /reference/structluwra_1_1Table.html [luwra-read]: /reference/namespaceluwra.html#a4fe4e574680cf54a0f8d958740eb90ab [luwra-value-push]: /reference/structluwra_1_1Value.html#aa376d68285606c206562b822e8187384 [luwra-push]: /reference/namespaceluwra.html#ae8e7eab11fc2cf3f258ffd81571066fa [luwra-setglobal]: /reference/namespaceluwra.html#afed27900ff117638937ad92e0217258d [luwra-getglobal]: /reference/namespaceluwra.html#af0a7dbbbdb339227c6ecaaa46422e05b