diff --git a/docs/source/api/table.rst b/docs/source/api/table.rst index b5a94648..32a3ced5 100644 --- a/docs/source/api/table.rst +++ b/docs/source/api/table.rst @@ -150,6 +150,14 @@ Sets a previously created usertype with the specified ``key`` into the table. No Provides `input iterators`_ for a table. This allows tables to work with single-pass, input-only algorithms (like ``std::for_each``). +.. _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 :name: table-for-each diff --git a/docs/source/errors.rst b/docs/source/errors.rst index a8a130c1..c44ebe76 100644 --- a/docs/source/errors.rst +++ b/docs/source/errors.rst @@ -3,7 +3,7 @@ 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 @@ -43,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`.