Chris@16
|
1 // filesystem path_traits.hpp --------------------------------------------------------//
|
Chris@16
|
2
|
Chris@16
|
3 // Copyright Beman Dawes 2009
|
Chris@16
|
4
|
Chris@16
|
5 // Distributed under the Boost Software License, Version 1.0.
|
Chris@16
|
6 // See http://www.boost.org/LICENSE_1_0.txt
|
Chris@16
|
7
|
Chris@16
|
8 // Library home page: http://www.boost.org/libs/filesystem
|
Chris@16
|
9
|
Chris@16
|
10 #ifndef BOOST_FILESYSTEM_PATH_TRAITS_HPP
|
Chris@16
|
11 #define BOOST_FILESYSTEM_PATH_TRAITS_HPP
|
Chris@16
|
12
|
Chris@16
|
13 #include <boost/config.hpp>
|
Chris@16
|
14
|
Chris@16
|
15 # if defined( BOOST_NO_STD_WSTRING )
|
Chris@16
|
16 # error Configuration not supported: Boost.Filesystem V3 and later requires std::wstring support
|
Chris@16
|
17 # endif
|
Chris@16
|
18
|
Chris@16
|
19 #include <boost/filesystem/config.hpp>
|
Chris@16
|
20 #include <boost/utility/enable_if.hpp>
|
Chris@16
|
21 #include <boost/type_traits/is_array.hpp>
|
Chris@16
|
22 #include <boost/type_traits/decay.hpp>
|
Chris@16
|
23 #include <boost/system/error_code.hpp>
|
Chris@16
|
24 #include <cwchar> // for mbstate_t
|
Chris@16
|
25 #include <string>
|
Chris@16
|
26 #include <vector>
|
Chris@16
|
27 #include <list>
|
Chris@16
|
28 #include <iterator>
|
Chris@16
|
29 #include <locale>
|
Chris@16
|
30 #include <boost/assert.hpp>
|
Chris@16
|
31 // #include <iostream> //**** comment me out ****
|
Chris@16
|
32
|
Chris@16
|
33 #include <boost/config/abi_prefix.hpp> // must be the last #include
|
Chris@16
|
34
|
Chris@16
|
35 namespace boost { namespace filesystem {
|
Chris@16
|
36
|
Chris@16
|
37 BOOST_FILESYSTEM_DECL const system::error_category& codecvt_error_category();
|
Chris@16
|
38 // uses std::codecvt_base::result used for error codes:
|
Chris@16
|
39 //
|
Chris@16
|
40 // ok: Conversion successful.
|
Chris@16
|
41 // partial: Not all source characters converted; one or more additional source
|
Chris@16
|
42 // characters are needed to produce the final target character, or the
|
Chris@16
|
43 // size of the target intermediate buffer was too small to hold the result.
|
Chris@16
|
44 // error: A character in the source could not be converted to the target encoding.
|
Chris@16
|
45 // noconv: The source and target characters have the same type and encoding, so no
|
Chris@16
|
46 // conversion was necessary.
|
Chris@16
|
47
|
Chris@16
|
48 class directory_entry;
|
Chris@16
|
49
|
Chris@16
|
50 namespace path_traits {
|
Chris@16
|
51
|
Chris@16
|
52 typedef std::codecvt<wchar_t, char, std::mbstate_t> codecvt_type;
|
Chris@16
|
53
|
Chris@16
|
54 // is_pathable type trait; allows disabling over-agressive class path member templates
|
Chris@16
|
55
|
Chris@16
|
56 template <class T>
|
Chris@16
|
57 struct is_pathable { static const bool value = false; };
|
Chris@16
|
58
|
Chris@16
|
59 template<> struct is_pathable<char*> { static const bool value = true; };
|
Chris@16
|
60 template<> struct is_pathable<const char*> { static const bool value = true; };
|
Chris@16
|
61 template<> struct is_pathable<wchar_t*> { static const bool value = true; };
|
Chris@16
|
62 template<> struct is_pathable<const wchar_t*> { static const bool value = true; };
|
Chris@16
|
63 template<> struct is_pathable<std::string> { static const bool value = true; };
|
Chris@16
|
64 template<> struct is_pathable<std::wstring> { static const bool value = true; };
|
Chris@16
|
65 template<> struct is_pathable<std::vector<char> > { static const bool value = true; };
|
Chris@16
|
66 template<> struct is_pathable<std::vector<wchar_t> > { static const bool value = true; };
|
Chris@16
|
67 template<> struct is_pathable<std::list<char> > { static const bool value = true; };
|
Chris@16
|
68 template<> struct is_pathable<std::list<wchar_t> > { static const bool value = true; };
|
Chris@16
|
69 template<> struct is_pathable<directory_entry> { static const bool value = true; };
|
Chris@16
|
70
|
Chris@16
|
71 // Pathable empty
|
Chris@16
|
72
|
Chris@16
|
73 template <class Container> inline
|
Chris@16
|
74 // disable_if aids broken compilers (IBM, old GCC, etc.) and is harmless for
|
Chris@16
|
75 // conforming compilers. Replace by plain "bool" at some future date (2012?)
|
Chris@16
|
76 typename boost::disable_if<boost::is_array<Container>, bool>::type
|
Chris@16
|
77 empty(const Container & c)
|
Chris@16
|
78 { return c.begin() == c.end(); }
|
Chris@16
|
79
|
Chris@16
|
80 template <class T> inline
|
Chris@16
|
81 bool empty(T * const & c_str)
|
Chris@16
|
82 {
|
Chris@16
|
83 BOOST_ASSERT(c_str);
|
Chris@16
|
84 return !*c_str;
|
Chris@16
|
85 }
|
Chris@16
|
86
|
Chris@16
|
87 template <typename T, size_t N> inline
|
Chris@16
|
88 bool empty(T (&x)[N])
|
Chris@16
|
89 { return !x[0]; }
|
Chris@16
|
90
|
Chris@16
|
91 // value types differ ---------------------------------------------------------------//
|
Chris@16
|
92 //
|
Chris@16
|
93 // A from_end argument of 0 is less efficient than a known end, so use only if needed
|
Chris@101
|
94
|
Chris@101
|
95 // with codecvt
|
Chris@16
|
96
|
Chris@16
|
97 BOOST_FILESYSTEM_DECL
|
Chris@101
|
98 void convert(const char* from,
|
Chris@101
|
99 const char* from_end, // 0 for null terminated MBCS
|
Chris@101
|
100 std::wstring & to,
|
Chris@101
|
101 const codecvt_type& cvt);
|
Chris@16
|
102
|
Chris@101
|
103 BOOST_FILESYSTEM_DECL
|
Chris@101
|
104 void convert(const wchar_t* from,
|
Chris@101
|
105 const wchar_t* from_end, // 0 for null terminated MBCS
|
Chris@101
|
106 std::string & to,
|
Chris@101
|
107 const codecvt_type& cvt);
|
Chris@101
|
108
|
Chris@101
|
109 inline
|
Chris@101
|
110 void convert(const char* from,
|
Chris@101
|
111 std::wstring & to,
|
Chris@101
|
112 const codecvt_type& cvt)
|
Chris@16
|
113 {
|
Chris@16
|
114 BOOST_ASSERT(from);
|
Chris@16
|
115 convert(from, 0, to, cvt);
|
Chris@16
|
116 }
|
Chris@16
|
117
|
Chris@101
|
118 inline
|
Chris@101
|
119 void convert(const wchar_t* from,
|
Chris@101
|
120 std::string & to,
|
Chris@101
|
121 const codecvt_type& cvt)
|
Chris@16
|
122 {
|
Chris@16
|
123 BOOST_ASSERT(from);
|
Chris@16
|
124 convert(from, 0, to, cvt);
|
Chris@16
|
125 }
|
Chris@16
|
126
|
Chris@101
|
127 // without codecvt
|
Chris@101
|
128
|
Chris@101
|
129 inline
|
Chris@101
|
130 void convert(const char* from,
|
Chris@101
|
131 const char* from_end, // 0 for null terminated MBCS
|
Chris@101
|
132 std::wstring & to);
|
Chris@101
|
133
|
Chris@101
|
134 inline
|
Chris@101
|
135 void convert(const wchar_t* from,
|
Chris@101
|
136 const wchar_t* from_end, // 0 for null terminated MBCS
|
Chris@101
|
137 std::string & to);
|
Chris@101
|
138
|
Chris@101
|
139 inline
|
Chris@101
|
140 void convert(const char* from,
|
Chris@101
|
141 std::wstring & to);
|
Chris@101
|
142
|
Chris@101
|
143 inline
|
Chris@101
|
144 void convert(const wchar_t* from,
|
Chris@101
|
145 std::string & to);
|
Chris@101
|
146
|
Chris@16
|
147 // value types same -----------------------------------------------------------------//
|
Chris@16
|
148
|
Chris@101
|
149 // char with codecvt
|
Chris@16
|
150
|
Chris@101
|
151 inline
|
Chris@101
|
152 void convert(const char* from, const char* from_end, std::string & to,
|
Chris@16
|
153 const codecvt_type&)
|
Chris@16
|
154 {
|
Chris@16
|
155 BOOST_ASSERT(from);
|
Chris@16
|
156 BOOST_ASSERT(from_end);
|
Chris@16
|
157 to.append(from, from_end);
|
Chris@16
|
158 }
|
Chris@16
|
159
|
Chris@101
|
160 inline
|
Chris@101
|
161 void convert(const char* from,
|
Chris@101
|
162 std::string & to,
|
Chris@101
|
163 const codecvt_type&)
|
Chris@16
|
164 {
|
Chris@16
|
165 BOOST_ASSERT(from);
|
Chris@16
|
166 to += from;
|
Chris@16
|
167 }
|
Chris@16
|
168
|
Chris@101
|
169 // wchar_t with codecvt
|
Chris@16
|
170
|
Chris@101
|
171 inline
|
Chris@101
|
172 void convert(const wchar_t* from, const wchar_t* from_end, std::wstring & to,
|
Chris@16
|
173 const codecvt_type&)
|
Chris@16
|
174 {
|
Chris@16
|
175 BOOST_ASSERT(from);
|
Chris@16
|
176 BOOST_ASSERT(from_end);
|
Chris@16
|
177 to.append(from, from_end);
|
Chris@16
|
178 }
|
Chris@16
|
179
|
Chris@101
|
180 inline
|
Chris@101
|
181 void convert(const wchar_t* from,
|
Chris@101
|
182 std::wstring & to,
|
Chris@101
|
183 const codecvt_type&)
|
Chris@101
|
184 {
|
Chris@101
|
185 BOOST_ASSERT(from);
|
Chris@101
|
186 to += from;
|
Chris@101
|
187 }
|
Chris@101
|
188
|
Chris@101
|
189 // char without codecvt
|
Chris@101
|
190
|
Chris@101
|
191 inline
|
Chris@101
|
192 void convert(const char* from, const char* from_end, std::string & to)
|
Chris@101
|
193 {
|
Chris@101
|
194 BOOST_ASSERT(from);
|
Chris@101
|
195 BOOST_ASSERT(from_end);
|
Chris@101
|
196 to.append(from, from_end);
|
Chris@101
|
197 }
|
Chris@101
|
198
|
Chris@101
|
199 inline
|
Chris@101
|
200 void convert(const char* from, std::string & to)
|
Chris@101
|
201 {
|
Chris@101
|
202 BOOST_ASSERT(from);
|
Chris@101
|
203 to += from;
|
Chris@101
|
204 }
|
Chris@101
|
205
|
Chris@101
|
206 // wchar_t without codecvt
|
Chris@101
|
207
|
Chris@101
|
208 inline
|
Chris@101
|
209 void convert(const wchar_t* from, const wchar_t* from_end, std::wstring & to)
|
Chris@101
|
210 {
|
Chris@101
|
211 BOOST_ASSERT(from);
|
Chris@101
|
212 BOOST_ASSERT(from_end);
|
Chris@101
|
213 to.append(from, from_end);
|
Chris@101
|
214 }
|
Chris@101
|
215
|
Chris@101
|
216 inline
|
Chris@101
|
217 void convert(const wchar_t* from, std::wstring & to)
|
Chris@16
|
218 {
|
Chris@16
|
219 BOOST_ASSERT(from);
|
Chris@16
|
220 to += from;
|
Chris@16
|
221 }
|
Chris@16
|
222
|
Chris@16
|
223 // Source dispatch -----------------------------------------------------------------//
|
Chris@16
|
224
|
Chris@101
|
225 // contiguous containers with codecvt
|
Chris@16
|
226 template <class U> inline
|
Chris@16
|
227 void dispatch(const std::string& c, U& to, const codecvt_type& cvt)
|
Chris@16
|
228 {
|
Chris@16
|
229 if (c.size())
|
Chris@16
|
230 convert(&*c.begin(), &*c.begin() + c.size(), to, cvt);
|
Chris@16
|
231 }
|
Chris@16
|
232 template <class U> inline
|
Chris@16
|
233 void dispatch(const std::wstring& c, U& to, const codecvt_type& cvt)
|
Chris@16
|
234 {
|
Chris@16
|
235 if (c.size())
|
Chris@16
|
236 convert(&*c.begin(), &*c.begin() + c.size(), to, cvt);
|
Chris@16
|
237 }
|
Chris@16
|
238 template <class U> inline
|
Chris@16
|
239 void dispatch(const std::vector<char>& c, U& to, const codecvt_type& cvt)
|
Chris@16
|
240 {
|
Chris@16
|
241 if (c.size())
|
Chris@16
|
242 convert(&*c.begin(), &*c.begin() + c.size(), to, cvt);
|
Chris@16
|
243 }
|
Chris@16
|
244 template <class U> inline
|
Chris@16
|
245 void dispatch(const std::vector<wchar_t>& c, U& to, const codecvt_type& cvt)
|
Chris@16
|
246 {
|
Chris@16
|
247 if (c.size())
|
Chris@16
|
248 convert(&*c.begin(), &*c.begin() + c.size(), to, cvt);
|
Chris@16
|
249 }
|
Chris@16
|
250
|
Chris@101
|
251 // contiguous containers without codecvt
|
Chris@101
|
252 template <class U> inline
|
Chris@101
|
253 void dispatch(const std::string& c, U& to)
|
Chris@101
|
254 {
|
Chris@101
|
255 if (c.size())
|
Chris@101
|
256 convert(&*c.begin(), &*c.begin() + c.size(), to);
|
Chris@101
|
257 }
|
Chris@101
|
258 template <class U> inline
|
Chris@101
|
259 void dispatch(const std::wstring& c, U& to)
|
Chris@101
|
260 {
|
Chris@101
|
261 if (c.size())
|
Chris@101
|
262 convert(&*c.begin(), &*c.begin() + c.size(), to);
|
Chris@101
|
263 }
|
Chris@101
|
264 template <class U> inline
|
Chris@101
|
265 void dispatch(const std::vector<char>& c, U& to)
|
Chris@101
|
266 {
|
Chris@101
|
267 if (c.size())
|
Chris@101
|
268 convert(&*c.begin(), &*c.begin() + c.size(), to);
|
Chris@101
|
269 }
|
Chris@101
|
270 template <class U> inline
|
Chris@101
|
271 void dispatch(const std::vector<wchar_t>& c, U& to)
|
Chris@101
|
272 {
|
Chris@101
|
273 if (c.size())
|
Chris@101
|
274 convert(&*c.begin(), &*c.begin() + c.size(), to);
|
Chris@101
|
275 }
|
Chris@101
|
276
|
Chris@101
|
277 // non-contiguous containers with codecvt
|
Chris@16
|
278 template <class Container, class U> inline
|
Chris@16
|
279 // disable_if aids broken compilers (IBM, old GCC, etc.) and is harmless for
|
Chris@16
|
280 // conforming compilers. Replace by plain "void" at some future date (2012?)
|
Chris@16
|
281 typename boost::disable_if<boost::is_array<Container>, void>::type
|
Chris@101
|
282 dispatch(const Container & c, U& to, const codecvt_type& cvt)
|
Chris@16
|
283 {
|
Chris@16
|
284 if (c.size())
|
Chris@16
|
285 {
|
Chris@16
|
286 std::basic_string<typename Container::value_type> s(c.begin(), c.end());
|
Chris@16
|
287 convert(s.c_str(), s.c_str()+s.size(), to, cvt);
|
Chris@16
|
288 }
|
Chris@16
|
289 }
|
Chris@16
|
290
|
Chris@16
|
291 // c_str
|
Chris@16
|
292 template <class T, class U> inline
|
Chris@101
|
293 void dispatch(T * const & c_str, U& to, const codecvt_type& cvt)
|
Chris@16
|
294 {
|
Chris@101
|
295 // std::cout << "dispatch() const T *\n";
|
Chris@16
|
296 BOOST_ASSERT(c_str);
|
Chris@16
|
297 convert(c_str, to, cvt);
|
Chris@16
|
298 }
|
Chris@101
|
299
|
Chris@16
|
300 // Note: there is no dispatch on C-style arrays because the array may
|
Chris@16
|
301 // contain a string smaller than the array size.
|
Chris@16
|
302
|
Chris@16
|
303 BOOST_FILESYSTEM_DECL
|
Chris@101
|
304 void dispatch(const directory_entry & de,
|
Chris@16
|
305 # ifdef BOOST_WINDOWS_API
|
Chris@101
|
306 std::wstring & to,
|
Chris@16
|
307 # else
|
Chris@101
|
308 std::string & to,
|
Chris@16
|
309 # endif
|
Chris@101
|
310 const codecvt_type&);
|
Chris@101
|
311
|
Chris@101
|
312 // non-contiguous containers without codecvt
|
Chris@101
|
313 template <class Container, class U> inline
|
Chris@101
|
314 // disable_if aids broken compilers (IBM, old GCC, etc.) and is harmless for
|
Chris@101
|
315 // conforming compilers. Replace by plain "void" at some future date (2012?)
|
Chris@101
|
316 typename boost::disable_if<boost::is_array<Container>, void>::type
|
Chris@101
|
317 dispatch(const Container & c, U& to)
|
Chris@101
|
318 {
|
Chris@101
|
319 if (c.size())
|
Chris@101
|
320 {
|
Chris@101
|
321 std::basic_string<typename Container::value_type> seq(c.begin(), c.end());
|
Chris@101
|
322 convert(seq.c_str(), seq.c_str()+seq.size(), to);
|
Chris@101
|
323 }
|
Chris@101
|
324 }
|
Chris@101
|
325
|
Chris@101
|
326 // c_str
|
Chris@101
|
327 template <class T, class U> inline
|
Chris@101
|
328 void dispatch(T * const & c_str, U& to)
|
Chris@101
|
329 {
|
Chris@101
|
330 // std::cout << "dispatch() const T *\n";
|
Chris@101
|
331 BOOST_ASSERT(c_str);
|
Chris@101
|
332 convert(c_str, to);
|
Chris@101
|
333 }
|
Chris@101
|
334
|
Chris@101
|
335 // Note: there is no dispatch on C-style arrays because the array may
|
Chris@101
|
336 // contain a string smaller than the array size.
|
Chris@101
|
337
|
Chris@101
|
338 BOOST_FILESYSTEM_DECL
|
Chris@101
|
339 void dispatch(const directory_entry & de,
|
Chris@101
|
340 # ifdef BOOST_WINDOWS_API
|
Chris@101
|
341 std::wstring & to
|
Chris@101
|
342 # else
|
Chris@101
|
343 std::string & to
|
Chris@101
|
344 # endif
|
Chris@101
|
345 );
|
Chris@16
|
346
|
Chris@16
|
347
|
Chris@16
|
348 }}} // namespace boost::filesystem::path_traits
|
Chris@16
|
349
|
Chris@16
|
350 #include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas
|
Chris@16
|
351
|
Chris@16
|
352 #endif // BOOST_FILESYSTEM_PATH_TRAITS_HPP
|