revert codecvt fix for MinGW v7 and greater

add docs about compiler support
add notes about compilation issues
update single
This commit is contained in:
ThePhD 2017-06-07 12:33:59 -04:00
parent 090c834f2c
commit 661386c384
10 changed files with 75 additions and 18 deletions

View File

@ -56,9 +56,9 @@ args = parser.parse_args()
# general variables # general variables
include = [ '.', './include' ] include = [ '.', './include' ]
depends = [os.path.join('Catch', 'include')] depends = [os.path.join('Catch', 'include')]
cxxflags = [ '-Wall', '-Wextra', '-Wpedantic', '-pedantic', '-pedantic-errors', '-std=c++14', '-ftemplate-depth=1024' ] cxxflags = [ '-Wall', '-Wextra', '-Wpedantic', '-pedantic', '-pedantic-errors', '-Wno-noexcept-type', '-std=c++14', '-ftemplate-depth=1024' ]
cxxflags.extend([p for p in re.split("( |\\\".*?\\\"|'.*?')", args.cxx_flags) if p.strip()]) cxxflags.extend([p for p in re.split("( |\\\".*?\\\"|'.*?')", args.cxx_flags) if p.strip()])
example_cxxflags = [ '-Wall', '-Wextra', '-Wpedantic', '-pedantic', '-pedantic-errors', '-std=c++14', '-ftemplate-depth=1024' ] example_cxxflags = [ '-Wall', '-Wextra', '-Wpedantic', '-pedantic', '-pedantic-errors', '-Wno-noexcept-type', '-std=c++14', '-ftemplate-depth=1024' ]
example_cxxflags.extend([p for p in re.split("( |\\\".*?\\\"|'.*?')", args.cxx_flags) if p.strip()]) example_cxxflags.extend([p for p in re.split("( |\\\".*?\\\"|'.*?')", args.cxx_flags) if p.strip()])
ldflags = [] ldflags = []
script_dir = os.path.dirname(os.path.realpath(sys.argv[0])) script_dir = os.path.dirname(os.path.realpath(sys.argv[0]))

View File

@ -3,6 +3,8 @@ std::(w/u16/u32)string support
because this is surprisingly hard using standard C++ because this is surprisingly hard using standard C++
---------------------------------------------------- ----------------------------------------------------
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 GC 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. 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.
ThePhD did not want this to have to be a thing, but slow implementations and such force their hand. When GCC 7.x comes out, ThePhD will consider removing the effect of defining this macro and leaving <codecvt> support in at all times. ThePhD did not want this to have to be a thing, but slow implementations and such force their hand. When GCC 7.x comes out, ThePhD will consider removing the effect of defining this macro and leaving <codecvt> support in at all times.
GCC 7.x is now out, and its codecvt support seems to work in it as well. We will be removing the conditional SOL_CODECVT support and deprecating support for GCC 4.x.x, Clang 3.5.x, and Clang 3.6.x in releases past sol2 v2.17.5

View File

@ -1,8 +1,39 @@
binary size, compile time supported compilers, binary size, compile time
========================= ==============================================
getting good final product out of sol2 getting good final product out of sol2
-------------------------------------- --------------------------------------
supported compilers
-------------------
GCC 7.x is now out alongside Visual Studio 2017. This means that Sol v. 2.17.5 will be the last version of the code targeted at the older compilers. Newer code will be targeted at working with the following compilers and leveraging their features, possibly taking advantage of whatever C++17 features are made available by the compilers and standard libraries bundled by-default with them:
* VC++
- Visual Studio 2017
- Visual Studio 2015 (with latest updates)
* GCC (includes MinGW)
- v7.x
- v6.x
- v5.x
* Clang
- v4.x
- v3.9.x
- v3.8.x
- v3.7.x
- Note: this applies to XCode's Apple Clang as well, but that compiler packs its own deficiencies and problems as well
Note that Visual Studio's 2017 Community Edition is absolutely free now, and installs faster and easier than ever before. It also removes a lot of hacky work arounds and formally supports decltype SFINAE.
MinGW's GCC version 7.x of the compiler fixes a long-standing derp in the <codecvt> header that swapped the endianness of utf16 and utf32 strings.
Clang 3.4, 3.5 and 3.6 have many bugs we have run into when developing sol2 and that have negatively impacted users for a long time now.
We encourage all users to upgrade immediately. If you need old code, use sol2 release v2.17.5: otherwise, always grab sol2's latest.
binary sizes
------------
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. 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 what to do
@ -25,3 +56,4 @@ 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). 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. Hopefully, as things progress, we move things forward.

View File

