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