add handle for potentially overloaded size() definitions (pray it works with noexcept anyhow).

This commit is contained in:
ThePhD 2018-02-22 12:26:46 -05:00
parent 6c6c89132b
commit 8d62fbaf5d
8 changed files with 53 additions and 8 deletions

View File

@ -208,6 +208,8 @@ If you don't specify anything at all and the type is `destructible`_, then a des
You MUST specify ``sol::destructor`` around your destruction function, otherwise it will be ignored.
.. _automagical-registration:
usertype automatic meta functions
+++++++++++++++++++++++++++++++++
@ -380,6 +382,21 @@ Then, to register the base classes explicitly:
Specify all base class member variables and member functions to avoid current implementation caveats regarding automatic base member lookup. Sol currently attempts to link base class methods and variables with their derived classes with an undocumented, unsupported feature, provided you specify ``sol::bases<...>``. Unfortunately, this can come at the cost of performance, depending on how "far" the base is from the derived class in the bases lookup list. If you do not want to suffer the performance degradation while we iron out the kinks in the implementation (and want it to stay performant forever), please specify all the base methods on the derived class in the method listing you write. In the future, we hope that with reflection we will not have to worry about this.
.. _automagical:
automagical usertypes
---------------------
Usertypes automatically register special functions, whether or not they're bound using `new(_simple)_usertype`. You can turn this off by specializing the ``sol::is_automagical<T>`` template trait:
.. code-block:: cpp
struct my_strange_nonconfirming_type { /* ... */ };
namespace sol {
template <>
struct is_automagical<my_strange_nonconforming_type> : std::false_type {};
}
inheritance + overloading
-------------------------

View File

@ -0,0 +1,10 @@
yielding
========
*telling a C++ function to yield its results into Lua*
.. code-block:: cpp
template <typename F>
yield_wrapper<F> yielding( F&& f )
``sol::yielding`` is useful for calling C++ functions which need to yield into a Lua coroutine. It is a wrapper around a single argument which is expected to be bound as a function. You can pass it anywhere a regular function can be bound, **except for in usertype definitions**.

View File

@ -3,6 +3,11 @@ codecvt + std::(w/u16/u32)string support
because this is surprisingly hard using standard C++
----------------------------------------------------
.. warning::
This header is no longer used and sol2 now converts utf8, utf16, and utf32 with internal routines. If you have a problem with the transcoding, please file an issue report.
Individuals using Visual Studio 2015, or on Windows with the VC++ and MinGW compilers (possibly Clang++ on Windows as well) have ``<codecvt>`` headers, and thusly Sol will attempt to include it. Individuals on GCC 4.9.x, Clang 3.5.x, Clang 3.6.x do not seem to have ``<codecvt>`` shipped with the standard library that comes with installation of these compilers. If you want ``std::wstring``, ``std::u16string``, ``std::u32string`` automatic handling then you need to make sure you have those headers and then define ``SOL_CODECVT_SUPPORT`` on unsupported compilers.
.. _codecvt-deprecation:

View File

@ -61,7 +61,7 @@ author = 'ThePhD'
# The short X.Y version.
version = '2.19'
# The full version, including alpha/beta/rc tags.
release = '2.19.0'
release = '2.19.4'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.

View File

