types
=====
*nil, lua_primitive type traits, and other fundamentals*

The ``types.hpp`` header contains various fundamentals and utilities of sol.


enumerations
------------

.. code-block:: cpp
	:caption: syntax of a function called by Lua
	:name: call-syntax
	
	enum class call_syntax {
    	dot = 0,
    	colon = 1
	};

This enumeration indicates the syntax a function was called with in a specific scenario. There are two ways to call a function: with ``obj:func_name( ... )`` or ``obj.func_name( ... );`` The first one passes "obj" as the first argument: the second one does not. In the case of usertypes, this is used to determine whether the call to a :doc:`constructor/initializer<usertype>` was called with a ``:`` or a ``.``, and not misalign the arguments.

.. code-block:: cpp
	:caption: status of a Lua function call
	:name: call-status
	
	enum class call_status : int {
	    ok      = LUA_OK,
	    yielded = LUA_YIELD,
	    runtime = LUA_ERRRUN,
	    memory  = LUA_ERRMEM,
	    handler = LUA_ERRERR,
	    gc      = LUA_ERRGCMM
	};

This strongly-typed enumeration contains the errors potentially generated by a call to a :doc:`protected function<protected_function>` or a :doc:`coroutine<coroutine>`.

.. code-block:: cpp
	:caption: status of a Lua thread
	:name: thread-status
	
	enum class thread_status : int {
	    ok  = LUA_OK,
	    yielded = LUA_YIELD,
	    runtime = LUA_ERRRUN,
	    memory  = LUA_ERRMEM,
	    gc      = LUA_ERRGCMM,
	    handler = LUA_ERRERR,
	    dead,
	};

This enumeration contains the status of a thread. The ``thread_status::dead`` state is generated when the thread has nothing on its stack and it is not running anything.

.. code-block:: cpp
	:caption: status of a Lua load operation
	:name: load-status
	
	enum class load_status : int {
	    ok      = LUA_OK,
	    runtime = LUA_ERRSYNTAX,
	    memory  = LUA_ERRMEM,
	    gc      = LUA_ERRGCMM,
	    file    = LUA_ERRFILE,
	};

This enumeration contains the status of a load operation from :ref:`state::load(_file)<state-load-code>`.

.. code-block:: cpp
	:caption: type enumeration
	:name: type-enum

	enum class type : int {
	    none          = LUA_TNONE,
	    lua_nil       = LUA_TNIL,
	    string        = LUA_TSTRING,
	    number        = LUA_TNUMBER,
	    thread        = LUA_TTHREAD,
	    boolean       = LUA_TBOOLEAN,
	    function      = LUA_TFUNCTION,
	    userdata      = LUA_TUSERDATA,
	    lightuserdata = LUA_TLIGHTUSERDATA,
	    table         = LUA_TTABLE,
	    poly          = none   | nil     | string   | number   | thread          |
	                    table  | boolean | function | userdata | lightuserdata,
	    // if not in Objective C land...
	    nil           = LUA_TNIL
	};

The base types that Lua natively communicates in and understands. Note that "poly" isn't really a true type, it's just a symbol used in sol for something whose type hasn't been checked (and you should almost never see it).


type traits
-----------

.. code-block:: cpp
	:caption: lua_type_of trait
	:name: lua-type-of

	template <typename T>
	struct lua_type_of;

This type trait maps a C++ type to a :ref:`type enumeration<type-enum>` value. The default value is ``type::userdata``.

.. code-block:: cpp
	:caption: primitive checking traits
	:name: is-primitive
	
	template <typename T>
	struct is_lua_primitive;

	template <typename T>
	struct is_proxy_primitive;


This trait is used by :doc:`proxy<proxy>` to know which types should be returned as references to internal Lua memory (e.g., ``userdata`` types) and which ones to return as values (strings, numbers, :doc:`references<reference>`). ``std::reference_wrapper``, ``std::tuple<...>`` are returned as values, but their contents can be references. The default value is false.

special types
-------------

.. code-block:: cpp
	:caption: nil
	:name: nil

	struct lua_nil_t {};
	constexpr lua_nil_t lua_nil {};
	bool operator==(lua_nil_t, lua_nil_t);
	bool operator!=(lua_nil_t, lua_nil_t);

	// if not in Objective-C land
	using nil_t = lua_nil_t;
	constexpr nil_t nil {};
	

``nil`` is a constant used to signify Lua's ``nil``, which is a type and object that something does not exist. It is comparable to itself, :doc:`sol::object<object>` and :doc:`proxy values<proxy>`.


.. code-block:: cpp
	:caption: non_null

	template <typename T>
	struct non_null {};

A tag type that, when used with :doc:`stack::get\<non_null\<T*>><stack>`, does not perform a ``nil`` check when attempting to retrieve the userdata pointer.


.. code-block:: cpp
	:caption: type list
	:name: type-list

	template <typename... Args>
	struct types;

A type list that, unlike ``std::tuple<Args...>``, does not actually contain anything. Used to indicate types and groups of types all over sol.


functions
---------

.. code-block:: cpp
	:caption: type_of

	template<typename T>
	type type_of();

	type type_of(lua_State* L, int index);


These functions get the type of a C++ type ``T``; or the type at the specified index on the Lua stack.

.. code-block:: cpp
	:caption: type checking convenience functions

	int type_panic_string(lua_State* L, int index, type expected, type actual, const std::string& message);

	int type_panic_c_str(lua_State* L, int index, type expected, type actual, const char* message);

	int no_panic(lua_State*, int, type, type, const char*) noexcept;

	void type_error(lua_State* L, int expected, int actual);

	void type_error(lua_State* L, type expected, type actual);

	void type_assert(lua_State* L, int index, type expected, type actual);

	void type_assert(lua_State* L, int index, type expected);

The purpose of these functions is to assert / throw / crash / error (or do nothing, as is the case with ``no_panic``). They're mostly used internally in the framework, but they're provided here if you should need them.

.. code-block:: cpp
	:caption: type name retrieval

	std::string type_name(lua_State*L, type t);

Gets the Lua-specified name of the :ref:`type<type-enum>`.

structs
-------

.. code-block:: cpp

	struct userdata_value {
		void* value;
	};

	struct light_userdata_value {
		void* value;
	};

	struct upvalue_index {
    		int index;
	};

	struct raw_index {
    		int index;
	};

	struct absolute_index {
    		int index;
	};

	struct ref_index {
    		int index;
	};


Types that differentiate between the two kinds of ``void*`` Lua hands back from its API: full userdata and light userdata, as well as a type that modifies the index passed to ``get`` to refer to `up values`_ These types can be used to trigger different underlying API calls to Lua when working with :doc:`stack<stack>` namespace and the ``push``/``get``/``pop``/``check`` functions.

The ``raw_index`` type is used to tell a :doc:`sol::reference<reference>` type or similar that the desired index -- negative or not -- should be passed through directly to the API.

The ``absolute_index`` type is used to tell a :doc:`sol::reference<reference>` type or similar that the desired index -- negative or not -- should be passed through Lua's `lua_absindex`_ function first to adjust where it is, and then given to the underlying API.

The ``ref_index`` type is used to tell a :doc:`sol::reference<reference>` type or similar that it should look into the Lua C Registry for its type.

.. _up values: http://www.Lua.org/manual/5.3/manual.html#4.4
.. _lua_absindex: https://www.lua.org/manual/5.3/manual.html#lua_absindex
