summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/sol2/docs/source
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/sol2/docs/source')
-rw-r--r--3rdparty/sol2/docs/source/api/api-top.rst1
-rw-r--r--3rdparty/sol2/docs/source/api/as_args.rst50
-rw-r--r--3rdparty/sol2/docs/source/api/reference.rst5
-rw-r--r--3rdparty/sol2/docs/source/api/resolve.rst4
-rw-r--r--3rdparty/sol2/docs/source/api/state.rst21
-rw-r--r--3rdparty/sol2/docs/source/api/table.rst10
-rw-r--r--3rdparty/sol2/docs/source/api/thread.rst30
-rw-r--r--3rdparty/sol2/docs/source/api/usertype.rst3
-rw-r--r--3rdparty/sol2/docs/source/compilation.rst25
-rw-r--r--3rdparty/sol2/docs/source/conf.py2
-rw-r--r--3rdparty/sol2/docs/source/errors.rst19
-rw-r--r--3rdparty/sol2/docs/source/index.rst1
-rw-r--r--3rdparty/sol2/docs/source/tutorial/all-the-things.rst26
-rw-r--r--3rdparty/sol2/docs/source/tutorial/variables.rst6
14 files changed, 178 insertions, 25 deletions
diff --git a/3rdparty/sol2/docs/source/api/api-top.rst b/3rdparty/sol2/docs/source/api/api-top.rst
index 4dac922becf..ebeabf3ee3b 100644
--- a/3rdparty/sol2/docs/source/api/api-top.rst
+++ b/3rdparty/sol2/docs/source/api/api-top.rst
@@ -32,6 +32,7 @@ Browse the various function and classes :doc:`Sol<../index>` utilizes to make yo
optional
this_state
variadic_args
+ as_args
overload
property
var
diff --git a/3rdparty/sol2/docs/source/api/as_args.rst b/3rdparty/sol2/docs/source/api/as_args.rst
new file mode 100644
index 00000000000..8e323fdfaba
--- /dev/null
+++ b/3rdparty/sol2/docs/source/api/as_args.rst
@@ -0,0 +1,50 @@
+as_args
+=======
+turn an iterable argument into multiple arguments
+-------------------------------------------------
+
+.. code-block:: cpp
+
+ template <typename T>
+ as_args_t { ... };
+
+ template <typename T>
+ as_args_t<T> as_args( T&& );
+
+
+``sol::as_args`` is a function that that takes an iterable and turns it into multiple arguments to a function call. It forwards its arguments, and is meant to be used as shown below:
+
+.. code-block:: cpp
+ :caption: as_args.c++
+
+ #define SOL_CHECK_ARGUMENTS
+ #include <sol.hpp>
+
+ #include <vector>
+ #include <set>
+
+ int main(int argc, const char* argv[]) {
+
+ sol::state lua;
+ lua.open_libraries();
+
+ lua.script("function f (a, b, c, d) print(a, b, c, d) end");
+
+ sol::function f = lua["f"];
+
+ std::vector<int> v2{ 3, 4 };
+ f(1, 2, sol::as_args(v2));
+
+ std::set<int> v4{ 3, 1, 2, 4 };
+ f(sol::as_args(v4));
+
+ int v3[] = { 2, 3, 4 };
+ f(1, sol::as_args(v3));
+
+ return 0;
+ }
+
+
+It is basically implemented as a `one-way customization point`_. For more information about customization points, see the :doc:`tutorial on how to customize Sol to work with your types<../tutorial/customization>`.
+
+.. _one-way customization point: https://github.com/ThePhD/sol2/blob/develop/sol/as_args.hpp
diff --git a/3rdparty/sol2/docs/source/api/reference.rst b/3rdparty/sol2/docs/source/api/reference.rst
index 37886dc2300..57869de7db0 100644
--- a/3rdparty/sol2/docs/source/api/reference.rst
+++ b/3rdparty/sol2/docs/source/api/reference.rst
@@ -20,8 +20,11 @@ members
:caption: constructor: reference
reference(lua_State* L, int index = -1);
+ reference(lua_State* L, ref_index index);
+ template <typename Object>
+ reference(Object&& o);
-Creates a reference from the Lua stack at the specified index, saving it into the metatable registry. This constructor is exposed on all types that derive from ``sol::reference``.
+The first constructor creates a reference from the Lua stack at the specified index, saving it into the metatable registry. The second attemtps to register something that already exists in the registry. The third attempts to reference a pre-existing object and create a reference to it. These constructors are exposed on all types that derive from ``sol::reference``, meaning that you can grab tables, functions, and coroutines from the registry, stack, or from other objects easily.
.. code-block:: cpp
:caption: function: push referred-to element from the stack
diff --git a/3rdparty/sol2/docs/source/api/resolve.rst b/3rdparty/sol2/docs/source/api/resolve.rst
index 193e2fae80f..b1ceffd0134 100644
--- a/3rdparty/sol2/docs/source/api/resolve.rst
+++ b/3rdparty/sol2/docs/source/api/resolve.rst
@@ -19,6 +19,7 @@ utility to pick overloaded C++ function calls
int overloaded(int x, int y, int z);
struct thing {
+ int overloaded() const;
int overloaded(int x);
int overloaded(int x, int y);
int overloaded(int x, int y, int z);
@@ -33,8 +34,9 @@ You can disambiguate them using ``resolve``:
auto two_argument_func = resolve<int(int, int)>( overloaded );
auto three_argument_func = resolve<int(int, int, int)>( overloaded );
auto member_three_argument_func = resolve<int(int, int, int)>( &thing::overloaded );
+ auto member_zero_argument_const_func = resolve<int() const>( &thing::overloaded );
-This resolution becomes useful when setting functions on a :doc:`table<table>` or :doc:`state_view<state>`:
+It is *important* to note that ``const`` is placed at the end for when you desire const overloads. You will get compiler errors if you are not specific and do not properly disambiguate for const member functions. This resolution also becomes useful when setting functions on a :doc:`table<table>` or :doc:`state_view<state>`:
.. code-block:: cpp
:linenos:
diff --git a/3rdparty/sol2/docs/source/api/state.rst b/3rdparty/sol2/docs/source/api/state.rst
index a0838fbf110..b1b17a3cc67 100644
--- a/3rdparty/sol2/docs/source/api/state.rst
+++ b/3rdparty/sol2/docs/source/api/state.rst
@@ -102,13 +102,32 @@ Get either the global table or the Lua registry as a :doc:`sol::table<table>`, w
.. code-block:: cpp
- :caption: function: Lua set_panic
+ :caption: function: set_panic
:name: set-panic
void set_panic(lua_CFunction panic);
Overrides the panic function Lua calls when something unrecoverable or unexpected happens in the Lua VM. Must be a function of the that matches the ``int(lua_State*)`` function signature.
+
+.. code-block:: cpp
+ :caption: function: memory_used
+ :name: memory-used
+
+ std::size_t memory_used() const;
+
+Returns the amount of memory used *in bytes* by the Lua State.
+
+
+.. code-block:: cpp
+ :caption: function: collect_garbage
+ :name: collect-garbage
+
+ void collect_garbage();
+
+Attempts to run the garbage collector. Note that this is subject to the same rules as the Lua API's collect_garbage function: memory may or may not be freed, depending on dangling references or other things, so make sure you don't have tables or other stack-referencing items currently alive or referenced that you want to be collected.
+
+
.. code-block:: cpp
:caption: function: make a table
diff --git a/3rdparty/sol2/docs/source/api/table.rst b/3rdparty/sol2/docs/source/api/table.rst
index b5a946487de..25197b126c7 100644
--- a/3rdparty/sol2/docs/source/api/table.rst
+++ b/3rdparty/sol2/docs/source/api/table.rst
@@ -148,7 +148,15 @@ Sets a previously created usertype with the specified ``key`` into the table. No
table_iterator cbegin() const;
table_iterator cend() const;
-Provides `input iterators`_ for a table. This allows tables to work with single-pass, input-only algorithms (like ``std::for_each``).
+Provides (what can barely be called) `input iterators`_ for a table. This allows tables to work with single-pass, input-only algorithms (like ``std::for_each``). Note that manually getting an iterator from ``.begin()`` without a ``.end()`` or using postfix incrementation (``++mytable.begin()``) will lead to poor results. The Lua stack is manipulated by an iterator and thusly not performing the full iteration once you start is liable to ruin either the next iteration or break other things subtly. Use a C++11 ranged for loop, ``std::for_each``, or other algorithims which pass over the entire collection at least once and let the iterators fall out of scope.
+
+.. _iteration_note:
+.. warning::
+
+ The iterators you use to walk through a ``sol::table`` are NOT guaranteed to iterate in numeric order, or ANY kind of order. They may iterate backwards, forwards, in the style of cuckoo-hashing, by accumulating a visited list while calling ``rand()`` to find the next target, or some other crazy scheme. Now, no implementation would be crazy, but it is behavior specifically left undefined because there are many ways that your Lua package can implement the table type.
+
+ Iteration order is NOT something you should rely on. If you want to figure out the length of a table, call the length operation (``int count = mytable.size();`` using the sol API) and then iterate from ``1`` to ``count`` (inclusive of the value of count, because Lua expects iteration to work in the range of ``[1, count]``). This will save you some headaches in the future when the implementation decides not to iterate in numeric order.
+
.. code-block:: cpp
:caption: function: iteration with a function
diff --git a/3rdparty/sol2/docs/source/api/thread.rst b/3rdparty/sol2/docs/source/api/thread.rst
index 1a713f973b4..b7349d97efb 100644
--- a/3rdparty/sol2/docs/source/api/thread.rst
+++ b/3rdparty/sol2/docs/source/api/thread.rst
@@ -9,15 +9,36 @@ a separate state that can contain and run functions
``sol::thread`` is a separate runnable part of the Lua VM that can be used to execute work separately from the main thread, such as with :doc:`coroutines<coroutine>`. To take a table or a coroutine and run it specifically on the ``sol::thread`` you either pulled out of lua or created, just get that function through the :ref:`state of the thread<thread_state>`
+.. note::
+
+ A CPU thread is not always equivalent to a new thread in Lua: ``std::this_thread::get_id()`` can be the same for 2 callbacks that have 2 distinct Lua threads. In order to know which thread a callback was called in, hook into :doc:`sol::this_state<this_state>` from your Lua callback and then construct a ``sol::thread``, passing in the ``sol::this_state`` for both the first and last arguments. Then examine the results of the status and ``is_...`` calls below.
+
+free function
+-------------
+
+.. code-block:: cpp
+ :caption: function: main_thread
+
+ main_thread(lua_State* current, lua_State* backup_if_bad_platform = nullptr);
+
+The function ``sol::main_thread( ... )`` retrieves the main thread of the application on Lua 5.2 and above *only*. It is designed for code that needs to be multithreading-aware (e.g., uses multiple :doc:`threads<thread>` and :doc:`coroutines<coroutine>`).
+
+.. warning::
+
+ This code function will be present in Lua 5.1/LuaJIT, but only have proper behavior when given a single argument on Lua 5.2 and beyond. Lua 5.1 does not support retrieving the main thread from its registry, and therefore it is entirely suggested if you are writing cross-platform Lua code that you must store the main thread of your application in some global storage accessible somewhere. Then, pass this item into the ``sol::main_thread( possibly_thread_state, my_actual_main_state )`` and it will select that ``my_actual_main_state`` every time. If you are not going to use Lua 5.1 / LuaJIT, you can ignore the last parameter.
+
+
members
-------
.. code-block:: cpp
:caption: constructor: thread
+ thread(stack_reference r);
thread(lua_State* L, int index = -1);
+ thread(lua_State* L, lua_State* actual_thread);
-Takes a thread from the Lua stack at the specified index and allows a person to use all of the abstractions therein.
+Takes a thread from the Lua stack at the specified index and allows a person to use all of the abstractions therein. It can also take an actual thread state to make a thread from that as well.
.. code-block:: cpp
:caption: function: view into thread_state()'s state
@@ -43,6 +64,13 @@ This function retrieves the ``lua_State*`` that represents the thread.
Retrieves the :doc:`thread status<types>` that describes the current state of the thread.
.. code-block:: cpp
+ :caption: main thread status
+
+ bool is_main_thread () const;
+
+Checks to see if the thread is the main Lua thread.
+
+.. code-block:: cpp
:caption: function: thread creation
:name: thread-create
diff --git a/3rdparty/sol2/docs/source/api/usertype.rst b/3rdparty/sol2/docs/source/api/usertype.rst
index 2fa73a320a2..bd941c527dc 100644
--- a/3rdparty/sol2/docs/source/api/usertype.rst
+++ b/3rdparty/sol2/docs/source/api/usertype.rst
@@ -170,9 +170,10 @@ If you don't specify any constructor options at all and the type is `default_con
* ``{anything}, {some_factory_function}``
- Essentially binds whatever the function is to name ``{anything}``
- When used WITH the ``sol::no_constructor`` option above (e.g. ``"new", sol::no_constructor`` and after that having ``"create", &my_creation_func``), one can remove typical constructor avenues and then only provide specific factory functions. Note that this combination is similar to using the ``sol::factories`` method mentioned earlier in this list. To control the destructor as well, see further below
-* ``sol::call_constructor, {valid function / constructor / initializer / factory}``
+* ``sol::call_constructor, {valid constructor / initializer / factory}``
- The purpose of this is to enable the syntax ``local v = my_class( 24 )`` and have that call a constructor; it has no other purpose
- This is compatible with luabind, kaguya and other Lua library syntaxes and looks similar to C++ syntax, but the general consensus in Programming with Lua and other places is to use a function named ``new``
+ - Note that with the ``sol::call_constructor`` key, a construct type above must be specified. A free function without it will pass in the metatable describing this object as the first argument without that distinction, which can cause strange runtime errors.
usertype destructor options
+++++++++++++++++++++++++++
diff --git a/3rdparty/sol2/docs/source/compilation.rst b/3rdparty/sol2/docs/source/compilation.rst
new file mode 100644
index 00000000000..22b894e7f8d
--- /dev/null
+++ b/3rdparty/sol2/docs/source/compilation.rst
@@ -0,0 +1,25 @@
+binary size, compile time
+=========================
+getting good final product out of sol2
+--------------------------------------
+
+For individiauls who use :doc:`usertypes<api/usertype>` a lot, they can find their compilation times increase. This is due to C++11 and C++14 not having very good facilities for handling template parameters and variadic template parameters. There are a few things in cutting-edge C++17 and C++Next that sol can use, but the problem is many people cannot work with the latest and greatest: therefore, we have to use older techniques that result in a fair amount of redundant function specializations that can be subject to the pickiness of the compiler's inlining and other such techniques.
+
+what to do
+----------
+
+Here are some notes on achieving better compile-times without sacrificing too much performance:
+
+* When you bind lots of usertypes, put them all in a *single* translation unit (one C++ file) so that it is not recompiled multiple times over, only to be discarded later by the linker.
+ - Remember that the usertype binding ends up being serialized into the Lua state, so you never need them to appear in a header and cause that same compilation overhead for every compiled unit in your project.
+* For extremely large usertypes, consider using :doc:`simple_usertype<api/simple_usertype>`.
+ - It performs much more work at runtime rather than compile-time, and should still give comparative performance (but it loses out in some cases for variable bindings or when you bind all functions to a usertype).
+* If you are developing a shared library, restrict your overall surface area by specifically and explicitly marking functions as visible and exported and leaving everything else as hidden or invisible by default
+
+
+next steps
+----------
+
+The next step for Sol from a developer standpoint is to formally make the library a C++17 one. This would mean using Fold Expressions and several other things which will reduce compilation time drastically. Unfortunately, that means also boosting compiler requirements. While most wouldn't care, others are very slow to upgrade: finding the balance is difficult, and often we have to opt for backwards compatibility and fixes for bad / older compilers (of which there are many in the codebase already).
+
+Hopefully, as things progress, we move things forward.
diff --git a/3rdparty/sol2/docs/source/conf.py b/3rdparty/sol2/docs/source/conf.py
index e69c2f79f84..02d00f92ef4 100644
--- a/3rdparty/sol2/docs/source/conf.py
+++ b/3rdparty/sol2/docs/source/conf.py
@@ -61,7 +61,7 @@ author = 'ThePhD'
# The short X.Y version.
version = '2.15'
# The full version, including alpha/beta/rc tags.
-release = '2.15.1'
+release = '2.15.5'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
diff --git a/3rdparty/sol2/docs/source/errors.rst b/3rdparty/sol2/docs/source/errors.rst
index 5088c09e48e..c44ebe76988 100644
--- a/3rdparty/sol2/docs/source/errors.rst
+++ b/3rdparty/sol2/docs/source/errors.rst
@@ -3,7 +3,16 @@ errors
how to handle exceptions or other errors
----------------------------------------
-Here is some advice and some tricks to use when dealing with thrown exceptions, error conditions and the like in Sol.
+Here is some advice and some tricks for common errors about iteration, compile time / linker errors, and other pitfalls, especially when dealing with thrown exceptions, error conditions and the like in Sol.
+
+
+Linker Errors
+-------------
+
+There are lots of reasons for compiler linker errors. A common one is not knowing that you've compiled the Lua library as C++: when building with C++, it is important to note that every typical (static or dynamic) library expects the C calling convention to be used and that Sol includes the code using ``extern 'C'`` where applicable.
+
+However, when the target Lua library is compiled with C++, one must change the calling convention and name mangling scheme by getting rid of the ``extern 'C'`` block. This can be achieved by adding ``#define SOL_USING_CXX_LUA`` before including sol2, or by adding it to your compilation's command line.
+
Catch and CRASH!
----------------
@@ -34,8 +43,14 @@ Sometimes, some scripts load poorly. Even if you protect the function call, the
Raw Functions
-------------
-When you push a function into Lua using Sol using any methods and that function exactly matches the signature ``int( lua_State* );``, it will be treated as a *raw C function*. This means that the usual exception trampoline Sol wraps your other function calls in will not be present. You will be responsible for catching exceptions and handling them before they explode into the C API (and potentially destroy your code). Sol in all other cases adds an exception-handling trampoline that turns exceptions into Lua errors that can be caught by the above-mentioned protected functions and accessors.
+When you push a function into Lua using Sol using any methods and that function exactly matches the signature ``int( lua_State* );`` (and is a free function (e.g., not a member function pointer)), it will be treated as a *raw C function*. This means that the usual exception trampoline Sol wraps your other function calls in will not be present. You will be responsible for catching exceptions and handling them before they explode into the C API (and potentially destroy your code). Sol in all other cases adds an exception-handling trampoline that turns exceptions into Lua errors that can be caught by the above-mentioned protected functions and accessors.
.. warning::
Do NOT assume that building Lua as C++ will allow you to throw directly from a raw function. If an exception is raised and it bubbles into the Lua framework, even if you compile as C++, Lua does not recognize exceptions other than the ones that it uses with ``lua_error``. In other words, it will return some completely bogus result, potentially leave your Lua stack thrashed, and the rest of your VM *can* be in a semi-trashed state. Please avoid this!
+
+
+Iteration
+---------
+
+Tables may have other junk on them that makes iterating through their numeric part difficult when using a bland ``for-each`` loop, or when calling sol's ``for_each`` function. Use a numeric look to iterate through a table. Iteration does not iterate in any defined order also: see :ref:`this note in the table documentation for more explanation<iteration_note>`.
diff --git a/3rdparty/sol2/docs/source/index.rst b/3rdparty/sol2/docs/source/index.rst
index ca5233398c7..77fb8fdf9b6 100644
--- a/3rdparty/sol2/docs/source/index.rst
+++ b/3rdparty/sol2/docs/source/index.rst
@@ -33,6 +33,7 @@ get going:
tutorial/all-the-things
tutorial/tutorial-top
errors
+ compilation
features
usertypes
traits
diff --git a/3rdparty/sol2/docs/source/tutorial/all-the-things.rst b/3rdparty/sol2/docs/source/tutorial/all-the-things.rst
index 3695ac77fe2..3b764b8d2e9 100644
--- a/3rdparty/sol2/docs/source/tutorial/all-the-things.rst
+++ b/3rdparty/sol2/docs/source/tutorial/all-the-things.rst
@@ -133,7 +133,7 @@ Retrieve these variables using this syntax:
std::string important_string = lua["important_string"];
// dig into a table
- int value = lua["value"]["value"];
+ int value = lua["some_table"]["value"];
// get a function
sol::function a_function = lua["a_function"];
@@ -158,7 +158,7 @@ Retrieve Lua types using ``object`` and other ``sol::`` types.
sol::object function_obj = lua[ "a_function" ];
// sol::type::function
sol::type t2 = function_obj.get_type();
- bool is_it_really = function_obj.is<std::function<int()>(); // true
+ bool is_it_really = function_obj.is<std::function<int()>>(); // true
// will not contain data
sol::optional<int> check_for_me = lua["a_function"];
@@ -172,12 +172,11 @@ You can erase things by setting it to ``nullptr`` or ``sol::nil``.
lua.script("exists = 250");
- int first_try = lua.get_or<int>( 322 );
+ int first_try = lua.get_or( "exists", 322 );
// first_try == 250
lua.set("exists", sol::nil);
-
- int second_try = lua.get_or<int>( 322 );
+ int second_try = lua.get_or( "exists", 322 );
// second_try == 322
@@ -224,12 +223,12 @@ If you're going deep, be safe:
sol::optional<int> will_not_error = lua["abc"]["DOESNOTEXIST"]["ghi"];
// will_not_error == sol::nullopt
- int will_not_error2 = lua["abc"]["def"]["ghi"]["jklm"].get_or<int>(25);
+ int also_will_not_error = lua["abc"]["def"]["ghi"]["jklm"].get_or(25);
// is 25
// if you don't go safe,
// will throw (or do at_panic if no exceptions)
- int aaaahhh = lua["abc"]["hope_u_liek_crash"];
+ int aaaahhh = lua["boom"]["the_dynamite"];
make tables
@@ -423,7 +422,8 @@ multiple returns from lua
std::tuple<int, int, int> result;
result = lua["f"](100, 200, 300);
// result == { 100, 200, 300 }
- int a, int b;
+ int a;
+ int b;
std::string c;
sol::tie( a, b, c ) = lua["f"](100, 200, "bark");
// a == 100
@@ -447,7 +447,7 @@ multiple returns to lua
// result == { 100, 200, 300 }
std::tuple<int, int, std::string> result2;
- result2 = lua["f"](100, 200, "BARK BARK BARK!")
+ result2 = lua["f"](100, 200, "BARK BARK BARK!");
// result2 == { 100, 200, "BARK BARK BARK!" }
int a, int b;
@@ -476,7 +476,7 @@ Is set as a :doc:`userdata + usertype<../api/usertype>`.
struct Doge {
int tailwag = 50;
- }
+ };
Doge dog{};
@@ -504,7 +504,7 @@ Is set as a :doc:`userdata + usertype<../api/usertype>`.
struct Doge {
int tailwag = 50;
- }
+ };
sol::state lua;
lua.open_libraries(sol::lib::base);
@@ -528,7 +528,7 @@ Get userdata in the same way as everything else:
struct Doge {
int tailwag = 50;
- }
+ };
sol::state lua;
lua.open_libraries(sol::lib::base);
@@ -543,7 +543,7 @@ Note that you can change the data of usertype variables and it will affect thing
struct Doge {
int tailwag = 50;
- }
+ };
sol::state lua;
lua.open_libraries(sol::lib::base);
diff --git a/3rdparty/sol2/docs/source/tutorial/variables.rst b/3rdparty/sol2/docs/source/tutorial/variables.rst
index 20105bf8003..a911fcefdb4 100644
--- a/3rdparty/sol2/docs/source/tutorial/variables.rst
+++ b/3rdparty/sol2/docs/source/tutorial/variables.rst
@@ -60,7 +60,7 @@ You can interact with the variables like this:
return 0;
}
-From this example, you can see that there's many ways to pull out the varaibles you want. You can get For example, to determine if a nested variable exists or not, you can use ``auto`` to capture the value of a ``table[key]`` lookup, and then use the ``.valid()`` method:
+From this example, you can see that there's many ways to pull out the varaibles you want. For example, to determine if a nested variable exists or not, you can use ``auto`` to capture the value of a ``table[key]`` lookup, and then use the ``.valid()`` method:
.. code-block:: cpp
:caption: safe lookup
@@ -83,7 +83,7 @@ This comes in handy when you want to check if a nested variable exists. You can
// Branch not taken: value is not an integer
}
- sol::optoinal<bool> is_a_boolean = lua["config"]["fullscreen"];
+ sol::optional<bool> is_a_boolean = lua["config"]["fullscreen"];
if (is_a_boolean) {
// Branch taken: the value is a boolean
}
@@ -199,4 +199,4 @@ Finally, it's possible to erase a reference/variable by setting it to ``nil``, u
// y will not have a value
}
-It's easy to see that there's a lot of options to do what you want here. But, these are just traditional numbers and strings. What if we want more power, more capabilities than what these limited types can offer us? Let's throw some :doc:`functions in there<functions>` :doc:`C++ classes into the mix<cxx-in-lua>`! \ No newline at end of file
+It's easy to see that there's a lot of options to do what you want here. But, these are just traditional numbers and strings. What if we want more power, more capabilities than what these limited types can offer us? Let's throw some :doc:`functions in there<functions>` :doc:`C++ classes into the mix<cxx-in-lua>`!