@ -19,6 +19,7 @@ A myriad of compiler errors can occur when something goes wrong. Here is some ba
* 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. * 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. * 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.
* If you have a move-only type, that type may need to be made ``readonly`` if it is bound as a member variable on a usertype or bound using ``state_view::set_function``. See :doc:`sol::readonly<api/readonly>` for more details. * If you have a move-only type, that type may need to be made ``readonly`` if it is bound as a member variable on a usertype or bound using ``state_view::set_function``. See :doc:`sol::readonly<api/readonly>` for more details.
* Assigning a ``std::string`` or a ``std::pair<T1, T2>`` using ``operator=`` after it's been constructed can result in compiler errors when working with ``sol::function`` and its results. See `this issue for fixes to this behavior`_.
Linker Errors Linker Errors
------------- -------------
@ -70,3 +71,5 @@ 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>`. 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>`.
.. _this issue for fixes to this behavior: https://github.com/ThePhD/sol2/issues/414#issuecomment-306839439

View File

@ -20,8 +20,8 @@
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// This file was generated with a script. // This file was generated with a script.
// Generated 2017-06-03 10:24:17.749249 UTC // Generated 2017-06-07 16:29:19.321797 UTC
// This header was generated with sol v2.17.4 (revision 7168c31) // This header was generated with sol v2.17.4 (revision 090c834)
// https://github.com/ThePhD/sol2 // https://github.com/ThePhD/sol2
#ifndef SOL_SINGLE_INCLUDE_HPP #ifndef SOL_SINGLE_INCLUDE_HPP
@ -47,6 +47,7 @@
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshadow" #pragma GCC diagnostic ignored "-Wshadow"
#pragma GCC diagnostic ignored "-Wconversion" #pragma GCC diagnostic ignored "-Wconversion"
#pragma GCC diagnostic ignored "-Wnoexcept-type"
#elif defined _MSC_VER #elif defined _MSC_VER
#pragma warning( push ) #pragma warning( push )
#pragma warning( disable : 4324 ) // structure was padded due to alignment specifier #pragma warning( disable : 4324 ) // structure was padded due to alignment specifier
@ -672,6 +673,12 @@ namespace sol {
template <typename T> template <typename T>
using is_string_constructible = any<std::is_same<unqualified_t<T>, const char*>, std::is_same<unqualified_t<T>, char>, std::is_same<unqualified_t<T>, std::string>, std::is_same<unqualified_t<T>, std::initializer_list<char>>>; using is_string_constructible = any<std::is_same<unqualified_t<T>, const char*>, std::is_same<unqualified_t<T>, char>, std::is_same<unqualified_t<T>, std::string>, std::is_same<unqualified_t<T>, std::initializer_list<char>>>;
template <typename T>
struct is_pair : std::false_type {};
template <typename T1, typename T2>
struct is_pair<std::pair<T1, T2>> : std::true_type {};
template <typename T> template <typename T>
using is_c_str = any< using is_c_str = any<
std::is_same<std::decay_t<unqualified_t<T>>, const char*>, std::is_same<std::decay_t<unqualified_t<T>>, const char*>,
@ -3567,7 +3574,7 @@ namespace sol {
return static_cast<type>(lua_type(L, index)); return static_cast<type>(lua_type(L, index));
} }
inline int type_panic(lua_State* L, int index, type expected, type actual) { inline int type_panic(lua_State* L, int index, type expected, type actual) noexcept(false) {
return luaL_error(L, "stack index %d, expected %s, received %s", index, return luaL_error(L, "stack index %d, expected %s, received %s", index,
expected == type::poly ? "anything" : lua_typename(L, static_cast<int>(expected)), expected == type::poly ? "anything" : lua_typename(L, static_cast<int>(expected)),
expected == type::poly ? "anything" : lua_typename(L, static_cast<int>(actual)) expected == type::poly ? "anything" : lua_typename(L, static_cast<int>(actual))
@ -3579,15 +3586,15 @@ namespace sol {
return 0; return 0;
} }
inline void type_error(lua_State* L, int expected, int actual) { inline void type_error(lua_State* L, int expected, int actual) noexcept(false) {
luaL_error(L, "expected %s, received %s", lua_typename(L, expected), lua_typename(L, actual)); luaL_error(L, "expected %s, received %s", lua_typename(L, expected), lua_typename(L, actual));
} }
inline void type_error(lua_State* L, type expected, type actual) { inline void type_error(lua_State* L, type expected, type actual) noexcept(false) {
type_error(L, static_cast<int>(expected), static_cast<int>(actual)); type_error(L, static_cast<int>(expected), static_cast<int>(actual));
} }
inline void type_assert(lua_State* L, int index, type expected, type actual) { inline void type_assert(lua_State* L, int index, type expected, type actual) noexcept(false) {
if (expected != type::poly && expected != actual) { if (expected != type::poly && expected != actual) {
type_panic(L, index, expected, actual); type_panic(L, index, expected, actual);
} }
@ -5831,7 +5838,7 @@ namespace sol {
if (sizeof(wchar_t) == 2) { if (sizeof(wchar_t) == 2) {
static std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert; static std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert;
std::wstring r = convert.from_bytes(str, str + len); std::wstring r = convert.from_bytes(str, str + len);
#ifdef __MINGW32__ #if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ < 7
// Fuck you, MinGW, and fuck you libstdc++ for introducing this absolutely asinine bug // Fuck you, MinGW, and fuck you libstdc++ for introducing this absolutely asinine bug
// https://sourceforge.net/p/mingw-w64/bugs/538/ // https://sourceforge.net/p/mingw-w64/bugs/538/
// http://chat.stackoverflow.com/transcript/message/32271369#32271369 // http://chat.stackoverflow.com/transcript/message/32271369#32271369
@ -6438,8 +6445,6 @@ namespace sol {
template <typename Arg, meta::enable<std::is_base_of<Real, meta::unqualified_t<Arg>>> = meta::enabler> template <typename Arg, meta::enable<std::is_base_of<Real, meta::unqualified_t<Arg>>> = meta::enabler>
static int push(lua_State* L, Arg&& arg) { static int push(lua_State* L, Arg&& arg) {
if (unique_usertype_traits<T>::is_null(arg))
return stack::push(L, lua_nil);
return push_deep(L, std::forward<Arg>(arg)); return push_deep(L, std::forward<Arg>(arg));
} }

View File

@ -37,6 +37,7 @@
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshadow" #pragma GCC diagnostic ignored "-Wshadow"
#pragma GCC diagnostic ignored "-Wconversion" #pragma GCC diagnostic ignored "-Wconversion"
#pragma GCC diagnostic ignored "-Wnoexcept-type"
#elif defined _MSC_VER #elif defined _MSC_VER
#pragma warning( push ) #pragma warning( push )
#pragma warning( disable : 4324 ) // structure was padded due to alignment specifier #pragma warning( disable : 4324 ) // structure was padded due to alignment specifier

View File

@ -312,7 +312,7 @@ namespace sol {
if (sizeof(wchar_t) == 2) { if (sizeof(wchar_t) == 2) {
static std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert; static std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert;
std::wstring r = convert.from_bytes(str, str + len); std::wstring r = convert.from_bytes(str, str + len);
#ifdef __MINGW32__ #if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ < 7
// Fuck you, MinGW, and fuck you libstdc++ for introducing this absolutely asinine bug // Fuck you, MinGW, and fuck you libstdc++ for introducing this absolutely asinine bug
// https://sourceforge.net/p/mingw-w64/bugs/538/ // https://sourceforge.net/p/mingw-w64/bugs/538/
// http://chat.stackoverflow.com/transcript/message/32271369#32271369 // http://chat.stackoverflow.com/transcript/message/32271369#32271369

View File

@ -318,6 +318,12 @@ namespace sol {
template <typename T> template <typename T>
using is_string_constructible = any<std::is_same<unqualified_t<T>, const char*>, std::is_same<unqualified_t<T>, char>, std::is_same<unqualified_t<T>, std::string>, std::is_same<unqualified_t<T>, std::initializer_list<char>>>; using is_string_constructible = any<std::is_same<unqualified_t<T>, const char*>, std::is_same<unqualified_t<T>, char>, std::is_same<unqualified_t<T>, std::string>, std::is_same<unqualified_t<T>, std::initializer_list<char>>>;
template <typename T>
struct is_pair : std::false_type {};
template <typename T1, typename T2>
struct is_pair<std::pair<T1, T2>> : std::true_type {};
template <typename T> template <typename T>
using is_c_str = any< using is_c_str = any<
std::is_same<std::decay_t<unqualified_t<T>>, const char*>, std::is_same<std::decay_t<unqualified_t<T>>, const char*>,

View File

@ -240,7 +240,7 @@ nested = { variables = { no = { problem = 10 } } } )");
REQUIRE(cd == cddesired); REQUIRE(cd == cddesired);
ab = cpp_bark(std::make_pair(lua_variable_x, cpp_variable_y)); ab = cpp_bark(std::make_pair(lua_variable_x, cpp_variable_y));
cd = lua_bark(std::make_pair(lua["nested"]["variables"]["no"]["problem"], cpp_variable_y)); cd = static_cast<std::pair<int, int>>(lua_bark(std::make_pair(lua["nested"]["variables"]["no"]["problem"], cpp_variable_y)));
REQUIRE(ab == abdesired); REQUIRE(ab == abdesired);
REQUIRE(cd == cddesired); REQUIRE(cd == cddesired);

View File

@ -6,7 +6,15 @@
#include <iostream> #include <iostream>
#include <list> #include <list>
#include <memory> #include <memory>
#include <mutex>
struct non_copyable {
non_copyable() = default;
non_copyable(const non_copyable&) = delete;
non_copyable& operator=(const non_copyable&) = delete;
non_copyable(non_copyable&&) = default;
non_copyable& operator=(non_copyable&&) = default;
};
struct vars { struct vars {
vars() { vars() {
@ -1188,7 +1196,7 @@ TEST_CASE("usertype/copyability", "make sure user can write to a class variable
void set(int val) { _you_can_copy_me = val; } void set(int val) { _you_can_copy_me = val; }
int _you_can_copy_me; int _you_can_copy_me;
std::mutex _haha_you_cant_copy_me; non_copyable _haha_you_cant_copy_me;
}; };
sol::state lua; sol::state lua;