fork download
  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4.  
  5. #include <boost/locale.hpp>
  6.  
  7. namespace yekneb
  8. {
  9.  
  10. namespace detail
  11. {
  12. namespace string_cast
  13. {
  14.  
  15. inline bool IsUTF8(const std::locale &loc)
  16. {
  17. std::string locName = loc.name();
  18. if (! locName.empty() && std::string::npos != locName.find("UTF-8"))
  19. {
  20. return true;
  21. }
  22. return false;
  23. }
  24.  
  25. inline std::string w2s(const std::wstring& ws, const std::locale& loc)
  26. {
  27. typedef std::codecvt<wchar_t, char, std::mbstate_t> converter_type;
  28. typedef std::ctype<wchar_t> wchar_facet;
  29. std::string return_value;
  30. if (ws.empty())
  31. {
  32. return "";
  33. }
  34. if (IsUTF8(loc))
  35. {
  36. return_value = boost::locale::conv::utf_to_utf<char>(ws);
  37. if (! return_value.empty())
  38. {
  39. return return_value;
  40. }
  41. }
  42. const wchar_t* from = ws.c_str();
  43. size_t len = ws.length();
  44. size_t converterMaxLength = 6;
  45. size_t vectorSize = ((len + 6) * converterMaxLength);
  46. if (std::has_facet<converter_type>(loc))
  47. {
  48. const converter_type& converter = std::use_facet<converter_type>(loc);
  49. if (converter.always_noconv())
  50. {
  51. converterMaxLength = converter.max_length();
  52. if (converterMaxLength != 6)
  53. {
  54. vectorSize = ((len + 6) * converterMaxLength);
  55. }
  56. std::mbstate_t state;
  57. const wchar_t* from_next = nullptr;
  58. std::vector<char> to(vectorSize, 0);
  59. std::vector<char>::pointer toPtr = to.data();
  60. std::vector<char>::pointer to_next = nullptr;
  61. const converter_type::result result = converter.out(
  62. state, from, from + len, from_next,
  63. toPtr, toPtr + vectorSize, to_next);
  64. if (
  65. (converter_type::ok == result || converter_type::noconv == result)
  66. && 0 != toPtr[0]
  67. )
  68. {
  69. return_value.assign(toPtr, to_next);
  70. }
  71. }
  72. }
  73. if (return_value.empty() && std::has_facet<wchar_facet>(loc))
  74. {
  75. std::vector<char> to(vectorSize, 0);
  76. std::vector<char>::pointer toPtr = to.data();
  77. const wchar_facet& facet = std::use_facet<wchar_facet>(loc);
  78. if (facet.narrow(from, from + len, '?', toPtr) != 0)
  79. {
  80. return_value = toPtr;
  81. }
  82. }
  83. return return_value;
  84. }
  85.  
  86. inline std::wstring s2w(const std::string& s, const std::locale& loc)
  87. {
  88. typedef std::ctype<wchar_t> wchar_facet;
  89. std::wstring return_value;
  90. if (s.empty())
  91. {
  92. return L"";
  93. }
  94. if (std::has_facet<wchar_facet>(loc))
  95. {
  96. std::vector<wchar_t> to(s.size() + 2, 0);
  97. std::vector<wchar_t>::pointer toPtr = to.data();
  98. const wchar_facet& facet = std::use_facet<wchar_facet>(loc);
  99. if (facet.widen(s.c_str(), s.c_str() + s.size(), toPtr) != 0)
  100. {
  101. return_value = to.data();
  102. }
  103. }
  104. return return_value;
  105. }
  106.  
  107. }
  108. }
  109.  
  110. template<typename Target, typename Source>
  111. inline Target string_cast(const Source& source)
  112. {
  113. return source;
  114. }
  115.  
  116. template<>
  117. inline std::wstring string_cast(const std::string& source)
  118. {
  119. std::locale loc;
  120. return ::yekneb::detail::string_cast::s2w(source, loc);
  121. }
  122.  
  123. template<>
  124. inline std::string string_cast(const std::wstring& source)
  125. {
  126. std::locale loc;
  127. return ::yekneb::detail::string_cast::w2s(source, loc);
  128. }
  129.  
  130. }
  131.  
  132. int main()
  133. {
  134. std::string s1("Buenos días.");
  135. std::wstring ws1 = yekneb::string_cast<std::wstring>(s1);
  136. std::wcout << ws1 << L"\n";
  137.  
  138. std::wstring ws2(L"Buenos días.");
  139. std::string s2 = yekneb::string_cast<std::string>(ws2);
  140. std::cout << s1 << "\n";
  141.  
  142. return 0;
  143. }
  144.  
Success #stdin #stdout 0s 15240KB
stdin
Standard input is empty
stdout
Buenos d?