fix doc example typo
[boost.git] / boost / filesystem / operations.hpp
blob4d52ab720077bd8f36f226afb2162ccd148e1bb4
1 // boost/filesystem/operations.hpp -----------------------------------------//
3 // Copyright 2002-2005 Beman Dawes
4 // Copyright 2002 Jan Langer
5 // Copyright 2001 Dietmar Kuehl
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
10 // See library home page at http://www.boost.org/libs/filesystem
12 //----------------------------------------------------------------------------//
14 #ifndef BOOST_FILESYSTEM_OPERATIONS_HPP
15 #define BOOST_FILESYSTEM_OPERATIONS_HPP
17 #include <boost/filesystem/path.hpp>
18 #include <boost/detail/scoped_enum_emulation.hpp>
20 #include <boost/shared_ptr.hpp>
21 #include <boost/utility/enable_if.hpp>
22 #include <boost/type_traits/is_same.hpp>
23 #include <boost/iterator.hpp>
24 #include <boost/cstdint.hpp>
25 #include <boost/assert.hpp>
27 #include <string>
28 #include <utility> // for pair
29 #include <ctime>
31 #ifdef BOOST_WINDOWS_API
32 # include <fstream>
33 # if !defined(_WIN32_WINNT) || _WIN32_WINNT >= 0x0500
34 # define BOOST_FS_HARD_LINK // Default for Windows 2K or later
35 # endif
36 #endif
38 #include <boost/config/abi_prefix.hpp> // must be the last #include
40 # ifdef BOOST_NO_STDC_NAMESPACE
41 namespace std { using ::time_t; }
42 # endif
44 //----------------------------------------------------------------------------//
46 namespace boost
48 namespace filesystem
51 // typedef boost::filesystem::path Path; needs to be in namespace boost::filesystem
52 # ifndef BOOST_FILESYSTEM_NARROW_ONLY
53 # define BOOST_FS_FUNC(BOOST_FS_TYPE) \
54 template<class Path> typename boost::enable_if<is_basic_path<Path>, \
55 BOOST_FS_TYPE>::type
56 # define BOOST_INLINE_FS_FUNC(BOOST_FS_TYPE) \
57 template<class Path> inline typename boost::enable_if<is_basic_path<Path>, \
58 BOOST_FS_TYPE>::type
59 # define BOOST_FS_TYPENAME typename
60 # else
61 # define BOOST_FS_FUNC(BOOST_FS_TYPE) inline BOOST_FS_TYPE
62 # define BOOST_INLINE_FS_FUNC(BOOST_FS_TYPE) inline BOOST_FS_TYPE
63 typedef boost::filesystem::path Path;
64 # define BOOST_FS_TYPENAME
65 # endif
67 template<class Path> class basic_directory_iterator;
69 // BOOST_FILESYSTEM_NARROW_ONLY needs this:
70 typedef basic_directory_iterator<path> directory_iterator;
72 template<class Path> class basic_directory_entry;
74 enum file_type
76 status_unknown,
77 file_not_found,
78 regular_file,
79 directory_file,
80 // the following will never be reported by some operating or file systems
81 symlink_file,
82 block_file,
83 character_file,
84 fifo_file,
85 socket_file,
86 type_unknown // file does exist, but isn't one of the above types or
87 // we don't have strong enough permission to find its type
90 class file_status
92 public:
93 explicit file_status( file_type v = status_unknown ) : m_value(v) {}
95 void type( file_type v ) { m_value = v; }
96 file_type type() const { return m_value; }
98 private:
99 // the internal representation is unspecified so that additional state
100 // information such as permissions can be added in the future; this
101 // implementation just uses status_type as the internal representation
103 file_type m_value;
106 inline bool status_known( file_status f ) { return f.type() != status_unknown; }
107 inline bool exists( file_status f ) { return f.type() != status_unknown && f.type() != file_not_found; }
108 inline bool is_regular_file(file_status f){ return f.type() == regular_file; }
109 inline bool is_directory( file_status f ) { return f.type() == directory_file; }
110 inline bool is_symlink( file_status f ) { return f.type() == symlink_file; }
111 inline bool is_other( file_status f ) { return exists(f) && !is_regular_file(f) && !is_directory(f) && !is_symlink(f); }
113 # ifndef BOOST_FILESYSTEM_NO_DEPRECATED
114 inline bool is_regular( file_status f ) { return f.type() == regular_file; }
115 # endif
117 struct space_info
119 // all values are byte counts
120 boost::uintmax_t capacity;
121 boost::uintmax_t free; // <= capacity
122 boost::uintmax_t available; // <= free
125 namespace detail
127 typedef std::pair< system::error_code, bool >
128 query_pair;
130 typedef std::pair< system::error_code, boost::uintmax_t >
131 uintmax_pair;
133 typedef std::pair< system::error_code, std::time_t >
134 time_pair;
136 typedef std::pair< system::error_code, space_info >
137 space_pair;
139 template< class Path >
140 struct directory_pair
142 typedef std::pair< system::error_code,
143 typename Path::external_string_type > type;
146 # ifndef BOOST_FILESYSTEM_NO_DEPRECATED
147 BOOST_FILESYSTEM_DECL bool
148 symbolic_link_exists_api( const std::string & ); // deprecated
149 # endif
151 BOOST_FILESYSTEM_DECL file_status
152 status_api( const std::string & ph, system::error_code & ec );
153 # ifndef BOOST_WINDOWS_API
154 BOOST_FILESYSTEM_DECL file_status
155 symlink_status_api( const std::string & ph, system::error_code & ec );
156 # endif
157 BOOST_FILESYSTEM_DECL query_pair
158 is_empty_api( const std::string & ph );
159 BOOST_FILESYSTEM_DECL query_pair
160 equivalent_api( const std::string & ph1, const std::string & ph2 );
161 BOOST_FILESYSTEM_DECL uintmax_pair
162 file_size_api( const std::string & ph );
163 BOOST_FILESYSTEM_DECL space_pair
164 space_api( const std::string & ph );
165 BOOST_FILESYSTEM_DECL time_pair
166 last_write_time_api( const std::string & ph );
167 BOOST_FILESYSTEM_DECL system::error_code
168 last_write_time_api( const std::string & ph, std::time_t new_value );
169 BOOST_FILESYSTEM_DECL system::error_code
170 get_current_path_api( std::string & ph );
171 BOOST_FILESYSTEM_DECL system::error_code
172 set_current_path_api( const std::string & ph );
173 BOOST_FILESYSTEM_DECL query_pair
174 create_directory_api( const std::string & ph );
175 BOOST_FILESYSTEM_DECL system::error_code
176 create_hard_link_api( const std::string & to_ph,
177 const std::string & from_ph );
178 BOOST_FILESYSTEM_DECL system::error_code
179 create_symlink_api( const std::string & to_ph,
180 const std::string & from_ph );
181 BOOST_FILESYSTEM_DECL system::error_code
182 remove_api( const std::string & ph );
183 BOOST_FILESYSTEM_DECL system::error_code
184 rename_api( const std::string & from, const std::string & to );
185 BOOST_FILESYSTEM_DECL system::error_code
186 copy_file_api( const std::string & from, const std::string & to, bool fail_if_exists );
188 # if defined(BOOST_WINDOWS_API)
190 BOOST_FILESYSTEM_DECL system::error_code
191 get_full_path_name_api( const std::string & ph, std::string & target );
193 # if !defined(BOOST_FILESYSTEM_NARROW_ONLY)
195 BOOST_FILESYSTEM_DECL boost::filesystem::file_status
196 status_api( const std::wstring & ph, system::error_code & ec );
197 BOOST_FILESYSTEM_DECL query_pair
198 is_empty_api( const std::wstring & ph );
199 BOOST_FILESYSTEM_DECL query_pair
200 equivalent_api( const std::wstring & ph1, const std::wstring & ph2 );
201 BOOST_FILESYSTEM_DECL uintmax_pair
202 file_size_api( const std::wstring & ph );
203 BOOST_FILESYSTEM_DECL space_pair
204 space_api( const std::wstring & ph );
205 BOOST_FILESYSTEM_DECL system::error_code
206 get_full_path_name_api( const std::wstring & ph, std::wstring & target );
207 BOOST_FILESYSTEM_DECL time_pair
208 last_write_time_api( const std::wstring & ph );
209 BOOST_FILESYSTEM_DECL system::error_code
210 last_write_time_api( const std::wstring & ph, std::time_t new_value );
211 BOOST_FILESYSTEM_DECL system::error_code
212 get_current_path_api( std::wstring & ph );
213 BOOST_FILESYSTEM_DECL system::error_code
214 set_current_path_api( const std::wstring & ph );
215 BOOST_FILESYSTEM_DECL query_pair
216 create_directory_api( const std::wstring & ph );
217 # ifdef BOOST_FS_HARD_LINK
218 BOOST_FILESYSTEM_DECL system::error_code
219 create_hard_link_api( const std::wstring & existing_ph,
220 const std::wstring & new_ph );
221 # endif
222 BOOST_FILESYSTEM_DECL system::error_code
223 create_symlink_api( const std::wstring & to_ph,
224 const std::wstring & from_ph );
225 BOOST_FILESYSTEM_DECL system::error_code
226 remove_api( const std::wstring & ph );
227 BOOST_FILESYSTEM_DECL system::error_code
228 rename_api( const std::wstring & from, const std::wstring & to );
229 BOOST_FILESYSTEM_DECL system::error_code
230 copy_file_api( const std::wstring & from, const std::wstring & to, bool fail_if_exists );
232 # endif
233 # endif
235 template<class Path>
236 bool remove_aux( const Path & ph, file_status f );
238 template<class Path>
239 unsigned long remove_all_aux( const Path & ph, file_status f );
241 } // namespace detail
243 // operations functions ----------------------------------------------------//
245 // The non-template overloads enable automatic conversion from std and
246 // C-style strings. See basic_path constructors. The enable_if for the
247 // templates implements the famous "do-the-right-thing" rule.
249 // query functions ---------------------------------------------------------//
251 BOOST_INLINE_FS_FUNC(file_status)
252 status( const Path & ph, system::error_code & ec )
253 { return detail::status_api( ph.external_file_string(), ec ); }
255 BOOST_FS_FUNC(file_status)
256 status( const Path & ph )
258 system::error_code ec;
259 file_status result( detail::status_api( ph.external_file_string(), ec ) );
260 if ( ec )
261 boost::throw_exception( basic_filesystem_error<Path>(
262 "boost::filesystem::status", ph, ec ) );
263 return result;
266 BOOST_INLINE_FS_FUNC(file_status)
267 symlink_status( const Path & ph, system::error_code & ec )
268 # ifdef BOOST_WINDOWS_API
269 { return detail::status_api( ph.external_file_string(), ec ); }
270 # else
271 { return detail::symlink_status_api( ph.external_file_string(), ec ); }
272 # endif
274 BOOST_FS_FUNC(file_status)
275 symlink_status( const Path & ph )
277 system::error_code ec;
278 file_status result( symlink_status( ph, ec ) );
279 if ( ec )
280 boost::throw_exception( basic_filesystem_error<Path>(
281 "boost::filesystem::symlink_status", ph, ec ) );
282 return result;
285 # ifndef BOOST_FILESYSTEM_NO_DEPRECATED
286 inline bool symbolic_link_exists( const path & ph )
287 { return is_symlink( symlink_status(ph) ); }
288 # endif
290 BOOST_FS_FUNC(bool) exists( const Path & ph )
292 system::error_code ec;
293 file_status result( detail::status_api( ph.external_file_string(), ec ) );
294 if ( ec )
295 boost::throw_exception( basic_filesystem_error<Path>(
296 "boost::filesystem::exists", ph, ec ) );
297 return exists( result );
300 BOOST_FS_FUNC(bool) is_directory( const Path & ph )
302 system::error_code ec;
303 file_status result( detail::status_api( ph.external_file_string(), ec ) );
304 if ( ec )
305 boost::throw_exception( basic_filesystem_error<Path>(
306 "boost::filesystem::is_directory", ph, ec ) );
307 return is_directory( result );
310 BOOST_FS_FUNC(bool) is_regular_file( const Path & ph )
312 system::error_code ec;
313 file_status result( detail::status_api( ph.external_file_string(), ec ) );
314 if ( ec )
315 boost::throw_exception( basic_filesystem_error<Path>(
316 "boost::filesystem::is_regular_file", ph, ec ) );
317 return is_regular_file( result );
320 # ifndef BOOST_FILESYSTEM_NO_DEPRECATED
321 BOOST_FS_FUNC(bool) is_regular( const Path & ph )
323 system::error_code ec;
324 file_status result( detail::status_api( ph.external_file_string(), ec ) );
325 if ( ec )
326 boost::throw_exception( basic_filesystem_error<Path>(
327 "boost::filesystem::is_regular", ph, ec ) );
328 return is_regular( result );
330 # endif
332 BOOST_FS_FUNC(bool) is_other( const Path & ph )
334 system::error_code ec;
335 file_status result( detail::status_api( ph.external_file_string(), ec ) );
336 if ( ec )
337 boost::throw_exception( basic_filesystem_error<Path>(
338 "boost::filesystem::is_other", ph, ec ) );
339 return is_other( result );
342 BOOST_FS_FUNC(bool) is_symlink(
343 # ifdef BOOST_WINDOWS_API
344 const Path & )
346 return false;
347 # else
348 const Path & ph)
350 system::error_code ec;
351 file_status result( detail::symlink_status_api( ph.external_file_string(), ec ) );
352 if ( ec )
353 boost::throw_exception( basic_filesystem_error<Path>(
354 "boost::filesystem::is_symlink", ph, ec ) );
355 return is_symlink( result );
356 # endif
359 // VC++ 7.0 and earlier has a serious namespace bug that causes a clash
360 // between boost::filesystem::is_empty and the unrelated type trait
361 // boost::is_empty.
363 # if !defined( BOOST_MSVC ) || BOOST_MSVC > 1300
364 BOOST_FS_FUNC(bool) is_empty( const Path & ph )
365 # else
366 BOOST_FS_FUNC(bool) _is_empty( const Path & ph )
367 # endif
369 detail::query_pair result(
370 detail::is_empty_api( ph.external_file_string() ) );
371 if ( result.first )
372 boost::throw_exception( basic_filesystem_error<Path>(
373 "boost::filesystem::is_empty", ph, result.first ) );
374 return result.second;
377 BOOST_FS_FUNC(bool) equivalent( const Path & ph1, const Path & ph2 )
379 detail::query_pair result( detail::equivalent_api(
380 ph1.external_file_string(), ph2.external_file_string() ) );
381 if ( result.first )
382 boost::throw_exception( basic_filesystem_error<Path>(
383 "boost::filesystem::equivalent", ph1, ph2, result.first ) );
384 return result.second;
387 BOOST_FS_FUNC(boost::uintmax_t) file_size( const Path & ph )
389 detail::uintmax_pair result
390 ( detail::file_size_api( ph.external_file_string() ) );
391 if ( result.first )
392 boost::throw_exception( basic_filesystem_error<Path>(
393 "boost::filesystem::file_size", ph, result.first ) );
394 return result.second;
397 BOOST_FS_FUNC(space_info) space( const Path & ph )
399 detail::space_pair result
400 ( detail::space_api( ph.external_file_string() ) );
401 if ( result.first )
402 boost::throw_exception( basic_filesystem_error<Path>(
403 "boost::filesystem::space", ph, result.first ) );
404 return result.second;
407 BOOST_FS_FUNC(std::time_t) last_write_time( const Path & ph )
409 detail::time_pair result
410 ( detail::last_write_time_api( ph.external_file_string() ) );
411 if ( result.first )
412 boost::throw_exception( basic_filesystem_error<Path>(
413 "boost::filesystem::last_write_time", ph, result.first ) );
414 return result.second;
418 // operations --------------------------------------------------------------//
420 BOOST_FS_FUNC(bool) create_directory( const Path & dir_ph )
422 detail::query_pair result(
423 detail::create_directory_api( dir_ph.external_directory_string() ) );
424 if ( result.first )
425 boost::throw_exception( basic_filesystem_error<Path>(
426 "boost::filesystem::create_directory",
427 dir_ph, result.first ) );
428 return result.second;
431 #if !defined(BOOST_WINDOWS_API) || defined(BOOST_FS_HARD_LINK)
432 BOOST_FS_FUNC(void)
433 create_hard_link( const Path & to_ph, const Path & from_ph )
435 system::error_code ec(
436 detail::create_hard_link_api(
437 to_ph.external_file_string(),
438 from_ph.external_file_string() ) );
439 if ( ec )
440 boost::throw_exception( basic_filesystem_error<Path>(
441 "boost::filesystem::create_hard_link",
442 to_ph, from_ph, ec ) );
445 BOOST_FS_FUNC(system::error_code)
446 create_hard_link( const Path & to_ph, const Path & from_ph,
447 system::error_code & ec )
449 ec = detail::create_hard_link_api(
450 to_ph.external_file_string(),
451 from_ph.external_file_string() );
452 return ec;
454 #endif
456 BOOST_FS_FUNC(void)
457 create_symlink( const Path & to_ph, const Path & from_ph )
459 system::error_code ec(
460 detail::create_symlink_api(
461 to_ph.external_file_string(),
462 from_ph.external_file_string() ) );
463 if ( ec )
464 boost::throw_exception( basic_filesystem_error<Path>(
465 "boost::filesystem::create_symlink",
466 to_ph, from_ph, ec ) );
469 BOOST_FS_FUNC(system::error_code)
470 create_symlink( const Path & to_ph, const Path & from_ph,
471 system::error_code & ec )
473 ec = detail::create_symlink_api(
474 to_ph.external_file_string(),
475 from_ph.external_file_string() );
476 return ec;
479 BOOST_FS_FUNC(bool) remove( const Path & ph )
481 system::error_code ec;
482 file_status f = symlink_status( ph, ec );
483 if ( ec )
484 boost::throw_exception( basic_filesystem_error<Path>(
485 "boost::filesystem::remove", ph, ec ) );
486 return detail::remove_aux( ph, f );
489 BOOST_FS_FUNC(unsigned long) remove_all( const Path & ph )
491 system::error_code ec;
492 file_status f = symlink_status( ph, ec );
493 if ( ec )
494 boost::throw_exception( basic_filesystem_error<Path>(
495 "boost::filesystem::remove_all", ph, ec ) );
496 return exists( f ) ? detail::remove_all_aux( ph, f ) : 0;
499 BOOST_FS_FUNC(void) rename( const Path & from_path, const Path & to_path )
501 system::error_code ec( detail::rename_api(
502 from_path.external_directory_string(),
503 to_path.external_directory_string() ) );
504 if ( ec )
505 boost::throw_exception( basic_filesystem_error<Path>(
506 "boost::filesystem::rename",
507 from_path, to_path, ec ) );
510 BOOST_SCOPED_ENUM_START(copy_option)
511 { fail_if_exists, overwrite_if_exists };
512 BOOST_SCOPED_ENUM_END
514 BOOST_FS_FUNC(void) copy_file( const Path & from_path, const Path & to_path,
515 BOOST_SCOPED_ENUM(copy_option) option = copy_option::fail_if_exists )
517 system::error_code ec( detail::copy_file_api(
518 from_path.external_directory_string(),
519 to_path.external_directory_string(), option == copy_option::fail_if_exists ) );
520 if ( ec )
521 boost::throw_exception( basic_filesystem_error<Path>(
522 "boost::filesystem::copy_file",
523 from_path, to_path, ec ) );
526 template< class Path >
527 Path current_path()
529 typename Path::external_string_type ph;
530 system::error_code ec( detail::get_current_path_api( ph ) );
531 if ( ec )
532 boost::throw_exception( basic_filesystem_error<Path>(
533 "boost::filesystem::current_path", ec ) );
534 return Path( Path::traits_type::to_internal( ph ) );
537 BOOST_FS_FUNC(void) current_path( const Path & ph )
539 system::error_code ec( detail::set_current_path_api(
540 ph.external_directory_string() ) );
541 if ( ec )
542 boost::throw_exception( basic_filesystem_error<Path>(
543 "boost::filesystem::current_path", ph, ec ) );
546 template< class Path >
547 const Path & initial_path()
549 static Path init_path;
550 if ( init_path.empty() ) init_path = current_path<Path>();
551 return init_path;
554 # ifndef BOOST_FILESYSTEM_NO_DEPRECATED
555 // legacy support
556 inline path current_path() // overload supports pre-i18n apps
557 { return current_path<boost::filesystem::path>(); }
558 inline const path & initial_path() // overload supports pre-i18n apps
559 { return initial_path<boost::filesystem::path>(); }
560 # endif
562 BOOST_FS_FUNC(Path) system_complete( const Path & ph )
564 # ifdef BOOST_WINDOWS_API
565 if ( ph.empty() ) return ph;
566 BOOST_FS_TYPENAME Path::external_string_type sys_ph;
567 system::error_code ec( detail::get_full_path_name_api( ph.external_file_string(),
568 sys_ph ) );
569 if ( ec )
570 boost::throw_exception( basic_filesystem_error<Path>(
571 "boost::filesystem::system_complete", ph, ec ) );
572 return Path( Path::traits_type::to_internal( sys_ph ) );
573 # else
574 return (ph.empty() || ph.is_complete())
575 ? ph : current_path<Path>() / ph;
576 # endif
579 BOOST_FS_FUNC(Path)
580 complete( const Path & ph,
581 const Path & base/* = initial_path<Path>() */)
583 BOOST_ASSERT( base.is_complete()
584 && (ph.is_complete() || !ph.has_root_name())
585 && "boost::filesystem::complete() precondition not met" );
586 # ifdef BOOST_WINDOWS_PATH
587 if (ph.empty() || ph.is_complete()) return ph;
588 if ( !ph.has_root_name() )
589 return ph.has_root_directory()
590 ? Path( base.root_name() ) / ph
591 : base / ph;
592 return base / ph;
593 # else
594 return (ph.empty() || ph.is_complete()) ? ph : base / ph;
595 # endif
598 // VC++ 7.1 had trouble with default arguments, so separate one argument
599 // signatures are provided as workarounds; the effect is the same.
600 BOOST_FS_FUNC(Path) complete( const Path & ph )
601 { return complete( ph, initial_path<Path>() ); }
603 BOOST_FS_FUNC(void)
604 last_write_time( const Path & ph, const std::time_t new_time )
606 system::error_code ec( detail::last_write_time_api( ph.external_file_string(),
607 new_time ) );
608 if ( ec )
609 boost::throw_exception( basic_filesystem_error<Path>(
610 "boost::filesystem::last_write_time", ph, ec ) );
613 # ifndef BOOST_FILESYSTEM_NARROW_ONLY
615 // "do-the-right-thing" overloads ---------------------------------------//
617 inline file_status status( const path & ph )
618 { return status<path>( ph ); }
619 inline file_status status( const wpath & ph )
620 { return status<wpath>( ph ); }
622 inline file_status status( const path & ph, system::error_code & ec )
623 { return status<path>( ph, ec ); }
624 inline file_status status( const wpath & ph, system::error_code & ec )
625 { return status<wpath>( ph, ec ); }
627 inline file_status symlink_status( const path & ph )
628 { return symlink_status<path>( ph ); }
629 inline file_status symlink_status( const wpath & ph )
630 { return symlink_status<wpath>( ph ); }
632 inline file_status symlink_status( const path & ph, system::error_code & ec )
633 { return symlink_status<path>( ph, ec ); }
634 inline file_status symlink_status( const wpath & ph, system::error_code & ec )
635 { return symlink_status<wpath>( ph, ec ); }
637 inline bool exists( const path & ph ) { return exists<path>( ph ); }
638 inline bool exists( const wpath & ph ) { return exists<wpath>( ph ); }
640 inline bool is_directory( const path & ph )
641 { return is_directory<path>( ph ); }
642 inline bool is_directory( const wpath & ph )
643 { return is_directory<wpath>( ph ); }
645 inline bool is_regular_file( const path & ph )
646 { return is_regular_file<path>( ph ); }
647 inline bool is_regular_file( const wpath & ph )
648 { return is_regular_file<wpath>( ph ); }
650 # ifndef BOOST_FILESYSTEM_NO_DEPRECATED
651 inline bool is_regular( const path & ph )
652 { return is_regular<path>( ph ); }
653 inline bool is_regular( const wpath & ph )
654 { return is_regular<wpath>( ph ); }
655 # endif
657 inline bool is_other( const path & ph )
658 { return is_other<path>( ph ); }
659 inline bool is_other( const wpath & ph )
660 { return is_other<wpath>( ph ); }
662 inline bool is_symlink( const path & ph )
663 { return is_symlink<path>( ph ); }
664 inline bool is_symlink( const wpath & ph )
665 { return is_symlink<wpath>( ph ); }
667 inline bool is_empty( const path & ph )
668 { return boost::filesystem::is_empty<path>( ph ); }
669 inline bool is_empty( const wpath & ph )
670 { return boost::filesystem::is_empty<wpath>( ph ); }
672 inline bool equivalent( const path & ph1, const path & ph2 )
673 { return equivalent<path>( ph1, ph2 ); }
674 inline bool equivalent( const wpath & ph1, const wpath & ph2 )
675 { return equivalent<wpath>( ph1, ph2 ); }
677 inline boost::uintmax_t file_size( const path & ph )
678 { return file_size<path>( ph ); }
679 inline boost::uintmax_t file_size( const wpath & ph )
680 { return file_size<wpath>( ph ); }
682 inline space_info space( const path & ph )
683 { return space<path>( ph ); }
684 inline space_info space( const wpath & ph )
685 { return space<wpath>( ph ); }
687 inline std::time_t last_write_time( const path & ph )
688 { return last_write_time<path>( ph ); }
689 inline std::time_t last_write_time( const wpath & ph )
690 { return last_write_time<wpath>( ph ); }
692 inline bool create_directory( const path & dir_ph )
693 { return create_directory<path>( dir_ph ); }
694 inline bool create_directory( const wpath & dir_ph )
695 { return create_directory<wpath>( dir_ph ); }
697 #if !defined(BOOST_WINDOWS_API) || defined(BOOST_FS_HARD_LINK)
698 inline void create_hard_link( const path & to_ph,
699 const path & from_ph )
700 { return create_hard_link<path>( to_ph, from_ph ); }
701 inline void create_hard_link( const wpath & to_ph,
702 const wpath & from_ph )
703 { return create_hard_link<wpath>( to_ph, from_ph ); }
705 inline system::error_code create_hard_link( const path & to_ph,
706 const path & from_ph, system::error_code & ec )
707 { return create_hard_link<path>( to_ph, from_ph, ec ); }
708 inline system::error_code create_hard_link( const wpath & to_ph,
709 const wpath & from_ph, system::error_code & ec )
710 { return create_hard_link<wpath>( to_ph, from_ph, ec ); }
711 #endif
713 inline void create_symlink( const path & to_ph,
714 const path & from_ph )
715 { return create_symlink<path>( to_ph, from_ph ); }
716 inline void create_symlink( const wpath & to_ph,
717 const wpath & from_ph )
718 { return create_symlink<wpath>( to_ph, from_ph ); }
720 inline system::error_code create_symlink( const path & to_ph,
721 const path & from_ph, system::error_code & ec )
722 { return create_symlink<path>( to_ph, from_ph, ec ); }
723 inline system::error_code create_symlink( const wpath & to_ph,
724 const wpath & from_ph, system::error_code & ec )
725 { return create_symlink<wpath>( to_ph, from_ph, ec ); }
727 inline bool remove( const path & ph )
728 { return remove<path>( ph ); }
729 inline bool remove( const wpath & ph )
730 { return remove<wpath>( ph ); }
732 inline unsigned long remove_all( const path & ph )
733 { return remove_all<path>( ph ); }
734 inline unsigned long remove_all( const wpath & ph )
735 { return remove_all<wpath>( ph ); }
737 inline void rename( const path & from_path, const path & to_path )
738 { return rename<path>( from_path, to_path ); }
739 inline void rename( const wpath & from_path, const wpath & to_path )
740 { return rename<wpath>( from_path, to_path ); }
742 inline void copy_file( const path & from_path, const path & to_path )
743 { return copy_file<path>( from_path, to_path ); }
744 inline void copy_file( const wpath & from_path, const wpath & to_path )
745 { return copy_file<wpath>( from_path, to_path ); }
747 inline path system_complete( const path & ph )
748 { return system_complete<path>( ph ); }
749 inline wpath system_complete( const wpath & ph )
750 { return system_complete<wpath>( ph ); }
752 inline path complete( const path & ph,
753 const path & base/* = initial_path<path>()*/ )
754 { return complete<path>( ph, base ); }
755 inline wpath complete( const wpath & ph,
756 const wpath & base/* = initial_path<wpath>()*/ )
757 { return complete<wpath>( ph, base ); }
759 inline path complete( const path & ph )
760 { return complete<path>( ph, initial_path<path>() ); }
761 inline wpath complete( const wpath & ph )
762 { return complete<wpath>( ph, initial_path<wpath>() ); }
764 inline void last_write_time( const path & ph, const std::time_t new_time )
765 { last_write_time<path>( ph, new_time ); }
766 inline void last_write_time( const wpath & ph, const std::time_t new_time )
767 { last_write_time<wpath>( ph, new_time ); }
769 inline void current_path( const path & ph )
770 { current_path<path>( ph ); }
771 inline void current_path( const wpath & ph )
772 { current_path<wpath>( ph ); }
774 # endif // ifndef BOOST_FILESYSTEM_NARROW_ONLY
776 namespace detail
778 template<class Path>
779 bool remove_aux( const Path & ph, file_status f )
781 if ( exists( f ) )
783 system::error_code ec = remove_api( ph.external_file_string() );
784 if ( ec )
785 boost::throw_exception( basic_filesystem_error<Path>(
786 "boost::filesystem::remove", ph, ec ) );
787 return true;
789 return false;
792 template<class Path>
793 unsigned long remove_all_aux( const Path & ph, file_status f )
795 static const boost::filesystem::basic_directory_iterator<Path> end_itr;
796 unsigned long count = 1;
797 if ( !boost::filesystem::is_symlink( f ) // don't recurse symbolic links
798 && boost::filesystem::is_directory( f ) )
800 for ( boost::filesystem::basic_directory_iterator<Path> itr( ph );
801 itr != end_itr; ++itr )
803 boost::system::error_code ec;
804 boost::filesystem::file_status fn = boost::filesystem::symlink_status( itr->path(), ec );
805 if ( ec )
806 boost::throw_exception( basic_filesystem_error<Path>(
807 "boost::filesystem:remove_all", ph, ec ) );
808 count += remove_all_aux( itr->path(), fn );
811 remove_aux( ph, f );
812 return count;
815 // test helper -------------------------------------------------------------//
817 // not part of the documented interface because false positives are possible;
818 // there is no law that says that an OS that has large stat.st_size
819 // actually supports large file sizes.
820 BOOST_FILESYSTEM_DECL bool possible_large_file_size_support();
822 // directory_iterator helpers ----------------------------------------------//
824 // forwarding functions avoid need for BOOST_FILESYSTEM_DECL for class
825 // basic_directory_iterator, and so avoid iterator_facade DLL template
826 // problems. They also overload to the proper external path character type.
828 BOOST_FILESYSTEM_DECL system::error_code
829 dir_itr_first( void *& handle,
830 #if defined(BOOST_POSIX_API)
831 void *& buffer,
832 #endif
833 const std::string & dir_path,
834 std::string & target, file_status & fs, file_status & symlink_fs );
835 // eof: return==0 && handle==0
837 BOOST_FILESYSTEM_DECL system::error_code
838 dir_itr_increment( void *& handle,
839 #if defined(BOOST_POSIX_API)
840 void *& buffer,
841 #endif
842 std::string & target, file_status & fs, file_status & symlink_fs );
843 // eof: return==0 && handle==0
845 BOOST_FILESYSTEM_DECL system::error_code
846 dir_itr_close( void *& handle
847 #if defined(BOOST_POSIX_API)
848 , void *& buffer
849 #endif
851 // Effects: none if handle==0, otherwise close handle, set handle=0
853 # if defined(BOOST_WINDOWS_API) && !defined(BOOST_FILESYSTEM_NARROW_ONLY)
854 BOOST_FILESYSTEM_DECL system::error_code
855 dir_itr_first( void *& handle, const std::wstring & ph,
856 std::wstring & target, file_status & fs, file_status & symlink_fs );
857 BOOST_FILESYSTEM_DECL system::error_code
858 dir_itr_increment( void *& handle, std::wstring & target,
859 file_status & fs, file_status & symlink_fs );
860 # endif
862 template< class Path >
863 class dir_itr_imp
865 public:
866 basic_directory_entry<Path> m_directory_entry;
867 void * m_handle;
868 # ifdef BOOST_POSIX_API
869 void * m_buffer; // see dir_itr_increment implementation
870 # endif
871 dir_itr_imp() : m_handle(0)
872 # ifdef BOOST_POSIX_API
873 , m_buffer(0)
874 # endif
877 ~dir_itr_imp() { dir_itr_close( m_handle
878 #if defined(BOOST_POSIX_API)
879 , m_buffer
880 #endif
881 ); }
884 BOOST_FILESYSTEM_DECL system::error_code not_found_error();
886 } // namespace detail
888 // basic_directory_iterator ------------------------------------------------//
890 template< class Path >
891 class basic_directory_iterator
892 : public boost::iterator_facade<
893 basic_directory_iterator<Path>,
894 basic_directory_entry<Path>,
895 boost::single_pass_traversal_tag >
897 public:
898 typedef Path path_type;
900 basic_directory_iterator(){} // creates the "end" iterator
902 explicit basic_directory_iterator( const Path & dir_path );
903 basic_directory_iterator( const Path & dir_path, system::error_code & ec );
905 private:
907 // shared_ptr provides shallow-copy semantics required for InputIterators.
908 // m_imp.get()==0 indicates the end iterator.
909 boost::shared_ptr< detail::dir_itr_imp< Path > > m_imp;
911 friend class boost::iterator_core_access;
913 typename boost::iterator_facade<
914 basic_directory_iterator<Path>,
915 basic_directory_entry<Path>,
916 boost::single_pass_traversal_tag >::reference dereference() const
918 BOOST_ASSERT( m_imp.get() && "attempt to dereference end iterator" );
919 return m_imp->m_directory_entry;
922 void increment();
924 bool equal( const basic_directory_iterator & rhs ) const
925 { return m_imp == rhs.m_imp; }
927 system::error_code m_init( const Path & dir_path );
930 typedef basic_directory_iterator< path > directory_iterator;
931 # ifndef BOOST_FILESYSTEM_NARROW_ONLY
932 typedef basic_directory_iterator< wpath > wdirectory_iterator;
933 # endif
935 // basic_directory_iterator implementation ---------------------------//
937 template<class Path>
938 system::error_code basic_directory_iterator<Path>::m_init(
939 const Path & dir_path )
941 if ( dir_path.empty() )
943 m_imp.reset();
944 return detail::not_found_error();
946 typename Path::external_string_type name;
947 file_status fs, symlink_fs;
948 system::error_code ec( detail::dir_itr_first( m_imp->m_handle,
949 #if defined(BOOST_POSIX_API)
950 m_imp->m_buffer,
951 #endif
952 dir_path.external_directory_string(),
953 name, fs, symlink_fs ) );
955 if ( ec )
957 m_imp.reset();
958 return ec;
961 if ( m_imp->m_handle == 0 ) m_imp.reset(); // eof, so make end iterator
962 else // not eof
964 m_imp->m_directory_entry.assign( dir_path
965 / Path::traits_type::to_internal( name ), fs, symlink_fs );
966 if ( name[0] == dot<Path>::value // dot or dot-dot
967 && (name.size() == 1
968 || (name[1] == dot<Path>::value
969 && name.size() == 2)) )
970 { increment(); }
972 return boost::system::error_code();
975 template<class Path>
976 basic_directory_iterator<Path>::basic_directory_iterator(
977 const Path & dir_path )
978 : m_imp( new detail::dir_itr_imp<Path> )
980 system::error_code ec( m_init(dir_path) );
981 if ( ec )
983 boost::throw_exception( basic_filesystem_error<Path>(
984 "boost::filesystem::basic_directory_iterator constructor",
985 dir_path, ec ) );
989 template<class Path>
990 basic_directory_iterator<Path>::basic_directory_iterator(
991 const Path & dir_path, system::error_code & ec )
992 : m_imp( new detail::dir_itr_imp<Path> )
994 ec = m_init(dir_path);
997 template<class Path>
998 void basic_directory_iterator<Path>::increment()
1000 BOOST_ASSERT( m_imp.get() && "attempt to increment end iterator" );
1001 BOOST_ASSERT( m_imp->m_handle != 0 && "internal program error" );
1003 typename Path::external_string_type name;
1004 file_status fs, symlink_fs;
1005 system::error_code ec;
1007 for (;;)
1009 ec = detail::dir_itr_increment( m_imp->m_handle,
1010 #if defined(BOOST_POSIX_API)
1011 m_imp->m_buffer,
1012 #endif
1013 name, fs, symlink_fs );
1014 if ( ec )
1016 boost::throw_exception( basic_filesystem_error<Path>(
1017 "boost::filesystem::basic_directory_iterator increment",
1018 m_imp->m_directory_entry.path().parent_path(), ec ) );
1020 if ( m_imp->m_handle == 0 ) { m_imp.reset(); return; } // eof, make end
1021 if ( !(name[0] == dot<Path>::value // !(dot or dot-dot)
1022 && (name.size() == 1
1023 || (name[1] == dot<Path>::value
1024 && name.size() == 2))) )
1026 m_imp->m_directory_entry.replace_filename(
1027 Path::traits_type::to_internal( name ), fs, symlink_fs );
1028 return;
1033 // basic_directory_entry -----------------------------------------------//
1035 template<class Path>
1036 class basic_directory_entry
1038 public:
1039 typedef Path path_type;
1040 typedef typename Path::string_type string_type;
1042 // compiler generated copy-ctor, copy assignment, and destructor apply
1044 basic_directory_entry() {}
1045 explicit basic_directory_entry( const path_type & p,
1046 file_status st = file_status(), file_status symlink_st=file_status() )
1047 : m_path(p), m_status(st), m_symlink_status(symlink_st)
1050 void assign( const path_type & p,
1051 file_status st, file_status symlink_st )
1052 { m_path = p; m_status = st; m_symlink_status = symlink_st; }
1054 void replace_filename( const string_type & s,
1055 file_status st, file_status symlink_st )
1057 m_path.remove_filename();
1058 m_path /= s;
1059 m_status = st;
1060 m_symlink_status = symlink_st;
1063 # ifndef BOOST_FILESYSTEM_NO_DEPRECATED
1064 void replace_leaf( const string_type & s,
1065 file_status st, file_status symlink_st )
1066 { replace_filename( s, st, symlink_st ); }
1067 # endif
1069 const Path & path() const { return m_path; }
1070 file_status status() const;
1071 file_status status( system::error_code & ec ) const;
1072 file_status symlink_status() const;
1073 file_status symlink_status( system::error_code & ec ) const;
1075 // conversion simplifies the most common use of basic_directory_entry
1076 operator const path_type &() const { return m_path; }
1078 # ifndef BOOST_FILESYSTEM_NO_DEPRECATED
1079 // deprecated functions preserve common use cases in legacy code
1080 typename Path::string_type filename() const
1082 return path().filename();
1084 typename Path::string_type leaf() const
1086 return path().filename();
1088 typename Path::string_type string() const
1090 return path().string();
1092 # endif
1094 private:
1095 path_type m_path;
1096 mutable file_status m_status; // stat()-like
1097 mutable file_status m_symlink_status; // lstat()-like
1098 // note: m_symlink_status is not used by Windows implementation
1100 }; // basic_directory_status
1102 typedef basic_directory_entry<path> directory_entry;
1103 # ifndef BOOST_FILESYSTEM_NARROW_ONLY
1104 typedef basic_directory_entry<wpath> wdirectory_entry;
1105 # endif
1107 // basic_directory_entry implementation --------------------------------//
1109 template<class Path>
1110 file_status
1111 basic_directory_entry<Path>::status() const
1113 if ( !status_known( m_status ) )
1115 # ifndef BOOST_WINDOWS_API
1116 if ( status_known( m_symlink_status )
1117 && !is_symlink( m_symlink_status ) )
1118 { m_status = m_symlink_status; }
1119 else { m_status = boost::filesystem::status( m_path ); }
1120 # else
1121 m_status = boost::filesystem::status( m_path );
1122 # endif
1124 return m_status;
1127 template<class Path>
1128 file_status
1129 basic_directory_entry<Path>::status( system::error_code & ec ) const
1131 if ( !status_known( m_status ) )
1133 # ifndef BOOST_WINDOWS_API
1134 if ( status_known( m_symlink_status )
1135 && !is_symlink( m_symlink_status ) )
1136 { ec = boost::system::error_code();; m_status = m_symlink_status; }
1137 else { m_status = boost::filesystem::status( m_path, ec ); }
1138 # else
1139 m_status = boost::filesystem::status( m_path, ec );
1140 # endif
1142 else ec = boost::system::error_code();;
1143 return m_status;
1146 template<class Path>
1147 file_status
1148 basic_directory_entry<Path>::symlink_status() const
1150 # ifndef BOOST_WINDOWS_API
1151 if ( !status_known( m_symlink_status ) )
1152 { m_symlink_status = boost::filesystem::symlink_status( m_path ); }
1153 return m_symlink_status;
1154 # else
1155 return status();
1156 # endif
1159 template<class Path>
1160 file_status
1161 basic_directory_entry<Path>::symlink_status( system::error_code & ec ) const
1163 # ifndef BOOST_WINDOWS_API
1164 if ( !status_known( m_symlink_status ) )
1165 { m_symlink_status = boost::filesystem::symlink_status( m_path, ec ); }
1166 else ec = boost::system::error_code();;
1167 return m_symlink_status;
1168 # else
1169 return status( ec );
1170 # endif
1172 } // namespace filesystem
1173 } // namespace boost
1175 #undef BOOST_FS_FUNC
1178 #include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas
1179 #endif // BOOST_FILESYSTEM_OPERATIONS_HPP