annotate DEPENDENCIES/generic/include/boost/filesystem/operations.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 // boost/filesystem/operations.hpp ---------------------------------------------------//
Chris@16 2
Chris@16 3 // Copyright Beman Dawes 2002-2009
Chris@16 4 // Copyright Jan Langer 2002
Chris@16 5 // Copyright Dietmar Kuehl 2001
Chris@16 6 // Copyright Vladimir Prus 2002
Chris@16 7
Chris@16 8 // Distributed under the Boost Software License, Version 1.0.
Chris@16 9 // See http://www.boost.org/LICENSE_1_0.txt
Chris@16 10
Chris@16 11 // Library home page: http://www.boost.org/libs/filesystem
Chris@16 12
Chris@16 13 //--------------------------------------------------------------------------------------//
Chris@16 14
Chris@16 15 #ifndef BOOST_FILESYSTEM3_OPERATIONS_HPP
Chris@16 16 #define BOOST_FILESYSTEM3_OPERATIONS_HPP
Chris@16 17
Chris@16 18 #include <boost/config.hpp>
Chris@16 19
Chris@16 20 # if defined( BOOST_NO_STD_WSTRING )
Chris@16 21 # error Configuration not supported: Boost.Filesystem V3 and later requires std::wstring support
Chris@16 22 # endif
Chris@16 23
Chris@16 24 #include <boost/filesystem/config.hpp>
Chris@16 25 #include <boost/filesystem/path.hpp>
Chris@16 26
Chris@16 27 #include <boost/detail/scoped_enum_emulation.hpp>
Chris@16 28 #include <boost/detail/bitmask.hpp>
Chris@16 29 #include <boost/system/error_code.hpp>
Chris@16 30 #include <boost/system/system_error.hpp>
Chris@16 31 #include <boost/shared_ptr.hpp>
Chris@16 32 #include <boost/utility/enable_if.hpp>
Chris@16 33 #include <boost/type_traits/is_same.hpp>
Chris@16 34 #include <boost/iterator.hpp>
Chris@16 35 #include <boost/cstdint.hpp>
Chris@101 36 #include <boost/range/mutable_iterator.hpp>
Chris@101 37 #include <boost/range/const_iterator.hpp>
Chris@16 38 #include <boost/assert.hpp>
Chris@16 39 #include <string>
Chris@16 40 #include <utility> // for pair
Chris@16 41 #include <ctime>
Chris@16 42 #include <vector>
Chris@16 43 #include <stack>
Chris@16 44
Chris@16 45 #ifdef BOOST_WINDOWS_API
Chris@16 46 # include <fstream>
Chris@16 47 #endif
Chris@16 48
Chris@16 49 #include <boost/config/abi_prefix.hpp> // must be the last #include
Chris@16 50
Chris@16 51 //--------------------------------------------------------------------------------------//
Chris@16 52
Chris@16 53 namespace boost
Chris@16 54 {
Chris@16 55 namespace filesystem
Chris@16 56 {
Chris@16 57
Chris@101 58 //--------------------------------------------------------------------------------------//
Chris@101 59 // //
Chris@101 60 // class filesystem_error //
Chris@101 61 // //
Chris@101 62 //--------------------------------------------------------------------------------------//
Chris@101 63
Chris@101 64 class BOOST_SYMBOL_VISIBLE filesystem_error : public system::system_error
Chris@101 65 {
Chris@101 66 // see http://www.boost.org/more/error_handling.html for design rationale
Chris@101 67
Chris@101 68 // all functions are inline to avoid issues with crossing dll boundaries
Chris@101 69
Chris@101 70 // functions previously throw() are now BOOST_NOEXCEPT_OR_NOTHROW
Chris@101 71 // functions previously without throw() are now BOOST_NOEXCEPT
Chris@101 72
Chris@101 73 public:
Chris@101 74 // compiler generates copy constructor and copy assignment
Chris@101 75
Chris@101 76 filesystem_error(
Chris@101 77 const std::string & what_arg, system::error_code ec) BOOST_NOEXCEPT
Chris@101 78 : system::system_error(ec, what_arg)
Chris@101 79 {
Chris@101 80 try
Chris@101 81 {
Chris@101 82 m_imp_ptr.reset(new m_imp);
Chris@101 83 }
Chris@101 84 catch (...) { m_imp_ptr.reset(); }
Chris@101 85 }
Chris@101 86
Chris@101 87 filesystem_error(
Chris@101 88 const std::string & what_arg, const path& path1_arg,
Chris@101 89 system::error_code ec) BOOST_NOEXCEPT
Chris@101 90 : system::system_error(ec, what_arg)
Chris@101 91 {
Chris@101 92 try
Chris@101 93 {
Chris@101 94 m_imp_ptr.reset(new m_imp);
Chris@101 95 m_imp_ptr->m_path1 = path1_arg;
Chris@101 96 }
Chris@101 97 catch (...) { m_imp_ptr.reset(); }
Chris@101 98 }
Chris@101 99
Chris@101 100 filesystem_error(
Chris@101 101 const std::string & what_arg, const path& path1_arg,
Chris@101 102 const path& path2_arg, system::error_code ec) BOOST_NOEXCEPT
Chris@101 103 : system::system_error(ec, what_arg)
Chris@101 104 {
Chris@101 105 try
Chris@101 106 {
Chris@101 107 m_imp_ptr.reset(new m_imp);
Chris@101 108 m_imp_ptr->m_path1 = path1_arg;
Chris@101 109 m_imp_ptr->m_path2 = path2_arg;
Chris@101 110 }
Chris@101 111 catch (...) { m_imp_ptr.reset(); }
Chris@101 112 }
Chris@101 113
Chris@101 114 ~filesystem_error() BOOST_NOEXCEPT_OR_NOTHROW{}
Chris@101 115
Chris@101 116 const path& path1() const BOOST_NOEXCEPT
Chris@101 117 {
Chris@101 118 static const path empty_path;
Chris@101 119 return m_imp_ptr.get() ? m_imp_ptr->m_path1 : empty_path;
Chris@101 120 }
Chris@101 121 const path& path2() const BOOST_NOEXCEPT
Chris@101 122 {
Chris@101 123 static const path empty_path;
Chris@101 124 return m_imp_ptr.get() ? m_imp_ptr->m_path2 : empty_path;
Chris@101 125 }
Chris@101 126
Chris@101 127 const char* what() const BOOST_NOEXCEPT_OR_NOTHROW
Chris@101 128 {
Chris@101 129 if (!m_imp_ptr.get())
Chris@101 130 return system::system_error::what();
Chris@101 131
Chris@101 132 try
Chris@101 133 {
Chris@101 134 if (m_imp_ptr->m_what.empty())
Chris@101 135 {
Chris@101 136 m_imp_ptr->m_what = system::system_error::what();
Chris@101 137 if (!m_imp_ptr->m_path1.empty())
Chris@101 138 {
Chris@101 139 m_imp_ptr->m_what += ": \"";
Chris@101 140 m_imp_ptr->m_what += m_imp_ptr->m_path1.string();
Chris@101 141 m_imp_ptr->m_what += "\"";
Chris@101 142 }
Chris@101 143 if (!m_imp_ptr->m_path2.empty())
Chris@101 144 {
Chris@101 145 m_imp_ptr->m_what += ", \"";
Chris@101 146 m_imp_ptr->m_what += m_imp_ptr->m_path2.string();
Chris@101 147 m_imp_ptr->m_what += "\"";
Chris@101 148 }
Chris@101 149 }
Chris@101 150 return m_imp_ptr->m_what.c_str();
Chris@101 151 }
Chris@101 152 catch (...)
Chris@101 153 {
Chris@101 154 return system::system_error::what();
Chris@101 155 }
Chris@101 156 }
Chris@101 157
Chris@101 158 private:
Chris@101 159 struct m_imp
Chris@101 160 {
Chris@101 161 path m_path1; // may be empty()
Chris@101 162 path m_path2; // may be empty()
Chris@101 163 std::string m_what; // not built until needed
Chris@101 164 };
Chris@101 165 boost::shared_ptr<m_imp> m_imp_ptr;
Chris@101 166 };
Chris@101 167
Chris@16 168 //--------------------------------------------------------------------------------------//
Chris@16 169 // file_type //
Chris@16 170 //--------------------------------------------------------------------------------------//
Chris@16 171
Chris@16 172 enum file_type
Chris@16 173 {
Chris@16 174 status_error,
Chris@16 175 # ifndef BOOST_FILESYSTEM_NO_DEPRECATED
Chris@16 176 status_unknown = status_error,
Chris@16 177 # endif
Chris@16 178 file_not_found,
Chris@16 179 regular_file,
Chris@16 180 directory_file,
Chris@16 181 // the following may not apply to some operating systems or file systems
Chris@16 182 symlink_file,
Chris@16 183 block_file,
Chris@16 184 character_file,
Chris@16 185 fifo_file,
Chris@16 186 socket_file,
Chris@16 187 reparse_file, // Windows: FILE_ATTRIBUTE_REPARSE_POINT that is not a symlink
Chris@16 188 type_unknown, // file does exist, but isn't one of the above types or
Chris@16 189 // we don't have strong enough permission to find its type
Chris@16 190
Chris@16 191 _detail_directory_symlink // internal use only; never exposed to users
Chris@16 192 };
Chris@16 193
Chris@16 194 //--------------------------------------------------------------------------------------//
Chris@16 195 // perms //
Chris@16 196 //--------------------------------------------------------------------------------------//
Chris@16 197
Chris@16 198 enum perms
Chris@16 199 {
Chris@16 200 no_perms = 0, // file_not_found is no_perms rather than perms_not_known
Chris@16 201
Chris@16 202 // POSIX equivalent macros given in comments.
Chris@16 203 // Values are from POSIX and are given in octal per the POSIX standard.
Chris@16 204
Chris@16 205 // permission bits
Chris@16 206
Chris@16 207 owner_read = 0400, // S_IRUSR, Read permission, owner
Chris@16 208 owner_write = 0200, // S_IWUSR, Write permission, owner
Chris@16 209 owner_exe = 0100, // S_IXUSR, Execute/search permission, owner
Chris@16 210 owner_all = 0700, // S_IRWXU, Read, write, execute/search by owner
Chris@16 211
Chris@16 212 group_read = 040, // S_IRGRP, Read permission, group
Chris@16 213 group_write = 020, // S_IWGRP, Write permission, group
Chris@16 214 group_exe = 010, // S_IXGRP, Execute/search permission, group
Chris@16 215 group_all = 070, // S_IRWXG, Read, write, execute/search by group
Chris@16 216
Chris@16 217 others_read = 04, // S_IROTH, Read permission, others
Chris@16 218 others_write = 02, // S_IWOTH, Write permission, others
Chris@16 219 others_exe = 01, // S_IXOTH, Execute/search permission, others
Chris@16 220 others_all = 07, // S_IRWXO, Read, write, execute/search by others
Chris@16 221
Chris@101 222 all_all = 0777, // owner_all|group_all|others_all
Chris@16 223
Chris@16 224 // other POSIX bits
Chris@16 225
Chris@16 226 set_uid_on_exe = 04000, // S_ISUID, Set-user-ID on execution
Chris@16 227 set_gid_on_exe = 02000, // S_ISGID, Set-group-ID on execution
Chris@16 228 sticky_bit = 01000, // S_ISVTX,
Chris@16 229 // (POSIX XSI) On directories, restricted deletion flag
Chris@101 230 // (V7) 'sticky bit': save swapped text even after use
Chris@16 231 // (SunOS) On non-directories: don't cache this file
Chris@16 232 // (SVID-v4.2) On directories: restricted deletion flag
Chris@16 233 // Also see http://en.wikipedia.org/wiki/Sticky_bit
Chris@16 234
Chris@101 235 perms_mask = 07777, // all_all|set_uid_on_exe|set_gid_on_exe|sticky_bit
Chris@16 236
Chris@16 237 perms_not_known = 0xFFFF, // present when directory_entry cache not loaded
Chris@16 238
Chris@16 239 // options for permissions() function
Chris@16 240
Chris@16 241 add_perms = 0x1000, // adds the given permission bits to the current bits
Chris@16 242 remove_perms = 0x2000, // removes the given permission bits from the current bits;
Chris@16 243 // choose add_perms or remove_perms, not both; if neither add_perms
Chris@16 244 // nor remove_perms is given, replace the current bits with
Chris@16 245 // the given bits.
Chris@16 246
Chris@16 247 symlink_perms = 0x4000 // on POSIX, don't resolve symlinks; implied on Windows
Chris@16 248 };
Chris@16 249
Chris@16 250 BOOST_BITMASK(perms)
Chris@16 251
Chris@16 252 //--------------------------------------------------------------------------------------//
Chris@16 253 // file_status //
Chris@16 254 //--------------------------------------------------------------------------------------//
Chris@16 255
Chris@16 256 class BOOST_FILESYSTEM_DECL file_status
Chris@16 257 {
Chris@16 258 public:
Chris@16 259 file_status() : m_value(status_error), m_perms(perms_not_known) {}
Chris@16 260 explicit file_status(file_type v, perms prms = perms_not_known)
Chris@16 261 : m_value(v), m_perms(prms) {}
Chris@16 262
Chris@16 263 // observers
Chris@16 264 file_type type() const { return m_value; }
Chris@16 265 perms permissions() const { return m_perms; }
Chris@16 266
Chris@16 267 // modifiers
Chris@16 268 void type(file_type v) { m_value = v; }
Chris@16 269 void permissions(perms prms) { m_perms = prms; }
Chris@16 270
Chris@16 271 bool operator==(const file_status& rhs) const { return type() == rhs.type() &&
Chris@16 272 permissions() == rhs.permissions(); }
Chris@16 273 bool operator!=(const file_status& rhs) const { return !(*this == rhs); }
Chris@16 274
Chris@16 275 private:
Chris@16 276 file_type m_value;
Chris@16 277 enum perms m_perms;
Chris@16 278 };
Chris@16 279
Chris@16 280 inline bool type_present(file_status f) { return f.type() != status_error; }
Chris@16 281 inline bool permissions_present(file_status f)
Chris@16 282 {return f.permissions() != perms_not_known;}
Chris@16 283 inline bool status_known(file_status f) { return type_present(f) && permissions_present(f); }
Chris@16 284 inline bool exists(file_status f) { return f.type() != status_error
Chris@16 285 && f.type() != file_not_found; }
Chris@16 286 inline bool is_regular_file(file_status f){ return f.type() == regular_file; }
Chris@16 287 inline bool is_directory(file_status f) { return f.type() == directory_file; }
Chris@16 288 inline bool is_symlink(file_status f) { return f.type() == symlink_file; }
Chris@16 289 inline bool is_other(file_status f) { return exists(f) && !is_regular_file(f)
Chris@16 290 && !is_directory(f) && !is_symlink(f); }
Chris@16 291
Chris@16 292 # ifndef BOOST_FILESYSTEM_NO_DEPRECATED
Chris@16 293 inline bool is_regular(file_status f) { return f.type() == regular_file; }
Chris@16 294 # endif
Chris@16 295
Chris@16 296 struct space_info
Chris@16 297 {
Chris@16 298 // all values are byte counts
Chris@16 299 boost::uintmax_t capacity;
Chris@16 300 boost::uintmax_t free; // <= capacity
Chris@16 301 boost::uintmax_t available; // <= free
Chris@16 302 };
Chris@16 303
Chris@16 304 BOOST_SCOPED_ENUM_START(copy_option)
Chris@101 305 {none=0, fail_if_exists = none, overwrite_if_exists};
Chris@16 306 BOOST_SCOPED_ENUM_END
Chris@16 307
Chris@16 308 //--------------------------------------------------------------------------------------//
Chris@16 309 // implementation details //
Chris@16 310 //--------------------------------------------------------------------------------------//
Chris@16 311
Chris@16 312 namespace detail
Chris@16 313 {
Chris@101 314 // We cannot pass a BOOST_SCOPED_ENUM to a compled function because it will result
Chris@101 315 // in an undefined reference if the library is compled with -std=c++0x but the use
Chris@101 316 // is compiled in C++03 mode, or visa versa. See tickets 6124, 6779, 10038.
Chris@101 317 enum copy_option {none=0, fail_if_exists = none, overwrite_if_exists};
Chris@101 318
Chris@16 319 BOOST_FILESYSTEM_DECL
Chris@16 320 file_status status(const path&p, system::error_code* ec=0);
Chris@16 321 BOOST_FILESYSTEM_DECL
Chris@16 322 file_status symlink_status(const path& p, system::error_code* ec=0);
Chris@16 323 BOOST_FILESYSTEM_DECL
Chris@16 324 bool is_empty(const path& p, system::error_code* ec=0);
Chris@16 325 BOOST_FILESYSTEM_DECL
Chris@16 326 path initial_path(system::error_code* ec=0);
Chris@16 327 BOOST_FILESYSTEM_DECL
Chris@16 328 path canonical(const path& p, const path& base, system::error_code* ec=0);
Chris@16 329 BOOST_FILESYSTEM_DECL
Chris@16 330 void copy(const path& from, const path& to, system::error_code* ec=0);
Chris@16 331 BOOST_FILESYSTEM_DECL
Chris@16 332 void copy_directory(const path& from, const path& to, system::error_code* ec=0);
Chris@16 333 BOOST_FILESYSTEM_DECL
Chris@101 334 void copy_file(const path& from, const path& to, // See ticket #2925
Chris@101 335 detail::copy_option option, system::error_code* ec=0);
Chris@16 336 BOOST_FILESYSTEM_DECL
Chris@16 337 void copy_symlink(const path& existing_symlink, const path& new_symlink, system::error_code* ec=0);
Chris@16 338 BOOST_FILESYSTEM_DECL
Chris@16 339 bool create_directories(const path& p, system::error_code* ec=0);
Chris@16 340 BOOST_FILESYSTEM_DECL
Chris@16 341 bool create_directory(const path& p, system::error_code* ec=0);
Chris@16 342 BOOST_FILESYSTEM_DECL
Chris@16 343 void create_directory_symlink(const path& to, const path& from,
Chris@16 344 system::error_code* ec=0);
Chris@16 345 BOOST_FILESYSTEM_DECL
Chris@16 346 void create_hard_link(const path& to, const path& from, system::error_code* ec=0);
Chris@16 347 BOOST_FILESYSTEM_DECL
Chris@16 348 void create_symlink(const path& to, const path& from, system::error_code* ec=0);
Chris@16 349 BOOST_FILESYSTEM_DECL
Chris@16 350 path current_path(system::error_code* ec=0);
Chris@16 351 BOOST_FILESYSTEM_DECL
Chris@16 352 void current_path(const path& p, system::error_code* ec=0);
Chris@16 353 BOOST_FILESYSTEM_DECL
Chris@16 354 bool equivalent(const path& p1, const path& p2, system::error_code* ec=0);
Chris@16 355 BOOST_FILESYSTEM_DECL
Chris@16 356 boost::uintmax_t file_size(const path& p, system::error_code* ec=0);
Chris@16 357 BOOST_FILESYSTEM_DECL
Chris@16 358 boost::uintmax_t hard_link_count(const path& p, system::error_code* ec=0);
Chris@16 359 BOOST_FILESYSTEM_DECL
Chris@16 360 std::time_t last_write_time(const path& p, system::error_code* ec=0);
Chris@16 361 BOOST_FILESYSTEM_DECL
Chris@16 362 void last_write_time(const path& p, const std::time_t new_time,
Chris@16 363 system::error_code* ec=0);
Chris@16 364 BOOST_FILESYSTEM_DECL
Chris@16 365 void permissions(const path& p, perms prms, system::error_code* ec=0);
Chris@16 366 BOOST_FILESYSTEM_DECL
Chris@16 367 path read_symlink(const path& p, system::error_code* ec=0);
Chris@16 368 BOOST_FILESYSTEM_DECL
Chris@16 369 // For standardization, if the committee doesn't like "remove", consider "eliminate"
Chris@16 370 bool remove(const path& p, system::error_code* ec=0);
Chris@16 371 BOOST_FILESYSTEM_DECL
Chris@16 372 boost::uintmax_t remove_all(const path& p, system::error_code* ec=0);
Chris@16 373 BOOST_FILESYSTEM_DECL
Chris@16 374 void rename(const path& old_p, const path& new_p, system::error_code* ec=0);
Chris@16 375 BOOST_FILESYSTEM_DECL
Chris@16 376 void resize_file(const path& p, uintmax_t size, system::error_code* ec=0);
Chris@16 377 BOOST_FILESYSTEM_DECL
Chris@16 378 space_info space(const path& p, system::error_code* ec=0);
Chris@16 379 BOOST_FILESYSTEM_DECL
Chris@16 380 path system_complete(const path& p, system::error_code* ec=0);
Chris@16 381 BOOST_FILESYSTEM_DECL
Chris@16 382 path temp_directory_path(system::error_code* ec=0);
Chris@16 383 BOOST_FILESYSTEM_DECL
Chris@16 384 path unique_path(const path& p, system::error_code* ec=0);
Chris@16 385 } // namespace detail
Chris@16 386
Chris@16 387 //--------------------------------------------------------------------------------------//
Chris@16 388 // //
Chris@16 389 // status query functions //
Chris@16 390 // //
Chris@16 391 //--------------------------------------------------------------------------------------//
Chris@16 392
Chris@16 393 inline
Chris@16 394 file_status status(const path& p) {return detail::status(p);}
Chris@16 395 inline
Chris@16 396 file_status status(const path& p, system::error_code& ec)
Chris@16 397 {return detail::status(p, &ec);}
Chris@16 398 inline
Chris@16 399 file_status symlink_status(const path& p) {return detail::symlink_status(p);}
Chris@16 400 inline
Chris@16 401 file_status symlink_status(const path& p, system::error_code& ec)
Chris@16 402 {return detail::symlink_status(p, &ec);}
Chris@16 403 inline
Chris@16 404 bool exists(const path& p) {return exists(detail::status(p));}
Chris@16 405 inline
Chris@16 406 bool exists(const path& p, system::error_code& ec)
Chris@16 407 {return exists(detail::status(p, &ec));}
Chris@16 408 inline
Chris@16 409 bool is_directory(const path& p) {return is_directory(detail::status(p));}
Chris@16 410 inline
Chris@16 411 bool is_directory(const path& p, system::error_code& ec)
Chris@16 412 {return is_directory(detail::status(p, &ec));}
Chris@16 413 inline
Chris@16 414 bool is_regular_file(const path& p) {return is_regular_file(detail::status(p));}
Chris@16 415 inline
Chris@16 416 bool is_regular_file(const path& p, system::error_code& ec)
Chris@16 417 {return is_regular_file(detail::status(p, &ec));}
Chris@16 418 inline
Chris@16 419 bool is_other(const path& p) {return is_other(detail::status(p));}
Chris@16 420 inline
Chris@16 421 bool is_other(const path& p, system::error_code& ec)
Chris@16 422 {return is_other(detail::status(p, &ec));}
Chris@16 423 inline
Chris@16 424 bool is_symlink(const path& p) {return is_symlink(detail::symlink_status(p));}
Chris@16 425 inline
Chris@16 426 bool is_symlink(const path& p, system::error_code& ec)
Chris@16 427 {return is_symlink(detail::symlink_status(p, &ec));}
Chris@16 428 # ifndef BOOST_FILESYSTEM_NO_DEPRECATED
Chris@16 429 inline
Chris@16 430 bool is_regular(const path& p) {return is_regular(detail::status(p));}
Chris@16 431 inline
Chris@16 432 bool is_regular(const path& p, system::error_code& ec)
Chris@16 433 {return is_regular(detail::status(p, &ec));}
Chris@16 434 # endif
Chris@16 435
Chris@16 436 inline
Chris@16 437 bool is_empty(const path& p) {return detail::is_empty(p);}
Chris@16 438 inline
Chris@16 439 bool is_empty(const path& p, system::error_code& ec)
Chris@16 440 {return detail::is_empty(p, &ec);}
Chris@16 441
Chris@16 442 //--------------------------------------------------------------------------------------//
Chris@16 443 // //
Chris@16 444 // operational functions //
Chris@16 445 // in alphabetical order, unless otherwise noted //
Chris@16 446 // //
Chris@16 447 //--------------------------------------------------------------------------------------//
Chris@16 448
Chris@16 449 // forward declarations
Chris@16 450 path current_path(); // fwd declaration
Chris@16 451 path initial_path();
Chris@16 452
Chris@16 453 BOOST_FILESYSTEM_DECL
Chris@16 454 path absolute(const path& p, const path& base=current_path());
Chris@16 455 // If base.is_absolute(), throws nothing. Thus no need for ec argument
Chris@16 456
Chris@16 457 inline
Chris@16 458 path canonical(const path& p, const path& base=current_path())
Chris@16 459 {return detail::canonical(p, base);}
Chris@16 460 inline
Chris@16 461 path canonical(const path& p, system::error_code& ec)
Chris@16 462 {return detail::canonical(p, current_path(), &ec);}
Chris@16 463 inline
Chris@16 464 path canonical(const path& p, const path& base, system::error_code& ec)
Chris@16 465 {return detail::canonical(p, base, &ec);}
Chris@16 466
Chris@16 467 # ifndef BOOST_FILESYSTEM_NO_DEPRECATED
Chris@16 468 inline
Chris@16 469 path complete(const path& p)
Chris@16 470 {
Chris@16 471 return absolute(p, initial_path());
Chris@16 472 }
Chris@16 473
Chris@16 474 inline
Chris@16 475 path complete(const path& p, const path& base)
Chris@16 476 {
Chris@16 477 return absolute(p, base);
Chris@16 478 }
Chris@16 479 # endif
Chris@16 480
Chris@16 481 inline
Chris@16 482 void copy(const path& from, const path& to) {detail::copy(from, to);}
Chris@16 483
Chris@16 484 inline
Chris@16 485 void copy(const path& from, const path& to, system::error_code& ec)
Chris@16 486 {detail::copy(from, to, &ec);}
Chris@16 487 inline
Chris@16 488 void copy_directory(const path& from, const path& to)
Chris@16 489 {detail::copy_directory(from, to);}
Chris@16 490 inline
Chris@16 491 void copy_directory(const path& from, const path& to, system::error_code& ec)
Chris@16 492 {detail::copy_directory(from, to, &ec);}
Chris@16 493 inline
Chris@16 494 void copy_file(const path& from, const path& to, // See ticket #2925
Chris@16 495 BOOST_SCOPED_ENUM(copy_option) option)
Chris@101 496 {
Chris@101 497 detail::copy_file(from, to, static_cast<detail::copy_option>(option));
Chris@101 498 }
Chris@16 499 inline
Chris@16 500 void copy_file(const path& from, const path& to)
Chris@101 501 {
Chris@101 502 detail::copy_file(from, to, detail::fail_if_exists);
Chris@101 503 }
Chris@16 504 inline
Chris@16 505 void copy_file(const path& from, const path& to, // See ticket #2925
Chris@16 506 BOOST_SCOPED_ENUM(copy_option) option, system::error_code& ec)
Chris@101 507 {
Chris@101 508 detail::copy_file(from, to, static_cast<detail::copy_option>(option), &ec);
Chris@101 509 }
Chris@16 510 inline
Chris@16 511 void copy_file(const path& from, const path& to, system::error_code& ec)
Chris@101 512 {
Chris@101 513 detail::copy_file(from, to, detail::fail_if_exists, &ec);
Chris@101 514 }
Chris@16 515 inline
Chris@101 516 void copy_symlink(const path& existing_symlink,
Chris@101 517 const path& new_symlink) {detail::copy_symlink(existing_symlink, new_symlink);}
Chris@16 518
Chris@16 519 inline
Chris@16 520 void copy_symlink(const path& existing_symlink, const path& new_symlink, system::error_code& ec)
Chris@16 521 {detail::copy_symlink(existing_symlink, new_symlink, &ec);}
Chris@16 522 inline
Chris@16 523 bool create_directories(const path& p) {return detail::create_directories(p);}
Chris@16 524
Chris@16 525 inline
Chris@16 526 bool create_directories(const path& p, system::error_code& ec)
Chris@16 527 {return detail::create_directories(p, &ec);}
Chris@16 528 inline
Chris@16 529 bool create_directory(const path& p) {return detail::create_directory(p);}
Chris@16 530
Chris@16 531 inline
Chris@16 532 bool create_directory(const path& p, system::error_code& ec)
Chris@16 533 {return detail::create_directory(p, &ec);}
Chris@16 534 inline
Chris@16 535 void create_directory_symlink(const path& to, const path& from)
Chris@16 536 {detail::create_directory_symlink(to, from);}
Chris@16 537 inline
Chris@16 538 void create_directory_symlink(const path& to, const path& from, system::error_code& ec)
Chris@16 539 {detail::create_directory_symlink(to, from, &ec);}
Chris@16 540 inline
Chris@16 541 void create_hard_link(const path& to, const path& new_hard_link) {detail::create_hard_link(to, new_hard_link);}
Chris@16 542
Chris@16 543 inline
Chris@16 544 void create_hard_link(const path& to, const path& new_hard_link, system::error_code& ec)
Chris@16 545 {detail::create_hard_link(to, new_hard_link, &ec);}
Chris@16 546 inline
Chris@16 547 void create_symlink(const path& to, const path& new_symlink) {detail::create_symlink(to, new_symlink);}
Chris@16 548
Chris@16 549 inline
Chris@16 550 void create_symlink(const path& to, const path& new_symlink, system::error_code& ec)
Chris@16 551 {detail::create_symlink(to, new_symlink, &ec);}
Chris@16 552 inline
Chris@16 553 path current_path() {return detail::current_path();}
Chris@16 554
Chris@16 555 inline
Chris@16 556 path current_path(system::error_code& ec) {return detail::current_path(&ec);}
Chris@16 557
Chris@16 558 inline
Chris@16 559 void current_path(const path& p) {detail::current_path(p);}
Chris@16 560
Chris@16 561 inline
Chris@16 562 void current_path(const path& p, system::error_code& ec) {detail::current_path(p, &ec);}
Chris@16 563
Chris@16 564 inline
Chris@16 565 bool equivalent(const path& p1, const path& p2) {return detail::equivalent(p1, p2);}
Chris@16 566
Chris@16 567 inline
Chris@16 568 bool equivalent(const path& p1, const path& p2, system::error_code& ec)
Chris@16 569 {return detail::equivalent(p1, p2, &ec);}
Chris@16 570 inline
Chris@16 571 boost::uintmax_t file_size(const path& p) {return detail::file_size(p);}
Chris@16 572
Chris@16 573 inline
Chris@16 574 boost::uintmax_t file_size(const path& p, system::error_code& ec)
Chris@16 575 {return detail::file_size(p, &ec);}
Chris@16 576 inline
Chris@16 577 boost::uintmax_t hard_link_count(const path& p) {return detail::hard_link_count(p);}
Chris@16 578
Chris@16 579 inline
Chris@16 580 boost::uintmax_t hard_link_count(const path& p, system::error_code& ec)
Chris@16 581 {return detail::hard_link_count(p, &ec);}
Chris@16 582 inline
Chris@16 583 path initial_path() {return detail::initial_path();}
Chris@16 584
Chris@16 585 inline
Chris@16 586 path initial_path(system::error_code& ec) {return detail::initial_path(&ec);}
Chris@16 587
Chris@16 588 template <class Path>
Chris@16 589 path initial_path() {return initial_path();}
Chris@16 590 template <class Path>
Chris@16 591 path initial_path(system::error_code& ec) {return detail::initial_path(&ec);}
Chris@16 592
Chris@16 593 inline
Chris@16 594 std::time_t last_write_time(const path& p) {return detail::last_write_time(p);}
Chris@16 595
Chris@16 596 inline
Chris@16 597 std::time_t last_write_time(const path& p, system::error_code& ec)
Chris@16 598 {return detail::last_write_time(p, &ec);}
Chris@16 599 inline
Chris@16 600 void last_write_time(const path& p, const std::time_t new_time)
Chris@16 601 {detail::last_write_time(p, new_time);}
Chris@16 602 inline
Chris@16 603 void last_write_time(const path& p, const std::time_t new_time, system::error_code& ec)
Chris@16 604 {detail::last_write_time(p, new_time, &ec);}
Chris@16 605 inline
Chris@16 606 void permissions(const path& p, perms prms)
Chris@16 607 {detail::permissions(p, prms);}
Chris@16 608 inline
Chris@16 609 void permissions(const path& p, perms prms, system::error_code& ec)
Chris@16 610 {detail::permissions(p, prms, &ec);}
Chris@16 611
Chris@16 612 inline
Chris@16 613 path read_symlink(const path& p) {return detail::read_symlink(p);}
Chris@16 614
Chris@16 615 inline
Chris@16 616 path read_symlink(const path& p, system::error_code& ec)
Chris@16 617 {return detail::read_symlink(p, &ec);}
Chris@16 618 inline
Chris@16 619 // For standardization, if the committee doesn't like "remove", consider "eliminate"
Chris@16 620 bool remove(const path& p) {return detail::remove(p);}
Chris@16 621
Chris@16 622 inline
Chris@16 623 bool remove(const path& p, system::error_code& ec) {return detail::remove(p, &ec);}
Chris@16 624
Chris@16 625 inline
Chris@16 626 boost::uintmax_t remove_all(const path& p) {return detail::remove_all(p);}
Chris@16 627
Chris@16 628 inline
Chris@16 629 boost::uintmax_t remove_all(const path& p, system::error_code& ec)
Chris@16 630 {return detail::remove_all(p, &ec);}
Chris@16 631 inline
Chris@16 632 void rename(const path& old_p, const path& new_p) {detail::rename(old_p, new_p);}
Chris@16 633
Chris@16 634 inline
Chris@16 635 void rename(const path& old_p, const path& new_p, system::error_code& ec)
Chris@16 636 {detail::rename(old_p, new_p, &ec);}
Chris@16 637 inline // name suggested by Scott McMurray
Chris@16 638 void resize_file(const path& p, uintmax_t size) {detail::resize_file(p, size);}
Chris@16 639
Chris@16 640 inline
Chris@16 641 void resize_file(const path& p, uintmax_t size, system::error_code& ec)
Chris@16 642 {detail::resize_file(p, size, &ec);}
Chris@16 643 inline
Chris@16 644 space_info space(const path& p) {return detail::space(p);}
Chris@16 645
Chris@16 646 inline
Chris@16 647 space_info space(const path& p, system::error_code& ec) {return detail::space(p, &ec);}
Chris@16 648
Chris@16 649 # ifndef BOOST_FILESYSTEM_NO_DEPRECATED
Chris@16 650 inline bool symbolic_link_exists(const path& p)
Chris@16 651 { return is_symlink(symlink_status(p)); }
Chris@16 652 # endif
Chris@16 653
Chris@16 654 inline
Chris@16 655 path system_complete(const path& p) {return detail::system_complete(p);}
Chris@16 656
Chris@16 657 inline
Chris@16 658 path system_complete(const path& p, system::error_code& ec)
Chris@16 659 {return detail::system_complete(p, &ec);}
Chris@16 660 inline
Chris@16 661 path temp_directory_path() {return detail::temp_directory_path();}
Chris@16 662
Chris@16 663 inline
Chris@16 664 path temp_directory_path(system::error_code& ec)
Chris@16 665 {return detail::temp_directory_path(&ec);}
Chris@16 666 inline
Chris@16 667 path unique_path(const path& p="%%%%-%%%%-%%%%-%%%%")
Chris@16 668 { return detail::unique_path(p); }
Chris@16 669 inline
Chris@16 670 path unique_path(const path& p, system::error_code& ec)
Chris@16 671 { return detail::unique_path(p, &ec); }
Chris@16 672
Chris@16 673 //--------------------------------------------------------------------------------------//
Chris@16 674 // //
Chris@16 675 // directory_entry //
Chris@16 676 // //
Chris@16 677 //--------------------------------------------------------------------------------------//
Chris@16 678
Chris@16 679 // GCC has a problem with a member function named path within a namespace or
Chris@16 680 // sub-namespace that also has a class named path. The workaround is to always
Chris@16 681 // fully qualify the name path when it refers to the class name.
Chris@16 682
Chris@16 683 class BOOST_FILESYSTEM_DECL directory_entry
Chris@16 684 {
Chris@16 685 public:
Chris@16 686
Chris@16 687 // compiler generated copy constructor, copy assignment, and destructor apply
Chris@16 688
Chris@16 689 directory_entry() {}
Chris@16 690 explicit directory_entry(const boost::filesystem::path& p,
Chris@16 691 file_status st = file_status(), file_status symlink_st=file_status())
Chris@16 692 : m_path(p), m_status(st), m_symlink_status(symlink_st)
Chris@16 693 {}
Chris@16 694
Chris@16 695 void assign(const boost::filesystem::path& p,
Chris@16 696 file_status st = file_status(), file_status symlink_st = file_status())
Chris@16 697 { m_path = p; m_status = st; m_symlink_status = symlink_st; }
Chris@16 698
Chris@16 699 void replace_filename(const boost::filesystem::path& p,
Chris@16 700 file_status st = file_status(), file_status symlink_st = file_status())
Chris@16 701 {
Chris@16 702 m_path.remove_filename();
Chris@16 703 m_path /= p;
Chris@16 704 m_status = st;
Chris@16 705 m_symlink_status = symlink_st;
Chris@16 706 }
Chris@16 707
Chris@16 708 # ifndef BOOST_FILESYSTEM_NO_DEPRECATED
Chris@16 709 void replace_leaf(const boost::filesystem::path& p,
Chris@16 710 file_status st, file_status symlink_st)
Chris@16 711 { replace_filename(p, st, symlink_st); }
Chris@16 712 # endif
Chris@16 713
Chris@16 714 const boost::filesystem::path& path() const {return m_path;}
Chris@16 715 file_status status() const {return m_get_status();}
Chris@16 716 file_status status(system::error_code& ec) const {return m_get_status(&ec);}
Chris@16 717 file_status symlink_status() const {return m_get_symlink_status();}
Chris@16 718 file_status symlink_status(system::error_code& ec) const {return m_get_symlink_status(&ec);}
Chris@16 719
Chris@16 720 bool operator==(const directory_entry& rhs) {return m_path == rhs.m_path;}
Chris@16 721 bool operator!=(const directory_entry& rhs) {return m_path != rhs.m_path;}
Chris@16 722 bool operator< (const directory_entry& rhs) {return m_path < rhs.m_path;}
Chris@16 723 bool operator<=(const directory_entry& rhs) {return m_path <= rhs.m_path;}
Chris@16 724 bool operator> (const directory_entry& rhs) {return m_path > rhs.m_path;}
Chris@16 725 bool operator>=(const directory_entry& rhs) {return m_path >= rhs.m_path;}
Chris@16 726
Chris@16 727 private:
Chris@16 728 boost::filesystem::path m_path;
Chris@16 729 mutable file_status m_status; // stat()-like
Chris@16 730 mutable file_status m_symlink_status; // lstat()-like
Chris@16 731
Chris@16 732 file_status m_get_status(system::error_code* ec=0) const;
Chris@16 733 file_status m_get_symlink_status(system::error_code* ec=0) const;
Chris@16 734 }; // directory_entry
Chris@16 735
Chris@16 736 //--------------------------------------------------------------------------------------//
Chris@16 737 // //
Chris@16 738 // directory_iterator helpers //
Chris@16 739 // //
Chris@16 740 //--------------------------------------------------------------------------------------//
Chris@16 741
Chris@16 742 class directory_iterator;
Chris@16 743
Chris@16 744 namespace detail
Chris@16 745 {
Chris@16 746 BOOST_FILESYSTEM_DECL
Chris@16 747 system::error_code dir_itr_close(// never throws()
Chris@16 748 void *& handle
Chris@16 749 # if defined(BOOST_POSIX_API)
Chris@16 750 , void *& buffer
Chris@16 751 # endif
Chris@16 752 );
Chris@16 753
Chris@16 754 struct dir_itr_imp
Chris@16 755 {
Chris@16 756 directory_entry dir_entry;
Chris@16 757 void* handle;
Chris@16 758
Chris@16 759 # ifdef BOOST_POSIX_API
Chris@16 760 void* buffer; // see dir_itr_increment implementation
Chris@16 761 # endif
Chris@16 762
Chris@16 763 dir_itr_imp() : handle(0)
Chris@16 764 # ifdef BOOST_POSIX_API
Chris@16 765 , buffer(0)
Chris@16 766 # endif
Chris@16 767 {}
Chris@16 768
Chris@16 769 ~dir_itr_imp() // never throws
Chris@16 770 {
Chris@16 771 dir_itr_close(handle
Chris@16 772 # if defined(BOOST_POSIX_API)
Chris@16 773 , buffer
Chris@16 774 # endif
Chris@16 775 );
Chris@16 776 }
Chris@16 777 };
Chris@16 778
Chris@16 779 // see path::iterator: comment below
Chris@16 780 BOOST_FILESYSTEM_DECL void directory_iterator_construct(directory_iterator& it,
Chris@16 781 const path& p, system::error_code* ec);
Chris@16 782 BOOST_FILESYSTEM_DECL void directory_iterator_increment(directory_iterator& it,
Chris@16 783 system::error_code* ec);
Chris@16 784
Chris@16 785 } // namespace detail
Chris@16 786
Chris@16 787 //--------------------------------------------------------------------------------------//
Chris@16 788 // //
Chris@16 789 // directory_iterator //
Chris@16 790 // //
Chris@16 791 //--------------------------------------------------------------------------------------//
Chris@16 792
Chris@16 793 class directory_iterator
Chris@16 794 : public boost::iterator_facade< directory_iterator,
Chris@16 795 directory_entry,
Chris@16 796 boost::single_pass_traversal_tag >
Chris@16 797 {
Chris@16 798 public:
Chris@16 799
Chris@16 800 directory_iterator(){} // creates the "end" iterator
Chris@16 801
Chris@16 802 // iterator_facade derived classes don't seem to like implementations in
Chris@16 803 // separate translation unit dll's, so forward to detail functions
Chris@16 804 explicit directory_iterator(const path& p)
Chris@16 805 : m_imp(new detail::dir_itr_imp)
Chris@16 806 { detail::directory_iterator_construct(*this, p, 0); }
Chris@16 807
Chris@16 808 directory_iterator(const path& p, system::error_code& ec)
Chris@16 809 : m_imp(new detail::dir_itr_imp)
Chris@16 810 { detail::directory_iterator_construct(*this, p, &ec); }
Chris@16 811
Chris@16 812 ~directory_iterator() {} // never throws
Chris@16 813
Chris@16 814 directory_iterator& increment(system::error_code& ec)
Chris@16 815 {
Chris@16 816 detail::directory_iterator_increment(*this, &ec);
Chris@16 817 return *this;
Chris@16 818 }
Chris@16 819
Chris@16 820 private:
Chris@16 821 friend struct detail::dir_itr_imp;
Chris@16 822 friend BOOST_FILESYSTEM_DECL void detail::directory_iterator_construct(directory_iterator& it,
Chris@16 823 const path& p, system::error_code* ec);
Chris@16 824 friend BOOST_FILESYSTEM_DECL void detail::directory_iterator_increment(directory_iterator& it,
Chris@16 825 system::error_code* ec);
Chris@16 826
Chris@16 827 // shared_ptr provides shallow-copy semantics required for InputIterators.
Chris@16 828 // m_imp.get()==0 indicates the end iterator.
Chris@16 829 boost::shared_ptr< detail::dir_itr_imp > m_imp;
Chris@16 830
Chris@16 831 friend class boost::iterator_core_access;
Chris@16 832
Chris@16 833 boost::iterator_facade<
Chris@16 834 directory_iterator,
Chris@16 835 directory_entry,
Chris@16 836 boost::single_pass_traversal_tag >::reference dereference() const
Chris@16 837 {
Chris@16 838 BOOST_ASSERT_MSG(m_imp.get(), "attempt to dereference end iterator");
Chris@16 839 return m_imp->dir_entry;
Chris@16 840 }
Chris@16 841
Chris@16 842 void increment() { detail::directory_iterator_increment(*this, 0); }
Chris@16 843
Chris@16 844 bool equal(const directory_iterator& rhs) const
Chris@16 845 { return m_imp == rhs.m_imp; }
Chris@101 846
Chris@101 847 }; // directory_iterator
Chris@101 848
Chris@101 849 // enable directory_iterator C++11 range-base for statement use --------------------//
Chris@101 850
Chris@101 851 // begin() and end() are only used by a range-based for statement in the context of
Chris@101 852 // auto - thus the top-level const is stripped - so returning const is harmless and
Chris@101 853 // emphasizes begin() is just a pass through.
Chris@101 854 inline
Chris@101 855 const directory_iterator& begin(const directory_iterator& iter) {return iter;}
Chris@101 856 inline
Chris@101 857 directory_iterator end(const directory_iterator&) {return directory_iterator();}
Chris@101 858
Chris@101 859 // enable directory_iterator BOOST_FOREACH -----------------------------------------//
Chris@101 860
Chris@101 861 inline
Chris@101 862 directory_iterator& range_begin(directory_iterator& iter) {return iter;}
Chris@101 863 inline
Chris@101 864 directory_iterator range_begin(const directory_iterator& iter) {return iter;}
Chris@101 865 inline
Chris@101 866 directory_iterator range_end(const directory_iterator&) {return directory_iterator();}
Chris@101 867 } // namespace filesystem
Chris@101 868
Chris@101 869 // namespace boost template specializations
Chris@101 870 template<>
Chris@101 871 struct range_mutable_iterator<boost::filesystem::directory_iterator>
Chris@101 872 { typedef boost::filesystem::directory_iterator type; };
Chris@101 873 template<>
Chris@101 874 struct range_const_iterator <boost::filesystem::directory_iterator>
Chris@101 875 { typedef boost::filesystem::directory_iterator type; };
Chris@101 876
Chris@101 877 namespace filesystem
Chris@101 878 {
Chris@16 879
Chris@16 880 //--------------------------------------------------------------------------------------//
Chris@16 881 // //
Chris@16 882 // recursive_directory_iterator helpers //
Chris@16 883 // //
Chris@16 884 //--------------------------------------------------------------------------------------//
Chris@16 885
Chris@16 886 BOOST_SCOPED_ENUM_START(symlink_option)
Chris@16 887 {
Chris@16 888 none,
Chris@16 889 no_recurse = none, // don't follow directory symlinks (default behavior)
Chris@16 890 recurse, // follow directory symlinks
Chris@16 891 _detail_no_push = recurse << 1 // internal use only
Chris@16 892 };
Chris@16 893 BOOST_SCOPED_ENUM_END
Chris@16 894
Chris@16 895 BOOST_BITMASK(BOOST_SCOPED_ENUM(symlink_option))
Chris@16 896
Chris@16 897 namespace detail
Chris@16 898 {
Chris@16 899 struct recur_dir_itr_imp
Chris@16 900 {
Chris@16 901 typedef directory_iterator element_type;
Chris@16 902 std::stack< element_type, std::vector< element_type > > m_stack;
Chris@16 903 int m_level;
Chris@16 904 BOOST_SCOPED_ENUM(symlink_option) m_options;
Chris@16 905
Chris@16 906 recur_dir_itr_imp() : m_level(0), m_options(symlink_option::none) {}
Chris@16 907
Chris@16 908 void increment(system::error_code* ec); // ec == 0 means throw on error
Chris@16 909
Chris@101 910 bool push_directory(system::error_code& ec) BOOST_NOEXCEPT;
Chris@101 911
Chris@16 912 void pop();
Chris@16 913
Chris@16 914 };
Chris@16 915
Chris@16 916 // Implementation is inline to avoid dynamic linking difficulties with m_stack:
Chris@16 917 // Microsoft warning C4251, m_stack needs to have dll-interface to be used by
Chris@16 918 // clients of struct 'boost::filesystem::detail::recur_dir_itr_imp'
Chris@16 919
Chris@16 920 inline
Chris@101 921 bool recur_dir_itr_imp::push_directory(system::error_code& ec) BOOST_NOEXCEPT
Chris@101 922 // Returns: true if push occurs, otherwise false. Always returns false on error.
Chris@16 923 {
Chris@101 924 ec.clear();
Chris@101 925
Chris@101 926 // Discover if the iterator is for a directory that needs to be recursed into,
Chris@101 927 // taking symlinks and options into account.
Chris@101 928
Chris@16 929 if ((m_options & symlink_option::_detail_no_push) == symlink_option::_detail_no_push)
Chris@16 930 m_options &= ~symlink_option::_detail_no_push;
Chris@16 931
Chris@16 932 else
Chris@16 933 {
Chris@16 934 // Logic for following predicate was contributed by Daniel Aarno to handle cyclic
Chris@16 935 // symlinks correctly and efficiently, fixing ticket #5652.
Chris@16 936 // if (((m_options & symlink_option::recurse) == symlink_option::recurse
Chris@16 937 // || !is_symlink(m_stack.top()->symlink_status()))
Chris@16 938 // && is_directory(m_stack.top()->status())) ...
Chris@16 939 // The predicate code has since been rewritten to pass error_code arguments,
Chris@16 940 // per ticket #5653.
Chris@16 941
Chris@101 942 file_status symlink_stat;
Chris@101 943
Chris@101 944 if ((m_options & symlink_option::recurse) != symlink_option::recurse)
Chris@16 945 {
Chris@101 946 symlink_stat = m_stack.top()->symlink_status(ec);
Chris@101 947 if (ec)
Chris@101 948 return false;
Chris@101 949 }
Chris@101 950
Chris@101 951 if ((m_options & symlink_option::recurse) == symlink_option::recurse
Chris@101 952 || !is_symlink(symlink_stat))
Chris@101 953 {
Chris@101 954 file_status stat = m_stack.top()->status(ec);
Chris@101 955 if (ec || !is_directory(stat))
Chris@101 956 return false;
Chris@101 957
Chris@101 958 directory_iterator next(m_stack.top()->path(), ec);
Chris@101 959 if (!ec && next != directory_iterator())
Chris@16 960 {
Chris@101 961 m_stack.push(next);
Chris@101 962 ++m_level;
Chris@101 963 return true;
Chris@16 964 }
Chris@16 965 }
Chris@16 966 }
Chris@101 967 return false;
Chris@101 968 }
Chris@16 969
Chris@101 970 inline
Chris@101 971 void recur_dir_itr_imp::increment(system::error_code* ec)
Chris@101 972 // ec == 0 means throw on error
Chris@101 973 //
Chris@101 974 // Invariant: On return, the top of the iterator stack is the next valid (possibly
Chris@101 975 // end) iterator, regardless of whether or not an error is reported, and regardless of
Chris@101 976 // whether any error is reported by exception or error code. In other words, progress
Chris@101 977 // is always made so a loop on the iterator will always eventually terminate
Chris@101 978 // regardless of errors.
Chris@101 979 {
Chris@101 980 system::error_code ec_push_directory;
Chris@101 981
Chris@101 982 // if various conditions are met, push a directory_iterator into the iterator stack
Chris@101 983 if (push_directory(ec_push_directory))
Chris@101 984 {
Chris@101 985 if (ec)
Chris@101 986 ec->clear();
Chris@101 987 return;
Chris@101 988 }
Chris@101 989
Chris@101 990 // Do the actual increment operation on the top iterator in the iterator
Chris@101 991 // stack, popping the stack if necessary, until either the stack is empty or a
Chris@101 992 // non-end iterator is reached.
Chris@16 993 while (!m_stack.empty() && ++m_stack.top() == directory_iterator())
Chris@16 994 {
Chris@16 995 m_stack.pop();
Chris@16 996 --m_level;
Chris@16 997 }
Chris@101 998
Chris@101 999 // report errors if any
Chris@101 1000 if (ec_push_directory)
Chris@101 1001 {
Chris@101 1002 if (ec)
Chris@101 1003 *ec = ec_push_directory;
Chris@101 1004 else
Chris@101 1005 {
Chris@101 1006 BOOST_FILESYSTEM_THROW(filesystem_error(
Chris@101 1007 "filesystem::recursive_directory_iterator directory error",
Chris@101 1008 ec_push_directory));
Chris@101 1009 }
Chris@101 1010 }
Chris@101 1011 else if (ec)
Chris@101 1012 ec->clear();
Chris@16 1013 }
Chris@16 1014
Chris@16 1015 inline
Chris@16 1016 void recur_dir_itr_imp::pop()
Chris@16 1017 {
Chris@16 1018 BOOST_ASSERT_MSG(m_level > 0,
Chris@16 1019 "pop() on recursive_directory_iterator with level < 1");
Chris@16 1020
Chris@16 1021 do
Chris@16 1022 {
Chris@16 1023 m_stack.pop();
Chris@16 1024 --m_level;
Chris@16 1025 }
Chris@16 1026 while (!m_stack.empty() && ++m_stack.top() == directory_iterator());
Chris@16 1027 }
Chris@16 1028 } // namespace detail
Chris@16 1029
Chris@16 1030 //--------------------------------------------------------------------------------------//
Chris@16 1031 // //
Chris@16 1032 // recursive_directory_iterator //
Chris@16 1033 // //
Chris@16 1034 //--------------------------------------------------------------------------------------//
Chris@16 1035
Chris@16 1036 class recursive_directory_iterator
Chris@16 1037 : public boost::iterator_facade<
Chris@16 1038 recursive_directory_iterator,
Chris@16 1039 directory_entry,
Chris@16 1040 boost::single_pass_traversal_tag >
Chris@16 1041 {
Chris@16 1042 public:
Chris@16 1043
Chris@16 1044 recursive_directory_iterator(){} // creates the "end" iterator
Chris@16 1045
Chris@16 1046 explicit recursive_directory_iterator(const path& dir_path,
Chris@16 1047 BOOST_SCOPED_ENUM(symlink_option) opt = symlink_option::none)
Chris@16 1048 : m_imp(new detail::recur_dir_itr_imp)
Chris@16 1049 {
Chris@16 1050 m_imp->m_options = opt;
Chris@16 1051 m_imp->m_stack.push(directory_iterator(dir_path));
Chris@16 1052 if (m_imp->m_stack.top() == directory_iterator())
Chris@16 1053 { m_imp.reset (); }
Chris@16 1054 }
Chris@16 1055
Chris@16 1056 recursive_directory_iterator(const path& dir_path,
Chris@16 1057 BOOST_SCOPED_ENUM(symlink_option) opt,
Chris@16 1058 system::error_code & ec)
Chris@16 1059 : m_imp(new detail::recur_dir_itr_imp)
Chris@16 1060 {
Chris@16 1061 m_imp->m_options = opt;
Chris@16 1062 m_imp->m_stack.push(directory_iterator(dir_path, ec));
Chris@16 1063 if (m_imp->m_stack.top() == directory_iterator())
Chris@16 1064 { m_imp.reset (); }
Chris@16 1065 }
Chris@16 1066
Chris@16 1067 recursive_directory_iterator(const path& dir_path,
Chris@16 1068 system::error_code & ec)
Chris@16 1069 : m_imp(new detail::recur_dir_itr_imp)
Chris@16 1070 {
Chris@16 1071 m_imp->m_options = symlink_option::none;
Chris@16 1072 m_imp->m_stack.push(directory_iterator(dir_path, ec));
Chris@16 1073 if (m_imp->m_stack.top() == directory_iterator())
Chris@16 1074 { m_imp.reset (); }
Chris@16 1075 }
Chris@16 1076
Chris@16 1077 recursive_directory_iterator& increment(system::error_code& ec)
Chris@16 1078 {
Chris@16 1079 BOOST_ASSERT_MSG(m_imp.get(),
Chris@16 1080 "increment() on end recursive_directory_iterator");
Chris@16 1081 m_imp->increment(&ec);
Chris@16 1082 if (m_imp->m_stack.empty())
Chris@16 1083 m_imp.reset(); // done, so make end iterator
Chris@16 1084 return *this;
Chris@16 1085 }
Chris@16 1086
Chris@16 1087 int level() const
Chris@16 1088 {
Chris@16 1089 BOOST_ASSERT_MSG(m_imp.get(),
Chris@16 1090 "level() on end recursive_directory_iterator");
Chris@16 1091 return m_imp->m_level;
Chris@16 1092 }
Chris@16 1093
Chris@16 1094 bool no_push_pending() const
Chris@16 1095 {
Chris@16 1096 BOOST_ASSERT_MSG(m_imp.get(),
Chris@16 1097 "is_no_push_requested() on end recursive_directory_iterator");
Chris@16 1098 return (m_imp->m_options & symlink_option::_detail_no_push)
Chris@16 1099 == symlink_option::_detail_no_push;
Chris@16 1100 }
Chris@16 1101
Chris@16 1102 # ifndef BOOST_FILESYSTEM_NO_DEPRECATED
Chris@16 1103 bool no_push_request() const { return no_push_pending(); }
Chris@16 1104 # endif
Chris@16 1105
Chris@16 1106 void pop()
Chris@16 1107 {
Chris@16 1108 BOOST_ASSERT_MSG(m_imp.get(),
Chris@16 1109 "pop() on end recursive_directory_iterator");
Chris@16 1110 m_imp->pop();
Chris@16 1111 if (m_imp->m_stack.empty()) m_imp.reset(); // done, so make end iterator
Chris@16 1112 }
Chris@16 1113
Chris@16 1114 void no_push(bool value=true)
Chris@16 1115 {
Chris@16 1116 BOOST_ASSERT_MSG(m_imp.get(),
Chris@16 1117 "no_push() on end recursive_directory_iterator");
Chris@16 1118 if (value)
Chris@16 1119 m_imp->m_options |= symlink_option::_detail_no_push;
Chris@16 1120 else
Chris@16 1121 m_imp->m_options &= ~symlink_option::_detail_no_push;
Chris@16 1122 }
Chris@16 1123
Chris@16 1124 file_status status() const
Chris@16 1125 {
Chris@16 1126 BOOST_ASSERT_MSG(m_imp.get(),
Chris@16 1127 "status() on end recursive_directory_iterator");
Chris@16 1128 return m_imp->m_stack.top()->status();
Chris@16 1129 }
Chris@16 1130
Chris@16 1131 file_status symlink_status() const
Chris@16 1132 {
Chris@16 1133 BOOST_ASSERT_MSG(m_imp.get(),
Chris@16 1134 "symlink_status() on end recursive_directory_iterator");
Chris@16 1135 return m_imp->m_stack.top()->symlink_status();
Chris@16 1136 }
Chris@16 1137
Chris@16 1138 private:
Chris@16 1139
Chris@16 1140 // shared_ptr provides shallow-copy semantics required for InputIterators.
Chris@16 1141 // m_imp.get()==0 indicates the end iterator.
Chris@16 1142 boost::shared_ptr< detail::recur_dir_itr_imp > m_imp;
Chris@16 1143
Chris@16 1144 friend class boost::iterator_core_access;
Chris@16 1145
Chris@16 1146 boost::iterator_facade<
Chris@16 1147 recursive_directory_iterator,
Chris@16 1148 directory_entry,
Chris@16 1149 boost::single_pass_traversal_tag >::reference
Chris@16 1150 dereference() const
Chris@16 1151 {
Chris@16 1152 BOOST_ASSERT_MSG(m_imp.get(),
Chris@16 1153 "dereference of end recursive_directory_iterator");
Chris@16 1154 return *m_imp->m_stack.top();
Chris@16 1155 }
Chris@16 1156
Chris@16 1157 void increment()
Chris@16 1158 {
Chris@16 1159 BOOST_ASSERT_MSG(m_imp.get(),
Chris@16 1160 "increment of end recursive_directory_iterator");
Chris@16 1161 m_imp->increment(0);
Chris@16 1162 if (m_imp->m_stack.empty())
Chris@16 1163 m_imp.reset(); // done, so make end iterator
Chris@16 1164 }
Chris@16 1165
Chris@16 1166 bool equal(const recursive_directory_iterator& rhs) const
Chris@16 1167 { return m_imp == rhs.m_imp; }
Chris@16 1168
Chris@101 1169 }; // recursive directory iterator
Chris@101 1170
Chris@101 1171 // enable recursive directory iterator C++11 range-base for statement use ----------//
Chris@101 1172
Chris@101 1173 // begin() and end() are only used by a range-based for statement in the context of
Chris@101 1174 // auto - thus the top-level const is stripped - so returning const is harmless and
Chris@101 1175 // emphasizes begin() is just a pass through.
Chris@101 1176 inline
Chris@101 1177 const recursive_directory_iterator& begin(const recursive_directory_iterator& iter)
Chris@101 1178 {return iter;}
Chris@101 1179 inline
Chris@101 1180 recursive_directory_iterator end(const recursive_directory_iterator&)
Chris@101 1181 {return recursive_directory_iterator();}
Chris@101 1182
Chris@101 1183 // enable recursive directory iterator BOOST_FOREACH -------------------------------//
Chris@101 1184
Chris@101 1185 inline
Chris@101 1186 recursive_directory_iterator& range_begin(recursive_directory_iterator& iter)
Chris@101 1187 {return iter;}
Chris@101 1188 inline
Chris@101 1189 recursive_directory_iterator range_begin(const recursive_directory_iterator& iter)
Chris@101 1190 {return iter;}
Chris@101 1191 inline
Chris@101 1192 recursive_directory_iterator range_end(const recursive_directory_iterator&)
Chris@101 1193 {return recursive_directory_iterator();}
Chris@101 1194 } // namespace filesystem
Chris@101 1195
Chris@101 1196 // namespace boost template specializations
Chris@101 1197 template<>
Chris@101 1198 struct range_mutable_iterator<boost::filesystem::recursive_directory_iterator>
Chris@101 1199 { typedef boost::filesystem::recursive_directory_iterator type; };
Chris@101 1200 template<>
Chris@101 1201 struct range_const_iterator <boost::filesystem::recursive_directory_iterator>
Chris@101 1202 { typedef boost::filesystem::recursive_directory_iterator type; };
Chris@101 1203
Chris@101 1204 namespace filesystem
Chris@101 1205 {
Chris@16 1206
Chris@16 1207 # if !defined(BOOST_FILESYSTEM_NO_DEPRECATED)
Chris@16 1208 typedef recursive_directory_iterator wrecursive_directory_iterator;
Chris@16 1209 # endif
Chris@16 1210
Chris@16 1211 // test helper -----------------------------------------------------------------------//
Chris@16 1212
Chris@16 1213 // Not part of the documented interface since false positives are possible;
Chris@16 1214 // there is no law that says that an OS that has large stat.st_size
Chris@16 1215 // actually supports large file sizes.
Chris@16 1216
Chris@16 1217 namespace detail
Chris@16 1218 {
Chris@16 1219 BOOST_FILESYSTEM_DECL bool possible_large_file_size_support();
Chris@16 1220 }
Chris@16 1221
Chris@16 1222 } // namespace filesystem
Chris@16 1223 } // namespace boost
Chris@16 1224
Chris@16 1225 #include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas
Chris@16 1226 #endif // BOOST_FILESYSTEM3_OPERATIONS_HPP