From 30e570aae7d2ba5522feafb962b334ef3f35459e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Thu, 21 Jun 2018 14:44:00 +0200 Subject: [core] add polyfill for codecvt for STLs that don't have it yet --- CMakeLists.txt | 2 ++ cmake/codecvt.cmake | 19 +++++++++++++++++++ cmake/core.cmake | 2 ++ platform/android/config.cmake | 3 +++ platform/default/codecvt/codecvt | 30 ++++++++++++++++++++++++++++++ platform/default/utf.cpp | 16 ++-------------- 6 files changed, 58 insertions(+), 14 deletions(-) create mode 100644 cmake/codecvt.cmake create mode 100644 platform/default/codecvt/codecvt diff --git a/CMakeLists.txt b/CMakeLists.txt index bb315916b4..b37a69a83e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -142,6 +142,8 @@ else() message(STATUS "Can't find ccache — consider installing ccache to improve recompilation performance") endif() +include(cmake/codecvt.cmake) + if(NOT EXISTS ${CMAKE_SOURCE_DIR}/platform/${MBGL_PLATFORM}/config.cmake) message(ERROR "Can't find config.cmake file for platform ${MBGL_PLATFORM}") endif() diff --git a/cmake/codecvt.cmake b/cmake/codecvt.cmake new file mode 100644 index 0000000000..8228a6df6b --- /dev/null +++ b/cmake/codecvt.cmake @@ -0,0 +1,19 @@ +add_library(codecvt INTERFACE) + +# Determine if the STL has codecvt +file(WRITE "${CMAKE_BINARY_DIR}/features/codecvt/main.cpp" "#include \nint main() {}") +try_compile(STL_SUPPORTS_CODECVT + "${CMAKE_BINARY_DIR}/features/codecvt" + SOURCES "${CMAKE_BINARY_DIR}/features/codecvt/main.cpp" + CMAKE_FLAGS "-DCMAKE_MACOSX_BUNDLE:STRING=YES" "-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED:STRING=NO" + COMPILE_DEFINITIONS "-std=c++14" # CXX_STANDARD wasn't added to try_compile until CMake 3.8 + OUTPUT_VARIABLE CODECVT_TEST_OUTPUT +) + +if (NOT STL_SUPPORTS_CODECVT) + if ($ENV{V}) + message("codecvt support not detected: ${CODECVT_TEST_OUTPUT}") + endif() + target_include_directories(codecvt INTERFACE platform/default/codecvt) + target_add_mason_package(codecvt INTERFACE boost) +endif() diff --git a/cmake/core.cmake b/cmake/core.cmake index 32e77f5d55..1b29b4fb08 100644 --- a/cmake/core.cmake +++ b/cmake/core.cmake @@ -7,6 +7,8 @@ target_include_directories(mbgl-core PRIVATE src ) +target_link_libraries(mbgl-core PRIVATE codecvt) + target_add_mason_package(mbgl-core PUBLIC geometry) target_add_mason_package(mbgl-core PUBLIC variant) target_add_mason_package(mbgl-core PRIVATE unique_resource) diff --git a/platform/android/config.cmake b/platform/android/config.cmake index d6be05095b..004912ba1a 100644 --- a/platform/android/config.cmake +++ b/platform/android/config.cmake @@ -71,6 +71,7 @@ macro(mbgl_filesource) target_add_mason_package(mbgl-filesource PUBLIC jni.hpp) target_link_libraries(mbgl-filesource + PRIVATE codecvt PUBLIC sqlite PUBLIC -llog PUBLIC -landroid @@ -86,6 +87,7 @@ add_library(mapbox-gl SHARED ) target_link_libraries(mapbox-gl + PRIVATE codecvt PRIVATE mbgl-core PRIVATE mbgl-filesource ) @@ -106,6 +108,7 @@ macro(mbgl_platform_test) ) target_link_libraries(mbgl-test + PRIVATE codecvt PRIVATE mbgl-core PRIVATE mbgl-filesource ) diff --git a/platform/default/codecvt/codecvt b/platform/default/codecvt/codecvt new file mode 100644 index 0000000000..8d21e82348 --- /dev/null +++ b/platform/default/codecvt/codecvt @@ -0,0 +1,30 @@ +#pragma once + +// This is a minimal polyfill that'll only work exactly for how we use codecvt + +#include +#include + +namespace std { + +template +class wstring_convert { +public: + static_assert(std::is_same::value, "type mismatch"); + + inline std::basic_string from_bytes(const string& str) { + return boost::locale::conv::utf_to_utf(str); + } + + inline string to_bytes(const std::basic_string& str) { + return boost::locale::conv::utf_to_utf(str); + } +}; + +template +class codecvt_utf8_utf16 { +public: + using Elem = E; +}; + +} // namespace std diff --git a/platform/default/utf.cpp b/platform/default/utf.cpp index 8fc44a9ed3..8bc8ea7314 100644 --- a/platform/default/utf.cpp +++ b/platform/default/utf.cpp @@ -1,25 +1,13 @@ #include -#include #include - -// GCC 4.9 compatibility -#if !defined(__GNUC__) || __GNUC__ >= 5 #include -#else -#include -#endif namespace mbgl { namespace util { -std::u16string utf8_to_utf16::convert(std::string const& utf8) { -#if !defined(__GNUC__) || __GNUC__ >= 5 - std::wstring_convert, char16_t> converter; - return converter.from_bytes(utf8); -#else - return boost::locale::conv::utf_to_utf(utf8.c_str(), utf8.c_str() + utf8.size()); -#endif +std::u16string utf8_to_utf16::convert(const std::string& utf8) { + return std::wstring_convert, char16_t>().from_bytes(utf8); } } // namespace util -- cgit v1.2.1