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