1 // boost/filesystem/fstream.hpp --------------------------------------------//
3 // Copyright Beman Dawes 2002.
4 // Use, modification, and distribution is subject to the Boost Software
5 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
8 // See library home page at http://www.boost.org/libs/filesystem
10 //----------------------------------------------------------------------------//
12 #ifndef BOOST_FILESYSTEM_FSTREAM_HPP
13 #define BOOST_FILESYSTEM_FSTREAM_HPP
15 #include <boost/filesystem/operations.hpp> // for 8.3 hack (see below)
16 #include <boost/utility/enable_if.hpp>
17 #include <boost/detail/workaround.hpp>
22 #include <boost/config/abi_prefix.hpp> // must be the last #include
24 // NOTE: fstream.hpp for Boost 1.32.0 and earlier supplied workarounds for
25 // various compiler problems. They have been removed to ease development of the
26 // basic i18n functionality. Once the new interface is stable, the workarounds
27 // will be reinstated for any compilers that otherwise can support the rest of
28 // the library after internationalization.
36 # if defined(BOOST_WINDOWS_API) && !defined(BOOST_FILESYSTEM_NARROW_ONLY)
37 # if !defined(BOOST_DINKUMWARE_STDLIB) || BOOST_DINKUMWARE_STDLIB < 405
39 // C++98 does not supply a wchar_t open, so try to get an equivalent
40 // narrow char name based on the short, so-called 8.3, name.
41 // Not needed for Dinkumware 405 and later as they do supply wchar_t open.
42 BOOST_FILESYSTEM_DECL
bool create_file_api( const std::wstring
& ph
,
43 std::ios_base::openmode mode
); // true if succeeds
44 BOOST_FILESYSTEM_DECL
std::string
narrow_path_api(
45 const std::wstring
& ph
); // return is empty if fails
47 inline std::string
path_proxy( const std::wstring
& file_ph
,
48 std::ios_base::openmode mode
)
49 // Return a non-existant path if cannot supply narrow short path.
50 // An empty path doesn't work because some Dinkumware versions
51 // assert the path is non-empty.
53 std::string narrow_ph
;
54 bool created_file( false );
55 if ( !exists( file_ph
)
56 && (mode
& std::ios_base::out
) != 0
57 && create_file_api( file_ph
, mode
) )
61 narrow_ph
= narrow_path_api( file_ph
);
62 if ( narrow_ph
.empty() )
64 if ( created_file
) remove_api( file_ph
);
70 // Dinkumware 405 and later does supply wchar_t functions
71 inline const std::wstring
& path_proxy( const std::wstring
& file_ph
,
72 std::ios_base::openmode
)
77 inline const std::string
& path_proxy( const std::string
& file_ph
,
78 std::ios_base::openmode
)
83 template < class charT
, class traits
= std::char_traits
<charT
> >
84 class basic_filebuf
: public std::basic_filebuf
<charT
,traits
>
86 private: // disallow copying
87 basic_filebuf( const basic_filebuf
& );
88 const basic_filebuf
& operator=( const basic_filebuf
& );
91 virtual ~basic_filebuf() {}
93 # ifndef BOOST_FILESYSTEM_NARROW_ONLY
95 typename
boost::enable_if
<is_basic_path
<Path
>,
96 basic_filebuf
<charT
,traits
> *>::type
97 open( const Path
& file_ph
, std::ios_base::openmode mode
);
99 basic_filebuf
<charT
,traits
> *
100 open( const wpath
& file_ph
, std::ios_base::openmode mode
);
103 # if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this
104 basic_filebuf
<charT
,traits
> *
105 open( const path
& file_ph
, std::ios_base::openmode mode
);
109 template < class charT
, class traits
= std::char_traits
<charT
> >
110 class basic_ifstream
: public std::basic_ifstream
<charT
,traits
>
112 private: // disallow copying
113 basic_ifstream( const basic_ifstream
& );
114 const basic_ifstream
& operator=( const basic_ifstream
& );
118 // use two signatures, rather than one signature with default second
119 // argument, to workaround VC++ 7.1 bug (ID VSWhidbey 38416)
121 # ifndef BOOST_FILESYSTEM_NARROW_ONLY
123 explicit basic_ifstream( const Path
& file_ph
,
124 typename
boost::enable_if
<is_basic_path
<Path
> >::type
* dummy
= 0 );
127 basic_ifstream( const Path
& file_ph
, std::ios_base::openmode mode
,
128 typename
boost::enable_if
<is_basic_path
<Path
> >::type
* dummy
= 0 );
131 typename
boost::enable_if
<is_basic_path
<Path
>, void>::type
132 open( const Path
& file_ph
);
135 typename
boost::enable_if
<is_basic_path
<Path
>, void>::type
136 open( const Path
& file_ph
, std::ios_base::openmode mode
);
138 explicit basic_ifstream( const wpath
& file_ph
);
139 basic_ifstream( const wpath
& file_ph
, std::ios_base::openmode mode
);
140 void open( const wpath
& file_ph
);
141 void open( const wpath
& file_ph
, std::ios_base::openmode mode
);
144 explicit basic_ifstream( const path
& file_ph
);
145 basic_ifstream( const path
& file_ph
, std::ios_base::openmode mode
);
146 # if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this
147 void open( const path
& file_ph
);
148 void open( const path
& file_ph
, std::ios_base::openmode mode
);
150 virtual ~basic_ifstream() {}
153 template < class charT
, class traits
= std::char_traits
<charT
> >
154 class basic_ofstream
: public std::basic_ofstream
<charT
,traits
>
156 private: // disallow copying
157 basic_ofstream( const basic_ofstream
& );
158 const basic_ofstream
& operator=( const basic_ofstream
& );
162 // use two signatures, rather than one signature with default second
163 // argument, to workaround VC++ 7.1 bug (ID VSWhidbey 38416)
165 # ifndef BOOST_FILESYSTEM_NARROW_ONLY
168 explicit basic_ofstream( const Path
& file_ph
,
169 typename
boost::enable_if
<is_basic_path
<Path
> >::type
* dummy
= 0 );
170 explicit basic_ofstream( const wpath
& file_ph
);
173 basic_ofstream( const Path
& file_ph
, std::ios_base::openmode mode
,
174 typename
boost::enable_if
<is_basic_path
<Path
> >::type
* dummy
= 0 );
175 basic_ofstream( const wpath
& file_ph
, std::ios_base::openmode mode
);
178 typename
boost::enable_if
<is_basic_path
<Path
>, void>::type
179 open( const Path
& file_ph
);
180 void open( const wpath
& file_ph
);
183 typename
boost::enable_if
<is_basic_path
<Path
>, void>::type
184 open( const Path
& file_ph
, std::ios_base::openmode mode
);
185 void open( const wpath
& file_ph
, std::ios_base::openmode mode
);
189 explicit basic_ofstream( const path
& file_ph
);
190 basic_ofstream( const path
& file_ph
, std::ios_base::openmode mode
);
191 # if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this
192 void open( const path
& file_ph
);
193 void open( const path
& file_ph
, std::ios_base::openmode mode
);
195 virtual ~basic_ofstream() {}
198 template < class charT
, class traits
= std::char_traits
<charT
> >
199 class basic_fstream
: public std::basic_fstream
<charT
,traits
>
201 private: // disallow copying
202 basic_fstream( const basic_fstream
& );
203 const basic_fstream
& operator=( const basic_fstream
& );
207 // use two signatures, rather than one signature with default second
208 // argument, to workaround VC++ 7.1 bug (ID VSWhidbey 38416)
210 # ifndef BOOST_FILESYSTEM_NARROW_ONLY
213 explicit basic_fstream( const Path
& file_ph
,
214 typename
boost::enable_if
<is_basic_path
<Path
> >::type
* dummy
= 0 );
215 explicit basic_fstream( const wpath
& file_ph
);
218 basic_fstream( const Path
& file_ph
, std::ios_base::openmode mode
,
219 typename
boost::enable_if
<is_basic_path
<Path
> >::type
* dummy
= 0 );
220 basic_fstream( const wpath
& file_ph
, std::ios_base::openmode mode
);
223 typename
boost::enable_if
<is_basic_path
<Path
>, void>::type
224 open( const Path
& file_ph
);
225 void open( const wpath
& file_ph
);
228 typename
boost::enable_if
<is_basic_path
<Path
>, void>::type
229 open( const Path
& file_ph
, std::ios_base::openmode mode
);
230 void open( const wpath
& file_ph
, std::ios_base::openmode mode
);
234 explicit basic_fstream( const path
& file_ph
);
235 basic_fstream( const path
& file_ph
, std::ios_base::openmode mode
);
236 # if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this
237 void open( const path
& file_ph
);
238 void open( const path
& file_ph
, std::ios_base::openmode mode
);
240 virtual ~basic_fstream() {}
244 typedef basic_filebuf
<char> filebuf
;
245 typedef basic_ifstream
<char> ifstream
;
246 typedef basic_ofstream
<char> ofstream
;
247 typedef basic_fstream
<char> fstream
;
249 # ifndef BOOST_FILESYSTEM_NARROW_ONLY
250 typedef basic_filebuf
<wchar_t> wfilebuf
;
251 typedef basic_ifstream
<wchar_t> wifstream
;
252 typedef basic_fstream
<wchar_t> wfstream
;
253 typedef basic_ofstream
<wchar_t> wofstream
;
256 # ifndef BOOST_FILESYSTEM_NARROW_ONLY
258 // basic_filebuf definitions -----------------------------------------------//
260 template <class charT
, class traits
>
262 typename
boost::enable_if
<is_basic_path
<Path
>,
263 basic_filebuf
<charT
,traits
> *>::type
264 basic_filebuf
<charT
,traits
>::open( const Path
& file_ph
,
265 std::ios_base::openmode mode
)
267 return (std::basic_filebuf
<charT
,traits
>::open( detail::path_proxy(
268 file_ph
.external_file_string(), mode
).c_str(), mode
)
272 template <class charT
, class traits
>
273 basic_filebuf
<charT
,traits
> *
274 basic_filebuf
<charT
, traits
>::open( const wpath
& file_ph
,
275 std::ios_base::openmode mode
)
277 return this->BOOST_NESTED_TEMPLATE open
<wpath
>( file_ph
, mode
);
280 // basic_ifstream definitions ----------------------------------------------//
282 template <class charT
, class traits
> template<class Path
>
283 basic_ifstream
<charT
,traits
>::basic_ifstream(const Path
& file_ph
,
284 typename
boost::enable_if
<is_basic_path
<Path
> >::type
* )
285 : std::basic_ifstream
<charT
,traits
>(
286 detail::path_proxy( file_ph
.external_file_string(),
287 std::ios_base::in
).c_str(), std::ios_base::in
) {}
289 template <class charT
, class traits
>
290 basic_ifstream
<charT
,traits
>::basic_ifstream( const wpath
& file_ph
)
291 : std::basic_ifstream
<charT
,traits
>(
292 detail::path_proxy( file_ph
.external_file_string(),
293 std::ios_base::in
).c_str(), std::ios_base::in
) {}
295 template <class charT
, class traits
> template<class Path
>
296 basic_ifstream
<charT
,traits
>::basic_ifstream( const Path
& file_ph
,
297 std::ios_base::openmode mode
,
298 typename
boost::enable_if
<is_basic_path
<Path
> >::type
* )
299 : std::basic_ifstream
<charT
,traits
>(
300 detail::path_proxy( file_ph
.external_file_string(),
301 mode
).c_str(), mode
| std::ios_base::in
) {}
303 template <class charT
, class traits
>
304 basic_ifstream
<charT
,traits
>::basic_ifstream( const wpath
& file_ph
,
305 std::ios_base::openmode mode
)
306 : std::basic_ifstream
<charT
,traits
>(
307 detail::path_proxy( file_ph
.external_file_string(),
308 mode
).c_str(), mode
| std::ios_base::in
) {}
310 template <class charT
, class traits
> template<class Path
>
311 typename
boost::enable_if
<is_basic_path
<Path
>, void>::type
312 basic_ifstream
<charT
,traits
>::open( const Path
& file_ph
)
314 std::basic_ifstream
<charT
,traits
>::open(
315 detail::path_proxy( file_ph
.external_file_string(),
316 std::ios_base::in
).c_str(), std::ios_base::in
);
319 template <class charT
, class traits
>
320 void basic_ifstream
<charT
,traits
>::open( const wpath
& file_ph
)
322 std::basic_ifstream
<charT
,traits
>::open(
323 detail::path_proxy( file_ph
.external_file_string(),
324 std::ios_base::in
).c_str(), std::ios_base::in
);
327 template <class charT
, class traits
> template<class Path
>
328 typename
boost::enable_if
<is_basic_path
<Path
>, void>::type
329 basic_ifstream
<charT
,traits
>::open( const Path
& file_ph
,
330 std::ios_base::openmode mode
)
332 std::basic_ifstream
<charT
,traits
>::open(
333 detail::path_proxy( file_ph
.external_file_string(),
334 mode
).c_str(), mode
| std::ios_base::in
);
337 template <class charT
, class traits
>
338 void basic_ifstream
<charT
,traits
>::open( const wpath
& file_ph
,
339 std::ios_base::openmode mode
)
341 std::basic_ifstream
<charT
,traits
>::open(
342 detail::path_proxy( file_ph
.external_file_string(),
343 mode
).c_str(), mode
| std::ios_base::in
);
346 // basic_ofstream definitions ----------------------------------------------//
348 template <class charT
, class traits
> template<class Path
>
349 basic_ofstream
<charT
,traits
>::basic_ofstream(const Path
& file_ph
,
350 typename
boost::enable_if
<is_basic_path
<Path
> >::type
* )
351 : std::basic_ofstream
<charT
,traits
>(
352 detail::path_proxy( file_ph
.external_file_string(),
353 std::ios_base::out
).c_str(), std::ios_base::out
) {}
355 template <class charT
, class traits
>
356 basic_ofstream
<charT
,traits
>::basic_ofstream( const wpath
& file_ph
)
357 : std::basic_ofstream
<charT
,traits
>(
358 detail::path_proxy( file_ph
.external_file_string(),
359 std::ios_base::out
).c_str(), std::ios_base::out
) {}
361 template <class charT
, class traits
> template<class Path
>
362 basic_ofstream
<charT
,traits
>::basic_ofstream( const Path
& file_ph
,
363 std::ios_base::openmode mode
,
364 typename
boost::enable_if
<is_basic_path
<Path
> >::type
* )
365 : std::basic_ofstream
<charT
,traits
>(
366 detail::path_proxy( file_ph
.external_file_string(),
367 mode
).c_str(), mode
| std::ios_base::out
) {}
369 template <class charT
, class traits
>
370 basic_ofstream
<charT
,traits
>::basic_ofstream( const wpath
& file_ph
,
371 std::ios_base::openmode mode
)
372 : std::basic_ofstream
<charT
,traits
>(
373 detail::path_proxy( file_ph
.external_file_string(),
374 mode
).c_str(), mode
| std::ios_base::out
) {}
376 template <class charT
, class traits
> template<class Path
>
377 typename
boost::enable_if
<is_basic_path
<Path
>, void>::type
378 basic_ofstream
<charT
,traits
>::open( const Path
& file_ph
)
380 std::basic_ofstream
<charT
,traits
>::open(
381 detail::path_proxy( file_ph
.external_file_string(),
382 std::ios_base::out
).c_str(), std::ios_base::out
);
385 template <class charT
, class traits
>
386 void basic_ofstream
<charT
,traits
>::open( const wpath
& file_ph
)
388 std::basic_ofstream
<charT
,traits
>::open(
389 detail::path_proxy( file_ph
.external_file_string(),
390 std::ios_base::out
).c_str(), std::ios_base::out
);
393 template <class charT
, class traits
> template<class Path
>
394 typename
boost::enable_if
<is_basic_path
<Path
>, void>::type
395 basic_ofstream
<charT
,traits
>::open( const Path
& file_ph
,
396 std::ios_base::openmode mode
)
398 std::basic_ofstream
<charT
,traits
>::open(
399 detail::path_proxy( file_ph
.external_file_string(),
400 mode
).c_str(), mode
| std::ios_base::out
);
403 template <class charT
, class traits
>
404 void basic_ofstream
<charT
,traits
>::open( const wpath
& file_ph
,
405 std::ios_base::openmode mode
)
407 std::basic_ofstream
<charT
,traits
>::open(
408 detail::path_proxy( file_ph
.external_file_string(),
409 mode
).c_str(), mode
| std::ios_base::out
);
412 // basic_fstream definitions -----------------------------------------------//
414 template <class charT
, class traits
> template<class Path
>
415 basic_fstream
<charT
,traits
>::basic_fstream(const Path
& file_ph
,
416 typename
boost::enable_if
<is_basic_path
<Path
> >::type
* )
417 : std::basic_fstream
<charT
,traits
>(
418 detail::path_proxy( file_ph
.external_file_string(),
419 std::ios_base::in
|std::ios_base::out
).c_str(),
420 std::ios_base::in
|std::ios_base::out
) {}
422 template <class charT
, class traits
>
423 basic_fstream
<charT
,traits
>::basic_fstream( const wpath
& file_ph
)
424 : std::basic_fstream
<charT
,traits
>(
425 detail::path_proxy( file_ph
.external_file_string(),
426 std::ios_base::in
|std::ios_base::out
).c_str(),
427 std::ios_base::in
|std::ios_base::out
) {}
429 template <class charT
, class traits
> template<class Path
>
430 basic_fstream
<charT
,traits
>::basic_fstream( const Path
& file_ph
,
431 std::ios_base::openmode mode
,
432 typename
boost::enable_if
<is_basic_path
<Path
> >::type
* )
433 : std::basic_fstream
<charT
,traits
>(
434 detail::path_proxy( file_ph
.external_file_string(),
435 mode
).c_str(), mode
| std::ios_base::in
| std::ios_base::out
) {}
437 template <class charT
, class traits
>
438 basic_fstream
<charT
,traits
>::basic_fstream( const wpath
& file_ph
,
439 std::ios_base::openmode mode
)
440 : std::basic_fstream
<charT
,traits
>(
441 detail::path_proxy( file_ph
.external_file_string(),
442 mode
).c_str(), mode
| std::ios_base::in
| std::ios_base::out
) {}
444 template <class charT
, class traits
> template<class Path
>
445 typename
boost::enable_if
<is_basic_path
<Path
>, void>::type
446 basic_fstream
<charT
,traits
>::open( const Path
& file_ph
)
448 std::basic_fstream
<charT
,traits
>::open(
449 detail::path_proxy( file_ph
.external_file_string(),
450 std::ios_base::in
|std::ios_base::out
).c_str(),
451 std::ios_base::in
|std::ios_base::out
);
454 template <class charT
, class traits
>
455 void basic_fstream
<charT
,traits
>::open( const wpath
& file_ph
)
457 std::basic_fstream
<charT
,traits
>::open(
458 detail::path_proxy( file_ph
.external_file_string(),
459 std::ios_base::in
|std::ios_base::out
).c_str(),
460 std::ios_base::in
|std::ios_base::out
);
463 template <class charT
, class traits
> template<class Path
>
464 typename
boost::enable_if
<is_basic_path
<Path
>, void>::type
465 basic_fstream
<charT
,traits
>::open( const Path
& file_ph
,
466 std::ios_base::openmode mode
)
468 std::basic_fstream
<charT
,traits
>::open(
469 detail::path_proxy( file_ph
.external_file_string(),
470 mode
).c_str(), mode
| std::ios_base::in
| std::ios_base::out
);
473 template <class charT
, class traits
>
474 void basic_fstream
<charT
,traits
>::open( const wpath
& file_ph
,
475 std::ios_base::openmode mode
)
477 std::basic_fstream
<charT
,traits
>::open(
478 detail::path_proxy( file_ph
.external_file_string(),
479 mode
).c_str(), mode
| std::ios_base::in
| std::ios_base::out
);
484 # if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this
485 template <class charT
, class traits
>
486 basic_filebuf
<charT
,traits
> *
487 basic_filebuf
<charT
, traits
>::open( const path
& file_ph
,
488 std::ios_base::openmode mode
)
490 return std::basic_filebuf
<charT
,traits
>::open(
491 file_ph
.file_string().c_str(), mode
) == 0 ? 0 : this;
495 template <class charT
, class traits
>
496 basic_ifstream
<charT
,traits
>::basic_ifstream( const path
& file_ph
)
497 : std::basic_ifstream
<charT
,traits
>(
498 file_ph
.file_string().c_str(), std::ios_base::in
) {}
500 template <class charT
, class traits
>
501 basic_ifstream
<charT
,traits
>::basic_ifstream( const path
& file_ph
,
502 std::ios_base::openmode mode
)
503 : std::basic_ifstream
<charT
,traits
>(
504 file_ph
.file_string().c_str(), mode
) {}
506 # if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this
507 template <class charT
, class traits
>
508 void basic_ifstream
<charT
,traits
>::open( const path
& file_ph
)
510 std::basic_ifstream
<charT
,traits
>::open(
511 file_ph
.file_string().c_str(), std::ios_base::in
);
514 template <class charT
, class traits
>
515 void basic_ifstream
<charT
,traits
>::open( const path
& file_ph
,
516 std::ios_base::openmode mode
)
518 std::basic_ifstream
<charT
,traits
>::open(
519 file_ph
.file_string().c_str(), mode
);
523 template <class charT
, class traits
>
524 basic_ofstream
<charT
,traits
>::basic_ofstream( const path
& file_ph
)
525 : std::basic_ofstream
<charT
,traits
>(
526 file_ph
.file_string().c_str(), std::ios_base::out
) {}
528 template <class charT
, class traits
>
529 basic_ofstream
<charT
,traits
>::basic_ofstream( const path
& file_ph
,
530 std::ios_base::openmode mode
)
531 : std::basic_ofstream
<charT
,traits
>(
532 file_ph
.file_string().c_str(), mode
) {}
534 # if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this
535 template <class charT
, class traits
>
536 void basic_ofstream
<charT
,traits
>::open( const path
& file_ph
)
538 std::basic_ofstream
<charT
,traits
>::open(
539 file_ph
.file_string().c_str(), std::ios_base::out
);
542 template <class charT
, class traits
>
543 void basic_ofstream
<charT
,traits
>::open( const path
& file_ph
,
544 std::ios_base::openmode mode
)
546 std::basic_ofstream
<charT
,traits
>::open(
547 file_ph
.file_string().c_str(), mode
);
551 template <class charT
, class traits
>
552 basic_fstream
<charT
,traits
>::basic_fstream( const path
& file_ph
)
553 : std::basic_fstream
<charT
,traits
>(
554 file_ph
.file_string().c_str(),
555 std::ios_base::in
|std::ios_base::out
) {}
558 template <class charT
, class traits
>
559 basic_fstream
<charT
,traits
>::basic_fstream( const path
& file_ph
,
560 std::ios_base::openmode mode
)
561 : std::basic_fstream
<charT
,traits
>(
562 file_ph
.file_string().c_str(), mode
) {}
564 # if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this
565 template <class charT
, class traits
>
566 void basic_fstream
<charT
,traits
>::open( const path
& file_ph
)
568 std::basic_fstream
<charT
,traits
>::open(
569 file_ph
.file_string().c_str(), std::ios_base::in
|std::ios_base::out
);
572 template <class charT
, class traits
>
573 void basic_fstream
<charT
,traits
>::open( const path
& file_ph
,
574 std::ios_base::openmode mode
)
576 std::basic_fstream
<charT
,traits
>::open(
577 file_ph
.file_string().c_str(), mode
);
580 } // namespace filesystem
583 #include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas
584 #endif // BOOST_FILESYSTEM_FSTREAM_HPP