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