File indexing completed on 2025-01-30 09:35:37
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef BOOST_FILESYSTEM_DIRECTORY_HPP
0017 #define BOOST_FILESYSTEM_DIRECTORY_HPP
0018
0019 #include <boost/filesystem/config.hpp>
0020 #include <boost/filesystem/path.hpp>
0021 #include <boost/filesystem/file_status.hpp>
0022 #include <boost/filesystem/detail/path_traits.hpp>
0023
0024 #include <cstddef>
0025 #include <string>
0026 #include <vector>
0027
0028 #include <boost/assert.hpp>
0029 #include <boost/core/scoped_enum.hpp>
0030 #include <boost/detail/bitmask.hpp>
0031 #include <boost/system/error_code.hpp>
0032 #include <boost/smart_ptr/intrusive_ptr.hpp>
0033 #include <boost/smart_ptr/intrusive_ref_counter.hpp>
0034 #include <boost/iterator/iterator_facade.hpp>
0035 #include <boost/iterator/iterator_categories.hpp>
0036
0037 #include <boost/filesystem/detail/header.hpp> // must be the last #include
0038
0039
0040
0041 namespace boost {
0042 namespace filesystem {
0043
0044 class directory_iterator;
0045
0046 namespace detail {
0047
0048 struct directory_iterator_params;
0049
0050 BOOST_FILESYSTEM_DECL void directory_iterator_construct(directory_iterator& it, path const& p, unsigned int opts, directory_iterator_params* params, system::error_code* ec);
0051 BOOST_FILESYSTEM_DECL void directory_iterator_increment(directory_iterator& it, system::error_code* ec);
0052
0053 }
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065 class directory_entry
0066 {
0067 friend BOOST_FILESYSTEM_DECL void detail::directory_iterator_construct(directory_iterator& it, path const& p, unsigned int opts, detail::directory_iterator_params* params, system::error_code* ec);
0068 friend BOOST_FILESYSTEM_DECL void detail::directory_iterator_increment(directory_iterator& it, system::error_code* ec);
0069
0070 public:
0071 typedef boost::filesystem::path::value_type value_type;
0072
0073 directory_entry() BOOST_NOEXCEPT {}
0074
0075 explicit directory_entry(boost::filesystem::path const& p);
0076
0077 #if BOOST_FILESYSTEM_VERSION >= 4
0078 directory_entry(boost::filesystem::path const& p, system::error_code& ec) :
0079 m_path(p)
0080 {
0081 refresh_impl(&ec);
0082 if (ec)
0083 m_path.clear();
0084 }
0085 #else
0086 directory_entry(boost::filesystem::path const& p, file_status st, file_status symlink_st = file_status()) :
0087 m_path(p), m_status(st), m_symlink_status(symlink_st)
0088 {
0089 }
0090 #endif
0091
0092 directory_entry(directory_entry const& rhs) :
0093 m_path(rhs.m_path), m_status(rhs.m_status), m_symlink_status(rhs.m_symlink_status)
0094 {
0095 }
0096
0097 directory_entry& operator=(directory_entry const& rhs)
0098 {
0099 m_path = rhs.m_path;
0100 m_status = rhs.m_status;
0101 m_symlink_status = rhs.m_symlink_status;
0102 return *this;
0103 }
0104
0105
0106
0107
0108
0109 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0110 directory_entry(directory_entry&& rhs) BOOST_NOEXCEPT :
0111 m_path(static_cast< boost::filesystem::path&& >(rhs.m_path)),
0112 m_status(static_cast< file_status&& >(rhs.m_status)),
0113 m_symlink_status(static_cast< file_status&& >(rhs.m_symlink_status))
0114 {
0115 }
0116
0117 directory_entry& operator=(directory_entry&& rhs) BOOST_NOEXCEPT
0118 {
0119 m_path = static_cast< boost::filesystem::path&& >(rhs.m_path);
0120 m_status = static_cast< file_status&& >(rhs.m_status);
0121 m_symlink_status = static_cast< file_status&& >(rhs.m_symlink_status);
0122 return *this;
0123 }
0124
0125 void assign(boost::filesystem::path&& p);
0126
0127 #if BOOST_FILESYSTEM_VERSION >= 4
0128 void assign(boost::filesystem::path&& p, system::error_code& ec)
0129 {
0130 m_path = static_cast< boost::filesystem::path&& >(p);
0131 refresh_impl(&ec);
0132 }
0133 #else
0134 void assign(boost::filesystem::path&& p, file_status st, file_status symlink_st = file_status())
0135 {
0136 assign_with_status(static_cast< boost::filesystem::path&& >(p), st, symlink_st);
0137 }
0138 #endif
0139 #endif
0140
0141 void assign(boost::filesystem::path const& p);
0142
0143 #if BOOST_FILESYSTEM_VERSION >= 4
0144 void assign(boost::filesystem::path const& p, system::error_code& ec)
0145 {
0146 m_path = p;
0147 refresh_impl(&ec);
0148 }
0149 #else
0150 void assign(boost::filesystem::path const& p, file_status st, file_status symlink_st = file_status())
0151 {
0152 assign_with_status(p, st, symlink_st);
0153 }
0154 #endif
0155
0156 void replace_filename(boost::filesystem::path const& p);
0157
0158 #if BOOST_FILESYSTEM_VERSION >= 4
0159 void replace_filename(boost::filesystem::path const& p, system::error_code& ec)
0160 {
0161 m_path.replace_filename(p);
0162 refresh_impl(&ec);
0163 }
0164 #else
0165 void replace_filename(boost::filesystem::path const& p, file_status st, file_status symlink_st = file_status())
0166 {
0167 replace_filename_with_status(p, st, symlink_st);
0168 }
0169
0170 BOOST_FILESYSTEM_DETAIL_DEPRECATED("Use directory_entry::replace_filename() instead")
0171 void replace_leaf(boost::filesystem::path const& p, file_status st, file_status symlink_st)
0172 {
0173 replace_filename_with_status(p, st, symlink_st);
0174 }
0175 #endif
0176
0177 boost::filesystem::path const& path() const BOOST_NOEXCEPT { return m_path; }
0178 operator boost::filesystem::path const&() const BOOST_NOEXCEPT { return m_path; }
0179
0180 void refresh() { refresh_impl(); }
0181 void refresh(system::error_code& ec) BOOST_NOEXCEPT { refresh_impl(&ec); }
0182
0183 file_status status() const
0184 {
0185 if (!filesystem::status_known(m_status))
0186 refresh_impl();
0187 return m_status;
0188 }
0189
0190 file_status status(system::error_code& ec) const BOOST_NOEXCEPT
0191 {
0192 ec.clear();
0193
0194 if (!filesystem::status_known(m_status))
0195 refresh_impl(&ec);
0196 return m_status;
0197 }
0198
0199 file_status symlink_status() const
0200 {
0201 if (!filesystem::status_known(m_symlink_status))
0202 refresh_impl();
0203 return m_symlink_status;
0204 }
0205
0206 file_status symlink_status(system::error_code& ec) const BOOST_NOEXCEPT
0207 {
0208 ec.clear();
0209
0210 if (!filesystem::status_known(m_symlink_status))
0211 refresh_impl(&ec);
0212 return m_symlink_status;
0213 }
0214
0215 filesystem::file_type file_type() const
0216 {
0217 if (!filesystem::type_present(m_status))
0218 refresh_impl();
0219 return m_status.type();
0220 }
0221
0222 filesystem::file_type file_type(system::error_code& ec) const BOOST_NOEXCEPT
0223 {
0224 ec.clear();
0225
0226 if (!filesystem::type_present(m_status))
0227 refresh_impl(&ec);
0228 return m_status.type();
0229 }
0230
0231 filesystem::file_type symlink_file_type() const
0232 {
0233 if (!filesystem::type_present(m_symlink_status))
0234 refresh_impl();
0235 return m_symlink_status.type();
0236 }
0237
0238 filesystem::file_type symlink_file_type(system::error_code& ec) const BOOST_NOEXCEPT
0239 {
0240 ec.clear();
0241
0242 if (!filesystem::type_present(m_symlink_status))
0243 refresh_impl(&ec);
0244 return m_symlink_status.type();
0245 }
0246
0247 bool exists() const
0248 {
0249 filesystem::file_type ft = this->file_type();
0250 return ft != filesystem::status_error && ft != filesystem::file_not_found;
0251 }
0252
0253 bool exists(system::error_code& ec) const BOOST_NOEXCEPT
0254 {
0255 filesystem::file_type ft = this->file_type(ec);
0256 return ft != filesystem::status_error && ft != filesystem::file_not_found;
0257 }
0258
0259 bool is_regular_file() const
0260 {
0261 return this->file_type() == filesystem::regular_file;
0262 }
0263
0264 bool is_regular_file(system::error_code& ec) const BOOST_NOEXCEPT
0265 {
0266 return this->file_type(ec) == filesystem::regular_file;
0267 }
0268
0269 bool is_directory() const
0270 {
0271 return this->file_type() == filesystem::directory_file;
0272 }
0273
0274 bool is_directory(system::error_code& ec) const BOOST_NOEXCEPT
0275 {
0276 return this->file_type(ec) == filesystem::directory_file;
0277 }
0278
0279 bool is_symlink() const
0280 {
0281 return this->symlink_file_type() == filesystem::symlink_file;
0282 }
0283
0284 bool is_symlink(system::error_code& ec) const BOOST_NOEXCEPT
0285 {
0286 return this->symlink_file_type(ec) == filesystem::symlink_file;
0287 }
0288
0289 bool is_block_file() const
0290 {
0291 return this->file_type() == filesystem::block_file;
0292 }
0293
0294 bool is_block_file(system::error_code& ec) const BOOST_NOEXCEPT
0295 {
0296 return this->file_type(ec) == filesystem::block_file;
0297 }
0298
0299 bool is_character_file() const
0300 {
0301 return this->file_type() == filesystem::character_file;
0302 }
0303
0304 bool is_character_file(system::error_code& ec) const BOOST_NOEXCEPT
0305 {
0306 return this->file_type(ec) == filesystem::character_file;
0307 }
0308
0309 bool is_fifo() const
0310 {
0311 return this->file_type() == filesystem::fifo_file;
0312 }
0313
0314 bool is_fifo(system::error_code& ec) const BOOST_NOEXCEPT
0315 {
0316 return this->file_type(ec) == filesystem::fifo_file;
0317 }
0318
0319 bool is_socket() const
0320 {
0321 return this->file_type() == filesystem::socket_file;
0322 }
0323
0324 bool is_socket(system::error_code& ec) const BOOST_NOEXCEPT
0325 {
0326 return this->file_type(ec) == filesystem::socket_file;
0327 }
0328
0329 bool is_reparse_file() const
0330 {
0331 return this->symlink_file_type() == filesystem::reparse_file;
0332 }
0333
0334 bool is_reparse_file(system::error_code& ec) const BOOST_NOEXCEPT
0335 {
0336 return this->symlink_file_type(ec) == filesystem::reparse_file;
0337 }
0338
0339 bool is_other() const
0340 {
0341 filesystem::file_type ft = this->file_type();
0342 return ft != filesystem::status_error && ft != filesystem::file_not_found &&
0343 ft != filesystem::regular_file && ft != filesystem::directory_file;
0344 }
0345
0346 bool is_other(system::error_code& ec) const BOOST_NOEXCEPT
0347 {
0348 filesystem::file_type ft = this->file_type(ec);
0349 return ft != filesystem::status_error && ft != filesystem::file_not_found &&
0350 ft != filesystem::regular_file && ft != filesystem::directory_file;
0351 }
0352
0353 bool operator==(directory_entry const& rhs) const { return m_path == rhs.m_path; }
0354 bool operator!=(directory_entry const& rhs) const { return m_path != rhs.m_path; }
0355 bool operator<(directory_entry const& rhs) const { return m_path < rhs.m_path; }
0356 bool operator<=(directory_entry const& rhs) const { return m_path <= rhs.m_path; }
0357 bool operator>(directory_entry const& rhs) const { return m_path > rhs.m_path; }
0358 bool operator>=(directory_entry const& rhs) const { return m_path >= rhs.m_path; }
0359
0360 private:
0361 BOOST_FILESYSTEM_DECL void refresh_impl(system::error_code* ec = NULL) const;
0362
0363 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0364 void assign_with_status(boost::filesystem::path&& p, file_status st, file_status symlink_st)
0365 {
0366 m_path = static_cast< boost::filesystem::path&& >(p);
0367 m_status = static_cast< file_status&& >(st);
0368 m_symlink_status = static_cast< file_status&& >(symlink_st);
0369 }
0370 #endif
0371
0372 void assign_with_status(boost::filesystem::path const& p, file_status st, file_status symlink_st)
0373 {
0374 m_path = p;
0375 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0376 m_status = static_cast< file_status&& >(st);
0377 m_symlink_status = static_cast< file_status&& >(symlink_st);
0378 #else
0379 m_status = st;
0380 m_symlink_status = symlink_st;
0381 #endif
0382 }
0383
0384 void replace_filename_with_status(boost::filesystem::path const& p, file_status st, file_status symlink_st)
0385 {
0386 m_path.replace_filename(p);
0387 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0388 m_status = static_cast< file_status&& >(st);
0389 m_symlink_status = static_cast< file_status&& >(symlink_st);
0390 #else
0391 m_status = st;
0392 m_symlink_status = symlink_st;
0393 #endif
0394 }
0395
0396 private:
0397 boost::filesystem::path m_path;
0398 mutable file_status m_status;
0399 mutable file_status m_symlink_status;
0400 };
0401
0402 #if !defined(BOOST_FILESYSTEM_SOURCE)
0403
0404 inline directory_entry::directory_entry(boost::filesystem::path const& p) :
0405 m_path(p)
0406 {
0407 #if BOOST_FILESYSTEM_VERSION >= 4
0408 refresh_impl();
0409 #endif
0410 }
0411
0412 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0413 inline void directory_entry::assign(boost::filesystem::path&& p)
0414 {
0415 m_path = static_cast< boost::filesystem::path&& >(p);
0416 #if BOOST_FILESYSTEM_VERSION >= 4
0417 refresh_impl();
0418 #else
0419 m_status = file_status();
0420 m_symlink_status = file_status();
0421 #endif
0422 }
0423 #endif
0424
0425 inline void directory_entry::assign(boost::filesystem::path const& p)
0426 {
0427 m_path = p;
0428 #if BOOST_FILESYSTEM_VERSION >= 4
0429 refresh_impl();
0430 #else
0431 m_status = file_status();
0432 m_symlink_status = file_status();
0433 #endif
0434 }
0435
0436 inline void directory_entry::replace_filename(boost::filesystem::path const& p)
0437 {
0438 m_path.replace_filename(p);
0439 #if BOOST_FILESYSTEM_VERSION >= 4
0440 refresh_impl();
0441 #else
0442 m_status = file_status();
0443 m_symlink_status = file_status();
0444 #endif
0445 }
0446
0447 #endif
0448
0449 namespace detail {
0450 namespace path_traits {
0451
0452
0453 template< typename Callback >
0454 BOOST_FORCEINLINE typename Callback::result_type dispatch(directory_entry const& de, Callback cb, const codecvt_type* cvt, directory_entry_tag)
0455 {
0456 boost::filesystem::path::string_type const& source = de.path().native();
0457 return cb(source.data(), source.data() + source.size(), cvt);
0458 }
0459
0460 }
0461 }
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475 inline file_status status(directory_entry const& e)
0476 {
0477 return e.status();
0478 }
0479
0480 inline file_status status(directory_entry const& e, system::error_code& ec) BOOST_NOEXCEPT
0481 {
0482 return e.status(ec);
0483 }
0484
0485 inline file_status symlink_status(directory_entry const& e)
0486 {
0487 return e.symlink_status();
0488 }
0489
0490 inline file_status symlink_status(directory_entry const& e, system::error_code& ec) BOOST_NOEXCEPT
0491 {
0492 return e.symlink_status(ec);
0493 }
0494
0495 inline bool type_present(directory_entry const& e)
0496 {
0497 return e.file_type() != filesystem::status_error;
0498 }
0499
0500 inline bool type_present(directory_entry const& e, system::error_code& ec) BOOST_NOEXCEPT
0501 {
0502 return e.file_type(ec) != filesystem::status_error;
0503 }
0504
0505 inline bool status_known(directory_entry const& e)
0506 {
0507 return filesystem::status_known(e.status());
0508 }
0509
0510 inline bool status_known(directory_entry const& e, system::error_code& ec) BOOST_NOEXCEPT
0511 {
0512 return filesystem::status_known(e.status(ec));
0513 }
0514
0515 inline bool exists(directory_entry const& e)
0516 {
0517 return e.exists();
0518 }
0519
0520 inline bool exists(directory_entry const& e, system::error_code& ec) BOOST_NOEXCEPT
0521 {
0522 return e.exists(ec);
0523 }
0524
0525 inline bool is_regular_file(directory_entry const& e)
0526 {
0527 return e.is_regular_file();
0528 }
0529
0530 inline bool is_regular_file(directory_entry const& e, system::error_code& ec) BOOST_NOEXCEPT
0531 {
0532 return e.is_regular_file(ec);
0533 }
0534
0535 inline bool is_directory(directory_entry const& e)
0536 {
0537 return e.is_directory();
0538 }
0539
0540 inline bool is_directory(directory_entry const& e, system::error_code& ec) BOOST_NOEXCEPT
0541 {
0542 return e.is_directory(ec);
0543 }
0544
0545 inline bool is_symlink(directory_entry const& e)
0546 {
0547 return e.is_symlink();
0548 }
0549
0550 inline bool is_symlink(directory_entry const& e, system::error_code& ec) BOOST_NOEXCEPT
0551 {
0552 return e.is_symlink(ec);
0553 }
0554
0555 inline bool is_block_file(directory_entry const& e)
0556 {
0557 return e.is_block_file();
0558 }
0559
0560 inline bool is_block_file(directory_entry const& e, system::error_code& ec) BOOST_NOEXCEPT
0561 {
0562 return e.is_block_file(ec);
0563 }
0564
0565 inline bool is_character_file(directory_entry const& e)
0566 {
0567 return e.is_character_file();
0568 }
0569
0570 inline bool is_character_file(directory_entry const& e, system::error_code& ec) BOOST_NOEXCEPT
0571 {
0572 return e.is_character_file(ec);
0573 }
0574
0575 inline bool is_fifo(directory_entry const& e)
0576 {
0577 return e.is_fifo();
0578 }
0579
0580 inline bool is_fifo(directory_entry const& e, system::error_code& ec) BOOST_NOEXCEPT
0581 {
0582 return e.is_fifo(ec);
0583 }
0584
0585 inline bool is_socket(directory_entry const& e)
0586 {
0587 return e.is_socket();
0588 }
0589
0590 inline bool is_socket(directory_entry const& e, system::error_code& ec) BOOST_NOEXCEPT
0591 {
0592 return e.is_socket(ec);
0593 }
0594
0595 inline bool is_reparse_file(directory_entry const& e)
0596 {
0597 return e.is_reparse_file();
0598 }
0599
0600 inline bool is_reparse_file(directory_entry const& e, system::error_code& ec) BOOST_NOEXCEPT
0601 {
0602 return e.is_reparse_file(ec);
0603 }
0604
0605 inline bool is_other(directory_entry const& e)
0606 {
0607 return e.is_other();
0608 }
0609
0610 inline bool is_other(directory_entry const& e, system::error_code& ec) BOOST_NOEXCEPT
0611 {
0612 return e.is_other(ec);
0613 }
0614
0615 #ifndef BOOST_FILESYSTEM_NO_DEPRECATED
0616 BOOST_FILESYSTEM_DETAIL_DEPRECATED("Use is_regular_file() instead")
0617 inline bool is_regular(directory_entry const& e)
0618 {
0619 return filesystem::is_regular_file(e);
0620 }
0621 #endif
0622
0623
0624
0625
0626
0627
0628
0629 BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(directory_options, unsigned int)
0630 {
0631 none = 0u,
0632 skip_permission_denied = 1u,
0633 follow_directory_symlink = 1u << 1u,
0634 skip_dangling_symlinks = 1u << 2u,
0635 pop_on_error = 1u << 3u,
0636
0637 _detail_no_follow = 1u << 4u,
0638 _detail_no_push = 1u << 5u
0639 }
0640 BOOST_SCOPED_ENUM_DECLARE_END(directory_options)
0641
0642 BOOST_BITMASK(BOOST_SCOPED_ENUM_NATIVE(directory_options))
0643
0644 namespace detail {
0645
0646 struct dir_itr_imp :
0647 public boost::intrusive_ref_counter< dir_itr_imp >
0648 {
0649 #ifdef BOOST_WINDOWS_API
0650 bool close_handle;
0651 unsigned char extra_data_format;
0652 std::size_t current_offset;
0653 #endif
0654 directory_entry dir_entry;
0655 void* handle;
0656
0657 dir_itr_imp() BOOST_NOEXCEPT :
0658 #ifdef BOOST_WINDOWS_API
0659 close_handle(false),
0660 extra_data_format(0u),
0661 current_offset(0u),
0662 #endif
0663 handle(NULL)
0664 {
0665 }
0666 BOOST_FILESYSTEM_DECL ~dir_itr_imp() BOOST_NOEXCEPT;
0667
0668 BOOST_FILESYSTEM_DECL static void* operator new(std::size_t class_size, std::size_t extra_size) BOOST_NOEXCEPT;
0669 BOOST_FILESYSTEM_DECL static void operator delete(void* p, std::size_t extra_size) BOOST_NOEXCEPT;
0670 BOOST_FILESYSTEM_DECL static void operator delete(void* p) BOOST_NOEXCEPT;
0671 };
0672
0673 }
0674
0675
0676
0677
0678
0679
0680
0681 class directory_iterator :
0682 public boost::iterator_facade<
0683 directory_iterator,
0684 directory_entry,
0685 boost::single_pass_traversal_tag
0686 >
0687 {
0688 friend class boost::iterator_core_access;
0689
0690 friend BOOST_FILESYSTEM_DECL void detail::directory_iterator_construct(directory_iterator& it, path const& p, unsigned int opts, detail::directory_iterator_params* params, system::error_code* ec);
0691 friend BOOST_FILESYSTEM_DECL void detail::directory_iterator_increment(directory_iterator& it, system::error_code* ec);
0692
0693 public:
0694 directory_iterator() BOOST_NOEXCEPT {}
0695
0696
0697
0698 explicit directory_iterator(path const& p, BOOST_SCOPED_ENUM_NATIVE(directory_options) opts = directory_options::none)
0699 {
0700 detail::directory_iterator_construct(*this, p, static_cast< unsigned int >(opts), NULL, NULL);
0701 }
0702
0703 directory_iterator(path const& p, system::error_code& ec) BOOST_NOEXCEPT
0704 {
0705 detail::directory_iterator_construct(*this, p, static_cast< unsigned int >(directory_options::none), NULL, &ec);
0706 }
0707
0708 directory_iterator(path const& p, BOOST_SCOPED_ENUM_NATIVE(directory_options) opts, system::error_code& ec) BOOST_NOEXCEPT
0709 {
0710 detail::directory_iterator_construct(*this, p, static_cast< unsigned int >(opts), NULL, &ec);
0711 }
0712
0713 BOOST_DEFAULTED_FUNCTION(directory_iterator(directory_iterator const& that), : m_imp(that.m_imp) {})
0714 BOOST_DEFAULTED_FUNCTION(directory_iterator& operator=(directory_iterator const& that), { m_imp = that.m_imp; return *this; })
0715
0716 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0717 directory_iterator(directory_iterator&& that) BOOST_NOEXCEPT :
0718 m_imp(static_cast< boost::intrusive_ptr< detail::dir_itr_imp >&& >(that.m_imp))
0719 {
0720 }
0721
0722 directory_iterator& operator=(directory_iterator&& that) BOOST_NOEXCEPT
0723 {
0724 m_imp = static_cast< boost::intrusive_ptr< detail::dir_itr_imp >&& >(that.m_imp);
0725 return *this;
0726 }
0727 #endif
0728
0729 directory_iterator& increment(system::error_code& ec) BOOST_NOEXCEPT
0730 {
0731 detail::directory_iterator_increment(*this, &ec);
0732 return *this;
0733 }
0734
0735 private:
0736 boost::iterator_facade<
0737 directory_iterator,
0738 directory_entry,
0739 boost::single_pass_traversal_tag
0740 >::reference dereference() const
0741 {
0742 BOOST_ASSERT_MSG(!is_end(), "attempt to dereference end directory iterator");
0743 return m_imp->dir_entry;
0744 }
0745
0746 void increment() { detail::directory_iterator_increment(*this, NULL); }
0747
0748 bool equal(directory_iterator const& rhs) const BOOST_NOEXCEPT
0749 {
0750 return m_imp == rhs.m_imp || (is_end() && rhs.is_end());
0751 }
0752
0753 bool is_end() const BOOST_NOEXCEPT
0754 {
0755
0756
0757 return !m_imp || !m_imp->handle;
0758 }
0759
0760 private:
0761
0762
0763 boost::intrusive_ptr< detail::dir_itr_imp > m_imp;
0764 };
0765
0766
0767
0768
0769
0770
0771 inline directory_iterator const& begin(directory_iterator const& iter) BOOST_NOEXCEPT
0772 {
0773 return iter;
0774 }
0775
0776 inline directory_iterator end(directory_iterator const&) BOOST_NOEXCEPT
0777 {
0778 return directory_iterator();
0779 }
0780
0781
0782 inline directory_iterator const& cbegin(directory_iterator const& iter) BOOST_NOEXCEPT
0783 {
0784 return iter;
0785 }
0786
0787 inline directory_iterator cend(directory_iterator const&) BOOST_NOEXCEPT
0788 {
0789 return directory_iterator();
0790 }
0791
0792
0793
0794 inline directory_iterator& range_begin(directory_iterator& iter) BOOST_NOEXCEPT
0795 {
0796 return iter;
0797 }
0798
0799 inline directory_iterator range_begin(directory_iterator const& iter) BOOST_NOEXCEPT
0800 {
0801 return iter;
0802 }
0803
0804 inline directory_iterator range_end(directory_iterator&) BOOST_NOEXCEPT
0805 {
0806 return directory_iterator();
0807 }
0808
0809 inline directory_iterator range_end(directory_iterator const&) BOOST_NOEXCEPT
0810 {
0811 return directory_iterator();
0812 }
0813
0814 }
0815
0816
0817 template< typename C, typename Enabler >
0818 struct range_mutable_iterator;
0819
0820 template<>
0821 struct range_mutable_iterator< boost::filesystem::directory_iterator, void >
0822 {
0823 typedef boost::filesystem::directory_iterator type;
0824 };
0825
0826 template< typename C, typename Enabler >
0827 struct range_const_iterator;
0828
0829 template<>
0830 struct range_const_iterator< boost::filesystem::directory_iterator, void >
0831 {
0832 typedef boost::filesystem::directory_iterator type;
0833 };
0834
0835 namespace filesystem {
0836
0837
0838
0839
0840
0841
0842
0843 #if !defined(BOOST_FILESYSTEM_NO_DEPRECATED)
0844
0845 BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(symlink_option, unsigned int)
0846 {
0847 none = static_cast< unsigned int >(directory_options::none),
0848 no_recurse = none,
0849 recurse = static_cast< unsigned int >(directory_options::follow_directory_symlink),
0850 _detail_no_push = static_cast< unsigned int >(directory_options::_detail_no_push)
0851 }
0852 BOOST_SCOPED_ENUM_DECLARE_END(symlink_option)
0853
0854 BOOST_BITMASK(BOOST_SCOPED_ENUM_NATIVE(symlink_option))
0855 #endif
0856
0857 class recursive_directory_iterator;
0858
0859 namespace detail {
0860
0861 struct recur_dir_itr_imp :
0862 public boost::intrusive_ref_counter< recur_dir_itr_imp >
0863 {
0864 typedef directory_iterator element_type;
0865 std::vector< element_type > m_stack;
0866
0867 unsigned int m_options;
0868
0869 explicit recur_dir_itr_imp(unsigned int opts) BOOST_NOEXCEPT : m_options(opts) {}
0870 };
0871
0872 BOOST_FILESYSTEM_DECL void recursive_directory_iterator_construct(recursive_directory_iterator& it, path const& dir_path, unsigned int opts, system::error_code* ec);
0873 BOOST_FILESYSTEM_DECL void recursive_directory_iterator_increment(recursive_directory_iterator& it, system::error_code* ec);
0874 BOOST_FILESYSTEM_DECL void recursive_directory_iterator_pop(recursive_directory_iterator& it, system::error_code* ec);
0875
0876 }
0877
0878
0879
0880
0881
0882
0883
0884 class recursive_directory_iterator :
0885 public boost::iterator_facade<
0886 recursive_directory_iterator,
0887 directory_entry,
0888 boost::single_pass_traversal_tag
0889 >
0890 {
0891 friend class boost::iterator_core_access;
0892
0893 friend BOOST_FILESYSTEM_DECL void detail::recursive_directory_iterator_construct(recursive_directory_iterator& it, path const& dir_path, unsigned int opts, system::error_code* ec);
0894 friend BOOST_FILESYSTEM_DECL void detail::recursive_directory_iterator_increment(recursive_directory_iterator& it, system::error_code* ec);
0895 friend BOOST_FILESYSTEM_DECL void detail::recursive_directory_iterator_pop(recursive_directory_iterator& it, system::error_code* ec);
0896
0897 public:
0898 recursive_directory_iterator() BOOST_NOEXCEPT {}
0899
0900 explicit recursive_directory_iterator(path const& dir_path)
0901 {
0902 detail::recursive_directory_iterator_construct(*this, dir_path, static_cast< unsigned int >(directory_options::none), NULL);
0903 }
0904
0905 recursive_directory_iterator(path const& dir_path, system::error_code& ec)
0906 {
0907 detail::recursive_directory_iterator_construct(*this, dir_path, static_cast< unsigned int >(directory_options::none), &ec);
0908 }
0909
0910 recursive_directory_iterator(path const& dir_path, BOOST_SCOPED_ENUM_NATIVE(directory_options) opts)
0911 {
0912 detail::recursive_directory_iterator_construct(*this, dir_path, static_cast< unsigned int >(opts), NULL);
0913 }
0914
0915 recursive_directory_iterator(path const& dir_path, BOOST_SCOPED_ENUM_NATIVE(directory_options) opts, system::error_code& ec)
0916 {
0917 detail::recursive_directory_iterator_construct(*this, dir_path, static_cast< unsigned int >(opts), &ec);
0918 }
0919
0920 #if !defined(BOOST_FILESYSTEM_NO_DEPRECATED)
0921
0922 BOOST_FILESYSTEM_DETAIL_DEPRECATED("Use directory_options instead of symlink_option")
0923 recursive_directory_iterator(path const& dir_path, BOOST_SCOPED_ENUM_NATIVE(symlink_option) opts)
0924 {
0925 detail::recursive_directory_iterator_construct(*this, dir_path, static_cast< unsigned int >(opts), NULL);
0926 }
0927
0928 BOOST_FILESYSTEM_DETAIL_DEPRECATED("Use directory_options instead of symlink_option")
0929 recursive_directory_iterator(path const& dir_path, BOOST_SCOPED_ENUM_NATIVE(symlink_option) opts, system::error_code& ec) BOOST_NOEXCEPT
0930 {
0931 detail::recursive_directory_iterator_construct(*this, dir_path, static_cast< unsigned int >(opts), &ec);
0932 }
0933 #endif
0934
0935 BOOST_DEFAULTED_FUNCTION(recursive_directory_iterator(recursive_directory_iterator const& that), : m_imp(that.m_imp) {})
0936 BOOST_DEFAULTED_FUNCTION(recursive_directory_iterator& operator=(recursive_directory_iterator const& that), { m_imp = that.m_imp; return *this; })
0937
0938 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0939 recursive_directory_iterator(recursive_directory_iterator&& that) BOOST_NOEXCEPT :
0940 m_imp(static_cast< boost::intrusive_ptr< detail::recur_dir_itr_imp >&& >(that.m_imp))
0941 {
0942 }
0943
0944 recursive_directory_iterator& operator=(recursive_directory_iterator&& that) BOOST_NOEXCEPT
0945 {
0946 m_imp = static_cast< boost::intrusive_ptr< detail::recur_dir_itr_imp >&& >(that.m_imp);
0947 return *this;
0948 }
0949 #endif
0950
0951 recursive_directory_iterator& increment(system::error_code& ec) BOOST_NOEXCEPT
0952 {
0953 detail::recursive_directory_iterator_increment(*this, &ec);
0954 return *this;
0955 }
0956
0957 int depth() const BOOST_NOEXCEPT
0958 {
0959 BOOST_ASSERT_MSG(!is_end(), "depth() on end recursive_directory_iterator");
0960 return static_cast< int >(m_imp->m_stack.size() - 1u);
0961 }
0962
0963 bool recursion_pending() const BOOST_NOEXCEPT
0964 {
0965 BOOST_ASSERT_MSG(!is_end(), "recursion_pending() on end recursive_directory_iterator");
0966 return (m_imp->m_options & static_cast< unsigned int >(directory_options::_detail_no_push)) == 0u;
0967 }
0968
0969 #ifndef BOOST_FILESYSTEM_NO_DEPRECATED
0970 BOOST_FILESYSTEM_DETAIL_DEPRECATED("Use recursive_directory_iterator::depth() instead")
0971 int level() const BOOST_NOEXCEPT
0972 {
0973 return depth();
0974 }
0975 bool no_push_pending() const BOOST_NOEXCEPT { return !recursion_pending(); }
0976 bool no_push_request() const BOOST_NOEXCEPT { return !recursion_pending(); }
0977 #endif
0978
0979 void pop()
0980 {
0981 detail::recursive_directory_iterator_pop(*this, NULL);
0982 }
0983
0984 void pop(system::error_code& ec) BOOST_NOEXCEPT
0985 {
0986 detail::recursive_directory_iterator_pop(*this, &ec);
0987 }
0988
0989 void disable_recursion_pending(bool value = true) BOOST_NOEXCEPT
0990 {
0991 BOOST_ASSERT_MSG(!is_end(), "disable_recursion_pending() on end recursive_directory_iterator");
0992 if (value)
0993 m_imp->m_options |= static_cast< unsigned int >(directory_options::_detail_no_push);
0994 else
0995 m_imp->m_options &= ~static_cast< unsigned int >(directory_options::_detail_no_push);
0996 }
0997
0998 #ifndef BOOST_FILESYSTEM_NO_DEPRECATED
0999 BOOST_FILESYSTEM_DETAIL_DEPRECATED("Use recursive_directory_iterator::disable_recursion_pending() instead")
1000 void no_push(bool value = true) BOOST_NOEXCEPT
1001 {
1002 disable_recursion_pending(value);
1003 }
1004 #endif
1005
1006 file_status status() const
1007 {
1008 BOOST_ASSERT_MSG(!is_end(), "status() on end recursive_directory_iterator");
1009 return m_imp->m_stack.back()->status();
1010 }
1011
1012 file_status symlink_status() const
1013 {
1014 BOOST_ASSERT_MSG(!is_end(), "symlink_status() on end recursive_directory_iterator");
1015 return m_imp->m_stack.back()->symlink_status();
1016 }
1017
1018 private:
1019 boost::iterator_facade<
1020 recursive_directory_iterator,
1021 directory_entry,
1022 boost::single_pass_traversal_tag
1023 >::reference dereference() const
1024 {
1025 BOOST_ASSERT_MSG(!is_end(), "dereference of end recursive_directory_iterator");
1026 return *m_imp->m_stack.back();
1027 }
1028
1029 void increment() { detail::recursive_directory_iterator_increment(*this, NULL); }
1030
1031 bool equal(recursive_directory_iterator const& rhs) const BOOST_NOEXCEPT
1032 {
1033 return m_imp == rhs.m_imp || (is_end() && rhs.is_end());
1034 }
1035
1036 bool is_end() const BOOST_NOEXCEPT
1037 {
1038
1039
1040 return !m_imp || m_imp->m_stack.empty();
1041 }
1042
1043 private:
1044
1045
1046 boost::intrusive_ptr< detail::recur_dir_itr_imp > m_imp;
1047 };
1048
1049 #if !defined(BOOST_FILESYSTEM_NO_DEPRECATED)
1050 BOOST_FILESYSTEM_DETAIL_DEPRECATED("Use recursive_directory_iterator instead")
1051 typedef recursive_directory_iterator wrecursive_directory_iterator;
1052 #endif
1053
1054
1055
1056
1057
1058
1059 inline recursive_directory_iterator const& begin(recursive_directory_iterator const& iter) BOOST_NOEXCEPT
1060 {
1061 return iter;
1062 }
1063
1064 inline recursive_directory_iterator end(recursive_directory_iterator const&) BOOST_NOEXCEPT
1065 {
1066 return recursive_directory_iterator();
1067 }
1068
1069
1070 inline recursive_directory_iterator const& cbegin(recursive_directory_iterator const& iter) BOOST_NOEXCEPT
1071 {
1072 return iter;
1073 }
1074
1075 inline recursive_directory_iterator cend(recursive_directory_iterator const&) BOOST_NOEXCEPT
1076 {
1077 return recursive_directory_iterator();
1078 }
1079
1080
1081
1082 inline recursive_directory_iterator& range_begin(recursive_directory_iterator& iter) BOOST_NOEXCEPT
1083 {
1084 return iter;
1085 }
1086
1087 inline recursive_directory_iterator range_begin(recursive_directory_iterator const& iter) BOOST_NOEXCEPT
1088 {
1089 return iter;
1090 }
1091
1092 inline recursive_directory_iterator range_end(recursive_directory_iterator&) BOOST_NOEXCEPT
1093 {
1094 return recursive_directory_iterator();
1095 }
1096
1097 inline recursive_directory_iterator range_end(recursive_directory_iterator const&) BOOST_NOEXCEPT
1098 {
1099 return recursive_directory_iterator();
1100 }
1101
1102 }
1103
1104
1105 template<>
1106 struct range_mutable_iterator< boost::filesystem::recursive_directory_iterator, void >
1107 {
1108 typedef boost::filesystem::recursive_directory_iterator type;
1109 };
1110
1111 template<>
1112 struct range_const_iterator< boost::filesystem::recursive_directory_iterator, void >
1113 {
1114 typedef boost::filesystem::recursive_directory_iterator type;
1115 };
1116
1117 }
1118
1119 #include <boost/filesystem/detail/footer.hpp>
1120
1121 #endif