diff options
| -rw-r--r-- | Makefile | 14 | ||||
| -rw-r--r-- | include/unicode.h | 21 | ||||
| -rw-r--r-- | src/test-unicode.cpp | 5 | 
3 files changed, 28 insertions, 12 deletions
| @@ -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<char8_t>  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<char8_t> 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<char8_t> 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 <memory>  #include <stdexcept>  #include <string> +#include <type_traits>  #include <unordered_map>  #ifdef __cpp_char8_t @@ -526,7 +527,7 @@ namespace unicode {   typedef UTF<utf_iterator<char32_t>, utf_back_insert_iterator<char32_t>> UTF_32;   // From and To are facets - template<typename From, typename To> + template<typename From, typename To, std::enable_if_t<std::is_empty<From>::value && std::is_empty<To>::value, bool> = true>   std::basic_string<typename To::value_type> convert(const std::basic_string<typename From::value_type>& s)   {    std::basic_string<typename To::value_type> result; @@ -561,7 +562,9 @@ namespace unicode {   };   // From and To are from: utf8_t, char16_t and char32_t - template<typename From, typename To> + template<typename From, typename To, +  std::enable_if_t<std::is_trivial<From>::value && std::is_trivial<To>::value, bool> = true + >   std::basic_string<To> convert(const std::basic_string<From>& s)   {    typedef UTF<utf_iterator<From>, utf_back_insert_iterator<To>> UTF_Trait; @@ -573,6 +576,20 @@ namespace unicode {    return result;   } + template<typename FromContainer, typename ToContainer, +  std::enable_if_t<!std::is_empty<FromContainer>::value && !std::is_empty<ToContainer>::value, bool> = true + > + ToContainer convert(const FromContainer& s) + { +  typedef UTF<utf_iterator<typename FromContainer::value_type>, utf_back_insert_iterator<typename ToContainer::value_type>> 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<typename T>   bool is_valid_utf(const std::basic_string<T>& 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<char, wchar_t>(u8"\U0001F63A")) == std::wstring{L"\U0001F63A"});   BOOST_CHECK((unicode::convert<wchar_t, char32_t>(L"\U0001F63A")) == std::u32string{U"\U0001F63A"});   BOOST_CHECK((unicode::convert<wchar_t, char>(L"\U0001F63A")) == std::string{u8"\U0001F63A"}); +  + BOOST_CHECK((unicode::convert<std::string, std::wstring>(std::string{"äöü"})) == std::wstring{L"äöü"}); +  + //BOOST_CHECK((unicode::convert<std::vector<char>, std::vector<wchar_t>>(std::vector<char>{})) == std::vector<wchar_t>{});  }  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? | 
