LCOV - code coverage report
Current view: top level - usr/include/boost/filesystem - operations.hpp (source / functions) Hit Total Coverage
Test: ROSE Lines: 8 118 6.8 %
Date: 2022-12-08 13:48:47 Functions: 0 12 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14