| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 | // Copyright (c) 2016 Klemens D. Morgenstern// Copyright (c) 2008 Beman Dawes// Distributed under the Boost Software License, Version 1.0. (See accompanying// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)#ifndef BOOST_PROCESS_LOCALE_HPP_#define BOOST_PROCESS_LOCALE_HPP_#include <system_error>#include <boost/process/detail/config.hpp>#if defined(BOOST_WINDOWS_API)#include <boost/process/detail/windows/locale.hpp># elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) \|| defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__HAIKU__)#include <codecvt>#endif#include <locale>namespace boost{namespace process{namespace detail{class codecvt_category_t : public std::error_category{public:    codecvt_category_t(){}    const char* name() const noexcept override {return "codecvt";}    std::string message(int ev) const override    {        std::string str;        switch (ev)        {        case std::codecvt_base::ok:            str = "ok";            break;        case std::codecvt_base::partial:            str = "partial";            break;        case std::codecvt_base::error:            str = "error";            break;        case std::codecvt_base::noconv:            str = "noconv";            break;        default:            str = "unknown error";        }        return str;    }};}///Internally used error cateory for code conversion.inline const std::error_category& codecvt_category(){    static const ::boost::process::detail::codecvt_category_t cat;    return cat;}namespace detail{//copied from boost.filesysteminline std::locale default_locale(){# if defined(BOOST_WINDOWS_API)    std::locale global_loc = std::locale();    return std::locale(global_loc, new boost::process::detail::windows::windows_file_codecvt);# elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) \|| defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__HAIKU__)    std::locale global_loc = std::locale();    return std::locale(global_loc, new std::codecvt_utf8<wchar_t>);# else  // Other POSIX    // ISO C calls std::locale("") "the locale-specific native environment", and this    // locale is the default for many POSIX-based operating systems such as Linux.    return std::locale("");# endif}inline std::locale& process_locale(){    static std::locale loc(default_locale());    return loc;}}///The internally used type for code conversion.typedef std::codecvt<wchar_t, char, std::mbstate_t> codecvt_type;///Get a reference to the currently used code converter.inline const codecvt_type& codecvt(){  return std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t>>(                detail::process_locale());}///Set the locale of the library.inline std::locale imbue(const std::locale& loc){  std::locale temp(detail::process_locale());  detail::process_locale() = loc;  return temp;}namespace detail{inline std::size_t convert(const char* from,                    const char* from_end,                    wchar_t* to, wchar_t* to_end,                    const ::boost::process::codecvt_type & cvt =                                 ::boost::process::codecvt()){    std::mbstate_t state  = std::mbstate_t();  // perhaps unneeded, but cuts bug reports    const char* from_next;    wchar_t* to_next;    auto res = cvt.in(state, from, from_end, from_next,                 to, to_end, to_next);    if (res != std::codecvt_base::ok)         throw process_error(res, ::boost::process::codecvt_category(),             "boost::process codecvt to wchar_t");    return to_next - to;}inline std::size_t convert(const wchar_t* from,                    const wchar_t* from_end,                    char* to, char* to_end,                    const ::boost::process::codecvt_type & cvt =                                 ::boost::process::codecvt()){    std::mbstate_t state  = std::mbstate_t();  // perhaps unneeded, but cuts bug reports    const wchar_t* from_next;    char* to_next;    std::codecvt_base::result res;    if ((res=cvt.out(state, from, from_end, from_next,           to, to_end, to_next)) != std::codecvt_base::ok)               throw process_error(res, ::boost::process::codecvt_category(),                   "boost::process codecvt to char");    return to_next - to;}inline std::wstring convert(const std::string & st,                            const ::boost::process::codecvt_type & cvt =                                ::boost::process::codecvt()){    std::wstring out(st.size() + 10, ' '); //just to be sure    auto sz = convert(st.c_str(), st.c_str() + st.size(),                      &out.front(), &out.back(), cvt);    out.resize(sz);    return out;}inline std::string convert(const std::wstring & st,                           const ::boost::process::codecvt_type & cvt =                                ::boost::process::codecvt()){    std::string out(st.size() * 2, ' '); //just to be sure    auto sz = convert(st.c_str(), st.c_str() + st.size(),                      &out.front(), &out.back(), cvt);    out.resize(sz);    return out;}inline std::vector<wchar_t> convert(const std::vector<char> & st,                                    const ::boost::process::codecvt_type & cvt =                                        ::boost::process::codecvt()){    std::vector<wchar_t> out(st.size() + 10); //just to be sure    auto sz = convert(st.data(), st.data() + st.size(),                      &out.front(), &out.back(), cvt);    out.resize(sz);    return out;}inline std::vector<char> convert(const std::vector<wchar_t> & st,                                 const ::boost::process::codecvt_type & cvt =                                     ::boost::process::codecvt()){    std::vector<char> out(st.size() * 2); //just to be sure    auto sz = convert(st.data(), st.data() + st.size(),                      &out.front(), &out.back(), cvt);    out.resize(sz);    return out;}inline std::wstring convert(const char *begin, const char* end,                            const ::boost::process::codecvt_type & cvt =                                ::boost::process::codecvt()){    auto size = end-begin;    std::wstring out(size + 10, ' '); //just to be sure    using namespace std;    auto sz = convert(begin, end,                      &out.front(), &out.back(), cvt);    out.resize(sz);    return out;}inline std::string convert(const wchar_t  * begin, const wchar_t *end,                           const ::boost::process::codecvt_type & cvt =                                ::boost::process::codecvt()){    auto size = end-begin;    std::string out(size * 2, ' '); //just to be sure    auto sz = convert(begin, end ,                      &out.front(), &out.back(), cvt);    out.resize(sz);    return out;}}}}#endif /* BOOST_PROCESS_LOCALE_HPP_ */
 |