@ -18,6 +18,7 @@ Compiler Errors / Warnings
A myriad of compiler errors can occur when something goes wrong. Here is some basic advice about working with these types:
* If there are a myriad of errors relating to ``std::index_sequence``, type traits, and other ``std::`` members, it is likely you have not turned on your C++14 switch for your compiler. Visual Studio 2015 turns these on by default, but g++ and clang++ do not have them as defaults and you should pass the flag ``--std=c++1y`` or ``--std=c++14``, or similar for your compiler.
* If you are pushing a non-primitive type into Lua, you may get strange errors about initializer lists or being unable to initializer a ``luaL_Reg``. This may be due to :ref:`automatic function and operator registration<automagical-registration>`. :ref:`Disabling it<automagical>` may help.
* Sometimes, a generated usertype can be very long if you are binding a lot of member functions. You may end up with a myriad of warnings about debug symbols being cut off or about ``__LINE_VAR`` exceeding maximum length. You can silence these warnings safely for some compilers.
* Template depth errors may also be a problem on earlier versions of clang++ and g++. Use ``-ftemplate-depth`` compiler flag and specify really high number (something like 2048 or even double that amount) to let the compiler work freely. Also consider potentially using :doc:`simple usertypes<api/simple_usertype>` to save compilation speed.
* When using usertype templates extensively, MSVC may invoke `compiler error C1128 <https://msdn.microsoft.com/en-us/library/8578y171.aspx>`_ , which is solved by using the `/bigobj compilation flag <https://msdn.microsoft.com/en-us/library/ms173499.aspx>`_.
@ -83,6 +84,8 @@ Destructors and Safety
Another issue is that Lua is a C API. It uses ``setjmp`` and ``longjmp`` to jump out of code when an error occurs. This means it will ignore destructors in your code if you use the library or the underlying Lua VM improperly. To solve this issue, build Lua as C++. When a Lua VM error occurs and ``lua_error`` is triggered, it raises it as an exception which will provoke proper unwinding semantics.
Building Lua as C++ gets around this issue, and allows lua-thrown errors to properly stack unwind.
Protected Functions and Access
------------------------------

View File

@ -1231,6 +1231,9 @@ namespace sol {
template <typename T>
struct is_environment : std::integral_constant<bool, is_userdata<T>::value || is_table<T>::value> {};
template <typename T>
struct is_automagical : std::true_type {};
template <typename T>
inline type type_of() {
return lua_type_of<meta::unqualified_t<T>>::value;

View File

@ -151,8 +151,10 @@ namespace sol {
template <typename T, typename Regs, meta::enable<meta::has_size<T>> = meta::enabler>
inline void make_length_op(Regs& l, int& index) {
typedef decltype(std::declval<T>().size()) R;
using sz_func = R(T::*)()const;
const char* name = to_string(meta_function::length).c_str();
l[index] = luaL_Reg{ name, &c_call<decltype(&T::size), &T::size> };
l[index] = luaL_Reg{ name, &c_call<decltype(static_cast<sz_func>(&T::size)), static_cast<sz_func>(&T::size)> };
++index;
}
@ -181,7 +183,12 @@ namespace sol {
}
}
template <typename T, typename Regs, typename Fx>
template <typename T, typename Regs, typename Fx, meta::disable<is_automagical<T>> = meta::enabler>
void insert_default_registrations(Regs&, int&, Fx&&) {
// no-op
}
template <typename T, typename Regs, typename Fx, meta::enable<is_automagical<T>> = meta::enabler>
void insert_default_registrations(Regs& l, int& index, Fx&& fx) {
if (fx(meta_function::less_than)) {
const char* name = to_string(meta_function::less_than).c_str();

View File

@ -697,20 +697,20 @@ TEST_CASE("regressions/one", "issue number 48") {
}
TEST_CASE("usertype/get-set-references", "properly get and set with std::ref semantics. Note that to get, we must not use Unqualified<T> on the type...") {
std::cout << "----- in 4" << std::endl;
std::cout << "----- in 4" << std::endl;
sol::state lua;
lua.new_usertype<vars>("vars",
"boop", &vars::boop);
vars var{};
vars rvar{};
std::cout << "setting beep" << std::endl;
std::cout << "setting beep" << std::endl;
lua.set("beep", var);
std::cout << "setting rbeep" << std::endl;
std::cout << "setting rbeep" << std::endl;
lua.set("rbeep", std::ref(rvar));
std::cout << "getting my_var" << std::endl;
std::cout << "getting my_var" << std::endl;
auto& my_var = lua.get<vars>("beep");
std::cout << "setting rbeep" << std::endl;
std::cout << "setting rbeep" << std::endl;
auto& ref_var = lua.get<std::reference_wrapper<vars>>("rbeep");
vars& proxy_my_var = lua["beep"];
std::reference_wrapper<vars> proxy_ref_var = lua["rbeep"];