1 /* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
2  * Use of this file is governed by the BSD 3-clause license that
3  * can be found in the LICENSE.txt file in the project root.
4  */
5 
6 #pragma once
7 
8 #include "antlr4-common.h"
9 
10 namespace antlrcpp {
11 
12   // For all conversions utf8 <-> utf32.
13   // VS 2015 and VS 2017 have different bugs in std::codecvt_utf8<char32_t> (VS 2013 works fine).
14 #if defined(_MSC_VER) && _MSC_VER >= 1900 && _MSC_VER < 2000
15   typedef std::wstring_convert<std::codecvt_utf8<__int32>, __int32> UTF32Converter;
16 #else
17   typedef std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> UTF32Converter;
18 #endif
19 
20   // The conversion functions fails in VS2017, so we explicitly use a workaround.
21   template<typename T>
utf32_to_utf8(T const & data)22   inline std::string utf32_to_utf8(T const& data)
23   {
24     // Don't make the converter static or we have to serialize access to it.
25     thread_local UTF32Converter converter;
26 
27     #if defined(_MSC_VER) && _MSC_VER >= 1900 && _MSC_VER < 2000
28       auto p = reinterpret_cast<const int32_t *>(data.data());
29       return converter.to_bytes(p, p + data.size());
30     #else
31       return converter.to_bytes(data);
32     #endif
33   }
34 
utf8_to_utf32(const char * first,const char * last)35   inline UTF32String utf8_to_utf32(const char* first, const char* last)
36   {
37     thread_local UTF32Converter converter;
38 
39     #if defined(_MSC_VER) && _MSC_VER >= 1900 && _MSC_VER < 2000
40       auto r = converter.from_bytes(first, last);
41       i32string s = reinterpret_cast<const int32_t *>(r.data());
42     #else
43       std::u32string s = converter.from_bytes(first, last);
44     #endif
45 
46     return s;
47   }
48 
49   void replaceAll(std::string &str, std::string const& from, std::string const& to);
50 
51   // string <-> wstring conversion (UTF-16), e.g. for use with Window's wide APIs.
52   ANTLR4CPP_PUBLIC std::string ws2s(std::wstring const& wstr);
53   ANTLR4CPP_PUBLIC std::wstring s2ws(std::string const& str);
54 }
55