imgtools/imglib/boostlibrary/boost/filesystem/operations.hpp
changeset 607 378360dbbdba
parent 600 6d08f4a05d93
equal deleted inserted replaced
591:22486c9c7b15 607:378360dbbdba
       
     1 //  boost/filesystem/operations.hpp  -----------------------------------------//
       
     2 
       
     3 //  Copyright 2002-2005 Beman Dawes
       
     4 //  Copyright 2002 Jan Langer
       
     5 //  Copyright 2001 Dietmar Kuehl                                        
       
     6 //  
       
     7 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
       
     8 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       
     9 
       
    10 //  See library home page at http://www.boost.org/libs/filesystem
       
    11 
       
    12 //----------------------------------------------------------------------------// 
       
    13 
       
    14 #ifndef BOOST_FILESYSTEM_OPERATIONS_HPP
       
    15 #define BOOST_FILESYSTEM_OPERATIONS_HPP
       
    16 
       
    17 #include <boost/filesystem/path.hpp>
       
    18 
       
    19 #include <boost/shared_ptr.hpp>
       
    20 #include <boost/utility/enable_if.hpp>
       
    21 #include <boost/type_traits/is_same.hpp>
       
    22 #include <boost/iterator.hpp>
       
    23 #include <boost/cstdint.hpp>
       
    24 #include <boost/assert.hpp>
       
    25 
       
    26 #include <string>
       
    27 #include <utility> // for pair
       
    28 #include <ctime>
       
    29 
       
    30 #ifdef BOOST_WINDOWS_API
       
    31 #  include <fstream>
       
    32 #  if !defined(_WIN32_WINNT) || _WIN32_WINNT >= 0x0500
       
    33 #    define BOOST_FS_HARD_LINK // Default for Windows 2K or later 
       
    34 #  endif
       
    35 #endif
       
    36 
       
    37 #include <boost/config/abi_prefix.hpp> // must be the last #include
       
    38 
       
    39 # ifdef BOOST_NO_STDC_NAMESPACE
       
    40     namespace std { using ::time_t; }
       
    41 # endif
       
    42 
       
    43 //----------------------------------------------------------------------------//
       
    44 
       
    45 namespace boost
       
    46 {
       
    47   namespace filesystem
       
    48   {
       
    49 
       
    50 // typedef boost::filesystem::path Path; needs to be in namespace boost::filesystem
       
    51 # ifndef BOOST_FILESYSTEM_NARROW_ONLY
       
    52 #   define BOOST_FS_FUNC(BOOST_FS_TYPE) \
       
    53       template<class Path> typename boost::enable_if<is_basic_path<Path>, \
       
    54       BOOST_FS_TYPE>::type
       
    55 #   define BOOST_INLINE_FS_FUNC(BOOST_FS_TYPE) \
       
    56       template<class Path> inline typename boost::enable_if<is_basic_path<Path>, \
       
    57       BOOST_FS_TYPE>::type
       
    58 #   define BOOST_FS_TYPENAME typename
       
    59 # else
       
    60 #   define BOOST_FS_FUNC(BOOST_FS_TYPE) inline BOOST_FS_TYPE
       
    61 #   define BOOST_INLINE_FS_FUNC(BOOST_FS_TYPE) inline BOOST_FS_TYPE
       
    62     typedef boost::filesystem::path Path;
       
    63 #   define BOOST_FS_TYPENAME
       
    64 # endif
       
    65 
       
    66     template<class Path> class basic_directory_iterator;
       
    67 
       
    68     // BOOST_FILESYSTEM_NARROW_ONLY needs this:
       
    69     typedef basic_directory_iterator<path> directory_iterator;
       
    70 
       
    71     template<class Path> class basic_directory_entry;
       
    72 
       
    73     enum file_type
       
    74     { 
       
    75       status_unknown,
       
    76       file_not_found,
       
    77       regular_file,
       
    78       directory_file,
       
    79       // the following will never be reported by some operating or file systems
       
    80       symlink_file,
       
    81       block_file,
       
    82       character_file,
       
    83       fifo_file,
       
    84       socket_file,
       
    85       type_unknown // file does exist, but isn't one of the above types or
       
    86                    // we don't have strong enough permission to find its type
       
    87     };
       
    88 
       
    89     class file_status
       
    90     {
       
    91     public:
       
    92       explicit file_status( file_type v = status_unknown ) : m_value(v) {}
       
    93 
       
    94       void type( file_type v )  { m_value = v; }
       
    95       file_type type() const    { return m_value; }
       
    96 
       
    97     private:
       
    98       // the internal representation is unspecified so that additional state
       
    99       // information such as permissions can be added in the future; this
       
   100       // implementation just uses status_type as the internal representation
       
   101 
       
   102       file_type m_value;
       
   103     };
       
   104 
       
   105     inline bool status_known( file_status f ) { return f.type() != status_unknown; }
       
   106     inline bool exists( file_status f )       { return f.type() != status_unknown && f.type() != file_not_found; }
       
   107     inline bool is_regular_file(file_status f){ return f.type() == regular_file; }
       
   108     inline bool is_directory( file_status f ) { return f.type() == directory_file; }
       
   109     inline bool is_symlink( file_status f )   { return f.type() == symlink_file; }
       
   110     inline bool is_other( file_status f )     { return exists(f) && !is_regular_file(f) && !is_directory(f) && !is_symlink(f); }
       
   111 
       
   112 # ifndef BOOST_FILESYSTEM_NO_DEPRECATED
       
   113     inline bool is_regular( file_status f )   { return f.type() == regular_file; }
       
   114 # endif
       
   115 
       
   116     struct space_info
       
   117     {
       
   118       // all values are byte counts
       
   119       boost::uintmax_t capacity;
       
   120       boost::uintmax_t free;      // <= capacity
       
   121       boost::uintmax_t available; // <= free
       
   122     };
       
   123 
       
   124     namespace detail
       
   125     {
       
   126       typedef std::pair< system::error_code, bool >
       
   127         query_pair;
       
   128 
       
   129       typedef std::pair< system::error_code, boost::uintmax_t >
       
   130         uintmax_pair;
       
   131 
       
   132       typedef std::pair< system::error_code, std::time_t >
       
   133         time_pair;
       
   134 
       
   135       typedef std::pair< system::error_code, space_info >
       
   136         space_pair;
       
   137 
       
   138       template< class Path >
       
   139       struct directory_pair
       
   140       {
       
   141         typedef std::pair< system::error_code,
       
   142           typename Path::external_string_type > type;
       
   143       };
       
   144 
       
   145 #   ifndef BOOST_FILESYSTEM_NO_DEPRECATED
       
   146       BOOST_FILESYSTEM_DECL bool
       
   147         symbolic_link_exists_api( const std::string & ); // deprecated
       
   148 #   endif
       
   149 
       
   150       BOOST_FILESYSTEM_DECL file_status
       
   151         status_api( const std::string & ph, system::error_code & ec );
       
   152 #   ifndef BOOST_WINDOWS_API
       
   153       BOOST_FILESYSTEM_DECL file_status
       
   154         symlink_status_api( const std::string & ph, system::error_code & ec );
       
   155 #   endif
       
   156       BOOST_FILESYSTEM_DECL query_pair
       
   157         is_empty_api( const std::string & ph );
       
   158       BOOST_FILESYSTEM_DECL query_pair
       
   159         equivalent_api( const std::string & ph1, const std::string & ph2 );
       
   160       BOOST_FILESYSTEM_DECL uintmax_pair
       
   161         file_size_api( const std::string & ph );
       
   162       BOOST_FILESYSTEM_DECL space_pair
       
   163         space_api( const std::string & ph );
       
   164       BOOST_FILESYSTEM_DECL time_pair 
       
   165         last_write_time_api( const std::string & ph );
       
   166       BOOST_FILESYSTEM_DECL system::error_code
       
   167         last_write_time_api( const std::string & ph, std::time_t new_value );
       
   168       BOOST_FILESYSTEM_DECL system::error_code
       
   169         get_current_path_api( std::string & ph );
       
   170       BOOST_FILESYSTEM_DECL system::error_code
       
   171         set_current_path_api( const std::string & ph );
       
   172       BOOST_FILESYSTEM_DECL query_pair
       
   173         create_directory_api( const std::string & ph );
       
   174       BOOST_FILESYSTEM_DECL system::error_code
       
   175         create_hard_link_api( const std::string & to_ph,
       
   176           const std::string & from_ph );
       
   177       BOOST_FILESYSTEM_DECL system::error_code
       
   178         create_symlink_api( const std::string & to_ph,
       
   179           const std::string & from_ph );
       
   180       BOOST_FILESYSTEM_DECL system::error_code
       
   181         remove_api( const std::string & ph );
       
   182       BOOST_FILESYSTEM_DECL system::error_code
       
   183         rename_api( const std::string & from, const std::string & to );
       
   184       BOOST_FILESYSTEM_DECL system::error_code
       
   185         copy_file_api( const std::string & from, const std::string & to );
       
   186 
       
   187 #   if defined(BOOST_WINDOWS_API)
       
   188       
       
   189       BOOST_FILESYSTEM_DECL system::error_code
       
   190         get_full_path_name_api( const std::string & ph, std::string & target );
       
   191 
       
   192 #     if !defined(BOOST_FILESYSTEM_NARROW_ONLY)
       
   193 
       
   194       BOOST_FILESYSTEM_DECL  boost::filesystem::file_status
       
   195         status_api( const std::wstring & ph, system::error_code & ec );
       
   196       BOOST_FILESYSTEM_DECL query_pair 
       
   197         is_empty_api( const std::wstring & ph );
       
   198       BOOST_FILESYSTEM_DECL query_pair
       
   199         equivalent_api( const std::wstring & ph1, const std::wstring & ph2 );
       
   200       BOOST_FILESYSTEM_DECL uintmax_pair 
       
   201         file_size_api( const std::wstring & ph );
       
   202       BOOST_FILESYSTEM_DECL space_pair 
       
   203         space_api( const std::wstring & ph );
       
   204       BOOST_FILESYSTEM_DECL system::error_code
       
   205         get_full_path_name_api( const std::wstring & ph, std::wstring & target );
       
   206       BOOST_FILESYSTEM_DECL time_pair 
       
   207         last_write_time_api( const std::wstring & ph );
       
   208       BOOST_FILESYSTEM_DECL system::error_code
       
   209         last_write_time_api( const std::wstring & ph, std::time_t new_value );
       
   210       BOOST_FILESYSTEM_DECL system::error_code 
       
   211         get_current_path_api( std::wstring & ph );
       
   212       BOOST_FILESYSTEM_DECL system::error_code 
       
   213         set_current_path_api( const std::wstring & ph );
       
   214       BOOST_FILESYSTEM_DECL query_pair
       
   215         create_directory_api( const std::wstring & ph );
       
   216 # ifdef BOOST_FS_HARD_LINK
       
   217       BOOST_FILESYSTEM_DECL system::error_code
       
   218         create_hard_link_api( const std::wstring & existing_ph,
       
   219           const std::wstring & new_ph );
       
   220 # endif
       
   221       BOOST_FILESYSTEM_DECL system::error_code
       
   222         create_symlink_api( const std::wstring & to_ph,
       
   223           const std::wstring & from_ph );
       
   224       BOOST_FILESYSTEM_DECL system::error_code
       
   225         remove_api( const std::wstring & ph );
       
   226       BOOST_FILESYSTEM_DECL system::error_code
       
   227         rename_api( const std::wstring & from, const std::wstring & to );
       
   228       BOOST_FILESYSTEM_DECL system::error_code
       
   229         copy_file_api( const std::wstring & from, const std::wstring & to );
       
   230 
       
   231 #     endif
       
   232 #   endif
       
   233 
       
   234       template<class Path>
       
   235       bool remove_aux( const Path & ph, file_status f );
       
   236 
       
   237       template<class Path>
       
   238       unsigned long remove_all_aux( const Path & ph, file_status f );
       
   239 
       
   240     } // namespace detail
       
   241 
       
   242 //  operations functions  ----------------------------------------------------//
       
   243 
       
   244     //  The non-template overloads enable automatic conversion from std and
       
   245     //  C-style strings. See basic_path constructors. The enable_if for the
       
   246     //  templates implements the famous "do-the-right-thing" rule.
       
   247 
       
   248 //  query functions  ---------------------------------------------------------//
       
   249 
       
   250     BOOST_INLINE_FS_FUNC(file_status)
       
   251     status( const Path & ph, system::error_code & ec )
       
   252       { return detail::status_api( ph.external_file_string(), ec ); }
       
   253 
       
   254     BOOST_FS_FUNC(file_status)
       
   255     status( const Path & ph )
       
   256     { 
       
   257       system::error_code ec;
       
   258       file_status result( detail::status_api( ph.external_file_string(), ec ) );
       
   259       if ( ec )
       
   260         boost::throw_exception( basic_filesystem_error<Path>(
       
   261         "boost::filesystem::status", ph, ec ) );
       
   262       return result;
       
   263     }
       
   264 
       
   265     BOOST_INLINE_FS_FUNC(file_status)
       
   266     symlink_status( const Path & ph, system::error_code & ec )
       
   267 #   ifdef BOOST_WINDOWS_API
       
   268       { return detail::status_api( ph.external_file_string(), ec ); }
       
   269 #   else
       
   270       { return detail::symlink_status_api( ph.external_file_string(), ec ); }
       
   271 #   endif
       
   272 
       
   273     BOOST_FS_FUNC(file_status)
       
   274     symlink_status( const Path & ph )
       
   275     { 
       
   276       system::error_code ec;
       
   277       file_status result( symlink_status( ph, ec ) );
       
   278       if ( ec )
       
   279         boost::throw_exception( basic_filesystem_error<Path>(
       
   280         "boost::filesystem::symlink_status", ph, ec ) );
       
   281       return result;
       
   282     }
       
   283 
       
   284 # ifndef BOOST_FILESYSTEM_NO_DEPRECATED
       
   285     inline bool symbolic_link_exists( const path & ph )
       
   286       { return is_symlink( symlink_status(ph) ); }
       
   287 # endif
       
   288 
       
   289     BOOST_FS_FUNC(bool) exists( const Path & ph )
       
   290     { 
       
   291       system::error_code ec;
       
   292       file_status result( detail::status_api( ph.external_file_string(), ec ) );
       
   293       if ( ec )
       
   294         boost::throw_exception( basic_filesystem_error<Path>(
       
   295           "boost::filesystem::exists", ph, ec ) );
       
   296       return exists( result );
       
   297     }
       
   298 
       
   299     BOOST_FS_FUNC(bool) is_directory( const Path & ph )
       
   300     { 
       
   301       system::error_code ec;
       
   302       file_status result( detail::status_api( ph.external_file_string(), ec ) );
       
   303       if ( ec )
       
   304         boost::throw_exception( basic_filesystem_error<Path>(
       
   305           "boost::filesystem::is_directory", ph, ec ) );
       
   306       return is_directory( result );
       
   307     }
       
   308 
       
   309     BOOST_FS_FUNC(bool) is_regular_file( const Path & ph )
       
   310     { 
       
   311       system::error_code ec;
       
   312       file_status result( detail::status_api( ph.external_file_string(), ec ) );
       
   313       if ( ec )
       
   314         boost::throw_exception( basic_filesystem_error<Path>(
       
   315           "boost::filesystem::is_regular_file", ph, ec ) );
       
   316       return is_regular_file( result );
       
   317     }
       
   318 
       
   319 # ifndef BOOST_FILESYSTEM_NO_DEPRECATED
       
   320     BOOST_FS_FUNC(bool) is_regular( const Path & ph )
       
   321     { 
       
   322       system::error_code ec;
       
   323       file_status result( detail::status_api( ph.external_file_string(), ec ) );
       
   324       if ( ec )
       
   325         boost::throw_exception( basic_filesystem_error<Path>(
       
   326           "boost::filesystem::is_regular", ph, ec ) );
       
   327       return is_regular( result );
       
   328     }
       
   329 # endif
       
   330 
       
   331     BOOST_FS_FUNC(bool) is_other( const Path & ph )
       
   332     { 
       
   333       system::error_code ec;
       
   334       file_status result( detail::status_api( ph.external_file_string(), ec ) );
       
   335       if ( ec )
       
   336         boost::throw_exception( basic_filesystem_error<Path>(
       
   337           "boost::filesystem::is_other", ph, ec ) );
       
   338       return is_other( result );
       
   339     }
       
   340 
       
   341     BOOST_FS_FUNC(bool) is_symlink(
       
   342 #   ifdef BOOST_WINDOWS_API
       
   343       const Path & )
       
   344     {
       
   345       return false;
       
   346 #   else
       
   347       const Path & ph)
       
   348     {
       
   349       system::error_code ec;
       
   350       file_status result( detail::symlink_status_api( ph.external_file_string(), ec ) );
       
   351       if ( ec )
       
   352         boost::throw_exception( basic_filesystem_error<Path>(
       
   353           "boost::filesystem::is_symlink", ph, ec ) );
       
   354       return is_symlink( result );
       
   355 #   endif
       
   356     }
       
   357 
       
   358     // VC++ 7.0 and earlier has a serious namespace bug that causes a clash
       
   359     // between boost::filesystem::is_empty and the unrelated type trait
       
   360     // boost::is_empty.
       
   361 
       
   362 # if !defined( BOOST_MSVC ) || BOOST_MSVC > 1300
       
   363     BOOST_FS_FUNC(bool) is_empty( const Path & ph )
       
   364 # else
       
   365     BOOST_FS_FUNC(bool) _is_empty( const Path & ph )
       
   366 # endif
       
   367     {
       
   368       detail::query_pair result(
       
   369         detail::is_empty_api( ph.external_file_string() ) );
       
   370       if ( result.first )
       
   371         boost::throw_exception( basic_filesystem_error<Path>(
       
   372           "boost::filesystem::is_empty", ph, result.first ) );
       
   373       return result.second;
       
   374     }
       
   375 
       
   376     BOOST_FS_FUNC(bool) equivalent( const Path & ph1, const Path & ph2 )
       
   377     {
       
   378       detail::query_pair result( detail::equivalent_api(
       
   379         ph1.external_file_string(), ph2.external_file_string() ) );
       
   380       if ( result.first )
       
   381         boost::throw_exception( basic_filesystem_error<Path>(
       
   382           "boost::filesystem::equivalent", ph1, ph2, result.first ) );
       
   383       return result.second;
       
   384     }
       
   385 
       
   386     BOOST_FS_FUNC(boost::uintmax_t) file_size( const Path & ph )
       
   387     {
       
   388       detail::uintmax_pair result
       
   389         ( detail::file_size_api( ph.external_file_string() ) );
       
   390       if ( result.first )
       
   391         boost::throw_exception( basic_filesystem_error<Path>(
       
   392           "boost::filesystem::file_size", ph, result.first ) );
       
   393       return result.second;
       
   394     }
       
   395 
       
   396     BOOST_FS_FUNC(space_info) space( const Path & ph )
       
   397     {
       
   398       detail::space_pair result
       
   399         ( detail::space_api( ph.external_file_string() ) );
       
   400       if ( result.first )
       
   401         boost::throw_exception( basic_filesystem_error<Path>(
       
   402           "boost::filesystem::space", ph, result.first ) );
       
   403       return result.second;
       
   404     }
       
   405 
       
   406     BOOST_FS_FUNC(std::time_t) last_write_time( const Path & ph )
       
   407     {
       
   408       detail::time_pair result
       
   409         ( detail::last_write_time_api( ph.external_file_string() ) );
       
   410       if ( result.first )
       
   411         boost::throw_exception( basic_filesystem_error<Path>(
       
   412           "boost::filesystem::last_write_time", ph, result.first ) );
       
   413       return result.second;
       
   414     }
       
   415 
       
   416 
       
   417 //  operations  --------------------------------------------------------------//
       
   418 
       
   419     BOOST_FS_FUNC(bool) create_directory( const Path & dir_ph )
       
   420     {
       
   421       detail::query_pair result(
       
   422         detail::create_directory_api( dir_ph.external_directory_string() ) );
       
   423       if ( result.first )
       
   424         boost::throw_exception( basic_filesystem_error<Path>(
       
   425           "boost::filesystem::create_directory",
       
   426           dir_ph, result.first ) );
       
   427       return result.second;
       
   428     }
       
   429 
       
   430 #if !defined(BOOST_WINDOWS_API) || defined(BOOST_FS_HARD_LINK)
       
   431     BOOST_FS_FUNC(void)
       
   432     create_hard_link( const Path & to_ph, const Path & from_ph )
       
   433     {
       
   434       system::error_code ec( 
       
   435         detail::create_hard_link_api(
       
   436           to_ph.external_file_string(),
       
   437           from_ph.external_file_string() ) );
       
   438       if ( ec )
       
   439         boost::throw_exception( basic_filesystem_error<Path>(
       
   440           "boost::filesystem::create_hard_link",
       
   441           to_ph, from_ph, ec ) );
       
   442     }
       
   443 
       
   444     BOOST_FS_FUNC(system::error_code)
       
   445     create_hard_link( const Path & to_ph, const Path & from_ph,
       
   446       system::error_code & ec )
       
   447     {
       
   448       ec = detail::create_hard_link_api(
       
   449             to_ph.external_file_string(),
       
   450             from_ph.external_file_string() );
       
   451       return ec;
       
   452     }
       
   453 #endif
       
   454 
       
   455     BOOST_FS_FUNC(void)
       
   456     create_symlink( const Path & to_ph, const Path & from_ph )
       
   457     {
       
   458       system::error_code ec( 
       
   459         detail::create_symlink_api(
       
   460           to_ph.external_file_string(),
       
   461           from_ph.external_file_string() ) );
       
   462       if ( ec )
       
   463         boost::throw_exception( basic_filesystem_error<Path>(
       
   464           "boost::filesystem::create_symlink",
       
   465           to_ph, from_ph, ec ) );
       
   466     }
       
   467 
       
   468     BOOST_FS_FUNC(system::error_code)
       
   469     create_symlink( const Path & to_ph, const Path & from_ph,
       
   470       system::error_code & ec )
       
   471     {
       
   472       ec = detail::create_symlink_api(
       
   473              to_ph.external_file_string(),
       
   474              from_ph.external_file_string() );
       
   475       return ec;
       
   476     }
       
   477 
       
   478     BOOST_FS_FUNC(bool) remove( const Path & ph )
       
   479     {
       
   480       system::error_code ec;
       
   481       file_status f = symlink_status( ph, ec );
       
   482       if ( ec )
       
   483         boost::throw_exception( basic_filesystem_error<Path>(
       
   484           "boost::filesystem::remove", ph, ec ) );
       
   485       return detail::remove_aux( ph, f );
       
   486     }
       
   487 
       
   488     BOOST_FS_FUNC(unsigned long) remove_all( const Path & ph )
       
   489     {
       
   490       system::error_code ec;
       
   491       file_status f = symlink_status( ph, ec );
       
   492       if ( ec )
       
   493         boost::throw_exception( basic_filesystem_error<Path>(
       
   494           "boost::filesystem::remove_all", ph, ec ) );
       
   495       return exists( f ) ? detail::remove_all_aux( ph, f ) : 0;
       
   496     }
       
   497 
       
   498     BOOST_FS_FUNC(void) rename( const Path & from_path, const Path & to_path )
       
   499     {
       
   500       system::error_code ec( detail::rename_api(
       
   501         from_path.external_directory_string(),
       
   502         to_path.external_directory_string() ) );
       
   503       if ( ec )
       
   504         boost::throw_exception( basic_filesystem_error<Path>(
       
   505           "boost::filesystem::rename",
       
   506           from_path, to_path, ec ) );
       
   507     }
       
   508 
       
   509     BOOST_FS_FUNC(void) copy_file( const Path & from_path, const Path & to_path )
       
   510     {
       
   511       system::error_code ec( detail::copy_file_api(
       
   512         from_path.external_directory_string(),
       
   513         to_path.external_directory_string() ) );
       
   514       if ( ec )
       
   515         boost::throw_exception( basic_filesystem_error<Path>(
       
   516           "boost::filesystem::copy_file",
       
   517           from_path, to_path, ec ) );
       
   518     }
       
   519 
       
   520     template< class Path >
       
   521     Path current_path()
       
   522     {
       
   523       typename Path::external_string_type ph;
       
   524       system::error_code ec( detail::get_current_path_api( ph ) );
       
   525       if ( ec )
       
   526           boost::throw_exception( basic_filesystem_error<Path>(
       
   527             "boost::filesystem::current_path", ec ) );
       
   528       return Path( Path::traits_type::to_internal( ph ) );
       
   529     }
       
   530 
       
   531     BOOST_FS_FUNC(void) current_path( const Path & ph )
       
   532     {
       
   533       system::error_code ec( detail::set_current_path_api(
       
   534         ph.external_directory_string() ) );
       
   535       if ( ec )
       
   536           boost::throw_exception( basic_filesystem_error<Path>(
       
   537             "boost::filesystem::current_path", ph, ec ) );
       
   538     }
       
   539 
       
   540     template< class Path >
       
   541     const Path & initial_path()
       
   542     {
       
   543       static Path init_path;
       
   544       if ( init_path.empty() ) init_path = current_path<Path>();
       
   545       return init_path;
       
   546     }
       
   547 
       
   548 # ifndef BOOST_FILESYSTEM_NO_DEPRECATED
       
   549     // legacy support
       
   550     inline path current_path()  // overload supports pre-i18n apps
       
   551       { return current_path<boost::filesystem::path>(); }
       
   552     inline const path & initial_path() // overload supports pre-i18n apps
       
   553       { return initial_path<boost::filesystem::path>(); }
       
   554 # endif
       
   555 
       
   556     BOOST_FS_FUNC(Path) system_complete( const Path & ph )
       
   557     {
       
   558 # ifdef BOOST_WINDOWS_API
       
   559       if ( ph.empty() ) return ph;
       
   560       BOOST_FS_TYPENAME Path::external_string_type sys_ph;
       
   561       system::error_code ec( detail::get_full_path_name_api( ph.external_file_string(),
       
   562               sys_ph ) );
       
   563       if ( ec )
       
   564           boost::throw_exception( basic_filesystem_error<Path>(
       
   565             "boost::filesystem::system_complete", ph, ec ) );
       
   566       return Path( Path::traits_type::to_internal( sys_ph ) );
       
   567 # else
       
   568       return (ph.empty() || ph.is_complete())
       
   569         ? ph : current_path<Path>() / ph;
       
   570 # endif
       
   571     }
       
   572 
       
   573     BOOST_FS_FUNC(Path)
       
   574     complete( const Path & ph,
       
   575       const Path & base/* = initial_path<Path>() */)
       
   576     {
       
   577       BOOST_ASSERT( base.is_complete()
       
   578         && (ph.is_complete() || !ph.has_root_name())
       
   579         && "boost::filesystem::complete() precondition not met" );
       
   580 #   ifdef BOOST_WINDOWS_PATH
       
   581       if (ph.empty() || ph.is_complete()) return ph;
       
   582       if ( !ph.has_root_name() )
       
   583         return ph.has_root_directory()
       
   584           ? Path( base.root_name() ) / ph
       
   585           : base / ph;
       
   586       return base / ph;
       
   587 #   else
       
   588       return (ph.empty() || ph.is_complete()) ? ph : base / ph;
       
   589 #   endif
       
   590     }
       
   591 
       
   592     // VC++ 7.1 had trouble with default arguments, so separate one argument
       
   593     // signatures are provided as workarounds; the effect is the same.
       
   594     BOOST_FS_FUNC(Path) complete( const Path & ph )
       
   595       { return complete( ph, initial_path<Path>() ); }
       
   596 
       
   597     BOOST_FS_FUNC(void)
       
   598     last_write_time( const Path & ph, const std::time_t new_time )
       
   599     {
       
   600       system::error_code ec( detail::last_write_time_api( ph.external_file_string(),
       
   601           new_time ) );
       
   602       if ( ec )
       
   603         boost::throw_exception( basic_filesystem_error<Path>(
       
   604           "boost::filesystem::last_write_time", ph, ec ) );
       
   605     }
       
   606 
       
   607 # ifndef BOOST_FILESYSTEM_NARROW_ONLY
       
   608 
       
   609     // "do-the-right-thing" overloads  ---------------------------------------//
       
   610 
       
   611     inline file_status status( const path & ph )
       
   612       { return status<path>( ph ); }
       
   613     inline file_status status( const wpath & ph )
       
   614       { return status<wpath>( ph ); }
       
   615 
       
   616     inline file_status status( const path & ph, system::error_code & ec )
       
   617       { return status<path>( ph, ec ); }
       
   618     inline file_status status( const wpath & ph, system::error_code & ec )
       
   619       { return status<wpath>( ph, ec ); }
       
   620 
       
   621     inline file_status symlink_status( const path & ph )
       
   622       { return symlink_status<path>( ph ); }
       
   623     inline file_status symlink_status( const wpath & ph )
       
   624       { return symlink_status<wpath>( ph ); }
       
   625 
       
   626     inline file_status symlink_status( const path & ph, system::error_code & ec )
       
   627       { return symlink_status<path>( ph, ec ); }
       
   628     inline file_status symlink_status( const wpath & ph, system::error_code & ec )
       
   629       { return symlink_status<wpath>( ph, ec ); }
       
   630 
       
   631     inline bool exists( const path & ph ) { return exists<path>( ph ); }
       
   632     inline bool exists( const wpath & ph ) { return exists<wpath>( ph ); }
       
   633 
       
   634     inline bool is_directory( const path & ph )
       
   635       { return is_directory<path>( ph ); }
       
   636     inline bool is_directory( const wpath & ph )
       
   637       { return is_directory<wpath>( ph ); }
       
   638  
       
   639     inline bool is_regular_file( const path & ph )
       
   640       { return is_regular_file<path>( ph ); }
       
   641     inline bool is_regular_file( const wpath & ph )
       
   642       { return is_regular_file<wpath>( ph ); }
       
   643 
       
   644 # ifndef BOOST_FILESYSTEM_NO_DEPRECATED
       
   645     inline bool is_regular( const path & ph )
       
   646       { return is_regular<path>( ph ); }
       
   647     inline bool is_regular( const wpath & ph )
       
   648       { return is_regular<wpath>( ph ); }
       
   649 # endif
       
   650 
       
   651     inline bool is_other( const path & ph )
       
   652       { return is_other<path>( ph ); }
       
   653     inline bool is_other( const wpath & ph )
       
   654       { return is_other<wpath>( ph ); }
       
   655 
       
   656     inline bool is_symlink( const path & ph )
       
   657       { return is_symlink<path>( ph ); }
       
   658     inline bool is_symlink( const wpath & ph )
       
   659       { return is_symlink<wpath>( ph ); }
       
   660 
       
   661     inline bool is_empty( const path & ph )
       
   662       { return is_empty<path>( ph ); }
       
   663     inline bool is_empty( const wpath & ph )
       
   664       { return is_empty<wpath>( ph ); }
       
   665 
       
   666     inline bool equivalent( const path & ph1, const path & ph2 )
       
   667       { return equivalent<path>( ph1, ph2 ); }
       
   668     inline bool equivalent( const wpath & ph1, const wpath & ph2 )
       
   669       { return equivalent<wpath>( ph1, ph2 ); }
       
   670 
       
   671     inline boost::uintmax_t file_size( const path & ph )
       
   672       { return file_size<path>( ph ); }
       
   673     inline boost::uintmax_t file_size( const wpath & ph )
       
   674       { return file_size<wpath>( ph ); }
       
   675 
       
   676     inline space_info space( const path & ph )
       
   677       { return space<path>( ph ); }
       
   678     inline space_info space( const wpath & ph )
       
   679       { return space<wpath>( ph ); }
       
   680 
       
   681     inline std::time_t last_write_time( const path & ph )
       
   682       { return last_write_time<path>( ph ); }
       
   683     inline std::time_t last_write_time( const wpath & ph )
       
   684       { return last_write_time<wpath>( ph ); }
       
   685 
       
   686     inline bool create_directory( const path & dir_ph )
       
   687       { return create_directory<path>( dir_ph ); }
       
   688     inline bool create_directory( const wpath & dir_ph )
       
   689       { return create_directory<wpath>( dir_ph ); }
       
   690 
       
   691 #if !defined(BOOST_WINDOWS_API) || defined(BOOST_FS_HARD_LINK)
       
   692     inline void create_hard_link( const path & to_ph,
       
   693       const path & from_ph )
       
   694       { return create_hard_link<path>( to_ph, from_ph ); }
       
   695     inline void create_hard_link( const wpath & to_ph,
       
   696       const wpath & from_ph )
       
   697       { return create_hard_link<wpath>( to_ph, from_ph ); }
       
   698 
       
   699     inline system::error_code create_hard_link( const path & to_ph,
       
   700       const path & from_ph, system::error_code & ec )
       
   701       { return create_hard_link<path>( to_ph, from_ph, ec ); }
       
   702     inline system::error_code create_hard_link( const wpath & to_ph,
       
   703       const wpath & from_ph, system::error_code & ec )
       
   704       { return create_hard_link<wpath>( to_ph, from_ph, ec ); }
       
   705 #endif
       
   706     
       
   707     inline void create_symlink( const path & to_ph,
       
   708       const path & from_ph )
       
   709       { return create_symlink<path>( to_ph, from_ph ); }
       
   710     inline void create_symlink( const wpath & to_ph,
       
   711       const wpath & from_ph )
       
   712       { return create_symlink<wpath>( to_ph, from_ph ); }
       
   713 
       
   714     inline system::error_code create_symlink( const path & to_ph,
       
   715       const path & from_ph, system::error_code & ec )
       
   716       { return create_symlink<path>( to_ph, from_ph, ec ); }
       
   717     inline system::error_code create_symlink( const wpath & to_ph,
       
   718       const wpath & from_ph, system::error_code & ec )
       
   719       { return create_symlink<wpath>( to_ph, from_ph, ec ); }
       
   720 
       
   721     inline bool remove( const path & ph )
       
   722       { return remove<path>( ph ); }
       
   723     inline bool remove( const wpath & ph )
       
   724       { return remove<wpath>( ph ); }
       
   725 
       
   726     inline unsigned long remove_all( const path & ph )
       
   727       { return remove_all<path>( ph ); }
       
   728     inline unsigned long remove_all( const wpath & ph )
       
   729       { return remove_all<wpath>( ph ); }
       
   730 
       
   731     inline void rename( const path & from_path, const path & to_path )
       
   732       { return rename<path>( from_path, to_path ); }
       
   733     inline void rename( const wpath & from_path, const wpath & to_path )
       
   734       { return rename<wpath>( from_path, to_path ); }
       
   735 
       
   736     inline void copy_file( const path & from_path, const path & to_path )
       
   737       { return copy_file<path>( from_path, to_path ); }
       
   738     inline void copy_file( const wpath & from_path, const wpath & to_path )
       
   739       { return copy_file<wpath>( from_path, to_path ); }
       
   740 
       
   741     inline path system_complete( const path & ph )
       
   742       { return system_complete<path>( ph ); }
       
   743     inline wpath system_complete( const wpath & ph )
       
   744       { return system_complete<wpath>( ph ); }
       
   745 
       
   746     inline path complete( const path & ph,
       
   747       const path & base/* = initial_path<path>()*/ )
       
   748       { return complete<path>( ph, base ); }
       
   749     inline wpath complete( const wpath & ph,
       
   750       const wpath & base/* = initial_path<wpath>()*/ )
       
   751       { return complete<wpath>( ph, base ); }
       
   752 
       
   753     inline path complete( const path & ph )
       
   754       { return complete<path>( ph, initial_path<path>() ); }
       
   755     inline wpath complete( const wpath & ph )
       
   756       { return complete<wpath>( ph, initial_path<wpath>() ); }
       
   757 
       
   758     inline void last_write_time( const path & ph, const std::time_t new_time )
       
   759       { last_write_time<path>( ph, new_time ); }
       
   760     inline void last_write_time( const wpath & ph, const std::time_t new_time )
       
   761       { last_write_time<wpath>( ph, new_time ); }
       
   762 
       
   763     inline void current_path( const path & ph )
       
   764       { current_path<path>( ph ); }
       
   765     inline void current_path( const wpath & ph )
       
   766       { current_path<wpath>( ph ); }
       
   767 
       
   768 # endif // ifndef BOOST_FILESYSTEM_NARROW_ONLY
       
   769 
       
   770     namespace detail
       
   771     {
       
   772       template<class Path>
       
   773       bool remove_aux( const Path & ph, file_status f )
       
   774       {
       
   775         if ( exists( f ) )
       
   776         {
       
   777           system::error_code ec = remove_api( ph.external_file_string() );
       
   778           if ( ec )
       
   779             boost::throw_exception( basic_filesystem_error<Path>(
       
   780               "boost::filesystem::remove", ph, ec ) );
       
   781           return true;
       
   782         }
       
   783         return false;
       
   784       }
       
   785 
       
   786       template<class Path>
       
   787       unsigned long remove_all_aux( const Path & ph, file_status f )
       
   788       {
       
   789         static const boost::filesystem::basic_directory_iterator<Path> end_itr;
       
   790         unsigned long count = 1;
       
   791         if ( !boost::filesystem::is_symlink( f ) // don't recurse symbolic links
       
   792           && boost::filesystem::is_directory( f ) )
       
   793         {
       
   794           for ( boost::filesystem::basic_directory_iterator<Path> itr( ph );
       
   795                 itr != end_itr; ++itr )
       
   796           {
       
   797             boost::system::error_code ec;
       
   798             boost::filesystem::file_status fn = boost::filesystem::symlink_status( itr->path(), ec );
       
   799             if ( ec )
       
   800               boost::throw_exception( basic_filesystem_error<Path>( 
       
   801                 "boost::filesystem:remove_all", ph, ec ) );
       
   802             count += remove_all_aux( itr->path(), fn );
       
   803           }
       
   804         }
       
   805         remove_aux( ph, f );
       
   806         return count;
       
   807       }
       
   808 
       
   809 //  test helper  -------------------------------------------------------------//
       
   810 
       
   811     // not part of the documented interface because false positives are possible;
       
   812     // there is no law that says that an OS that has large stat.st_size
       
   813     // actually supports large file sizes.
       
   814       BOOST_FILESYSTEM_DECL bool possible_large_file_size_support();
       
   815 
       
   816 //  directory_iterator helpers  ----------------------------------------------//
       
   817 
       
   818 //    forwarding functions avoid need for BOOST_FILESYSTEM_DECL for class
       
   819 //    basic_directory_iterator, and so avoid iterator_facade DLL template
       
   820 //    problems. They also overload to the proper external path character type.
       
   821 
       
   822       BOOST_FILESYSTEM_DECL system::error_code
       
   823         dir_itr_first( void *& handle,
       
   824 #if       defined(BOOST_POSIX_API)
       
   825             void *& buffer,
       
   826 #endif
       
   827           const std::string & dir_path,
       
   828           std::string & target, file_status & fs, file_status & symlink_fs );
       
   829       // eof: return==0 && handle==0
       
   830 
       
   831       BOOST_FILESYSTEM_DECL system::error_code
       
   832         dir_itr_increment( void *& handle,
       
   833 #if       defined(BOOST_POSIX_API)
       
   834             void *& buffer,
       
   835 #endif
       
   836           std::string & target, file_status & fs, file_status & symlink_fs );
       
   837       // eof: return==0 && handle==0
       
   838 
       
   839       BOOST_FILESYSTEM_DECL system::error_code
       
   840         dir_itr_close( void *& handle
       
   841 #if       defined(BOOST_POSIX_API)
       
   842             , void *& buffer
       
   843 #endif
       
   844           );
       
   845       // Effects: none if handle==0, otherwise close handle, set handle=0
       
   846 
       
   847 #     if defined(BOOST_WINDOWS_API) && !defined(BOOST_FILESYSTEM_NARROW_ONLY)
       
   848       BOOST_FILESYSTEM_DECL system::error_code
       
   849         dir_itr_first( void *& handle, const std::wstring & ph,
       
   850           std::wstring & target, file_status & fs, file_status & symlink_fs );
       
   851       BOOST_FILESYSTEM_DECL system::error_code
       
   852         dir_itr_increment( void *& handle, std::wstring & target,
       
   853           file_status & fs, file_status & symlink_fs );
       
   854 #     endif
       
   855 
       
   856       template< class Path >
       
   857       class dir_itr_imp
       
   858       {
       
   859       public:  
       
   860         basic_directory_entry<Path> m_directory_entry;
       
   861         void *        m_handle;
       
   862 #       ifdef BOOST_POSIX_API
       
   863           void *      m_buffer;  // see dir_itr_increment implementation
       
   864 #       endif
       
   865         dir_itr_imp() : m_handle(0)
       
   866 #       ifdef BOOST_POSIX_API
       
   867           , m_buffer(0)
       
   868 #       endif
       
   869         {}
       
   870 
       
   871         ~dir_itr_imp() { dir_itr_close( m_handle
       
   872 #if       defined(BOOST_POSIX_API)
       
   873             , m_buffer
       
   874 #endif
       
   875           ); }
       
   876       };
       
   877 
       
   878       BOOST_FILESYSTEM_DECL system::error_code not_found_error();
       
   879 
       
   880     } // namespace detail
       
   881 
       
   882 //  basic_directory_iterator  ------------------------------------------------//
       
   883 
       
   884     template< class Path >
       
   885     class basic_directory_iterator
       
   886       : public boost::iterator_facade<
       
   887           basic_directory_iterator<Path>,
       
   888           basic_directory_entry<Path>,
       
   889           boost::single_pass_traversal_tag >
       
   890     {
       
   891     public:
       
   892       typedef Path path_type;
       
   893 
       
   894       basic_directory_iterator(){}  // creates the "end" iterator
       
   895 
       
   896       explicit basic_directory_iterator( const Path & dir_path );
       
   897       basic_directory_iterator( const Path & dir_path, system::error_code & ec );
       
   898 
       
   899     private:
       
   900 
       
   901       // shared_ptr provides shallow-copy semantics required for InputIterators.
       
   902       // m_imp.get()==0 indicates the end iterator.
       
   903       boost::shared_ptr< detail::dir_itr_imp< Path > >  m_imp;
       
   904 
       
   905       friend class boost::iterator_core_access;
       
   906 
       
   907       typename boost::iterator_facade<
       
   908         basic_directory_iterator<Path>,
       
   909         basic_directory_entry<Path>,
       
   910         boost::single_pass_traversal_tag >::reference dereference() const 
       
   911       {
       
   912         BOOST_ASSERT( m_imp.get() && "attempt to dereference end iterator" );
       
   913         return m_imp->m_directory_entry;
       
   914       }
       
   915 
       
   916       void increment();
       
   917 
       
   918       bool equal( const basic_directory_iterator & rhs ) const
       
   919         { return m_imp == rhs.m_imp; }
       
   920 
       
   921       system::error_code m_init( const Path & dir_path );
       
   922     };
       
   923 
       
   924     typedef basic_directory_iterator< path > directory_iterator;
       
   925 # ifndef BOOST_FILESYSTEM_NARROW_ONLY
       
   926     typedef basic_directory_iterator< wpath > wdirectory_iterator;
       
   927 # endif
       
   928 
       
   929     //  basic_directory_iterator implementation  ---------------------------//
       
   930 
       
   931     template<class Path>
       
   932     system::error_code basic_directory_iterator<Path>::m_init(
       
   933       const Path & dir_path )
       
   934     {
       
   935       if ( dir_path.empty() )
       
   936       {
       
   937         m_imp.reset();
       
   938         return detail::not_found_error();
       
   939       }
       
   940       typename Path::external_string_type name;
       
   941       file_status fs, symlink_fs;
       
   942       system::error_code ec( detail::dir_itr_first( m_imp->m_handle,
       
   943 #if   defined(BOOST_POSIX_API)
       
   944         m_imp->m_buffer,
       
   945 #endif
       
   946         dir_path.external_directory_string(),
       
   947         name, fs, symlink_fs ) );
       
   948 
       
   949       if ( ec )
       
   950       {
       
   951         m_imp.reset();
       
   952         return ec;
       
   953       }
       
   954       
       
   955       if ( m_imp->m_handle == 0 ) m_imp.reset(); // eof, so make end iterator
       
   956       else // not eof
       
   957       {
       
   958         m_imp->m_directory_entry.assign( dir_path
       
   959           / Path::traits_type::to_internal( name ), fs, symlink_fs );
       
   960         if ( name[0] == dot<Path>::value // dot or dot-dot
       
   961           && (name.size() == 1
       
   962             || (name[1] == dot<Path>::value
       
   963               && name.size() == 2)) )
       
   964           {  increment(); }
       
   965       }
       
   966       return boost::system::error_code();
       
   967     }
       
   968 
       
   969     template<class Path>
       
   970     basic_directory_iterator<Path>::basic_directory_iterator(
       
   971       const Path & dir_path )
       
   972       : m_imp( new detail::dir_itr_imp<Path> )
       
   973     {
       
   974       system::error_code ec( m_init(dir_path) );
       
   975       if ( ec )
       
   976       {
       
   977         boost::throw_exception( basic_filesystem_error<Path>( 
       
   978           "boost::filesystem::basic_directory_iterator constructor",
       
   979           dir_path, ec ) );
       
   980       }
       
   981     }
       
   982 
       
   983     template<class Path>
       
   984     basic_directory_iterator<Path>::basic_directory_iterator(
       
   985       const Path & dir_path, system::error_code & ec )
       
   986       : m_imp( new detail::dir_itr_imp<Path> )
       
   987     {
       
   988       ec = m_init(dir_path);
       
   989     }
       
   990 
       
   991     template<class Path>
       
   992     void basic_directory_iterator<Path>::increment()
       
   993     {
       
   994       BOOST_ASSERT( m_imp.get() && "attempt to increment end iterator" );
       
   995       BOOST_ASSERT( m_imp->m_handle != 0 && "internal program error" );
       
   996       
       
   997       typename Path::external_string_type name;
       
   998       file_status fs, symlink_fs;
       
   999       system::error_code ec;
       
  1000 
       
  1001       for (;;)
       
  1002       {
       
  1003         ec = detail::dir_itr_increment( m_imp->m_handle,
       
  1004 #if     defined(BOOST_POSIX_API)
       
  1005           m_imp->m_buffer,
       
  1006 #endif
       
  1007           name, fs, symlink_fs );
       
  1008         if ( ec )
       
  1009         {
       
  1010           boost::throw_exception( basic_filesystem_error<Path>(  
       
  1011             "boost::filesystem::basic_directory_iterator increment",
       
  1012             m_imp->m_directory_entry.path().parent_path(), ec ) );
       
  1013         }
       
  1014         if ( m_imp->m_handle == 0 ) { m_imp.reset(); return; } // eof, make end
       
  1015         if ( !(name[0] == dot<Path>::value // !(dot or dot-dot)
       
  1016           && (name.size() == 1
       
  1017             || (name[1] == dot<Path>::value
       
  1018               && name.size() == 2))) )
       
  1019         {
       
  1020           m_imp->m_directory_entry.replace_filename(
       
  1021             Path::traits_type::to_internal( name ), fs, symlink_fs );
       
  1022           return;
       
  1023         }
       
  1024       }
       
  1025     }
       
  1026 
       
  1027     //  basic_directory_entry  -----------------------------------------------//
       
  1028     
       
  1029     template<class Path>
       
  1030     class basic_directory_entry
       
  1031     {
       
  1032     public:
       
  1033       typedef Path path_type;
       
  1034       typedef typename Path::string_type string_type;
       
  1035 
       
  1036       // compiler generated copy-ctor, copy assignment, and destructor apply
       
  1037 
       
  1038       basic_directory_entry() {}
       
  1039       explicit basic_directory_entry( const path_type & p,
       
  1040         file_status st = file_status(), file_status symlink_st=file_status() )
       
  1041         : m_path(p), m_status(st), m_symlink_status(symlink_st)
       
  1042         {}
       
  1043 
       
  1044       void assign( const path_type & p,
       
  1045         file_status st, file_status symlink_st )
       
  1046         { m_path = p; m_status = st; m_symlink_status = symlink_st; }
       
  1047 
       
  1048       void replace_filename( const string_type & s,
       
  1049         file_status st, file_status symlink_st )
       
  1050       {
       
  1051         m_path.remove_filename();
       
  1052         m_path /= s;
       
  1053         m_status = st;
       
  1054         m_symlink_status = symlink_st;
       
  1055       }
       
  1056 
       
  1057 #   ifndef BOOST_FILESYSTEM_NO_DEPRECATED
       
  1058       void replace_leaf( const string_type & s,
       
  1059         file_status st, file_status symlink_st )
       
  1060           { replace_filename( s, st, symlink_st ); }
       
  1061 #   endif
       
  1062 
       
  1063       const Path &  path() const { return m_path; }
       
  1064       file_status   status() const;
       
  1065       file_status   status( system::error_code & ec ) const;
       
  1066       file_status   symlink_status() const;
       
  1067       file_status   symlink_status( system::error_code & ec ) const;
       
  1068 
       
  1069       // conversion simplifies the most common use of basic_directory_entry
       
  1070       operator const path_type &() const { return m_path; }
       
  1071 
       
  1072 #   ifndef BOOST_FILESYSTEM_NO_DEPRECATED
       
  1073       // deprecated functions preserve common use cases in legacy code
       
  1074       typename Path::string_type filename() const
       
  1075       {
       
  1076         return path().filename();
       
  1077       }
       
  1078       typename Path::string_type leaf() const
       
  1079       {
       
  1080         return path().filename();
       
  1081       }
       
  1082       typename Path::string_type string() const
       
  1083       {
       
  1084         return path().string();
       
  1085       }
       
  1086 #   endif
       
  1087 
       
  1088     private:
       
  1089       path_type             m_path;
       
  1090       mutable file_status  m_status;           // stat()-like
       
  1091       mutable file_status  m_symlink_status;   // lstat()-like
       
  1092         // note: m_symlink_status is not used by Windows implementation
       
  1093 
       
  1094     }; // basic_directory_status
       
  1095 
       
  1096     typedef basic_directory_entry<path> directory_entry;
       
  1097 # ifndef BOOST_FILESYSTEM_NARROW_ONLY
       
  1098     typedef basic_directory_entry<wpath> wdirectory_entry;
       
  1099 # endif
       
  1100 
       
  1101     //  basic_directory_entry implementation  --------------------------------//
       
  1102 
       
  1103     template<class Path>
       
  1104     file_status
       
  1105     basic_directory_entry<Path>::status() const
       
  1106     {
       
  1107       if ( !status_known( m_status ) )
       
  1108       {
       
  1109 #     ifndef BOOST_WINDOWS_API
       
  1110         if ( status_known( m_symlink_status )
       
  1111           && !is_symlink( m_symlink_status ) )
       
  1112           { m_status = m_symlink_status; }
       
  1113         else { m_status = boost::filesystem::status( m_path ); }
       
  1114 #     else
       
  1115         m_status = boost::filesystem::status( m_path );
       
  1116 #     endif
       
  1117       }
       
  1118       return m_status;
       
  1119     }
       
  1120 
       
  1121     template<class Path>
       
  1122     file_status
       
  1123     basic_directory_entry<Path>::status( system::error_code & ec ) const
       
  1124     {
       
  1125       if ( !status_known( m_status ) )
       
  1126       {
       
  1127 #     ifndef BOOST_WINDOWS_API
       
  1128         if ( status_known( m_symlink_status )
       
  1129           && !is_symlink( m_symlink_status ) )
       
  1130           { ec = boost::system::error_code();; m_status = m_symlink_status; }
       
  1131         else { m_status = boost::filesystem::status( m_path, ec ); }
       
  1132 #     else
       
  1133         m_status = boost::filesystem::status( m_path, ec );
       
  1134 #     endif
       
  1135       }
       
  1136       else ec = boost::system::error_code();;
       
  1137       return m_status;
       
  1138     }
       
  1139 
       
  1140     template<class Path>
       
  1141     file_status
       
  1142     basic_directory_entry<Path>::symlink_status() const
       
  1143     {
       
  1144 #   ifndef BOOST_WINDOWS_API
       
  1145       if ( !status_known( m_symlink_status ) )
       
  1146         { m_symlink_status = boost::filesystem::symlink_status( m_path ); }
       
  1147       return m_symlink_status;
       
  1148 #   else
       
  1149       return status();
       
  1150 #   endif
       
  1151     }
       
  1152 
       
  1153     template<class Path>
       
  1154     file_status
       
  1155     basic_directory_entry<Path>::symlink_status( system::error_code & ec ) const
       
  1156     {
       
  1157 #   ifndef BOOST_WINDOWS_API
       
  1158       if ( !status_known( m_symlink_status ) )
       
  1159         { m_symlink_status = boost::filesystem::symlink_status( m_path, ec ); }
       
  1160       else ec = boost::system::error_code();;
       
  1161       return m_symlink_status;
       
  1162 #   else
       
  1163       return status( ec );
       
  1164 #   endif
       
  1165     }
       
  1166   } // namespace filesystem
       
  1167 } // namespace boost
       
  1168 
       
  1169 #undef BOOST_FS_FUNC
       
  1170 
       
  1171 
       
  1172 #include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas
       
  1173 #endif // BOOST_FILESYSTEM_OPERATIONS_HPP