1 // Copyright (c) 2016 Klemens D. Morgenstern 2 // 3 // Distributed under the Boost Software License, Version 1.0. (See accompanying 4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 5 6 7 #ifndef BOOST_PROCESS_DETAIL_TRAITS_WCHAR_T_HPP_ 8 #define BOOST_PROCESS_DETAIL_TRAITS_WCHAR_T_HPP_ 9 10 #include <algorithm> 11 12 #include <boost/process/detail/traits/decl.hpp> 13 #include <boost/process/detail/traits/cmd_or_exe.hpp> 14 #include <boost/process/detail/traits/env.hpp> 15 #include <boost/process/locale.hpp> 16 17 namespace boost { namespace process { namespace detail { 18 19 //template 20 21 template<typename T> struct is_wchar_t : std::false_type {}; 22 23 template<> struct is_wchar_t<boost::filesystem::path> : std::is_same<typename boost::filesystem::path::value_type, wchar_t> 24 { 25 }; 26 27 template<> struct is_wchar_t<const wchar_t* > : std::true_type {}; 28 29 template<> struct is_wchar_t<wchar_t* > : std::true_type {}; 30 31 template<std::size_t Size> struct is_wchar_t<const wchar_t [Size]> : std::true_type {}; 32 template<std::size_t Size> struct is_wchar_t<const wchar_t (&)[Size]> : std::true_type {}; 33 34 template<> struct is_wchar_t<std::wstring> : std::true_type {}; 35 template<> struct is_wchar_t<std::vector<std::wstring>> : std::true_type {}; 36 template<> struct is_wchar_t<std::initializer_list<std::wstring>> : std::true_type {}; 37 template<> struct is_wchar_t<std::vector<wchar_t *>> : std::true_type {}; 38 template<> struct is_wchar_t<std::initializer_list<wchar_t *>> : std::true_type {}; 39 40 41 42 template<typename Char, typename T> 43 struct char_converter 44 { convboost::process::detail::char_converter45 static T& conv(T & in) 46 { 47 return in; 48 } convboost::process::detail::char_converter49 static T&& conv(T&& in) 50 { 51 return std::move(in); 52 } convboost::process::detail::char_converter53 static const T& conv(const T & in) 54 { 55 return in; 56 } 57 }; 58 59 template<typename Char, typename T> 60 using char_converter_t = char_converter<Char, 61 typename std::remove_cv<typename std::remove_reference<T>::type>::type>; 62 63 64 template<> 65 struct char_converter<char, const wchar_t*> 66 { convboost::process::detail::char_converter67 static std::string conv(const wchar_t* in) 68 { 69 std::size_t size = 0; 70 while (in[size] != L'\0') size++; 71 return ::boost::process::detail::convert(in, in + size); 72 } 73 }; 74 75 template<> 76 struct char_converter<char, wchar_t*> 77 { convboost::process::detail::char_converter78 static std::string conv(wchar_t* in) 79 { 80 std::size_t size = 0; 81 while (in[size] != L'\0') size++; 82 return ::boost::process::detail::convert(in, in + size); 83 } 84 }; 85 86 template<std::size_t Size> 87 struct char_converter<char, wchar_t[Size]> 88 { convboost::process::detail::char_converter89 static std::string conv(const wchar_t(&in)[Size]) 90 { 91 return ::boost::process::detail::convert(in, in + Size -1); 92 } 93 }; 94 95 template<> 96 struct char_converter<wchar_t, const char*> 97 { convboost::process::detail::char_converter98 static std::wstring conv(const char* in) 99 { 100 std::size_t size = 0; 101 while (in[size] != '\0') size++; 102 return ::boost::process::detail::convert(in, in + size); 103 } 104 }; 105 106 template<> 107 struct char_converter<wchar_t, char*> 108 { convboost::process::detail::char_converter109 static std::wstring conv(char* in) 110 { 111 std::size_t size = 0; 112 while (in[size] != '\0') size++; 113 return ::boost::process::detail::convert(in, in + size); 114 } 115 }; 116 117 118 template<std::size_t Size> 119 struct char_converter<wchar_t, char[Size]> 120 { convboost::process::detail::char_converter121 static std::wstring conv(const char(&in)[Size]) 122 { 123 return ::boost::process::detail::convert(in, in + Size -1); 124 } 125 }; 126 127 //all the containers. 128 template<> 129 struct char_converter<wchar_t, std::string> 130 { convboost::process::detail::char_converter131 static std::wstring conv(const std::string & in) 132 { 133 return ::boost::process::detail::convert(in); 134 } 135 }; 136 137 template<> 138 struct char_converter<char, std::wstring> 139 { convboost::process::detail::char_converter140 static std::string conv(const std::wstring & in) 141 { 142 return ::boost::process::detail::convert(in); 143 } 144 }; 145 146 template<> 147 struct char_converter<wchar_t, std::vector<std::string>> 148 { convboost::process::detail::char_converter149 static std::vector<std::wstring> conv(const std::vector<std::string> & in) 150 { 151 std::vector<std::wstring> ret(in.size()); 152 std::transform(in.begin(), in.end(), ret.begin(), 153 [](const std::string & st) 154 { 155 return convert(st); 156 }); 157 return ret; 158 } 159 }; 160 161 template<> 162 struct char_converter<wchar_t, std::initializer_list<std::string>> 163 { convboost::process::detail::char_converter164 static std::vector<std::wstring> conv(const std::initializer_list<std::string> & in) 165 { 166 std::vector<std::wstring> ret(in.size()); 167 std::transform(in.begin(), in.end(), ret.begin(), 168 [](const std::string & st) 169 { 170 return convert(st); 171 }); 172 return ret; 173 } 174 }; 175 176 template<> 177 struct char_converter<wchar_t, std::vector<char* >> 178 { convboost::process::detail::char_converter179 static std::vector<std::wstring> conv(const std::vector<char* > & in) 180 { 181 std::vector<std::wstring> ret(in.size()); 182 std::transform(in.begin(), in.end(), ret.begin(), 183 [](const char* st) 184 { 185 std::size_t sz = 0; 186 while (st[sz] != '\0') sz++; 187 return convert(st, st + sz); 188 }); 189 return ret; 190 } 191 }; 192 193 template<> 194 struct char_converter<wchar_t, std::initializer_list<char *>> 195 { convboost::process::detail::char_converter196 static std::vector<std::wstring> conv(const std::initializer_list<char * > & in) 197 { 198 std::vector<std::wstring> ret(in.size()); 199 std::transform(in.begin(), in.end(), ret.begin(), 200 [](const char* st) 201 { 202 std::size_t sz = 0; 203 while (st[sz] != '\0') sz++; 204 return convert(st, st + sz); 205 }); 206 return ret; 207 } 208 }; 209 210 template<> 211 struct char_converter<char, std::vector<std::wstring>> 212 { convboost::process::detail::char_converter213 static std::vector<std::string> conv(const std::vector<std::wstring> & in) 214 { 215 std::vector<std::string> ret(in.size()); 216 std::transform(in.begin(), in.end(), ret.begin(), 217 [](const std::wstring & st) 218 { 219 return convert(st); 220 }); 221 return ret; 222 } 223 }; 224 225 template<> 226 struct char_converter<char, std::initializer_list<std::wstring>> 227 { convboost::process::detail::char_converter228 static std::vector<std::string> conv(const std::initializer_list<std::wstring> & in) 229 { 230 std::vector<std::string> ret(in.size()); 231 std::transform(in.begin(), in.end(), ret.begin(), 232 [](const std::wstring & st) 233 { 234 return convert(st); 235 }); 236 return ret; 237 } 238 }; 239 240 template<> 241 struct char_converter<char, std::vector<wchar_t* >> 242 { convboost::process::detail::char_converter243 static std::vector<std::string> conv(const std::vector<wchar_t* > & in) 244 { 245 std::vector<std::string> ret(in.size()); 246 std::transform(in.begin(), in.end(), ret.begin(), 247 [](const wchar_t* st) 248 { 249 std::size_t sz = 0; 250 while (st[sz] != L'\0') sz++; 251 return convert(st, st + sz); 252 }); 253 return ret; 254 } 255 }; 256 257 template<> 258 struct char_converter<char, std::initializer_list<wchar_t * >> 259 { convboost::process::detail::char_converter260 static std::vector<std::string> conv(const std::initializer_list<wchar_t *> & in) 261 { 262 std::vector<std::string> ret(in.size()); 263 std::transform(in.begin(), in.end(), ret.begin(), 264 [](const wchar_t* st) 265 { 266 std::size_t sz = 0; 267 while (st[sz] != L'\0') sz++; 268 return convert(st, st + sz); 269 }); 270 return ret; 271 } 272 }; 273 274 275 }}} 276 #endif /* BOOST_PROCESS_DETAIL_TRAITS_WCHAR_T_HPP_ */ 277