1 // boost/filesystem/operations.hpp -----------------------------------------//
3 // Copyright 2002-2005 Beman Dawes
4 // Copyright 2002 Jan Langer
5 // Copyright 2001 Dietmar Kuehl
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>
28 #include <utility> // for pair
31 #ifdef BOOST_WINDOWS_API
33 # if !defined(_WIN32_WINNT) || _WIN32_WINNT >= 0x0500
34 # define BOOST_FS_HARD_LINK // Default for Windows 2K or later
38 #include <boost/config/abi_prefix.hpp> // must be the last #include
40 # ifdef BOOST_NO_STDC_NAMESPACE
41 namespace std
{ using ::time_t; }
44 //----------------------------------------------------------------------------//
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>, \
56 # define BOOST_INLINE_FS_FUNC(BOOST_FS_TYPE) \
57 template<class Path> inline typename boost::enable_if<is_basic_path<Path>, \
59 # define BOOST_FS_TYPENAME typename
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
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
;
80 // the following will never be reported by some operating or file systems
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
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
; }
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
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
; }
119 // all values are byte counts
120 boost::uintmax_t capacity
;
121 boost::uintmax_t free
; // <= capacity
122 boost::uintmax_t available
; // <= free
127 typedef std::pair
< system::error_code
, bool >
130 typedef std::pair
< system::error_code
, boost::uintmax_t >
133 typedef std::pair
< system::error_code
, std::time_t >
136 typedef std::pair
< system::error_code
, space_info
>
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
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
);
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
);
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
);
236 bool remove_aux( const Path
& ph
, file_status f
);
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
) );
261 boost::throw_exception( basic_filesystem_error
<Path
>(
262 "boost::filesystem::status", ph
, ec
) );
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
); }
271 { return detail::symlink_status_api( ph
.external_file_string(), ec
); }
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
) );
280 boost::throw_exception( basic_filesystem_error
<Path
>(
281 "boost::filesystem::symlink_status", ph
, ec
) );
285 # ifndef BOOST_FILESYSTEM_NO_DEPRECATED
286 inline bool symbolic_link_exists( const path
& ph
)
287 { return is_symlink( symlink_status(ph
) ); }
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
) );
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
) );
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
) );
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
) );
326 boost::throw_exception( basic_filesystem_error
<Path
>(
327 "boost::filesystem::is_regular", ph
, ec
) );
328 return is_regular( result
);
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
) );
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
350 system::error_code ec
;
351 file_status
result( detail::symlink_status_api( ph
.external_file_string(), ec
) );
353 boost::throw_exception( basic_filesystem_error
<Path
>(
354 "boost::filesystem::is_symlink", ph
, ec
) );
355 return is_symlink( result
);
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
363 # if !defined( BOOST_MSVC ) || BOOST_MSVC > 1300
364 BOOST_FS_FUNC(bool) is_empty( const Path
& ph
)
366 BOOST_FS_FUNC(bool) _is_empty( const Path
& ph
)
369 detail::query_pair
result(
370 detail::is_empty_api( ph
.external_file_string() ) );
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() ) );
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() ) );
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() ) );
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() ) );
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() ) );
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)
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() ) );
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() );
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() ) );
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() );
479 BOOST_FS_FUNC(bool) remove( const Path
& ph
)
481 system::error_code ec
;
482 file_status f
= symlink_status( ph
, 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
);
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() ) );
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
) );
521 boost::throw_exception( basic_filesystem_error
<Path
>(
522 "boost::filesystem::copy_file",
523 from_path
, to_path
, ec
) );
526 template< class Path
>
529 typename
Path::external_string_type ph
;
530 system::error_code
ec( detail::get_current_path_api( ph
) );
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() ) );
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
>();
554 # ifndef BOOST_FILESYSTEM_NO_DEPRECATED
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
>(); }
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(),
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
) );
574 return (ph
.empty() || ph
.is_complete())
575 ? ph
: current_path
<Path
>() / ph
;
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
594 return (ph
.empty() || ph
.is_complete()) ? ph
: base
/ ph
;
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
>() ); }
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(),
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
); }
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
); }
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
779 bool remove_aux( const Path
& ph
, file_status f
)
783 system::error_code ec
= remove_api( ph
.external_file_string() );
785 boost::throw_exception( basic_filesystem_error
<Path
>(
786 "boost::filesystem::remove", ph
, ec
) );
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
);
806 boost::throw_exception( basic_filesystem_error
<Path
>(
807 "boost::filesystem:remove_all", ph
, ec
) );
808 count
+= remove_all_aux( itr
->path(), fn
);
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)
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)
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)
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
);
862 template< class Path
>
866 basic_directory_entry
<Path
> m_directory_entry
;
868 # ifdef BOOST_POSIX_API
869 void * m_buffer
; // see dir_itr_increment implementation
871 dir_itr_imp() : m_handle(0)
872 # ifdef BOOST_POSIX_API
877 ~dir_itr_imp() { dir_itr_close( m_handle
878 #if defined(BOOST_POSIX_API)
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
>
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
);
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
;
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
;
935 // basic_directory_iterator implementation ---------------------------//
938 system::error_code basic_directory_iterator
<Path
>::m_init(
939 const Path
& dir_path
)
941 if ( dir_path
.empty() )
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)
952 dir_path
.external_directory_string(),
953 name
, fs
, symlink_fs
) );
961 if ( m_imp
->m_handle
== 0 ) m_imp
.reset(); // eof, so make end iterator
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
968 || (name
[1] == dot
<Path
>::value
969 && name
.size() == 2)) )
972 return boost::system::error_code();
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
) );
983 boost::throw_exception( basic_filesystem_error
<Path
>(
984 "boost::filesystem::basic_directory_iterator constructor",
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
);
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
;
1009 ec
= detail::dir_itr_increment( m_imp
->m_handle
,
1010 #if defined(BOOST_POSIX_API)
1013 name
, fs
, symlink_fs
);
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
);
1033 // basic_directory_entry -----------------------------------------------//
1035 template<class Path
>
1036 class basic_directory_entry
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();
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
); }
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();
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
;
1107 // basic_directory_entry implementation --------------------------------//
1109 template<class Path
>
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
); }
1121 m_status
= boost::filesystem::status( m_path
);
1127 template<class Path
>
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
); }
1139 m_status
= boost::filesystem::status( m_path
, ec
);
1142 else ec
= boost::system::error_code();;
1146 template<class Path
>
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
;
1159 template<class Path
>
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
;
1169 return status( ec
);
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