Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:35:37

0001 //  boost/filesystem/directory.hpp  ---------------------------------------------------//
0002 
0003 //  Copyright Beman Dawes 2002-2009
0004 //  Copyright Jan Langer 2002
0005 //  Copyright Dietmar Kuehl 2001
0006 //  Copyright Vladimir Prus 2002
0007 //  Copyright Andrey Semashev 2019, 2022
0008 
0009 //  Distributed under the Boost Software License, Version 1.0.
0010 //  See http://www.boost.org/LICENSE_1_0.txt
0011 
0012 //  Library home page: http://www.boost.org/libs/filesystem
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 } // namespace detail
0054 
0055 //--------------------------------------------------------------------------------------//
0056 //                                                                                      //
0057 //                                 directory_entry                                      //
0058 //                                                                                      //
0059 //--------------------------------------------------------------------------------------//
0060 
0061 //  GCC has a problem with a member function named path within a namespace or
0062 //  sub-namespace that also has a class named path. The workaround is to always
0063 //  fully qualify the name path when it refers to the class name.
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; // enables class path ctor taking directory_entry
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     //  As of October 2015 the interaction between noexcept and =default is so troublesome
0106     //  for VC++, GCC, and probably other compilers, that =default is not used with noexcept
0107     //  functions. GCC is not even consistent for the same release on different platforms.
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 // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
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;         // stat()-like
0399     mutable file_status m_symlink_status; // lstat()-like
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 // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
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 // !defined(BOOST_FILESYSTEM_SOURCE)
0448 
0449 namespace detail {
0450 namespace path_traits {
0451 
0452 // Dispatch function for integration with path class
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 } // namespace path_traits
0461 } // namespace detail
0462 
0463 //--------------------------------------------------------------------------------------//
0464 //                                                                                      //
0465 //                            directory_entry overloads                                 //
0466 //                                                                                      //
0467 //--------------------------------------------------------------------------------------//
0468 
0469 //  Without these functions, calling (for example) 'is_directory' with a 'directory_entry' results in:
0470 //  - a conversion to 'path' using 'operator boost::filesystem::path const&()',
0471 //  - then a call to 'is_directory(path const& p)' which recomputes the status with 'detail::status(p)'.
0472 //
0473 //  These functions avoid a costly recomputation of the status if one calls 'is_directory(e)' instead of 'is_directory(e.status())'
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 //                            directory_iterator helpers                                //
0626 //                                                                                      //
0627 //--------------------------------------------------------------------------------------//
0628 
0629 BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(directory_options, unsigned int)
0630 {
0631     none = 0u,
0632     skip_permission_denied = 1u,         // if a directory cannot be opened because of insufficient permissions, pretend that the directory is empty
0633     follow_directory_symlink = 1u << 1u, // recursive_directory_iterator: follow directory symlinks
0634     skip_dangling_symlinks = 1u << 2u,   // non-standard extension for recursive_directory_iterator: don't follow dangling directory symlinks,
0635     pop_on_error = 1u << 3u,             // non-standard extension for recursive_directory_iterator: instead of producing an end iterator on errors,
0636                                          // repeatedly invoke pop() until it succeeds or the iterator becomes equal to end iterator
0637     _detail_no_follow = 1u << 4u,        // internal use only
0638     _detail_no_push = 1u << 5u           // internal use only
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 } // namespace detail
0674 
0675 //--------------------------------------------------------------------------------------//
0676 //                                                                                      //
0677 //                                directory_iterator                                    //
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 {} // creates the "end" iterator
0695 
0696     // iterator_facade derived classes don't seem to like implementations in
0697     // separate translation unit dll's, so forward to detail functions
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 // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
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         // Note: The check for handle is needed because the iterator can be copied and the copy
0756         // can be incremented to end while the original iterator still refers to the same dir_itr_imp.
0757         return !m_imp || !m_imp->handle;
0758     }
0759 
0760 private:
0761     // intrusive_ptr provides the shallow-copy semantics required for single pass iterators
0762     // (i.e. InputIterators). The end iterator is indicated by is_end().
0763     boost::intrusive_ptr< detail::dir_itr_imp > m_imp;
0764 };
0765 
0766 //  enable directory_iterator C++11 range-based for statement use  --------------------//
0767 
0768 // begin() and end() are only used by a range-based for statement in the context of
0769 // auto - thus the top-level const is stripped - so returning const is harmless and
0770 // emphasizes begin() is just a pass through.
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 // enable C++14 generic accessors for range const iterators
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 //  enable directory_iterator BOOST_FOREACH  -----------------------------------------//
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 } // namespace filesystem
0815 
0816 //  namespace boost template specializations
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 //                      recursive_directory_iterator helpers                            //
0840 //                                                                                      //
0841 //--------------------------------------------------------------------------------------//
0842 
0843 #if !defined(BOOST_FILESYSTEM_NO_DEPRECATED)
0844 // Deprecated enum, use directory_options instead
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,                                                                  // don't follow directory symlinks (default behavior)
0849     recurse = static_cast< unsigned int >(directory_options::follow_directory_symlink), // follow directory symlinks
0850     _detail_no_push = static_cast< unsigned int >(directory_options::_detail_no_push)   // internal use only
0851 }
0852 BOOST_SCOPED_ENUM_DECLARE_END(symlink_option)
0853 
0854 BOOST_BITMASK(BOOST_SCOPED_ENUM_NATIVE(symlink_option))
0855 #endif // BOOST_FILESYSTEM_NO_DEPRECATED
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     // directory_options values, declared as unsigned int for ABI compatibility
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 } // namespace detail
0877 
0878 //--------------------------------------------------------------------------------------//
0879 //                                                                                      //
0880 //                           recursive_directory_iterator                               //
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 {} // creates the "end" iterator
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     // Deprecated constructors
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 // BOOST_FILESYSTEM_NO_DEPRECATED
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 // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
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         // Note: The check for m_stack.empty() is needed because the iterator can be copied and the copy
1039         // can be incremented to end while the original iterator still refers to the same recur_dir_itr_imp.
1040         return !m_imp || m_imp->m_stack.empty();
1041     }
1042 
1043 private:
1044     // intrusive_ptr provides the shallow-copy semantics required for single pass iterators
1045     // (i.e. InputIterators). The end iterator is indicated by is_end().
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 //  enable recursive directory iterator C++11 range-base for statement use  ----------//
1055 
1056 // begin() and end() are only used by a range-based for statement in the context of
1057 // auto - thus the top-level const is stripped - so returning const is harmless and
1058 // emphasizes begin() is just a pass through.
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 // enable C++14 generic accessors for range const iterators
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 //  enable recursive directory iterator BOOST_FOREACH  -------------------------------//
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 } // namespace filesystem
1103 
1104 //  namespace boost template specializations
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 } // namespace boost
1118 
1119 #include <boost/filesystem/detail/footer.hpp>
1120 
1121 #endif // BOOST_FILESYSTEM_DIRECTORY_HPP