25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 
 
 
 

569 satır
16 KiB

  1. // from https://github.com/javacommons/strconv
  2. /* strconv.h v1.8.10 */
  3. /* Last Modified: 2021/08/30 21:53 */
  4. /*
  5. ------------------------------------------------------------------------------
  6. This software is available under 2 licenses -- choose whichever you prefer.
  7. ------------------------------------------------------------------------------
  8. ALTERNATIVE A - MIT License
  9. Copyright (c) 2019-2021 JavaCommons
  10. Permission is hereby granted, free of charge, to any person obtaining a copy of
  11. this software and associated documentation files (the "Software"), to deal in
  12. the Software without restriction, including without limitation the rights to
  13. use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  14. of the Software, and to permit persons to whom the Software is furnished to do
  15. so, subject to the following conditions:
  16. The above copyright notice and this permission notice shall be included in all
  17. copies or substantial portions of the Software.
  18. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  24. SOFTWARE.
  25. ------------------------------------------------------------------------------
  26. ALTERNATIVE B - Public Domain (www.unlicense.org)
  27. This is free and unencumbered software released into the public domain.
  28. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
  29. software, either in source code form or as a compiled binary, for any purpose,
  30. commercial or non-commercial, and by any means.
  31. In jurisdictions that recognize copyright laws, the author or authors of this
  32. software dedicate any and all copyright interest in the software to the public
  33. domain. We make this dedication for the benefit of the public at large and to
  34. the detriment of our heirs and successors. We intend this dedication to be an
  35. overt act of relinquishment in perpetuity of all present and future rights to
  36. this software under copyright law.
  37. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  38. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  39. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  40. AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  41. ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  42. WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  43. -----------------------------------------------------------------------------
  44. */
  45. #ifndef STRCONV_H
  46. #define STRCONV_H
  47. #include <windows.h>
  48. #include <string>
  49. #include <vector>
  50. #include <iostream>
  51. #include <sstream>
  52. #if __cplusplus >= 201103L && !defined(STRCONV_CPP98)
  53. static inline std::wstring cp_to_wide(const std::string &s, UINT codepage)
  54. {
  55. int in_length = (int)s.length();
  56. int out_length = MultiByteToWideChar(codepage, 0, s.c_str(), in_length, 0, 0);
  57. std::wstring result(out_length, L'\0');
  58. if (out_length)
  59. MultiByteToWideChar(codepage, 0, s.c_str(), in_length, &result[0], out_length);
  60. return result;
  61. }
  62. static inline std::string wide_to_cp(const std::wstring &s, UINT codepage)
  63. {
  64. int in_length = (int)s.length();
  65. int out_length = WideCharToMultiByte(codepage, 0, s.c_str(), in_length, 0, 0, 0, 0);
  66. std::string result(out_length, '\0');
  67. if (out_length)
  68. WideCharToMultiByte(codepage, 0, s.c_str(), in_length, &result[0], out_length, 0, 0);
  69. return result;
  70. }
  71. #else /* __cplusplus < 201103L */
  72. static inline std::wstring cp_to_wide(const std::string &s, UINT codepage)
  73. {
  74. int in_length = (int)s.length();
  75. int out_length = MultiByteToWideChar(codepage, 0, s.c_str(), in_length, 0, 0);
  76. std::vector<wchar_t> buffer(out_length);
  77. if (out_length)
  78. MultiByteToWideChar(codepage, 0, s.c_str(), in_length, &buffer[0], out_length);
  79. std::wstring result(buffer.begin(), buffer.end());
  80. return result;
  81. }
  82. static inline std::string wide_to_cp(const std::wstring &s, UINT codepage)
  83. {
  84. int in_length = (int)s.length();
  85. int out_length = WideCharToMultiByte(codepage, 0, s.c_str(), in_length, 0, 0, 0, 0);
  86. std::vector<char> buffer(out_length);
  87. if (out_length)
  88. WideCharToMultiByte(codepage, 0, s.c_str(), in_length, &buffer[0], out_length, 0, 0);
  89. std::string result(buffer.begin(), buffer.end());
  90. return result;
  91. }
  92. #endif
  93. static inline std::string cp_to_utf8(const std::string &s, UINT codepage)
  94. {
  95. if (codepage == CP_UTF8)
  96. return s;
  97. std::wstring wide = cp_to_wide(s, codepage);
  98. return wide_to_cp(wide, CP_UTF8);
  99. }
  100. static inline std::string utf8_to_cp(const std::string &s, UINT codepage)
  101. {
  102. if (codepage == CP_UTF8)
  103. return s;
  104. std::wstring wide = cp_to_wide(s, CP_UTF8);
  105. return wide_to_cp(wide, codepage);
  106. }
  107. static inline std::wstring ansi_to_wide(const std::string &s)
  108. {
  109. return cp_to_wide(s, CP_ACP);
  110. }
  111. static inline std::string wide_to_ansi(const std::wstring &s)
  112. {
  113. return wide_to_cp(s, CP_ACP);
  114. }
  115. static inline std::wstring sjis_to_wide(const std::string &s)
  116. {
  117. return cp_to_wide(s, 932);
  118. }
  119. static inline std::string wide_to_sjis(const std::wstring &s)
  120. {
  121. return wide_to_cp(s, 932);
  122. }
  123. static inline std::wstring utf8_to_wide(const std::string &s)
  124. {
  125. return cp_to_wide(s, CP_UTF8);
  126. }
  127. static inline std::string wide_to_utf8(const std::wstring &s)
  128. {
  129. return wide_to_cp(s, CP_UTF8);
  130. }
  131. static inline std::string ansi_to_utf8(const std::string &s)
  132. {
  133. return cp_to_utf8(s, CP_ACP);
  134. }
  135. static inline std::string utf8_to_ansi(const std::string &s)
  136. {
  137. return utf8_to_cp(s, CP_ACP);
  138. }
  139. static inline std::string sjis_to_utf8(const std::string &s)
  140. {
  141. return cp_to_utf8(s, 932);
  142. }
  143. static inline std::string utf8_to_sjis(const std::string &s)
  144. {
  145. return utf8_to_cp(s, 932);
  146. }
  147. #ifdef __cpp_char8_t
  148. static inline std::u8string utf8_to_char8(const std::string &s)
  149. {
  150. return std::u8string(s.begin(), s.end());
  151. }
  152. static inline std::string char8_to_utf8(const std::u8string &s)
  153. {
  154. return std::string(s.begin(), s.end());
  155. }
  156. static inline std::wstring char8_to_wide(const std::u8string &s)
  157. {
  158. return cp_to_wide(char8_to_utf8(s), CP_UTF8);
  159. }
  160. static inline std::u8string wide_to_char8(const std::wstring &s)
  161. {
  162. return utf8_to_char8(wide_to_cp(s, CP_UTF8));
  163. }
  164. static inline std::u8string cp_to_char8(const std::string &s, UINT codepage)
  165. {
  166. return utf8_to_char8(cp_to_utf8(s, codepage));
  167. }
  168. static inline std::string char8_to_cp(const std::u8string &s, UINT codepage)
  169. {
  170. return utf8_to_cp(char8_to_utf8(s), codepage);
  171. }
  172. static inline std::u8string ansi_to_char8(const std::string &s)
  173. {
  174. return cp_to_char8(s, CP_ACP);
  175. }
  176. static inline std::string char8_to_ansi(const std::u8string &s)
  177. {
  178. return char8_to_cp(s, CP_ACP);
  179. }
  180. static inline std::u8string sjis_to_char8(const std::string &s)
  181. {
  182. return cp_to_char8(s, 932);
  183. }
  184. static inline std::string char8_to_sjis(const std::u8string &s)
  185. {
  186. return char8_to_cp(s, 932);
  187. }
  188. #endif
  189. #if defined(_MSC_VER)
  190. #pragma warning(push)
  191. #pragma warning(disable : 4996)
  192. #endif
  193. static inline std::wstring vformat(const wchar_t *format, va_list args)
  194. {
  195. int len = _vsnwprintf(0, 0, format, args);
  196. if (len < 0)
  197. return L"";
  198. std::vector<wchar_t> buffer(len + 1);
  199. len = _vsnwprintf(&buffer[0], len, format, args);
  200. if (len < 0)
  201. return L"";
  202. buffer[len] = L'\0';
  203. return &buffer[0];
  204. }
  205. static inline std::string vformat(const char *format, va_list args)
  206. {
  207. int len = _vsnprintf(0, 0, format, args);
  208. if (len < 0)
  209. return "";
  210. std::vector<char> buffer(len + 1);
  211. len = _vsnprintf(&buffer[0], len, format, args);
  212. if (len < 0)
  213. return "";
  214. buffer[len] = '\0';
  215. return &buffer[0];
  216. }
  217. #ifdef __cpp_char8_t
  218. static inline std::u8string vformat(const char8_t *format, va_list args)
  219. {
  220. int len = _vsnprintf(0, 0, (const char *)format, args);
  221. if (len < 0)
  222. return u8"";
  223. std::vector<char> buffer(len + 1);
  224. len = _vsnprintf(&buffer[0], len, (const char *)format, args);
  225. if (len < 0)
  226. return u8"";
  227. buffer[len] = '\0';
  228. return (char8_t *)&buffer[0];
  229. }
  230. #endif
  231. #if defined(_MSC_VER)
  232. #pragma warning(pop)
  233. #endif
  234. static inline std::wstring format(const wchar_t *format, ...)
  235. {
  236. va_list args;
  237. va_start(args, format);
  238. std::wstring s = vformat(format, args);
  239. va_end(args);
  240. return s;
  241. }
  242. static inline std::string format(const char *format, ...)
  243. {
  244. va_list args;
  245. va_start(args, format);
  246. std::string s = vformat(format, args);
  247. va_end(args);
  248. return s;
  249. }
  250. #ifdef __cpp_char8_t
  251. static inline std::u8string format(const char8_t *format, ...)
  252. {
  253. va_list args;
  254. va_start(args, format);
  255. std::u8string s = vformat(format, args);
  256. va_end(args);
  257. return s;
  258. }
  259. #endif
  260. static inline void format(std::ostream &ostrm, const wchar_t *format, ...)
  261. {
  262. va_list args;
  263. va_start(args, format);
  264. std::wstring s = vformat(format, args);
  265. va_end(args);
  266. ostrm << wide_to_utf8(s) << std::flush;
  267. }
  268. static inline void format(std::ostream &ostrm, const char *format, ...)
  269. {
  270. va_list args;
  271. va_start(args, format);
  272. std::string s = vformat(format, args);
  273. va_end(args);
  274. ostrm << s << std::flush;
  275. }
  276. #ifdef __cpp_char8_t
  277. static inline void format(std::ostream &ostrm, const char8_t *format, ...)
  278. {
  279. va_list args;
  280. va_start(args, format);
  281. std::u8string s = vformat(format, args);
  282. va_end(args);
  283. ostrm << char8_to_utf8(s) << std::flush;
  284. }
  285. #endif
  286. static inline std::string formatA(const wchar_t *format, ...)
  287. {
  288. va_list args;
  289. va_start(args, format);
  290. std::wstring s = vformat(format, args);
  291. va_end(args);
  292. return wide_to_ansi(s);
  293. }
  294. static inline std::string formatA(const char *format, ...)
  295. {
  296. va_list args;
  297. va_start(args, format);
  298. std::string s = vformat(format, args);
  299. va_end(args);
  300. return utf8_to_ansi(s);
  301. }
  302. #ifdef __cpp_char8_t
  303. static inline std::string formatA(const char8_t *format, ...)
  304. {
  305. va_list args;
  306. va_start(args, format);
  307. std::u8string s = vformat(format, args);
  308. va_end(args);
  309. return char8_to_ansi(s);
  310. }
  311. #endif
  312. static inline void formatA(std::ostream &ostrm, const wchar_t *format, ...)
  313. {
  314. va_list args;
  315. va_start(args, format);
  316. std::wstring s = vformat(format, args);
  317. va_end(args);
  318. ostrm << wide_to_ansi(s) << std::flush;
  319. }
  320. static inline void formatA(std::ostream &ostrm, const char *format, ...)
  321. {
  322. va_list args;
  323. va_start(args, format);
  324. std::string s = vformat(format, args);
  325. va_end(args);
  326. ostrm << utf8_to_ansi(s) << std::flush;
  327. }
  328. #ifdef __cpp_char8_t
  329. static inline void formatA(std::ostream &ostrm, const char8_t *format, ...)
  330. {
  331. va_list args;
  332. va_start(args, format);
  333. std::u8string s = vformat(format, args);
  334. va_end(args);
  335. ostrm << char8_to_ansi(s) << std::flush;
  336. }
  337. #endif
  338. static inline void dbgmsg(const wchar_t *title, const wchar_t *format, ...)
  339. {
  340. va_list args;
  341. va_start(args, format);
  342. std::wstring s = vformat(format, args);
  343. va_end(args);
  344. MessageBoxW(0, s.c_str(), title, MB_OK);
  345. }
  346. static inline void dbgmsg(const char *title, const char *format, ...)
  347. {
  348. va_list args;
  349. va_start(args, format);
  350. std::string s = vformat(format, args);
  351. va_end(args);
  352. MessageBoxW(0, utf8_to_wide(s).c_str(), utf8_to_wide(title).c_str(), MB_OK);
  353. }
  354. #ifdef __cpp_char8_t
  355. static inline void dbgmsg(const char8_t *title, const char8_t *format, ...)
  356. {
  357. va_list args;
  358. va_start(args, format);
  359. std::u8string s = vformat(format, args);
  360. va_end(args);
  361. MessageBoxW(0, char8_to_wide(s).c_str(), char8_to_wide(title).c_str(), MB_OK);
  362. }
  363. #endif
  364. static inline HANDLE handle_for_ostream(std::ostream &ostrm)
  365. {
  366. if (&ostrm == &std::cout)
  367. {
  368. return GetStdHandle(STD_OUTPUT_HANDLE);
  369. }
  370. else if (&ostrm == &std::cerr)
  371. {
  372. return GetStdHandle(STD_ERROR_HANDLE);
  373. }
  374. return INVALID_HANDLE_VALUE;
  375. }
  376. static inline void dbgout(std::ostream &ostrm, const wchar_t *format, ...)
  377. {
  378. va_list args;
  379. va_start(args, format);
  380. std::wstring ws = vformat(format, args);
  381. va_end(args);
  382. HANDLE h = handle_for_ostream(ostrm);
  383. if (h == INVALID_HANDLE_VALUE)
  384. {
  385. return;
  386. }
  387. DWORD dwNumberOfCharsWrite;
  388. if (GetFileType(h) != FILE_TYPE_CHAR)
  389. {
  390. std::string s = wide_to_cp(ws, GetConsoleOutputCP());
  391. WriteFile(h, s.c_str(), (DWORD)s.size(), &dwNumberOfCharsWrite, NULL);
  392. }
  393. else
  394. {
  395. WriteConsoleW(h,
  396. ws.c_str(),
  397. (DWORD)ws.size(),
  398. &dwNumberOfCharsWrite,
  399. NULL);
  400. }
  401. }
  402. static inline void dbgout(std::ostream &ostrm, const char *format, ...)
  403. {
  404. va_list args;
  405. va_start(args, format);
  406. std::string s = vformat(format, args);
  407. va_end(args);
  408. HANDLE h = handle_for_ostream(ostrm);
  409. if (h == INVALID_HANDLE_VALUE)
  410. {
  411. return;
  412. }
  413. DWORD dwNumberOfCharsWrite;
  414. if (GetFileType(h) != FILE_TYPE_CHAR)
  415. {
  416. s = utf8_to_cp(s, GetConsoleOutputCP());
  417. WriteFile(h, s.c_str(), (DWORD)s.size(), &dwNumberOfCharsWrite, NULL);
  418. }
  419. else
  420. {
  421. std::wstring ws = utf8_to_wide(s);
  422. WriteConsoleW(h,
  423. ws.c_str(),
  424. (DWORD)ws.size(),
  425. &dwNumberOfCharsWrite,
  426. NULL);
  427. }
  428. }
  429. #ifdef __cpp_char8_t
  430. static inline void dbgout(std::ostream &ostrm, const char8_t *format, ...)
  431. {
  432. va_list args;
  433. va_start(args, format);
  434. std::u8string s = vformat(format, args);
  435. va_end(args);
  436. HANDLE h = handle_for_ostream(ostrm);
  437. if (h == INVALID_HANDLE_VALUE)
  438. {
  439. return;
  440. }
  441. DWORD dwNumberOfCharsWrite;
  442. if (GetFileType(h) != FILE_TYPE_CHAR)
  443. {
  444. std::string str = char8_to_cp(s, GetConsoleOutputCP());
  445. WriteFile(h, (const char *)str.c_str(), (DWORD)str.size(), &dwNumberOfCharsWrite, NULL);
  446. }
  447. else
  448. {
  449. std::wstring ws = char8_to_wide(s);
  450. WriteConsoleW(h,
  451. ws.c_str(),
  452. (DWORD)ws.size(),
  453. &dwNumberOfCharsWrite,
  454. NULL);
  455. }
  456. }
  457. #endif
  458. class unicode_ostream
  459. {
  460. private:
  461. std::ostream *m_ostrm;
  462. UINT m_target_cp;
  463. bool is_ascii(const std::string &s)
  464. {
  465. for (std::size_t i = 0; i < s.size(); i++)
  466. {
  467. unsigned char c = (unsigned char)s[i];
  468. if (c > 0x7f)
  469. return false;
  470. }
  471. return true;
  472. }
  473. public:
  474. unicode_ostream(std::ostream &ostrm, UINT target_cp = CP_ACP) : m_ostrm(&ostrm), m_target_cp(target_cp) {}
  475. std::ostream &stream() { return *m_ostrm; }
  476. void stream(std::ostream &ostrm) { m_ostrm = &ostrm; }
  477. UINT target_cp() { return m_target_cp; }
  478. void target_cp(UINT cp) { m_target_cp = cp; }
  479. template <typename T>
  480. unicode_ostream &operator<<(const T &x)
  481. {
  482. std::ostringstream oss;
  483. oss << x;
  484. std::string output = oss.str();
  485. if (is_ascii(output))
  486. {
  487. (*m_ostrm) << x;
  488. }
  489. else
  490. {
  491. (*m_ostrm) << utf8_to_cp(output, m_target_cp);
  492. }
  493. return *this;
  494. }
  495. unicode_ostream &operator<<(const std::wstring &x)
  496. {
  497. (*m_ostrm) << wide_to_cp(x, m_target_cp);
  498. return *this;
  499. }
  500. unicode_ostream &operator<<(const wchar_t *x)
  501. {
  502. (*m_ostrm) << wide_to_cp(x, m_target_cp);
  503. return *this;
  504. }
  505. unicode_ostream &operator<<(const std::string &x)
  506. {
  507. (*m_ostrm) << utf8_to_cp(x, m_target_cp);
  508. return *this;
  509. }
  510. unicode_ostream &operator<<(const char *x)
  511. {
  512. (*m_ostrm) << utf8_to_cp(x, m_target_cp);
  513. return *this;
  514. }
  515. #ifdef __cpp_char8_t
  516. unicode_ostream &operator<<(const std::u8string &x)
  517. {
  518. (*m_ostrm) << char8_to_cp(x, m_target_cp);
  519. return *this;
  520. }
  521. unicode_ostream &operator<<(const char8_t *x)
  522. {
  523. (*m_ostrm) << char8_to_cp(x, m_target_cp);
  524. return *this;
  525. }
  526. #endif
  527. unicode_ostream &operator<<(std::ostream &(*pf)(std::ostream &)) // For manipulators...
  528. {
  529. (*m_ostrm) << pf;
  530. return *this;
  531. }
  532. unicode_ostream &operator<<(std::basic_ios<char> &(*pf)(std::basic_ios<char> &)) // For manipulators...
  533. {
  534. (*m_ostrm) << pf;
  535. return *this;
  536. }
  537. };
  538. #define U8(X) ((const char *)u8##X)
  539. #define WIDE(X) (L##X)
  540. #endif /* STRCONV_H */