From 07c77b45ba9f74cfe1bed547bea1eeb705f0582b Mon Sep 17 00:00:00 2001 From: Roland Reichwein Date: Sat, 13 Feb 2021 12:47:39 +0100 Subject: Support G++, support string type as template argument for convert() --- Makefile | 14 +++++--------- include/unicode.h | 21 +++++++++++++++++++-- src/test-unicode.cpp | 5 ++++- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index 7ea075e..39dcafb 100644 --- a/Makefile +++ b/Makefile @@ -5,16 +5,15 @@ DISTROS=base debian10 ubuntu2004 ubuntu2010 ifeq ($(wildcard $(shell which clang++-11)),) ifeq ($(wildcard $(shell which clang++)),) -$(error No clang++-11 nor clang++ available!) +CXX=g++-10 else CXX=clang++ endif else CXX=clang++-11 -# GCC is buggy: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85282 -#CXX=g++-10 endif +# boost is buggy for C++20: error: static_assert failed due to requirement 'detail::is_endian_reversible_inplace STANDARD=c++17 #STANDARD=c++20 @@ -35,11 +34,6 @@ COMPILER_SUITE=clang LIBS+=-fuse-ld=lld endif -ifeq ($(COMPILER_SUITE),clang) -# libc++ is buggy for C++20: std::hash not implemented. Fixed in LLVM-12 -CXXFLAGS+=-stdlib=libc++ -endif - LDLIBS+=\ -lboost_context \ -lboost_filesystem \ @@ -47,6 +41,8 @@ LDLIBS+=\ -lboost_system \ ifeq ($(COMPILER_SUITE),clang) +# libc++ is buggy for C++20: std::hash not implemented. Fixed in LLVM-12 +CXXFLAGS+=-stdlib=libc++ LIBS+= \ -lc++ \ -lc++abi @@ -55,7 +51,7 @@ LIBS+= \ #-lstdc++fs else LIBS+= \ --lstdc++ +-lstdc++ \ -lstdc++fs endif diff --git a/include/unicode.h b/include/unicode.h index d6f8e51..171496e 100644 --- a/include/unicode.h +++ b/include/unicode.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #ifdef __cpp_char8_t @@ -526,7 +527,7 @@ namespace unicode { typedef UTF, utf_back_insert_iterator> UTF_32; // From and To are facets - template + template::value && std::is_empty::value, bool> = true> std::basic_string convert(const std::basic_string& s) { std::basic_string result; @@ -561,7 +562,9 @@ namespace unicode { }; // From and To are from: utf8_t, char16_t and char32_t - template + template::value && std::is_trivial::value, bool> = true + > std::basic_string convert(const std::basic_string& s) { typedef UTF, utf_back_insert_iterator> UTF_Trait; @@ -573,6 +576,20 @@ namespace unicode { return result; } + template::value && !std::is_empty::value, bool> = true + > + ToContainer convert(const FromContainer& s) + { + typedef UTF, utf_back_insert_iterator> UTF_Trait; + + ToContainer result; + + std::copy(UTF_Trait::begin(s), UTF_Trait::end(s), UTF_Trait::back_inserter(result)); + + return result; + } + // basic type version template bool is_valid_utf(const std::basic_string& s) diff --git a/src/test-unicode.cpp b/src/test-unicode.cpp index 99a8f99..5f5ebbf 100644 --- a/src/test-unicode.cpp +++ b/src/test-unicode.cpp @@ -351,6 +351,10 @@ BOOST_AUTO_TEST_CASE(convert) BOOST_CHECK((unicode::convert(u8"\U0001F63A")) == std::wstring{L"\U0001F63A"}); BOOST_CHECK((unicode::convert(L"\U0001F63A")) == std::u32string{U"\U0001F63A"}); BOOST_CHECK((unicode::convert(L"\U0001F63A")) == std::string{u8"\U0001F63A"}); + + BOOST_CHECK((unicode::convert(std::string{"äöü"})) == std::wstring{L"äöü"}); + + //BOOST_CHECK((unicode::convert, std::vector>(std::vector{})) == std::vector{}); } BOOST_AUTO_TEST_CASE(is_valid_utf) @@ -375,6 +379,5 @@ BOOST_AUTO_TEST_CASE(string_u8string) // TODO: // -// char8_t, char16_t, char32_t, char, wchar_t (UTF-16 on Windows, UTF-32 on Linux) // string, vector? // uint8_t, uint16_t, uint32_t? -- cgit v1.2.3