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 <boost/process/detail/traits/decl.hpp> 11 #include <boost/process/detail/traits/cmd_or_exe.hpp> 12 #include <boost/process/detail/traits/env.hpp> 13 #include <boost/process/locale.hpp> 14 15 namespace boost { namespace process { namespace detail { 16 17 //template 18 19 template<typename T> struct is_wchar_t : std::false_type {}; 20 21 template<> struct is_wchar_t<boost::filesystem::path> : std::is_same<typename boost::filesystem::path::value_type, wchar_t> 22 { 23 }; 24 25 template<> struct is_wchar_t<const wchar_t* > : std::true_type {}; 26 27 template<> struct is_wchar_t<wchar_t* > : std::true_type {}; 28 29 template<std::size_t Size> struct is_wchar_t<const wchar_t [Size]> : std::true_type {}; 30 template<std::size_t Size> struct is_wchar_t<const wchar_t (&)[Size]> : std::true_type {}; 31 32 template<> struct is_wchar_t<std::wstring> : std::true_type {}; 33 template<> struct is_wchar_t<std::vector<std::wstring>> : std::true_type {}; 34 template<> struct is_wchar_t<std::initializer_list<std::wstring>> : std::true_type {}; 35 template<> struct is_wchar_t<std::vector<wchar_t *>> : std::true_type {}; 36 template<> struct is_wchar_t<std::initializer_list<wchar_t *>> : std::true_type {}; 37 38 39 40 template<typename Char, typename T> 41 struct char_converter 42 { convboost::process::detail::char_converter43 static T& conv(T & in) 44 { 45 return in; 46 } convboost::process::detail::char_converter47 static T&& conv(T&& in) 48 { 49 return std::move(in); 50 } convboost::process::detail::char_converter51 static const T& conv(const T & in) 52 { 53 return in; 54 } 55 }; 56 57 template<typename Char, typename T> 58 using char_converter_t = char_converter<Char, 59 typename std::remove_cv<typename std::remove_reference<T>::type>::type>; 60 61 62 template<> 63 struct char_converter<char, const wchar_t*> 64 { convboost::process::detail::char_converter65 static std::string conv(const wchar_t* in) 66 { 67 std::size_t size = 0; 68 while (in[size] != L'\0') size++; 69 return ::boost::process::detail::convert(in, in + size); 70 } 71 }; 72 73 template<> 74 struct char_converter<char, wchar_t*> 75 { convboost::process::detail::char_converter76 static std::string conv(wchar_t* in) 77 { 78 std::size_t size = 0; 79 while (in[size] != L'\0') size++; 80 return ::boost::process::detail::convert(in, in + size); 81 } 82 }; 83 84 template<std::size_t Size> 85 struct char_converter<char, wchar_t[Size]> 86 { convboost::process::detail::char_converter87 static std::string conv(const wchar_t(&in)[Size]) 88 { 89 return ::boost::process::detail::convert(in, in + Size -1); 90 } 91 }; 92 93 template<> 94 struct char_converter<wchar_t, const char*> 95 { convboost::process::detail::char_converter96 static std::wstring conv(const char* in) 97 { 98 std::size_t size = 0; 99 while (in[size] != '\0') size++; 100 return ::boost::process::detail::convert(in, in + size); 101 } 102 }; 103 104 template<> 105 struct char_converter<wchar_t, char*> 106 { convboost::process::detail::char_converter107 static std::wstring conv(char* in) 108 { 109 std::size_t size = 0; 110 while (in[size] != '\0') size++; 111 return ::boost::process::detail::convert(in, in + size); 112 } 113 }; 114 115 116 template<std::size_t Size> 117 struct char_converter<wchar_t, char[Size]> 118 { convboost::process::detail::char_converter119 static std::wstring conv(const char(&in)[Size]) 120 { 121 return ::boost::process::detail::convert(in, in + Size -1); 122 } 123 }; 124 125 //all the containers. 126 template<> 127 struct char_converter<wchar_t, std::string> 128 { convboost::process::detail::char_converter129 static std::wstring conv(const std::string & in) 130 { 131 return ::boost::process::detail::convert(in); 132 } 133 }; 134 135 template<> 136 struct char_converter<char, std::wstring> 137 { convboost::process::detail::char_converter138 static std::string conv(const std::wstring & in) 139 { 140 return ::boost::process::detail::convert(in); 141 } 142 }; 143 144 template<> 145 struct char_converter<wchar_t, std::vector<std::string>> 146 { convboost::process::detail::char_converter147 static std::vector<std::wstring> conv(const std::vector<std::string> & in) 148 { 149 std::vector<std::wstring> ret(in.size()); 150 std::transform(in.begin(), in.end(), ret.begin(), 151 [](const std::string & st) 152 { 153 return convert(st); 154 }); 155 return ret; 156 } 157 }; 158 159 template<> 160 struct char_converter<wchar_t, std::initializer_list<std::string>> 161 { convboost::process::detail::char_converter162 static std::vector<std::wstring> conv(const std::initializer_list<std::string> & in) 163 { 164 std::vector<std::wstring> ret(in.size()); 165 std::transform(in.begin(), in.end(), ret.begin(), 166 [](const std::string & st) 167 { 168 return convert(st); 169 }); 170 return ret; 171 } 172 }; 173 174 template<> 175 struct char_converter<wchar_t, std::vector<char* >> 176 { convboost::process::detail::char_converter177 static std::vector<std::wstring> conv(const std::vector<char* > & in) 178 { 179 std::vector<std::wstring> ret(in.size()); 180 std::transform(in.begin(), in.end(), ret.begin(), 181 [](const char* st) 182 { 183 std::size_t sz = 0; 184 while (st[sz] != '\0') sz++; 185 return convert(st, st + sz); 186 }); 187 return ret; 188 } 189 }; 190 191 template<> 192 struct char_converter<wchar_t, std::initializer_list<char *>> 193 { convboost::process::detail::char_converter194 static std::vector<std::wstring> conv(const std::initializer_list<char * > & in) 195 { 196 std::vector<std::wstring> ret(in.size()); 197 std::transform(in.begin(), in.end(), ret.begin(), 198 [](const char* st) 199 { 200 std::size_t sz = 0; 201 while (st[sz] != '\0') sz++; 202 return convert(st, st + sz); 203 }); 204 return ret; 205 } 206 }; 207 208 template<> 209 struct char_converter<char, std::vector<std::wstring>> 210 { convboost::process::detail::char_converter211 static std::vector<std::string> conv(const std::vector<std::wstring> & in) 212 { 213 std::vector<std::string> ret(in.size()); 214 std::transform(in.begin(), in.end(), ret.begin(), 215 [](const std::wstring & st) 216 { 217 return convert(st); 218 }); 219 return ret; 220 } 221 }; 222 223 template<> 224 struct char_converter<char, std::initializer_list<std::wstring>> 225 { convboost::process::detail::char_converter226 static std::vector<std::string> conv(const std::initializer_list<std::wstring> & in) 227 { 228 std::vector<std::string> ret(in.size()); 229 std::transform(in.begin(), in.end(), ret.begin(), 230 [](const std::wstring & st) 231 { 232 return convert(st); 233 }); 234 return ret; 235 } 236 }; 237 238 template<> 239 struct char_converter<char, std::vector<wchar_t* >> 240 { convboost::process::detail::char_converter241 static std::vector<std::string> conv(const std::vector<wchar_t* > & in) 242 { 243 std::vector<std::string> ret(in.size()); 244 std::transform(in.begin(), in.end(), ret.begin(), 245 [](const wchar_t* st) 246 { 247 std::size_t sz = 0; 248 while (st[sz] != L'\0') sz++; 249 return convert(st, st + sz); 250 }); 251 return ret; 252 } 253 }; 254 255 template<> 256 struct char_converter<char, std::initializer_list<wchar_t * >> 257 { convboost::process::detail::char_converter258 static std::vector<std::string> conv(const std::initializer_list<wchar_t *> & in) 259 { 260 std::vector<std::string> ret(in.size()); 261 std::transform(in.begin(), in.end(), ret.begin(), 262 [](const wchar_t* st) 263 { 264 std::size_t sz = 0; 265 while (st[sz] != L'\0') sz++; 266 return convert(st, st + sz); 267 }); 268 return ret; 269 } 270 }; 271 272 273 }}} 274 #endif /* BOOST_PROCESS_DETAIL_TRAITS_WCHAR_T_HPP_ */ 275