Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-01-08 10:09:17

0001 // Copyright (c) 2017-2025, University of Cincinnati, developed by Henry Schreiner
0002 // under NSF AWARD 1414736 and by the respective contributors.
0003 // All rights reserved.
0004 //
0005 // SPDX-License-Identifier: BSD-3-Clause
0006 
0007 #pragma once
0008 
0009 // IWYU pragma: private, include "CLI/CLI.hpp"
0010 
0011 // This include is only needed for IDEs to discover symbols
0012 #include "../Encoding.hpp"
0013 #include "../Macros.hpp"
0014 
0015 // [CLI11:public_includes:set]
0016 #include <array>
0017 #include <clocale>
0018 #include <cstdlib>
0019 #include <cstring>
0020 #include <cwchar>
0021 #include <locale>
0022 #include <stdexcept>
0023 #include <string>
0024 #include <type_traits>
0025 #include <utility>
0026 // [CLI11:public_includes:end]
0027 
0028 namespace CLI {
0029 // [CLI11:encoding_inl_hpp:verbatim]
0030 
0031 namespace detail {
0032 
0033 #if !CLI11_HAS_CODECVT
0034 /// Attempt to set one of the acceptable unicode locales for conversion
0035 CLI11_INLINE void set_unicode_locale() {
0036     static const std::array<const char *, 3> unicode_locales{{"C.UTF-8", "en_US.UTF-8", ".UTF-8"}};
0037 
0038     for(const auto &locale_name : unicode_locales) {
0039         if(std::setlocale(LC_ALL, locale_name) != nullptr) {
0040             return;
0041         }
0042     }
0043     throw std::runtime_error("CLI::narrow: could not set locale to C.UTF-8");
0044 }
0045 
0046 template <typename F> struct scope_guard_t {
0047     F closure;
0048 
0049     explicit scope_guard_t(F closure_) : closure(closure_) {}
0050     ~scope_guard_t() { closure(); }
0051 };
0052 
0053 template <typename F> CLI11_NODISCARD CLI11_INLINE scope_guard_t<F> scope_guard(F &&closure) {
0054     return scope_guard_t<F>{std::forward<F>(closure)};
0055 }
0056 
0057 #endif  // !CLI11_HAS_CODECVT
0058 
0059 CLI11_DIAGNOSTIC_PUSH
0060 CLI11_DIAGNOSTIC_IGNORE_DEPRECATED
0061 
0062 CLI11_INLINE std::string narrow_impl(const wchar_t *str, std::size_t str_size) {
0063 #if CLI11_HAS_CODECVT
0064 #ifdef _WIN32
0065     return std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>>().to_bytes(str, str + str_size);
0066 
0067 #else
0068     return std::wstring_convert<std::codecvt_utf8<wchar_t>>().to_bytes(str, str + str_size);
0069 
0070 #endif  // _WIN32
0071 #else   // CLI11_HAS_CODECVT
0072     (void)str_size;
0073     std::mbstate_t state = std::mbstate_t();
0074     const wchar_t *it = str;
0075 
0076     std::string old_locale = std::setlocale(LC_ALL, nullptr);
0077     auto sg = scope_guard([&] { std::setlocale(LC_ALL, old_locale.c_str()); });
0078     set_unicode_locale();
0079 
0080     std::size_t new_size = std::wcsrtombs(nullptr, &it, 0, &state);
0081     if(new_size == static_cast<std::size_t>(-1)) {
0082         throw std::runtime_error("CLI::narrow: conversion error in std::wcsrtombs at offset " +
0083                                  std::to_string(it - str));
0084     }
0085     std::string result(new_size, '\0');
0086     std::wcsrtombs(const_cast<char *>(result.data()), &str, new_size, &state);
0087 
0088     return result;
0089 
0090 #endif  // CLI11_HAS_CODECVT
0091 }
0092 
0093 CLI11_INLINE std::wstring widen_impl(const char *str, std::size_t str_size) {
0094 #if CLI11_HAS_CODECVT
0095 #ifdef _WIN32
0096     return std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>>().from_bytes(str, str + str_size);
0097 
0098 #else
0099     return std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes(str, str + str_size);
0100 
0101 #endif  // _WIN32
0102 #else   // CLI11_HAS_CODECVT
0103     (void)str_size;
0104     std::mbstate_t state = std::mbstate_t();
0105     const char *it = str;
0106 
0107     std::string old_locale = std::setlocale(LC_ALL, nullptr);
0108     auto sg = scope_guard([&] { std::setlocale(LC_ALL, old_locale.c_str()); });
0109     set_unicode_locale();
0110 
0111     std::size_t new_size = std::mbsrtowcs(nullptr, &it, 0, &state);
0112     if(new_size == static_cast<std::size_t>(-1)) {
0113         throw std::runtime_error("CLI::widen: conversion error in std::mbsrtowcs at offset " +
0114                                  std::to_string(it - str));
0115     }
0116     std::wstring result(new_size, L'\0');
0117     std::mbsrtowcs(const_cast<wchar_t *>(result.data()), &str, new_size, &state);
0118 
0119     return result;
0120 
0121 #endif  // CLI11_HAS_CODECVT
0122 }
0123 
0124 CLI11_DIAGNOSTIC_POP
0125 
0126 }  // namespace detail
0127 
0128 CLI11_INLINE std::string narrow(const wchar_t *str, std::size_t str_size) { return detail::narrow_impl(str, str_size); }
0129 CLI11_INLINE std::string narrow(const std::wstring &str) { return detail::narrow_impl(str.data(), str.size()); }
0130 // Flawfinder: ignore
0131 CLI11_INLINE std::string narrow(const wchar_t *str) { return detail::narrow_impl(str, std::wcslen(str)); }
0132 
0133 CLI11_INLINE std::wstring widen(const char *str, std::size_t str_size) { return detail::widen_impl(str, str_size); }
0134 CLI11_INLINE std::wstring widen(const std::string &str) { return detail::widen_impl(str.data(), str.size()); }
0135 // Flawfinder: ignore
0136 CLI11_INLINE std::wstring widen(const char *str) { return detail::widen_impl(str, std::strlen(str)); }
0137 
0138 #ifdef CLI11_CPP17
0139 CLI11_INLINE std::string narrow(std::wstring_view str) { return detail::narrow_impl(str.data(), str.size()); }
0140 CLI11_INLINE std::wstring widen(std::string_view str) { return detail::widen_impl(str.data(), str.size()); }
0141 #endif  // CLI11_CPP17
0142 
0143 #if defined CLI11_HAS_FILESYSTEM && CLI11_HAS_FILESYSTEM > 0
0144 CLI11_INLINE std::filesystem::path to_path(std::string_view str) {
0145     return std::filesystem::path{
0146 #ifdef _WIN32
0147         widen(str)
0148 #else
0149         str
0150 #endif  // _WIN32
0151     };
0152 }
0153 #endif  // CLI11_HAS_FILESYSTEM
0154 
0155 // [CLI11:encoding_inl_hpp:end]
0156 }  // namespace CLI