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