summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2018-06-21 14:44:00 +0200
committerKonstantin Käfer <mail@kkaefer.com>2018-09-11 11:43:54 +0200
commit30e570aae7d2ba5522feafb962b334ef3f35459e (patch)
tree5a8f787197772ed302e1fbf45839d973feb80838
parent536652ca201ce59190ae5c41d1202372d28d6d6d (diff)
downloadqtlocation-mapboxgl-30e570aae7d2ba5522feafb962b334ef3f35459e.tar.gz
[core] add polyfill for codecvt for STLs that don't have it yet
-rw-r--r--CMakeLists.txt2
-rw-r--r--cmake/codecvt.cmake19
-rw-r--r--cmake/core.cmake2
-rw-r--r--platform/android/config.cmake3
-rw-r--r--platform/default/codecvt/codecvt30
-rw-r--r--platform/default/utf.cpp16
6 files changed, 58 insertions, 14 deletions
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 <codecvt>\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 <string>
+#include <boost/locale/encoding_utf.hpp>
+
+namespace std {
+
+template <typename Codecvt, typename Elem = wchar_t>
+class wstring_convert {
+public:
+ static_assert(std::is_same<Elem, typename Codecvt::Elem>::value, "type mismatch");
+
+ inline std::basic_string<Elem> from_bytes(const string& str) {
+ return boost::locale::conv::utf_to_utf<Elem>(str);
+ }
+
+ inline string to_bytes(const std::basic_string<Elem>& str) {
+ return boost::locale::conv::utf_to_utf<char>(str);
+ }
+};
+
+template <typename E>
+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 <mbgl/util/utf.hpp>
-#include <memory>
#include <locale>
-
-// GCC 4.9 compatibility
-#if !defined(__GNUC__) || __GNUC__ >= 5
#include <codecvt>
-#else
-#include <boost/locale/encoding_utf.hpp>
-#endif
namespace mbgl {
namespace util {
-std::u16string utf8_to_utf16::convert(std::string const& utf8) {
-#if !defined(__GNUC__) || __GNUC__ >= 5
- std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> converter;
- return converter.from_bytes(utf8);
-#else
- return boost::locale::conv::utf_to_utf<char16_t>(utf8.c_str(), utf8.c_str() + utf8.size());
-#endif
+std::u16string utf8_to_utf16::convert(const std::string& utf8) {
+ return std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>().from_bytes(utf8);
}
} // namespace util