Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:50:14

0001 // Copyright (c) 2016 Klemens D. Morgenstern
0002 // Copyright (c) 2008 Beman Dawes
0003 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0004 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 #ifndef BOOST_PROCESS_LOCALE_HPP_
0007 #define BOOST_PROCESS_LOCALE_HPP_
0008 
0009 #include <system_error>
0010 #include <boost/process/detail/config.hpp>
0011 
0012 #if defined(BOOST_WINDOWS_API)
0013 #include <boost/process/detail/windows/locale.hpp>
0014 # elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) \
0015 || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__HAIKU__)
0016 #include <codecvt>
0017 #endif
0018 
0019 #include <locale>
0020 
0021 namespace boost
0022 {
0023 namespace process
0024 {
0025 namespace detail
0026 {
0027 
0028 class codecvt_category_t : public std::error_category
0029 {
0030 public:
0031     codecvt_category_t() = default;
0032     const char* name() const noexcept override {return "codecvt";}
0033     std::string message(int ev) const override
0034     {
0035         std::string str;
0036         switch (ev)
0037         {
0038         case std::codecvt_base::ok:
0039             str = "ok";
0040             break;
0041         case std::codecvt_base::partial:
0042             str = "partial";
0043             break;
0044         case std::codecvt_base::error:
0045             str = "error";
0046             break;
0047         case std::codecvt_base::noconv:
0048             str = "noconv";
0049             break;
0050         default:
0051             str = "unknown error";
0052         }
0053         return str;
0054     }
0055 };
0056 
0057 }
0058 
0059 ///Internally used error cateory for code conversion.
0060 inline const std::error_category& codecvt_category()
0061 {
0062     static const ::boost::process::detail::codecvt_category_t cat;
0063     return cat;
0064 }
0065 
0066 namespace detail
0067 {
0068 //copied from boost.filesystem
0069 inline std::locale default_locale()
0070 {
0071 # if defined(BOOST_WINDOWS_API)
0072     std::locale global_loc = std::locale();
0073     return std::locale(global_loc, new boost::process::detail::windows::windows_file_codecvt);
0074 # elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) \
0075 || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__HAIKU__)
0076     std::locale global_loc = std::locale();
0077     return std::locale(global_loc, new std::codecvt_utf8<wchar_t>);
0078 # else  // Other POSIX
0079     // Return a default locale object.
0080     return std::locale();
0081 # endif
0082 }
0083 
0084 inline std::locale& process_locale()
0085 {
0086     static std::locale loc(default_locale());
0087     return loc;
0088 }
0089 
0090 }
0091 
0092 ///The internally used type for code conversion.
0093 typedef std::codecvt<wchar_t, char, std::mbstate_t> codecvt_type;
0094 
0095 ///Get a reference to the currently used code converter.
0096 inline const codecvt_type& codecvt()
0097 {
0098   return std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t>>(
0099                 detail::process_locale());
0100 }
0101 
0102 ///Set the locale of the library.
0103 inline std::locale imbue(const std::locale& loc)
0104 {
0105   std::locale temp(detail::process_locale());
0106   detail::process_locale() = loc;
0107   return temp;
0108 }
0109 
0110 
0111 namespace detail
0112 {
0113 
0114 inline std::size_t convert(const char* from,
0115                     const char* from_end,
0116                     wchar_t* to, wchar_t* to_end,
0117                     const ::boost::process::codecvt_type & cvt =
0118                                  ::boost::process::codecvt())
0119 {
0120     std::mbstate_t state  = std::mbstate_t();  // perhaps unneeded, but cuts bug reports
0121     const char* from_next;
0122     wchar_t* to_next;
0123 
0124     auto res = cvt.in(state, from, from_end, from_next,
0125                  to, to_end, to_next);
0126 
0127     if (res != std::codecvt_base::ok)
0128          throw process_error(res, ::boost::process::codecvt_category(),
0129              "boost::process codecvt to wchar_t");
0130 
0131 
0132     return to_next - to;
0133 
0134 }
0135 
0136 inline std::size_t convert(const wchar_t* from,
0137                     const wchar_t* from_end,
0138                     char* to, char* to_end,
0139                     const ::boost::process::codecvt_type & cvt =
0140                                  ::boost::process::codecvt())
0141 {
0142     std::mbstate_t state  = std::mbstate_t();  // perhaps unneeded, but cuts bug reports
0143     const wchar_t* from_next;
0144     char* to_next;
0145 
0146     std::codecvt_base::result res;
0147 
0148     if ((res=cvt.out(state, from, from_end, from_next,
0149            to, to_end, to_next)) != std::codecvt_base::ok)
0150                throw process_error(res, ::boost::process::codecvt_category(),
0151                    "boost::process codecvt to char");
0152 
0153     return to_next - to;
0154 }
0155 
0156 inline std::wstring convert(const std::string & st,
0157                             const ::boost::process::codecvt_type & cvt =
0158                                 ::boost::process::codecvt())
0159 {
0160     std::wstring out(st.size() + 10, ' '); //just to be sure
0161     auto sz = convert(st.c_str(), st.c_str() + st.size(),
0162                       &out.front(), &out.back(), cvt);
0163 
0164     out.resize(sz);
0165     return out;
0166 }
0167 
0168 inline std::string convert(const std::wstring & st,
0169                            const ::boost::process::codecvt_type & cvt =
0170                                 ::boost::process::codecvt())
0171 {
0172     std::string out(st.size() * 2, ' '); //just to be sure
0173     auto sz = convert(st.c_str(), st.c_str() + st.size(),
0174                       &out.front(), &out.back(), cvt);
0175 
0176     out.resize(sz);
0177     return out;
0178 }
0179 
0180 inline std::vector<wchar_t> convert(const std::vector<char> & st,
0181                                     const ::boost::process::codecvt_type & cvt =
0182                                         ::boost::process::codecvt())
0183 {
0184     std::vector<wchar_t> out(st.size() + 10); //just to be sure
0185     auto sz = convert(st.data(), st.data() + st.size(),
0186                       &out.front(), &out.back(), cvt);
0187 
0188     out.resize(sz);
0189     return out;
0190 }
0191 
0192 inline std::vector<char> convert(const std::vector<wchar_t> & st,
0193                                  const ::boost::process::codecvt_type & cvt =
0194                                      ::boost::process::codecvt())
0195 {
0196     std::vector<char> out(st.size() * 2); //just to be sure
0197     auto sz = convert(st.data(), st.data() + st.size(),
0198                       &out.front(), &out.back(), cvt);
0199 
0200     out.resize(sz);
0201     return out;
0202 }
0203 
0204 
0205 inline std::wstring convert(const char *begin, const char* end,
0206                             const ::boost::process::codecvt_type & cvt =
0207                                 ::boost::process::codecvt())
0208 {
0209     auto size = end-begin;
0210     std::wstring out(size + 10, ' '); //just to be sure
0211     using namespace std;
0212     auto sz = convert(begin, end,
0213                       &out.front(), &out.back(), cvt);
0214     out.resize(sz);
0215     return out;
0216 }
0217 
0218 inline std::string convert(const wchar_t  * begin, const wchar_t *end,
0219                            const ::boost::process::codecvt_type & cvt =
0220                                 ::boost::process::codecvt())
0221 {
0222     auto size = end-begin;
0223 
0224     std::string out(size * 2, ' '); //just to be sure
0225     auto sz = convert(begin, end ,
0226                       &out.front(), &out.back(), cvt);
0227 
0228     out.resize(sz);
0229     return out;
0230 }
0231 
0232 
0233 
0234 
0235 }
0236 
0237 
0238 
0239 }
0240 }
0241 
0242 
0243 
0244 
0245 #endif /* BOOST_PROCESS_LOCALE_HPP_ */