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