|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r50380 - in sandbox/filesystem-v3: . boost boost/filesystem boost/filesystem/v3 libs libs/filesystem libs/filesystem/v3 libs/filesystem/v3/build libs/filesystem/v3/doc libs/filesystem/v3/example libs/filesystem/v3/src libs/filesystem/v3/test libs/filesystem/v3/test/msvc libs/filesystem/v3/test/msvc/convenience_test libs/filesystem/v3/test/msvc/operations_test libs/filesystem/v3/test/msvc/operations_unit_test libs/filesystem/v3/test/msvc/path_test libs/filesystem/v3/test/msvc/path_unit_test libs/filesystem/v3/test/msvc/tchar_example
From: bdawes_at_[hidden]
Date: 2008-12-24 08:50:42
Author: bemandawes
Date: 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
New Revision: 50380
URL: http://svn.boost.org/trac/boost/changeset/50380
Log:
Initial commit of work-in-progress.
Added:
sandbox/filesystem-v3/
sandbox/filesystem-v3/boost/
sandbox/filesystem-v3/boost/filesystem/
sandbox/filesystem-v3/boost/filesystem/v3/
sandbox/filesystem-v3/boost/filesystem/v3/config.hpp (contents, props changed)
sandbox/filesystem-v3/boost/filesystem/v3/convenience.hpp (contents, props changed)
sandbox/filesystem-v3/boost/filesystem/v3/exception.hpp (contents, props changed)
sandbox/filesystem-v3/boost/filesystem/v3/fstream.hpp (contents, props changed)
sandbox/filesystem-v3/boost/filesystem/v3/operations.hpp (contents, props changed)
sandbox/filesystem-v3/boost/filesystem/v3/path.hpp (contents, props changed)
sandbox/filesystem-v3/index.html (contents, props changed)
sandbox/filesystem-v3/libs/
sandbox/filesystem-v3/libs/filesystem/
sandbox/filesystem-v3/libs/filesystem/v3/
sandbox/filesystem-v3/libs/filesystem/v3/build/
sandbox/filesystem-v3/libs/filesystem/v3/build/Jamfile.v2 (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/doc/
sandbox/filesystem-v3/libs/filesystem/v3/doc/POSIX_filename_encoding.txt (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/doc/boost.png (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/doc/minimal.css (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/doc/reference.html (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/doc/v3_design.html (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/example/
sandbox/filesystem-v3/libs/filesystem/v3/example/Jamfile.v2 (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/example/file_size.cpp (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/example/mbcopy.cpp (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/example/mbpath.cpp (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/example/mbpath.hpp (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/example/path_table.cpp (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/example/simple_ls.cpp (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/example/tchar.cpp (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/src/
sandbox/filesystem-v3/libs/filesystem/v3/src/error_code.cpp (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/src/operations.cpp (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/src/path.cpp (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/src/portability.cpp (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/src/utf8_codecvt_facet.cpp (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/src/utf8_codecvt_facet.hpp (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/test/
sandbox/filesystem-v3/libs/filesystem/v3/test/Jamfile.v2 (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/test/convenience_test.cpp (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/test/deprecated_test.cpp (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/test/design_use_cases.cpp (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/test/equivalent.cpp (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/test/fstream_test.cpp (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/test/gcc_operations_unit_test.bat (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/test/gcc_path_unit_test.bat (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/test/large_file_support_test.cpp (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/test/lpath.hpp (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/test/msvc/
sandbox/filesystem-v3/libs/filesystem/v3/test/msvc/common.vsprops (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/test/msvc/convenience_test/
sandbox/filesystem-v3/libs/filesystem/v3/test/msvc/convenience_test/convenience_test.vcproj (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/test/msvc/operations_test/
sandbox/filesystem-v3/libs/filesystem/v3/test/msvc/operations_test/operations_test.vcproj (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/test/msvc/operations_unit_test/
sandbox/filesystem-v3/libs/filesystem/v3/test/msvc/operations_unit_test/operations_unit_test.vcproj (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/test/msvc/path_test/
sandbox/filesystem-v3/libs/filesystem/v3/test/msvc/path_test/path_test.vcproj (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/test/msvc/path_unit_test/
sandbox/filesystem-v3/libs/filesystem/v3/test/msvc/path_unit_test/path_unit_test.vcproj (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/test/msvc/tchar_example/
sandbox/filesystem-v3/libs/filesystem/v3/test/msvc/tchar_example/tchar_example.vcproj (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/test/operations_test.cpp (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/test/operations_unit_test.cpp (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/test/path_test.cpp (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/test/path_unit_test.cpp (contents, props changed)
sandbox/filesystem-v3/libs/filesystem/v3/test/wide_test.cpp (contents, props changed)
Added: sandbox/filesystem-v3/boost/filesystem/v3/config.hpp
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/boost/filesystem/v3/config.hpp 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,112 @@
+// boost/filesystem/config.hpp ---------------------------------------------//
+
+// Copyright Beman Dawes 2003
+
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See library home page at http://www.boost.org/libs/filesystem
+
+//----------------------------------------------------------------------------//
+
+#ifndef BOOST_FILESYSTEM_CONFIG_HPP
+#define BOOST_FILESYSTEM_CONFIG_HPP
+
+#define BOOST_FILESYSTEM_I18N // aid users wishing to compile several versions
+
+// ability to change namespace aids path_table.cpp ------------------------//
+#ifndef BOOST_FILESYSTEM_NAMESPACE
+# define BOOST_FILESYSTEM_NAMESPACE filesystem
+#endif
+
+// This header implements separate compilation features as described in
+// http://www.boost.org/more/separate_compilation.html
+
+#include <boost/config.hpp>
+#include <boost/detail/workaround.hpp>
+
+// determine platform ------------------------------------------------------//
+
+// BOOST_POSIX_API or BOOST_WINDOWS_API specify which API to use
+
+#ifdef BOOST_WINDOWS_API
+# warning BOOST_WINDOWS_API defined
+#endif
+
+# if defined( BOOST_WINDOWS_API ) && defined( BOOST_POSIX_API )
+# error both BOOST_WINDOWS_API and BOOST_POSIX_API are defined
+# elif !defined( BOOST_WINDOWS_API ) && !defined( BOOST_POSIX_API )
+# if (defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) && !defined(BOOST_NO_STD_WSTRING)
+# define BOOST_WINDOWS_API
+# else
+# define BOOST_POSIX_API
+# endif
+# endif
+
+# if defined( BOOST_WINDOWS_API ) && defined( BOOST_NO_STD_WSTRING )
+# error BOOST_WINDOWS_API can not be used when BOOST_NO_STD_WSTRING is defined
+# endif
+
+// BOOST_WINDOWS_PATH enables Windows path syntax recognition
+
+// filesystem.v2 defined BOOST_WINDOWS_PATH unconditionally for __CYGWIN__, but
+// that isn't possible for v3 because BOOST_WINDOWS_PATH requires wstring support
+
+# if !defined(BOOST_POSIX_PATH) && (defined(_WIN32) || defined(__WIN32__) || defined(WIN32) \
+ || (defined(__CYGWIN__) && !defined(BOOST_NO_STD_WSTRING)))
+# define BOOST_WINDOWS_PATH
+# endif
+
+// narrow support only for badly broken compilers or libraries -------------//
+
+# if defined(BOOST_NO_STD_WSTRING) || defined(BOOST_NO_SFINAE) || defined(BOOST_NO_STD_LOCALE) || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592))
+# define BOOST_FILESYSTEM_NARROW_ONLY
+# endif
+
+// enable dynamic linking on Windows ---------------------------------------//
+
+# if (defined(BOOST_ALL_DYN_LINK) || defined(BOOST_FILESYSTEM_DYN_LINK)) && defined(__BORLANDC__) && defined(__WIN32__)
+# error Dynamic linking Boost.Filesystem does not work for Borland; use static linking instead
+# endif
+
+#ifdef BOOST_HAS_DECLSPEC // defined in config system
+// we need to import/export our code only if the user has specifically
+// asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost
+// libraries to be dynamically linked, or BOOST_FILESYSTEM_DYN_LINK
+// if they want just this one to be dynamically liked:
+#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_FILESYSTEM_DYN_LINK)
+// export if this is our own source, otherwise import:
+#ifdef BOOST_FILESYSTEM_SOURCE
+# define BOOST_FILESYSTEM_DECL __declspec(dllexport)
+#else
+# define BOOST_FILESYSTEM_DECL __declspec(dllimport)
+#endif // BOOST_FILESYSTEM_SOURCE
+#endif // DYN_LINK
+#endif // BOOST_HAS_DECLSPEC
+//
+// if BOOST_FILESYSTEM_DECL isn't defined yet define it now:
+#ifndef BOOST_FILESYSTEM_DECL
+#define BOOST_FILESYSTEM_DECL
+#endif
+
+// enable automatic library variant selection ------------------------------//
+
+#if !defined(BOOST_FILESYSTEM_SOURCE) && !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_FILESYSTEM_NO_LIB)
+//
+// Set the name of our library, this will get undef'ed by auto_link.hpp
+// once it's done with it:
+//
+#define BOOST_LIB_NAME boost_filesystem
+//
+// If we're importing code from a dll, then tell auto_link.hpp about it:
+//
+#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_FILESYSTEM_DYN_LINK)
+# define BOOST_DYN_LINK
+#endif
+//
+// And include the header that does the work:
+//
+#include <boost/config/auto_link.hpp>
+#endif // auto-linking disabled
+
+#endif // BOOST_FILESYSTEM_CONFIG_HPP
Added: sandbox/filesystem-v3/boost/filesystem/v3/convenience.hpp
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/boost/filesystem/v3/convenience.hpp 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,230 @@
+// boost/filesystem/convenience.hpp ----------------------------------------//
+
+// Copyright Beman Dawes, 2002-2005
+// Copyright Vladimir Prus, 2002
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See library home page at http://www.boost.org/libs/filesystem
+
+//----------------------------------------------------------------------------//
+
+#ifndef BOOST_FILESYSTEM_CONVENIENCE_HPP
+#define BOOST_FILESYSTEM_CONVENIENCE_HPP
+
+#include <boost/filesystem/operations.hpp>
+#include <boost/system/error_code.hpp>
+#include <vector>
+#include <stack>
+
+#include <boost/config/abi_prefix.hpp> // must be the last #include
+
+namespace boost
+{
+ namespace filesystem
+ {
+
+# ifndef BOOST_FILESYSTEM_NO_DEPRECATED
+
+ BOOST_FS_FUNC_STRING extension(const Path& ph)
+ {
+ typedef BOOST_FS_TYPENAME Path::string_type string_type;
+ string_type filename = ph.filename();
+
+ BOOST_FS_TYPENAME string_type::size_type n = filename.rfind('.');
+ if (n != string_type::npos)
+ return filename.substr(n);
+ else
+ return string_type();
+ }
+
+ BOOST_FS_FUNC_STRING basename(const Path& ph)
+ {
+ typedef BOOST_FS_TYPENAME Path::string_type string_type;
+ string_type filename = ph.filename();
+ BOOST_FS_TYPENAME string_type::size_type n = filename.rfind('.');
+ return filename.substr(0, n);
+ }
+
+
+ BOOST_FS_FUNC(Path) change_extension( const Path & ph,
+ const BOOST_FS_TYPENAME Path::string_type & new_extension )
+ { return ph.parent_path() / (basename(ph) + new_extension); }
+
+ inline std::string extension(const path& ph)
+ { return extension<path>(ph); }
+ inline std::wstring extension(const wpath& ph)
+ { return extension<wpath>(ph); }
+
+ inline std::string basename(const path& ph)
+ { return basename<path>( ph ); }
+ inline std::wstring basename(const wpath& ph)
+ { return basename<wpath>( ph ); }
+
+ inline path change_extension( const path & ph, const std::string& new_ex )
+ { return change_extension<path>( ph, new_ex ); }
+ inline wpath change_extension( const wpath & ph, const std::wstring& new_ex )
+ { return change_extension<wpath>( ph, new_ex ); }
+# endif
+
+
+ // basic_recursive_directory_iterator helpers --------------------------//
+
+ namespace detail
+ {
+ struct recur_dir_itr_imp
+ {
+ typedef directory_iterator element_type;
+ std::stack< element_type, std::vector< element_type > > m_stack;
+ int m_level;
+ bool m_no_push;
+ bool m_no_throw;
+
+ recur_dir_itr_imp() : m_level(0), m_no_push(false), m_no_throw(false) {}
+ };
+
+ } // namespace detail
+
+ // recursive_directory_iterator ----------------------------------------//
+
+ class recursive_directory_iterator
+ : public boost::iterator_facade<
+ recursive_directory_iterator,
+ directory_entry,
+ boost::single_pass_traversal_tag >
+ {
+ public:
+
+ recursive_directory_iterator(){} // creates the "end" iterator
+
+ explicit recursive_directory_iterator( const path & dir_path )
+ : m_imp( new detail::recur_dir_itr_imp )
+ {
+ m_imp->m_stack.push( directory_iterator( dir_path ) );
+ if ( m_imp->m_stack.top () == directory_iterator() )
+ { m_imp.reset (); }
+ }
+
+ recursive_directory_iterator( const path & dir_path,
+ system::error_code & ec )
+ : m_imp( new detail::recur_dir_itr_imp )
+ {
+ m_imp->m_no_throw = true;
+ m_imp->m_stack.push( directory_iterator( dir_path, ec ) );
+ if ( m_imp->m_stack.top () == directory_iterator() )
+ { m_imp.reset (); }
+ }
+
+ int level() const { return m_imp->m_level; }
+
+ void pop();
+ void no_push()
+ {
+ BOOST_ASSERT( m_imp.get() && "no_push() on end recursive_directory_iterator" );
+ m_imp->m_no_push = true;
+ }
+
+ file_status status() const
+ {
+ BOOST_ASSERT( m_imp.get()
+ && "status() on end recursive_directory_iterator" );
+ return m_imp->m_stack.top()->status();
+ }
+
+ file_status symlink_status() const
+ {
+ BOOST_ASSERT( m_imp.get()
+ && "symlink_status() on end recursive_directory_iterator" );
+ return m_imp->m_stack.top()->symlink_status();
+ }
+
+ private:
+
+ // shared_ptr provides shallow-copy semantics required for InputIterators.
+ // m_imp.get()==0 indicates the end iterator.
+ boost::shared_ptr< detail::recur_dir_itr_imp > m_imp;
+
+ friend class boost::iterator_core_access;
+
+ boost::iterator_facade<
+ recursive_directory_iterator,
+ directory_entry,
+ boost::single_pass_traversal_tag >::reference
+ dereference() const
+ {
+ BOOST_ASSERT( m_imp.get() && "dereference end recursive_directory_iterator" );
+ return *m_imp->m_stack.top();
+ }
+
+ void increment();
+
+ bool equal( const recursive_directory_iterator & rhs ) const
+ { return m_imp == rhs.m_imp; }
+
+ };
+
+# if !defined(BOOST_FILESYSTEM_NARROW_ONLY) && !defined(BOOST_FILESYSTEM_NO_DEPRECATED)
+ typedef recursive_directory_iterator wrecursive_directory_iterator;
+# endif
+
+ // basic_recursive_directory_iterator implementation -------------------//
+
+ // increment
+ inline void recursive_directory_iterator::increment()
+ {
+ BOOST_ASSERT( m_imp.get() && "increment end recursive_directory_iterator" );
+
+ static const directory_iterator end_itr;
+
+ if ( m_imp->m_no_push )
+ { m_imp->m_no_push = false; }
+ else if ( is_directory( m_imp->m_stack.top()->status() ) )
+ {
+ system::error_code ec;
+ m_imp->m_stack.push(
+ m_imp->m_no_throw
+ ? directory_iterator( *m_imp->m_stack.top(), ec )
+ : directory_iterator( *m_imp->m_stack.top() ) );
+ if ( m_imp->m_stack.top() != end_itr )
+ {
+ ++m_imp->m_level;
+ return;
+ }
+ m_imp->m_stack.pop();
+ }
+
+ while ( !m_imp->m_stack.empty()
+ && ++m_imp->m_stack.top() == end_itr )
+ {
+ m_imp->m_stack.pop();
+ --m_imp->m_level;
+ }
+
+ if ( m_imp->m_stack.empty() ) m_imp.reset(); // done, so make end iterator
+ }
+
+ // pop
+ inline void recursive_directory_iterator::pop()
+ {
+ BOOST_ASSERT( m_imp.get() && "pop end recursive_directory_iterator" );
+ BOOST_ASSERT( m_imp->m_level > 0 && "pop recursive_directory_iterator with level < 1" );
+
+ static const directory_iterator end_itr;
+
+ do
+ {
+ m_imp->m_stack.pop();
+ --m_imp->m_level;
+ }
+ while ( !m_imp->m_stack.empty()
+ && ++m_imp->m_stack.top() == end_itr );
+
+ if ( m_imp->m_stack.empty() ) m_imp.reset(); // done, so make end iterator
+ }
+
+ } // namespace filesystem
+} // namespace boost
+
+#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas
+#endif // BOOST_FILESYSTEM_CONVENIENCE_HPP
Added: sandbox/filesystem-v3/boost/filesystem/v3/exception.hpp
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/boost/filesystem/v3/exception.hpp 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,9 @@
+// boost/filesystem/exception.hpp -------------------------------------------//
+
+// Copyright Beman Dawes 2003
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This header is no long used. The contents have been moved to path.hpp.
+// It is provided so that user code #includes do not have to be changed.
Added: sandbox/filesystem-v3/boost/filesystem/v3/fstream.hpp
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/boost/filesystem/v3/fstream.hpp 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,584 @@
+// boost/filesystem/fstream.hpp --------------------------------------------//
+
+// Copyright Beman Dawes 2002.
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See library home page at http://www.boost.org/libs/filesystem
+
+//----------------------------------------------------------------------------//
+
+#ifndef BOOST_FILESYSTEM_FSTREAM_HPP
+#define BOOST_FILESYSTEM_FSTREAM_HPP
+
+#include <boost/filesystem/operations.hpp> // for 8.3 hack (see below)
+#include <boost/utility/enable_if.hpp>
+#include <boost/detail/workaround.hpp>
+
+#include <iosfwd>
+#include <fstream>
+
+#include <boost/config/abi_prefix.hpp> // must be the last #include
+
+// NOTE: fstream.hpp for Boost 1.32.0 and earlier supplied workarounds for
+// various compiler problems. They have been removed to ease development of the
+// basic i18n functionality. Once the new interface is stable, the workarounds
+// will be reinstated for any compilers that otherwise can support the rest of
+// the library after internationalization.
+
+namespace boost
+{
+ namespace filesystem
+ {
+ namespace detail
+ {
+# if defined(BOOST_WINDOWS_API) && !defined(BOOST_FILESYSTEM_NARROW_ONLY)
+# if !defined(BOOST_DINKUMWARE_STDLIB) || BOOST_DINKUMWARE_STDLIB < 405
+ // The 8.3 hack:
+ // C++98 does not supply a wchar_t open, so try to get an equivalent
+ // narrow char name based on the short, so-called 8.3, name.
+ // Not needed for Dinkumware 405 and later as they do supply wchar_t open.
+ BOOST_FILESYSTEM_DECL bool create_file_api( const std::wstring & ph,
+ std::ios_base::openmode mode ); // true if succeeds
+ BOOST_FILESYSTEM_DECL std::string narrow_path_api(
+ const std::wstring & ph ); // return is empty if fails
+
+ inline std::string path_proxy( const std::wstring & file_ph,
+ std::ios_base::openmode mode )
+ // Return a non-existant path if cannot supply narrow short path.
+ // An empty path doesn't work because some Dinkumware versions
+ // assert the path is non-empty.
+ {
+ std::string narrow_ph;
+ bool created_file( false );
+ if ( !exists( file_ph )
+ && (mode & std::ios_base::out) != 0
+ && create_file_api( file_ph, mode ) )
+ {
+ created_file = true;
+ }
+ narrow_ph = narrow_path_api( file_ph );
+ if ( narrow_ph.empty() )
+ {
+ if ( created_file ) remove_api( file_ph );
+ narrow_ph = "\x01";
+ }
+ return narrow_ph;
+ }
+# else
+ // Dinkumware 405 and later does supply wchar_t functions
+ inline const std::wstring & path_proxy( const std::wstring & file_ph,
+ std::ios_base::openmode )
+ { return file_ph; }
+# endif
+# endif
+
+ inline const std::string & path_proxy( const std::string & file_ph,
+ std::ios_base::openmode )
+ { return file_ph; }
+
+ } // namespace detail
+
+ template < class charT, class traits = std::char_traits<charT> >
+ class basic_filebuf : public std::basic_filebuf<charT,traits>
+ {
+ private: // disallow copying
+ basic_filebuf( const basic_filebuf & );
+ const basic_filebuf & operator=( const basic_filebuf & );
+ public:
+ basic_filebuf() {}
+ virtual ~basic_filebuf() {}
+
+# ifndef BOOST_FILESYSTEM_NARROW_ONLY
+ template<class Path>
+ typename boost::enable_if<is_basic_path<Path>,
+ basic_filebuf<charT,traits> *>::type
+ open( const Path & file_ph, std::ios_base::openmode mode );
+
+ basic_filebuf<charT,traits> *
+ open( const wpath & file_ph, std::ios_base::openmode mode );
+# endif
+
+# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this
+ basic_filebuf<charT,traits> *
+ open( const path & file_ph, std::ios_base::openmode mode );
+# endif
+ };
+
+ template < class charT, class traits = std::char_traits<charT> >
+ class basic_ifstream : public std::basic_ifstream<charT,traits>
+ {
+ private: // disallow copying
+ basic_ifstream( const basic_ifstream & );
+ const basic_ifstream & operator=( const basic_ifstream & );
+ public:
+ basic_ifstream() {}
+
+ // use two signatures, rather than one signature with default second
+ // argument, to workaround VC++ 7.1 bug (ID VSWhidbey 38416)
+
+# ifndef BOOST_FILESYSTEM_NARROW_ONLY
+ template<class Path>
+ explicit basic_ifstream( const Path & file_ph,
+ typename boost::enable_if<is_basic_path<Path> >::type* dummy = 0 );
+
+ template<class Path>
+ basic_ifstream( const Path & file_ph, std::ios_base::openmode mode,
+ typename boost::enable_if<is_basic_path<Path> >::type* dummy = 0 );
+
+ template<class Path>
+ typename boost::enable_if<is_basic_path<Path>, void>::type
+ open( const Path & file_ph );
+
+ template<class Path>
+ typename boost::enable_if<is_basic_path<Path>, void>::type
+ open( const Path & file_ph, std::ios_base::openmode mode );
+
+ explicit basic_ifstream( const wpath & file_ph );
+ basic_ifstream( const wpath & file_ph, std::ios_base::openmode mode );
+ void open( const wpath & file_ph );
+ void open( const wpath & file_ph, std::ios_base::openmode mode );
+# endif
+
+ explicit basic_ifstream( const path & file_ph );
+ basic_ifstream( const path & file_ph, std::ios_base::openmode mode );
+# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this
+ void open( const path & file_ph );
+ void open( const path & file_ph, std::ios_base::openmode mode );
+# endif
+ virtual ~basic_ifstream() {}
+ };
+
+ template < class charT, class traits = std::char_traits<charT> >
+ class basic_ofstream : public std::basic_ofstream<charT,traits>
+ {
+ private: // disallow copying
+ basic_ofstream( const basic_ofstream & );
+ const basic_ofstream & operator=( const basic_ofstream & );
+ public:
+ basic_ofstream() {}
+
+ // use two signatures, rather than one signature with default second
+ // argument, to workaround VC++ 7.1 bug (ID VSWhidbey 38416)
+
+# ifndef BOOST_FILESYSTEM_NARROW_ONLY
+
+ template<class Path>
+ explicit basic_ofstream( const Path & file_ph,
+ typename boost::enable_if<is_basic_path<Path> >::type* dummy = 0 );
+ explicit basic_ofstream( const wpath & file_ph );
+
+ template<class Path>
+ basic_ofstream( const Path & file_ph, std::ios_base::openmode mode,
+ typename boost::enable_if<is_basic_path<Path> >::type* dummy = 0 );
+ basic_ofstream( const wpath & file_ph, std::ios_base::openmode mode );
+
+ template<class Path>
+ typename boost::enable_if<is_basic_path<Path>, void>::type
+ open( const Path & file_ph );
+ void open( const wpath & file_ph );
+
+ template<class Path>
+ typename boost::enable_if<is_basic_path<Path>, void>::type
+ open( const Path & file_ph, std::ios_base::openmode mode );
+ void open( const wpath & file_ph, std::ios_base::openmode mode );
+
+# endif
+
+ explicit basic_ofstream( const path & file_ph );
+ basic_ofstream( const path & file_ph, std::ios_base::openmode mode );
+# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this
+ void open( const path & file_ph );
+ void open( const path & file_ph, std::ios_base::openmode mode );
+# endif
+ virtual ~basic_ofstream() {}
+ };
+
+ template < class charT, class traits = std::char_traits<charT> >
+ class basic_fstream : public std::basic_fstream<charT,traits>
+ {
+ private: // disallow copying
+ basic_fstream( const basic_fstream & );
+ const basic_fstream & operator=( const basic_fstream & );
+ public:
+ basic_fstream() {}
+
+ // use two signatures, rather than one signature with default second
+ // argument, to workaround VC++ 7.1 bug (ID VSWhidbey 38416)
+
+# ifndef BOOST_FILESYSTEM_NARROW_ONLY
+
+ template<class Path>
+ explicit basic_fstream( const Path & file_ph,
+ typename boost::enable_if<is_basic_path<Path> >::type* dummy = 0 );
+ explicit basic_fstream( const wpath & file_ph );
+
+ template<class Path>
+ basic_fstream( const Path & file_ph, std::ios_base::openmode mode,
+ typename boost::enable_if<is_basic_path<Path> >::type* dummy = 0 );
+ basic_fstream( const wpath & file_ph, std::ios_base::openmode mode );
+
+ template<class Path>
+ typename boost::enable_if<is_basic_path<Path>, void>::type
+ open( const Path & file_ph );
+ void open( const wpath & file_ph );
+
+ template<class Path>
+ typename boost::enable_if<is_basic_path<Path>, void>::type
+ open( const Path & file_ph, std::ios_base::openmode mode );
+ void open( const wpath & file_ph, std::ios_base::openmode mode );
+
+# endif
+
+ explicit basic_fstream( const path & file_ph );
+ basic_fstream( const path & file_ph, std::ios_base::openmode mode );
+# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this
+ void open( const path & file_ph );
+ void open( const path & file_ph, std::ios_base::openmode mode );
+# endif
+ virtual ~basic_fstream() {}
+
+ };
+
+ typedef basic_filebuf<char> filebuf;
+ typedef basic_ifstream<char> ifstream;
+ typedef basic_ofstream<char> ofstream;
+ typedef basic_fstream<char> fstream;
+
+# ifndef BOOST_FILESYSTEM_NARROW_ONLY
+ typedef basic_filebuf<wchar_t> wfilebuf;
+ typedef basic_ifstream<wchar_t> wifstream;
+ typedef basic_fstream<wchar_t> wfstream;
+ typedef basic_ofstream<wchar_t> wofstream;
+# endif
+
+# ifndef BOOST_FILESYSTEM_NARROW_ONLY
+
+// basic_filebuf definitions -----------------------------------------------//
+
+ template <class charT, class traits>
+ template<class Path>
+ typename boost::enable_if<is_basic_path<Path>,
+ basic_filebuf<charT,traits> *>::type
+ basic_filebuf<charT,traits>::open( const Path & file_ph,
+ std::ios_base::openmode mode )
+ {
+ return (std::basic_filebuf<charT,traits>::open( detail::path_proxy(
+ file_ph.external_file_string(), mode ).c_str(), mode )
+ == 0) ? 0 : this;
+ }
+
+ template <class charT, class traits>
+ basic_filebuf<charT,traits> *
+ basic_filebuf<charT, traits>::open( const wpath & file_ph,
+ std::ios_base::openmode mode )
+ {
+ return this->BOOST_NESTED_TEMPLATE open<wpath>( file_ph, mode );
+ }
+
+// basic_ifstream definitions ----------------------------------------------//
+
+ template <class charT, class traits> template<class Path>
+ basic_ifstream<charT,traits>::basic_ifstream(const Path & file_ph,
+ typename boost::enable_if<is_basic_path<Path> >::type* )
+ : std::basic_ifstream<charT,traits>(
+ detail::path_proxy( file_ph.external_file_string(),
+ std::ios_base::in ).c_str(), std::ios_base::in ) {}
+
+ template <class charT, class traits>
+ basic_ifstream<charT,traits>::basic_ifstream( const wpath & file_ph )
+ : std::basic_ifstream<charT,traits>(
+ detail::path_proxy( file_ph.external_file_string(),
+ std::ios_base::in ).c_str(), std::ios_base::in ) {}
+
+ template <class charT, class traits> template<class Path>
+ basic_ifstream<charT,traits>::basic_ifstream( const Path & file_ph,
+ std::ios_base::openmode mode,
+ typename boost::enable_if<is_basic_path<Path> >::type* )
+ : std::basic_ifstream<charT,traits>(
+ detail::path_proxy( file_ph.external_file_string(),
+ mode ).c_str(), mode | std::ios_base::in ) {}
+
+ template <class charT, class traits>
+ basic_ifstream<charT,traits>::basic_ifstream( const wpath & file_ph,
+ std::ios_base::openmode mode )
+ : std::basic_ifstream<charT,traits>(
+ detail::path_proxy( file_ph.external_file_string(),
+ mode ).c_str(), mode | std::ios_base::in ) {}
+
+ template <class charT, class traits> template<class Path>
+ typename boost::enable_if<is_basic_path<Path>, void>::type
+ basic_ifstream<charT,traits>::open( const Path & file_ph )
+ {
+ std::basic_ifstream<charT,traits>::open(
+ detail::path_proxy( file_ph.external_file_string(),
+ std::ios_base::in ).c_str(), std::ios_base::in );
+ }
+
+ template <class charT, class traits>
+ void basic_ifstream<charT,traits>::open( const wpath & file_ph )
+ {
+ std::basic_ifstream<charT,traits>::open(
+ detail::path_proxy( file_ph.external_file_string(),
+ std::ios_base::in ).c_str(), std::ios_base::in );
+ }
+
+ template <class charT, class traits> template<class Path>
+ typename boost::enable_if<is_basic_path<Path>, void>::type
+ basic_ifstream<charT,traits>::open( const Path & file_ph,
+ std::ios_base::openmode mode )
+ {
+ std::basic_ifstream<charT,traits>::open(
+ detail::path_proxy( file_ph.external_file_string(),
+ mode ).c_str(), mode | std::ios_base::in );
+ }
+
+ template <class charT, class traits>
+ void basic_ifstream<charT,traits>::open( const wpath & file_ph,
+ std::ios_base::openmode mode )
+ {
+ std::basic_ifstream<charT,traits>::open(
+ detail::path_proxy( file_ph.external_file_string(),
+ mode ).c_str(), mode | std::ios_base::in );
+ }
+
+// basic_ofstream definitions ----------------------------------------------//
+
+ template <class charT, class traits> template<class Path>
+ basic_ofstream<charT,traits>::basic_ofstream(const Path & file_ph,
+ typename boost::enable_if<is_basic_path<Path> >::type* )
+ : std::basic_ofstream<charT,traits>(
+ detail::path_proxy( file_ph.external_file_string(),
+ std::ios_base::out ).c_str(), std::ios_base::out ) {}
+
+ template <class charT, class traits>
+ basic_ofstream<charT,traits>::basic_ofstream( const wpath & file_ph )
+ : std::basic_ofstream<charT,traits>(
+ detail::path_proxy( file_ph.external_file_string(),
+ std::ios_base::out ).c_str(), std::ios_base::out ) {}
+
+ template <class charT, class traits> template<class Path>
+ basic_ofstream<charT,traits>::basic_ofstream( const Path & file_ph,
+ std::ios_base::openmode mode,
+ typename boost::enable_if<is_basic_path<Path> >::type* )
+ : std::basic_ofstream<charT,traits>(
+ detail::path_proxy( file_ph.external_file_string(),
+ mode ).c_str(), mode | std::ios_base::out ) {}
+
+ template <class charT, class traits>
+ basic_ofstream<charT,traits>::basic_ofstream( const wpath & file_ph,
+ std::ios_base::openmode mode )
+ : std::basic_ofstream<charT,traits>(
+ detail::path_proxy( file_ph.external_file_string(),
+ mode ).c_str(), mode | std::ios_base::out ) {}
+
+ template <class charT, class traits> template<class Path>
+ typename boost::enable_if<is_basic_path<Path>, void>::type
+ basic_ofstream<charT,traits>::open( const Path & file_ph )
+ {
+ std::basic_ofstream<charT,traits>::open(
+ detail::path_proxy( file_ph.external_file_string(),
+ std::ios_base::out ).c_str(), std::ios_base::out );
+ }
+
+ template <class charT, class traits>
+ void basic_ofstream<charT,traits>::open( const wpath & file_ph )
+ {
+ std::basic_ofstream<charT,traits>::open(
+ detail::path_proxy( file_ph.external_file_string(),
+ std::ios_base::out ).c_str(), std::ios_base::out );
+ }
+
+ template <class charT, class traits> template<class Path>
+ typename boost::enable_if<is_basic_path<Path>, void>::type
+ basic_ofstream<charT,traits>::open( const Path & file_ph,
+ std::ios_base::openmode mode )
+ {
+ std::basic_ofstream<charT,traits>::open(
+ detail::path_proxy( file_ph.external_file_string(),
+ mode ).c_str(), mode | std::ios_base::out );
+ }
+
+ template <class charT, class traits>
+ void basic_ofstream<charT,traits>::open( const wpath & file_ph,
+ std::ios_base::openmode mode )
+ {
+ std::basic_ofstream<charT,traits>::open(
+ detail::path_proxy( file_ph.external_file_string(),
+ mode ).c_str(), mode | std::ios_base::out );
+ }
+
+// basic_fstream definitions -----------------------------------------------//
+
+ template <class charT, class traits> template<class Path>
+ basic_fstream<charT,traits>::basic_fstream(const Path & file_ph,
+ typename boost::enable_if<is_basic_path<Path> >::type* )
+ : std::basic_fstream<charT,traits>(
+ detail::path_proxy( file_ph.external_file_string(),
+ std::ios_base::in|std::ios_base::out ).c_str(),
+ std::ios_base::in|std::ios_base::out ) {}
+
+ template <class charT, class traits>
+ basic_fstream<charT,traits>::basic_fstream( const wpath & file_ph )
+ : std::basic_fstream<charT,traits>(
+ detail::path_proxy( file_ph.external_file_string(),
+ std::ios_base::in|std::ios_base::out ).c_str(),
+ std::ios_base::in|std::ios_base::out ) {}
+
+ template <class charT, class traits> template<class Path>
+ basic_fstream<charT,traits>::basic_fstream( const Path & file_ph,
+ std::ios_base::openmode mode,
+ typename boost::enable_if<is_basic_path<Path> >::type* )
+ : std::basic_fstream<charT,traits>(
+ detail::path_proxy( file_ph.external_file_string(),
+ mode ).c_str(), mode | std::ios_base::in | std::ios_base::out ) {}
+
+ template <class charT, class traits>
+ basic_fstream<charT,traits>::basic_fstream( const wpath & file_ph,
+ std::ios_base::openmode mode )
+ : std::basic_fstream<charT,traits>(
+ detail::path_proxy( file_ph.external_file_string(),
+ mode ).c_str(), mode | std::ios_base::in | std::ios_base::out ) {}
+
+ template <class charT, class traits> template<class Path>
+ typename boost::enable_if<is_basic_path<Path>, void>::type
+ basic_fstream<charT,traits>::open( const Path & file_ph )
+ {
+ std::basic_fstream<charT,traits>::open(
+ detail::path_proxy( file_ph.external_file_string(),
+ std::ios_base::in|std::ios_base::out ).c_str(),
+ std::ios_base::in|std::ios_base::out );
+ }
+
+ template <class charT, class traits>
+ void basic_fstream<charT,traits>::open( const wpath & file_ph )
+ {
+ std::basic_fstream<charT,traits>::open(
+ detail::path_proxy( file_ph.external_file_string(),
+ std::ios_base::in|std::ios_base::out ).c_str(),
+ std::ios_base::in|std::ios_base::out );
+ }
+
+ template <class charT, class traits> template<class Path>
+ typename boost::enable_if<is_basic_path<Path>, void>::type
+ basic_fstream<charT,traits>::open( const Path & file_ph,
+ std::ios_base::openmode mode )
+ {
+ std::basic_fstream<charT,traits>::open(
+ detail::path_proxy( file_ph.external_file_string(),
+ mode ).c_str(), mode | std::ios_base::in | std::ios_base::out );
+ }
+
+ template <class charT, class traits>
+ void basic_fstream<charT,traits>::open( const wpath & file_ph,
+ std::ios_base::openmode mode )
+ {
+ std::basic_fstream<charT,traits>::open(
+ detail::path_proxy( file_ph.external_file_string(),
+ mode ).c_str(), mode | std::ios_base::in | std::ios_base::out );
+ }
+
+# endif
+
+# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this
+ template <class charT, class traits>
+ basic_filebuf<charT,traits> *
+ basic_filebuf<charT, traits>::open( const path & file_ph,
+ std::ios_base::openmode mode )
+ {
+ return std::basic_filebuf<charT,traits>::open(
+ file_ph.file_string().c_str(), mode ) == 0 ? 0 : this;
+ }
+# endif
+
+ template <class charT, class traits>
+ basic_ifstream<charT,traits>::basic_ifstream( const path & file_ph )
+ : std::basic_ifstream<charT,traits>(
+ file_ph.file_string().c_str(), std::ios_base::in ) {}
+
+ template <class charT, class traits>
+ basic_ifstream<charT,traits>::basic_ifstream( const path & file_ph,
+ std::ios_base::openmode mode )
+ : std::basic_ifstream<charT,traits>(
+ file_ph.file_string().c_str(), mode ) {}
+
+# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this
+ template <class charT, class traits>
+ void basic_ifstream<charT,traits>::open( const path & file_ph )
+ {
+ std::basic_ifstream<charT,traits>::open(
+ file_ph.file_string().c_str(), std::ios_base::in );
+ }
+
+ template <class charT, class traits>
+ void basic_ifstream<charT,traits>::open( const path & file_ph,
+ std::ios_base::openmode mode )
+ {
+ std::basic_ifstream<charT,traits>::open(
+ file_ph.file_string().c_str(), mode );
+ }
+# endif
+
+ template <class charT, class traits>
+ basic_ofstream<charT,traits>::basic_ofstream( const path & file_ph )
+ : std::basic_ofstream<charT,traits>(
+ file_ph.file_string().c_str(), std::ios_base::out ) {}
+
+ template <class charT, class traits>
+ basic_ofstream<charT,traits>::basic_ofstream( const path & file_ph,
+ std::ios_base::openmode mode )
+ : std::basic_ofstream<charT,traits>(
+ file_ph.file_string().c_str(), mode ) {}
+
+# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this
+ template <class charT, class traits>
+ void basic_ofstream<charT,traits>::open( const path & file_ph )
+ {
+ std::basic_ofstream<charT,traits>::open(
+ file_ph.file_string().c_str(), std::ios_base::out );
+ }
+
+ template <class charT, class traits>
+ void basic_ofstream<charT,traits>::open( const path & file_ph,
+ std::ios_base::openmode mode )
+ {
+ std::basic_ofstream<charT,traits>::open(
+ file_ph.file_string().c_str(), mode );
+ }
+# endif
+
+ template <class charT, class traits>
+ basic_fstream<charT,traits>::basic_fstream( const path & file_ph )
+ : std::basic_fstream<charT,traits>(
+ file_ph.file_string().c_str(),
+ std::ios_base::in|std::ios_base::out ) {}
+
+
+ template <class charT, class traits>
+ basic_fstream<charT,traits>::basic_fstream( const path & file_ph,
+ std::ios_base::openmode mode )
+ : std::basic_fstream<charT,traits>(
+ file_ph.file_string().c_str(), mode ) {}
+
+# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this
+ template <class charT, class traits>
+ void basic_fstream<charT,traits>::open( const path & file_ph )
+ {
+ std::basic_fstream<charT,traits>::open(
+ file_ph.file_string().c_str(), std::ios_base::in|std::ios_base::out );
+ }
+
+ template <class charT, class traits>
+ void basic_fstream<charT,traits>::open( const path & file_ph,
+ std::ios_base::openmode mode )
+ {
+ std::basic_fstream<charT,traits>::open(
+ file_ph.file_string().c_str(), mode );
+ }
+# endif
+ } // namespace filesystem
+} // namespace boost
+
+#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas
+#endif // BOOST_FILESYSTEM_FSTREAM_HPP
Added: sandbox/filesystem-v3/boost/filesystem/v3/operations.hpp
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/boost/filesystem/v3/operations.hpp 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,671 @@
+// boost/filesystem/operations.hpp -----------------------------------------//
+
+// Copyright Beman Dawes 2002-2008
+// Copyright Jan Langer 2002
+// Copyright Dietmar Kuehl 2001
+// Copyright Vladimir Prus 2002
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// See library home page at http://www.boost.org/libs/filesystem
+
+//----------------------------------------------------------------------------//
+/*
+* TODO List
+*
+* Scoped enum workaround for file_type.
+* Enable all BOOST_FILESYSTEM_NO_DEPRECATED code.
+* Vista symlink_status support.
+* Merge fixes from trunk
+* rename and remove really need to be renamed. If users says "using namespace boost::filesystem"
+ and some header included stdio, there is just too much chance of silent error.
+* create_directories error handling.
+* Review any commented out code, both in operations.hpp and operations.cpp
+* Finish refactoring operations_test.
+* Fold convenience.hpp into operations.hpp
+* Two argument recursive_directory_iterator ctor isn't recognizing system::throws.
+ would it be better to fold into a single two argument ctor with default?
+* Add the push_directory class from tools/release/required_files.cpp
+
+*/
+//----------------------------------------------------------------------------//
+
+#ifndef BOOST_FILESYSTEM_OPERATIONS_HPP
+#define BOOST_FILESYSTEM_OPERATIONS_HPP
+
+#include <boost/filesystem/path.hpp>
+
+#include <boost/system/error_code.hpp>
+#include <boost/system/system_error.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/iterator.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/assert.hpp>
+
+#include <string>
+#include <utility> // for pair
+#include <ctime>
+
+#ifdef BOOST_WINDOWS_API
+# include <fstream>
+# if !defined(_WIN32_WINNT)
+# define _WIN32_WINNT 0x0500 // assume Windows 2000 or later SDK
+# endif
+#endif
+
+#include <boost/config/abi_prefix.hpp> // must be the last #include
+
+# ifdef BOOST_NO_STDC_NAMESPACE
+ namespace std { using ::time_t; }
+# endif
+
+//----------------------------------------------------------------------------//
+
+namespace boost
+{
+ namespace filesystem
+ {
+
+//----------------------------------------------------------------------------//
+// //
+// support classes and enums //
+// //
+//----------------------------------------------------------------------------//
+
+ enum file_type
+ {
+ status_unknown,
+ file_not_found,
+ regular_file,
+ directory_file,
+ // the following will never be reported by some operating or file systems
+ symlink_file,
+ block_file,
+ character_file,
+ fifo_file,
+ socket_file,
+ type_unknown // file does exist, but isn't one of the above types or
+ // we don't have strong enough permission to find its type
+ };
+
+ class BOOST_FILESYSTEM_DECL file_status
+ {
+ public:
+ explicit file_status( file_type v = status_unknown ) : m_value(v) {}
+
+ void type( file_type v ) { m_value = v; }
+ file_type type() const { return m_value; }
+
+ bool operator==( const file_status & rhs ) const { return type() == rhs.type(); }
+ bool operator!=( const file_status & rhs ) const { return !(*this == rhs); }
+
+ private:
+ // the internal representation is unspecified so that additional state
+ // information such as permissions can be added in the future; this
+ // implementation just uses status_type as the internal representation
+
+ file_type m_value;
+ };
+
+ inline bool status_known( file_status f ) { return f.type() != status_unknown; }
+ inline bool exists( file_status f ) { return f.type() != status_unknown && f.type() != file_not_found; }
+ inline bool is_regular_file(file_status f){ return f.type() == regular_file; }
+ inline bool is_directory( file_status f ) { return f.type() == directory_file; }
+ inline bool is_symlink( file_status f ) { return f.type() == symlink_file; }
+ inline bool is_other( file_status f ) { return exists(f) && !is_regular_file(f) && !is_directory(f) && !is_symlink(f); }
+
+# ifndef BOOST_FILESYSTEM_NO_DEPRECATED
+ inline bool is_regular( file_status f ) { return f.type() == regular_file; }
+# endif
+
+ struct space_info
+ {
+ // all values are byte counts
+ boost::uintmax_t capacity;
+ boost::uintmax_t free; // <= capacity
+ boost::uintmax_t available; // <= free
+ };
+
+//----------------------------------------------------------------------------//
+// //
+// query functions //
+// //
+//----------------------------------------------------------------------------//
+
+ BOOST_FILESYSTEM_DECL
+ file_status status( const path & p,
+ system::error_code & ec = system::throws );
+
+ BOOST_FILESYSTEM_DECL
+ file_status symlink_status( const path & p,
+ system::error_code & ec = system::throws );
+
+ inline bool exists( const path & p, system::error_code & ec = system::throws ) { return exists( status( p, ec ) ); }
+ inline bool is_directory( const path & p, system::error_code & ec = system::throws ) { return is_directory( status( p, ec ) ); }
+ inline bool is_regular_file( const path & p, system::error_code & ec = system::throws ) { return is_regular_file( status( p, ec ) ); }
+ inline bool is_other( const path & p, system::error_code & ec = system::throws ) { return is_other( status( p, ec ) ); }
+ inline bool is_symlink( const path & p, system::error_code & ec = system::throws ) { return is_symlink( symlink_status( p, ec ) ); }
+
+# ifndef BOOST_FILESYSTEM_NO_DEPRECATED
+ inline bool is_regular( const path & p, system::error_code & ec = system::throws ) { return is_regular( status( p, ec ) ); }
+# endif
+
+
+// // VC++ 7.0 and earlier has a serious namespace bug that causes a clash
+// // between boost::filesystem::is_empty and the unrelated type trait
+// // boost::is_empty.
+//
+//# if !defined( BOOST_MSVC ) || BOOST_MSVC > 1300
+// BOOST_FS_FUNC(bool) is_empty( const Path & ph )
+//# else
+// BOOST_FS_FUNC(bool) _is_empty( const Path & ph )
+//# endif
+// {
+// detail::query_pair result(
+// detail::is_empty_api( ph.external_file_string() ) );
+// if ( result.first )
+// boost::throw_exception( basic_filesystem_error<Path>(
+// "boost::filesystem::is_empty", ph, result.first ) );
+// return result.second;
+// }
+
+ BOOST_FILESYSTEM_DECL
+ bool is_empty( const path & p, system::error_code & ec = system::throws );
+
+//----------------------------------------------------------------------------//
+// //
+// operational functions //
+// in alphabetical order, unless otherwise noted //
+// //
+//----------------------------------------------------------------------------//
+
+ BOOST_FILESYSTEM_DECL // declaration must precede complete()
+ path initial_path( system::error_code & ec = system::throws );
+
+ BOOST_FILESYSTEM_DECL
+ path complete( const path & p, const path & base = initial_path() );
+
+ BOOST_FILESYSTEM_DECL
+ void copy_file( const path & from, const path & to,
+ system::error_code & ec = system::throws );
+
+ BOOST_FILESYSTEM_DECL
+ bool create_directories( const path & p/*,
+ system::error_code & ec = system::throws*/ );
+
+ BOOST_FILESYSTEM_DECL
+ bool create_directory( const path & p, system::error_code & ec = system::throws );
+
+ BOOST_FILESYSTEM_DECL
+ void create_directory_symlink( const path & to, const path & from,
+ system::error_code & ec = system::throws );
+
+ BOOST_FILESYSTEM_DECL
+ void create_hard_link( const path & to, const path & from,
+ system::error_code & ec = system::throws );
+
+ BOOST_FILESYSTEM_DECL
+ void create_symlink( const path & to, const path & from,
+ system::error_code & ec = system::throws );
+
+ BOOST_FILESYSTEM_DECL
+ path current_path( system::error_code & ec = system::throws );
+
+ BOOST_FILESYSTEM_DECL
+ void current_path( const path & p, system::error_code & ec = system::throws );
+
+ BOOST_FILESYSTEM_DECL
+ bool equivalent( const path & p1, const path & p2,
+ system::error_code & ec = system::throws );
+
+ BOOST_FILESYSTEM_DECL
+ boost::uintmax_t file_size( const path & p,
+ system::error_code & ec = system::throws );
+
+ // initial_path() declaration precedes complete()
+
+ BOOST_FILESYSTEM_DECL
+ std::time_t last_write_time( const path & p,
+ system::error_code & ec = system::throws );
+
+ BOOST_FILESYSTEM_DECL
+ void last_write_time( const path & p, const std::time_t new_time,
+ system::error_code & ec = system::throws );
+
+ BOOST_FILESYSTEM_DECL
+ bool remove( const path & p, system::error_code & ec = system::throws );
+
+ BOOST_FILESYSTEM_DECL
+ boost::uintmax_t remove_all( const path & p,
+ system::error_code & ec = system::throws );
+
+ BOOST_FILESYSTEM_DECL
+ void rename( const path & from, const path & to,
+ system::error_code & ec = system::throws );
+
+ BOOST_FILESYSTEM_DECL
+ space_info space( const path & p, system::error_code & ec = system::throws );
+
+ BOOST_FILESYSTEM_DECL
+ path system_complete( const path & p, system::error_code & ec = system::throws );
+
+//----------------------------------------------------------------------------//
+// //
+// directory_entry //
+// //
+//----------------------------------------------------------------------------//
+
+// GCC has a problem with a member function named path within a namespace or
+// sub-namespace that also has a class named path. The workaround is to always
+// fully qualify the name path when it refers to the class name.
+
+class BOOST_FILESYSTEM_DECL directory_entry
+{
+public:
+
+ // compiler generated copy-ctor, copy assignment, and destructor apply
+
+ directory_entry() {}
+ explicit directory_entry( const boost::filesystem::path & p,
+ file_status st = file_status(), file_status symlink_st=file_status() )
+ : m_path(p), m_status(st), m_symlink_status(symlink_st)
+ {}
+
+ void assign( const boost::filesystem::path & p,
+ file_status st, file_status symlink_st )
+ { m_path = p; m_status = st; m_symlink_status = symlink_st; }
+
+ void replace_filename( const boost::filesystem::path & p,
+ file_status st, file_status symlink_st )
+ {
+ m_path.remove_filename();
+ m_path /= p;
+ m_status = st;
+ m_symlink_status = symlink_st;
+ }
+
+# ifndef BOOST_FILESYSTEM_NO_DEPRECATED
+ void replace_leaf( const boost::filesystem::path & p,
+ file_status st, file_status symlink_st )
+ { replace_filename( p, st, symlink_st ); }
+# endif
+
+ const boost::filesystem::path & path() const { return m_path; }
+ file_status status( system::error_code & ec = system::throws ) const;
+ file_status symlink_status( system::error_code & ec = system::throws ) const;
+
+ // conversion simplifies the most common use of directory_entry
+ operator const boost::filesystem::path &() const { return m_path; }
+
+//# ifndef BOOST_FILESYSTEM_NO_DEPRECATED
+// // deprecated functions preserve common use cases in legacy code
+// typename Path::string_type filename() const
+// {
+// return path().filename();
+// }
+// typename Path::string_type leaf() const
+// {
+// return path().filename();
+// }
+// typename Path::string_type string() const
+// {
+// return path().string();
+// }
+//# endif
+
+private:
+ boost::filesystem::path m_path;
+ mutable file_status m_status; // stat()-like
+ mutable file_status m_symlink_status; // lstat()-like
+
+}; // directory_entry
+
+//----------------------------------------------------------------------------//
+// //
+// directory_iterator helpers //
+// //
+//----------------------------------------------------------------------------//
+
+class directory_iterator;
+
+namespace detail
+{
+ BOOST_FILESYSTEM_DECL
+ system::error_code dir_itr_close( // never throws
+ void *& handle
+# if defined(BOOST_POSIX_API)
+ , void *& buffer
+# endif
+ );
+
+ struct BOOST_FILESYSTEM_DECL dir_itr_imp
+ {
+ directory_entry dir_entry;
+ void * handle;
+
+# ifdef BOOST_POSIX_API
+ void * buffer; // see dir_itr_increment implementation
+# endif
+
+ dir_itr_imp() : handle(0)
+# ifdef BOOST_POSIX_API
+ , buffer(0)
+# endif
+ {}
+
+ ~dir_itr_imp() // never throws
+ {
+ dir_itr_close( handle
+# if defined(BOOST_POSIX_API)
+ , buffer
+# endif
+ );
+ }
+ };
+
+ // see path::iterator: comment below
+ BOOST_FILESYSTEM_DECL void directory_iterator_construct( directory_iterator & it,
+ const path & p, system::error_code & ec );
+ BOOST_FILESYSTEM_DECL void directory_iterator_increment( directory_iterator & it );
+
+} // namespace detail
+
+//----------------------------------------------------------------------------//
+// //
+// directory_iterator //
+// //
+//----------------------------------------------------------------------------//
+
+ class directory_iterator
+ : public boost::iterator_facade<
+ directory_iterator,
+ directory_entry,
+ boost::single_pass_traversal_tag >
+ {
+ public:
+
+ directory_iterator(){} // creates the "end" iterator
+
+ // iterator_facade derived classes don't seem to like implementations in
+ // separate translation unit dll's, so forward to detail functions
+ directory_iterator( const path & p,
+ system::error_code & ec = system::throws )
+ : m_imp( new detail::dir_itr_imp )
+ { detail::directory_iterator_construct( *this, p, ec ); }
+
+ ~directory_iterator() {} // never throws
+
+ private:
+ friend struct detail::dir_itr_imp;
+ friend void detail::directory_iterator_construct( directory_iterator & it,
+ const path & p, system::error_code & ec);
+ friend void detail::directory_iterator_increment( directory_iterator & it );
+
+ // shared_ptr provides shallow-copy semantics required for InputIterators.
+ // m_imp.get()==0 indicates the end iterator.
+ boost::shared_ptr< detail::dir_itr_imp > m_imp;
+
+ friend class boost::iterator_core_access;
+
+ boost::iterator_facade<
+ directory_iterator,
+ directory_entry,
+ boost::single_pass_traversal_tag >::reference dereference() const
+ {
+ BOOST_ASSERT( m_imp.get() && "attempt to dereference end iterator" );
+ return m_imp->dir_entry;
+ }
+
+ void increment() { detail::directory_iterator_increment( *this ); }
+
+ bool equal( const directory_iterator & rhs ) const
+ { return m_imp == rhs.m_imp; }
+ };
+
+//----------------------------------------------------------------------------//
+// //
+// class filesystem_error //
+// //
+//----------------------------------------------------------------------------//
+
+ class filesystem_error : public system::system_error
+ {
+ // see http://www.boost.org/more/error_handling.html for design rationale
+
+ // all functions are inline to avoid issues with crossing dll boundaries
+
+ public:
+ // compiler generates copy constructor and copy assignment
+
+ // constructors without path arguments
+
+ filesystem_error::filesystem_error(
+ const std::string & what_arg, system::error_code ec )
+ : system::system_error(ec, what_arg)
+ {
+ try
+ {
+ m_imp_ptr.reset( new m_imp );
+ }
+ catch (...) { m_imp_ptr.reset(); }
+ }
+
+ filesystem_error::filesystem_error(
+ const char * what_arg, system::error_code ec )
+ : system::system_error(ec, what_arg)
+ {
+ try
+ {
+ m_imp_ptr.reset( new m_imp );
+ }
+ catch (...) { m_imp_ptr.reset(); }
+ }
+
+ filesystem_error::filesystem_error(
+ const std::string & what_arg, int ev, const system::error_category & ecat )
+ : system::system_error(ev, ecat, what_arg)
+ {
+ try
+ {
+ m_imp_ptr.reset( new m_imp );
+ }
+ catch (...) { m_imp_ptr.reset(); }
+ }
+
+ filesystem_error::filesystem_error(
+ const char * what_arg, int ev, const system::error_category & ecat )
+ : system::system_error(ev, ecat, what_arg)
+ {
+ try
+ {
+ m_imp_ptr.reset( new m_imp );
+ }
+ catch (...) { m_imp_ptr.reset(); }
+ }
+
+ // constructors with one path argument
+
+ filesystem_error::filesystem_error(
+ const std::string & what_arg, const path & path1_arg,
+ system::error_code ec )
+ : system::system_error(ec, what_arg)
+ {
+ try
+ {
+ m_imp_ptr.reset( new m_imp );
+ m_imp_ptr->m_path1 = path1_arg;
+ }
+ catch (...) { m_imp_ptr.reset(); }
+ }
+
+ filesystem_error::filesystem_error(
+ const char * what_arg, const path & path1_arg,
+ system::error_code ec )
+ : system::system_error(ec, what_arg)
+ {
+ try
+ {
+ m_imp_ptr.reset( new m_imp );
+ m_imp_ptr->m_path1 = path1_arg;
+ }
+ catch (...) { m_imp_ptr.reset(); }
+ }
+
+ filesystem_error::filesystem_error(
+ const std::string & what_arg, const path & path1_arg,
+ int ev, const system::error_category & ecat )
+ : system::system_error(ev, ecat, what_arg)
+ {
+ try
+ {
+ m_imp_ptr.reset( new m_imp );
+ m_imp_ptr->m_path1 = path1_arg;
+ }
+ catch (...) { m_imp_ptr.reset(); }
+ }
+
+ filesystem_error::filesystem_error(
+ const char * what_arg, const path & path1_arg,
+ int ev, const system::error_category & ecat )
+ : system::system_error(ev, ecat, what_arg)
+ {
+ try
+ {
+ m_imp_ptr.reset( new m_imp );
+ m_imp_ptr->m_path1 = path1_arg;
+ }
+ catch (...) { m_imp_ptr.reset(); }
+ }
+
+ // constructors with two path arguments
+
+ filesystem_error::filesystem_error(
+ const std::string & what_arg, const path & path1_arg,
+ const path & path2_arg, system::error_code ec )
+ : system::system_error(ec, what_arg)
+ {
+ try
+ {
+ m_imp_ptr.reset( new m_imp );
+ m_imp_ptr->m_path1 = path1_arg;
+ m_imp_ptr->m_path2 = path2_arg;
+ }
+ catch (...) { m_imp_ptr.reset(); }
+ }
+
+ filesystem_error::filesystem_error(
+ const char * what_arg, const path & path1_arg,
+ const path & path2_arg, system::error_code ec )
+ : system::system_error(ec, what_arg)
+ {
+ try
+ {
+ m_imp_ptr.reset( new m_imp );
+ m_imp_ptr->m_path1 = path1_arg;
+ m_imp_ptr->m_path2 = path2_arg;
+ }
+ catch (...) { m_imp_ptr.reset(); }
+ }
+
+ filesystem_error::filesystem_error(
+ const std::string & what_arg, const path & path1_arg,
+ const path & path2_arg, int ev, const system::error_category & ecat )
+ : system::system_error(ev, ecat, what_arg)
+ {
+ try
+ {
+ m_imp_ptr.reset( new m_imp );
+ m_imp_ptr->m_path1 = path1_arg;
+ m_imp_ptr->m_path2 = path2_arg;
+ }
+ catch (...) { m_imp_ptr.reset(); }
+ }
+
+ filesystem_error::filesystem_error(
+ const char * what_arg, const path & path1_arg,
+ const path & path2_arg, int ev, const system::error_category & ecat )
+ : system::system_error(ev, ecat, what_arg)
+ {
+ try
+ {
+ m_imp_ptr.reset( new m_imp );
+ m_imp_ptr->m_path1 = path1_arg;
+ m_imp_ptr->m_path2 = path2_arg;
+ }
+ catch (...) { m_imp_ptr.reset(); }
+ }
+
+ ~filesystem_error() throw() {}
+
+ const path & path1() const
+ {
+ static const path empty_path;
+ return m_imp_ptr.get() ? m_imp_ptr->m_path1 : empty_path ;
+ }
+ const path & path2() const
+ {
+ static const path empty_path;
+ return m_imp_ptr.get() ? m_imp_ptr->m_path2 : empty_path ;
+ }
+
+ const char * filesystem_error::what() const throw()
+ {
+ if ( !m_imp_ptr.get() )
+ return system::system_error::what();
+
+ try
+ {
+ if ( m_imp_ptr->m_what.empty() )
+ {
+ m_imp_ptr->m_what = system::system_error::what();
+ if ( !m_imp_ptr->m_path1.empty() )
+ {
+ m_imp_ptr->m_what += ": \"";
+ m_imp_ptr->m_what += m_imp_ptr->m_path1.string();
+ m_imp_ptr->m_what += "\"";
+ }
+ if ( !m_imp_ptr->m_path2.empty() )
+ {
+ m_imp_ptr->m_what += ", \"";
+ m_imp_ptr->m_what += m_imp_ptr->m_path2.string();
+ m_imp_ptr->m_what += "\"";
+ }
+ }
+ return m_imp_ptr->m_what.c_str();
+ }
+ catch (...)
+ {
+ return system::system_error::what();
+ }
+ }
+
+ private:
+ struct m_imp
+ {
+ path m_path1; // may be empty()
+ path m_path2; // may be empty()
+ std::string m_what; // not built until needed
+ };
+ boost::shared_ptr<m_imp> m_imp_ptr;
+ };
+
+// test helper -------------------------------------------------------------//
+
+// Not part of the documented interface since false positives are possible;
+// there is no law that says that an OS that has large stat.st_size
+// actually supports large file sizes.
+
+ namespace detail
+ {
+ BOOST_FILESYSTEM_DECL bool possible_large_file_size_support();
+ }
+
+ } // namespace filesystem
+} // namespace boost
+
+
+#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas
+#endif // BOOST_FILESYSTEM_OPERATIONS_HPP
Added: sandbox/filesystem-v3/boost/filesystem/v3/path.hpp
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/boost/filesystem/v3/path.hpp 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,858 @@
+// filesystem path.hpp -----------------------------------------------------//
+
+// Copyright Beman Dawes 2002-2005, 2008
+// Copyright Vladimir Prus 2002
+
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See library home page at http://www.boost.org/libs/filesystem
+
+// basic_path's stem(), extension(), and replace_extension() are based on
+// basename(), extension(), and change_extension() from the original
+// filesystem/convenience.hpp header by Vladimir Prus.
+
+//----------------------------------------------------------------------------//
+/*
+ TO DO
+
+ * Windows, POSIX, conversions for char16_t, char32_t for supporting compilers.
+ * Add Alternate Data Stream test cases. See http://en.wikipedia.org/wiki/NTFS Features.
+ * test case: relational on paths differing only in trailing separator. rationale?
+ * Behavior of root_path() has been changed. Change needs to be propagated to trunk.
+ reference.html#Path-decomposition-table needs rows for //, //netname, //netname/foo
+ Make sure current trunk has passing tests for those cases, all decompositions.
+ See test_decompositions() in path_unit_test.cpp
+ * Get the deprecated names working.
+ * path_test ~line 1200 replace_extension() tests commented out
+ * Document leading //: no longer treated specially.
+ * reference.html: operator /= is underspecified as to when a "/" is appended, and
+ whether a '/' or '\' is appended.
+ * path_unit_test needs to probe error handling, verify exceptions are thrown when
+ requested.
+ * Provide the name check functions for more character types. Templatize?
+
+ Design Questions
+
+ * Should path_locale use thread local storage?
+ * Will locale overloads be needed in practice?
+ * Is it OK for single-element decomposition functions to return paths? Yes;
+ keep the interface simple and usable in generic code at the expense of some
+ notational convenience.
+ * Are generic versions of string(), native_string() needed? IE:
+ template< class T >
+ T string( const error_code ec = throws );
+ TODO: Yes; all member functions need to be usable in generic code.
+ Can string() and native_string() make use of detail::convert()?
+ * Assuming generic versions of string(), native_string(), are the w flavors needed?
+ No. KISS. basic_string<char> is special because it is the predominent
+ use case. w (and other) flavors can be added later.
+ * Should UDT's be supported? Yes. Easy to do and pretty harmless.
+ * What to do about Cygwin and other environments that don't support wchar_t?
+ * Should path iteration to a separator result in:
+ -- the actual separator used
+ -- the preferred separator
+ -- the generic separator <-- makes it easier to write portable code
+ * Should the preferred native separator be available?
+ */
+//----------------------------------------------------------------------------//
+
+#ifndef BOOST_FILESYSTEM_PATH_HPP
+#define BOOST_FILESYSTEM_PATH_HPP
+
+#include <boost/filesystem/config.hpp>
+#include <boost/system/error_code.hpp>
+#include <boost/system/system_error.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/static_assert.hpp>
+#include <string>
+#include <cstring>
+#include <iosfwd> // needed by basic_path inserter and extractor
+#include <stdexcept>
+#include <cassert>
+#include <locale>
+#include <algorithm>
+
+# ifdef BOOST_WINDOWS_API
+# else // BOOST_POSIX_API
+# endif
+
+
+#include <boost/config/abi_prefix.hpp> // must be the last #include
+
+//----------------------------------------------------------------------------//
+
+namespace boost
+{
+namespace filesystem
+{
+ // exception classes -----------------------------------------------------//
+
+ // filesystem_error is not used because errors are sometimes thrown during
+ // path construction when there isn't a complete path to include.
+ // system_error is not used because most uses will be conversion errors, and
+ // thus it is useful to include the source string causing the error. Since
+ // processing source string errors is by its nature type dependent, the
+ // exception class is templated on the string type.
+
+ // path_error can be caught when further type distinctions aren't needed.
+ class path_error : public std::runtime_error
+ {
+ public:
+ path_error( const char * what_, boost::system::error_code ec_ )
+ : std::runtime_error( what_ ), m_ec( ec_ ) {}
+
+ boost::system::error_code error_code() const throw() { return m_ec; }
+
+ private:
+ boost::system::error_code m_ec;
+ };
+
+ template < class String >
+ class basic_path_error : public path_error
+ {
+ public:
+ basic_path_error( const char * what_, boost::system::error_code ec_,
+ const String & source_ )
+ : path_error( what_, ec_ ), m_source( source_ ) {}
+
+ const String & source() const { return m_source; }
+
+ private:
+ String m_source;
+ };
+
+ //--------------------------------------------------------------------------//
+ // //
+ // implementation details //
+ // //
+ //--------------------------------------------------------------------------//
+
+ namespace detail
+ {
+
+ BOOST_FILESYSTEM_DECL extern const std::locale * path_locale;
+
+# ifdef BOOST_WINDOWS_PATH
+
+ const wchar_t separator = L'/';
+ const wchar_t preferred_separator = L'\\';
+ const wchar_t * const separators = L"/\\";
+ const wchar_t colon = L':';
+ const wchar_t dot = L'.';
+
+# else // BOOST_POSIX_PATH
+
+ const char separator = '/';
+ const char preferred_separator = '/';
+ const char * const separators = "/";
+ const char colon = ':';
+ const char dot = '.';
+
+# endif
+
+# ifdef BOOST_WINDOWS_API
+
+ typedef std::wstring string_type;
+ typedef string_type::value_type value_type;
+ typedef string_type::size_type size_type;
+
+ // class path has a number of generic functions that are implemented by
+ // detail::convert_append() or detail::convert(). detail::convert_append()
+ // functions called indirectly via detail::convert_append_helper() functions
+ // to reduce the number of overloads required. Overloads are supplied
+ // for all supported character array types to string_type.
+
+ // ----- char[] to wstring -----
+
+ BOOST_FILESYSTEM_DECL
+ void convert_append( const char * begin,
+ const char * end, // 0 for null terminated MBCS
+ std::wstring & target,
+ system::error_code & ec );
+
+ inline void convert_append( const char * begin, std::wstring & target,
+ system::error_code & ec )
+ {
+ convert_append( begin, 0, target, ec );
+ }
+
+ // ----- wchar_t[] to wstring -----
+
+ inline void convert_append( const wchar_t * begin, const wchar_t * end,
+ std::wstring & target, system::error_code & ec )
+ {
+ ec.clear();
+ target.assign( begin, end ); // but what if throws bad_alloc?
+ }
+
+ inline void convert_append( const wchar_t * begin, std::wstring & target,
+ system::error_code & ec )
+ {
+ ec.clear();
+ target += begin; // but what if throws bad_alloc?
+ }
+
+ // ----- convert ----
+
+ BOOST_FILESYSTEM_DECL
+ std::string convert( const std::wstring & src, system::error_code & ec );
+
+# else // BOOST_POSIX_API
+
+ typedef std::string string_type;
+ typedef string_type::value_type value_type;
+ typedef string_type::size_type size_type;
+
+ // See comment at equivalent location in Windows API detail above
+
+ // ----- char[] to string -----
+
+ inline void convert_append( const char * begin,
+ const char * end, // 0 for null terminated MBCS
+ std::string & target,
+ system::error_code & ec )
+ {
+ ec.clear();
+ target.assign( begin, end ); // but what if this throws bad_alloc?
+ }
+
+ inline void convert_append( const char * begin, std::string & target,
+ system::error_code & ec )
+ {
+ ec.clear();
+ target += begin; // but what if throws bad_alloc?
+ }
+
+# ifndef BOOST_FILESYSTEM_NARROW_ONLY
+
+ // ----- wchar_t[] to string -----
+
+ inline void convert_append( const wchar_t * begin, const wchar_t * end,
+ std::string & target, system::error_code & ec );
+
+ inline void convert_append( const wchar_t * begin, std::string & target,
+ system::error_code & ec )
+ {
+ convert_append( begin, 0, target, ec );
+ }
+
+ // ----- convert ----
+
+ BOOST_FILESYSTEM_DECL
+ std::wstring convert( const std::string & src, system::error_code & ec );
+
+# endif
+
+# endif // BOOST_POSIX_API
+
+ // helpers ---------------------------------------------------------------//
+
+ inline bool is_separator( value_type c )
+ {
+ return c == separator
+# ifdef BOOST_WINDOWS_PATH
+ || c == L'\\'
+# endif
+ ;
+ }
+
+ // These helpers factor out common code, convert iterators to pointers,
+ // and add the locale. Thus they reduce the number of detail::convert_append
+ // overloads required.
+
+ template< class InputIterator >
+ inline void convert_append_helper( InputIterator begin,
+ string_type & target, system::error_code & ec )
+ {
+ BOOST_ASSERT( &*begin );
+ convert_append( &*begin, target, ec );
+ }
+
+ template< class FowardIterator >
+ inline void convert_append_helper( FowardIterator begin, FowardIterator end,
+ string_type & target, system::error_code & ec )
+ {
+ if ( begin == end ) return;
+ BOOST_ASSERT( &*begin );
+ convert_append( &*begin,
+ &*begin + std::distance( begin, end ), // avoid dereference of end iterator
+ target, ec );
+ }
+
+ BOOST_FILESYSTEM_DECL
+ void first_element(
+ const string_type & src,
+ size_type & element_pos,
+ size_type & element_size,
+ # if !BOOST_WORKAROUND( BOOST_MSVC, <= 1310 ) // VC++ 7.1
+ size_type size = string_type::npos
+ # else
+ size_type size = -1
+ # endif
+ );
+
+ BOOST_FILESYSTEM_DECL
+ bool is_non_root_separator( const string_type & str, size_type pos );
+ // pos is position of the separator
+
+ BOOST_FILESYSTEM_DECL
+ size_type filename_pos( const string_type & str,
+ size_type end_pos ); // end_pos is past-the-end position
+ // Returns: 0 if str itself is filename (or empty)
+
+ BOOST_FILESYSTEM_DECL
+ size_type root_directory_start( const string_type & path, size_type size );
+ // Returns: npos if no root_directory found
+
+} // namespace detail
+
+ //--------------------------------------------------------------------------//
+ // //
+ // traits and conversions //
+ // //
+ // users are permitted to add specializations for user defined types // //
+ // //
+ //--------------------------------------------------------------------------//
+
+ template< class T > struct pathable_iterator { static const bool value = false; };
+ template<> struct pathable_iterator<const char *> { static const bool value = true; };
+ template<> struct pathable_iterator<char *> { static const bool value = true; };
+ template<> struct pathable_iterator<std::string::iterator> { static const bool value = true; };
+ template<> struct pathable_iterator<std::string::const_iterator> { static const bool value = true; };
+
+ template< class T > struct pathable_container { static const bool value = false; };
+ template<> struct pathable_container<std::string> { static const bool value = true; };
+
+# ifndef BOOST_FILESYSTEM_NARROW_ONLY
+ template<> struct pathable_iterator<const wchar_t *> { static const bool value = true; };
+ template<> struct pathable_iterator<wchar_t *> { static const bool value = true; };
+ template<> struct pathable_iterator<std::wstring::iterator> { static const bool value = true; };
+ template<> struct pathable_iterator<std::wstring::const_iterator> { static const bool value = true; };
+
+ template<> struct pathable_container<std::wstring> { static const bool value = true; };
+# endif
+
+ template< class T >
+ T convert( const detail::string_type & src, system::error_code & ec );
+
+# ifdef BOOST_WINDOWS_API
+ template<> inline std::string convert<std::string>( const std::wstring & s, system::error_code & ec )
+ { return detail::convert( s, ec ); }
+ template<> inline std::wstring convert<std::wstring>( const std::wstring & s, system::error_code & ec )
+ { return s; }
+# endif
+
+ //--------------------------------------------------------------------------//
+ // //
+ // class path //
+ // //
+ //--------------------------------------------------------------------------//
+
+ class BOOST_FILESYSTEM_DECL path
+ {
+ public:
+
+ // string_type is the std::basic_string type corresponding to the character
+ // type for paths used by the native operating system API.
+ //
+ // Thus string_type is std::string for POSIX and std::wstring for Windows.
+ // value_type is char for POSIX and wchar_t for Windows.
+
+ typedef detail::string_type string_type;
+ typedef string_type::value_type value_type;
+ typedef string_type::size_type size_type;
+
+ // ----- character encoding conversions -----
+
+ // Following the principle of least astonishment, path input arguments
+ // passed to or obtained from the operating system via objects of
+ // class path behave as if they were directly passed to or
+ // obtained from the O/S API, unless conversion is explicitly requested.
+ //
+ // POSIX specfies that path strings are passed unchanged to and from the
+ // API. Note that this is different from the POSIX command line utilities,
+ // which convert according to a locale.
+ //
+ // Thus for POSIX, char strings do not undergo conversion. wchar_t strings
+ // are converted to/from char using the path locale or, if a conversion
+ // argument is given, using a conversion object modeled on
+ // std::wstring_convert.
+ //
+ // The path locale, which is global to the thread, can be changed by the
+ // imbue() function. It is initialized to an implementation defined locale.
+ //
+ // For Windows, wchar_t strings do not undergo conversion. char strings
+ // are converted using the "ANSI" or "OEM" code pages, as determined by
+ // the AreFileApisANSI() function, or, if a conversion argument is given,
+ // using a conversion object modeled on std::wstring_convert.
+ //
+ // See m_path comments for further important rationale.
+
+ // Design alternative; each function can have an additional overload that
+ // supplies a conversion locale. For example:
+ //
+ // template< class ForwardIterator, class WStringConvert >
+ // path( ForwardIterator begin, ForwardIterator end,
+ // const std::locale & loc,
+ // system::error_code & ec = system::throws );
+ //
+ // This alternative was rejected as too complex for the limited benefits;
+ // it nearly doubles the size of the interface, and adds a lot of
+ // implementation and test code, yet would likely be rarely used. The same
+ // effect can be achieved via the much simpler imbue() mechanism.
+
+
+ // TODO: rules needed for operating systems that use / or .
+ // differently, or format directory paths differently from file paths.
+ //
+ // ************************************************************************
+ //
+ // More work needed: How to handle an operating system that may have
+ // slash characters or dot characters in valid filenames, either because
+ // it doesn't follow the POSIX standard, or because it allows MBCS
+ // filename encodings that may contain slash or dot characters. For
+ // example, ISO/IEC 2022 (JIS) encoding which allows switching to
+ // JIS x0208-1983 encoding. A valid filename in this set of encodings is
+ // 0x1B 0x24 0x42 [switch to X0208-1983] 0x24 0x2F [U+304F Kiragana letter KU]
+ // ^^^^
+ // Note that 0x2F is the ASCII slash character
+ //
+ // ************************************************************************
+
+ // ----- constructors -----
+
+ path(){} // #1
+
+ path( const path & p ) : m_path(p.m_path) {} // #2
+
+ // construct from null terminated sequence
+
+ template< class InputIterator >
+ path( InputIterator begin,
+ system::error_code & ec = system::throws,
+ typename boost::enable_if<pathable_iterator<InputIterator> >::type* dummy=0 ) // #3
+ { detail::convert_append_helper( begin, m_path, ec ); }
+
+ // construct from (potentially) multi-byte character string, which may have
+ // embedded nulls. Embedded null support is required for some Asian languages on
+ // Windows.
+
+ template< class ForwardIterator >
+ path( ForwardIterator begin, ForwardIterator end,
+ system::error_code & ec = system::throws ) // #4
+ { detail::convert_append_helper( begin, end, m_path, ec ); }
+
+ // construct from container of (potentially) multi-byte character string,
+ // which may have embedded nulls. Embedded null support is required for
+ // some Asian languages on Windows.
+
+ template< class Container >
+ path( const Container & ctr,
+ system::error_code & ec = system::throws,
+ typename boost::enable_if<pathable_container<Container> >::type* dummy=0 ) // #5
+ { detail::convert_append_helper( ctr.begin(), ctr.end(), m_path, ec ); }
+
+
+ // ----- assignments -----
+
+ path & operator=( const path & p ) // #1
+ {
+ m_path = p.m_path;
+ return *this;
+ }
+
+ template< class InputIterator >
+ typename boost::enable_if<pathable_iterator<InputIterator>, path &>::type
+ operator=( InputIterator begin ) // #2
+ {
+ m_path.clear();
+ detail::convert_append_helper( begin, m_path, system::throws );
+ return *this;
+ }
+
+ template< class InputIterator >
+ typename boost::enable_if<pathable_iterator<InputIterator>, path &>::type
+ assign( InputIterator begin,
+ system::error_code & ec = system::throws ) // #3
+ {
+ m_path.clear();
+ detail::convert_append_helper( begin, m_path, ec );
+ return *this;
+ }
+
+ template< class FowardIterator >
+ path & assign( FowardIterator begin, FowardIterator end,
+ system::error_code & ec = system::throws ) // #4
+ {
+ m_path.clear();
+ detail::convert_append_helper( begin, end, m_path, ec );
+ return *this;
+ }
+
+ template< class Container >
+ typename boost::enable_if<pathable_container<Container>, path &>::type
+ operator=( const Container & ctr ) // #5
+ {
+ m_path.clear();
+ detail::convert_append_helper( ctr.begin(), ctr.end(), m_path, system::throws );
+ return *this;
+ }
+
+ template< class Container >
+ typename boost::enable_if<pathable_container<Container>, path &>::type
+ assign( const Container & ctr,
+ system::error_code & ec = system::throws ) // #6
+ {
+ m_path.clear();
+ detail::convert_append_helper( ctr.begin(), ctr.end(), m_path, ec );
+ return *this;
+ }
+
+ // ----- appends -----
+
+ path & operator/=( const path & p ) // #1
+ {
+ append_separator_if_needed_();
+ m_path += p.m_path;
+ return *this;
+ }
+
+ template< class InputIterator >
+ typename boost::enable_if<pathable_iterator<InputIterator>, path &>::type
+ operator/=( InputIterator begin ) // #2
+ {
+ append_separator_if_needed_();
+ detail::convert_append_helper( begin, m_path, system::throws );
+ return *this;
+ }
+
+ template< class InputIterator >
+ typename boost::enable_if<pathable_iterator<InputIterator>, path &>::type
+ append( InputIterator begin,
+ system::error_code & ec = system::throws ) // #3
+ {
+ append_separator_if_needed_();
+ detail::convert_append_helper( begin, m_path, ec );
+ return *this;
+ }
+
+ template< class FowardIterator >
+ path & append( FowardIterator begin, FowardIterator end,
+ system::error_code & ec = system::throws ) // #4
+ {
+ append_separator_if_needed_();
+ detail::convert_append_helper( begin, end, m_path, ec );
+ return *this;
+ }
+
+ template< class Container >
+ typename boost::enable_if<pathable_container<Container>, path &>::type
+ operator/=( const Container & ctr ) // #5
+ {
+ append_separator_if_needed_();
+ detail::convert_append_helper( ctr.begin(), ctr.end(), m_path, system::throws );
+ return *this;
+ }
+
+ template< class Container >
+ typename boost::enable_if<pathable_container<Container>, path &>::type
+ append( const Container & ctr,
+ system::error_code & ec = system::throws ) // #6
+ {
+ append_separator_if_needed_();
+ detail::convert_append_helper( ctr.begin(), ctr.end(), m_path, ec );
+ return *this;
+ }
+
+ // ----- modifiers -----
+
+ void clear() { m_path.clear(); }
+
+ void swap( path & rhs )
+ {
+ m_path.swap( rhs.m_path );
+# ifdef BOOST_CYGWIN_PATH
+ std::swap( m_cygwin_root, rhs.m_cygwin_root );
+# endif
+ }
+
+ path & remove_filename()
+ {
+ m_path.erase(
+ detail::filename_pos( m_path, m_path.size() ) );
+ return *this;
+ }
+
+ // ----- conversion operators -----
+
+ // return formatted "as input"
+
+# ifdef BOOST_WINDOWS_API
+
+ operator const std::string() const { return detail::convert( m_path, system::throws ); }
+ operator const std::wstring&() const { return m_path; }
+
+# else // BOOST_POSIX_API
+
+ operator const std::string&() const { return m_path; }
+# ifndef BOOST_FILESYSTEM_NARROW_ONLY
+ operator const std::wstring() const { return detail::convert( m_path, system::throws ); }
+# endif
+
+# endif
+
+ // ----- observers -----
+
+ // For operating systems that format file paths differently than directory
+ // paths, returns from observers are formatted as file names unless there
+ // is a trailing separator, in which case returns are formatted as directory
+ // paths. POSIX and Windows make no such distinction.
+
+ // Implementations are permitted to return const values or const references.
+
+ template< class T >
+ T string( system::error_code & ec = system::throws ) const
+ { return convert<T>( m_path, ec ); }
+
+# ifdef BOOST_WINDOWS_API
+
+ // return formatted "as input"
+ const std::string string( system::error_code & ec = system::throws ) const { return detail::convert( m_path, ec ); }
+ const std::wstring & wstring() const { return m_path; }
+ const std::wstring & wstring( system::error_code & ec ) const { ec.clear(); return m_path; }
+
+# else // BOOST_POSIX_API
+
+ // return formatted "as input"
+ const std::string & string() const { return m_path; }
+ const std::string & string( system::error_code & ec ) const { ec.clear(); return m_path; }
+# ifndef BOOST_FILESYSTEM_NARROW_ONLY
+ const std::wstring wstring( system::error_code & ec = system::throws ) const { return detail::convert( m_path, ec ); }
+# endif
+# endif
+
+
+ // return formatted as indicated by function name
+# ifdef BOOST_WINDOWS_PATH
+
+ const path native() const;
+ const path generic() const;
+
+# else // BOOST_POSIX_PATH
+
+ const path native() const { return m_path; }
+ const path generic() const { return m_path; }
+
+# endif
+
+ const value_type * c_str() const { return m_path.c_str(); } // native format
+
+ // ----- decomposition -----
+
+ path root_path() const;
+ path root_name() const; // returns 0 or 1 element path
+ // even on POSIX, root_name() is non-empty() for network paths
+ path root_directory() const; // returns 0 or 1 element path
+ path relative_path() const;
+ path parent_path() const;
+ path filename() const; // returns 0 or 1 element path
+ path stem() const; // returns 0 or 1 element path
+ path extension() const; // returns 0 or 1 element path
+
+ // ----- query -----
+
+ bool empty() const { return m_path.empty(); } // name consistent with std containers
+ bool has_root_path() const { return has_root_directory() || has_root_name(); }
+ bool has_root_name() const { return !root_name().empty(); }
+ bool has_root_directory() const { return !root_directory().empty(); }
+ bool has_relative_path() const { return !relative_path().empty(); }
+ bool has_filename() const { return !m_path.empty(); }
+ bool has_parent_path() const { return !parent_path().empty(); }
+ bool is_complete() const
+ {
+# ifdef BOOST_WINDOWS_PATH
+ return has_root_name() && has_root_directory();
+# else
+ return has_root_directory();
+# endif
+ }
+
+ // ----- locale -----
+
+ static std::locale imbue( const std::locale & loc )
+ {
+ std::locale tmp;
+ tmp = *detail::path_locale;
+ detail::path_locale = &loc;
+ return tmp;
+ }
+
+ static std::locale getloc() { return *detail::path_locale; }
+
+ // ----- iterators -----
+
+ class iterator;
+ typedef iterator const_iterator;
+
+ iterator begin() const;
+ iterator end() const;
+
+ private:
+
+ // m_path has the type, encoding, and format required by the native
+ // operating system. Thus for POSIX and Windows there is no conversion for
+ // passing m_path.c_str() to the O/S API or when obtaining a path from the
+ // O/S API. POSIX encoding is unspecified other than for dot and slash
+ // characters; POSIX just treats paths as a sequence of bytes. Windows
+ // encoding is UCS-2 or UTF-16 depending on the version.
+
+ string_type m_path; // Windows: backslashes NOT converted to slashes
+
+
+ void append_separator_if_needed_();
+
+ // Was qualified; como433beta8 reports:
+ // warning #427-D: qualified name is not allowed in member declaration
+ friend class iterator;
+ friend bool operator<( const path & lhs, const path & rhs );
+
+ static bool m_path_lex_compare( iterator first1, iterator last1,
+ iterator first2, iterator last2 );
+
+ // see path::iterator::increment/decrement comment below
+ static void m_path_iterator_increment( path::iterator & it );
+ static void m_path_iterator_decrement( path::iterator & it );
+ };
+
+ //--------------------------------------------------------------------------//
+ // //
+ // class path::iterator //
+ // //
+ //--------------------------------------------------------------------------//
+
+ class path::iterator
+ : public boost::iterator_facade<
+ iterator,
+ path const,
+ boost::bidirectional_traversal_tag >
+ {
+ private:
+ friend class boost::iterator_core_access;
+ friend class boost::filesystem::path;
+ friend void m_path_iterator_increment( path::iterator & it );
+ friend void m_path_iterator_decrement( path::iterator & it );
+
+ const path & dereference() const { return m_element; }
+
+ bool equal( const iterator & rhs ) const
+ {
+ return m_path_ptr == rhs.m_path_ptr && m_pos == rhs.m_pos;
+ }
+
+ // iterator_facade derived classes don't seem to like implementations in
+ // separate translation unit dll's, so forward to class path static members
+ void increment() { m_path_iterator_increment( *this ); }
+ void decrement() { m_path_iterator_decrement( *this ); }
+
+ path m_element; // current element
+ const path * m_path_ptr; // path being iterated over
+ string_type::size_type m_pos; // position of name in
+ // m_path_ptr->m_path. The
+ // end() iterator is indicated by
+ // m_pos == m_path_ptr->m_path.size()
+ }; // path::iterator
+
+ //--------------------------------------------------------------------------//
+ // //
+ // non-member functions //
+ // //
+ //--------------------------------------------------------------------------//
+
+ inline bool operator<( const path & lhs, const path & rhs )
+ {
+ // because path iterators yield paths, std::lexicographical_compare
+ // infinately recurses, so use a path aware version
+ return path::m_path_lex_compare(
+ lhs.begin(), lhs.end(), rhs.begin(), rhs.end() );
+ }
+
+ inline bool operator==( const path & lhs, const path & rhs ) { return !(lhs < rhs) && !(rhs < lhs); }
+ inline bool operator!=( const path & lhs, const path & rhs ) { return !(lhs == rhs); }
+ inline bool operator<=( const path & lhs, const path & rhs ) { return !(rhs < lhs); }
+ inline bool operator> ( const path & lhs, const path & rhs ) { return rhs < lhs; }
+ inline bool operator>=( const path & lhs, const path & rhs ) { return !(lhs < rhs); }
+
+ inline void swap( path & lhs, path & rhs ) { lhs.swap( rhs ); }
+
+ inline path operator/( const path & lhs, const path & rhs ) { return path( lhs ) /= rhs; }
+
+ // inserters and extractors
+
+ // templated versions are too aggressive; path_test gets ambiguous overloads
+ // with std::basic_string.
+ //
+ //template < class Ostream >
+ //Ostream & operator<<( Ostream & os, const path & p )
+ //{
+ // os << p.string< std::basic_string<typename Ostream::char_type,
+ // typename Ostream::traits_type > >();
+ // return os;
+ //}
+ //
+ //template < class Istream >
+ //Istream & operator>>( Istream & is, path & p )
+ //{
+ // std::basic_string<typename Istream::char_type,
+ // typename Istream::traits_type > > str;
+ // is >> str;
+ // p = str;
+ // return is;
+ //}
+
+ inline std::ostream & operator<<( std::ostream & os, const path & p )
+ {
+ os << p.string();
+ return os;
+ }
+
+ inline std::wostream & operator<<( std::wostream & os, const path & p )
+ {
+ os << p.wstring();
+ return os;
+ }
+
+ inline std::istream & operator>>( std::istream & is, path & p )
+ {
+ std::string str;
+ is >> str;
+ p = str;
+ return is;
+ }
+
+ inline std::wistream & operator>>( std::wistream & is, path & p )
+ {
+ std::wstring str;
+ is >> str;
+ p = str;
+ return is;
+ }
+ // name_checks
+
+ BOOST_FILESYSTEM_DECL bool portable_posix_name( const std::string & name );
+ BOOST_FILESYSTEM_DECL bool windows_name( const std::string & name );
+ BOOST_FILESYSTEM_DECL bool portable_name( const std::string & name );
+ BOOST_FILESYSTEM_DECL bool portable_directory_name( const std::string & name );
+ BOOST_FILESYSTEM_DECL bool portable_file_name( const std::string & name );
+ BOOST_FILESYSTEM_DECL bool native( const std::string & name );
+
+} // namespace filesystem
+} // namespace boost
+
+#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas
+
+#endif // BOOST_FILESYSTEM_PATH_HPP
Added: sandbox/filesystem-v3/index.html
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/index.html 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,22 @@
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
+<meta name="ProgId" content="FrontPage.Editor.Document">
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
+<title>Filesystem Version 3</title>
+</head>
+
+<body>
+
+<h1>Filesystem Version 3 in the Sandbox</h1>
+<p>To experiment with filesystem.v3:</p>
+<ul>
+ <li>Subversion checkout filesystem-v3 from the sandbox.</li>
+ <li>Subversion export trunk to the same directory.</li>
+</ul>
+
+</body>
+
+</html>
\ No newline at end of file
Added: sandbox/filesystem-v3/libs/filesystem/v3/build/Jamfile.v2
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/build/Jamfile.v2 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,32 @@
+
+# Boost Filesystem Library Build Jamfile
+
+# (C) Copyright Beman Dawes 2002-2006
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or www.boost.org/LICENSE_1_0.txt)
+
+
+# See library home page at http://www.boost.org/libs/filesystem
+
+project boost/filesystem
+ : source-location ../src
+ : usage-requirements # pass these requirement to dependents (i.e. users)
+ <link>shared:<define>BOOST_FILESYSTEM_DYN_LINK=1
+ <link>static:<define>BOOST_FILESYSTEM_STATIC_LINK=1
+ ;
+
+SOURCES =
+ operations path portability utf8_codecvt_facet ;
+
+lib boost_filesystem
+ :
+ $(SOURCES).cpp
+ ../../system/build//boost_system
+ :
+ <link>shared:<define>BOOST_ALL_DYN_LINK=1 # tell source we're building dll's
+ <link>static:<define>BOOST_All_STATIC_LINK=1 # tell source we're building static lib's
+ :
+ :
+ ;
+
+boost-install boost_filesystem ;
\ No newline at end of file
Added: sandbox/filesystem-v3/libs/filesystem/v3/doc/POSIX_filename_encoding.txt
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/doc/POSIX_filename_encoding.txt 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,55 @@
+http://www.linuxfromscratch.org/blfs/view/svn/introduction/locale-issues.html
+
+"The POSIX standard mandates that the filename encoding is the encoding implied by the current LC_CTYPE locale category."
+
+-------
+
+http://mail.nl.linux.org/linux-utf8/2001-02/msg00103.html
+
+From: Markus Kuhn
+
+Tom Tromey wrote on 2001-02-05 00:36 UTC:
+> Kai> IMAO, a *real* filesystem should use some encoding of ISO 10646 -
+> Kai> UTF-8, UTF-16, or UTF-32 are all viable options. The same should
+> Kai> be true for the kernel filename interfaces.
+>
+> I like this, but what should I do right now?
+
+The POSIX kernel file system interface is engraved into stone and
+extremely unlikely to change. File names are arbitrary binary strings,
+with only the '/' and '\0' bytes having any special semantics. You can
+use arbitrary coded character sets on it as long as they do not
+introduce '/' and '\0' bytes spuriously. Writers and readers have to
+somehow agree on what encoding to use and the only really practical way
+is to use the same encoding on all systems that share files. Eventually,
+everyone will be using UTF-8 for file names on POSIX systems. Right now,
+I would recommend users to use only ASCII for filenames, as this is
+already UTF-8 and therefore simplifies migration. Using the ISO 8859,
+JIS, etc. filenames should soon be considered deprecated practice.
+
+> I work on libgcj, the runtime component of gcj, the Java front end to
+> GCC. In libgcj of course we use UCS-2 everywhere, since that is what
+> Java does. Currently, for Unixy systems, we assume that all file
+> names are UTF-8.
+
+The best solution is to assume that the file names are in the
+locale-specific multi-byte encoding. Simply use mbrtowc and wcrtomb to
+convert between Unicode and the locale-dependent multi-byte encoding
+used in file names and text files if the ISO C 99 symbol
+__STDC_ISO_10646__ is defined (which guarantees that wchar_t = UCS). On
+Linux, this has been the case since glibc 2.2.
+
+> (Actually, we do something notably worse, which is
+> assume that file names are Java-style UTF-8, with the weird encoding
+> for \u0000.)
+
+\u0000 = NUL was never a character allowed in filenames under POSIX.
+Raise an exception if someone tries to use it in a filename. Problem
+solved.
+
+I never understood, why Java found it necessary to introduce two
+distinct ASCII NUL characters.
+
+------
+
+Interesting idea. Use iconv to create shift-jis or other mbcs test cases.
Added: sandbox/filesystem-v3/libs/filesystem/v3/doc/boost.png
==============================================================================
Binary file. No diff available.
Added: sandbox/filesystem-v3/libs/filesystem/v3/doc/minimal.css
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/doc/minimal.css 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,29 @@
+/*
+
+ © Copyright Beman Dawes, 2007
+
+ Distributed under the Boost Software License, Version 1.0.
+ See www.boost.org/LICENSE_1_0.txt
+
+*/
+
+/*******************************************************************************
+ Body
+*******************************************************************************/
+
+body { font-family: sans-serif; margin: 1em; }
+
+/*******************************************************************************
+ Table
+*******************************************************************************/
+
+table { margin: 0.5em; }
+
+/*******************************************************************************
+ Font sizes
+*******************************************************************************/
+
+p, td, li, blockquote { font-size: 10pt; }
+pre { font-size: 9pt; }
+
+/*** end ***/
\ No newline at end of file
Added: sandbox/filesystem-v3/libs/filesystem/v3/doc/reference.html
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/doc/reference.html 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,3079 @@
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
+<meta name="ProgId" content="FrontPage.Editor.Document">
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
+<title>Filesystem Reference
+</title>
+<link rel="stylesheet" type="text/css" href="../../../doc/html/minimal.css">
+</head>
+
+<body>
+
+<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="710">
+ <tr>
+ <td width="277">
+<a href="../../../index.htm">
+<img src="../../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86" border="0"></a></td>
+ <td width="410" align="middle">
+ <font size="7">Filesystem Library</font>
+ </td>
+ </tr>
+</table>
+
+<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="100%">
+ <tr>
+ <td>Boost Home
+ Library Home
+ Tutorial <a href="reference.html">
+ Reference</a> FAQ</td>
+ </tr>
+</table>
+
+<h1>Reference Documentation</h1>
+
+<h2><a name="TOC">Table of Contents</a></h2>
+
+<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%">
+ <tr>
+ <td width="26%" valign="top">Introduction<br>
+ Definitions<br>
+ Requirements<br>
+
+Requirements on programs<br>
+ Requirementson implementations<br>
+ <a href="#Header-filesystem-synopsis">
+ Header <filesystem> synopsis</a><br>
+ Path traits<br>
+ <a href="#Class-template-basic_path">
+ Class template basic_path</a><br>
+
+Pathname formats<br>
+
+Pathname grammar<br>
+
+Filename conversion<br>
+
+Requirements </td>
+ <td width="35%" valign="top"> Class template basic_path (continued)<br>
+
+basic_path constructors<br>
+
+basic_path assignments<br>
+
+basic_path modifiers<br>
+
+basic_path operators<br>
+
+basic_path observers<br>
+
+basic_path iterators<br>
+
+basic_path non-member functions<br>
+
+basic_path inserter and extractor<span style="background-color: #FFFFFF"><br>
+</span>
+<a href="#Class-template-basic_filesystem_error">Class template
+ basic_filesystem_error</a><br>
+
+<a href="#basic_filesystem_error-constructors">basic_filesystem_error
+ constructors</a><br>
+
+basic_filesystem_error observers<br>
+
+<a href="#Class-template-basic_directory_entry">Class template
+ basic_directory_entry</a><br>
+
+basic_directory_entry constructors<br>
+
+basic_directory_entry modifiers<br>
+
+basic_directory_entry observers<br>
+
+basic_directory_entry comparisons</td>
+ <td width="89%" valign="top">Filesystem library chapter (continued)<br>
+
+<a href="#Class-template-basic_directory_iterator">Class template
+ basic_directory_iterator</a><br>
+
+<a href="#basic_directory_iterator-constructors">basic_directory_iterator
+ constructors</a><br>
+
+<a href="#Class-template-basic_recursive_directory_iterator">Class template
+ basic_recursive_directory_iterator</a><br>
+ <a href="#file_status">Class
+ file_status</a><br>
+ <a href="#Non-member-functions">
+ Non-member operational functions</a><br>
+
+Status functions<br>
+
+Predicate functions<br>
+
+Attribute functions<br>
+
+Other operations functions<br>
+
+Convenience functions<br>
+ <a href="#header-fstream">Additions
+ to header <fstream></a><br>
+Suggestions for <fstream>
<code><br>
+ </code>
+ implementations<br>
+Path decomposition table<br>
+Acknowledgements<br>
+References<br>
+ </td>
+ </tr>
+</table>
+
+<h2><a name="Introduction">Introduction</a></h2>
+<p>Some library behavior is specified by reference to ISO/IEC 9945:2003, <i>
+POSIX</i>. How such behavior is actually implemented is unspecified.</p>
+<blockquote>
+<p>[<i>Note:</i> This constitutes an "as if" rule for implementation of
+operating system dependent behavior. Presumably implementations will usually call native
+operating system API's. <i>--end note</i>]</p>
+</blockquote>
+<p>Implementations are encouraged, but not required, to support such behavior
+
+as it is defined by <i>POSIX</i>. Implementations shall document any
+behavior that differs from the <i>POSIX</i> defined behavior. Implementations that do not support exact <i>POSIX</i> behavior are
+encouraged to provide behavior as close to <i>POSIX</i> behavior as is reasonable given the
+limitations of actual operating systems and file systems. If an implementation cannot provide any
+reasonable behavior, the implementation shall report an error in an
+implementation-defined manner.</p>
+<blockquote>
+<p>[<i>Note:</i> Such errors might be reported by an #error directive, a <code>
+static_assert</code>, a <code>basic_filesystem_error</code> exception, a special
+return value, or some other manner. <i>--end note</i>]</p>
+</blockquote>
+<p>Specific operating systems such as <i>OpenMVS</i>,
+<i>UNIX</i>, and <i>Windows</i> are mentioned only for purposes of illustration or to
+give guidance to implementors. No slight to other operating systems is implied
+or intended.</p>
+<p>The <i>Effects</i> and <i>Postconditions</i> of functions described in this
+reference
+may not be achieved in
+the presence of race conditions. No diagnostic is required.</p>
+<p>If the possibility of race conditions makes it unreliable for a program to
+test for a precondition before calling a function described in this clause, <i>
+Requires</i> is not specified for the condition. Instead, the condition is
+specified as a <i>Throws</i> condition.</p>
+<blockquote>
+<p>[<i>Note:</i> As a design practice, preconditions are not specified when it
+is unreasonable for a program to detect them prior to calling the function. <i>
+-- end note</i>]</p>
+</blockquote>
+<h3><a name="Definitions">Definitions</a></h3>
+<p>The following definitions apply throughout this reference documentation:</p>
+<p><i><a name="File">File</a>: </i>An object that can be written to, or read from, or both. A file
+has certain attributes, including type. File types include regular file,
+symbolic link, and directory. Other types of files may be supported by the
+implementation.</p>
+<p><i><a name="File-system">File system</a>:</i> A collection of files and certain of their attributes.</p>
+<p><i><a name="Filename">Filename</a>:</i> The name of a file. The format is as
+specified by the <i>POSIX
+<a href="http://www.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap03.html#tag_03_169">
+Filename</a></i> base definition.</p>
+<p><i><a name="Path">Path</a>:</i> A sequence of elements which identify
+a location within a filesystem. The elements are the <i>root-name</i>, <i>
+root-directory</i>, and each successive <i>filename</i>. See
+Pathname grammar.</p>
+<p><i><a name="Pathname">Pathname</a>: </i>A character string that represents a
+path.</p>
+<p><i><a name="Link">Link</a>: </i>A directory entry object that associates a
+filename with a file. On some file systems, several directory entries can
+associate names with the same file.</p>
+<p><i><a name="Hard-link">Hard link</a>:</i> A link to an existing file. Some
+file systems support multiple hard links to a file. If the last hard link to a
+file is removed, the file itself is removed.</p>
+<blockquote>
+<p>[<i>Note:</i> A hard link can be thought of as a shared-ownership smart
+pointer to a file.<i> -- end note</i>]<i> </i></p>
+</blockquote>
+<p><i><a name="Symbolic-link">Symbolic link</a>: </i>A type of file with the
+property that when the file is encountered during pathname resolution, a string
+stored by the file is used to modify the pathname resolution.</p>
+<blockquote>
+<p>[<i>Note:</i> A symbolic link can be thought of as a raw pointer to a file.
+If the file pointed to does not exist, the symbolic link is said to be a
+"dangling" symbolic link.<i> -- end note</i>]<i> </i></p>
+</blockquote>
+<p><i><a name="Slash">Slash</a>:</i> The character <tt>'/'</tt>, also known as
+solidus.</p>
+<p><i><a name="Dot">Dot</a>:</i> The character '.', also known as period.</p>
+<p><i><a name="Race-condition">Race condition</a>:</i> The condition that occurs
+when multiple threads, processes, or computers interleave access and
+modification of
+the same object within a file system.</p>
+<h3><a name="Requirements">Requirements</a></h3>
+<h4><a name="Requirements-on-programs">Requirements on programs</a></h4>
+<p>The arguments for template parameters named <code>Path</code>, <code>Path1</code>,
+or <code>Path2</code> described in this clause shall be of type <code>basic_path</code>,
+or a class derived from <code>basic_path</code>, unless otherwise
+specified.</p>
+<h4><a name="Requirements-on-implementations">Requirements on implementations</a></h4>
+<p>Some function templates described in this clause have a template parameter
+named <code>Path</code>, <code>Path1</code>, or <code>Path2</code>. When called
+with a function argument <code>s</code> of type <code>char*</code> or <code>
+std::string</code>, the implementation shall treat the argument as if it were
+coded <code>path(s)</code>. When called with a function argument <code>s</code>
+of type <code>wchar_t*</code> or <code>std::wstring</code>, the implementation
+shall treat the argument as if it were coded <code>wpath(s)</code>. For
+functions with two arguments, implementations shall not supply this treatment
+when <code>Path1</code> and <code>Path2</code> are different types.</p>
+<blockquote>
+<p>[<i>Note:</i> This "do-the-right-thing" rule allows users to write <code>exists("foo")</code>,
+taking advantage of class <code>basic_path</code>'s string conversion
+constructor, rather
+than the lengthier and more error prone <code>exists(path("foo"))</code>. This
+is particularly important for the simple, script-like, programs which are an
+important use case for the library. Calling two argument functions with
+different types is a very rare usage, and may well be a coding error, so
+automatic conversion is not supported for such cases.</p>
+<p>The implementation technique is unspecified. One possible implementation
+technique, using
+<code>exists()</code> as an example, is:</p>
+ <blockquote>
+ <pre>template <class Path>
+ typename boost::enable_if<is_basic_path<Path>,bool>::type exists(const Path& p);
+inline bool exists(const path& p) { return exists<path>(p); }
+inline bool exists(const wpath& p) { return exists<wpath>(p); }</pre>
+ </blockquote>
+ <p> The <code>enable_if</code> will fail for a C string or <code>
+ std::basic_string</code> argument, which will then be automatically converted
+ to a <code>basic_path</code> object via the appropriate <code>basic_path</code> conversion
+ constructor. <i>-- end note</i>]</p>
+ <p><span style="background-color: #E0E0E0"><i>The two overloads are not given
+ in the normative text because:</i></span></p>
+ <ul>
+ <li><span style="background-color: #E0E0E0"><i>Better techniques for
+ achieving the desired affect may be developed, perhaps enabled by core
+ language changes like Concepts.</i></span></li>
+ <li><span style="background-color: #E0E0E0"><i>Implementations may prefer
+ techniques that work with legacy compilers that do not support enable_if.</i></span></li>
+ <li><span style="background-color: #E0E0E0"><i>Spelling out the overloads
+ makes the text longer and harder to read without adding much benefit.</i></span></li>
+ <li><span style="background-color: #E0E0E0"><i>More overloads will probably
+ be needed for char16_t and char32_t (or whatever they end up being called),
+ making it even less attractive to actually spell out each one. </i></span>
+ </li>
+ </ul>
+</blockquote>
+<p>Implementations of functions described in this clause are permitted to call the applications
+program interface (API) provided by the operating system. If such an operating
+system API call results in an error, implementations
+shall report the error by throwing exception <code>basic_filesystem_error</code>,
+unless otherwise specified.</p>
+<blockquote>
+<p>[<i>Note: </i>Such exceptions and the conditions that cause them to be thrown
+are not explicitly described in each <i>Throws</i> element within this clause.
+Because hardware failures, network failures, race conditions, and a plethora of
+other errors occur frequently in file system operations, users should be aware
+that <span style="background-color: #FFFFFF">unless otherwise specified</span> any file system operation, not matter how apparently innocuous, may throw
+an exception. <i>-- end note</i>]</p>
+</blockquote>
+<p><span style="background-color: #FFFFFF">Functions commonly used in contexts
+where errors are not exceptional have overloads taking an additional argument of
+type </span><code><span style="background-color: #FFFFFF">error_code& ec</span></code><span style="background-color: #FFFFFF">. Such overloaded functions shall not throw exceptions. If an error occurs,
+<code>ec</code> shall be set to the
+error code reported by the operating system, otherwise <code>ec</code> shall be set to 0. If
+an overload without an argument of type </span><code>
+<span style="background-color: #FFFFFF">error_code& ec</span></code><span style="background-color: #FFFFFF"> returns void, the other overload (with an argument of type </span><code>
+<span style="background-color: #FFFFFF">error_code& ec</span></code><span style="background-color: #FFFFFF">) returns an <code>
+error_code</code> with the value of ec.</span></p>
+<h3><a name="Header-filesystem-synopsis">Header <code><boost/filesystem></code> synopsis</a></h3>
+<pre> namespace boost
+ {
+ namespace filesystem
+ {
+ template <class String, class Traits> class basic_path;
+
+ template<class String, class Traits>
+ void swap(basic_path<String, Traits> & lhs, basic_path<String, Traits> & rhs);
+
+ template<class String, class Traits> bool operator<(<i>a</i> a, <i>b</i> b);
+ template<class String, class Traits> bool operator==(<i>a</i> a, <i>b</i> b);
+ template<class String, class Traits> bool operator!=(<i>a</i> a, <i>b</i> b);
+ template<class String, class Traits> bool operator>(<i>a</i> a, <i>b</i> b);
+ template<class String, class Traits> bool operator<=(<i>a</i> a, <i>b</i> b);
+ template<class String, class Traits> bool operator>=(<i>a</i> a, <i>b</i> b);
+ template<class String, class Traits> bool operator/(<i>a</i> a, <i>b</i> b);
+
+ template<class Path>
+ basic_ostream<typename Path::string_type::value_type, typename Path::string_type::traits_type> &
+ operator<<(basic_ostream<typename Path::string_type::value_type, typename Path::string_type::traits_type>& os, const Path & ph);
+
+ template<class Path>
+ basic_istream<typename Path::string_type::value_type, typename Path::string_type::traits_type> &
+ operator>>(basic_istream<typename Path::string_type::value_type, typename Path::string_type::traits_type>& is, Path & ph);
+
+ struct path_traits;
+ struct wpath_traits;
+
+ typedef basic_path<std::string, path_traits> path;
+ typedef basic_path<std::wstring, wpath_traits> wpath;
+
+ template<class Path> struct is_basic_path;
+
+ template<class Path> struct slash { static const char value = '/'; };
+ template<class Path> struct dot { static const char value = '.'; };
+<span style="background-color: #FFFFFF"> template<class Path> struct colon { static const char value = ':'; };</span><span style="background-color: #FFFF00">
+</span>
+ <span style="background-color: #FFFFFF">class filesystem_error;</span><span style="background-color: #FFFF00">
+</span>
+ template <class Path> class basic_filesystem_error;
+
+ typedef basic_filesystem_error<path> filesystem_error;
+ typedef basic_filesystem_error<wpath> wfilesystem_error;
+
+ <span style="background-color: #FFFFFF">template <class Path> class basic_directory_entry;
+
+ typedef basic_directory_entry<path> directory_entry;
+ typedef basic_directory_entry<wpath> wdirectory_entry;
+</span>
+ template <class Path> class basic_directory_iterator;
+
+ typedef basic_directory_iterator<path> directory_iterator;
+ typedef basic_directory_iterator<wpath> wdirectory_iterator;
+
+ template <class Path> class basic_recursive_directory_iterator;
+
+ typedef basic_recursive_directory_iterator<path> <a name="recursive_directory_iterator">recursive_directory_iterator</a>;
+ typedef basic_recursive_directory_iterator<wpath> wrecursive_directory_iterator;
+
+ enum file_type { status_unknown, file_not_found, regular_file, directory_file,
+ symlink_file, block_file, character_file, fifo_file, socket_file,
+ type_unknown
+ };
+
+ class file_status;
+
+ <span style="background-color: #FFFFFF">struct space_info // returned by </span>space<span style="background-color: #FFFFFF"> function
+ {
+ uintmax_t capacity;
+ uintmax_t free;
+ uintmax_t available;
+ };
+</span>
+ // status functions
+ template <class Path> file_status status(const Path& p);
+ template <class Path> file_status status(const Path& p, error_code& ec);
+ template <class Path> file_status symlink_status(const Path& p);
+ template <class Path> file_status symlink_status(const Path& p, error_code& ec);
+
+ // predicate functions
+ bool status_known( file_status s );
+ bool exists( file_status s );
+ bool is_regular_file( file_status s );
+ bool is_directory( file_status s );
+ bool is_symlink( file_status s );
+ bool is_other( file_status s );
+
+ template <class Path> bool exists(const Path& p);
+ template <class Path> bool is_directory(const Path& p);
+ template <class Path> bool is_regular_file(const Path& p);
+ template <class Path> bool is_other(const Path& p);
+ template <class Path> bool is_symlink(const Path& p);
+ template <class Path> bool is_empty(const Path& p);
+
+ template <class Path1, class Path2>
+ bool equivalent(const Path1& p1, const Path2& p2);
+
+ // attribute functions
+ template <class Path> Path current_path();
+ template <class Path> void current_path(const Path& p);
+ template <class Path> const Path& initial_path();
+ template <class Path> <span style="background-color: #FFFFFF; ">uintmax_t</span> file_size(const Path& p);
+<span style="background-color: #FFFFFF"> template <class Path> space_info space(const Path& p);</span><span style="background-color: #FFFF00">
+</span> template <class Path> std::time_t last_write_time(const Path& p);
+ template <class Path>
+ void last_write_time(const Path& p, const std::time_t new_time);
+
+ // operations functions
+ template <class Path> bool create_directory(const Path& dp);
+ template <class Path1, class Path2>
+ void create_hard_link(const Path1& old_fp, const Path2& new_fp);
+<span style="background-color: #FFFFFF"> template <class Path1, class Path2>
+ error_code create_hard_link(const Path1& old_fp, const Path2& new_fp, error_code& ec);
+ template <class Path1, class Path2>
+ void create_symlink(const Path1& old_fp, const Path2& new_fp);
+ template <class Path1, class Path2>
+ error_code create_symlink(const Path1& old_fp, const Path2& new_fp, error_code& ec);
+</span> template <class Path> bool remove(const Path& p);
+ template <class Path1, class Path2>
+ void rename(const Path1& from_p, const Path2& to_p);
+ template <class Path1, class Path2>
+ void copy_file(const Path1& from_fp, const Path2& to_fp);
+ template <class Path> Path system_complete(const Path& p);
+ template <class Path> Path complete(const Path& p, const Path& base=initial_path<Path>());
+
+ // convenience functions
+ template <class Path> bool create_directories(const Path& p);
+ template <class Path> typename Path::string_type extension(const Path& p);
+ template <class Path> typename Path::string_type basename(const Path& p);
+ template <class Path>
+ Path change_extension(const Path& p, const typename Path::string_type& new_extension);
+
+ } // namespace filesystem
+ } // namespace boost</pre>
+<h3><a name="Path-traits">Path traits</a></h3>
+<p>This subclause defines requirements on classes representing path behavior
+traits, and defines two classes that satisfy those requirements for paths based
+on <code>string</code> and <code>wstring</code>.. It also defines several path
+additional path traits structure templates, and defines several specializations
+of them.</p>
+<p>Class template <code>basic_path</code> defined in this clause requires additional
+types, values, and behavior to complete the definition of its semantics.</p>
+<p>For purposes of exposition, Traits behaves as if it is a class with private
+members bool m_locked, initialized false, and std::locale m_locale, initialized </p>
+<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%">
+ <tr>
+ <td width="50%" align="center" colspan="2"><b><i>
+ <a name="Path-Behavior-Traits-Requirements">Path Behavior Traits
+ Requirements</a></i></b></td>
+ </tr>
+ <tr>
+ <td width="38%" align="center"><b><i>Expression</i></b></td>
+ <td width="62%" align="center"><b><i>Requirements</i></b></td>
+ </tr>
+ <tr>
+ <td width="38%" valign="top"><code>Traits::external_string_type</code></td>
+ <td width="62%">A typedef which is a specialization of <code>basic_string</code>.
+ The <code>value_type</code> is a character type used by the operating system
+ to represent pathnames.</td>
+ </tr>
+ <tr>
+ <td width="38%" valign="top"><code>Traits::internal_string_type</code></td>
+ <td width="62%">A typedef which is a specialization of <code>basic_string</code>.
+ The <code>value_type</code> is a character type to be used by the program to
+ represent pathnames. Required be the same type as the <code>basic_path
+ String</code> template parameter. </td>
+ </tr>
+ <tr>
+ <td width="38%" valign="top"><code>Traits::to_external( p, is )</code></td>
+ <td width="62%"><code>is</code>, converted by the <code>m_locale</code>
+ <code>codecvt</code> facet to <code>external_string_type</code>.</td>
+ </tr>
+ <tr>
+ <td width="38%" valign="top"><code>Traits::to_internal( p, xs )</code></td>
+ <td width="62%"><code>xs</code>, converted by the <code>m_locale</code>
+ <code>codecvt</code> facet to to <code>internal_string_type</code>.</td>
+ </tr>
+ <tr>
+ <td width="38%" valign="top"><code>Traits::imbue(loc)</code></td>
+ <td width="62%"><i>Effects:</i> if <code>m_locked</code>, throw. Otherwise,
+ <code>m_locked = true; m_locale = loc;<br>
+ </code><i>Returns:</i> <code>void</code><b><br>
+ </b><i>Throws:</i> <code>basic_filesystem_error</code></td>
+ </tr>
+ <tr>
+ <td width="38%" valign="top"><code>Traits::imbue(loc, std::nothrow)</code></td>
+ <td width="62%"><i>Effects:</i> <code>if (!m_locked) m_locale = loc; bool
+ temp(m_locked); m_locked = true;<br>
+ </code><i>Returns:</i> <code>temp</code></td>
+ </tr>
+</table>
+<p>Type <code>is_basic_path</code> shall be a <i>UnaryTypeTrait</i> (TR1, 4.1).
+The primary template shall be derived directly or indirectly from <code>
+std::tr1::false_type</code>. Type <code>is_basic_path</code> shall be
+specialized for <code>path</code>, <code>wpath</code>, and any
+user-specialized <code>basic_path</code> types, and such specializations shall
+be derived directly or indirectly from <code>std::tr1::true_type</code>.</p>
+<p>Structure templates <code>slash</code>, <code>dot</code>, and <code>
+<span style="background-color: #FFFFFF">colon</span></code><span style="background-color: #FFFFFF">
+</span>are supplied with
+values of type <code>char</code>. If a user-specialized <code>basic_path</code>
+has a <code>
+value_type</code> type which is not convertible from <code>char</code>, the
+templates <code>slash</code> and <code>dot</code> shall be specialized to
+provide <code>value</code> with type which is convertible to <code>
+basic_path::value_type</code>.</p>
+<h3><a name="Class-template-basic_path">Class template <code>basic_path</code></a></h3>
+<p>Class template <code>basic_path</code> provides a portable mechanism for
+representing paths in C++ programs, using a portable generic
+pathname grammar. When portability is not a
+requirement, native file system specific formats can be used. Class template
+<code>basic_path</code> is concerned only with the lexical and syntactic aspects
+of a path. The path does not have to exist in the operating system's file
+system, and may contain names which are not even valid for the current operating
+system. </p>
+<blockquote>
+ <p>[<i>Note: </i>If the library's functions trafficked only in C++<i> </i>or
+ C-style strings, they would provide only the illusion of portability since
+ while the syntax of function calls would be portable, the semantics of the
+ strings they operate on would not be portable. <i>-- end note</i>]</p>
+</blockquote>
+<pre> namespace boost
+ {
+ namespace filesystem
+ {
+ template <class String, class Traits> class basic_path
+ {
+ public:
+ typedef basic_path<String, Traits> path_type;
+ typedef String string_type;
+ typedef typename String::value_type value_type;
+ typedef Traits traits_type;
+ typedef typename Traits::external_string_type external_string_type;
+
+ // constructors/destructor
+ basic_path();
+ basic_path(const basic_path& p);
+ basic_path(const string_type& s);
+ basic_path(const value_type* s);
+ template <class InputIterator>
+ basic_path(InputIterator first, InputIterator last);
+
+ ~basic_path();
+
+ // assignments
+ basic_path& operator=(const basic_path& p);
+ basic_path& operator=(const string_type& s);
+ basic_path& operator=(const value_type* s);
+ template <class InputIterator>
+ basic_path& assign(InputIterator first, InputIterator last);
+
+ // modifiers
+ basic_path& operator/=(const basic_path& rhs);
+ basic_path& operator/=(const string_type& s);
+ basic_path& operator/=(const value_type* s);
+ template <class InputIterator>
+ basic_path& append(InputIterator first, InputIterator last);
+
+ <span style="background-color: #FFFFFF">void clear();
+ void swap( basic_path & rhs );</span>
+ basic_path& remove_filename();
+ basic_path& replace_extension(const string_type & new_extension = "");
+
+ // observers
+ const string_type string() const;
+ const string_type file_string() const;
+ const string_type directory_string() const;
+
+ const external_string_type external_file_string() const;
+ const external_string_type external_directory_string() const;
+
+ string_type root_name() const;
+ string_type root_directory() const;
+ basic_path root_path() const;
+ basic_path relative_path() const;
+
+ basic_path parent_path() const;
+ string_type filename() const;
+
+ string_type stem() const;
+ string_type extension() const;
+
+ bool empty() const;
+ bool is_complete() const;
+ bool has_root_name() const;
+ bool has_root_directory() const;
+ bool has_root_path() const;
+ bool has_relative_path() const;
+ bool has_filename() const;
+ bool has_parent_path() const;
+
+ // iterators
+ class iterator;
+ typedef iterator const_iterator;
+
+ iterator begin() const;
+ iterator end() const;
+
+ };
+
+ } // namespace filesystem
+ } // namespace boost</pre>
+<p>A <code>basic_path</code> object stores a possibly empty path.
+The internal form of the stored path is unspecified.</p>
+<p><a name="pathname-resolution">Functions</a> described in this clause which access files or their attributes do so by
+resolving a <code>basic_path</code> object into a particular file in a file
+hierarchy. The pathname, suitably converted to the string type, format, and
+encoding
+required by the operating system, is resolved as if by the <i>POSIX</i>
+<a href="http://www.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap04.html#tag_04_11">
+Pathname Resolution</a> mechanism. The encoding of the resulting pathname is determined by the <code>Traits::to_external</code> conversion function.</p>
+<blockquote>
+<p>[<i>Note:</i> There is no guarantee that the path stored in a <code>basic_path</code>
+object is valid for a particular operating system or file system. <i>-- end note</i>]</p>
+</blockquote>
+<p>Some functions in this clause return <code>basic_path</code> objects for
+paths composed partly or wholly of pathnames obtained from the operating system.
+Such pathnames are suitably converted from the actual format and string
+type supplied by the operating system. The encoding of the resulting path is determined by the <code>Traits::to_internal</code> conversion function.</p>
+<p>For member functions described as returning "<code>const string_type</code>" or
+"<code>const external_string_type</code>", implementations are permitted to return
+"<code>const string_type&</code>" or "<code>const external_string_type&</code>"
+respectively.</p>
+<blockquote>
+<p>[<i>Note:</i> This allows implementations to avoid unnecessary copies.
+Return-by-value is specified as
+<code>const</code> to ensure programs won't break if moved to a return-by-reference
+implementation. <i>--
+end note</i>]</p>
+</blockquote>
+<h4><a name="Pathname-formats">Pathname formats</a></h4>
+<p>There are two formats for string or sequence arguments that describe a
+path:</p>
+<ul>
+ <li>The portable pathname format as described in <a href="#Pathname-grammar">
+ Pathname grammar</a> and by the <i>POSIX</i> <i>Filename,
+<a href="http://www.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap03.html#tag_03_266">
+Pathname</a> </i>and<i>
+<a href="http://www.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap04.html#tag_04_11">
+Pathname Resolution</a></i> definitions.<blockquote>
+<p>[<i>Note:</i> <span style="background-color: #FFFFFF">The <i>POSIX</i> format
+is the basis for the portable format because it is already an ISO standard, is
+the basis for the ubiquitous <i>URL</i> format, and is the native format or a
+subset of the native format for <i>UNIX</i>-like and <i>Windows</i>-like
+operating systems familiar to large numbers of programmers. </span></p>
+<p>Use of the portable format does not alone guarantee
+portability; filenames must also be portable.<span style="background-color: #FFFFFF">
+See Filename conversions. Each operating system
+
+follows its own rules. Use of the portable format
+does not change that. </span> <i>-- end note</i>]</p>
+ </blockquote>
+ </li>
+ <li>A native pathname format
+ as defined by the operating system.<blockquote>
+ <p>[<i>Note:</i> If an operating system supports only the <i>POSIX</i>
+ pathname format, the portable format and the native format are the same. </p>
+ <p><span style="background-color: #FFFFFF">Identifying user-provided paths
+ as native format is a common need, and ensures maximum portability, even
+ though not strictly needed except on systems where the native format
+ is not implicitly recognized.</span></p>
+ <p><span style="background-color: #FFFFFF">Programs using hard-coding native
+ formats are likely to be non-portable. --</span><i><span style="background-color: #FFFFFF"> end note</span></i><span style="background-color: #FFFFFF">]</span></p>
+ </blockquote>
+ </li>
+</ul>
+<p><span style="background-color: #FFFFFF">All <code>basic_path</code> string or sequence arguments that describe a
+path shall accept the portable pathname format, and shall accept the native
+format if explicitly identified by a native format escape sequence prefix of
+<code>slash slash colon</code>.</span></p>
+<blockquote>
+ <p><span style="background-color: #FFFFFF">[<i>Note:</i> <code>slash
+ slash colon</code> was chosen as the escape sequence because a leading <code>
+ slash slash</code> is already implementation-defined by POSIX, <code>
+ colon</code> is prohibited in a Windows filename, and on any system a single
+ <code>slash</code> can be used when a filename beginning with a <code>colon</code>
+ is desired. These factors eliminate the chance of collision with a real
+ filename. --</span><i><span style="background-color: #FFFFFF"> end note</span></i><span style="background-color: #FFFFFF">]</span></p>
+ </blockquote>
+<p><span style="background-color: #FFFFFF">Implementations are encouraged to
+implicitly recognize the native pathname format if it can be lexically
+identified. An implementation </span>shall document whether or
+not the native pathname format is <span style="background-color: #FFFFFF">
+implicitly recognized</span>.</p>
+<blockquote>
+<p>[<i>Example:</i></p>
+<p><i>-- OpenVMS:</i> <code>"SYS1::DISK1:[JANE.TYLER.HARRY]</code>" is treated
+as a native pathname with a system name, drive name, and three directory
+filenames, rather than a portable pathname with one filename.</p>
+<p><i>-- Windows: </i><code>"c:\\jane\\tyler\\harry"</code> is treated as a
+native pathname with a drive letter, root-directory, and three filenames, rather
+than a portable pathname with one filename.</p>
+<p><i>-- Counter-example 1:</i> An operating system that allows slashes in
+filenames and uses dot as a directory separator. Distinguishing between portable
+and native format argument strings or sequences is not possible as there is no
+other distinguishing syntax. The implementation does not accept native format
+pathnames unless the <code>native</code> argument is present.</p>
+<p><i>-- Counter-example 2:</i> An operating system that allows slashes in
+filenames and uses some unusual character as a directory separator. The
+implementation does accept native format pathnames without the additional <code>
+native</code> argument, which only has to be used for native format arguments
+containing slashes in filenames.</p>
+<p><i>-- end example</i>]</p>
+<p>[<i>Note:</i> This <i><a name="duck-rule">duck-rule</a></i> ("if it looks
+like a duck, walks like a duck, and quacks like a duck, it must be a duck")
+eliminates format confusion as a source of programmer error and support
+requests. <i>-- end note</i>]</p>
+</blockquote>
+<p>If both the portable and native formats are accepted, implementations shall
+document what characters or character sequences are used to distinguish between
+portable and native formats.</p>
+<blockquote>
+<p>[<i>Note:</i> <i>Windows</i> implementations are encouraged to define colons
+and backslashes as the characters which distinguish native from portable
+formats. <i>--end note</i>]</p>
+</blockquote>
+<h4><a name="Pathname-grammar">Pathname grammar</a></h4>
+<p>The grammar for the portable pathname format is as follows:</p>
+<blockquote>
+<p><i>pathname:<br>
+ root-name<sub>opt</sub>
+root-directory<sub>opt</sub> relative-path<sub>opt</sub></i></p>
+<p><i>root-name:<br>
+
+implementation-defined</i></p>
+<p><i>root-directory:<br>
+ slash<br>
+
+root-directory slash<br>
+
+implementation-defined</i></p>
+<p><i>relative-path:<br>
+
+filename<br>
+ relative-path
+slash<br>
+ relative-path
+slash filename</i></p>
+<p><i>filename:<br>
+ name<br>
+ dot<br>
+ dot dot</i></p>
+<p><i>slash:<br>
+ <code>
+slash<Path>::value</code></i></p>
+<p><i>dot:<br>
+ <code>
+dot<Path>::value</code></i></p>
+</blockquote>
+<p>The grammar is aligned with the <i>POSIX </i> <i>Filename,
+<a href="http://www.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap03.html#tag_03_266">
+Pathname</a> </i>and<i>
+<a href="http://www.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap04.html#tag_04_11">
+Pathname Resolution</a></i> definitions. Any conflict between the grammar and <i>
+POSIX</i> is unintentional. This technical report defers to <i>POSIX</i>.</p>
+<blockquote>
+<p><span style="background-color: #E0E0E0"><i>The form of the above wording was taken
+from POSIX, which uses it in several places to defer to the C standard.</i></span></p>
+<p>[<i>Note: Windows</i> implementations are encouraged to define <i>slash slash
+name</i> as a permissible <i>root-name</i>. <i>POSIX</i> permits, but does not
+require, implementations to do the same. <i>Windows</i> implementations are
+encouraged to define an additional <i>root-directory</i> element <i>
+root_directory name.</i> It is applicable only to the <i>slash slash name</i>
+form of <i>root-name.</i></p>
+<p> <i>Windows</i> implementations are encouraged to recognize a <i>name</i>
+followed by a colon as a native format <i>root-name</i>,
+and a backslash as a format element equivalent to <i>slash</i>. <i>-- end note</i>]</p>
+</blockquote>
+<h4><a name="Filename-conversion">Filename conversion</a></h4>
+<p>When converting filenames to the native operating system format,
+implementations are encouraged, but not required, to convert otherwise invalid
+characters or character sequences to valid characters or character sequences.
+Such conversions are implementation-defined.</p>
+<blockquote>
+<p>[<i>Note:</i> Filename conversion allows much wider portability of both
+programs and filenames that would otherwise be possible.</p>
+<p>Implementations are encouraged to base conversion on existing standards or
+practice. Examples include the Uniform Resource Locator escape syntax of a percent sign (<code>'%'</code>)
+followed by two hex digits representing the character value. On
+<i>OpenVMS</i>, which does not allow percent signs in filenames, a dollar sign (<code>'$'</code>)
+followed by two hex digits is the existing practice, as is converting lowercase
+letters to uppercase.<i> -- end note.</i>]</p>
+<p><span style="background-color: #E0E0E0"><i>The Boost implementation for
+Windows currently does not map invalid characters. Pending feedback from the LWG,
+Boost may settle on % hex hex as the preferred escape sequence. If so, should
+there be normative encouragement?</i></span></p>
+</blockquote>
+<h4><a name="basic_path-requirements">Requirements</a></h4>
+<p>The argument for the template parameter named <code>String</code> shall be a
+class that includes members with the same names, types, values, and semantics as
+class template <code>basic_string</code>.</p>
+<p>The argument for the template parameter named <code>Traits</code> shall be a
+class that satisfies the requirements specified in the
+Path Behavior Traits Requirements
+table.</p>
+<p>The argument for template parameters named <code>InputIterator</code> shall satisfy the
+requirements of an input iterator (C++ Std, 24.1.1, Input iterators [lib.input.iterators]) and shall have a value type convertible to
+<code>basic_path::value_type</code>. </p>
+<p>Some function templates with a template
+parameter named <code>InputIterator</code> also have non-template overloads. Implementations shall
+only select the function template overload if the type named by <code>InputIterator</code>
+is not <code>path_format_t</code>.</p>
+<blockquote>
+<p>[<i>Note:</i> This "do-the-right-thing" rule ensures that the
+overload expected by the user is selected. The implementation technique is unspecified -
+implementations may use
+enable_if or
+other techniques to achieve the effect. <i>-- end note</i>]</p>
+</blockquote>
+<h4> <a name="basic_path-constructors"> <code>basic_path</code> constructors</a></h4>
+<pre>basic_path();</pre>
+<blockquote>
+ <p><i>Postconditions:</i> <code>empty()</code>.</p>
+ </blockquote>
+<pre>basic_path(const string_type& s);
+basic_path(const value_type * s);
+template <class InputIterator>
+ basic_path(InputIterator s, InputIterator last);</pre>
+<blockquote>
+ <p><i>Remarks:</i> The format of string <code>s</code> and sequence [<code>first</code>,<code>last</code>)
+ is described in Pathname formats.</p>
+ <p><i>Effects:</i> The path elements in string <code>s</code> or sequence [<code>first</code>,<code>last</code>)
+ are stored.</p>
+</blockquote>
+<h4> <a name="basic_path-assignments"> <code>basic_path</code> assignments</a></h4>
+<pre>basic_path& operator=(const string_type& s);
+basic_path& operator=(const value_type* s);
+template <class InputIterator>
+ basic_path& assign(InputIterator first, InputIterator last);</pre>
+<blockquote>
+ <p><i>Remarks:</i> The format of string <code>s</code> and sequence [<code>first</code>,<code>last</code>)
+ is described in Pathname formats.</p>
+ <p><i>Effects:</i> The path elements in string <code>s</code> or sequence [<code>first</code>,<code>last</code>)
+ are stored.</p>
+ <p><i>Returns: </i><code>*this</code></p>
+ </blockquote>
+<h4> <a name="basic_path-modifiers"> <code>basic_path</code> modifiers</a></h4>
+<pre>basic_path& operator/=(const basic_path& rhs);</pre>
+<blockquote>
+ <p><i>Effects:</i> The path stored in <code>rhs</code> is appended to the
+ stored path.</p>
+ <p><i>Returns:</i> <code>*this</code></p>
+</blockquote>
+<pre>basic_path& operator/=(const string_type& s);
+basic_path& operator/=(const value_type* s);
+template <class InputIterator>
+basic_path& append(InputIterator first, InputIterator last);</pre>
+<blockquote>
+ <p><i>Remarks:</i> The format of string <code>s</code> and sequence [<code>first</code>,<code>last</code>)
+ is described in Pathname formats.</p>
+<p><i>Effects:</i> The path elements in string <code>s</code> or sequence [<code>first</code>,<code>last</code>)
+ are appended to the stored path.</p>
+ <p><i>Returns: </i><code>*this</code></p>
+ </blockquote>
+<pre>void clear();</pre>
+<blockquote>
+<p><i>Postcondition:</i> <code>this->empty()</code> is true.</p>
+</blockquote>
+<pre><code><span style="background-color: #FFFFFF">void swap( basic_path & rhs );</span></code></pre>
+<blockquote>
+ <p><i><span style="background-color: #FFFFFF">Effects:</span></i><span style="background-color: #FFFFFF">
+ Swaps the contents of the two paths.</span></p>
+ <p><i><span style="background-color: #FFFFFF">Throws: </span></i>
+ <span style="background-color: #FFFFFF">nothing.</span></p>
+ <p><i><span style="background-color: #FFFFFF">Postcondition:</span></i><span style="background-color: #FFFFFF">
+ </span><code><span style="background-color: #FFFFFF">this->string()</span></code><span style="background-color: #FFFFFF">
+ contains the same sequence of characters that were in </span><code><span style="background-color: #FFFFFF">
+ rhs.string()</span></code><span style="background-color: #FFFFFF">, </span><code><span style="background-color: #FFFFFF">
+ rhs.string()</span></code><span style="background-color: #FFFFFF">
+ contains the same sequence of characters that were is </span><code>
+ <span style="background-color: #FFFFFF">this->string()</span></code><span style="background-color: #FFFFFF">.</span></p>
+ <p><i><span style="background-color: #FFFFFF">Complexity: </span></i>
+ <span style="background-color: #FFFFFF">constant time.</span></p>
+</blockquote>
+<pre>basic_path& remove_filename();</pre>
+<blockquote>
+ <p><i>Effects:</i> If <code>has_parent_path()</code> then remove the last <i>filename</i> from the stored path. If that leaves
+ the stored path with one or more trailing <i>slash</i> elements not
+ representing <i>root-directory</i>, remove them.</p>
+ <p><i>Returns:</i> <code>*this</code></p>
+ <p>[<i>Note:</i> This function is needed to efficiently implement <code>
+ basic_directory_iterator</code>. It is made public to allow additional uses. <i>-- end
+ note</i>]</p>
+</blockquote>
+<pre>basic_path& replace_extension( const string_type & new_extension = "" );</pre>
+<blockquote>
+ <p><i>Postcondition: </i> <code>extension() == <i>replacement</i></code>,
+ where <code><i>replacement</i></code> is <code>new_extension</code> if <code>
+ new_extension.empty() || new_extension[0] ==</code> the dot character,
+ otherwise <code><i>replacement</i></code> is the dot character followed by
+ <code>new_extension</code>.</p>
+ <p><i>Returns:</i> <code>*this</code></p>
+</blockquote>
+<h4> <a name="basic_path-observers"> <code>basic_path</code> observers</a></h4>
+<blockquote>
+<p><span style="background-color: #E0E0E0"><i>See the
+Path decomposition table for examples
+for values returned by decomposition functions.</i></span></p>
+</blockquote>
+<pre>const string_type string() const;</pre>
+<blockquote>
+<p><i>Returns:</i> The stored path, formatted according to the
+Pathname grammar rules.</p>
+</blockquote>
+<pre>const string_type file_string() const;</pre>
+<blockquote>
+<p><i>Returns:</i> The stored path, formatted according to the
+operating system rules for regular file pathnames, with any
+Filename conversion applied.</p>
+<p>[<i>Note:</i> For some operating systems, including <i>POSIX</i> and <i>
+Windows</i>, the native format for regular file pathnames and directory
+pathnames is the same, so <code>file_string()</code> and <code>directory_string()</code>
+return the same string. On OpenMVS, however, the expression <code>path("/cats/jane").file_string()</code>
+would return the string <code>"[CATS]JANE"</code> while <code>path("/cats/jane").directory_string()</code>
+would return the string <code>"[CATS.JANE]"</code>. <i>-- end note</i>]</p>
+</blockquote>
+<pre>const string_type directory_string() const;</pre>
+<blockquote>
+<p><i>Returns:</i> The stored path, formatted according to the
+operating system rules for directory pathnames, with any
+Filename conversion applied.</p>
+</blockquote>
+<pre>const external_string_type external_file_string() const;</pre>
+<blockquote>
+<p><i>Returns:</i> The stored path, formatted according to the
+operating system rules for regular file pathnames, with any
+Filename conversion applied, and encoded by the <code>Traits::to_external</code>
+conversion function.</p>
+</blockquote>
+<pre>const external_string_type external_directory_string() const;</pre>
+<blockquote>
+<p><i>Returns:</i> The stored path, formatted according to the
+operating system rules for directory pathnames, with any
+Filename conversion applied, and encoded by the <code>Traits::to_external</code>
+conversion function.</p>
+</blockquote>
+<pre>string_type root_name() const;</pre>
+<blockquote>
+<p><i>Returns:</i> <i>root-name,</i> if the stored path includes <i>
+root-name</i>, otherwise <code>string_type()</code>. </p>
+</blockquote>
+<pre>string_type root_directory() const;</pre>
+<blockquote>
+<p><i>Returns:</i> <i>root-directory</i>, if the stored path includes <i>
+root-directory</i>, otherwise <code>string_type()</code>.</p>
+<p>If <i>root-directory</i> is composed <i>slash name</i>, <i>slash</i> is
+excluded from the returned string.</p>
+</blockquote>
+<pre>basic_path root_path() const;</pre>
+<blockquote>
+ <p><i>Returns:</i> <code>root_name() / root_directory()</code></p>
+</blockquote>
+<pre>basic_path relative_path() const;</pre>
+<blockquote>
+<p><i>Returns:</i> A <code>basic_path</code> composed from the the stored path, if any, beginning
+with the first <i>filename</i> after <i>root-path</i>.
+Otherwise, an empty <code>basic_path</code>.</p>
+</blockquote>
+<pre>string_type filename() const;</pre>
+<blockquote>
+ <p><i>Returns:</i> <code>empty() ? string_type() : *--end()</code></p>
+</blockquote>
+<pre>basic_path parent_path() const;</pre>
+<blockquote>
+ <p><i>Returns:</i> <code>(string().empty() || begin() == --end()) ? path_type("") :
+ <i>br</i></code>, where <code><i>br</i></code> is constructed as if by
+ starting with an empty <code>basic_path</code> and successively applying <code>
+ operator/=</code> for each element in the range <code>begin()</code>, <code>
+ --end()</code>.</p>
+</blockquote>
+<pre>string_type stem(const Path & p) const;</pre>
+<blockquote>
+ <p><i>Returns:</i> if <code>p.filename()</code> contains a <i>dot</i>, returns
+ the substring of <code>p.filename()</code> starting at its beginning and
+ ending at the last <i>dot</i> (the <i>dot</i> is not included). Otherwise,
+ returns <code>
+ p.filename()</code>.</p>
+</blockquote>
+<pre>string_type extension(const Path & p) const;</pre>
+<blockquote>
+ <p><i>Returns:</i> if <code>p.filename()</code> contains a <i>dot</i>, returns
+ the substring of <code>p.filename()</code> starting at the rightmost <i>dot</i>
+ and ending at the string's end. Otherwise, returns an empty string. </p>
+ <p>[<i>Note:<b> </b></i>The <i>dot</i> is included in the return value so that
+ it is possible to distinguish between no extension and an empty extension. </p>
+ <p>Implementations are permitted but not required to define additional
+ behavior for file systems which append additional elements to extensions, such
+ as alternate data stream or partitioned dataset names. <i>-- end note</i>]</p>
+</blockquote>
+<pre>bool empty() const;</pre>
+<blockquote>
+ <p><i>Returns:</i> <code>string().empty()</code>.</p>
+</blockquote>
+<pre>bool is_complete() const;</pre>
+<blockquote>
+ <p><span style="background-color: #FFFFFF"><i>Returns:</i> <code>true</code>,
+ if the elements of root_path() uniquely identify a directory, else <code>false</code>.</span></p>
+</blockquote>
+<pre>bool has_root_path() const;</pre>
+<blockquote>
+ <p><i>Returns:</i> <code>!root_path().empty()</code></p>
+</blockquote>
+<pre>bool has_root_name() const;</pre>
+<blockquote>
+ <p><i>Returns:</i> <code>!root_name().empty()</code></p>
+</blockquote>
+<pre>bool has_root_directory() const;</pre>
+<blockquote>
+ <p><i>Returns:</i> <code>!root_directory().empty()</code></p>
+</blockquote>
+<pre>bool has_relative_path() const;</pre>
+<blockquote>
+ <p><i>Returns:</i> <code>!relative_path().empty()</code></p>
+</blockquote>
+<pre>bool has_filename() const;</pre>
+<blockquote>
+ <p><i>Returns:</i> <code>!filename().empty()</code></p>
+</blockquote>
+<pre>bool has_parent_path() const;</pre>
+<blockquote>
+ <p><i>Returns:</i> <code>!parent_path().empty()</code></p>
+</blockquote>
+<h4> <a name="basic_path-iterators"> <code>basic_path</code> iterators</a></h4>
+<p> A <code>basic_path::iterator</code> is a constant iterator satisfying all
+the requirements of a bidirectional iterator (C++ Std, 24.1.4 Bidirectional
+iterators [lib.bidirectional.iterators]). Its <code>value_type</code> is
+<code>string_type</code>.</p>
+ <p>Calling any non-const member function of a <code>basic_path</code> object
+ invalidates all iterators referring to elements of the object.</p>
+<p> The forward traversal order is as follows:</p>
+<ul>
+ <li>The <i>root-name</i> element, if present.</li>
+ <li>The <i>root-directory</i> element, if present.</li>
+ <li>Each successive <i>filename</i> element, if present.</li>
+ <li><i>Dot</i>, if one or more trailing non-root <i>slash</i>
+ characters are present.</li>
+</ul>
+ <p>The backward traversal order is the reverse of forward traversal.</p>
+ <pre>iterator begin() const;</pre>
+<blockquote>
+ <p><i>Returns:</i> An iterator for the first present element in the traversal
+ list above. If no elements are present, the end iterator.</p>
+</blockquote>
+<pre>iterator end() const;</pre>
+<blockquote>
+ <p><i>Returns:</i> The end iterator.</p>
+</blockquote>
+<h4> <a name="basic_path-non-member-functions">
+<span style="background-color: #FFFFFF">basic_path non-member functions</span></a></h4>
+<pre><span style="background-color: #FFFFFF">template<class String, class Traits>
+void swap( basic_path<String, Traits> & lhs, basic_path<String, Traits> & rhs )</span></pre>
+<blockquote>
+ <p><i><span style="background-color: #FFFFFF">Effects: </span></i><code>
+ <span style="background-color: #FFFFFF">lhs.swap(
+ rhs )</span></code></p>
+</blockquote>
+ <h4><span style="background-color: #FFFFFF">basic_path non-member operators</span></h4>
+ <p><span style="background-color: #FFFFFF">There are seven basic_path non-member operators (/,
+ </span> <code><span style="background-color: #FFFFFF">==</span></code><span style="background-color: #FFFFFF">,
+ </span> <code>
+ <span style="background-color: #FFFFFF">!=</span></code><span style="background-color: #FFFFFF">,
+ </span> <code><span style="background-color: #FFFFFF"><</span></code><span style="background-color: #FFFFFF">,
+ </span> <code><span style="background-color: #FFFFFF">></span></code><span style="background-color: #FFFFFF">,
+ </span> <code><span style="background-color: #FFFFFF"><=</span></code><span style="background-color: #FFFFFF">,
+ </span> <code><span style="background-color: #FFFFFF">>=</span></code><span style="background-color: #FFFFFF">),
+ each with five overloads. For brevity, the specifications are given in tabular
+ form. Each of the resulting thirty-five signatures is a template, with
+ template parameter list template</span><code><span style="background-color: #FFFFFF"><class
+ String, class Traits></span></code><span style="background-color: #FFFFFF">.
+ The format of such arguments is described in </span> <a href="#Pathname-formats">
+ <span style="background-color: #FFFFFF">Pathname formats</span></a><span style="background-color: #FFFFFF">.</span></p>
+ <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%">
+ <tr>
+ <td width="100%">
+ <p align="center"><i><b><span style="background-color: #FFFFFF">Argument type overloads</span></b></i></td>
+ </tr>
+ <tr>
+ <td width="100%"><span style="background-color: #FFFFFF"><code>
+ basic_path<String, Traits>& a, basic_path<String, Traits>&
+ b</code></span></td>
+ </tr>
+ <tr>
+ <td width="100%"><span style="background-color: #FFFFFF"><code>const
+ typename basic_path<String, Traits>::string_type& a,
+ basic_path<String, Traits>& b</code></span></td>
+ </tr>
+ <tr>
+ <td width="100%"><span style="background-color: #FFFFFF"><code>const
+ typename basic_path<String, Traits>::string_type::value_type* a,
+ basic_path<String, Traits>& b</code></span></td>
+ </tr>
+ <tr>
+ <td width="100%"><span style="background-color: #FFFFFF"><code>const
+ basic_path<String, Traits>& a, typename basic_path<String, Traits>::string_type&
+ b</code></span></td>
+ </tr>
+ <tr>
+ <td width="100%"><span style="background-color: #FFFFFF"><code>const
+ basic_path<String, Traits>& a, typename
+ basic_path<String, Traits>::string_type::value_type* b</code></span></td>
+ </tr>
+ </table>
+ <p><span style="background-color: #FFFFFF">In the </span><b><i>
+ <span style="background-color: #FFFFFF">basic_path non-member operators </span>
+ </i></b><span style="background-color: #FFFFFF">table, </span><code>
+ <span style="background-color: #FFFFFF">a</span></code><span style="background-color: #FFFFFF">
+ and </span><code><span style="background-color: #FFFFFF">b</span></code><span style="background-color: #FFFFFF">
+ are of the types given in the </span><i><b>
+ <span style="background-color: #FFFFFF">Argument type overloads</span></b></i><span style="background-color: #FFFFFF">
+ table. If </span><code><span style="background-color: #FFFFFF">a</span></code><span style="background-color: #FFFFFF">
+ or </span><code><span style="background-color: #FFFFFF">b</span></code><span style="background-color: #FFFFFF">
+ is of type </span><code><span style="background-color: #FFFFFF">const
+ basic_path<String, Traits>&</span></code><span style="background-color: #FFFFFF">,
+ then </span><i><b><span style="background-color: #FFFFFF">a</span></b></i><code><i><b><span style="background-color: #FFFFFF">'</span></b></i></code><span style="background-color: #FFFFFF">
+ or </span><i><b><span style="background-color: #FFFFFF">b'</span></b></i><span style="background-color: #FFFFFF">
+ respectively is </span><code><span style="background-color: #FFFFFF">a</span></code><span style="background-color: #FFFFFF">
+ or </span><code><span style="background-color: #FFFFFF">b</span></code><span style="background-color: #FFFFFF">
+ respectively. Otherwise </span><i><b><span style="background-color: #FFFFFF">a</span></b></i><code><i><b><span style="background-color: #FFFFFF">'</span></b></i></code><span style="background-color: #FFFFFF">
+ or </span><i><b><span style="background-color: #FFFFFF">b'</span></b></i><span style="background-color: #FFFFFF">
+ respectively represent named or unnamed temporary </span><code>
+ <span style="background-color: #FFFFFF">basic_path<String, Traits></span></code><span style="background-color: #FFFFFF">
+ objects constructed from </span><code><span style="background-color: #FFFFFF">
+ a</span></code><span style="background-color: #FFFFFF"> or </span><code>
+ <span style="background-color: #FFFFFF">b</span></code><span style="background-color: #FFFFFF">
+ respectively.</span></p>
+<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%" height="280">
+ <tr>
+ <td width="100%" colspan="3" align="center" height="19"><b><i>
+ <span style="background-color: #FFFFFF">basic_path non-member operators</span></i></b></td>
+ </tr>
+ <tr>
+ <td width="20%" align="center" height="19"><i><b>
+ <span style="background-color: #FFFFFF">Expression</span></b></i></td>
+ <td width="25%" align="center" height="19"><i><b>
+ <span style="background-color: #FFFFFF">Return type</span></b></i></td>
+ <td width="55%" align="center" height="19"><i><b>
+ <span style="background-color: #FFFFFF">Semantics</span></b></i></td>
+ </tr>
+ <tr>
+ <td width="20%" align="center" height="30" valign="top"><code>
+ <span style="background-color: #FFFFFF">a / b</span></code></td>
+ <td width="25%" align="center" height="30" valign="top"><code>
+ <span style="background-color: #FFFFFF">basic_path<String, Traits></span></code></td>
+ <td width="55%" height="30"><code><span style="background-color: #FFFFFF">
+ basic_path<String, Traits> tmp(a);<br>
+ return tmp /= </span></code><i><b><span style="background-color: #FFFFFF">b'</span></b></i><code><span style="background-color: #FFFFFF">;</span></code></td>
+ </tr>
+ <tr>
+ <td width="20%" align="center" height="19" valign="top"><code>
+ <span style="background-color: #FFFFFF">a < b</span></code></td>
+ <td width="25%" align="center" height="19" valign="top"><code>
+ <span style="background-color: #FFFFFF">bool</span></code></td>
+ <td width="55%" height="19"><code><span style="background-color: #FFFFFF">
+ return lexicographical_compare(</span></code><span style="background-color: #FFFFFF"><i><b>a</b></i></span><code><span style="background-color: #FFFFFF"><i><b>'</b></i>.begin(), </span></code><i><b>
+ <span style="background-color: #FFFFFF">a</span></b></i><code><span style="background-color: #FFFFFF"><i><b>'</b></i>.end(), </span></code><i><b>
+ <span style="background-color: #FFFFFF">b'</span></b></i><code><span style="background-color: #FFFFFF">.begin(), </span></code><i><b>
+ <span style="background-color: #FFFFFF">b'</span></b></i><code><span style="background-color: #FFFFFF">.end());</span></code></td>
+ </tr>
+ <tr>
+ <td width="20%" align="center" height="19" valign="top"><code>
+ <span style="background-color: #FFFFFF">a == b</span></code></td>
+ <td width="25%" align="center" height="19" valign="top"><code>
+ <span style="background-color: #FFFFFF">bool</span></code></td>
+ <td width="55%" height="19"><code><span style="background-color: #FFFFFF">
+ return !(</span></code><i><b><span style="background-color: #FFFFFF">a</span></b></i><code><i><b><span style="background-color: #FFFFFF">'</span></b></i><span style="background-color: #FFFFFF">
+ < </span></code><i><b><span style="background-color: #FFFFFF">b'</span></b></i><code><span style="background-color: #FFFFFF">)
+ && !(</span></code><i><b><span style="background-color: #FFFFFF">b'</span></b></i><code><span style="background-color: #FFFFFF">
+ < </span></code><i><b><span style="background-color: #FFFFFF">a</span></b></i><code><i><b><span style="background-color: #FFFFFF">'</span></b></i><span style="background-color: #FFFFFF">);</span></code></td>
+ </tr>
+ <tr>
+ <td width="20%" align="center" height="19" valign="top"><code>
+ <span style="background-color: #FFFFFF">a != b</span></code></td>
+ <td width="25%" align="center" height="19" valign="top"><code>
+ <span style="background-color: #FFFFFF">bool</span></code></td>
+ <td width="55%" height="19"><code><span style="background-color: #FFFFFF">
+ return !(</span></code><i><b><span style="background-color: #FFFFFF">a</span></b></i><code><i><b><span style="background-color: #FFFFFF">'</span></b></i><span style="background-color: #FFFFFF">
+ == </span></code><i><b><span style="background-color: #FFFFFF">b'</span></b></i><code><span style="background-color: #FFFFFF">);</span></code></td>
+ </tr>
+ <tr>
+ <td width="20%" align="center" height="19" valign="top"><code>
+ <span style="background-color: #FFFFFF">a > b</span></code></td>
+ <td width="25%" align="center" height="19" valign="top"><code>
+ <span style="background-color: #FFFFFF">bool</span></code></td>
+ <td width="55%" height="19"><code><span style="background-color: #FFFFFF">
+ return </span></code><i><b><span style="background-color: #FFFFFF">b'</span></b></i><code><span style="background-color: #FFFFFF">
+ < </span></code><i><b><span style="background-color: #FFFFFF">a</span></b></i><code><i><b><span style="background-color: #FFFFFF">'</span></b></i><span style="background-color: #FFFFFF">;</span></code></td>
+ </tr>
+ <tr>
+ <td width="20%" align="center" height="19" valign="top"><code>
+ <span style="background-color: #FFFFFF">a <= b</span></code></td>
+ <td width="25%" align="center" height="19" valign="top"><code>
+ <span style="background-color: #FFFFFF">bool</span></code></td>
+ <td width="55%" height="19"><code><span style="background-color: #FFFFFF">
+ return !(</span></code><i><b><span style="background-color: #FFFFFF">b'</span></b></i><code><span style="background-color: #FFFFFF">
+ < </span></code><i><b><span style="background-color: #FFFFFF">a</span></b></i><code><i><b><span style="background-color: #FFFFFF">'</span></b></i><span style="background-color: #FFFFFF">);</span></code></td>
+ </tr>
+ <tr>
+ <td width="20%" align="center" height="19" valign="top"><code>
+ <span style="background-color: #FFFFFF">a >= b</span></code></td>
+ <td width="25%" align="center" height="19" valign="top"><code>
+ <span style="background-color: #FFFFFF">bool</span></code></td>
+ <td width="55%" height="19"><code><span style="background-color: #FFFFFF">
+ return !(</span></code><i><b><span style="background-color: #FFFFFF">a</span></b></i><code><i><b><span style="background-color: #FFFFFF">'</span></b></i><span style="background-color: #FFFFFF">
+ < </span></code><i><b><span style="background-color: #FFFFFF">b'</span></b></i><code><span style="background-color: #FFFFFF">);</span></code></td>
+ </tr>
+</table>
+ <blockquote>
+ <p><span style="background-color: #FFFFFF">[</span><i><span style="background-color: #FFFFFF">Note:</span></i><span style="background-color: #FFFFFF">
+ </span> <a name="Path-equality"><span style="background-color: #FFFFFF">Path equality</span></a><span style="background-color: #FFFFFF"> and path
+ equivalence have different semantics.</span></p>
+ <p><span style="background-color: #FFFFFF">Equality is determined by </span> <i>
+ <span style="background-color: #FFFFFF">basic_path</span></i><span style="background-color: #FFFFFF">'s
+ non-member </span> <code><a href="#operator-eq">
+ <span style="background-color: #FFFFFF">operator==</span></a></code><span style="background-color: #FFFFFF">, which considers the two path's lexical representations
+ only. Paths "abc" and "ABC" are never equal.</span></p>
+ <p><span style="background-color: #FFFFFF">Equivalence is determined by the
+ </span> equivalent()<span style="background-color: #FFFFFF">
+ non-member function, which determines if two paths </span>
+ resolve<span style="background-color: #FFFFFF"> to the same file system entity.
+ Paths "abc"
+ and "ABC" may or may not resolve to the same file, depending on the file
+ system.</span></p>
+ <p><span style="background-color: #FFFFFF">Programmers wishing to determine if two paths are "the same" must decide if
+ "the same" means "the same representation" or "resolve to the same actual
+ file", and choose the appropriate function accordingly. </span> <i>
+ <span style="background-color: #FFFFFF">-- end note</span></i><span style="background-color: #FFFFFF">]</span></p>
+</blockquote>
+ <h4><a name="basic_path-inserter-extractor"> <code>
+ <span style="background-color: #FFFFFF">basic_path</span></code><span style="background-color: #FFFFFF"> inserter
+ and extractor</span></a></h4>
+<pre><span style="background-color: #FFFFFF">template<class Path>
+ basic_istream<typename Path::string_type::value_type, typename Path::string_type::traits_type>&
+ operator>>(basic_istream< typename Path::string_type::value_type, typename Path::string_type::traits_type>& is,
+ Path& ph );</span></pre>
+<blockquote>
+ <p><i><span style="background-color: #FFFFFF">Effects: </span></i>
+ <code><span style="background-color: #FFFFFF">typename Path::string_type str;<br>
+
+ is >> str;<br>
+
+ ph = str;</span></code></p>
+ <p><i><span style="background-color: #FFFFFF">Returns:</span></i><span style="background-color: #FFFFFF">
+ </span> <code><span style="background-color: #FFFFFF">is</span></code></p>
+</blockquote>
+<pre><span style="background-color: #FFFFFF">template<class Path>
+ basic_ostream<typename Path::string_type::value_type, typename Path::string_type::traits_type>&
+ operator<<(basic_ostream< typename Path::string_type::value_type, typename Path::string_type::traits_type>& os,
+ const Path& ph );</span></pre>
+<blockquote>
+ <p><i><span style="background-color: #FFFFFF">Effects:</span></i><span style="background-color: #FFFFFF">
+ </span> <code><span style="background-color: #FFFFFF">os << ph.string()</span></code></p>
+ <p><i><span style="background-color: #FFFFFF">Returns:</span></i><span style="background-color: #FFFFFF">
+ </span> <code><span style="background-color: #FFFFFF">os</span></code></p>
+</blockquote>
+<h3><a name="Class-template-basic_filesystem_error">Class template <code>basic_filesystem_error</code></a></h3>
+<pre> namespace boost
+ {
+ namespace filesystem
+ {
+ template <class Path> class basic_filesystem_error : public <span style="background-color: #FFFFFF">system</span>_error
+ {
+ public:
+ typedef Path path_type;
+
+ explicit basic_filesystem_error(const std::string& <span style="background-color: #FFFFFF">what_arg</span>, error_code ec);
+ basic_filesystem_error(const std::string& <span style="background-color: #FFFFFF">what_arg</span>, const path_type& p1, error_code ec);
+ basic_filesystem_error(const std::string& <span style="background-color: #FFFFFF">what_arg</span>, const path_type& p1, const path_type& p2, error_code ec);
+
+ const path_type& path1() const;
+ const path_type& path2() const;
+
+ const char * what() const;
+ };
+ } // namespace filesystem
+ } // namespace boost</pre>
+<p>The class template <code>basic_filesystem_error</code> defines the type of
+objects thrown as exceptions to report file system errors from functions described in this
+clause.</p>
+<h4> <a name="basic_filesystem_error-constructors"> <code>basic_filesystem_error</code> constructors</a></h4>
+<pre>explicit basic_filesystem_error(const std::string& <span style="background-color: #FFFFFF">what_arg</span>, error_code ec);</pre>
+<blockquote>
+ <p><i>Postconditions:</i></p>
+ <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="46%">
+ <tr>
+ <td width="18%"><b>Expression</b></td>
+ <td width="82%"><b>Value</b></td>
+ </tr>
+ <tr>
+ <td width="18%" bgcolor="#FFFFFF"><code>
+ <span style="background-color: #FFFFFF">runtime_error::what</span>()</code></td>
+ <td width="82%" bgcolor="#FFFFFF"><span style="background-color: #FFFFFF">
+ <code><i>what_arg</i>.c_str()</code></span></td>
+ </tr>
+ <tr>
+ <td width="18%"><code>code()</code></td>
+ <td width="82%"><code>ec</code></td>
+ </tr>
+ <tr>
+ <td width="18%"><code>path1().empty()</code></td>
+ <td width="82%"><code>true</code></td>
+ </tr>
+ <tr>
+ <td width="18%"><code>path2().empty()</code></td>
+ <td width="82%"><code>true</code></td>
+ </tr>
+ </table>
+</blockquote>
+<pre>basic_filesystem_error(const std::string& <span style="background-color: #FFFFFF">what_arg</span>, const path_type& p1, error_code ec);</pre>
+<blockquote>
+ <p><i>Postconditions:</i></p>
+ <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="46%">
+ <tr>
+ <td width="18%"><b>Expression</b></td>
+ <td width="82%"><b>Value</b></td>
+ </tr>
+ <tr>
+ <td width="18%" valign="top"><code>
+ <span style="background-color: #FFFFFF">runtime_error::what</span>()</code></td>
+ <td width="82%"><span style="background-color: #FFFFFF">
+ <code><i>what_arg</i>.c_str()</code></span></td>
+ </tr>
+ <tr>
+ <td width="18%" valign="top"><code>code()</code></td>
+ <td width="82%"><code>ec</code></td>
+ </tr>
+ <tr>
+ <td width="18%" valign="top"><code>path1()</code></td>
+ <td width="82%"><span style="background-color: #FFFFFF">Reference to stored copy of
+ </span> <code>p1</code></td>
+ </tr>
+ <tr>
+ <td width="18%" valign="top"><code>path2().empty()</code></td>
+ <td width="82%"><code>true</code></td>
+ </tr>
+ </table>
+</blockquote>
+<pre>basic_filesystem_error(const std::string& <span style="background-color: #FFFFFF">what_arg</span>, const path_type& p1, const path_type& p2, error_code ec);</pre>
+<blockquote>
+ <p><i>Postconditions:</i></p>
+ <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="46%">
+ <tr>
+ <td width="18%"><b>Expression</b></td>
+ <td width="82%"><b>Value</b></td>
+ </tr>
+ <tr>
+ <td width="18%"><code>
+ <span style="background-color: #FFFFFF">runtime_error::what</span>()</code></td>
+ <td width="82%"><span style="background-color: #FFFFFF">
+ <u>
+ <code><i>w</i></code></u><code><i>hat_arg</i>.c_str()</code></span></td>
+ </tr>
+ <tr>
+ <td width="18%"><code>code()</code></td>
+ <td width="82%"><code>ec</code></td>
+ </tr>
+ <tr>
+ <td width="18%"><code>path1()</code></td>
+ <td width="82%"><span style="background-color: #FFFFFF">Reference to stored copy of
+ </span> <code>p1</code></td>
+ </tr>
+ <tr>
+ <td width="18%"><code>path2()</code></td>
+ <td width="82%"><span style="background-color: #FFFFFF">Reference to stored copy of
+ </span> <code>p2</code></td>
+ </tr>
+ </table>
+</blockquote>
+<h4> <a name="basic_filesystem_error-observers"> <code>basic_filesystem_error</code> observers</a></h4>
+<pre>const path_type& path1() const;</pre>
+<blockquote>
+ <p><i>Returns:</i> Reference to copy of <code>p1</code> stored by the
+ constructor, or, if none, an empty path.</p>
+</blockquote>
+<pre>const path_type& path2() const;</pre>
+<blockquote>
+ <p><i>Returns:</i> Reference to copy of <code>p2</code> stored by the
+ constructor, or, if none, an empty path.</p>
+</blockquote>
+<pre>const char * what() const;</pre>
+<blockquote>
+ <p><i>Returns: </i>A string containing <code>runtime_error::what()</code> and
+ the result of calling <code>system_message()</code> with a first argument of
+ <code>code()</code>. The exact format is unspecified.</p>
+<p>The implementation shall supply a specialization <code>template<> const char
+* basic_filesystem_error<path>::what() const</code> that returns a string
+containing <code>runtime_error::what(),</code> the result of calling <code>
+system_message()</code> with a first argument of <code>code()</code>, and if
+non-empty, <code>path1().file_string()</code> and <code>path2.file_string()</code>.
+The exact format is unspecified.</p>
+<p>Implementations and users are permitted to provide other specializations of
+the <code>what</code> member function.</p>
+</blockquote>
+<h3><a name="Class-template-basic_directory_entry">Class template <code>basic_directory_entry</code></a></h3>
+<pre> namespace boost
+ {
+ namespace filesystem
+ {
+ template <class Path> class basic_directory_entry
+ {
+ public:
+ typedef Path path_type;
+ typedef typename Path::string_type string_type;
+
+ // constructors
+ basic_directory_entry();
+ explicit basic_directory_entry(const path_type& p,
+ <span style="background-color: #FFFFFF">file_status</span> st=file_status(), <span style="background-color: #FFFFFF">file_status</span> symlink_st=file_status());
+
+ // modifiers
+ void assign(const path_type& p, <span style="background-color: #FFFFFF">file_status</span> st=file_status(), <span style="background-color: #FFFFFF">file_status</span> symlink_st=file_status());
+ void replace_filename(const string_type& s, <span style="background-color: #FFFFFF">file_status</span> st=file_status(), <span style="background-color: #FFFFFF">file_status</span> symlink_st=file_status());
+
+ // observers
+ const Path& path() const;
+ operator const Path&() const;
+<span style="background-color: #FFFFFF">
+ file_status status() const;
+ file_status status(error_code& ec) const;
+ file_status symlink_status() const;
+ file_status symlink_status(error_code& ec) const;
+</span><span style="background-color: #FFFF00">
+</span> // comparisons
+ bool operator<(const basic_directory_entry<Path>& rhs);
+ bool operator==(const basic_directory_entry<Path>& rhs);
+ bool operator!=(const basic_directory_entry<Path>& rhs);
+ bool operator>(const basic_directory_entry<Path>& rhs);
+ bool operator<=(const basic_directory_entry<Path>& rhs);
+ bool operator>=(const basic_directory_entry<Path>& rhs);
+
+ private:
+ path_type m_path; // for exposition only
+ mutable <span style="background-color: #FFFFFF">file_status</span> m_status; // for exposition only; stat()-like
+ mutable <span style="background-color: #FFFFFF">file_status</span> m_symlink_status; // for exposition only; lstat()-like
+ };
+
+ } // namespace filesystem
+ } // namespace boost</pre>
+<p>A <code>basic_directory_entry</code> object stores a <code>basic_path object</code>,
+a <code>file_status</code> object for non-symbolic link status, and a <code>
+file_status</code> object for symbolic link status. The <code>file_status</code>
+objects act as value caches.</p>
+<blockquote>
+<p>[<i>Note:</i> Because <code>status()</code>on a pathname may be a very expensive operation,
+some operating systems provide status information as a byproduct of directory
+iteration. Caching such status information can result is significant time savings. Cached and
+non-cached results may differ in the presence of race conditions. <i>-- end note</i>]</p>
+<p><span style="background-color: #E0E0E0"><i>Actual cold-boot timing of iteration over
+a directory with 15,047 entries was six seconds for non-cached status queries
+versus one second for cached status queries. Windows XP, 3.0 GHz processor, with
+a moderately fast hard-drive. Similar speedup expected on Linux and BSD-derived
+Unix variants that provide status during directory iteration.</i></span></p>
+</blockquote>
+<h4> <a name="basic_directory_entry-constructors"> <code>basic_directory_entry </code>constructors</a></h4>
+<pre>basic_directory_entry();</pre>
+<blockquote>
+ <p><i>Postconditions:</i></p>
+ <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="36%">
+ <tr>
+ <td width="18%"><b>Expression</b></td>
+ <td width="82%"><b>Value</b></td>
+ </tr>
+ <tr>
+ <td width="18%"><code>path().empty()</code></td>
+ <td width="82%"><code>true</code></td>
+ </tr>
+ <tr>
+ <td width="18%"><code>status()</code></td>
+ <td width="82%"><code>file_status()</code></td>
+ </tr>
+ <tr>
+ <td width="18%"><code>symlink_status()</code></td>
+ <td width="82%"><code>file_status()</code></td>
+ </tr>
+ </table>
+</blockquote>
+<pre>explicit basic_directory_entry(const path_type& p, <span style="background-color: #FFFFFF">file_status</span> st=file_status(), <span style="background-color: #FFFFFF">file_status</span> symlink_st=file_status());</pre>
+<blockquote>
+ <p><i>Postconditions:</i></p>
+ <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="36%">
+ <tr>
+ <td width="18%"><b>Expression</b></td>
+ <td width="82%"><b>Value</b></td>
+ </tr>
+ <tr>
+ <td width="18%"><code>path()</code></td>
+ <td width="82%"><code>p</code></td>
+ </tr>
+ <tr>
+ <td width="18%"><code>status()</code></td>
+ <td width="82%"><code>st</code></td>
+ </tr>
+ <tr>
+ <td width="18%"><code>symlink_status()</code></td>
+ <td width="82%"><code>symlink_st</code></td>
+ </tr>
+ </table>
+</blockquote>
+<h4> <a name="basic_directory_entry-modifiers"> <code>basic_directory_entry </code>modifiers</a></h4>
+<pre>void assign(const path_type& p, <span style="background-color: #FFFFFF">file_status</span> st=file_status(), <span style="background-color: #FFFFFF">file_status</span> symlink_st=file_status());</pre>
+<blockquote>
+ <p><i>Postconditions:</i></p>
+ <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="36%">
+ <tr>
+ <td width="18%"><b>Expression</b></td>
+ <td width="82%"><b>Value</b></td>
+ </tr>
+ <tr>
+ <td width="18%"><code>path()</code></td>
+ <td width="82%"><code>p</code></td>
+ </tr>
+ <tr>
+ <td width="18%"><code>status()</code></td>
+ <td width="82%"><code>st</code></td>
+ </tr>
+ <tr>
+ <td width="18%"><code>symlink_status()</code></td>
+ <td width="82%"><code>symlink_st</code></td>
+ </tr>
+ </table>
+</blockquote>
+<pre>void replace_filename(const string_type& s, <span style="background-color: #FFFFFF">file_status</span> st=file_status(), <span style="background-color: #FFFFFF">file_status</span> symlink_st=file_status());</pre>
+<blockquote>
+ <p><i>Postconditions:</i></p>
+ <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="43%">
+ <tr>
+ <td width="18%"><b>Expression</b></td>
+ <td width="82%"><b>Value</b></td>
+ </tr>
+ <tr>
+ <td width="18%"><code>path()</code></td>
+ <td width="82%"><code>path().branch() / s</code></td>
+ </tr>
+ <tr>
+ <td width="18%"><code>status()</code></td>
+ <td width="82%"><code>st</code></td>
+ </tr>
+ <tr>
+ <td width="18%"><code>symlink_status()</code></td>
+ <td width="82%"><code>symlink_st</code></td>
+ </tr>
+ </table>
+</blockquote>
+<h4> <a name="basic_directory_entry-observers"> <code>basic_directory_entry</code> observers</a></h4>
+<pre>const Path& path() const;
+operator const Path&() const;</pre>
+<blockquote>
+ <p><i>Returns:</i> <code>m_path</code></p>
+</blockquote>
+<pre><span style="background-color: #FFFFFF">file_status status() const;</span></pre>
+<blockquote>
+<p><span style="font-style: italic; background-color: #FFFFFF">Effects:</span><span style="background-color: #FFFFFF">
+As if,</span></p>
+ <blockquote>
+ <pre><span style="background-color: #FFFFFF">if ( !status_known( m_status ) )
+{
+ if ( status_known(m_symlink_status) && !is_symlink(m_symlink_status) )
+ { m_status = m_symlink_status; }
+ else { m_status = status(m_path); }
+}</span></pre>
+ </blockquote>
+ <p><span style="background-color: #FFFFFF"><i>Throws:</i> See <code>status</code>
+ function.</span></p>
+ <p><span style="background-color: #FFFFFF"><i>Returns:</i> <code>m_status</code></span></p>
+</blockquote>
+<pre><span style="background-color: #FFFFFF">file_status status(error_code& ec) const;</span></pre>
+<blockquote>
+<p><span style="font-style: italic; background-color: #FFFFFF">Effects:</span><span style="background-color: #FFFFFF">
+As if,</span></p>
+ <blockquote>
+ <pre><span style="background-color: #FFFFFF">if ( !status_known( m_status ) )
+{
+ if ( status_known(m_symlink_status) && !is_symlink(m_symlink_status) )
+ { m_status = m_symlink_status; }
+ else { m_status = status(m_path, ec); }
+}
+else ec = 0;</span></pre>
+ </blockquote>
+ <p><span style="background-color: #FFFFFF"><i>Returns:</i> <code>m_status</code></span></p>
+</blockquote>
+<pre><span style="background-color: #FFFFFF">file_status symlink_status() const;</span></pre>
+<blockquote>
+<p><span style="font-style: italic; background-color: #FFFFFF">Effects:</span><span style="background-color: #FFFFFF">
+As if,</span></p>
+ <blockquote>
+ <pre><span style="background-color: #FFFFFF">if ( !status_known( m_symlink_status ) )
+{
+ m_symlink_status = symlink_status(m_path);
+}</span></pre>
+ </blockquote>
+ <p><span style="background-color: #FFFFFF"><i>Throws:</i> See <code>symlink_status</code>
+ function.</span></p>
+ <p><span style="background-color: #FFFFFF"><i>Returns:</i> <code>
+ m_symlink_status</code></span></p>
+</blockquote>
+<pre><span style="background-color: #FFFFFF">file_status symlink_status(error_code& ec) const;</span></pre>
+<blockquote>
+<p><span style="font-style: italic; background-color: #FFFFFF">Effects:</span><span style="background-color: #FFFFFF">
+As if,</span></p>
+ <blockquote>
+ <pre><span style="background-color: #FFFFFF">if ( !status_known( m_symlink_status ) )
+{
+ m_symlink_status = symlink_status(m_path, ec);
+}
+else ec = 0;</span></pre>
+ </blockquote>
+ <p><span style="background-color: #FFFFFF"><i>Returns:</i> <code>m_symlink_status</code></span></p>
+</blockquote>
+<h3><a name="Class-template-basic_directory_iterator">Class template <code>basic_directory_iterator</code></a></h3>
+<pre> namespace boost
+ {
+ namespace filesystem
+ {
+ template <class Path>
+ class basic_directory_iterator :
+ public iterator<input_iterator_tag, basic_directory_entry<Path> >
+ {
+ public:
+ typedef Path path_type;
+
+ // constructors
+ basic_directory_iterator();
+ explicit basic_directory_iterator(const Path& dp);
+ basic_directory_iterator(const Path& dp, error_code& ec);
+ basic_directory_iterator(const basic_directory_iterator& bdi);
+ basic_directory_iterator& operator=(const basic_directory_iterator& bdi);
+ ~basic_directory_iterator();
+
+ // other members as required by
+ // C++ Std, 24.1.1 Input iterators [lib.input.iterators]
+ };
+
+ } // namespace filesystem
+ } // namespace boost</pre>
+<p> <code>basic_directory_iterator</code> satisfies the requirements of an
+input iterator (C++ Std, 24.1.1, Input iterators [lib.input.iterators]).</p>
+<p>A <code>basic_directory_iterator</code> reads successive elements from the directory for
+which it was constructed, as if by calling <i>POSIX</i>
+<code>
+readdir_r()</code>. After a <code>basic_directory_iterator</code> is constructed, and every time
+<code>operator++</code> is called,
+it reads and stores a value of <code>basic_directory_entry<Path></code>
+and possibly stores associated status values.
+<code>operator++</code> is not equality preserving; that is, <code>i == j</code> does not imply that
+<code>++i == ++j</code>. </p>
+<blockquote>
+<p>[<i>Note:</i> The practical consequence of not preserving equality is that directory iterators
+can be used only for single-pass algorithms. <i>--end note</i>]</p>
+</blockquote>
+<p>If the end of the directory elements is reached, the iterator becomes equal to
+the end iterator value. The constructor <code>basic_directory_iterator()</code>
+with no arguments always constructs an end iterator object, which is the only
+legitimate iterator to be used for the end condition. The result of <code>
+operator*</code> on an end iterator is not defined. For any other iterator value
+a <code>const basic_directory_entry<Path>&</code> is returned. The result of
+<code>operator-></code> on an end iterator is not defined. For any other
+iterator value a <code>const basic_directory_entry<Path>*</code> is
+returned. </p>
+<p>Two end iterators are always equal. An end iterator is not equal to a non-end
+iterator.</p>
+<blockquote>
+<p><i><span style="background-color: #E0E0E0">The above wording is based on the
+Standard Library's istream_iterator wording. Commentary was shortened and
+moved into a note.</span></i></p>
+</blockquote>
+<p>The result of calling the <code>path()</code> member of the <code>
+basic_directory_entry</code> object obtained by dereferencing a <code>
+basic_directory_iterator</code> is a reference to a <code>basic_path</code>
+object composed of the directory argument from which the iterator was
+constructed with filename of the directory entry appended as if by <code>
+operator/=</code>. </p>
+<blockquote>
+<p>[<i><a name="Example-program">Example</a>: </i>This program accepts an
+optional command line argument, and if that argument is a directory pathname,
+iterates over the contents of the directory. For each directory entry, the name
+is output, and if the entry is for a regular file, the size of the file is
+output.</p>
+ <blockquote>
+ <pre>#include <iostream>
+#include <filesystem>
+
+using std::tr2::sys;
+using std::cout;
+
+int main(int argc, char* argv[])
+{
+ std::string p(argc <= 1 ? "." : argv[1]);
+
+ if (is_directory(p))
+ {
+ for (directory_iterator itr(p); itr!=directory_iterator(); ++itr)
+ {
+ cout << itr->path().filename() << ' '; // display filename only
+ if (is_regular_file(itr->status())) cout << " [" << file_size(itr->path()) << ']';
+ cout << '\n';
+ }
+ }
+ else cout << (exists(p) : "Found: " : "Not found: ") << p << '\n';
+
+ return 0;
+}</pre>
+ </blockquote>
+ <p><i>-- end example</i>]</p>
+</blockquote>
+<p>Directory iteration shall not yield directory entries for the current (<i>dot</i>)
+and parent (<i>dot dot</i>) directories.</p>
+<p>The order of directory entries obtained by dereferencing successive
+increments of a <code>basic_directory_iterator</code> is unspecified.</p>
+<blockquote>
+<p>[<i>Note:</i> Programs performing directory iteration may wish to test if the
+path obtained by dereferencing a directory iterator actually exists. It could be
+a
+symbolic link to a non-existent file. Programs recursively
+walking directory trees for purposes of removing and renaming entries may wish
+to avoid following symbolic links.</p>
+<p>If a file is removed from or added to a directory after the
+construction of a <code>basic_directory_iterator</code> for the directory, it is
+unspecified whether or not subsequent incrementing of the iterator will ever
+result in an iterator whose value is the removed or added directory entry. See
+<i>POSIX</i>
+<code>
+readdir_r()</code>. <i>
+--end note</i>]</p>
+</blockquote>
+<h4><a name="basic_directory_iterator-constructors"><code>basic_directory_iterator</code> constructors</a></h4>
+
+<p><code>basic_directory_iterator();</code></p>
+
+<blockquote>
+
+<p><i>Effects:</i> Constructs the end iterator.</p>
+
+</blockquote>
+
+<p><code>explicit basic_directory_iterator(const Path& dp);</code></p>
+
+<blockquote>
+
+<p><i>Effects:</i> Constructs a iterator representing the first
+entry in the directory resolved to by <code>dp</code>, otherwise, the end iterator.</p>
+
+<p>[<i>Note:</i> To iterate over the current directory, write <code>
+directory_iterator(".")</code> rather than <code>directory_iterator("")</code>.
+<i>-- end note</i>]</p>
+</blockquote>
+<pre><code>basic_directory_iterator(const Path& dp, error_code& ec );</code></pre>
+<blockquote>
+
+<p><i>Effects:</i> Constructs a iterator representing the first
+entry in the directory resolved to by <code>dp</code>, otherwise, the end iterator.
+If an error occurs while establishing the results, the iterator constructed
+represents the end iterator and <code>ec</code> is set to the error code
+reported by the operating system, otherwise to 0.</p>
+
+</blockquote>
+<h3><a name="Class-template-basic_recursive_directory_iterator">Class template <code>basic_recursive_directory_iterator</code></a></h3>
+<pre> namespace boost
+ {
+ namespace filesystem
+ {
+ template <class Path>
+ class basic_recursive_directory_iterator :
+ public iterator<input_iterator_tag, basic_directory_entry<Path> >
+ {
+ public:
+ typedef Path path_type;
+
+ // constructors
+ basic_recursive_directory_iterator();
+ explicit basic_recursive_directory_iterator(const Path& dp);
+ basic_recursive_directory_iterator(const basic_recursive_directory_iterator& brdi);
+ basic_recursive_directory_iterator& operator=(const basic_recursive_directory_iterator& brdi);
+ ~basic_recursive_directory_iterator();
+
+ // observers
+ int level() const;
+
+ // modifiers
+ void pop();
+ void no_push();
+
+ // other members as required by
+ // C++ Std, 24.1.1 Input iterators [lib.input.iterators]
+
+ private:
+ int m_level; // for exposition only
+ };
+
+ } // namespace filesystem
+ } // namespace boost</pre>
+<p>The behavior of a <code>basic_recursive_directory_iterator</code> is the same
+as a <code>basic_directory_iterator</code> unless otherwise specified.</p>
+<ul>
+ <li>When an iterator is constructed, <code>m_level</code> is set to 0;</li>
+ <li>When an iterator <code>it</code> is incremented, if <code>it->is_directory()</code>
+ is true and <code>no_push()</code> had not been called subsequent to
+ the most recent increment operation (or construction, if no increment has
+ occurred), then <code>m_level</code> is incremented, the
+ directory is visited, and its contents recursively iterated over.</li>
+ <li>When an iterator reaches the end of the directory currently being iterated
+ over, or when <code>pop()</code> is called, <code>m_level</code> is
+ decremented, and iteration continues with the parent directory, until the
+ directory specified in the constructor argument is reached.</li>
+ <li><code>level()</code> returns <code>m_level</code>.</li>
+ <li><code>level()</code>, <code>pop()</code>, and <code>no_push()</code> all
+ require that the iterator not be the end iterator.</li>
+</ul>
+<blockquote>
+ <p>[<i>Note:</i> One of the uses of <code>no_push()</code> is to prevent
+ unwanted recursion into symlinked directories. This may be necessary to
+ prevent loops on some operating systems. <i>--end note</i>]</p>
+</blockquote>
+<h3><a name="file_status">Class file_status</a></h3>
+<pre> namespace boost
+ {
+ namespace filesystem
+ {
+ class file_status
+ {
+ public:
+ explicit file_status( file_type v = status_unknown );
+
+ file_type type() const;
+ void type( file_type v );
+ };
+ } // namespace filesystem
+ } // namespace boost</pre>
+<p>A <code>file_status</code> object stores information about the status of a
+file. The internal form of the stored information is unspecified.</p>
+<blockquote>
+ <p><i>[Note: </i>The class may be extended in the future to store
+ additional status information. <i>--end note]</i></p>
+</blockquote>
+<h4>Members</h4>
+<pre>explicit file_status( file_type v = status_unknown );</pre>
+<blockquote>
+ <p><i>Effects:</i> Stores <code>v</code>.</p>
+</blockquote>
+<pre>file_type type() const;</pre>
+<blockquote>
+ <p><i>Returns: </i>The stored <code>file_type</code>.</p>
+</blockquote>
+<pre>void type( file_type v );</pre>
+<blockquote>
+ <p><i>Effects:</i> Stores <code>v</code>, replacing the previously stored
+ value.</p>
+</blockquote>
+<h3><a name="Non-member-functions">Non-member operational functions</a></h3>
+<h4><a name="Status-functions">Status functions</a></h4>
+<pre>template <class Path> file_status status(const Path& p, error_code& ec);
+template <class Path> file_status <a name="symlink_status">symlink_status</a>(const Path& p, error_code& ec);</pre>
+<blockquote>
+ <p><i>Returns:</i></p>
+ <blockquote>
+ For <code>status</code>, determine the attributes
+ of
+ <code>p</code> as if by<i> POSIX </i> <code>
+ stat()</code>,
+ for <code>symlink_status</code>, determine the attributes as if by <i>POSIX </i> <code>
+ <a href="http://www.opengroup.org/onlinepubs/000095399/functions/lstat.html">
+ lstat()</a></code>.<blockquote>
+ <p>[<i>Note:</i> For symbolic links, <code>stat()</code> continues
+ pathname resolution using the contents of the symbolic link, <code>lstat()</code>
+ does not. <i>--
+ end note</i>]</p>
+ </blockquote>
+ <p>If the underlying file system reports an error during attribute determination:</p>
+ <ul>
+ <li>If the error indicating that <code>p</code> could not be resolved, as
+ if by POSIX errors ENOENT or ENOTDIR, call <code>ec.clear()</code> and return <code>
+ file_status(not_found_flag)</code>.</li>
+ </ul>
+ <blockquote>
+ <blockquote>
+ <p>[<i>Note:</i> The effect of this behavior is to distinguish between
+ knowing that p
+ does not exist, and not being able to determine the status of p. This
+ distinction is important to users. <i>--end note</i>]</p>
+ </blockquote>
+ </blockquote>
+ <ul>
+ <li>Otherwise, set ec to the error number reported by the underlying
+ implementation API
+ and return <code>
+ file_status(status_unknown)</code>.</li>
+ </ul>
+ Otherwise:<ul>
+ <li>If the attributes indicate a regular file, as if by <i>POSIX</i> S_ISREG(),
+ return <code>
+ file_status(regular_file)</code>.</li>
+ <li>Else if the attributes indicate a directory, as if by <i>POSIX</i> S_ISDIR(),
+ return <code>
+ file_status(directory_file)</code>.</li>
+ <li>Else if the attributes indicate a symbolic link, as if by <i>POSIX</i> S_ISLNK(),
+ return <code>
+ file_status(symlink_file)</code>. <i>[Note: </i>Only possible for <code>
+ symlink_status</code>. <i>--end note]</i></li>
+ <li>Else if the attributes indicate a block special file, as if by <i>POSIX</i> S_ISBLK(),
+ return <code>
+ file_status(block_file)</code>.</li>
+ <li>Else if the attributes indicate a character special file, as if by <i>POSIX</i> S_ISCHR(),
+ return <code>
+ file_status(character_file)</code>.</li>
+ <li>Else if the attributes indicate a fifo or pipe file, as if by <i>POSIX</i> S_ISFIFO(),
+ return <code>
+ file_status(fifo_file)</code>.</li>
+ <li>Else if the attributes indicate a socket, as if by <i>POSIX</i> S_ISSOCK(),
+ return <code>
+ file_status(socket_file)</code>.</li>
+ <li>Else return <code>
+ file_status(type_unknown)</code>.</li>
+ </ul>
+ </blockquote>
+<p>[<i>Note:</i> <code>directory_file</code> implies <code>
+basic_directory_iterator</code> on the file would succeed, and <code>
+regular_file</code> implies appropriate <code><fstream></code> operations would succeed,
+assuming no hardware, permission, access, or race
+condition errors. For <code>regular_file,</code> the converse is not true; lack of
+<code>regular_file</code> does not necessarily imply <code><fstream></code> operations would
+fail on a directory.
+<i>-- end note</i>]</p>
+</blockquote>
+<pre>template <class Path> file_status status(const Path& p);</pre>
+<blockquote>
+ <p><i>Effects:</i> <code>system_error_code ec;</code><br>
+
+ <code>file_status stat(status(p, ec));</code></p>
+ <p><i>Throws:</i> <code>basic_filesystem_error<Path></code> if <code>ec
+ != 0</code></p>
+ <p><i>Returns:</i> <code>stat</code></p>
+</blockquote>
+<pre>template <class Path> file_status symlink_status(const Path& p);</pre>
+<blockquote>
+ <p><i>Effects:</i> <code>system_error_code ec;</code><br>
+
+ <code>file_status stat(symlink_status(p, ec));</code></p>
+ <p><i>Throws:</i> <code>basic_filesystem_error<Path></code> if <code>ec
+ != 0</code></p>
+ <p><i>Returns: </i><code>stat</code></p>
+</blockquote>
+<h4><a name="Predicate-functions">Predicate functions</a></h4>
+<pre><span style="background-color: #FFFFFF">bool <a name="status_known">status_known</a>(file_status s);</span></pre>
+<blockquote>
+ <p><i><span style="background-color: #FFFFFF">Returns:</span></i><span style="background-color: #FFFFFF">
+ <code>s.type() != status_unknown</code></span></p>
+</blockquote>
+<pre><span style="background-color: #FFFFFF">bool </span><a name="exists"><span style="background-color: #FFFFFF">exists</span></a><span style="background-color: #FFFFFF">(file_status</span><span style="background-color: #FFFFFF"> s);</span></pre>
+<blockquote>
+ <p><i><span style="background-color: #FFFFFF">Returns:</span></i><span style="background-color: #FFFFFF">
+ <code>status_known(s) && s.type() != file_not_found</code></span></p>
+</blockquote>
+<pre>template <class Path> bool <a name="exists">exists</a>(const Path& p);</pre>
+<blockquote>
+ <p><i>Returns:</i> <code>exists( status(p) )</code></p>
+</blockquote>
+<pre><span style="background-color: #FFFFFF">bool </span><code><span style="background-color: #FFFFFF">is_regular_file</span></code><span style="background-color: #FFFFFF">(file_status</span><span style="background-color: #FFFFFF"> s);</span></pre>
+<blockquote>
+ <p><i><span style="background-color: #FFFFFF">Returns:</span></i><span style="background-color: #FFFFFF">
+ <code>s.type() == regular_file</code></span></p>
+</blockquote>
+<pre><code>template <class Path> bool is_regular_file(const Path& p);</code></pre>
+<blockquote>
+ <p><i>Returns:</i> <code>is_regular_file( status(p) )</code></p>
+</blockquote>
+<pre><span style="background-color: #FFFFFF">bool </span><code><span style="background-color: #FFFFFF">is_directory</span></code><span style="background-color: #FFFFFF">(file_status</span><span style="background-color: #FFFFFF"> s);</span></pre>
+<blockquote>
+ <p><i><span style="background-color: #FFFFFF">Returns:</span></i><span style="background-color: #FFFFFF"> </span>
+ <code><span style="background-color: #FFFFFF">s.type() == directory_file</span></code></p>
+</blockquote>
+<pre><code>template <class Path> bool is_directory(const Path& p);</code></pre>
+<blockquote>
+ <p><i>Returns:</i> <code>is_directory( status(p) )</code></p>
+</blockquote>
+<pre><span style="background-color: #FFFFFF">bool <a name="exists">is_symlink</a>(file_status s);</span></pre>
+<blockquote>
+ <p><i><span style="background-color: #FFFFFF">Returns:</span></i><span style="background-color: #FFFFFF"> </span>
+ <code><span style="background-color: #FFFFFF">s.type() == symlink_file</span></code></p>
+</blockquote>
+<pre><code>template <class Path> bool is_symlink(const Path& p);</code></pre>
+<blockquote>
+ <p><i>Returns:</i> <code>is_symlink( symlink_status(p) )</code></p>
+</blockquote>
+<pre><span style="background-color: #FFFFFF">bool <a name="exists">is_other</a>(file_status s);</span></pre>
+<blockquote>
+ <p><i><span style="background-color: #FFFFFF">Returns:</span></i><span style="background-color: #FFFFFF">
+ <code>return exists(s) && !is_regular_file(s) && !is_directory(s) && !is_symlink(s)</code></span></p>
+ <p><span style="background-color: #FFFFFF">[<i>Note: </i>The specification of
+ <code>is_other()</code> will remain unchanged even if additional <code>is_xxx()</code>
+ functions are added in the future. <i>-- end note</i>]</span></p>
+</blockquote>
+<pre><code>template <class Path> bool is_other(const Path& p);</code></pre>
+<blockquote>
+ <p><i>Returns:</i> <code>is_other( status(p) )</code></p>
+</blockquote>
+<pre><code>template <class Path> bool <span style="background-color: #FFFFFF; text-decoration:underline">is_</span>empty(const Path& p);</code></pre>
+<blockquote>
+ <p><i>Effects:</i> Determines <code>file_status s</code>, as if by <code>
+ status(p)</code>.</p>
+ <p><i>Throws:</i> <code>basic_filesystem_error<Path></code> if <code>!exist(s) ||
+ is_other(s)</code>.</p>
+ <p><i>Returns:</i> <code>is_directory(s)<br>
+ ?
+ basic_directory_iterator<Path>(p) == basic_directory_iterator<Path>()<br>
+ : file_size(p) == 0;</code></p>
+</blockquote>
+<pre><code>template <class Path1, class Path2> bool <a name="equivalent">equivalent</a>(const Path1& p1, const Path2& p2);</code></pre>
+<blockquote>
+ <p><i>Requires:</i> <code>Path1::external_string_type</code> and <code>
+ Path2::external_string_type</code> are the same type. </p>
+ <p><i>Effects:</i> Determines <code>file_status s1</code> and <code>s2</code>,
+ as if by <code>status(p1)</code> and <code>status(p2)</code>,
+ respectively.</p>
+ <p><i>Throws:</i> <code>basic_filesystem_error<Path1></code><span style="background-color: #FFFFFF"> </span>
+ if <code>(!exists(s1) && !exists(s2)) || (is_other(s1) &&
+ is_other(s2))</code>.</p>
+ <p><i>Returns:</i> <code>true</code>, if <code>sf1 == sf2</code> and <code>p1</code> and <code>p2</code>
+ resolve to the same file system entity, else <code>false</code>.</p>
+ <p>Two paths are considered to resolve to
+ the same file system entity if two candidate entities reside on the same
+ device at the same location. This is determined as if by the values of the <i>POSIX</i> <code>
+ stat</code>
+ structure<code>,</code> obtained as if by <code>
+ stat()</code> for the two paths, having equal
+ <code>st_dev</code> values and equal <code>st_ino</code> values.</p>
+ <p>[<i>Note:</i> <i>POSIX</i> requires that <i>"st_dev</i> must be unique
+ within a Local Area Network". Conservative <i>POSIX</i> implementations may
+ also wish to check for equal <code>st_size</code> and <code>st_mtime</code>
+ values. <i>Windows</i> implementations may use <code>GetFileInformationByHandle()</code> as a surrogate for <code>
+ stat()</code>, and consider "same" to be equal values for <code>
+ dwVolumeSerialNumber</code>, <code>nFileIndexHigh</code>, <code>
+ nFileIndexLow</code>, <code>nFileSizeHigh</code>, <code>nFileSizeLow</code>,
+ <code>ftLastWriteTime.dwLowDateTime</code>, and <code>
+ ftLastWriteTime.dwHighDateTime</code>. <i>-- end note</i>]</p>
+</blockquote>
+<h4><a name="Attribute-functions">Attribute functions</a></h4>
+<p>[<i>Note:</i> A strictly limited number of attribute functions are provided
+because few file system attributes are portable. Even the functions provided will be impossible to implement on some file
+systems. <i>--end note</i>.]</p>
+<pre>template <class Path> const Path& <a name="initial_path">initial_path</a>();</pre>
+<blockquote>
+ <p><i>Returns:</i> <code>current_path()</code> at the time of entry to <code>
+ main()</code>.</p>
+ <p>[<i>Note:</i> These semantics turn a dangerous global variable into a safer
+ global constant. <i>--end note</i>]</p>
+ <p>[<i>Note:</i> Full implementation requires runtime library support.
+ Implementations which cannot provide runtime library support are encouraged to
+ instead store the value of <code>current_path()</code> at the first call of
+ <a name="initial_path"><code>initial_path</code></a><code>()</code>, and
+ return this value for all subsequent calls. Programs using
+ <a name="initial_path"><code>initial_path</code></a><code>()</code> are
+ encouraged to call it immediately on entrance to <code>main()</code> so that
+ they will work correctly with such partial implementations. <i>--end note</i>]</p>
+</blockquote>
+<pre>template <class Path> Path current_path();</pre>
+<blockquote>
+ <p><i>Returns:</i> The current path, as if by <i>POSIX</i>
+ <a href="http://www.opengroup.org/onlinepubs/000095399/functions/getcwd.html">
+ <code>getcwd()</code></a>.</p>
+ <p><i>Postcondition:</i> <code>current_path().is_complete()</code></p>
+ <p>[<i>Note:</i> The current path as returned by many operating systems is a
+ dangerous global variable. It may be changed unexpectedly by a third-party or
+ system library functions, or by another thread. Although dangerous, the
+ function is useful in dealing with other libraries.. For a safer alternative,
+ see <code>initial_path()</code>. The <code>
+ current_path()</code> name was chosen to emphasize that the return is a
+ complete path, not just a single directory name. <i>-- </i><i>end note</i>]</p>
+</blockquote>
+<pre>template <class Path> void current_path(const Path& p);</pre>
+<blockquote>
+<p><i>Postcondition:</i> equivalent( p, current_path() );</p>
+</blockquote>
+<pre>template <class Path> <span style="background-color: #FFFFFF; ">uintmax_t</span> file_size(const Path& p);</pre>
+<blockquote>
+ <p><i>Returns:</i> The size
+ <span style="background-color: #FFFFFF; ">in bytes</span>
+ of the file <code>p</code> resolves to, determined as if by the value of
+ the <i>POSIX</i> <code>
+ stat</code> structure member <code>st_size</code>
+ obtained as if by <i>POSIX</i> <code>
+ stat()</code>.</p>
+</blockquote>
+<pre><span style="background-color: #FFFFFF"><a name="space">template</a> <class Path> space_info space(const Path& p);</span></pre>
+<blockquote>
+ <p><span style="background-color: #FFFFFF"><i>Returns:</i> A <code>space_info</code>
+ object. The value of the <code>space_info</code> object is determined as if by
+ using </span> <i><span style="background-color: #FFFFFF">POSIX</span></i><span style="background-color: #FFFFFF"> <code>
+ <a href="http://www.opengroup.org/onlinepubs/000095399/functions/statvfs.html" style="text-decoration: none">
+ statvfs()</a></code> to obtain a <i>POSIX</i> struct <code>
+ <a href="http://www.opengroup.org/onlinepubs/000095399/basedefs/sys/statvfs.h.html" style="text-decoration: none">
+ statvfs</a></code>, and then multiplying its <code>f_blocks</code>, <code>
+ f_bfree</code>, and <code>f_bavail</code> members by its <code>f_frsize</code>
+ member, and assigning the results to the <code>capacity</code>, <code>free</code>,
+ and <code>available</code> members respectively. Any members for which the
+ value cannot be determined shall be set to -1.</span></p>
+</blockquote>
+<pre>template <class Path> std::time_t last_write_time(const Path& p);</pre>
+<blockquote>
+ <p><i>Returns:</i> The time of last data modification of <code>p</code>, determined as if by the
+ value of the <i>POSIX</i> <code>
+ stat</code> structure member <code>st_mtime</code> obtained
+ as if by <i>POSIX</i> <code>
+ stat()</code>.</p>
+</blockquote>
+<pre>template <class Path> void last_write_time(const Path& p, const std::time_t new_time);</pre>
+<blockquote>
+ <p><i>Effects:</i> Sets the time of last data modification of the file
+ resolved to by <code>p</code>
+ to <code>new_time</code>, as if by <i>POSIX</i> <code>
+ stat()</code>
+ followed by <i>POSIX</i>
+ <a href="http://www.opengroup.org/onlinepubs/000095399/functions/utime.html">
+ <code>utime()</code></a>.</p>
+ <p>[<i>Note:</i> The apparent postcondition <code>last_write_time(p) ==
+ new_time</code> is not specified since it would not hold for many file systems
+ due to coarse time mechanism granularity. <i>-- end note</i>]</p>
+</blockquote>
+<h4>Other o<a name="Operations-functions">perations functions</a></h4>
+<pre>template <class Path> bool create_directory(const Path& dp);</pre>
+<blockquote>
+ <p><i>Effects:</i> Attempts to create the directory <code>dp</code> resolves to,
+ as if by<i> POSIX </i><code>
+ mkdir()</code> with a second argument of S_IRWXU|S_IRWXG|S_IRWXO. </p>
+ <p><i>Throws:</i> <code>basic_filesystem_error<Path></code> if <i>
+ Effects</i> fails for any reason other than because the directory already exists.</p>
+ <p><i>Returns:</i> True if a new directory was created, otherwise false.</p>
+ <p><i>Postcondition:</i> <code>is_directory(dp)</code></p>
+</blockquote>
+<pre><span style="background-color: #FFFFFF">template <class Path1, class Path2>
+ error_code create_hard_link(const Path1& to_p, const Path2& from_p, error_code& ec);</span></pre>
+<blockquote>
+ <p><i><span style="background-color: #FFFFFF">Requires:</span></i><span style="background-color: #FFFFFF">
+ </span> <code><span style="background-color: #FFFFFF">Path1::external_string_type</span></code><span style="background-color: #FFFFFF"> and
+ </span> <code>
+ <span style="background-color: #FFFFFF">Path2::external_string_type</span></code><span style="background-color: #FFFFFF"> are the same type.</span></p>
+ <p><i><span style="background-color: #FFFFFF">Effects:</span></i><span style="background-color: #FFFFFF"> Establishes the postcondition, as if by
+ </span> <i><span style="background-color: #FFFFFF">POSIX</span></i><span style="background-color: #FFFFFF">
+ </span> <code>
+ <a href="http://www.opengroup.org/onlinepubs/000095399/functions/link.html">
+ <span style="background-color: #FFFFFF">link()</span></a></code><span style="background-color: #FFFFFF">.</span></p>
+ <p><i><span style="background-color: #FFFFFF">Returns:</span></i><span style="background-color: #FFFFFF"> If the
+ postcondition cannot be established, a system error code
+ indicating the reason for the failure, otherwise 0.</span></p>
+ <p><i><span style="background-color: #FFFFFF">Postcondition:</span></i></p>
+ <ul>
+ <li><span style="background-color: #FFFFFF"> </span><code><span style="background-color: #FFFFFF">exists(to_p) && exists(from_p) && equivalent(to_p,
+ from_p)</span></code></li>
+ <li><span style="background-color: #FFFFFF">The contents of the file or directory
+ </span> <code><span style="background-color: #FFFFFF">to_p</span></code><span style="background-color: #FFFFFF"> resolves to are unchanged.</span></li>
+ </ul>
+ <p><span style="background-color: #FFFFFF">[</span><i><span style="background-color: #FFFFFF">Note:</span></i><span style="background-color: #FFFFFF">
+ Some operating systems do not support hard links or support
+ them only for regular files. Some operating systems limit the number of links per
+ file.
+ Some file systems that do not
+ support
+ hard links - the FAT system used on floppy discs, memory cards and flash
+ drives,
+ for example. Thus hard links should be avoided if wide portability is
+ a concern. </span> <i><span style="background-color: #FFFFFF">-- end note</span></i><span style="background-color: #FFFFFF">]</span></p>
+ </blockquote>
+<pre><span style="background-color: #FFFFFF">template <class Path1, class Path2>
+ void create_hard_link(const Path1& to_p, const Path2& from_p);</span></pre>
+<blockquote>
+ <p><i><span style="background-color: #FFFFFF">Requires:</span></i><span style="background-color: #FFFFFF">
+ </span> <code><span style="background-color: #FFFFFF">Path1::external_string_type</span></code><span style="background-color: #FFFFFF"> and
+ </span> <code>
+ <span style="background-color: #FFFFFF">Path2::external_string_type</span></code><span style="background-color: #FFFFFF"> are the same type.</span></p>
+ <p><i><span style="background-color: #FFFFFF">Effects:</span></i><span style="background-color: #FFFFFF">
+ As if <code>system_error_code ec( create_hard_link( to_p, from_p ) );</code></span></p>
+ <p><span style="font-style: italic; background-color: #FFFFFF">Throws:</span><span style="background-color: #FFFFFF">
+ </span> <code>basic_filesystem_error<Path1, Path2></code><span style="background-color: #FFFFFF">
+ if <code>ec</code> is not zero.</span></p>
+ </blockquote>
+<pre><span style="background-color: #FFFFFF">template <class Path1, class Path2>
+ error_code create_symlink(const Path1& to_p, const Path2& from_p, error_code& ec);</span></pre>
+<blockquote>
+ <p><i><span style="background-color: #FFFFFF">Requires:</span></i><span style="background-color: #FFFFFF">
+ </span> <code><span style="background-color: #FFFFFF">Path1::external_string_type</span></code><span style="background-color: #FFFFFF"> and
+ </span> <code>
+ <span style="background-color: #FFFFFF">Path2::external_string_type</span></code><span style="background-color: #FFFFFF"> are the same type.</span></p>
+ <p><i><span style="background-color: #FFFFFF">Effects:</span></i><span style="background-color: #FFFFFF"> Establishes the postcondition, as if by
+ </span> <i><span style="background-color: #FFFFFF">POSIX</span></i><span style="background-color: #FFFFFF">
+ </span> <code>
+ <span style="background-color: #FFFFFF">
+ <a href="http://www.opengroup.org/onlinepubs/000095399/functions/symlink.html">
+ symlink()</a></span></code><span style="background-color: #FFFFFF">.</span></p>
+ <p><i><span style="background-color: #FFFFFF">Returns:</span></i><span style="background-color: #FFFFFF"> If the
+ postcondition cannot be established, a system error code
+ indicating the reason for the failure, otherwise 0.</span></p>
+ <p><span style="background-color: #FFFFFF"><i>Postcondition:</i> <code>from_p</code>
+ resolves to a symbolic link file that contains an unspecified representation
+ of <code>to_p</code>.</span></p>
+ <p><span style="background-color: #FFFFFF">[</span><i><span style="background-color: #FFFFFF">Note:</span></i><span style="background-color: #FFFFFF">
+ Some operating systems do not support symbolic links at all or support
+ them only for regular files. Thus symbolic links should be avoided if code portability is
+ a concern. </span> <i><span style="background-color: #FFFFFF">-- end note</span></i><span style="background-color: #FFFFFF">]</span></p>
+ </blockquote>
+<pre><span style="background-color: #FFFFFF">template <class Path1, class Path2>
+ void create_symlink(const Path1& to_p, const Path2& from_p);</span></pre>
+<blockquote>
+ <p><i><span style="background-color: #FFFFFF">Requires:</span></i><span style="background-color: #FFFFFF">
+ </span> <code><span style="background-color: #FFFFFF">Path1::external_string_type</span></code><span style="background-color: #FFFFFF"> and
+ </span> <code>
+ <span style="background-color: #FFFFFF">Path2::external_string_type</span></code><span style="background-color: #FFFFFF"> are the same type.</span></p>
+ <p><i><span style="background-color: #FFFFFF">Effects:</span></i><span style="background-color: #FFFFFF">
+ As if <code>system_error_code ec( create_symlink( to_p, from_p ) );</code></span></p>
+ <p><span style="font-style: italic; background-color: #FFFFFF">Throws:</span><span style="background-color: #FFFFFF">
+ </span> <code>basic_filesystem_error<Path1, Path2></code><span style="background-color: #FFFFFF">
+ if <code>ec</code> is not zero.</span></p>
+ </blockquote>
+<pre>template <class Path> void remove(const Path& p, system::error_code & ec = <i>singular</i> );</pre>
+<blockquote>
+ <p><i>Effects:</i> Removes the file <code>p</code>,
+ as if by<i> POSIX </i><code>
+ remove()</code>.
+ If no error is reported by the underlying removal implementation or if <code>
+ status(p).type() == file_not_found</code>, then:</p>
+ <ul>
+ <li>if <code>ec != </code><i><code>singular</code></i>, then <code>ec.clear()</code>.</li>
+ </ul>
+ <p>Otherwise,</p>
+ <ul>
+ <li>if <code>ec != </code><i><code>singular</code></i>, then set <code>ec</code>
+ to represent the error.</li>
+ <li>otherwise, throw <code>basic_filesystem_error<Path></code> to represent
+ the error.if <code>ec != </code><i><code>singular</code></i>, then <code>
+ ec.clear()</code></li>
+ </ul>
+ <p><i>Postcondition:</i> <code>!exists(p)</code></p>
+ <p><i>Throws:</i> See <i>Effects</i>.</p>
+ <p>[<i>Note:</i> A symbolic link is itself removed, rather than the file it
+ resolves to being removed. <i>-- end note</i>]</p>
+</blockquote>
+<pre>template <class Path> unsigned long remove_all(const Path& p);</pre>
+<blockquote>
+ <p><i>Effects:</i> Recursively deletes the contents of p if it exists,
+ then deletes file <code>p</code> itself,
+ as if by<i> POSIX </i><code>
+ remove()</code>.</p>
+ <p><i>Returns:</i> The number of files removed.</p>
+ <p><i>Postcondition:</i> <code>!exists(p)</code></p>
+ <p>[<i>Note:</i> A symbolic link is itself removed, rather than the file it
+ resolves to being removed. <i>-- end note</i>]</p>
+</blockquote>
+<pre>template <class Path1, class Path2> void rename(const Path1& from_p, const Path2& to_p);</pre>
+<blockquote>
+ <p><i>Requires:</i> <code>Path1::external_string_type</code> and <code>
+ Path2::external_string_type</code> are the same type. </p>
+ <p><i>Effects:</i> Renames <code>from_p</code> to <code>to_p</code>, as if by
+ <i>POSIX</i> <code>
+ <a href="http://www.opengroup.org/onlinepubs/000095399/functions/rename.html">
+ rename()</a></code>.</p>
+ <p><i>Postconditions:</i> <code>!exists(from_p) && exists(to_p)</code>, and
+ the contents and attributes of the file originally named <code>from_p</code>
+ are otherwise unchanged.</p>
+ <p>[<i>Note:</i> If <code>from_p</code> and <code>to_p</code> resolve to the
+ same file, no action is taken. Otherwise, if <code>to_p</code> resolves to an
+ existing file, it is removed. A symbolic link is itself renamed, rather than
+ the file it resolves to being renamed. <i>-- end note</i>]</p>
+</blockquote>
+<pre>template <class Path1, class Path2> void copy_file(const Path1& from_fp, const Path2& to_fp);</pre>
+<blockquote>
+ <p><i>Requires:</i> <code>Path1::external_string_type</code> and <code>
+ Path2::external_string_type</code> are the same type. </p>
+ <p><i>Effects:</i> The contents and attributes of the file <code>from_fp</code>
+ resolves to are copied to the file <code>to_fp</code> resolves to.</p>
+ <p><i>Throws:</i> <code>basic_filesystem_error<Path></code> if <code>
+ from_fp.empty() || to_fp.empty() ||!exists(from_fp) || !is_regular_file(from_fp)
+ || exists(to_fp)</code></p>
+</blockquote>
+<pre>template <class Path> Path complete(const Path& p, const Path& base=initial_path<Path>());</pre>
+<blockquote>
+ <p><i>Effects:</i> Composes a complete path from <code>p</code> and <code>base</code>,
+ using the following rules:</p>
+ <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111">
+ <tr>
+ <td align="center"> </td>
+ <td align="center"><b><code>p.has_root_directory()</code></b></td>
+ <td align="center"><b><code>!p.has_root_directory()</code></b></td>
+ </tr>
+ <tr>
+ <td align="center"><b><code>p.has_root_name()</code></b></td>
+ <td align="center"><code>p</code></td>
+ <td align="center">precondition failure</td>
+ </tr>
+ <tr>
+ <td align="center"><b><code>!p.has_root_name()</code></b></td>
+ <td align="center"><code>base.root_name()<br>
+ / p</code></td>
+ <td align="center"><code>base / p</code></td>
+ </tr>
+ </table>
+ <p><i>Returns:</i> The composed path.</p>
+ <p><i>Postcondition:</i> For the returned path, <code>rp,</code> <code>
+ rp.is_complete()</code> is true.</p>
+ <p><i>Throws:</i>
+ <span style="background-color: #FFFFFF">If </span> <code>
+ <span style="background-color: #FFFFFF">!(base.is_complete() && (p.is_complete() || !p.has_root_name()))</span></code></p>
+ <p>[<i><a name="complete_note">Note</a>:</i> When portable behavior is
+ required, use <i>complete()</i>. When operating system dependent behavior is
+ required, use <i>system_complete()</i>.</p>
+ <p>Portable behavior is useful when dealing with paths created
+ internally within a program, particularly if the program should exhibit the
+ same behavior on all operating systems.</p>
+ <p>Operating system dependent behavior is useful when dealing with
+ paths supplied by user input, reported to program users, or when such behavior
+ is expected by program users. <i>--
+ end note</i>]</p>
+</blockquote>
+<pre>template <class Path> Path system_complete(const Path& p);</pre>
+<blockquote>
+ <p><i>Effects:</i> Composes a complete path from <code>p</code>, using the
+ same rules used by the operating system to resolve a path passed as the
+ filename argument to standard library open functions.</p>
+ <p><i>Returns:</i> The composed path.</p>
+ <p><i>Postcondition:</i> For the returned path, <code>rp,</code> <code>
+ rp.is_complete()</code> is true.</p>
+ <p><i>Throws:</i> <span style="background-color: #FFFFFF">If <code>p.empty()</code>.</span></p>
+ <p>[<i>Note:</i> For <i>POSIX</i>, <code>system_complete(p)</code> has the same semantics as
+ <code>complete(p, current_path())</code>.</p>
+ <p><a name="windows_effects">For <i>Windows</i></a>, <code>system_complete(p)</code> has the
+ same semantics as <code>complete(ph, current_path())</code> if
+ <code>p.is_complete() || !p.has_root_name()</code> or <code>p</code> and <code>base</code> have the same
+ <code>root_name()</code>.
+ Otherwise it acts like <code>complete(p, kinky)</code>, where <code>kinky</code>
+ is the current directory for the <code>p.root_name()</code> drive. This will
+ be the current directory of that drive the last time it was set, and thus may
+ be <b>residue left over from a prior program</b> run by the command
+ processor! Although these semantics are often useful, they are also very
+ error-prone.</p>
+ <p>See <a href="#complete_note">
+ <i>complete()</i> note</a> for usage suggestions. <i>-- end note</i>]</p>
+</blockquote>
+<h4><a name="Convenience-functions">Convenience functions</a></h4>
+<pre>template <class Path> bool create_directories(const Path & p);</pre>
+<blockquote>
+ <p><i>Requires:</i> <code>p.empty() || <br>
+ forall px: px == p || is_parent(px, p): is_directory(px) || !exists( px )</code>
+ </p>
+ <p><i>Returns:</i> The value of <code>!exists(p)</code> prior to the
+ establishment of the postcondition.</p>
+ <p><i>Postcondition:</i> <code>is_directory(p)</code></p>
+ <p><i>Throws:</i> <code>basic_filesystem_error<Path></code> if<code>
+ exists(p) && !is_directory(p)</code></p>
+</blockquote>
+<table border="1" cellpadding="5" cellspacing="1" style="border-collapse: collapse" bordercolor="#111111">
+ <tr>
+ <td>
+ <h4>Deprecated convenience functions</h4>
+ <p>The following functions have been replaced by <code>basic_path</code>
+ member functions <code>extension()</code>, <code>stem()</code>, and <code>
+ replace_extension()</code>.</p>
+<pre>template <class Path> typename Path::string_type extension(const Path & p);</pre>
+<blockquote>
+ <p><i>Returns:</i> if <code>p.filename()</code> contains a <i>dot</i>, returns
+ the substring of <code>p.filename()</code> starting at the rightmost <i>dot</i>
+ and ending at the string's end. Otherwise, returns an empty string. </p>
+ <p>[<i>Note:<b> </b></i>The <i>dot</i> is included in the return value so that
+ it is possible to distinguish between no extension and an empty extension. </p>
+ <p>Implementations are permitted but not required to define additional
+ behavior for file systems which append additional elements to extensions, such
+ as alternate data stream or partitioned dataset names. <i>-- end note</i>]</p>
+</blockquote>
+<pre>template <class Path> typename Path::string_type basename(const Path & p);</pre>
+<blockquote>
+ <p><i>Returns:</i> if <code>p.filename()</code> contains a <i>dot</i>, returns
+ the substring of <code>p.filename()</code> starting at its beginning and
+ ending at the last <i>dot</i> (the <i>dot</i> is not included). Otherwise,
+ returns <code>
+ p.filename()</code>.</p>
+</blockquote>
+<pre>template <class Path>
+ Path change_extension(const Path & p, const typename Path::string_type & new_extension);</pre>
+<blockquote>
+ <p><i>Postcondition:</i> <code>basename(<i>return_value</i>) == basename(p) &&
+ extension(<i>return_value</i>) == new_extension</code> </p>
+ <p>[<i>Note:</i> It follows from the semantics of <code>extension()</code>
+ that <code>new_extension</code> should include <i>dot</i> to achieve
+ reasonable results. <i>-- end note</i>]</p>
+</blockquote>
+ </td>
+ </tr>
+</table>
+<h3><a name="header-fstream">Additions</a> to header <code><fstream></code></h3>
+<blockquote>
+<p><span style="background-color: #E0E0E0; font-style:italic">These additions have been carefully
+specified to avoid breaking existing code in common operating environments such as
+</span> <i><span style="background-color: #E0E0E0">POSIX</span></i><span style="background-color: #E0E0E0; font-style:italic">,
+</span> <i>
+<span style="background-color: #E0E0E0">Windows</span></i><span style="background-color: #E0E0E0; font-style:italic">, and
+</span> <i><span style="background-color: #E0E0E0">OpenVMS.
+See </span><a href="#Suggestions-for-fstream">
+<span style="background-color: #E0E0E0">Suggestions for <code><fstream></code>
+implementations</span></a><span style="background-color: #E0E0E0"> for
+techniques to avoid breaking existing code in other environments, particularly
+on operating systems allowing slashes in filenames.</span></i></p>
+<p><span style="background-color: #FFFFFF">[<i>Note:</i> The
+"do-the-right-thing" rule from <a href="#Requirements-on-implementations">
+Requirements on implementations</a> does apply to header <code><fstream></code>.</span></p>
+<p><span style="background-color: #FFFFFF">The overloads
+below are specified as additions rather than replacements for existing
+functions. This preserves existing code (perhaps
+using a <a name="home-grown-path">home-grown path</a> class) that relies on an
+automatic conversion to <code>const char*</code>.<i> -- end note</i>]</span></p>
+</blockquote>
+<p><span style="background-color: #FFFFFF"><i>In 27.8.1.1 Class template
+basic_filebuf [lib.filebuf] synopsis preceding paragraph 1, add the function:</i></span></p>
+<blockquote>
+<pre><span style="background-color: #FFFFFF">template <class Path> </span><span style="background-color: #FFFFFF">basic_filebuf</span><span style="background-color: #FFFFFF"><charT,traits>* </span><span style="background-color: #FFFFFF">open(const</span><span style="background-color: #FFFFFF"> Path& p, </span><span style="background-color: #FFFFFF">ios_base::openmode</span><span style="background-color: #FFFFFF"> mode);</span></pre>
+</blockquote>
+<p><span style="background-color: #FFFFFF"><i>In 27.8.1.3 Member functions [lib.filebuf.members],
+add the above to the signature preceding paragraph 2, and replace the
+sentence:</i></span></p>
+<blockquote>
+<p><span style="background-color: #FFFFFF">It then opens a file, if possible,
+whose name is the NTBS s (âas ifâ by calling <code>std::fopen(s ,<i>modstr</i>
+))</code>.</span></p>
+</blockquote>
+<p><span style="background-color: #FFFFFF"><i>with:</i></span></p>
+<blockquote>
+<p><span style="background-color: #FFFFFF">It then opens, if possible, the file
+that
+<code>p</code> or <code>path(s)</code> resolves to, âas ifâ by calling <code>std::fopen()</code> with a
+second argument of <i>modstr</i>.</span></p>
+</blockquote>
+<p><span style="background-color: #FFFFFF"><i>In 27.8.1.5 Class template
+basic_ifstream [lib.ifstream] synopsis preceding paragraph 1, add the functions:</i></span></p>
+<blockquote>
+ <pre><span style="background-color: #FFFFFF">template <class Path> explicit basic_ifstream(const Path& p, ios_base::openmode mode = ios_base::in);
+template <class Path> void open(const Path& p, ios_base::openmode mode = ios_base::in);</span></pre>
+</blockquote>
+<p><i><span style="background-color: #FFFFFF">In 27.8.1.6 basic_ifstream
+constructors [lib.ifstream.cons] </span></i>
+<span style="background-color: #FFFFFF"><i>add the above constructor to the signature preceding
+paragraph 2, and in paragraph 2 replace</i></span></p>
+<blockquote>
+<p><span style="background-color: #FFFFFF"><code>rdbuf()->open(s, mode |
+ios_base::in)</code></span></p>
+</blockquote>
+<p><span style="background-color: #FFFFFF"><i>with</i></span></p>
+<blockquote>
+<p><span style="background-color: #FFFFFF"><code>rdbuf()->open(path(s), mode |
+ios_base::in)</code> or <code>rdbuf()->open(p, mode | ios_base::in)</code> as
+appropriate</span></p>
+</blockquote>
+<p><i><span style="background-color: #FFFFFF">In 27.8.1.7 Member functions [lib.ifstream.members]
+</span></i><span style="background-color: #FFFFFF"><i>add the above open
+function to the signature
+preceding paragraph 3, and in paragraph 3 replace</i></span></p>
+<blockquote>
+<p><span style="background-color: #FFFFFF"><code>rdbuf()->open(s, mode |
+ios_base::in)</code></span></p>
+</blockquote>
+<p><span style="background-color: #FFFFFF"><i>with</i></span></p>
+<blockquote>
+<p><span style="background-color: #FFFFFF"><code>rdbuf()->open(path(s), mode |
+ios_base::in)</code> or <code>rdbuf()->open(p, mode | ios_base::in)</code> as
+appropriate</span></p>
+</blockquote>
+<p><span style="background-color: #FFFFFF"><i>In 27.8.1.8 Class template
+basic_ofstream [lib.ofstream] synopsis preceding paragraph 1, add the
+
+functions:</i></span></p>
+<blockquote>
+ <pre><span style="background-color: #FFFFFF">template <class Path> explicit basic_ofstream(const Path& p, ios_base::openmode mode = ios_base::out);
+template <class Path> void open(const Path& p, ios_base::openmode mode = ios_base::out);</span></pre>
+</blockquote>
+<p><i><span style="background-color: #FFFFFF">In 27.8.1.9 basic_ofstream
+constructors [lib.ofstream.cons] </span></i>
+<span style="background-color: #FFFFFF"><i>add the above constructor to the signature preceding
+paragraph 2, and in paragraph 2 replace</i></span></p>
+<blockquote>
+<p><span style="background-color: #FFFFFF"><code>rdbuf()->open(s, mode |
+ios_base::out)</code></span></p>
+</blockquote>
+<p><span style="background-color: #FFFFFF"><i>with</i></span></p>
+<blockquote>
+<p><span style="background-color: #FFFFFF"><code>rdbuf()->open(path(s), mode |
+ios_base::out)</code> or <code>rdbuf()->open(p, mode | ios_base::out)</code> as
+appropriate</span></p>
+</blockquote>
+<p><i><span style="background-color: #FFFFFF">In 27.8.1.10 Member functions [lib.ofstream.members]
+</span></i><span style="background-color: #FFFFFF"><i>add the above open
+function to the signature
+preceding paragraph 3, and in paragraph 3 replace</i></span></p>
+<blockquote>
+<p><span style="background-color: #FFFFFF"><code>rdbuf()->open(s, mode |
+ios_base::out)</code></span></p>
+</blockquote>
+<p><span style="background-color: #FFFFFF"><i>with</i></span></p>
+<blockquote>
+<p><span style="background-color: #FFFFFF"><code>rdbuf()->open(path(s), mode |
+ios_base::out)</code> or <code>rdbuf()->open(p, mode | ios_base::out)</code> as
+appropriate</span></p>
+</blockquote>
+<p><span style="background-color: #FFFFFF"><i>In 27.8.1.11 Class template
+basic_fstream [lib.fstream] synopsis preceding paragraph 1, add the functions:</i></span></p>
+<blockquote>
+ <pre><span style="background-color: #FFFFFF">template <class Path> explicit basic_fstream(const Path& p, ios_base::openmode mode = ios_base::in|ios_base::out);
+template <class Path> void open(const Path& p, ios_base::openmode mode = ios_base::in|ios_base::out);</span></pre>
+</blockquote>
+<p><i><span style="background-color: #FFFFFF">In 27.8.1.12 basic_fstream
+constructors [lib.fstream.cons] </span></i>
+<span style="background-color: #FFFFFF"><i>add the above constructor to the signature preceding
+paragraph 2, and in paragraph 2 replace</i></span></p>
+<blockquote>
+<p><span style="background-color: #FFFFFF"><code>rdbuf()->open(s, mode)</code></span></p>
+</blockquote>
+<p><span style="background-color: #FFFFFF"><i>with</i></span></p>
+<blockquote>
+<p><span style="background-color: #FFFFFF"><code>rdbuf()->open(path(s), mode)</code>
+or <code>rdbuf()->open(p, mode)</code> as appropriate</span></p>
+</blockquote>
+<p><i><span style="background-color: #FFFFFF">In 27.8.1.13 Member functions [lib.fstream.members]
+</span></i><span style="background-color: #FFFFFF"><i>add the above open
+function to the signature
+preceding paragraph 3, and in paragraph 3 replace</i></span></p>
+<blockquote>
+<p><span style="background-color: #FFFFFF"><code>rdbuf()->open(s, mode)</code></span></p>
+</blockquote>
+<p><span style="background-color: #FFFFFF"><i>with</i></span></p>
+<blockquote>
+<p><span style="background-color: #FFFFFF"><code>rdbuf()->open(path(s), mode)</code>
+or <code>rdbuf()->open(p, mode)</code> as appropriate</span></p>
+</blockquote>
+<p><span style="background-color: #FFFFFF"><i>End of proposed text.</i></span></p>
+<h2><a name="Path-decomposition-table">Path decomposition table</a></h2>
+<p>The table is generated by a program compiled with the Boost implementation.</p>
+<p>Shaded entries indicate cases where <i>POSIX</i> and <i>Windows</i>
+implementations yield different results. The top value is the
+<i>POSIX</i> result and the bottom value is the <i>Windows</i> result. <br>
+ <table border="1" cellspacing="0" cellpadding="5" width="1066">
+<p>
+<tr><td width="112"><b>Constructor<br>argument</b></td>
+<td width="160"><b>Elements found<br>by iteration</b></td>
+<td width="112"><b><code>string()</code></b></td>
+<td width="112"><code><b>file_<br>string()</b></td>
+<td width="72"><b><code>root_<br>path()<br>.string()</code></b></td>
+<td width="48"><b><code>root_<br>name()</code></b></td>
+<td width="88"><b><code>root_<br>directory()</code></b></td>
+<td width="96"><b><code>relative_<br>path()<br>.string()</code></b></td>
+<td width="72"><b><code>parent_<br>path()<br>.string()</code></b></td>
+<td width="72"><b><code>filename()</code></b></td>
+</tr>
+<tr>
+<td width="112"><code>""</code></td>
+<td width="160"><code>""</code></td>
+<td width="112"><code>""</code></td>
+<td width="112"><code>""</code></td>
+<td width="72"><code>""</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>""</code></td>
+<td width="96"><code>""</code></td>
+<td width="72"><code>""</code></td>
+<td width="72"><code>""</code></td>
+</tr>
+<tr>
+<td width="112"><code>"."</code></td>
+<td width="160"><code>"."</code></td>
+<td width="112"><code>"."</code></td>
+<td width="112"><code>"."</code></td>
+<td width="72"><code>""</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>""</code></td>
+<td width="96"><code>"."</code></td>
+<td width="72"><code>""</code></td>
+<td width="72"><code>"."</code></td>
+</tr>
+<tr>
+<td width="112"><code>".."</code></td>
+<td width="160"><code>".."</code></td>
+<td width="112"><code>".."</code></td>
+<td width="112"><code>".."</code></td>
+<td width="72"><code>""</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>""</code></td>
+<td width="96"><code>".."</code></td>
+<td width="72"><code>""</code></td>
+<td width="72"><code>".."</code></td>
+</tr>
+<tr>
+<td width="112"><code>"foo"</code></td>
+<td width="160"><code>"foo"</code></td>
+<td width="112"><code>"foo"</code></td>
+<td width="112"><code>"foo"</code></td>
+<td width="72"><code>""</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>""</code></td>
+<td width="96"><code>"foo"</code></td>
+<td width="72"><code>""</code></td>
+<td width="72"><code>"foo"</code></td>
+</tr>
+<tr>
+<td width="112"><code>"/"</code></td>
+<td width="160"><code>"/"</code></td>
+<td width="112"><code>"/"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"/"<br>"\"</code></td>
+<td width="72"><code>"/"</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>"/"</code></td>
+<td width="96"><code>""</code></td>
+<td width="72"><code>""</code></td>
+<td width="72"><code>"/"</code></td>
+</tr>
+<tr>
+<td width="112"><code>"/foo"</code></td>
+<td width="160"><code>"/","foo"</code></td>
+<td width="112"><code>"/foo"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"/foo"<br>"\foo"</code></td>
+<td width="72"><code>"/"</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>"/"</code></td>
+<td width="96"><code>"foo"</code></td>
+<td width="72"><code>"/"</code></td>
+<td width="72"><code>"foo"</code></td>
+</tr>
+<tr>
+<td width="112"><code>"foo/"</code></td>
+<td width="160"><code>"foo","."</code></td>
+<td width="112"><code>"foo/"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"foo/"<br>"foo\"</code></td>
+<td width="72"><code>""</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>""</code></td>
+<td width="96"><code>"foo/"</code></td>
+<td width="72"><code>"foo"</code></td>
+<td width="72"><code>"."</code></td>
+</tr>
+<tr>
+<td width="112"><code>"/foo/"</code></td>
+<td width="160"><code>"/","foo","."</code></td>
+<td width="112"><code>"/foo/"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"/foo/"<br>"\foo\"</code></td>
+<td width="72"><code>"/"</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>"/"</code></td>
+<td width="96"><code>"foo/"</code></td>
+<td width="72"><code>"/foo"</code></td>
+<td width="72"><code>"."</code></td>
+</tr>
+<tr>
+<td width="112"><code>"foo/bar"</code></td>
+<td width="160"><code>"foo","bar"</code></td>
+<td width="112"><code>"foo/bar"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"foo/bar"<br>"foo\bar"</code></td>
+<td width="72"><code>""</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>""</code></td>
+<td width="96"><code>"foo/bar"</code></td>
+<td width="72"><code>"foo"</code></td>
+<td width="72"><code>"bar"</code></td>
+</tr>
+<tr>
+<td width="112"><code>"/foo/bar"</code></td>
+<td width="160"><code>"/","foo","bar"</code></td>
+<td width="112"><code>"/foo/bar"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"/foo/bar"<br>"\foo\bar"</code></td>
+<td width="72"><code>"/"</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>"/"</code></td>
+<td width="96"><code>"foo/bar"</code></td>
+<td width="72"><code>"/foo"</code></td>
+<td width="72"><code>"bar"</code></td>
+</tr>
+<tr>
+<td width="112"><code>"///foo///"</code></td>
+<td width="160"><code>"/","foo","."</code></td>
+<td width="112"><code>"///foo///"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"///foo///"<br>"\foo\\\"</code></td>
+<td width="72"><code>"/"</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>"/"</code></td>
+<td width="96"><code>"foo///"</code></td>
+<td width="72"><code>"///foo"</code></td>
+<td width="72"><code>"."</code></td>
+</tr>
+<tr>
+<td width="112"><code>"///foo///bar"</code></td>
+<td width="160"><code>"/","foo","bar"</code></td>
+<td width="112"><code>"///foo///bar"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"///foo///bar"<br>"\foo\\\bar"</code></td>
+<td width="72"><code>"/"</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>"/"</code></td>
+<td width="96"><code>"foo///bar"</code></td>
+<td width="72"><code>"///foo"</code></td>
+<td width="72"><code>"bar"</code></td>
+</tr>
+<tr>
+<td width="112"><code>"/."</code></td>
+<td width="160"><code>"/","."</code></td>
+<td width="112"><code>"/."</code></td>
+<td bgcolor="#99FF66" width="112"><code>"/."<br>"\."</code></td>
+<td width="72"><code>"/"</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>"/"</code></td>
+<td width="96"><code>"."</code></td>
+<td width="72"><code>"/"</code></td>
+<td width="72"><code>"."</code></td>
+</tr>
+<tr>
+<td width="112"><code>"./"</code></td>
+<td width="160"><code>".","."</code></td>
+<td width="112"><code>"./"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"./"<br>".\"</code></td>
+<td width="72"><code>""</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>""</code></td>
+<td width="96"><code>"./"</code></td>
+<td width="72"><code>"."</code></td>
+<td width="72"><code>"."</code></td>
+</tr>
+<tr>
+<td width="112"><code>"/.."</code></td>
+<td width="160"><code>"/",".."</code></td>
+<td width="112"><code>"/.."</code></td>
+<td bgcolor="#99FF66" width="112"><code>"/.."<br>"\.."</code></td>
+<td width="72"><code>"/"</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>"/"</code></td>
+<td width="96"><code>".."</code></td>
+<td width="72"><code>"/"</code></td>
+<td width="72"><code>".."</code></td>
+</tr>
+<tr>
+<td width="112"><code>"../"</code></td>
+<td width="160"><code>"..","."</code></td>
+<td width="112"><code>"../"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"../"<br>"..\"</code></td>
+<td width="72"><code>""</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>""</code></td>
+<td width="96"><code>"../"</code></td>
+<td width="72"><code>".."</code></td>
+<td width="72"><code>"."</code></td>
+</tr>
+<tr>
+<td width="112"><code>"foo/."</code></td>
+<td width="160"><code>"foo","."</code></td>
+<td width="112"><code>"foo/."</code></td>
+<td bgcolor="#99FF66" width="112"><code>"foo/."<br>"foo\."</code></td>
+<td width="72"><code>""</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>""</code></td>
+<td width="96"><code>"foo/."</code></td>
+<td width="72"><code>"foo"</code></td>
+<td width="72"><code>"."</code></td>
+</tr>
+<tr>
+<td width="112"><code>"foo/.."</code></td>
+<td width="160"><code>"foo",".."</code></td>
+<td width="112"><code>"foo/.."</code></td>
+<td bgcolor="#99FF66" width="112"><code>"foo/.."<br>"foo\.."</code></td>
+<td width="72"><code>""</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>""</code></td>
+<td width="96"><code>"foo/.."</code></td>
+<td width="72"><code>"foo"</code></td>
+<td width="72"><code>".."</code></td>
+</tr>
+<tr>
+<td width="112"><code>"foo/./"</code></td>
+<td width="160"><code>"foo",".","."</code></td>
+<td width="112"><code>"foo/./"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"foo/./"<br>"foo\.\"</code></td>
+<td width="72"><code>""</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>""</code></td>
+<td width="96"><code>"foo/./"</code></td>
+<td width="72"><code>"foo/."</code></td>
+<td width="72"><code>"."</code></td>
+</tr>
+<tr>
+<td width="112"><code>"foo/./bar"</code></td>
+<td width="160"><code>"foo",".","bar"</code></td>
+<td width="112"><code>"foo/./bar"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"foo/./bar"<br>"foo\.\bar"</code></td>
+<td width="72"><code>""</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>""</code></td>
+<td width="96"><code>"foo/./bar"</code></td>
+<td width="72"><code>"foo/."</code></td>
+<td width="72"><code>"bar"</code></td>
+</tr>
+<tr>
+<td width="112"><code>"foo/.."</code></td>
+<td width="160"><code>"foo",".."</code></td>
+<td width="112"><code>"foo/.."</code></td>
+<td bgcolor="#99FF66" width="112"><code>"foo/.."<br>"foo\.."</code></td>
+<td width="72"><code>""</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>""</code></td>
+<td width="96"><code>"foo/.."</code></td>
+<td width="72"><code>"foo"</code></td>
+<td width="72"><code>".."</code></td>
+</tr>
+<tr>
+<td width="112"><code>"foo/../"</code></td>
+<td width="160"><code>"foo","..","."</code></td>
+<td width="112"><code>"foo/../"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"foo/../"<br>"foo\..\"</code></td>
+<td width="72"><code>""</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>""</code></td>
+<td width="96"><code>"foo/../"</code></td>
+<td width="72"><code>"foo/.."</code></td>
+<td width="72"><code>"."</code></td>
+</tr>
+<tr>
+<td width="112"><code>"foo/../bar"</code></td>
+<td width="160"><code>"foo","..","bar"</code></td>
+<td width="112"><code>"foo/../bar"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"foo/../bar"<br>"foo\..\bar"</code></td>
+<td width="72"><code>""</code></td>
+<td width="48"><code>""</code></td>
+<td width="88"><code>""</code></td>
+<td width="96"><code>"foo/../bar"</code></td>
+<td width="72"><code>"foo/.."</code></td>
+<td width="72"><code>"bar"</code></td>
+</tr>
+<tr>
+<td width="112"><code>"c:"</code></td>
+<td width="160"><code>"c:"</code></td>
+<td width="112"><code>"c:"</code></td>
+<td width="112"><code>"c:"</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:"</code></td>
+<td bgcolor="#99FF66" style="border-left-style: solid; border-left-width: 1; border-right-style: solid; border-right-width: 1; border-top-style: solid; border-top-width: 1" width="48"><code>
+""<br>"c:"</code></td>
+<td width="88"><code>""</code></td>
+<td bgcolor="#99FF66" width="96"><code>"c:"<br>""</code></td>
+<td width="72"><code>""</code></td>
+<td width="72"><code>"c:"</code></td>
+</tr>
+<tr>
+<td width="112"><code>"c:/"</code></td>
+<td bgcolor="#99FF66" width="160"><code>"c:","."<br>"c:","/"</code></td>
+<td width="112"><code>"c:/"</code></td>
+<td bgcolor="#99FF66" width="112"><code><span style="background-color: #99FF66">
+"c:/"<br>"c:\"</span></code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:/"</code></td>
+<td bgcolor="#99FF66" style="border-left-style: solid; border-left-width: 1; border-right-style: solid; border-right-width: 1" width="48"><code>
+""<br>"c:"</code></td>
+<td bgcolor="#99FF66" width="88"><code>""<br>"/"</code></td>
+<td bgcolor="#99FF66" width="96"><code>"c:/"<br>""</code></td>
+<td width="72"><code>"c:"</code></td>
+<td bgcolor="#99FF66" width="72"><code>"."<br>"/"</code></td>
+</tr>
+<tr>
+<td width="112"><code>"c:foo"</code></td>
+<td bgcolor="#99FF66" width="160"><code>"c:foo"<br>"c:","foo"</code></td>
+<td width="112"><code>"c:foo"</code></td>
+<td width="112"><code>"c:foo"</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:"</code></td>
+<td bgcolor="#99FF66" style="border-left-style: solid; border-left-width: 1; border-right-style: solid; border-right-width: 1" width="48"><code>
+""<br>"c:"</code></td>
+<td width="88"><code>""</code></td>
+<td bgcolor="#99FF66" width="96"><code>"c:foo"<br>"foo"</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:"</code></td>
+<td bgcolor="#99FF66" width="72"><code>"c:foo"<br>"foo"</code></td>
+</tr>
+<tr>
+<td width="112"><code>"c:/foo"</code></td>
+<td bgcolor="#99FF66" width="160"><code>"c:","foo"<br>"c:","/","foo"</code></td>
+<td width="112"><code>"c:/foo"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"c:/foo"<br>"c:\foo"</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:/"</code></td>
+<td bgcolor="#99FF66" style="border-left-style: solid; border-left-width: 1; border-right-style: solid; border-right-width: 1" width="48"><code>
+""<br>"c:"</code></td>
+<td bgcolor="#99FF66" width="88"><code>""<br>"/"</code></td>
+<td bgcolor="#99FF66" width="96"><code>"c:/foo"<br>"foo"</code></td>
+<td bgcolor="#99FF66" width="72"><code>"c:"<br>"c:/"</code></td>
+<td width="72"><code>"foo"</code></td>
+</tr>
+<tr>
+<td width="112"><code>"c:foo/"</code></td>
+<td bgcolor="#99FF66" width="160"><code>"c:foo","."<br>"c:","foo","."</code></td>
+<td width="112"><code>"c:foo/"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"c:foo/"<br>"c:foo\"</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:"</code></td>
+<td bgcolor="#99FF66" style="border-left-style: solid; border-left-width: 1; border-right-style: solid; border-right-width: 1" width="48"><code>
+""<br>"c:"</code></td>
+<td width="88"><code>""</code></td>
+<td bgcolor="#99FF66" width="96"><code>"c:foo/"<br>"foo/"</code></td>
+<td width="72"><code>"c:foo"</code></td>
+<td width="72"><code>"."</code></td>
+</tr>
+<tr>
+<td width="112"><code>"c:/foo/"</code></td>
+<td bgcolor="#99FF66" width="160"><code>"c:","foo","."<br>"c:","/","foo","."</code></td>
+<td width="112"><code>"c:/foo/"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"c:/foo/"<br>"c:\foo\"</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:/"</code></td>
+<td bgcolor="#99FF66" style="border-left-style: solid; border-left-width: 1; border-right-style: solid; border-right-width: 1" width="48"><code>
+""<br>"c:"</code></td>
+<td bgcolor="#99FF66" width="88"><code>""<br>"/"</code></td>
+<td bgcolor="#99FF66" width="96"><code>"c:/foo/"<br>"foo/"</code></td>
+<td width="72"><code>"c:/foo"</code></td>
+<td width="72"><code>"."</code></td>
+</tr>
+<tr>
+<td width="112"><code>"c:/foo/bar"</code></td>
+<td bgcolor="#99FF66" width="160"><code>"c:","foo","bar"<br>"c:","/","foo","bar"</code></td>
+<td width="112"><code>"c:/foo/bar"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"c:/foo/bar"<br>"c:\foo\bar"</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:/"</code></td>
+<td bgcolor="#99FF66" style="border-left-style: solid; border-left-width: 1; border-right-style: solid; border-right-width: 1" width="48"><code>
+""<br>"c:"</code></td>
+<td bgcolor="#99FF66" width="88"><code>""<br>"/"</code></td>
+<td bgcolor="#99FF66" width="96"><code>"c:/foo/bar"<br>"foo/bar"</code></td>
+<td width="72"><code>"c:/foo"</code></td>
+<td width="72"><code>"bar"</code></td>
+</tr>
+<tr>
+<td width="112"><code>"prn:"</code></td>
+<td width="160"><code>"prn:"</code></td>
+<td width="112"><code>"prn:"</code></td>
+<td width="112"><code>"prn:"</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"prn:"</code></td>
+<td bgcolor="#99FF66" style="border-left-style: solid; border-left-width: 1; border-right-style: solid; border-right-width: 1" width="48"><code>
+""<br>"prn:"</code></td>
+<td width="88"><code>""</code></td>
+<td bgcolor="#99FF66" width="96"><code>"prn:"<br>""</code></td>
+<td width="72"><code>""</code></td>
+<td width="72"><code>"prn:"</code></td>
+</tr>
+<tr>
+<td width="112"><code>"c:\"</code></td>
+<td bgcolor="#99FF66" width="160"><code>"c:\"<br>"c:","/"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"c:\"<br>"c:/"</code></td>
+<td width="112"><code>"c:\"</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:/"</code></td>
+<td bgcolor="#99FF66" style="border-left-style: solid; border-left-width: 1; border-right-style: solid; border-right-width: 1" width="48"><code>
+""<br>"c:"</code></td>
+<td bgcolor="#99FF66" width="88"><code>""<br>"/"</code></td>
+<td bgcolor="#99FF66" width="96"><code>"c:\"<br>""</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:"</code></td>
+<td bgcolor="#99FF66" width="72"><code>"c:\"<br>"/"</code></td>
+</tr>
+<tr>
+<td width="112"><code>"c:foo"</code></td>
+<td bgcolor="#99FF66" width="160"><code>"c:foo"<br>"c:","foo"</code></td>
+<td width="112"><code>"c:foo"</code></td>
+<td width="112"><code>"c:foo"</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:"</code></td>
+<td bgcolor="#99FF66" style="border-left-style: solid; border-left-width: 1; border-right-style: solid; border-right-width: 1" width="48"><code>
+""<br>"c:"</code></td>
+<td width="88"><code>""</code></td>
+<td bgcolor="#99FF66" width="96"><code>"c:foo"<br>"foo"</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:"</code></td>
+<td bgcolor="#99FF66" width="72"><code>"c:foo"<br>"foo"</code></td>
+</tr>
+<tr>
+<td width="112"><code>"c:\foo"</code></td>
+<td bgcolor="#99FF66" width="160"><code>"c:\foo"<br>"c:","/","foo"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"c:\foo"<br>"c:/foo"</code></td>
+<td width="112"><code>"c:\foo"</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:/"</code></td>
+<td bgcolor="#99FF66" style="border-left-style: solid; border-left-width: 1; border-right-style: solid; border-right-width: 1" width="48"><code>
+""<br>"c:"</code></td>
+<td bgcolor="#99FF66" width="88"><code>""<br>"/"</code></td>
+<td bgcolor="#99FF66" width="96"><code>"c:\foo"<br>"foo"</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:/"</code></td>
+<td bgcolor="#99FF66" width="72"><code>"c:\foo"<br>"foo"</code></td>
+</tr>
+<tr>
+<td width="112"><code>"c:foo\"</code></td>
+<td bgcolor="#99FF66" width="160"><code>"c:foo\"<br>"c:","foo","."</code></td>
+<td bgcolor="#99FF66" width="112"><code>"c:foo\"<br>"c:foo/"</code></td>
+<td width="112"><code>"c:foo\"</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:"</code></td>
+<td bgcolor="#99FF66" style="border-left-style: solid; border-left-width: 1; border-right-style: solid; border-right-width: 1" width="48"><code>
+""<br>"c:"</code></td>
+<td width="88"><code>""</code></td>
+<td bgcolor="#99FF66" width="96"><code>"c:foo\"<br>"foo/"</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:foo"</code></td>
+<td bgcolor="#99FF66" width="72"><code>"c:foo\"<br>"."</code></td>
+</tr>
+<tr>
+<td width="112"><code>"c:\foo\"</code></td>
+<td bgcolor="#99FF66" width="160"><code>"c:\foo\"<br>"c:","/","foo","."</code></td>
+<td bgcolor="#99FF66" width="112"><code>"c:\foo\"<br>"c:/foo/"</code></td>
+<td width="112"><code>"c:\foo\"</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:/"</code></td>
+<td bgcolor="#99FF66" style="border-left-style: solid; border-left-width: 1; border-right-style: solid; border-right-width: 1" width="48"><code>
+""<br>"c:"</code></td>
+<td bgcolor="#99FF66" width="88"><code>""<br>"/"</code></td>
+<td bgcolor="#99FF66" width="96"><code>"c:\foo\"<br>"foo/"</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:/foo"</code></td>
+<td bgcolor="#99FF66" width="72"><code>"c:\foo\"<br>"."</code></td>
+</tr>
+<tr>
+<td width="112"><code>"c:\foo/"</code></td>
+<td bgcolor="#99FF66" width="160"><code>"c:\foo","."<br>"c:","/","foo","."</code></td>
+<td bgcolor="#99FF66" width="112"><code>"c:\foo/"<br>"c:/foo/"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"c:\foo/"<br>"c:\foo\"</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:/"</code></td>
+<td bgcolor="#99FF66" style="border-left-style: solid; border-left-width: 1; border-right-style: solid; border-right-width: 1" width="48"><code>
+""<br>"c:"</code></td>
+<td bgcolor="#99FF66" width="88"><code>""<br>"/"</code></td>
+<td bgcolor="#99FF66" width="96"><code>"c:\foo/"<br>"foo/"</code></td>
+<td bgcolor="#99FF66" width="72"><code>"c:\foo"<br>"c:/foo"</code></td>
+<td width="72"><code>"."</code></td>
+</tr>
+<tr>
+<td width="112"><code>"c:/foo\bar"</code></td>
+<td bgcolor="#99FF66" width="160"><code>"c:","foo\bar"<br>"c:","/","foo","bar"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"c:/foo\bar"<br>"c:/foo/bar"</code></td>
+<td bgcolor="#99FF66" width="112"><code>"c:/foo\bar"<br>"c:\foo\bar"</code></td>
+<td bgcolor="#99FF66" width="72"><code>""<br>"c:/"</code></td>
+<td bgcolor="#99FF66" style="border-left-style: solid; border-left-width: 1; border-right-style: solid; border-right-width: 1; border-bottom-style: solid; border-bottom-width: 1" width="48"><code>
+""<br>"c:"</code></td>
+<td bgcolor="#99FF66" width="88"><code>""<br>"/"</code></td>
+<td bgcolor="#99FF66" width="96"><code>"c:/foo\bar"<br>"foo/bar"</code></td>
+<td bgcolor="#99FF66" width="72"><code>"c:"<br>"c:/foo"</code></td>
+<td bgcolor="#99FF66" width="72"><code>"foo\bar"<br>"bar"</code></td>
+</tr>
+</table>
+<h2><a name="Suggestions-for-fstream">Suggestions for <code><fstream></code></a>
+implementations</h2>
+<p><span style="background-color: #FFFFFF">The change in semantics to functions
+taking <code>const char*</code> arguments can break existing code, but only on
+operating systems where implementations don't
+implicitly accept native format pathnames or
+operating systems that allow slashes in filenames. Thus on <i>POSIX</i>,
+<i>Windows,</i> and <i>OpenVMS</i>, for example, there is no problem if the
+implementation follows encouraged behavior.</span></p>
+<p><span style="background-color: #FFFFFF">For most of the Filesystem Library,
+there is no existing code, so the issue preserving existing code that uses
+slashes in filenames doesn't arise. New code simply must use basic_path
+constructors with <code>path_format_t</code> arguments of <code>native</code>.
+To preserve existing fstream code that uses slashes in filenames, an
+implementation may wish to provide a mechanism such as a macro to control
+selection of the old behavior.</span></p>
+<p><span style="background-color: #FFFFFF">Implementations are already required
+by the TR front-matter to provide a mechanism such as a macro to control
+selection of the old behavior (useful to guarantee protection of existing code)
+or new behavior (useful in new code, and code being ported from other systems)
+for headers. Because use of the rest of the Filesystem Library is independent of
+use of the <code><fstream></code> additions, affected implementations are
+encouraged to allow disabling the <code><fstream></code> additions separately
+from other TR features.</span></p>
+<p><span style="background-color: #FFFFFF">An rejected alternative was to supply
+new fstream classes in namespace <code>filesystem</code>, inheriting from the current
+classes, overriding the constructors and opens taking pathname arguments, and
+providing the additional overloads. In Lillehammer LWG members indicated lack of
+support for this alternative, feeling that costs outweigh benefits.</span></p>
+<h2><a name="Acknowledgements">Acknowledgements</a></h2>
+<p>This Filesystem Library is dedicated to my wife, Sonda, who provided the
+support necessary to see both a trial implementation and the proposal itself
+through to completion. She gave me the strength to continue after a difficult
+year of cancer treatment in the middle of it all.</p>
+<p>Many people contributed technical comments, ideas, and suggestions to the
+Boost Filesystem Library. See
+<a href="http://www.boost.org/libs/filesystem/doc/index.htm#Acknowledgements">
+http://www.boost.org/libs/filesystem/doc/index.htm#Acknowledgements>.</p>
+<p>Dietmar Kuehl contributed the original Boost Filesystem Library directory_iterator design. Peter Dimov, Walter Landry, Rob Stewart, and Thomas
+Witt were particularly helpful in refining the library.</p>
+<p>The create_directories, extension, basename, and replace_extension functions
+were developed by Vladimir Prus.</p>
+<p>Howard Hinnant and John Maddock reviewed a draft of the proposal, and
+identified a number of mistakes or weaknesses, resulting in a more polished
+final document.</p>
+<h2><a name="References">References</a></h2>
+<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%">
+ <tr>
+ <td width="16%" valign="top">[<a name="ISO_POSIX">ISO-POSIX</a>]</td>
+ <td width="84%">ISO/IEC 9945:2003, IEEE Std 1003.1-2001, and The Open Group
+ Base Specifications, Issue 6. Also known as The Single Unix<font face="Times New Roman">®
+ Specification, Version 3. Available from each of the organizations involved
+ in its creation. For example, read online or download from
+ <a href="http://www.unix.org/single_unix_specification/">
+ www.unix.org/single_unix_specification/</a>.</font> The ISO JTC1/SC22/WG15 -
+ POSIX homepage is <a href="http://www.open-std.org/jtc1/sc22/WG15/">
+ www.open-std.org/jtc1/sc22/WG15/</a></td>
+ </tr>
+ <tr>
+ <td width="16%" valign="top">[Abrahams]</td>
+ <td width="84%">Dave Abrahams, Error and Exception Handling,
+ <a href="http://www.boost.org/more/error_handling.html">
+ www.boost.org/more/error_handling.html</a></td>
+ </tr>
+</table>
+<hr>
+<p>© Copyright Beman Dawes, 2002, 2006, 2007</p>
+<p>Distributed under the Boost Software License, Version 1.0. See
+www.boost.org/LICENSE_1_0.txt</p>
+<p>Revised
+<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->06 July 2008<!--webbot bot="Timestamp" endspan i-checksum="18830" --></p>
+
+</body>
+
+</html>
\ No newline at end of file
Added: sandbox/filesystem-v3/libs/filesystem/v3/doc/v3_design.html
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/doc/v3_design.html 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,98 @@
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
+<meta name="ProgId" content="FrontPage.Editor.Document">
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
+<title>Filesystem Home</title>
+<link rel="stylesheet" type="text/css" href="minimal.css">
+</head>
+
+<body>
+
+<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="710">
+ <tr>
+ <td width="277">
+<a href="../../../index.htm">
+<img src="boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86" border="0"></a></td>
+ <td width="410" align="middle">
+ <font size="7">Filesystem Library V3 Prototype Design</font>
+ </td>
+ </tr>
+</table>
+
+<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="100%">
+ <tr>
+ <td>Boost Home
+ Library Home Tutorial <a href="reference.html">
+ Reference</a> FAQ</td>
+ </tr>
+</table>
+
+<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" align="right">
+ <tr>
+ <td width="100%" bgcolor="#D7EEFF" align="center">
+ <i><b>Contents</b></i></td>
+ </tr>
+ <tr>
+ <td width="100%" bgcolor="#E8F5FF">
+ Introduction<br>
+ </td>
+ </tr>
+ <tr>
+ <td width="100%" bgcolor="#D7EEFF" align="center">
+ <i><b>Other Documents</b></i></td>
+ </tr>
+ <tr>
+ <td width="100%" bgcolor="#E8F5FF">
+ </td>
+ </tr>
+</table>
+
+<h2><a name="Introduction">Introduction</a></h2>
+
+<p>During the review of Boost.Filesystem V2 (Internationalization), Peter Dimov
+suggested that the class basic_path template was unwieldy, and that a single
+path type that accommodated multiple character types and encodings would be more
+flexible. Although I wasn't willing then to stop development at that time to
+explore how this idea might be implemented, or to break from the pattern for
+Internationalization used the C++ standard library, I've often thought about
+Peter's suggestion. With the advent of C++0x char16_t and char32_t character
+types, the basic_path class template approach becomes even more unwieldy, so it
+is time to revisit the problem.</p>
+
+<h2><b><a name="Problem">Problem</a></b></h2>
+
+<p>Say a user needs to take a path argument to a user defined function, and
+wishes to accommodate all applicable character types and encodings.
+<span style="background-color: #FFFF00">Must write template. Must provide
+do-the-right-thing overloads.</span></p>
+
+<h2><a name="Solution">Solution</a></h2>
+
+<p>The solution explored here:</p>
+<ul>
+ <li>A single class path.</li>
+ <li>Conversions from and to applicable character types and encodings.</li>
+ <li>Internally, the path is held in a string_type appropriate to the operating
+ system; std::string for POSIX, std::wstring for Windows.</li>
+</ul>
+
+<h2><a name="Prototype">Prototype</a></h2>
+
+<p>Windows only. Incomplete. Not thoroughly tested. Should not be used for
+production work.</p>
+
+<hr>
+<p>Revised
+<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->25 September, 2008<!--webbot bot="Timestamp" endspan i-checksum="39353" --></p>
+
+<p>© Copyright Beman Dawes, 2008</p>
+<p> Use, modification, and distribution are subject to the Boost Software
+License, Version 1.0. See <a href="http://www.boost.org/LICENSE_1_0.txt">
+www.boost.org/LICENSE_1_0.txt</a></p>
+
+</body>
+
+</html>
\ No newline at end of file
Added: sandbox/filesystem-v3/libs/filesystem/v3/example/Jamfile.v2
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/example/Jamfile.v2 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,16 @@
+# Boost Filesystem Library Example Jamfile
+
+# (C) Copyright Vladimir Prus 2003
+
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or www.boost.org/LICENSE_1_0.txt)
+
+# See library home page at http://www.boost.org/libs/filesystem
+
+project
+ : requirements <library>../build//boost_filesystem
+ <hardcode-dll-paths>true
+ ;
+
+exe file_size : file_size.cpp ;
+exe simple_ls : simple_ls.cpp ;
Added: sandbox/filesystem-v3/libs/filesystem/v3/example/file_size.cpp
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/example/file_size.cpp 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,44 @@
+// file_size program -------------------------------------------------------//
+
+// Copyright Beman Dawes, 2004
+
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org/libs/filesystem for documentation.
+
+#include <boost/filesystem/operations.hpp>
+#include <iostream>
+
+namespace fs = boost::filesystem;
+
+int main( int argc, char* argv[] )
+{
+
+ if ( argc != 2 )
+ {
+ std::cout << "Usage: file_size path\n";
+ return 1;
+ }
+
+ std::cout << "sizeof(intmax_t) is " << sizeof(boost::intmax_t) << '\n';
+
+ fs::path p( argv[1], fs::native );
+
+ if ( !fs::exists( p ) )
+ {
+ std::cout << "not found: " << argv[1] << std::endl;
+ return 1;
+ }
+
+ if ( !fs::is_regular( p ) )
+ {
+ std::cout << "not a regular file: " << argv[1] << std::endl;
+ return 1;
+ }
+
+ std::cout << "size of " << argv[1] << " is " << fs::file_size( p )
+ << std::endl;
+ return 0;
+}
Added: sandbox/filesystem-v3/libs/filesystem/v3/example/mbcopy.cpp
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/example/mbcopy.cpp 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,90 @@
+// Boost.Filesystem mbcopy.cpp ---------------------------------------------//
+
+// Copyright Beman Dawes 2005
+
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Copy the files in a directory, using mbpath to represent the new file names
+// See http://../doc/path.htm#mbpath for more information
+
+// See deprecated_test for tests of deprecated features
+#define BOOST_FILESYSTEM_NO_DEPRECATED
+
+#include <boost/filesystem/config.hpp>
+# ifdef BOOST_FILESYSTEM_NARROW_ONLY
+# error This compiler or standard library does not support wide-character strings or paths
+# endif
+
+#include "mbpath.hpp"
+#include <iostream>
+#include <boost/filesystem/operations.hpp>
+#include <boost/filesystem/fstream.hpp>
+#include "../src/utf8_codecvt_facet.hpp"
+
+namespace fs = boost::filesystem;
+
+namespace
+{
+ // we can't use boost::filesystem::copy_file() because the argument types
+ // differ, so provide a not-very-smart replacement.
+
+ void copy_file( const fs::wpath & from, const user::mbpath & to )
+ {
+ fs::ifstream from_file( from, std::ios_base::in | std::ios_base::binary );
+ if ( !from_file ) { std::cout << "input open failed\n"; return; }
+
+ fs::ofstream to_file( to, std::ios_base::out | std::ios_base::binary );
+ if ( !to_file ) { std::cout << "output open failed\n"; return; }
+
+ char c;
+ while ( from_file.get(c) )
+ {
+ to_file.put(c);
+ if ( to_file.fail() ) { std::cout << "write error\n"; return; }
+ }
+
+ if ( !from_file.eof() ) { std::cout << "read error\n"; }
+ }
+}
+
+int main( int argc, char * argv[] )
+{
+ if ( argc != 2 )
+ {
+ std::cout << "Copy files in the current directory to a target directory\n"
+ << "Usage: mbcopy <target-dir>\n";
+ return 1;
+ }
+
+ // For encoding, use Boost UTF-8 codecvt
+ std::locale global_loc = std::locale();
+ std::locale loc( global_loc, new fs::detail::utf8_codecvt_facet );
+ user::mbpath_traits::imbue( loc );
+
+ std::string target_string( argv[1] );
+ user::mbpath target_dir( user::mbpath_traits::to_internal( target_string ) );
+
+ if ( !fs::is_directory( target_dir ) )
+ {
+ std::cout << "Error: " << argv[1] << " is not a directory\n";
+ return 1;
+ }
+
+ for ( fs::wdirectory_iterator it( L"." );
+ it != fs::wdirectory_iterator(); ++it )
+ {
+ if ( fs::is_regular_file(it->status()) )
+ {
+ copy_file( *it, target_dir / it->path().filename() );
+ }
+ }
+
+ return 0;
+}
+
+
+
+
+
Added: sandbox/filesystem-v3/libs/filesystem/v3/example/mbpath.cpp
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/example/mbpath.cpp 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,80 @@
+// Boost.Filesystem mbpath.cpp ---------------------------------------------//
+
+// (c) Copyright Beman Dawes 2005
+
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See Boost.Filesystem home page at http://www.boost.org/libs/filesystem
+
+#include <boost/filesystem/config.hpp>
+# ifdef BOOST_FILESYSTEM_NARROW_ONLY
+# error This compiler or standard library does not support wide-character strings or paths
+# endif
+
+#include "mbpath.hpp"
+#include <boost/system/system_error.hpp>
+#include <boost/scoped_array.hpp>
+
+namespace fs = boost::filesystem;
+
+namespace
+{
+ // ISO C calls this "the locale-specific native environment":
+ std::locale loc("");
+
+ const std::codecvt<wchar_t, char, std::mbstate_t> *
+ cvt( &std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t> >
+ ( loc ) );
+}
+
+namespace user
+{
+ mbpath_traits::external_string_type
+ mbpath_traits::to_external( const mbpath & ph,
+ const internal_string_type & src )
+ {
+ std::size_t work_size( cvt->max_length() * (src.size()+1) );
+ boost::scoped_array<char> work( new char[ work_size ] );
+ std::mbstate_t state;
+ const internal_string_type::value_type * from_next;
+ external_string_type::value_type * to_next;
+ if ( cvt->out(
+ state, src.c_str(), src.c_str()+src.size(), from_next, work.get(),
+ work.get()+work_size, to_next ) != std::codecvt_base::ok )
+ boost::throw_exception<fs::basic_filesystem_error<mbpath> >(
+ fs::basic_filesystem_error<mbpath>(
+ "user::mbpath::to_external conversion error",
+ ph, boost::system::error_code( EINVAL, boost::system::errno_ecat ) ) );
+ *to_next = '\0';
+ return external_string_type( work.get() );
+ }
+
+ mbpath_traits::internal_string_type
+ mbpath_traits::to_internal( const external_string_type & src )
+ {
+ std::size_t work_size( src.size()+1 );
+ boost::scoped_array<wchar_t> work( new wchar_t[ work_size ] );
+ std::mbstate_t state;
+ const external_string_type::value_type * from_next;
+ internal_string_type::value_type * to_next;
+ if ( cvt->in(
+ state, src.c_str(), src.c_str()+src.size(), from_next, work.get(),
+ work.get()+work_size, to_next ) != std::codecvt_base::ok )
+ boost::throw_exception<fs::basic_filesystem_error<mbpath> >(
+ fs::basic_filesystem_error<mbpath>(
+ "user::mbpath::to_internal conversion error",
+ boost::system::error_code( EINVAL, boost::system::errno_ecat ) ) );
+ *to_next = L'\0';
+ return internal_string_type( work.get() );
+ }
+
+ void mbpath_traits::imbue( const std::locale & new_loc )
+ {
+ loc = new_loc;
+ cvt = &std::use_facet
+ <std::codecvt<wchar_t, char, std::mbstate_t> >( loc );
+ }
+
+} // namespace user
Added: sandbox/filesystem-v3/libs/filesystem/v3/example/mbpath.hpp
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/example/mbpath.hpp 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,44 @@
+// Boost.Filesystem mbpath.hpp ---------------------------------------------//
+
+// Copyright Beman Dawes 2005
+
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Encodes wide character paths as MBCS
+// See http://../doc/path.htm#mbpath for more information
+
+#include <boost/filesystem/path.hpp>
+#include <cwchar> // for std::mbstate_t
+#include <string>
+#include <locale>
+
+namespace user
+{
+ struct mbpath_traits;
+
+ typedef boost::filesystem::basic_path<std::wstring, mbpath_traits> mbpath;
+
+ struct mbpath_traits
+ {
+ typedef std::wstring internal_string_type;
+ typedef std::string external_string_type;
+
+ static external_string_type to_external( const mbpath & ph,
+ const internal_string_type & src );
+
+ static internal_string_type to_internal( const external_string_type & src );
+
+ static void imbue( const std::locale & loc );
+ };
+} // namespace user
+
+namespace boost
+{
+ namespace filesystem
+ {
+ template<> struct is_basic_path<user::mbpath>
+ { static const bool value = true; };
+ }
+}
Added: sandbox/filesystem-v3/libs/filesystem/v3/example/path_table.cpp
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/example/path_table.cpp 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,264 @@
+// Generate an HTML table showing path decomposition -----------------------//
+
+// Copyright Beman Dawes 2005. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org/libs/filesystem for documentation.
+
+// For purposes of generating the table, support both POSIX and Windows paths
+#define BOOST_FILESYSTEM_NAMESPACE posix
+#define BOOST_POSIX_PATH
+#include "boost/filesystem/path.hpp"
+
+#undef BOOST_FILESYSTEM_PATH_HPP
+#undef BOOST_FILESYSTEM_NAMESPACE
+#define BOOST_FILESYSTEM_NAMESPACE windows
+#define BOOST_WINDOWS_PATH
+#include "boost/filesystem/path.hpp"
+
+namespace pos = boost::posix;
+namespace win = boost::windows;
+
+#include <iostream>
+#include <fstream>
+
+using std::string;
+using std::cout;
+
+namespace
+{
+ std::ifstream infile;
+ std::ofstream outfile;
+
+ const string empty_string;
+
+ struct column_abc
+ {
+ virtual string heading() const = 0;
+ virtual string cell_value( const pos::path & p ) const = 0;
+ virtual string cell_value( const win::path & p ) const = 0;
+ };
+
+ struct c0 : public column_abc
+ {
+ string heading() const { return string("<code>string()</code>"); }
+ string cell_value( const pos::path & p ) const
+ {
+ return p.string();
+ }
+ string cell_value( const win::path & p ) const
+ {
+ return p.string();
+ }
+ } o0;
+
+ struct c1 : public column_abc
+ {
+ string heading() const { return string("<code>file_<br>string()"); }
+ string cell_value( const pos::path & p ) const { return p.file_string(); }
+ string cell_value( const win::path & p ) const { return p.file_string(); }
+ } o1;
+
+ struct c2 : public column_abc
+ {
+ string heading() const { return string("Elements found<br>by iteration"); }
+ string cell_value( const pos::path & p ) const
+ {
+ string s;
+ for( pos::path::iterator i(p.begin()); i != p.end(); ++i )
+ {
+ if ( i != p.begin() ) s += ',';
+ s += '\"';
+ s += *i;
+ s += '\"';
+ }
+ if ( s.empty() ) s += "\"\"";
+ return s;
+ }
+ string cell_value( const win::path & p ) const
+ {
+ string s;
+ for( win::path::iterator i(p.begin()); i != p.end(); ++i )
+ {
+ if ( i != p.begin() ) s += ',';
+ s += '\"';
+ s += *i;
+ s += '\"';
+ }
+ if ( s.empty() ) s += "\"\"";
+ return s;
+ }
+ } o2;
+
+ struct c3 : public column_abc
+ {
+ string heading() const { return string("<code>root_<br>path()<br>.string()</code>"); }
+ string cell_value( const pos::path & p ) const { return p.root_path().string(); }
+ string cell_value( const win::path & p ) const { return p.root_path().string(); }
+ } o3;
+
+ struct c4 : public column_abc
+ {
+ string heading() const { return string("<code>root_<br>name()</code>"); }
+ string cell_value( const pos::path & p ) const { return p.root_name(); }
+ string cell_value( const win::path & p ) const { return p.root_name(); }
+ } o4;
+
+ struct c5 : public column_abc
+ {
+ string heading() const { return string("<code>root_<br>directory()</code>"); }
+ string cell_value( const pos::path & p ) const { return p.root_directory(); }
+ string cell_value( const win::path & p ) const { return p.root_directory(); }
+ } o5;
+
+ struct c6 : public column_abc
+ {
+ string heading() const { return string("<code>relative_<br>path()<br>.string()</code>"); }
+ string cell_value( const pos::path & p ) const { return p.relative_path().string(); }
+ string cell_value( const win::path & p ) const { return p.relative_path().string(); }
+ } o6;
+
+ struct c7 : public column_abc
+ {
+ string heading() const { return string("<code>branch_<br>path()<br>.string()</code>"); }
+ string cell_value( const pos::path & p ) const { return p.branch_path().string(); }
+ string cell_value( const win::path & p ) const { return p.branch_path().string(); }
+ } o7;
+
+ struct c8 : public column_abc
+ {
+ string heading() const { return string("<code>leaf()</code>"); }
+ string cell_value( const pos::path & p ) const { return p.leaf(); }
+ string cell_value( const win::path & p ) const { return p.leaf(); }
+ } o8;
+
+ const column_abc * column[] = { &o2, &o0, &o1, &o3, &o4, &o5, &o6, &o7, &o8 };
+
+ // do_cell ---------------------------------------------------------------//
+
+ void do_cell( const string & test_case, int i )
+ {
+
+ string posix_result( column[i]->cell_value( pos::path(test_case) ) );
+ string windows_result( column[i]->cell_value( win::path(test_case) ) );
+
+ outfile <<
+ (posix_result != windows_result
+ ? "<td bgcolor=\"#CCFF99\"><code>"
+ : "<td><code>");
+
+ if ( posix_result.empty() || posix_result[0] != '\"' )
+ outfile << '\"' << posix_result << '\"';
+ else
+ outfile << posix_result;
+
+ if ( posix_result != windows_result )
+ {
+ outfile << "<br>";
+ if ( windows_result.empty() || windows_result[0] != '\"' )
+ outfile << '\"' << windows_result << '\"';
+ else
+ outfile << windows_result;
+ }
+
+ outfile << "</code></td>\n";
+ }
+
+// do_row ------------------------------------------------------------------//
+
+ void do_row( const string & test_case )
+ {
+ outfile << "<tr>\n<td><code>\"" << test_case << "\"</code></td>\n";
+
+ for ( int i = 0; i < sizeof(column)/sizeof(column_abc&); ++i )
+ {
+ do_cell( test_case, i );
+ }
+
+ outfile << "</tr>\n";
+ }
+
+// do_table ----------------------------------------------------------------//
+
+ void do_table()
+ {
+ outfile <<
+ "<h1>Path Decomposition Table for <i>POSIX</i> and <i>Windows</i></h1>\n"
+ "<p>Shaded entries indicate cases where <i>POSIX</i> and <i>Windows</i>\n"
+ "implementations yield different results. The top value is the\n"
+ "<i>POSIX</i> result and the bottom value is the <i>Windows</i> result.\n"
+ "<table border=\"1\" cellspacing=\"0\" cellpadding=\"5\">\n"
+ "<p>\n"
+ ;
+
+ // generate the column headings
+
+ outfile << "<tr><td><b>Constructor<br>argument</b></td>\n";
+
+ for ( int i = 0; i < sizeof(column)/sizeof(column_abc&); ++i )
+ {
+ outfile << "<td><b>" << column[i]->heading() << "</b></td>\n";
+ }
+
+ outfile << "</tr>\n";
+
+ // generate a row for each input line
+
+ string test_case;
+ while ( std::getline( infile, test_case ) )
+ {
+ do_row( test_case );
+ }
+
+ outfile << "</table>\n";
+ }
+
+} // unnamed namespace
+
+// main --------------------------------------------------------------------//
+
+#define BOOST_NO_CPP_MAIN_SUCCESS_MESSAGE
+#include <boost/test/included/prg_exec_monitor.hpp>
+
+int cpp_main( int argc, char * argv[] ) // note name!
+{
+ if ( argc != 3 )
+ {
+ std::cerr <<
+ "Usage: path_table input-file output-file\n"
+ " input-file contains the paths to appear in the table.\n"
+ " output-file will contain the generated HTML.\n"
+ ;
+ return 1;
+ }
+
+ infile.open( argv[1] );
+ if ( !infile )
+ {
+ std::cerr << "Could not open input file: " << argv[1] << std::endl;
+ return 1;
+ }
+
+ outfile.open( argv[2] );
+ if ( !outfile )
+ {
+ std::cerr << "Could not open output file: " << argv[2] << std::endl;
+ return 1;
+ }
+
+ outfile << "<html>\n"
+ "<head>\n"
+ "<title>Path Decomposition Table</title>\n"
+ "</head>\n"
+ "<body bgcolor=\"#ffffff\" text=\"#000000\">\n"
+ ;
+
+ do_table();
+
+ outfile << "</body>\n"
+ "</html>\n"
+ ;
+
+ return 0;
+}
Added: sandbox/filesystem-v3/libs/filesystem/v3/example/simple_ls.cpp
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/example/simple_ls.cpp 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,87 @@
+// simple_ls program -------------------------------------------------------//
+
+// Copyright Jeff Garland and Beman Dawes, 2002
+
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org/libs/filesystem for documentation.
+
+// As an example program, we don't want to use any deprecated features
+#define BOOST_FILESYSTEM_NO_DEPRECATED
+
+#include "boost/filesystem/operations.hpp"
+#include "boost/filesystem/path.hpp"
+#include "boost/progress.hpp"
+#include <iostream>
+
+namespace fs = boost::filesystem;
+
+int main( int argc, char* argv[] )
+{
+ boost::progress_timer t( std::clog );
+
+ fs::path full_path( fs::initial_path<fs::path>() );
+
+ if ( argc > 1 )
+ full_path = fs::system_complete( fs::path( argv[1] ) );
+ else
+ std::cout << "\nusage: simple_ls [path]" << std::endl;
+
+ unsigned long file_count = 0;
+ unsigned long dir_count = 0;
+ unsigned long other_count = 0;
+ unsigned long err_count = 0;
+
+ if ( !fs::exists( full_path ) )
+ {
+ std::cout << "\nNot found: " << full_path.file_string() << std::endl;
+ return 1;
+ }
+
+ if ( fs::is_directory( full_path ) )
+ {
+ std::cout << "\nIn directory: "
+ << full_path.directory_string() << "\n\n";
+ fs::directory_iterator end_iter;
+ for ( fs::directory_iterator dir_itr( full_path );
+ dir_itr != end_iter;
+ ++dir_itr )
+ {
+ try
+ {
+ if ( fs::is_directory( dir_itr->status() ) )
+ {
+ ++dir_count;
+ std::cout << dir_itr->path().filename() << " [directory]\n";
+ }
+ else if ( fs::is_regular_file( dir_itr->status() ) )
+ {
+ ++file_count;
+ std::cout << dir_itr->path().filename() << "\n";
+ }
+ else
+ {
+ ++other_count;
+ std::cout << dir_itr->path().filename() << " [other]\n";
+ }
+
+ }
+ catch ( const std::exception & ex )
+ {
+ ++err_count;
+ std::cout << dir_itr->path().filename() << " " << ex.what() << std::endl;
+ }
+ }
+ std::cout << "\n" << file_count << " files\n"
+ << dir_count << " directories\n"
+ << other_count << " others\n"
+ << err_count << " errors\n";
+ }
+ else // must be a file
+ {
+ std::cout << "\nFound: " << full_path.file_string() << "\n";
+ }
+ return 0;
+}
Added: sandbox/filesystem-v3/libs/filesystem/v3/example/tchar.cpp
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/example/tchar.cpp 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,39 @@
+// Example use of Microsoft TCHAR ------------------------------------------//
+
+// Copyright Beman Dawes 2008
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/filesystem/path.hpp>
+#include <boost/filesystem/operations.hpp>
+#include <string>
+#include <cassert>
+#include <windows.h>
+#include <winnt.h>
+
+namespace fs = boost::filesystem;
+
+typedef std::basic_string<TCHAR> tstring;
+
+void func( const fs::path & p )
+{
+ assert( fs::exists( p ) );
+}
+
+int main()
+{
+ // get a path that is known to exist
+ fs::path cp = fs::current_path();
+
+ // demo: get tstring from the path
+ tstring cp_as_tstring = cp.string<tstring>();
+
+ // demo: pass tstring to filesystem function taking path
+ assert( fs::exists( cp_as_tstring ) );
+
+ // demo: pass tstring to user function taking path
+ func( cp_as_tstring );
+
+ return 0;
+}
Added: sandbox/filesystem-v3/libs/filesystem/v3/src/error_code.cpp
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/src/error_code.cpp 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,421 @@
+// error_code support implementation file ----------------------------------//
+
+// Copyright Beman Dawes 2002, 2006
+
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See library home page at http://www.boost.org/libs/system
+
+//----------------------------------------------------------------------------//
+
+#include <boost/config/warning_disable.hpp>
+
+// define BOOST_SYSTEM_SOURCE so that <boost/system/config.hpp> knows
+// the library is being built (possibly exporting rather than importing code)
+#define BOOST_SYSTEM_SOURCE
+
+#include <boost/system/config.hpp>
+#include <boost/system/error_code.hpp>
+#include <boost/cerrno.hpp>
+#include <vector>
+#include <cstdlib>
+#include <cassert>
+
+using namespace boost::system;
+using namespace boost::system::posix_error;
+
+#include <cstring> // for strerror/strerror_r
+
+# if defined( BOOST_WINDOWS_API )
+# include <windows.h>
+# ifndef ERROR_INCORRECT_SIZE
+# define ERROR_INCORRECT_SIZE ERROR_BAD_ARGUMENTS
+# endif
+# endif
+
+//----------------------------------------------------------------------------//
+
+namespace
+{
+
+ // standard error categories ---------------------------------------------//
+
+ class generic_error_category : public error_category
+ {
+ public:
+ generic_error_category(){}
+ const char * name() const;
+ std::string message( int ev ) const;
+ };
+
+ class system_error_category : public error_category
+ {
+ public:
+ system_error_category(){}
+ const char * name() const;
+ std::string message( int ev ) const;
+ error_condition default_error_condition( int ev ) const;
+ };
+
+ // generic_error_category implementation ---------------------------------//
+
+ const char * generic_error_category::name() const
+ {
+ return "GENERIC";
+ }
+
+ std::string generic_error_category::message( int ev ) const
+ {
+ // strerror_r is preferred because it is always thread safe,
+ // however, we fallback to strerror in certain cases because:
+ // -- Windows doesn't provide strerror_r.
+ // -- HP and Sundo provide strerror_r on newer systems, but there is
+ // no way to tell if is available at runtime and in any case their
+ // versions of strerror are thread safe anyhow.
+ // -- Linux only sometimes provides strerror_r.
+ // -- Tru64 provides strerror_r only when compiled -pthread.
+ // -- VMS doesn't provide strerror_r, but on this platform, strerror is
+ // thread safe.
+ # if defined(BOOST_WINDOWS_API) || defined(__hpux) || defined(__sun)\
+ || (defined(__linux) && (!defined(__USE_XOPEN2K) || defined(BOOST_SYSTEM_USE_STRERROR)))\
+ || (defined(__osf__) && !defined(_REENTRANT))\
+ || (defined(__vms))
+ const char * c_str = std::strerror( ev );
+ return std::string( c_str ? c_str : "Unknown error" );
+ # else
+ char buf[64];
+ char * bp = buf;
+ std::size_t sz = sizeof(buf);
+ # if defined(__CYGWIN__) || defined(__USE_GNU)
+ // Oddball version of strerror_r
+ const char * c_str = strerror_r( ev, bp, sz );
+ return std::string( c_str ? c_str : "Unknown error" );
+ # else
+ // POSIX version of strerror_r
+ int result;
+ for (;;)
+ {
+ // strerror_r returns 0 on success, otherwise ERANGE if buffer too small,
+ // invalid_argument if ev not a valid error number
+ # if defined (__sgi)
+ const char * c_str = strerror( ev );
+ result = 0;
+ return std::string( c_str ? c_str : "Unknown error" );
+ # else
+ result = strerror_r( ev, bp, sz );
+ # endif
+ if (result == 0 )
+ break;
+ else
+ {
+ # if defined(__linux)
+ // Linux strerror_r returns -1 on error, with error number in errno
+ result = errno;
+ # endif
+ if ( result != ERANGE ) break;
+ if ( sz > sizeof(buf) ) std::free( bp );
+ sz *= 2;
+ if ( (bp = static_cast<char*>(std::malloc( sz ))) == 0 )
+ return std::string( "ENOMEM" );
+ }
+ }
+ try
+ {
+ std::string msg( ( result == invalid_argument ) ? "Unknown error" : bp );
+ if ( sz > sizeof(buf) ) std::free( bp );
+ sz = 0;
+ return msg;
+ }
+ catch(...)
+ {
+ if ( sz > sizeof(buf) ) std::free( bp );
+ throw;
+ }
+ # endif
+ # endif
+ }
+ // system_error_category implementation --------------------------------//
+
+ const char * system_error_category::name() const
+ {
+ return "system";
+ }
+
+ error_condition system_error_category::default_error_condition( int ev ) const
+ {
+ switch ( ev )
+ {
+ case 0: return make_error_condition( success );
+ # if defined(BOOST_POSIX_API)
+ // POSIX-like O/S -> posix_errno decode table ---------------------------//
+ case E2BIG: return make_error_condition( argument_list_too_long );
+ case EACCES: return make_error_condition( permission_denied );
+ case EADDRINUSE: return make_error_condition( address_in_use );
+ case EADDRNOTAVAIL: return make_error_condition( address_not_available );
+ case EAFNOSUPPORT: return make_error_condition( address_family_not_supported );
+ case EAGAIN: return make_error_condition( resource_unavailable_try_again );
+ case EALREADY: return make_error_condition( connection_already_in_progress );
+ case EBADF: return make_error_condition( bad_file_descriptor );
+ case EBADMSG: return make_error_condition( bad_message );
+ case EBUSY: return make_error_condition( device_or_resource_busy );
+ case ECANCELED: return make_error_condition( operation_canceled );
+ case ECHILD: return make_error_condition( no_child_process );
+ case ECONNABORTED: return make_error_condition( connection_aborted );
+ case ECONNREFUSED: return make_error_condition( connection_refused );
+ case ECONNRESET: return make_error_condition( connection_reset );
+ case EDEADLK: return make_error_condition( resource_deadlock_would_occur );
+ case EDESTADDRREQ: return make_error_condition( destination_address_required );
+ case EDOM: return make_error_condition( argument_out_of_domain );
+ case EEXIST: return make_error_condition( file_exists );
+ case EFAULT: return make_error_condition( bad_address );
+ case EFBIG: return make_error_condition( file_too_large );
+ case EHOSTUNREACH: return make_error_condition( host_unreachable );
+ case EIDRM: return make_error_condition( identifier_removed );
+ case EILSEQ: return make_error_condition( illegal_byte_sequence );
+ case EINPROGRESS: return make_error_condition( operation_in_progress );
+ case EINTR: return make_error_condition( interrupted );
+ case EINVAL: return make_error_condition( invalid_argument );
+ case EIO: return make_error_condition( io_error );
+ case EISCONN: return make_error_condition( already_connected );
+ case EISDIR: return make_error_condition( is_a_directory );
+ case ELOOP: return make_error_condition( too_many_synbolic_link_levels );
+ case EMFILE: return make_error_condition( too_many_files_open );
+ case EMLINK: return make_error_condition( too_many_links );
+ case EMSGSIZE: return make_error_condition( message_size );
+ case ENAMETOOLONG: return make_error_condition( filename_too_long );
+ case ENETDOWN: return make_error_condition( network_down );
+ case ENETRESET: return make_error_condition( network_reset );
+ case ENETUNREACH: return make_error_condition( network_unreachable );
+ case ENFILE: return make_error_condition( too_many_files_open_in_system );
+ case ENOBUFS: return make_error_condition( no_buffer_space );
+ case ENODATA: return make_error_condition( no_message_available );
+ case ENODEV: return make_error_condition( no_such_device );
+ case ENOENT: return make_error_condition( no_such_file_or_directory );
+ case ENOEXEC: return make_error_condition( executable_format_error );
+ case ENOLCK: return make_error_condition( no_lock_available );
+ case ENOLINK: return make_error_condition( no_link );
+ case ENOMEM: return make_error_condition( not_enough_memory );
+ case ENOMSG: return make_error_condition( no_message );
+ case ENOPROTOOPT: return make_error_condition( no_protocol_option );
+ case ENOSPC: return make_error_condition( no_space_on_device );
+ case ENOSR: return make_error_condition( no_stream_resources );
+ case ENOSTR: return make_error_condition( not_a_stream );
+ case ENOSYS: return make_error_condition( function_not_supported );
+ case ENOTCONN: return make_error_condition( not_connected );
+ case ENOTDIR: return make_error_condition( not_a_directory );
+ # if ENOTEMPTY != EEXIST // AIX treats ENOTEMPTY and EEXIST as the same value
+ case ENOTEMPTY: return make_error_condition( directory_not_empty );
+ # endif // ENOTEMPTY != EEXIST
+ case ENOTRECOVERABLE: return make_error_condition( state_not_recoverable );
+ case ENOTSOCK: return make_error_condition( not_a_socket );
+ case ENOTSUP: return make_error_condition( not_supported );
+ case ENOTTY: return make_error_condition( inappropriate_io_control_operation );
+ case ENXIO: return make_error_condition( no_such_device_or_address );
+ # if EOPNOTSUPP != ENOTSUP
+ case EOPNOTSUPP: return make_error_condition( operation_not_supported );
+ # endif // EOPNOTSUPP != ENOTSUP
+ case EOVERFLOW: return make_error_condition( value_too_large );
+ case EOWNERDEAD: return make_error_condition( owner_dead );
+ case EPERM: return make_error_condition( operation_not_permitted );
+ case EPIPE: return make_error_condition( broken_pipe );
+ case EPROTO: return make_error_condition( protocol_error );
+ case EPROTONOSUPPORT: return make_error_condition( protocol_not_supported );
+ case EPROTOTYPE: return make_error_condition( wrong_protocol_type );
+ case ERANGE: return make_error_condition( result_out_of_range );
+ case EROFS: return make_error_condition( read_only_file_system );
+ case ESPIPE: return make_error_condition( invalid_seek );
+ case ESRCH: return make_error_condition( no_such_process );
+ case ETIME: return make_error_condition( stream_timeout );
+ case ETIMEDOUT: return make_error_condition( timed_out );
+ case ETXTBSY: return make_error_condition( text_file_busy );
+ # if EAGAIN != EWOULDBLOCK
+ case EWOULDBLOCK: return make_error_condition( operation_would_block );
+ # endif // EAGAIN != EWOULDBLOCK
+ case EXDEV: return make_error_condition( cross_device_link );
+ #else
+ // Windows system -> posix_errno decode table ---------------------------//
+ // see WinError.h comments for descriptions of errors
+ case ERROR_ACCESS_DENIED: return make_error_condition( permission_denied );
+ case ERROR_ALREADY_EXISTS: return make_error_condition( file_exists );
+ case ERROR_BAD_UNIT: return make_error_condition( no_such_device );
+ case ERROR_BUFFER_OVERFLOW: return make_error_condition( filename_too_long );
+ case ERROR_BUSY: return make_error_condition( device_or_resource_busy );
+ case ERROR_BUSY_DRIVE: return make_error_condition( device_or_resource_busy );
+ case ERROR_CANNOT_MAKE: return make_error_condition( permission_denied );
+ case ERROR_CANTOPEN: return make_error_condition( io_error );
+ case ERROR_CANTREAD: return make_error_condition( io_error );
+ case ERROR_CANTWRITE: return make_error_condition( io_error );
+ case ERROR_CURRENT_DIRECTORY: return make_error_condition( permission_denied );
+ case ERROR_DEV_NOT_EXIST: return make_error_condition( no_such_device );
+ case ERROR_DEVICE_IN_USE: return make_error_condition( device_or_resource_busy );
+ case ERROR_DIR_NOT_EMPTY: return make_error_condition( directory_not_empty );
+ case ERROR_DIRECTORY: return make_error_condition( invalid_argument ); // WinError.h: "The directory name is invalid"
+ case ERROR_DISK_FULL: return make_error_condition( no_space_on_device );
+ case ERROR_FILE_EXISTS: return make_error_condition( file_exists );
+ case ERROR_FILE_NOT_FOUND: return make_error_condition( no_such_file_or_directory );
+ case ERROR_HANDLE_DISK_FULL: return make_error_condition( no_space_on_device );
+ case ERROR_INVALID_ACCESS: return make_error_condition( permission_denied );
+ case ERROR_INVALID_DRIVE: return make_error_condition( no_such_device );
+ case ERROR_INVALID_FUNCTION: return make_error_condition( function_not_supported );
+ case ERROR_INVALID_HANDLE: return make_error_condition( invalid_argument );
+ case ERROR_INVALID_NAME: return make_error_condition( invalid_argument );
+ case ERROR_LOCK_VIOLATION: return make_error_condition( no_lock_available );
+ case ERROR_LOCKED: return make_error_condition( no_lock_available );
+ case ERROR_NEGATIVE_SEEK: return make_error_condition( invalid_argument );
+ case ERROR_NOACCESS: return make_error_condition( permission_denied );
+ case ERROR_NOT_ENOUGH_MEMORY: return make_error_condition( not_enough_memory );
+ case ERROR_NOT_READY: return make_error_condition( resource_unavailable_try_again );
+ case ERROR_NOT_SAME_DEVICE: return make_error_condition( cross_device_link );
+ case ERROR_OPEN_FAILED: return make_error_condition( io_error );
+ case ERROR_OPEN_FILES: return make_error_condition( device_or_resource_busy );
+ case ERROR_OPERATION_ABORTED: return make_error_condition( operation_canceled );
+ case ERROR_OUTOFMEMORY: return make_error_condition( not_enough_memory );
+ case ERROR_PATH_NOT_FOUND: return make_error_condition( no_such_file_or_directory );
+ case ERROR_READ_FAULT: return make_error_condition( io_error );
+ case ERROR_RETRY: return make_error_condition( resource_unavailable_try_again );
+ case ERROR_SEEK: return make_error_condition( io_error );
+ case ERROR_SHARING_VIOLATION: return make_error_condition( permission_denied );
+ case ERROR_TOO_MANY_OPEN_FILES: return make_error_condition( too_many_files_open );
+ case ERROR_WRITE_FAULT: return make_error_condition( io_error );
+ case ERROR_WRITE_PROTECT: return make_error_condition( permission_denied );
+ case WSAEACCES: return make_error_condition( permission_denied );
+ case WSAEADDRINUSE: return make_error_condition( address_in_use );
+ case WSAEADDRNOTAVAIL: return make_error_condition( address_not_available );
+ case WSAEAFNOSUPPORT: return make_error_condition( address_family_not_supported );
+ case WSAEALREADY: return make_error_condition( connection_already_in_progress );
+ case WSAEBADF: return make_error_condition( bad_file_descriptor );
+ case WSAECONNABORTED: return make_error_condition( connection_aborted );
+ case WSAECONNREFUSED: return make_error_condition( connection_refused );
+ case WSAECONNRESET: return make_error_condition( connection_reset );
+ case WSAEDESTADDRREQ: return make_error_condition( destination_address_required );
+ case WSAEFAULT: return make_error_condition( bad_address );
+ case WSAEHOSTUNREACH: return make_error_condition( host_unreachable );
+ case WSAEINPROGRESS: return make_error_condition( operation_in_progress );
+ case WSAEINTR: return make_error_condition( interrupted );
+ case WSAEINVAL: return make_error_condition( invalid_argument );
+ case WSAEISCONN: return make_error_condition( already_connected );
+ case WSAEMFILE: return make_error_condition( too_many_files_open );
+ case WSAEMSGSIZE: return make_error_condition( message_size );
+ case WSAENAMETOOLONG: return make_error_condition( filename_too_long );
+ case WSAENETDOWN: return make_error_condition( network_down );
+ case WSAENETRESET: return make_error_condition( network_reset );
+ case WSAENETUNREACH: return make_error_condition( network_unreachable );
+ case WSAENOBUFS: return make_error_condition( no_buffer_space );
+ case WSAENOPROTOOPT: return make_error_condition( no_protocol_option );
+ case WSAENOTCONN: return make_error_condition( not_connected );
+ case WSAENOTSOCK: return make_error_condition( not_a_socket );
+ case WSAEOPNOTSUPP: return make_error_condition( operation_not_supported );
+ case WSAEPROTONOSUPPORT: return make_error_condition( protocol_not_supported );
+ case WSAEPROTOTYPE: return make_error_condition( wrong_protocol_type );
+ case WSAETIMEDOUT: return make_error_condition( timed_out );
+ case WSAEWOULDBLOCK: return make_error_condition( operation_would_block );
+ #endif
+ default: return error_condition( ev, system_category );
+ }
+ }
+
+# if !defined( BOOST_WINDOWS_API )
+
+ std::string system_error_category::message( int ev ) const
+ {
+ return generic_category.message( ev );
+ }
+# else
+// TODO:
+
+//Some quick notes on the implementation (sorry for the noise if
+//someone has already mentioned them):
+//
+//- The ::LocalFree() usage isn't exception safe.
+//
+//See:
+//
+//<http://boost.cvs.sourceforge.net/boost/boost/boost/asio/system_exception.hpp?revision=1.1&view=markup>
+//
+//in the implementation of what() for an example.
+//
+//Cheers,
+//Chris
+ std::string system_error_category::message( int ev ) const
+ {
+# ifndef BOOST_NO_ANSI_APIS
+ LPVOID lpMsgBuf;
+ DWORD retval = ::FormatMessageA(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ ev,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+ (LPSTR) &lpMsgBuf,
+ 0,
+ NULL
+ );
+ if (retval == 0)
+ return std::string("Unknown error");
+
+ std::string str( static_cast<LPCSTR>(lpMsgBuf) );
+ ::LocalFree( lpMsgBuf ); // free the buffer
+# else // WinCE workaround
+ LPVOID lpMsgBuf;
+ DWORD retval = ::FormatMessageW(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ ev,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+ (LPWSTR) &lpMsgBuf,
+ 0,
+ NULL
+ );
+ if (retval == 0)
+ return std::string("Unknown error");
+
+ int num_chars = (wcslen( static_cast<LPCWSTR>(lpMsgBuf) ) + 1) * 2;
+ LPSTR narrow_buffer = (LPSTR)_alloca( num_chars );
+ if (::WideCharToMultiByte(CP_ACP, 0, static_cast<LPCWSTR>(lpMsgBuf), -1, narrow_buffer, num_chars, NULL, NULL) == 0)
+ return std::string("Unknown error");
+
+ std::string str( narrow_buffer );
+ ::LocalFree( lpMsgBuf ); // free the buffer
+# endif
+ while ( str.size()
+ && (str[str.size()-1] == '\n' || str[str.size()-1] == '\r') )
+ str.erase( str.size()-1 );
+ if ( str.size() && str[str.size()-1] == '.' )
+ { str.erase( str.size()-1 ); }
+ return str;
+ }
+# endif
+
+} // unnamed namespace
+
+namespace boost
+{
+ namespace system
+ {
+
+
+
+ BOOST_SYSTEM_DECL error_code throws; // "throw on error" special error_code;
+ // note that it doesn't matter if this
+ // isn't initialized before use since
+ // the only use is to take its
+ // address for comparison purposes
+
+ BOOST_SYSTEM_DECL const error_category & get_system_category()
+ {
+ static const system_error_category system_category_const;
+ return system_category_const;
+ }
+
+ BOOST_SYSTEM_DECL const error_category & get_generic_category()
+ {
+ static const generic_error_category generic_category_const;
+ return generic_category_const;
+ }
+
+ } // namespace system
+} // namespace boost
Added: sandbox/filesystem-v3/libs/filesystem/v3/src/operations.cpp
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/src/operations.cpp 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,1569 @@
+// operations.cpp ----------------------------------------------------------//
+
+// Copyright 2002-2005 Beman Dawes
+// Copyright 2001 Dietmar Kuehl
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// See library home page at http://www.boost.org/libs/filesystem
+
+//----------------------------------------------------------------------------//
+
+// define BOOST_FILESYSTEM_SOURCE so that <boost/filesystem/config.hpp> knows
+// the library is being built (possibly exporting rather than importing code)
+#define BOOST_FILESYSTEM_SOURCE
+
+#define _POSIX_PTHREAD_SEMANTICS // Sun readdir_r() needs this
+
+// enable the XPG-compliant version of readdir_r() on AIX
+#if defined(_AIX)
+# define _LINUX_SOURCE_COMPAT
+#endif
+
+#if !(defined(__HP_aCC) && defined(_ILP32) && \
+ !defined(_STATVFS_ACPP_PROBLEMS_FIXED))
+#define _FILE_OFFSET_BITS 64 // at worst, these defines may have no effect,
+#endif
+#define __USE_FILE_OFFSET64 // but that is harmless on Windows and on POSIX
+ // 64-bit systems or on 32-bit systems which don't have files larger
+ // than can be represented by a traditional POSIX/UNIX off_t type.
+ // OTOH, defining them should kick in 64-bit off_t's (and thus
+ // st_size) on 32-bit systems that provide the Large File
+ // Support (LFS) interface, such as Linux, Solaris, and IRIX.
+ // The defines are given before any headers are included to
+ // ensure that they are available to all included headers.
+ // That is required at least on Solaris, and possibly on other
+ // systems as well.
+
+// If not already defined, _WIN32_WINNT used to be defined as 0x0500
+// (Windows 2K or later) at this point. But with Vista it becomes more
+// important to know the exact version present, so sdkddkver.h is
+// now required; it will supply specific version infomation.
+
+#include <boost/filesystem/operations.hpp>
+#include <boost/scoped_array.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/detail/workaround.hpp>
+
+#ifdef BOOST_FILEYSTEM_INCLUDE_IOSTREAM
+# include <iostream>
+#endif
+
+namespace fs = boost::filesystem;
+using boost::filesystem::path;
+using boost::filesystem::filesystem_error;
+using boost::system::error_code;
+using boost::system::error_category;
+using boost::system::system_category;
+using boost::system::throws;
+using boost::throw_exception;
+using std::string;
+
+# ifndef BOOST_FILESYSTEM_NARROW_ONLY
+ using std::wstring;
+# endif
+
+# if defined(BOOST_WINDOWS_API)
+# include <windows.h>
+# if defined(__BORLANDC__) || defined(__MWERKS__)
+# if defined(__BORLANDC__)
+ using std::time_t;
+# endif
+# include <utime.h>
+# else
+# include <sys/utime.h>
+# endif
+
+# else // BOOST_POSIX_API
+# include <sys/types.h>
+# if !defined(__APPLE__) && !defined(__OpenBSD__)
+# include <sys/statvfs.h>
+# define BOOST_STATVFS statvfs
+# define BOOST_STATVFS_F_FRSIZE vfs.f_frsize
+# else
+#ifdef __OpenBSD__
+# include <sys/param.h>
+#endif
+# include <sys/mount.h>
+# define BOOST_STATVFS statfs
+# define BOOST_STATVFS_F_FRSIZE static_cast<boost::uintmax_t>( vfs.f_bsize )
+# endif
+# include <dirent.h>
+# include <unistd.h>
+# include <fcntl.h>
+# include <utime.h>
+# include "limits.h"
+# endif
+
+// BOOST_FILESYSTEM_STATUS_CACHE enables file_status cache in
+// dir_itr_increment. The config tests are placed here because some of the
+// macros being tested come from dirent.h.
+//
+// TODO: find out what macros indicate dirent::d_type present in more libraries
+# if defined(BOOST_WINDOWS_API) \
+ || defined(_DIRENT_HAVE_D_TYPE) // defined by GNU C library if d_type present
+# define BOOST_FILESYSTEM_STATUS_CACHE
+# endif
+
+#include <sys/stat.h> // even on Windows some functions use stat()
+#include <string>
+#include <cstring>
+#include <cstdio> // for remove, rename
+#include <cerrno>
+#include <cassert>
+// #include <iostream> // for debugging only; comment out when not in use
+
+#ifdef BOOST_NO_STDC_NAMESPACE
+namespace std { using ::strcmp; using ::remove; using ::rename; }
+#endif
+
+// POSIX/Windows macros ----------------------------------------------------//
+
+// Portions of the POSIX and Windows API's are very similar, except for name,
+// order of arguments, and meaning of zero/non-zero returns. The macros below
+// abstract away those differences. They follow Windows naming and order of
+// arguments, and return true to indicate no error occurred. [POSIX naming,
+// order of arguments, and meaning of return were followed initially, but
+// found to be less clear and cause more coding errors.]
+
+# if defined(BOOST_POSIX_API)
+
+# define BOOST_ERRNO errno
+# define BOOST_SET_CURRENT_DIRECTORY(P) (::chdir(P) == 0)
+# define BOOST_CREATE_DIRECTORY(P) (::mkdir( P, S_IRWXU|S_IRWXG|S_IRWXO ) == 0)
+# define BOOST_CREATE_HARD_LINK(F,T) (::link( T, F ) == 0)
+# define BOOST_CREATE_SYMBOLIC_LINK(F,T,Flag) (::symlink( T, F ) == 0)
+# define BOOST_REMOVE_DIRECTORY(P) (::rmdir( P ) == 0)
+# define BOOST_DELETE_FILE(P) (::unlink( P ) == 0)
+# define BOOST_COPY_FILE(F,T) copy_file_api(F, T)
+# define BOOST_MOVE_FILE(F,T) (::rename(F, T) == 0)
+
+# define BOOST_ERROR_NOT_SUPPORTED ENOSYS
+# define BOOST_ERROR_ALREADY_EXISTS EEXIST
+
+# else // BOOST_WINDOWS_API
+
+# define BOOST_ERRNO ::GetLastError()
+# define BOOST_SET_CURRENT_DIRECTORY(P) (::SetCurrentDirectoryW(P) != 0)
+# define BOOST_CREATE_DIRECTORY(P) (::CreateDirectoryW( P, 0 ) != 0)
+# define BOOST_CREATE_HARD_LINK(F,T) (create_hard_link_api( F, T, 0 ) != 0)
+# define BOOST_CREATE_SYMBOLIC_LINK(F,T,Flag) (create_symbolic_link_api( F, T, Flag ) != 0)
+# define BOOST_REMOVE_DIRECTORY(P) (::RemoveDirectoryW(P) != 0)
+# define BOOST_DELETE_FILE(P) (::DeleteFileW(P) != 0)
+# define BOOST_COPY_FILE(F,T) (::CopyFileW( F, T, /*fail_if_exists=*/true ) != 0)
+# define BOOST_MOVE_FILE(F,T) (::MoveFileW( F, T ) != 0)
+
+# define BOOST_ERROR_ALREADY_EXISTS ERROR_ALREADY_EXISTS
+# define BOOST_ERROR_NOT_SUPPORTED ERROR_NOT_SUPPORTED
+
+# endif
+
+//----------------------------------------------------------------------------//
+// //
+// non-specific helpers //
+// //
+//----------------------------------------------------------------------------//
+
+namespace
+{
+ const std::size_t buf_size( 128 );
+ const error_code ok;
+
+ bool error( bool was_error, error_code & ec, const string & message )
+ {
+ if ( !was_error )
+ {
+ if ( &ec != &throws ) ec.clear();
+ }
+ else
+ { // error
+ if ( &ec == &throws )
+ throw_exception( filesystem_error( message,
+ BOOST_ERRNO, system_category ) );
+ else
+ ec.assign( BOOST_ERRNO, system_category );
+ }
+ return was_error;
+ }
+
+ bool error( bool was_error, const path & p, error_code & ec, const string & message )
+ {
+ if ( !was_error )
+ {
+ if ( &ec != &throws ) ec.clear();
+ }
+ else
+ { // error
+ if ( &ec == &throws )
+ throw_exception( filesystem_error( message,
+ p, BOOST_ERRNO, system_category ) );
+ else
+ ec.assign( BOOST_ERRNO, system_category );
+ }
+ return was_error;
+ }
+
+ bool error( bool was_error, const path & p1, const path & p2, error_code & ec,
+ const string & message )
+ {
+ if ( !was_error )
+ {
+ if ( &ec != &throws ) ec.clear();
+ }
+ else
+ { // error
+ if ( &ec == &throws )
+ throw_exception( filesystem_error( message,
+ p1, p2, BOOST_ERRNO, system_category ) );
+ else
+ ec.assign( BOOST_ERRNO, system_category );
+ }
+ return was_error;
+ }
+
+ bool error( bool was_error, const error_code & result,
+ const path & p, error_code & ec, const string & message )
+ // Overwrites ec if there ahs already been an error
+ {
+ if ( !was_error )
+ {
+ if ( &ec != &throws ) ec.clear();
+ }
+ else
+ { // error
+ if ( &ec == &throws )
+ throw_exception( filesystem_error( message, p, result ) );
+ else
+ ec = result;
+ }
+ return was_error;
+ }
+
+ bool error( bool was_error, const error_code & result,
+ const path & p1, const path & p2, error_code & ec, const string & message )
+ // Overwrites ec if there ahs already been an error
+ {
+ if ( !was_error )
+ {
+ if ( &ec != &throws ) ec.clear();
+ }
+ else
+ { // error
+ if ( &ec == &throws )
+ throw_exception( filesystem_error( message, p1, p2, result ) );
+ else
+ ec = result;
+ }
+ return was_error;
+ }
+
+ bool is_empty_directory( const path & p )
+ {
+ static const fs::directory_iterator end_itr;
+ return fs::directory_iterator( p ) == end_itr;
+ }
+
+ bool remove_directory( const path & p ) // true if succeeds
+ { return BOOST_REMOVE_DIRECTORY( p.c_str() ); }
+
+ bool remove_file( const path & p ) // true if succeeds
+ { return BOOST_DELETE_FILE( p.c_str() ); }
+
+ // called by remove and remove_all_aux
+ bool remove_file_or_directory( const path & p, fs::file_status sym_stat, error_code & ec )
+ // return true if file removed, false if not removed
+ {
+ if ( sym_stat.type() == fs::file_not_found )
+ {
+ if ( &ec != &throws ) ec.clear();
+ return false;
+ }
+
+ if ( fs::is_directory( sym_stat ) )
+ {
+ if ( error( !remove_directory( p ), p, ec, "boost::filesystem::remove" ) )
+ return false;
+ }
+ else
+ {
+ if ( error( !remove_file( p ), p, ec, "boost::filesystem::remove" ) )
+ return false;
+ }
+ return true;
+ }
+
+ boost::uintmax_t remove_all_aux( const path & p, fs::file_status sym_stat, error_code & ec )
+ {
+ static const fs::directory_iterator end_itr;
+ boost::uintmax_t count = 1;
+
+ if ( !fs::is_symlink( sym_stat ) // don't recurse symbolic links
+ && fs::is_directory( sym_stat ) )
+ {
+ for ( fs::directory_iterator itr( p );
+ itr != end_itr; ++itr )
+ {
+ fs::file_status tmp_sym_stat = fs::symlink_status( itr->path(), ec );
+ if ( ec && &ec != &throws )
+ return count;
+ count += remove_all_aux( itr->path(), tmp_sym_stat, ec );
+ }
+ }
+ remove_file_or_directory( p, sym_stat, ec );
+ return count;
+ }
+
+//----------------------------------------------------------------------------//
+// //
+// Windows-specific helpers //
+// //
+//----------------------------------------------------------------------------//
+
+#if defined(BOOST_WINDOWS_API)
+
+ // these constants come from inspecting some Microsoft sample code
+ std::time_t to_time_t( const FILETIME & ft )
+ {
+ __int64 t = (static_cast<__int64>( ft.dwHighDateTime ) << 32)
+ + ft.dwLowDateTime;
+# if !defined( BOOST_MSVC ) || BOOST_MSVC > 1300 // > VC++ 7.0
+ t -= 116444736000000000LL;
+# else
+ t -= 116444736000000000;
+# endif
+ t /= 10000000;
+ return static_cast<std::time_t>( t );
+ }
+
+ void to_FILETIME( std::time_t t, FILETIME & ft )
+ {
+ __int64 temp = t;
+ temp *= 10000000;
+# if !defined( BOOST_MSVC ) || BOOST_MSVC > 1300 // > VC++ 7.0
+ temp += 116444736000000000LL;
+# else
+ temp += 116444736000000000;
+# endif
+ ft.dwLowDateTime = static_cast<DWORD>( temp );
+ ft.dwHighDateTime = static_cast<DWORD>( temp >> 32 );
+ }
+
+ // Thanks to Jeremy Maitin-Shepard for much help and for permission to
+ // base the equivalent() implementation on portions of his
+ // file-equivalence-win32.cpp experimental code.
+
+ struct handle_wrapper
+ {
+ HANDLE handle;
+ handle_wrapper( HANDLE h )
+ : handle(h) {}
+ ~handle_wrapper()
+ {
+ if ( handle != INVALID_HANDLE_VALUE )
+ ::CloseHandle(handle);
+ }
+ };
+
+ HANDLE create_file_handle( path p, DWORD dwDesiredAccess,
+ DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
+ DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes,
+ HANDLE hTemplateFile )
+ {
+ return ::CreateFileW( p.c_str(), dwDesiredAccess, dwShareMode,
+ lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
+ hTemplateFile );
+ }
+
+ inline std::size_t get_full_path_name(
+ const path & src, std::size_t len, wchar_t * buf, wchar_t ** p )
+ {
+ return static_cast<std::size_t>(
+ ::GetFullPathNameW( src.c_str(), static_cast<DWORD>(len), buf, p ));
+ }
+
+ // Windows kernel32.dll functions that may or may not be present
+ // must be accessed through pointers
+
+ typedef BOOL (WINAPI *PtrCreateHardLinkW)(
+ /*__in*/ LPCWSTR lpFileName,
+ /*__in*/ LPCWSTR lpExistingFileName,
+ /*__reserved*/ LPSECURITY_ATTRIBUTES lpSecurityAttributes
+ );
+
+ PtrCreateHardLinkW create_hard_link_api = PtrCreateHardLinkW(
+ ::GetProcAddress(
+ ::GetModuleHandle(TEXT("kernel32.dll")), "CreateHardLinkW") );
+
+ typedef BOOLEAN (WINAPI *PtrCreateSymbolicLinkW)(
+ /*__in*/ LPCWSTR lpSymlinkFileName,
+ /*__in*/ LPCWSTR lpTargetFileName,
+ /*__in*/ DWORD dwFlags
+ );
+
+ PtrCreateSymbolicLinkW create_symbolic_link_api = PtrCreateSymbolicLinkW(
+ ::GetProcAddress(
+ ::GetModuleHandle(TEXT("kernel32.dll")), "CreateSymbolicLinkW") );
+
+//----------------------------------------------------------------------------//
+// //
+// POSIX-specific helpers //
+// //
+//----------------------------------------------------------------------------//
+
+# else
+
+ bool // true if ok occurred
+ copy_file_api( const std::string & from_p,
+ const std::string & to_p )
+ {
+ const std::size_t buf_sz = 32768;
+ boost::scoped_array<char> buf( new char [buf_sz] );
+ int infile=0, outfile=0; // init quiets compiler warning
+ struct stat from_stat;
+
+ if ( ::stat( from_p.c_str(), &from_stat ) != 0
+ || (infile = ::open( from_p.c_str(),
+ O_RDONLY )) < 0
+ || (outfile = ::open( to_p.c_str(),
+ O_WRONLY | O_CREAT | O_EXCL,
+ from_stat.st_mode )) < 0 )
+ { // error
+ if ( infile >= 0 ) ::close( infile );
+ return false;
+ }
+
+ ssize_t sz, sz_read=1, sz_write;
+ while ( sz_read > 0
+ && (sz_read = ::read( infile, buf.get(), buf_sz )) > 0 )
+ {
+ // Allow for partial writes - see Advanced Unix Programming (2nd Ed.),
+ // Marc Rochkind, Addison-Wesley, 2004, page 94
+ sz_write = 0;
+ do
+ {
+ if ( (sz = ::write( outfile, buf.get() + sz_write,
+ sz_read - sz_write )) < 0 )
+ {
+ sz_read = sz; // cause read loop termination
+ break; // and error to be thrown after closes
+ }
+ sz_write += sz;
+ } while ( sz_write < sz_read );
+ }
+
+ if ( ::close( infile) < 0 ) sz_read = -1;
+ if ( ::close( outfile) < 0 ) sz_read = -1;
+
+ return sz_read >= 0; // true if ok
+ }
+
+#endif
+
+ //#ifdef BOOST_WINDOWS_API
+//
+//
+// inline bool get_free_disk_space( const std::wstring & ph,
+// PULARGE_INTEGER avail, PULARGE_INTEGER total, PULARGE_INTEGER free )
+// { return ::GetDiskFreeSpaceExW( ph.c_str(), avail, total, free ) != 0; }
+//
+//
+//#else // BOOST_POSIX_API
+//
+// int posix_remove( const char * p )
+// {
+//# if defined(__QNXNTO__) || (defined(__MSL__) && (defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)))
+// // Some Metrowerks C library versions fail on directories because of a
+// // known Metrowerks coding error in ::remove. Workaround is to call
+// // rmdir() or unlink() as indicated.
+// // Same bug also reported for QNX, with the same fix.
+// int err = ::unlink( p );
+// if ( err != EPERM )
+// return err;
+// return ::rmdir( p )
+//# else
+// return std::remove( p );
+//# endif
+// }
+//
+//#endif
+
+} // unnamed namespace
+
+//----------------------------------------------------------------------------//
+// //
+// operations functions declared in operations.hpp //
+// in alphabetic order //
+// //
+//----------------------------------------------------------------------------//
+
+namespace boost
+{
+ namespace filesystem
+ {
+ namespace detail
+ {
+ BOOST_FILESYSTEM_DECL bool possible_large_file_size_support()
+ {
+# ifdef BOOST_POSIX_API
+ struct stat lcl_stat;
+ return sizeof( lcl_stat.st_size ) > 4;
+# else
+ return true;
+# endif
+ }
+ } // namespace detail
+
+
+ BOOST_FILESYSTEM_DECL
+ path complete( const path & p, const path & base )
+ {
+ BOOST_ASSERT( base.is_complete()
+ && (p.is_complete() || !p.has_root_name())
+ && "boost::filesystem::complete() precondition not met" );
+# ifdef BOOST_WINDOWS_PATH
+ if (p.empty() || p.is_complete())
+ return p;
+ return !p.has_root_name() && p.has_root_directory()
+ ? base.root_name() / p
+ : base / p;
+# else
+ return (p.empty() || p.is_complete()) ? p : base / p;
+# endif
+ }
+
+ BOOST_FILESYSTEM_DECL
+ void copy_file( const path & from, const path & to, error_code & ec )
+ {
+ error( !BOOST_COPY_FILE( from.c_str(), to.c_str() ),
+ from, to, ec, "boost::filesystem::copy_file" );
+ }
+
+ BOOST_FILESYSTEM_DECL
+ bool create_directories( const path & p/*, system::error_code & ec*/ )
+ {
+ if ( p.empty() || exists(p))
+ {
+ if ( !p.empty() && !is_directory(p) )
+ boost::throw_exception( filesystem_error(
+ "boost::filesystem::create_directories", p,
+ error_code( system::errc::file_exists, system::generic_category ) ) );
+ return false;
+ }
+
+ // First create branch, by calling ourself recursively
+ create_directories( p.parent_path() );
+ // Now that parent's path exists, create the directory
+ create_directory( p );
+ return true;
+ }
+
+ BOOST_FILESYSTEM_DECL
+ bool create_directory( const path & p, error_code & ec )
+ {
+ if ( BOOST_CREATE_DIRECTORY( p.c_str() ) )
+ {
+ if ( &ec == &system::throws ) ec.clear();
+ return true;
+ }
+ int errval( BOOST_ERRNO );
+ error_code dummy;
+ if ( errval == BOOST_ERROR_ALREADY_EXISTS && is_directory( p, dummy ) )
+ {
+ if ( &ec == &system::throws ) ec.clear();
+ return false;
+ }
+ if ( &ec == &system::throws )
+ throw_exception( filesystem_error( "boost::filesystem::create_directory",
+ p, errval, system_category ) );
+ else
+ ec.assign( errval, system_category );
+ return false;
+ }
+
+ BOOST_FILESYSTEM_DECL
+ void create_directory_symlink( const path & to, const path & from,
+ system::error_code & ec )
+ {
+# if defined(BOOST_WINDOWS_API) && _WIN32_WINNT < 0x0600 // SDK earlier than Vista and Server 2008
+
+ error( true, error_code(BOOST_ERROR_NOT_SUPPORTED, system_category), to, from, ec,
+ "boost::filesystem::create_directory_symlink" );
+# else
+
+# if defined(BOOST_WINDOWS_API) && _WIN32_WINNT >= 0x0600
+ // see if actually supported by Windows runtime dll
+ if ( error( !create_symbolic_link_api,
+ error_code(BOOST_ERROR_NOT_SUPPORTED, system_category),
+ to, from, ec,
+ "boost::filesystem::create_directory_symlink" ) )
+ return;
+# endif
+
+ error( !BOOST_CREATE_SYMBOLIC_LINK( from.c_str(), to.c_str(), SYMBOLIC_LINK_FLAG_DIRECTORY ),
+ to, from, ec, "boost::filesystem::create_directory_symlink" );
+# endif
+ }
+
+ BOOST_FILESYSTEM_DECL
+ void create_hard_link( const path & to, const path & from, error_code & ec )
+ {
+
+# if defined(BOOST_WINDOWS_API) && _WIN32_WINNT < 0x0500 // SDK earlier than Win 2K
+
+ error( true, error_code(BOOST_ERROR_NOT_SUPPORTED, system_category), to, from, ec,
+ "boost::filesystem::create_hard_link" );
+# else
+
+# if defined(BOOST_WINDOWS_API) && _WIN32_WINNT >= 0x0500
+ // see if actually supported by Windows runtime dll
+ if ( error( !create_hard_link_api,
+ error_code(BOOST_ERROR_NOT_SUPPORTED, system_category),
+ to, from, ec,
+ "boost::filesystem::create_hard_link" ) )
+ return;
+# endif
+
+ error( !BOOST_CREATE_HARD_LINK( from.c_str(), to.c_str() ), to, from, ec,
+ "boost::filesystem::create_hard_link" );
+# endif
+ }
+
+ BOOST_FILESYSTEM_DECL
+ void create_symlink( const path & to, const path & from, error_code & ec )
+ {
+# if defined(BOOST_WINDOWS_API) && _WIN32_WINNT < 0x0600 // SDK earlier than Vista and Server 2008
+
+ error( true, error_code(BOOST_ERROR_NOT_SUPPORTED, system_category), to, from, ec,
+ "boost::filesystem::create_directory_symlink" );
+# else
+
+# if defined(BOOST_WINDOWS_API) && _WIN32_WINNT >= 0x0600
+ // see if actually supported by Windows runtime dll
+ if ( error( !create_symbolic_link_api,
+ error_code(BOOST_ERROR_NOT_SUPPORTED, system_category),
+ to, from, ec,
+ "boost::filesystem::create_directory_symlink" ) )
+ return;
+# endif
+
+ error( !BOOST_CREATE_SYMBOLIC_LINK( from.c_str(), to.c_str(), 0 ),
+ to, from, ec, "boost::filesystem::create_directory_symlink" );
+# endif
+ }
+
+ BOOST_FILESYSTEM_DECL
+ path current_path( error_code & ec )
+ {
+# ifdef BOOST_WINDOWS_API
+ DWORD sz;
+ if ( (sz = ::GetCurrentDirectoryW( 0, NULL )) == 0 ) sz = 1;
+ boost::scoped_array<path::value_type> buf( new path::value_type[sz] );
+ error( ::GetCurrentDirectoryW( sz, buf.get() ) == 0, ec,
+ "boost::filesystem::current_path" );
+ return path( buf.get() );
+
+# else
+ path cur;
+ for ( long path_max = 128;; path_max *=2 ) // loop 'til buffer large enough
+ {
+ boost::scoped_array<char>
+ buf( new char[static_cast<std::size_t>(path_max)] );
+ if ( ::getcwd( buf.get(), static_cast<std::size_t>(path_max) ) == 0 )
+ {
+ if ( error(errno != ERANGE
+ // bug in some versions of the Metrowerks C lib on the Mac: wrong errno set
+# if defined(__MSL__) && (defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__))
+ && errno != 0
+# endif
+ , ec, "boost::filesystem::current_path") )
+ {
+ break;
+ }
+ }
+ else
+ {
+ cur.assign( buf.get(), ec );
+ break;
+ }
+ }
+ return cur;
+# endif
+ }
+
+
+ BOOST_FILESYSTEM_DECL
+ void current_path( const path & p, system::error_code & ec )
+ {
+ error( !BOOST_SET_CURRENT_DIRECTORY( p.c_str() ),
+ p, ec, "boost::filesystem::current_path" );
+ }
+
+ BOOST_FILESYSTEM_DECL
+ bool equivalent( const path & p1, const path & p2, system::error_code & ec )
+ {
+# ifdef BOOST_WINDOWS_API
+ // Note well: Physical location on external media is part of the
+ // equivalence criteria. If there are no open handles, physical location
+ // can change due to defragmentation or other relocations. Thus handles
+ // must be held open until location information for both paths has
+ // been retrieved.
+
+ // p2 is done first, so any error reported is for p1
+ handle_wrapper h2(
+ create_file_handle(
+ p2.c_str(),
+ 0,
+ FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+ 0,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ 0 ) );
+
+ handle_wrapper h1(
+ create_file_handle(
+ p1.c_str(),
+ 0,
+ FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+ 0,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ 0 ) );
+
+ if ( h1.handle == INVALID_HANDLE_VALUE
+ || h2.handle == INVALID_HANDLE_VALUE )
+ {
+ // if one is invalid and the other isn't, then they aren't equivalent,
+ // but if both are invalid then it is an error
+ error( h1.handle == INVALID_HANDLE_VALUE
+ && h2.handle == INVALID_HANDLE_VALUE, p1, p2, ec,
+ "boost::filesystem::equivalent" );
+ return false;
+ }
+
+ // at this point, both handles are known to be valid
+
+ BY_HANDLE_FILE_INFORMATION info1, info2;
+
+ if ( error( !::GetFileInformationByHandle( h1.handle, &info1 ),
+ p1, p2, ec, "boost::filesystem::equivalent" ) )
+ return false;
+
+ if ( error( !::GetFileInformationByHandle( h2.handle, &info2 ),
+ p1, p2, ec, "boost::filesystem::equivalent" ) )
+ return false;
+
+ // In theory, volume serial numbers are sufficient to distinguish between
+ // devices, but in practice VSN's are sometimes duplicated, so last write
+ // time and file size are also checked.
+ return
+ info1.dwVolumeSerialNumber == info2.dwVolumeSerialNumber
+ && info1.nFileIndexHigh == info2.nFileIndexHigh
+ && info1.nFileIndexLow == info2.nFileIndexLow
+ && info1.nFileSizeHigh == info2.nFileSizeHigh
+ && info1.nFileSizeLow == info2.nFileSizeLow
+ && info1.ftLastWriteTime.dwLowDateTime
+ == info2.ftLastWriteTime.dwLowDateTime
+ && info1.ftLastWriteTime.dwHighDateTime
+ == info2.ftLastWriteTime.dwHighDateTime;
+
+# else
+ struct stat s2;
+ int e2( ::stat( p2.c_str(), &s2 ) );
+ struct stat s1;
+ int e1( ::stat( p1.c_str(), &s1 ) );
+
+ if ( e1 != 0 || e2 != 0 )
+ {
+ // if one is invalid and the other isn't then they aren't equivalent,
+ // but if both are invalid then it is an error
+ error (e1 != 0 && e2 != 0, p1, p2, ec, "boost::filesystem::equivalent" );
+ return false;
+ }
+
+ // both stats now known to be valid
+ return s1.st_dev == s2.st_dev && s1.st_ino == s2.st_ino
+ // According to the POSIX stat specs, "The st_ino and st_dev fields
+ // taken together uniquely identify the file within the system."
+ // Just to be sure, size and mod time are also checked.
+ && s1.st_size == s2.st_size && s1.st_mtime == s2.st_mtime;
+# endif
+ }
+
+ BOOST_FILESYSTEM_DECL
+ boost::uintmax_t file_size( const path & p, error_code & ec )
+ {
+# ifdef BOOST_WINDOWS_API
+
+ // assume uintmax_t is 64-bits on all Windows compilers
+
+ WIN32_FILE_ATTRIBUTE_DATA fad;
+
+ if ( error(::GetFileAttributesExW( p.c_str(), ::GetFileExInfoStandard, &fad ) == 0,
+ p, ec, "boost::filesystem::file_size" ) )
+ return 0;
+
+ if ( error((fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0,
+ error_code( ERROR_FILE_NOT_FOUND, system_category),
+ p, ec, "boost::filesystem::file_size" ) )
+ return 0;
+
+ return (static_cast<boost::uintmax_t>(fad.nFileSizeHigh)
+ << (sizeof(fad.nFileSizeLow)*8)) + fad.nFileSizeLow;
+# else
+
+ struct stat path_stat;
+ if ( error( ::stat( p.c_str(), &path_stat ) != 0,
+ p, ec, "boost::filesystem::file_size" ) )
+ return 0;
+ if ( error(!S_ISREG( path_stat.st_mode ),
+ error_code( EPERM, system_category),
+ p, ec, "boost::filesystem::file_size" ) )
+ return 0;
+
+ return static_cast<boost::uintmax_t>(path_stat.st_size);
+# endif
+ }
+
+ BOOST_FILESYSTEM_DECL
+ path initial_path( error_code & ec )
+ {
+ static path init_path;
+ if ( init_path.empty() )
+ init_path = current_path( ec );
+ else if ( &ec != &throws ) ec.clear();
+ return init_path;
+ }
+
+ BOOST_FILESYSTEM_DECL
+ bool is_empty( const path & p, system::error_code & ec )
+ {
+# ifdef BOOST_WINDOWS_API
+
+ WIN32_FILE_ATTRIBUTE_DATA fad;
+ if ( error(::GetFileAttributesExW( p.c_str(), ::GetFileExInfoStandard, &fad ) == 0,
+ p, ec, "boost::filesystem::is_empty" ) )
+ return false;
+
+ if ( &ec != &system::throws ) ec.clear();
+ return
+ ( fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
+ ? is_empty_directory( p )
+ : ( !fad.nFileSizeHigh && !fad.nFileSizeLow );
+# else
+
+ struct stat path_stat;
+ if ( error(::stat( p.c_str(), &path_stat ) != 0,
+ p, ec, "boost::filesystem::is_empty" ) )
+ return false;
+ return S_ISDIR( path_stat.st_mode )
+ ? is_empty_directory( p )
+ : path_stat.st_size == 0;
+# endif
+ }
+
+ BOOST_FILESYSTEM_DECL
+ std::time_t last_write_time( const path & p, system::error_code & ec )
+ {
+# ifdef BOOST_WINDOWS_API
+
+ handle_wrapper hw(
+ create_file_handle( p.c_str(), 0,
+ FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
+ OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 ) );
+
+ if ( error( hw.handle == INVALID_HANDLE_VALUE,
+ p, ec, "boost::filesystem::last_write_time" ) )
+ return std::time_t(-1);
+
+ FILETIME lwt;
+
+ if ( error( ::GetFileTime( hw.handle, 0, 0, &lwt ) == 0,
+ p, ec, "boost::filesystem::last_write_time" ) )
+ return std::time_t(-1);
+
+ return to_time_t( lwt );
+# else
+
+ struct stat path_stat;
+ if ( error( ::stat( p.c_str(), &path_stat ) != 0,
+ p, ec, "boost::filesystem::last_write_time" ) )
+ return std::time_t(-1);
+ return path_stat.st_mtime;
+# endif
+ }
+
+ BOOST_FILESYSTEM_DECL
+ void last_write_time( const path & p, const std::time_t new_time,
+ system::error_code & ec )
+ {
+# ifdef BOOST_WINDOWS_API
+
+ handle_wrapper hw(
+ create_file_handle( p.c_str(), FILE_WRITE_ATTRIBUTES,
+ FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
+ OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 ) );
+
+ if ( error( hw.handle == INVALID_HANDLE_VALUE,
+ p, ec, "boost::filesystem::last_write_time" ) )
+ return;
+
+ FILETIME lwt;
+ to_FILETIME( new_time, lwt );
+
+ error( ::SetFileTime( hw.handle, 0, 0, &lwt ) == 0,
+ p, ec, "boost::filesystem::last_write_time" );
+
+# else
+
+ struct stat path_stat;
+ if ( error( ::stat( p.c_str(), &path_stat ) != 0,
+ p, ec, "boost::filesystem::last_write_time" ) )
+ return;
+ ::utimbuf buf;
+ buf.actime = path_stat.st_atime; // utime() updates access time too:-(
+ buf.modtime = new_time;
+ error( ::utime( p.c_str(), &buf ) != 0,
+ p, ec, "boost::filesystem::last_write_time" );
+# endif
+ }
+
+ BOOST_FILESYSTEM_DECL
+ bool remove( const path & p, error_code & ec )
+ {
+ error_code tmp_ec;
+ file_status sym_status = symlink_status( p, tmp_ec );
+ if ( error( !!tmp_ec, tmp_ec, p, ec, "boost::filesystem::remove" ) )
+ return false;
+
+ return remove_file_or_directory( p, sym_status, ec );
+ }
+
+ BOOST_FILESYSTEM_DECL
+ boost::uintmax_t remove_all( const path & p, error_code & ec )
+ {
+ error_code tmp_ec;
+ file_status sym_status = symlink_status( p, tmp_ec );
+ if ( error( !!tmp_ec, tmp_ec, p, ec, "boost::filesystem::remove_all" ) )
+ return 0;
+
+ return exists( sym_status )
+ ? remove_all_aux( p, sym_status, ec )
+ : 0;
+ }
+
+ BOOST_FILESYSTEM_DECL
+ void rename( const path & from, const path & to, error_code & ec )
+ {
+# ifdef BOOST_POSIX_API
+
+ // POSIX is too permissive so must check
+ error_code dummy;
+ if ( error( fs::exists( to, dummy ),
+ error_code( EEXIST, system_category ),
+ from, to, ec, "boost::filesystem::rename" ) )
+ return;
+# endif
+
+ error( !BOOST_MOVE_FILE( from.c_str(), to.c_str() ), from, to, ec,
+ "boost::filesystem::rename" );
+ }
+
+ BOOST_FILESYSTEM_DECL
+ space_info space( const path & p, error_code & ec )
+ {
+# ifdef BOOST_WINDOWS_API
+
+ ULARGE_INTEGER avail, total, free;
+ space_info info;
+
+ if ( !error( ::GetDiskFreeSpaceExW( p.c_str(), &avail, &total, &free ) == 0,
+ p, ec, "boost::filesystem::space" ) )
+ {
+ info.capacity
+ = (static_cast<boost::uintmax_t>(total.HighPart) << 32)
+ + total.LowPart;
+ info.free
+ = (static_cast<boost::uintmax_t>(free.HighPart) << 32)
+ + free.LowPart;
+ info.available
+ = (static_cast<boost::uintmax_t>(avail.HighPart) << 32)
+ + avail.LowPart;
+ }
+# else
+
+ struct BOOST_STATVFS vfs;
+ space_info info;
+ if ( !error( ::BOOST_STATVFS( p.c_str(), &vfs ) != 0,
+ p, ec, "boost::filesystem::space" ) )
+ {
+ info.capacity
+ = static_cast<boost::uintmax_t>(vfs.f_blocks) * BOOST_STATVFS_F_FRSIZE;
+ info.free
+ = static_cast<boost::uintmax_t>(vfs.f_bfree) * BOOST_STATVFS_F_FRSIZE;
+ info.available
+ = static_cast<boost::uintmax_t>(vfs.f_bavail) * BOOST_STATVFS_F_FRSIZE;
+ }
+
+# endif
+ else
+ {
+ info.capacity = info.free = info.available = 0;
+ }
+ return info;
+ }
+
+
+ namespace detail
+ {
+# ifdef BOOST_WINDOWS_API
+
+ file_status process_status_failure( const path & p, error_code & ec )
+ {
+ int errval( ::GetLastError() );
+ if ((errval == ERROR_FILE_NOT_FOUND)
+ || (errval == ERROR_PATH_NOT_FOUND)
+ || (errval == ERROR_INVALID_NAME) // "tools/jam/src/:sys:stat.h", "//foo"
+ || (errval == ERROR_INVALID_PARAMETER) // ":sys:stat.h"
+ || (errval == ERROR_BAD_PATHNAME) // "//nosuch" on Win64
+ || (errval == ERROR_BAD_NETPATH)) // "//nosuch" on Win32
+ {
+
+ if ( &ec != &system::throws ) ec.clear(); // these are not errors
+ return file_status( file_not_found );
+ }
+ else if ((errval == ERROR_SHARING_VIOLATION))
+ {
+ if ( &ec != &system::throws ) ec.clear(); // these are not errors
+ return file_status( type_unknown );
+ }
+ if ( &ec == &system::throws )
+ throw_exception( filesystem_error( "boost::filesystem::status",
+ p, errval, system_category ) );
+ else
+ ec.assign( errval, system_category );
+ return file_status( status_unknown );
+ }
+
+# endif
+ } // namespace detail
+
+ BOOST_FILESYSTEM_DECL
+ file_status status( const path & p, error_code & ec )
+ {
+# ifdef BOOST_WINDOWS_API
+
+ DWORD attr( ::GetFileAttributesW( p.c_str() ) );
+ if ( attr == 0xFFFFFFFF )
+ {
+ return detail::process_status_failure( p, ec );
+ }
+
+ // symlink handling
+ if ( attr & FILE_ATTRIBUTE_REPARSE_POINT ) // aka symlink
+ {
+ handle_wrapper h(
+ create_file_handle(
+ p.c_str(),
+ 0, // dwDesiredAccess; attributes only
+ FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+ 0, // lpSecurityAttributes
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ 0 ) ); // hTemplateFile
+ if ( h.handle == INVALID_HANDLE_VALUE )
+ {
+ return detail::process_status_failure( p, ec );
+ }
+ }
+
+ if ( &ec != &system::throws ) ec.clear(); // these are not errors
+ return (attr & FILE_ATTRIBUTE_DIRECTORY)
+ ? file_status( directory_file )
+ : file_status( regular_file );
+
+# else
+
+ struct stat path_stat;
+ if ( ::stat( p.c_str(), &path_stat ) != 0 )
+ {
+ if ( errno == ENOENT || errno == ENOTDIR )
+ {
+ if ( &ec != &throws ) ec.clear();;
+ return fs::file_status( fs::file_not_found );
+ }
+ if ( &ec != &throws )
+ ec.assign( errno, system_category );
+ else
+ throw_exception( filesystem_error( "boost::filesystem::status",
+ p, errno, system_category ) );
+
+ return fs::file_status( fs::status_unknown );
+ }
+ if ( &ec != &throws ) ec.clear();;
+ if ( S_ISDIR( path_stat.st_mode ) )
+ return fs::file_status( fs::directory_file );
+ if ( S_ISREG( path_stat.st_mode ) )
+ return fs::file_status( fs::regular_file );
+ if ( S_ISBLK( path_stat.st_mode ) )
+ return fs::file_status( fs::block_file );
+ if ( S_ISCHR( path_stat.st_mode ) )
+ return fs::file_status( fs::character_file );
+ if ( S_ISFIFO( path_stat.st_mode ) )
+ return fs::file_status( fs::fifo_file );
+ if ( S_ISSOCK( path_stat.st_mode ) )
+ return fs::file_status( fs::socket_file );
+ return fs::file_status( fs::type_unknown );
+
+# endif
+ }
+
+ BOOST_FILESYSTEM_DECL
+ file_status symlink_status( const path & p, error_code & ec )
+ {
+# ifdef BOOST_WINDOWS_API
+
+ DWORD attr( ::GetFileAttributesW( p.c_str() ) );
+ if ( attr == 0xFFFFFFFF )
+ {
+ return detail::process_status_failure( p, ec );
+ }
+
+ if ( attr & FILE_ATTRIBUTE_REPARSE_POINT ) // aka symlink
+ return file_status( symlink_file );
+
+ if ( &ec != &system::throws ) ec.clear(); // these are not errors
+ return (attr & FILE_ATTRIBUTE_DIRECTORY)
+ ? file_status( directory_file )
+ : file_status( regular_file );
+
+# else
+
+ struct stat path_stat;
+ if ( ::lstat( p.c_str(), &path_stat ) != 0 )
+ {
+ if ( errno == ENOENT || errno == ENOTDIR ) // these are not errors
+ {
+ if ( &ec != &system::throws ) ec.clear();
+ return fs::file_status( fs::file_not_found );
+ }
+ if ( &ec != &system::throws ) ec.assign( errno, system_category );
+ else
+ return fs::file_status( fs::status_unknown );
+ }
+ if ( &ec != &system::throws ) ec.clear();
+ if ( S_ISREG( path_stat.st_mode ) )
+ return fs::file_status( fs::regular_file );
+ if ( S_ISDIR( path_stat.st_mode ) )
+ return fs::file_status( fs::directory_file );
+ if ( S_ISLNK( path_stat.st_mode ) )
+ return fs::file_status( fs::symlink_file );
+ if ( S_ISBLK( path_stat.st_mode ) )
+ return fs::file_status( fs::block_file );
+ if ( S_ISCHR( path_stat.st_mode ) )
+ return fs::file_status( fs::character_file );
+ if ( S_ISFIFO( path_stat.st_mode ) )
+ return fs::file_status( fs::fifo_file );
+ if ( S_ISSOCK( path_stat.st_mode ) )
+ return fs::file_status( fs::socket_file );
+ return fs::file_status( fs::type_unknown );
+
+# endif
+ }
+
+ BOOST_FILESYSTEM_DECL
+ path system_complete( const path & p, system::error_code & ec )
+ {
+# ifdef BOOST_WINDOWS_API
+ if ( p.empty() ) return p;
+ wchar_t buf[buf_size];
+ wchar_t * pfn;
+ std::size_t len = get_full_path_name( p, buf_size, buf, &pfn );
+
+ if ( error( len == 0, p, ec, "boost::filesystem::system_complete" ) )
+ return path();
+
+ if ( len < buf_size ) // len does not include null termination character
+ return path( buf );
+
+ boost::scoped_array<wchar_t> big_buf( new wchar_t[len] );
+
+ return error( get_full_path_name( p, len , big_buf.get(), &pfn ) == 0,
+ p, ec, "boost::filesystem::system_complete" )
+ ? path()
+ : path( big_buf.get() );
+
+# else
+ return (p.empty() || p.is_complete())
+ ? p : current_path() / p;
+# endif
+ }
+
+//
+//# else // BOOST_POSIX_API
+//
+//
+//
+// // suggested by Walter Landry
+// BOOST_FILESYSTEM_DECL bool
+// symbolic_link_exists_api( const std::string & ph )
+// {
+// struct stat path_stat;
+// return ::lstat( ph.c_str(), &path_stat ) == 0
+// && S_ISLNK( path_stat.st_mode );
+// }
+//
+//
+// BOOST_FILESYSTEM_DECL error_code
+// remove_api( const std::string & ph )
+// {
+// if ( posix_remove( ph.c_str() ) == 0 )
+// return ok;
+// int error = errno;
+// // POSIX says "If the directory is not an empty directory, rmdir()
+// // shall fail and set errno to EEXIST or ENOTEMPTY."
+// // Linux uses ENOTEMPTY, Solaris uses EEXIST.
+// if ( error == EEXIST ) error = ENOTEMPTY;
+//
+// error_code ec;
+//
+// // ignore errors if post-condition satisfied
+// return status_api(ph, ec).type() == file_not_found
+// ? ok : error_code( error, system_category ) ;
+// }
+//
+//
+//
+//
+//# endif
+// } // namespace detail
+
+//----------------------------------------------------------------------------//
+// //
+// directory_entry //
+// //
+//----------------------------------------------------------------------------//
+
+ file_status
+ directory_entry::status( system::error_code & ec ) const
+ {
+ if ( !status_known( m_status ) )
+ {
+ // optimization: if the symlink status is known, and it isn't a symlink,
+ // then status and symlink_status are identical so just copy the
+ // symlink status to the regular status.
+ if ( status_known( m_symlink_status )
+ && !is_symlink( m_symlink_status ) )
+ {
+ m_status = m_symlink_status;
+ if ( &ec != &system::throws ) ec.clear();
+ }
+ else m_status = fs::status( m_path, ec );
+ }
+ else if ( &ec != &system::throws ) ec.clear();
+ return m_status;
+ }
+
+ file_status
+ directory_entry::symlink_status( system::error_code & ec ) const
+ {
+ if ( !status_known( m_symlink_status ) )
+ m_symlink_status = fs::symlink_status( m_path, ec );
+ else if ( &ec != &system::throws ) ec.clear();
+ return m_symlink_status;
+ }
+
+} // namespace filesystem
+} // namespace boost
+
+//----------------------------------------------------------------------------//
+// //
+// directory_iterator //
+// //
+//----------------------------------------------------------------------------//
+
+namespace
+{
+# ifdef BOOST_WINDOWS_API
+
+ error_code dir_itr_first( void *& handle, const wstring & dir,
+ wstring & target, fs::file_status & sf, fs::file_status & symlink_sf )
+ // Note: an empty root directory has no "." or ".." entries, so this
+ // causes a ERROR_FILE_NOT_FOUND error which we do not considered an
+ // error. It is treated as eof instead.
+ {
+ // use a form of search Sebastian Martel reports will work with Win98
+ wstring dirpath( dir );
+ dirpath += (dirpath.empty()
+ || (dirpath[dirpath.size()-1] != L'\\'
+ && dirpath[dirpath.size()-1] != L'/'
+ && dirpath[dirpath.size()-1] != L':')) ? L"\\*" : L"*";
+
+ WIN32_FIND_DATAW data;
+ if ( (handle = ::FindFirstFileW( dirpath.c_str(), &data ))
+ == INVALID_HANDLE_VALUE )
+ {
+ handle = 0;
+ return error_code( ::GetLastError() == ERROR_FILE_NOT_FOUND
+ ? 0 : ::GetLastError(), system_category );
+ }
+ target = data.cFileName;
+ if ( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
+ { sf.type( fs::directory_file ); symlink_sf.type( fs::directory_file ); }
+ else { sf.type( fs::regular_file ); symlink_sf.type( fs::regular_file ); }
+ return error_code();
+ }
+
+ error_code dir_itr_increment( void *& handle, wstring & target,
+ fs::file_status & sf, fs::file_status & symlink_sf )
+ {
+ WIN32_FIND_DATAW data;
+ if ( ::FindNextFileW( handle, &data ) == 0 ) // fails
+ {
+ int error = ::GetLastError();
+ fs::detail::dir_itr_close( handle );
+ return error_code( error == ERROR_NO_MORE_FILES ? 0 : error, system_category );
+ }
+ target = data.cFileName;
+ if ( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
+ { sf.type( fs::directory_file ); symlink_sf.type( fs::directory_file ); }
+ else { sf.type( fs::regular_file ); symlink_sf.type( fs::regular_file ); }
+ return error_code();
+ }
+# else // BOOST_POSIX_API
+
+ error_code path_max( std::size_t & result )
+ // this code is based on Stevens and Rago, Advanced Programming in the
+ // UNIX envirnment, 2nd Ed., ISBN 0-201-43307-9, page 49
+ {
+# ifdef PATH_MAX
+ static std::size_t max = PATH_MAX;
+# else
+ static std::size_t max = 0;
+# endif
+ if ( max == 0 )
+ {
+ errno = 0;
+ long tmp = ::pathconf( "/", _PC_NAME_MAX );
+ if ( tmp < 0 )
+ {
+ if ( errno == 0 ) // indeterminate
+ max = 4096; // guess
+ else return error_code( errno, system_category );
+ }
+ else max = static_cast<std::size_t>( tmp + 1 ); // relative root
+ }
+ result = max;
+ return ok;
+ }
+
+ error_code dir_itr_first( void *& handle, void *& buffer,
+ const string & dir, string & target,
+ fs::file_status &, fs::file_status & )
+ {
+ if ( (handle = ::opendir( dir.c_str() )) == 0 )
+ return error_code( errno, system_category );
+ target = string( "." ); // string was static but caused trouble
+ // when iteration called from dtor, after
+ // static had already been destroyed
+ std::size_t path_size;
+ error_code ec = path_max( path_size );
+ if ( ec ) return ec;
+ dirent de;
+ buffer = std::malloc( (sizeof(dirent) - sizeof(de.d_name))
+ + path_size + 1 ); // + 1 for "/0"
+ return ok;
+ }
+
+ //error_code dir_itr_close( void *& handle, void*& buffer )
+ //{
+ // std::free( buffer );
+ // buffer = 0;
+ // if ( handle == 0 ) return ok;
+ // DIR * h( static_cast<DIR*>(handle) );
+ // handle = 0;
+ // return error_code( ::closedir( h ) == 0 ? 0 : errno, system_category );
+ //}
+
+ // warning: the only dirent member updated is d_name
+ inline int readdir_r_simulator( DIR * dirp, struct dirent * entry,
+ struct dirent ** result ) // *result set to 0 on end of directory
+ {
+ errno = 0;
+
+# if !defined(__CYGWIN__) \
+ && defined(_POSIX_THREAD_SAFE_FUNCTIONS) \
+ && defined(_SC_THREAD_SAFE_FUNCTIONS) \
+ && (_POSIX_THREAD_SAFE_FUNCTIONS+0 >= 0) \
+ && (!defined(__hpux) || (defined(__hpux) && defined(_REENTRANT)))
+ if ( ::sysconf( _SC_THREAD_SAFE_FUNCTIONS ) >= 0 )
+ { return ::readdir_r( dirp, entry, result ); }
+# endif
+
+ struct dirent * p;
+ *result = 0;
+ if ( (p = ::readdir( dirp )) == 0 )
+ return errno;
+ std::strcpy( entry->d_name, p->d_name );
+ *result = entry;
+ return 0;
+ }
+
+ error_code dir_itr_increment( void *& handle, void *& buffer,
+ string & target, fs::file_status & sf, fs::file_status & symlink_sf )
+ {
+ BOOST_ASSERT( buffer != 0 );
+ dirent * entry( static_cast<dirent *>(buffer) );
+ dirent * result;
+ int return_code;
+ if ( (return_code = readdir_r_simulator( static_cast<DIR*>(handle),
+ entry, &result )) != 0 ) return error_code( errno, system_category );
+ if ( result == 0 )
+ return fs::detail::dir_itr_close( handle, buffer );
+ target = entry->d_name;
+# ifdef BOOST_FILESYSTEM_STATUS_CACHE
+ if ( entry->d_type == DT_UNKNOWN ) // filesystem does not supply d_type value
+ {
+ sf = symlink_sf = fs::file_status(fs::status_unknown);
+ }
+ else // filesystem supplies d_type value
+ {
+ if ( entry->d_type == DT_DIR )
+ sf = symlink_sf = fs::file_status( fs::directory_file );
+ else if ( entry->d_type == DT_REG )
+ sf = symlink_sf = fs::file_status( fs::regular_file );
+ else if ( entry->d_type == DT_LNK )
+ {
+ sf = fs::file_status( fs::status_unknown );
+ symlink_sf = fs::file_status( fs::symlink_file );
+ }
+ else sf = symlink_sf = fs::file_status( fs::status_unknown );
+ }
+# else
+ sf = symlink_sf = fs::file_status( fs::status_unknown );
+# endif
+ return ok;
+ }
+#endif
+
+ const error_code not_found_error (
+# ifdef BOOST_WINDOWS_API
+ ERROR_PATH_NOT_FOUND
+# else
+ ENOENT
+# endif
+ , system_category );
+
+} // unnamed namespace
+
+namespace boost
+{
+namespace filesystem
+{
+
+namespace detail
+{
+ // dir_itr_close is called both from the ~dir_itr_imp() destructor
+ // and dir_itr_increment()
+ BOOST_FILESYSTEM_DECL
+ system::error_code dir_itr_close( // never throws
+ void *& handle
+# if defined(BOOST_POSIX_API)
+ , void *& buffer
+# endif
+ )
+ {
+# ifdef BOOST_WINDOWS_API
+ if ( handle != 0 )
+ {
+ ::FindClose( handle );
+ handle = 0;
+ }
+ return ok;
+# else
+
+ std::free( buffer );
+ buffer = 0;
+ if ( handle == 0 ) return ok;
+ DIR * h( static_cast<DIR*>(handle) );
+ handle = 0;
+ return error_code( ::closedir( h ) == 0 ? 0 : errno, system_category );
+# endif
+ }
+
+ void directory_iterator_construct( directory_iterator & it,
+ const path & p, system::error_code & ec )
+ {
+ if ( error( p.empty(), not_found_error, p, ec,
+ "boost::filesystem::directory_iterator::construct" ) ) return;
+
+ path::string_type filename;
+ file_status file_stat, symlink_file_stat;
+ error_code result = dir_itr_first( it.m_imp->handle,
+ #if defined(BOOST_POSIX_API)
+ it.m_imp->buffer,
+ #endif
+ p, filename, file_stat, symlink_file_stat );
+
+ if ( result )
+ {
+ it.m_imp.reset();
+ error( true, result, p,
+ ec, "boost::filesystem::directory_iterator::construct" );
+ return;
+ }
+
+ if ( it.m_imp->handle == 0 ) it.m_imp.reset(); // eof, so make end iterator
+ else // not eof
+ {
+ it.m_imp->dir_entry.assign( p / filename,
+ file_stat, symlink_file_stat );
+ if ( filename[0] == detail::dot // dot or dot-dot
+ && (filename.size() == 1
+ || (filename[1] == detail::dot
+ && filename.size() == 2)) )
+ { it.increment(); }
+ }
+ }
+
+ void directory_iterator_increment( directory_iterator & it )
+ {
+ BOOST_ASSERT( it.m_imp.get() && "attempt to increment end iterator" );
+ BOOST_ASSERT( it.m_imp->handle != 0 && "internal program error" );
+
+ path::string_type filename;
+ file_status file_stat, symlink_file_stat;
+ system::error_code ec;
+
+ for (;;)
+ {
+ ec = dir_itr_increment( it.m_imp->handle,
+#if defined(BOOST_POSIX_API)
+ it.m_imp->buffer,
+#endif
+ filename, file_stat, symlink_file_stat );
+
+ if ( ec )
+ {
+ it.m_imp.reset();
+ error( true, it.m_imp->dir_entry.path().parent_path(),
+ ec, "boost::filesystem::directory_iterator::operator++" );
+ return;
+ }
+
+ if ( it.m_imp->handle == 0 ) { it.m_imp.reset(); return; } // eof, make end
+ if ( !(filename[0] == detail::dot // !(dot or dot-dot)
+ && (filename.size() == 1
+ || (filename[1] == detail::dot
+ && filename.size() == 2))) )
+ {
+ it.m_imp->dir_entry.replace_filename(
+ filename, file_stat, symlink_file_stat );
+ return;
+ }
+ }
+ }
+
+} // namespace detail
+} // namespace filesystem
+} // namespace boost
Added: sandbox/filesystem-v3/libs/filesystem/v3/src/path.cpp
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/src/path.cpp 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,635 @@
+// filesystem path.cpp --------------------------------------------------- //
+
+// Copyright Beman Dawes 2008
+
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// define BOOST_FILESYSTEM_SOURCE so that <boost/system/config.hpp> knows
+// the library is being built (possibly exporting rather than importing code)
+#define BOOST_FILESYSTEM_SOURCE
+
+#include <boost/filesystem/config.hpp>
+#include <boost/filesystem/path.hpp>
+#include <boost/scoped_array.hpp>
+#include <boost/system/error_code.hpp>
+#include <boost/assert.hpp>
+#include <cstddef>
+#include <cstring>
+#include <cassert>
+#include <windows.h>
+
+namespace fs = boost::filesystem;
+
+using std::string;
+
+# ifndef BOOST_FILESYSTEM_NARROW_ONLY
+ using std::wstring;
+# endif
+
+namespace
+{
+
+# ifdef BOOST_WINDOWS_PATH
+
+ const wchar_t * separator_string = L"/";
+ const wchar_t * preferred_separator_string = L"\\";
+ const fs::path dot_path( L"." );
+
+# else
+
+ const char * separator_string = "/";
+ const char * preferred_separator_string = "/";
+ const fs::path dot_path( "." );
+
+# endif
+
+# ifdef BOOST_WINDOWS_API
+
+ const std::locale windows_default; // only use is to take address
+
+ void windows_convert_append( const char * begin, const char * end,
+ // end == 0 for null terminated MBCS
+ std::wstring & target, boost::system::error_code & ec );
+
+ void locale_convert_append( const char * begin, const char * end,
+ // end == 0 for null terminated MBCS
+ std::wstring & target, boost::system::error_code & ec );
+# else // BOOST_POSIX_API
+
+
+
+# endif
+
+}
+
+namespace boost
+{
+namespace filesystem
+{
+
+# ifdef BOOST_WINDOWS_API
+
+namespace detail
+{
+ const std::locale * path_locale( &windows_default );
+
+ // convert_append --------------------------------------------------------//
+
+ void convert_append( const char * begin, const char * end,
+ std::wstring & target, system::error_code & ec )
+ {
+ if ( path_locale == &windows_default )
+ windows_convert_append( begin, end, target, ec );
+ else
+ locale_convert_append( begin, end, target, ec );
+ }
+
+ // convert ---------------------------------------------------------------//
+
+ BOOST_FILESYSTEM_DECL
+ string convert( const wstring & src, system::error_code & ec )
+ {
+ if ( src.empty() ) return std::string();
+
+ UINT codepage = AreFileApisANSI() ? CP_THREAD_ACP : CP_OEMCP;
+
+ // buffer management strategy; use a probably large enough default buffer,
+ // but fallback to an explict allocation if the default buffer is too small
+
+ const std::size_t default_buf_sz = MAX_PATH+1;
+ char buf[default_buf_sz+1];
+ int count;
+
+ if ( (count = ::WideCharToMultiByte( codepage, WC_NO_BEST_FIT_CHARS, src.c_str(),
+ src.size(), buf, default_buf_sz, 0, 0 )) != 0 ) // success
+ {
+ ec.clear();
+ buf[count] = '\0';
+ return std::string( buf );
+ }
+
+ // TODO: implement fallback
+ BOOST_ASSERT(0);
+ throw "path::native_string() error handling not implemented yet";
+ return std::string();
+ }
+
+} // namespace detail
+} // namespace filesystem
+} // namespace boost
+
+namespace
+{
+
+ void locale_convert_append( const char * begin, const char * end,
+ // end == 0 for null terminated MBCS
+ std::wstring & target, boost::system::error_code & ec )
+ {
+ BOOST_ASSERT( 0 && "not implemented yet" );
+ }
+
+
+ void windows_convert_append( const char * begin, const char * end,
+ std::wstring & target, boost::system::error_code & ec )
+ {
+ UINT codepage = AreFileApisANSI() ? CP_THREAD_ACP : CP_OEMCP;
+ int size( end == 0 ? -1 : (end - begin) );
+
+ // buffer management:
+ //
+ // if path prefixed by "\\?\" (Windows 'long path' prefix)
+ // then use dynamic allocation, else use automatic allocation
+
+ bool dynamic_allocation = target.find( L"\\\\?\\" ) == 0
+ || ( target.empty()
+ && ( (size >= 4 && std::memcmp( begin, "\\\\?\\", 4 ) == 0)
+ || (size == -1 && std::strcmp( begin, "\\\\?\\" ) == 0) ) );
+
+ wchar_t stack_buf[MAX_PATH+1];
+ boost::scoped_array< wchar_t > heap_buf;
+ wchar_t * buf = stack_buf;
+ int buf_size = sizeof(stack_buf)/sizeof(wchar_t) - 1;
+
+ if ( dynamic_allocation )
+ {
+ // get the allocation size for the buffer
+ // rationale for calling MultiByteToWideChar: begin may point to a
+ // multi-byte encoded string with embedded nulls, so a simplistic
+ // computation of the size can fail
+
+ buf_size = ::MultiByteToWideChar( codepage, MB_PRECOMPOSED, begin, size, 0, 0 );
+ heap_buf.reset( new wchar_t [buf_size] );
+ buf = heap_buf.get();
+ }
+
+ // perform the conversion
+
+ if ( (buf_size = ::MultiByteToWideChar( codepage, MB_PRECOMPOSED, begin,
+ size, buf, buf_size )) == 0 )
+ {
+ // conversion failed
+ ec = boost::system::error_code( ::GetLastError(), boost::system::system_category );
+ return;
+ }
+
+ ec.clear();
+
+ // perform the append
+
+ buf[buf_size] = L'\0';
+ target += buf;
+ }
+
+} // unnamed namespace
+
+namespace boost
+{
+namespace filesystem
+{
+
+# else // BOOST_POSIX_API
+
+# endif // BOOST_POSIX_API
+
+//---------------------- class path member functions -----------------------//
+
+# ifdef BOOST_WINDOWS_PATH
+
+ // generic ---------------------------------------------------------------//
+
+ const path path::generic() const
+ {
+ path tmp;
+
+ for ( string_type::const_iterator it = m_path.begin();
+ it != m_path.end(); ++it )
+ {
+ tmp.m_path += *it != L'\\' ? *it : L'/';
+ }
+
+ return tmp;
+ }
+
+ // native ---------------------------------------------------------------//
+
+ const path path::native() const
+ {
+ path tmp;
+
+ for ( string_type::const_iterator it = m_path.begin();
+ it != m_path.end(); ++it )
+ {
+ tmp.m_path += *it != L'/' ? *it : L'\\';
+ }
+
+ return tmp;
+ }
+# endif // BOOST_WINDOWS_PATH
+
+ // append_separator_if_needed_ -------------------------------------------//
+
+ void path::append_separator_if_needed_()
+ {
+ if ( !m_path.empty() &&
+# ifdef BOOST_WINDOWS_PATH
+ *(m_path.end()-1) != detail::colon &&
+# endif
+ !detail::is_separator( *(m_path.end()-1) ) )
+ {
+ m_path += detail::preferred_separator;
+ }
+ }
+
+ // decomposition ---------------------------------------------------------//
+
+ path path::root_path() const
+ {
+ path temp( root_name() );
+ if ( !root_directory().empty() ) temp.m_path += root_directory().c_str();
+ return temp;
+ }
+
+ path path::root_name() const
+ {
+ iterator itr( begin() );
+
+ return ( itr.m_pos != m_path.size()
+ && (
+ ( itr.m_element.m_path.size() > 1
+ && detail::is_separator( itr.m_element.m_path[0] )
+ && detail::is_separator( itr.m_element.m_path[1] )
+ )
+# ifdef BOOST_WINDOWS_PATH
+ || itr.m_element.m_path[itr.m_element.m_path.size()-1] == detail::colon
+# endif
+ ) )
+ ? itr.m_element
+ : path();
+ }
+
+ path path::root_directory() const
+ {
+ size_type pos( detail::root_directory_start( m_path, m_path.size() ) );
+
+ return pos == string_type::npos
+ ? path()
+ : path( m_path.c_str() + pos, m_path.c_str() + pos + 1 );
+ }
+
+ path path::relative_path() const
+ {
+ iterator itr( begin() );
+
+ for ( ; itr.m_pos != m_path.size()
+ && ( detail::is_separator( itr.m_element.m_path[0] )
+# ifdef BOOST_WINDOWS_PATH
+ || itr.m_element.m_path[itr.m_element.m_path.size()-1] == detail::colon
+# endif
+ ); ++itr ) {}
+
+ return path( m_path.c_str() + itr.m_pos );
+ }
+
+ path path::parent_path() const
+ {
+ size_type end_pos( detail::filename_pos( m_path, m_path.size() ) );
+
+ bool filename_was_separator( m_path.size()
+ && detail::is_separator( m_path[end_pos] ) );
+
+ // skip separators unless root directory
+ size_type root_dir_pos( detail::root_directory_start( m_path, end_pos ) );
+ for ( ;
+ end_pos > 0
+ && (end_pos-1) != root_dir_pos
+ && detail::is_separator( m_path[end_pos-1] )
+ ;
+ --end_pos ) {}
+
+ return (end_pos == 1 && root_dir_pos == 0 && filename_was_separator)
+ ? path()
+ : path( m_path.c_str(), m_path.c_str() + end_pos );
+ }
+
+ path path::filename() const
+ {
+ size_type pos( detail::filename_pos( m_path, m_path.size() ) );
+ return (m_path.size()
+ && pos
+ && detail::is_separator( m_path[pos] )
+ && detail::is_non_root_separator(m_path, pos))
+ ? dot_path
+ : path( m_path.c_str() + pos );
+ }
+
+ path path::stem() const
+ {
+ path name( filename() );
+ size_type pos( name.m_path.rfind( detail::dot ) );
+ return pos == string_type::npos
+ ? name
+ : path( name.m_path.c_str(), name.m_path.c_str() + pos );
+ }
+
+ path path::extension() const
+ {
+ path name( filename() );
+ size_type pos( name.m_path.rfind( detail::dot ) );
+ return pos == string_type::npos
+ ? path()
+ : path( name.m_path.c_str() + pos );
+ }
+
+ //---------------------- namespace detail functions -----------------------//
+
+namespace detail
+{
+
+ // is_non_root_separator -------------------------------------------------//
+
+ BOOST_FILESYSTEM_DECL
+ bool is_non_root_separator( const string_type & str, size_type pos )
+ // pos is position of the separator
+ {
+ BOOST_ASSERT( !str.empty() && is_separator( str[pos] )
+ && "precondition violation" );
+
+ // subsequent logic expects pos to be for leftmost slash of a set
+ while ( pos > 0 && is_separator( str[pos-1] ) )
+ --pos;
+
+ return pos != 0
+ && (pos <= 2 || !is_separator( str[1] )
+ || str.find_first_of( separators, 2 ) != pos)
+# ifdef BOOST_WINDOWS_PATH
+ && (pos !=2 || str[1] != colon)
+# endif
+ ;
+ }
+
+ // filename_pos ----------------------------------------------------------//
+
+ BOOST_FILESYSTEM_DECL
+ size_type filename_pos( const string_type & str,
+ size_type end_pos ) // end_pos is past-the-end position
+ // return 0 if str itself is filename (or empty)
+ {
+ // case: "//"
+ if ( end_pos == 2
+ && is_separator( str[0] )
+ && is_separator( str[1] ) ) return 0;
+
+ // case: ends in "/"
+ if ( end_pos && is_separator( str[end_pos-1] ) )
+ return end_pos-1;
+
+ // set pos to start of last element
+ size_type pos( str.find_last_of( separators, end_pos-1 ) );
+
+# ifdef BOOST_WINDOWS_PATH
+ if ( pos == string_type::npos )
+ pos = str.find_last_of( colon, end_pos-2 );
+# endif
+
+ return ( pos == string_type::npos // path itself must be a filename (or empty)
+ || (pos == 1 && is_separator( str[0] )) ) // or net
+ ? 0 // so filename is entire string
+ : pos + 1; // or starts after delimiter
+ }
+
+ // root_directory_start --------------------------------------------------//
+
+ BOOST_FILESYSTEM_DECL
+ size_type root_directory_start( const string_type & path, size_type size )
+ // return npos if no root_directory found
+ {
+
+# ifdef BOOST_WINDOWS_PATH
+ // case "c:/"
+ if ( size > 2
+ && path[1] == colon
+ && is_separator( path[2] ) ) return 2;
+# endif
+
+ // case "//"
+ if ( size == 2
+ && is_separator( path[0] )
+ && is_separator( path[1] ) ) return string_type::npos;
+
+ // case "//net {/}"
+ if ( size > 3
+ && is_separator( path[0] )
+ && is_separator( path[1] )
+ && !is_separator( path[2] ) )
+ {
+ string_type::size_type pos( path.find_first_of( separators, 2 ) );
+ return pos < size ? pos : string_type::npos;
+ }
+
+ // case "/"
+ if ( size > 0 && is_separator( path[0] ) ) return 0;
+
+ return string_type::npos;
+ }
+
+ // first_element ----------------------------------------------------------//
+ // sets pos and len of first element, excluding extra separators
+ // if src.empty(), sets pos,len, to 0,0.
+
+ BOOST_FILESYSTEM_DECL
+ void first_element(
+ const string_type & src,
+ size_type & element_pos,
+ size_type & element_size,
+ size_type size
+ )
+ {
+ if ( size == string_type::npos ) size = src.size();
+ element_pos = 0;
+ element_size = 0;
+ if ( src.empty() ) return;
+
+ string_type::size_type cur(0);
+
+ // deal with // [network]
+ if ( size >= 2 && is_separator( src[0] )
+ && is_separator( src[1] )
+ && (size == 2
+ || !is_separator( src[2] )) )
+ {
+ cur += 2;
+ element_size += 2;
+ }
+
+ // leading (not non-network) separator
+ else if ( is_separator( src[0] ) )
+ {
+ ++element_size;
+ // bypass extra leading separators
+ while ( cur+1 < size
+ && is_separator( src[cur+1] ) )
+ {
+ ++cur;
+ ++element_pos;
+ }
+ return;
+ }
+
+ // at this point, we have either a plain name, a network name,
+ // or (on Windows only) a device name
+
+ // find the end
+ while ( cur < size
+# ifdef BOOST_WINDOWS_PATH
+ && src[cur] != colon
+# endif
+ && !is_separator( src[cur] ) )
+ {
+ ++cur;
+ ++element_size;
+ }
+
+# ifdef BOOST_WINDOWS_PATH
+ if ( cur == size ) return;
+ // include device delimiter
+ if ( src[cur] == colon )
+ { ++element_size; }
+# endif
+
+ return;
+ }
+
+} // namespace detail
+
+ //--------------------------------------------------------------------------//
+ // //
+ // path::iterator implementation //
+ // //
+ //--------------------------------------------------------------------------//
+
+
+ path::iterator path::begin() const
+ {
+ iterator itr;
+ itr.m_path_ptr = this;
+ detail::size_type element_size;
+ detail::first_element( m_path, itr.m_pos, element_size );
+ itr.m_element = m_path.substr( itr.m_pos, element_size );
+ if ( itr.m_element.m_path == preferred_separator_string )
+ itr.m_element.m_path = separator_string; // needed for Windows, harmless on POSIX
+ return itr;
+ }
+
+ path::iterator path::end() const
+ {
+ iterator itr;
+ itr.m_path_ptr = this;
+ itr.m_pos = m_path.size();
+ return itr;
+ }
+
+ void path::m_path_iterator_increment( path::iterator & it )
+ {
+ BOOST_ASSERT( it.m_pos < it.m_path_ptr->m_path.size() && "path::basic_iterator increment past end()" );
+
+ // increment to position past current element
+ it.m_pos += it.m_element.m_path.size();
+
+ // if end reached, create end basic_iterator
+ if ( it.m_pos == it.m_path_ptr->m_path.size() )
+ {
+ it.m_element.clear();
+ return;
+ }
+
+ // both POSIX and Windows treat paths that begin with exactly two separators specially
+ bool was_net( it.m_element.m_path.size() > 2
+ && detail::is_separator( it.m_element.m_path[0] )
+ && detail::is_separator( it.m_element.m_path[1] )
+ && !detail::is_separator( it.m_element.m_path[2] ) );
+
+ // process separator (Windows drive spec is only case not a separator)
+ if ( detail::is_separator( it.m_path_ptr->m_path[it.m_pos] ) )
+ {
+ // detect root directory
+ if ( was_net
+# ifdef BOOST_WINDOWS_PATH
+ // case "c:/"
+ || it.m_element.m_path[it.m_element.m_path.size()-1] == detail::colon
+# endif
+ )
+ {
+ it.m_element.m_path = detail::separator;
+ return;
+ }
+
+ // bypass separators
+ while ( it.m_pos != it.m_path_ptr->m_path.size()
+ && detail::is_separator( it.m_path_ptr->m_path[it.m_pos] ) )
+ { ++it.m_pos; }
+
+ // detect trailing separator, and treat it as ".", per POSIX spec
+ if ( it.m_pos == it.m_path_ptr->m_path.size()
+ && detail::is_non_root_separator( it.m_path_ptr->m_path, it.m_pos-1 ) )
+ {
+ --it.m_pos;
+ it.m_element = dot_path;
+ return;
+ }
+ }
+
+ // get next element
+ size_type end_pos( it.m_path_ptr->m_path.find_first_of( detail::separators, it.m_pos ) );
+ if ( end_pos == string_type::npos ) end_pos = it.m_path_ptr->m_path.size();
+ it.m_element = it.m_path_ptr->m_path.substr( it.m_pos, end_pos - it.m_pos );
+ }
+
+ void path::m_path_iterator_decrement( path::iterator & it )
+ {
+ BOOST_ASSERT( it.m_pos && "path::iterator decrement past begin()" );
+
+ size_type end_pos( it.m_pos );
+
+ // if at end and there was a trailing non-root '/', return "."
+ if ( it.m_pos == it.m_path_ptr->m_path.size()
+ && it.m_path_ptr->m_path.size() > 1
+ && detail::is_separator( it.m_path_ptr->m_path[it.m_pos-1] )
+ && detail::is_non_root_separator( it.m_path_ptr->m_path, it.m_pos-1 )
+ )
+ {
+ --it.m_pos;
+ it.m_element = dot_path;
+ return;
+ }
+
+ size_type root_dir_pos( detail::root_directory_start( it.m_path_ptr->m_path, end_pos ) );
+
+ // skip separators unless root directory
+ for (
+ ;
+ end_pos > 0
+ && (end_pos-1) != root_dir_pos
+ && detail::is_separator( it.m_path_ptr->m_path[end_pos-1] )
+ ;
+ --end_pos ) {}
+
+ it.m_pos = detail::filename_pos( it.m_path_ptr->m_path, end_pos );
+ it.m_element = it.m_path_ptr->m_path.substr( it.m_pos, end_pos - it.m_pos );
+ if ( it.m_element.m_path == preferred_separator_string )
+ it.m_element.m_path = separator_string; // needed for Windows, harmless on POSIX
+ }
+
+ bool path::m_path_lex_compare( iterator first1, iterator last1,
+ iterator first2, iterator last2 )
+ {
+ for ( ; first1 != last1 && first2 != last2 ; ++first1, ++first2)
+ {
+ if ( first1->m_path < first2->m_path ) return true;
+ if ( first2->m_path < first1->m_path ) return false;
+ }
+ return first1 == last1 && first2 != last2;
+ }
+
+} // namespace filesystem
+} // namespace boost
Added: sandbox/filesystem-v3/libs/filesystem/v3/src/portability.cpp
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/src/portability.cpp 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,112 @@
+// portability.cpp ---------------------------------------------------------//
+
+// Copyright 2002-2005 Beman Dawes
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy
+// at http://www.boost.org/LICENSE_1_0.txt)
+
+// See library home page at http://www.boost.org/libs/filesystem
+
+//----------------------------------------------------------------------------//
+
+// define BOOST_FILESYSTEM_SOURCE so that <boost/filesystem/config.hpp> knows
+// the library is being built (possibly exporting rather than importing code)
+#define BOOST_FILESYSTEM_SOURCE
+
+#include <boost/filesystem/config.hpp>
+#include <boost/filesystem/path.hpp>
+
+namespace fs = boost::filesystem;
+
+#include <cstring> // SGI MIPSpro compilers need this
+
+# ifdef BOOST_NO_STDC_NAMESPACE
+ namespace std { using ::strerror; }
+# endif
+
+//----------------------------------------------------------------------------//
+
+namespace
+{
+ const char invalid_chars[] =
+ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
+ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"
+ "<>:\"/\\|";
+ // note that the terminating '\0' is part of the string - thus the size below
+ // is sizeof(invalid_chars) rather than sizeof(invalid_chars)-1. I
+ const std::string windows_invalid_chars( invalid_chars, sizeof(invalid_chars) );
+
+ const std::string valid_posix(
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-" );
+
+} // unnamed namespace
+
+namespace boost
+{
+ namespace filesystem
+ {
+
+ // name_check functions ----------------------------------------------//
+
+# ifdef BOOST_WINDOWS
+ BOOST_FILESYSTEM_DECL bool native( const std::string & name )
+ {
+ return windows_name( name );
+ }
+# else
+ BOOST_FILESYSTEM_DECL bool native( const std::string & name )
+ {
+ return name.find('/') == std::string::npos;
+ }
+# endif
+
+ BOOST_FILESYSTEM_DECL bool portable_posix_name( const std::string & name )
+ {
+ return name.size() != 0
+ && name.find_first_not_of( valid_posix ) == std::string::npos;
+ }
+
+ BOOST_FILESYSTEM_DECL bool windows_name( const std::string & name )
+ {
+ return name.size() != 0
+ && name.find_first_of( windows_invalid_chars ) == std::string::npos
+ && *(name.end()-1) != ' '
+ && (*(name.end()-1) != '.'
+ || name.length() == 1 || name == "..");
+ }
+
+ BOOST_FILESYSTEM_DECL bool portable_name( const std::string & name )
+ {
+ return
+ name.size() == 0
+ || name == "."
+ || name == ".."
+ || (windows_name( name )
+ && portable_posix_name( name )
+ && name[0] != '.' && name[0] != '-');
+ }
+
+ BOOST_FILESYSTEM_DECL bool portable_directory_name( const std::string & name )
+ {
+ return
+ name == "."
+ || name == ".."
+ || (portable_name( name )
+ && name.find('.') == std::string::npos);
+ }
+
+ BOOST_FILESYSTEM_DECL bool portable_file_name( const std::string & name )
+ {
+ std::string::size_type pos;
+ return
+ name == "."
+ || name == ".."
+ || (portable_name( name )
+ && ( (pos = name.find( '.' )) == std::string::npos
+ || (name.find( '.', pos+1 )== std::string::npos
+ && (pos + 5) > name.length() )))
+ ;
+ }
+
+ } // namespace filesystem
+} // namespace boost
Added: sandbox/filesystem-v3/libs/filesystem/v3/src/utf8_codecvt_facet.cpp
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/src/utf8_codecvt_facet.cpp 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,20 @@
+// Copyright Vladimir Prus 2004.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_FILESYSTEM_SOURCE
+#include <boost/filesystem/config.hpp>
+
+#define BOOST_UTF8_BEGIN_NAMESPACE \
+ namespace boost { namespace filesystem { namespace detail {
+
+#define BOOST_UTF8_END_NAMESPACE }}}
+#define BOOST_UTF8_DECL BOOST_FILESYSTEM_DECL
+
+#include "libs/detail/utf8_codecvt_facet.cpp"
+
+
+#undef BOOST_UTF8_BEGIN_NAMESPACE
+#undef BOOST_UTF8_END_NAMESPACE
+#undef BOOST_UTF8_DECL
Added: sandbox/filesystem-v3/libs/filesystem/v3/src/utf8_codecvt_facet.hpp
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/src/utf8_codecvt_facet.hpp 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,24 @@
+// Copyright (c) 2001 Ronald Garcia, Indiana University (garcia_at_[hidden])
+// Andrew Lumsdaine, Indiana University (lums_at_[hidden]).
+
+// Distributed under the Boost Software License, Version 1.0.
+// (See http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_FILESYSTEM_UTF8_CODECVT_FACET_HPP
+#define BOOST_FILESYSTEM_UTF8_CODECVT_FACET_HPP
+
+#include <boost/filesystem/config.hpp>
+
+#define BOOST_UTF8_BEGIN_NAMESPACE \
+ namespace boost { namespace filesystem { namespace detail {
+
+#define BOOST_UTF8_END_NAMESPACE }}}
+#define BOOST_UTF8_DECL BOOST_FILESYSTEM_DECL
+
+#include <boost/detail/utf8_codecvt_facet.hpp>
+
+#undef BOOST_UTF8_BEGIN_NAMESPACE
+#undef BOOST_UTF8_END_NAMESPACE
+#undef BOOST_UTF8_DECL
+
+#endif
Added: sandbox/filesystem-v3/libs/filesystem/v3/test/Jamfile.v2
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/test/Jamfile.v2 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,55 @@
+# Boost Filesystem Library test Jamfile
+
+# (C) Copyright Beman Dawes 2002-2006
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or www.boost.org/LICENSE_1_0.txt)
+
+project
+ : requirements
+ <library>/boost/filesystem//boost_filesystem
+ <toolset>msvc:<asynch-exceptions>on
+ ;
+
+ test-suite "filesystem" :
+ [ run path_unit_test.cpp
+ : : : <link>static
+ ]
+ [ run path_unit_test.cpp ../../system/build
+ : : : : path_unit_test_dll
+ ]
+ [ run path_test.cpp
+ : : : <link>static
+ ]
+ [ run path_test.cpp ../../system/build
+ : : : : path_test_dll
+ ]
+ [ run operations_unit_test.cpp
+ : : : <link>static
+ ]
+ [ run operations_unit_test.cpp ../../system/build
+ : : : : operations_unit_test_dll
+ ]
+ [ run operations_test.cpp
+ : : : <link>static
+ ]
+ [ run operations_test.cpp ../../system/build
+ : : : : operations_test_dll
+ ]
+ [ run fstream_test.cpp
+ : : : <link>static
+ ]
+ [ run convenience_test.cpp
+ : : : <link>static
+ ]
+ [ run large_file_support_test.cpp
+ : : : <link>static
+ ]
+ [ run wide_test.cpp
+ : : : <link>static
+ ]
+
+ [ compile deprecated_test.cpp ]
+ [ compile ../example/mbcopy.cpp ]
+ [ compile ../example/mbpath.cpp ]
+ [ compile ../example/simple_ls.cpp ]
+ ;
Added: sandbox/filesystem-v3/libs/filesystem/v3/test/convenience_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/test/convenience_test.cpp 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,164 @@
+// libs/filesystem/test/convenience_test.cpp -------------------------------//
+
+// Copyright Beman Dawes, 2002
+// Copyright Vladimir Prus, 2002
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See library home page at http://www.boost.org/libs/filesystem
+
+#include <boost/config/warning_disable.hpp>
+
+// See deprecated_test for tests of deprecated features
+#define BOOST_FILESYSTEM_NO_DEPRECATED
+
+#include <boost/filesystem/convenience.hpp>
+namespace fs = boost::filesystem;
+using fs::path;
+namespace sys = boost::system;
+
+#include <boost/test/minimal.hpp>
+#include <boost/bind.hpp>
+#include <fstream>
+#include <iostream>
+
+#ifndef BOOST_FILESYSTEM_NARROW_ONLY
+# define BOOST_FS_IS_EMPTY fs::is_empty
+#else
+# define BOOST_FS_IS_EMPTY fs::_is_empty
+#endif
+
+namespace
+{
+ template< typename F >
+ bool throws_fs_error( F func )
+ {
+ try { func(); }
+
+ catch ( const fs::filesystem_error & )
+ {
+ return true;
+ }
+ return false;
+ }
+
+ void create_recursive_iterator( const fs::path & ph )
+ {
+ fs::recursive_directory_iterator it( ph );
+ }
+}
+
+// --------------------------------------------------------------------------//
+
+int test_main( int, char*[] )
+{
+
+// create_directories() tests ----------------------------------------------//
+
+ BOOST_CHECK( !fs::create_directories( "" ) ); // should be harmless
+ BOOST_CHECK( !fs::create_directories( "/" ) ); // ditto
+
+ fs::remove_all( "xx" ); // make sure slate is blank
+ BOOST_CHECK( !fs::exists( "xx" ) ); // reality check
+
+ BOOST_CHECK( fs::create_directories( "xx" ) );
+ BOOST_CHECK( fs::exists( "xx" ) );
+ BOOST_CHECK( fs::is_directory( "xx" ) );
+
+ BOOST_CHECK( fs::create_directories( "xx/yy/zz" ) );
+ BOOST_CHECK( fs::exists( "xx" ) );
+ BOOST_CHECK( fs::exists( "xx/yy" ) );
+ BOOST_CHECK( fs::exists( "xx/yy/zz" ) );
+ BOOST_CHECK( fs::is_directory( "xx" ) );
+ BOOST_CHECK( fs::is_directory( "xx/yy" ) );
+ BOOST_CHECK( fs::is_directory( "xx/yy/zz" ) );
+
+ path is_a_file( "xx/uu" );
+ {
+ std::ofstream f( is_a_file.string().c_str() );
+ BOOST_CHECK( !!f );
+ }
+ BOOST_CHECK( throws_fs_error(
+ boost::bind( fs::create_directories, is_a_file ) ) );
+ BOOST_CHECK( throws_fs_error(
+ boost::bind( fs::create_directories, is_a_file / "aa" ) ) );
+
+// recursive_directory_iterator tests ----------------------------------------//
+
+ sys::error_code ec;
+ fs::recursive_directory_iterator it( "/no-such-path", ec );
+ BOOST_CHECK( ec );
+ BOOST_CHECK( throws_fs_error(
+ boost::bind( create_recursive_iterator, "/no-such-path" ) ) );
+
+ fs::remove( "xx/uu" );
+
+#ifdef BOOST_WINDOWS_API
+ // These tests depends on ordering of directory entries, and that's guaranteed
+ // on Windows but not necessarily on other operating systems
+ {
+ std::ofstream f( "xx/yya" );
+ BOOST_CHECK( !!f );
+ }
+
+ for ( it = fs::recursive_directory_iterator( "xx" );
+ it != fs::recursive_directory_iterator(); ++it )
+ { std::cout << it->path() << '\n'; }
+
+ it = fs::recursive_directory_iterator( "xx" );
+ BOOST_CHECK( it->path() == "xx/yy" );
+ BOOST_CHECK( it.level() == 0 );
+ ++it;
+ BOOST_CHECK( it->path() == "xx/yy/zz" );
+ BOOST_CHECK( it.level() == 1 );
+ it.pop();
+ BOOST_CHECK( it->path() == "xx/yya" );
+ BOOST_CHECK( it.level() == 0 );
+ it++;
+ BOOST_CHECK( it == fs::recursive_directory_iterator() );
+
+ it = fs::recursive_directory_iterator( "xx" );
+ BOOST_CHECK( it->path() == "xx/yy" );
+ it.no_push();
+ ++it;
+ BOOST_CHECK( it->path() == "xx/yya" );
+ ++it;
+ BOOST_CHECK( it == fs::recursive_directory_iterator() );
+
+ fs::remove( "xx/yya" );
+#endif
+
+ it = fs::recursive_directory_iterator( "xx/yy/zz" );
+ BOOST_CHECK( it == fs::recursive_directory_iterator() );
+
+ it = fs::recursive_directory_iterator( "xx" );
+ BOOST_CHECK( it->path() == "xx/yy" );
+ BOOST_CHECK( it.level() == 0 );
+ ++it;
+ BOOST_CHECK( it->path() == "xx/yy/zz" );
+ BOOST_CHECK( it.level() == 1 );
+ it++;
+ BOOST_CHECK( it == fs::recursive_directory_iterator() );
+
+ it = fs::recursive_directory_iterator( "xx" );
+ BOOST_CHECK( it->path() == "xx/yy" );
+ it.no_push();
+ ++it;
+ BOOST_CHECK( it == fs::recursive_directory_iterator() );
+
+ it = fs::recursive_directory_iterator( "xx" );
+ BOOST_CHECK( it->path() == "xx/yy" );
+ ++it;
+ it.pop();
+ BOOST_CHECK( it == fs::recursive_directory_iterator() );
+
+ ec.clear();
+ BOOST_CHECK( !ec );
+ // check that two argument failed constructor creates the end iterator
+ BOOST_CHECK( fs::recursive_directory_iterator("nosuchdir", ec)
+ == fs::recursive_directory_iterator() );
+ BOOST_CHECK( ec );
+
+ return 0;
+}
Added: sandbox/filesystem-v3/libs/filesystem/v3/test/deprecated_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/test/deprecated_test.cpp 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,204 @@
+// deprecated_test program --------------------------------------------------//
+
+// Copyright Beman Dawes 2002
+// Copyright Vladimir Prus 2002
+
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See library home page at http://www.boost.org/libs/filesystem
+
+// This test verifies that various deprecated names still compile. This is
+// important to preserve existing code that uses the old names.
+
+#include <boost/filesystem.hpp>
+#include <boost/test/minimal.hpp>
+
+namespace fs = boost::filesystem;
+using boost::filesystem::path;
+
+#define PATH_CHECK( a, b ) check( a, b, __LINE__ )
+
+namespace
+{
+ std::string platform( BOOST_PLATFORM );
+
+ int errors;
+
+ void check( const fs::path & source,
+ const std::string & expected, int line )
+ {
+ if ( source.string()== expected ) return;
+
+ ++errors;
+
+ std::cout << '(' << line << ") source.string(): \"" << source.string()
+ << "\" != expected: \"" << expected
+ << "\"" << std::endl;
+ }
+
+ void check_normalize()
+ {
+ PATH_CHECK( path("").normalize(), "" );
+ PATH_CHECK( path("/").normalize(), "/" );
+ PATH_CHECK( path("//").normalize(), "//" );
+ PATH_CHECK( path("///").normalize(), "/" );
+ PATH_CHECK( path("f").normalize(), "f" );
+ PATH_CHECK( path("foo").normalize(), "foo" );
+ PATH_CHECK( path("foo/").normalize(), "foo/." );
+ PATH_CHECK( path("f/").normalize(), "f/." );
+ PATH_CHECK( path( "/foo" ).normalize(), "/foo" );
+ PATH_CHECK( path( "foo/bar" ).normalize(), "foo/bar" );
+ PATH_CHECK( path("..").normalize(), ".." );
+ PATH_CHECK( path("../..").normalize(), "../.." );
+ PATH_CHECK( path("/..").normalize(), "/.." );
+ PATH_CHECK( path("/../..").normalize(), "/../.." );
+ PATH_CHECK( path("../foo").normalize(), "../foo" );
+ PATH_CHECK( path("foo/..").normalize(), "." );
+ PATH_CHECK( path("foo/../").normalize(), "./." );
+ PATH_CHECK( (path("foo") / "..").normalize() , "." );
+ PATH_CHECK( path("foo/...").normalize(), "foo/..." );
+ PATH_CHECK( path("foo/.../").normalize(), "foo/.../." );
+ PATH_CHECK( path("foo/..bar").normalize(), "foo/..bar" );
+ PATH_CHECK( path("../f").normalize(), "../f" );
+ PATH_CHECK( path("/../f").normalize(), "/../f" );
+ PATH_CHECK( path("f/..").normalize(), "." );
+ PATH_CHECK( (path("f") / "..").normalize() , "." );
+ PATH_CHECK( path("foo/../..").normalize(), ".." );
+ PATH_CHECK( path("foo/../../").normalize(), "../." );
+ PATH_CHECK( path("foo/../../..").normalize(), "../.." );
+ PATH_CHECK( path("foo/../../../").normalize(), "../../." );
+ PATH_CHECK( path("foo/../bar").normalize(), "bar" );
+ PATH_CHECK( path("foo/../bar/").normalize(), "bar/." );
+ PATH_CHECK( path("foo/bar/..").normalize(), "foo" );
+ PATH_CHECK( path("foo/bar/../").normalize(), "foo/." );
+ PATH_CHECK( path("foo/bar/../..").normalize(), "." );
+ PATH_CHECK( path("foo/bar/../../").normalize(), "./." );
+ PATH_CHECK( path("foo/bar/../blah").normalize(), "foo/blah" );
+ PATH_CHECK( path("f/../b").normalize(), "b" );
+ PATH_CHECK( path("f/b/..").normalize(), "f" );
+ PATH_CHECK( path("f/b/../").normalize(), "f/." );
+ PATH_CHECK( path("f/b/../a").normalize(), "f/a" );
+ PATH_CHECK( path("foo/bar/blah/../..").normalize(), "foo" );
+ PATH_CHECK( path("foo/bar/blah/../../bletch").normalize(), "foo/bletch" );
+ PATH_CHECK( path( "//net" ).normalize(), "//net" );
+ PATH_CHECK( path( "//net/" ).normalize(), "//net/" );
+ PATH_CHECK( path( "//..net" ).normalize(), "//..net" );
+ PATH_CHECK( path( "//net/.." ).normalize(), "//net/.." );
+ PATH_CHECK( path( "//net/foo" ).normalize(), "//net/foo" );
+ PATH_CHECK( path( "//net/foo/" ).normalize(), "//net/foo/." );
+ PATH_CHECK( path( "//net/foo/.." ).normalize(), "//net/" );
+ PATH_CHECK( path( "//net/foo/../" ).normalize(), "//net/." );
+
+ PATH_CHECK( path( "/net/foo/bar" ).normalize(), "/net/foo/bar" );
+ PATH_CHECK( path( "/net/foo/bar/" ).normalize(), "/net/foo/bar/." );
+ PATH_CHECK( path( "/net/foo/.." ).normalize(), "/net" );
+ PATH_CHECK( path( "/net/foo/../" ).normalize(), "/net/." );
+
+ PATH_CHECK( path( "//net//foo//bar" ).normalize(), "//net/foo/bar" );
+ PATH_CHECK( path( "//net//foo//bar//" ).normalize(), "//net/foo/bar/." );
+ PATH_CHECK( path( "//net//foo//.." ).normalize(), "//net/" );
+ PATH_CHECK( path( "//net//foo//..//" ).normalize(), "//net/." );
+
+ PATH_CHECK( path( "///net///foo///bar" ).normalize(), "/net/foo/bar" );
+ PATH_CHECK( path( "///net///foo///bar///" ).normalize(), "/net/foo/bar/." );
+ PATH_CHECK( path( "///net///foo///.." ).normalize(), "/net" );
+ PATH_CHECK( path( "///net///foo///..///" ).normalize(), "/net/." );
+
+ if ( platform == "Windows" )
+ {
+ PATH_CHECK( path( "c:.." ).normalize(), "c:.." );
+ PATH_CHECK( path( "c:foo/.." ).normalize(), "c:" );
+
+ PATH_CHECK( path( "c:foo/../" ).normalize(), "c:." );
+
+ PATH_CHECK( path( "c:/foo/.." ).normalize(), "c:/" );
+ PATH_CHECK( path( "c:/foo/../" ).normalize(), "c:/." );
+ PATH_CHECK( path( "c:/.." ).normalize(), "c:/.." );
+ PATH_CHECK( path( "c:/../" ).normalize(), "c:/../." );
+ PATH_CHECK( path( "c:/../.." ).normalize(), "c:/../.." );
+ PATH_CHECK( path( "c:/../../" ).normalize(), "c:/../../." );
+ PATH_CHECK( path( "c:/../foo" ).normalize(), "c:/../foo" );
+ PATH_CHECK( path( "c:/../foo/" ).normalize(), "c:/../foo/." );
+ PATH_CHECK( path( "c:/../../foo" ).normalize(), "c:/../../foo" );
+ PATH_CHECK( path( "c:/../../foo/" ).normalize(), "c:/../../foo/." );
+ PATH_CHECK( path( "c:/..foo" ).normalize(), "c:/..foo" );
+ }
+ else // POSIX
+ {
+ PATH_CHECK( path( "c:.." ).normalize(), "c:.." );
+ PATH_CHECK( path( "c:foo/.." ).normalize(), "." );
+ PATH_CHECK( path( "c:foo/../" ).normalize(), "./." );
+ PATH_CHECK( path( "c:/foo/.." ).normalize(), "c:" );
+ PATH_CHECK( path( "c:/foo/../" ).normalize(), "c:/." );
+ PATH_CHECK( path( "c:/.." ).normalize(), "." );
+ PATH_CHECK( path( "c:/../" ).normalize(), "./." );
+ PATH_CHECK( path( "c:/../.." ).normalize(), ".." );
+ PATH_CHECK( path( "c:/../../" ).normalize(), "../." );
+ PATH_CHECK( path( "c:/../foo" ).normalize(), "foo" );
+ PATH_CHECK( path( "c:/../foo/" ).normalize(), "foo/." );
+ PATH_CHECK( path( "c:/../../foo" ).normalize(), "../foo" );
+ PATH_CHECK( path( "c:/../../foo/" ).normalize(), "../foo/." );
+ PATH_CHECK( path( "c:/..foo" ).normalize(), "c:/..foo" );
+ }
+ }
+} // unnamed namespace
+
+//----------------------------------------------------------------------------//
+
+int test_main( int /*argc*/, char * /*argv*/[] )
+{
+ // The choice of platform is make at runtime rather than compile-time
+ // so that compile errors for all platforms will be detected even though
+ // only the current platform is runtime tested.
+ platform = ( platform == "Win32" || platform == "Win64" || platform == "Cygwin" )
+ ? "Windows"
+ : "POSIX";
+ std::cout << "Platform is " << platform << '\n';
+
+ path::default_name_check( fs::no_check );
+
+ fs::directory_entry de( "foo/bar" );
+
+ de.replace_leaf( "", fs::file_status(), fs::file_status() );
+
+ de.leaf();
+ de.string();
+
+ fs::path ng( " no-way, Jose" );
+ BOOST_CHECK( !fs::is_regular( ng ) ); // verify deprecated name still works
+ BOOST_CHECK( !fs::symbolic_link_exists( "nosuchfileordirectory" ) );
+
+ check_normalize();
+
+// extension() tests ---------------------------------------------------------//
+
+ BOOST_CHECK( fs::extension("a/b") == "" );
+ BOOST_CHECK( fs::extension("a/b.txt") == ".txt" );
+ BOOST_CHECK( fs::extension("a/b.") == "." );
+ BOOST_CHECK( fs::extension("a.b.c") == ".c" );
+ BOOST_CHECK( fs::extension("a.b.c.") == "." );
+ BOOST_CHECK( fs::extension("") == "" );
+ BOOST_CHECK( fs::extension("a/") == "." );
+
+// basename() tests ----------------------------------------------------------//
+
+ BOOST_CHECK( fs::basename("b") == "b" );
+ BOOST_CHECK( fs::basename("a/b.txt") == "b" );
+ BOOST_CHECK( fs::basename("a/b.") == "b" );
+ BOOST_CHECK( fs::basename("a.b.c") == "a.b" );
+ BOOST_CHECK( fs::basename("a.b.c.") == "a.b.c" );
+ BOOST_CHECK( fs::basename("") == "" );
+
+// change_extension tests ---------------------------------------------------//
+
+ BOOST_CHECK( fs::change_extension("a.txt", ".tex").string() == "a.tex" );
+ BOOST_CHECK( fs::change_extension("a.", ".tex").string() == "a.tex" );
+ BOOST_CHECK( fs::change_extension("a", ".txt").string() == "a.txt" );
+ BOOST_CHECK( fs::change_extension("a.b.txt", ".tex").string() == "a.b.tex" );
+ // see the rationale in html docs for explanation why this works
+ BOOST_CHECK( fs::change_extension("", ".png").string() == ".png" );
+
+ return errors;
+}
Added: sandbox/filesystem-v3/libs/filesystem/v3/test/design_use_cases.cpp
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/test/design_use_cases.cpp 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,81 @@
+#include <string>
+#include <iostream>
+
+// Minimal class path
+
+class path
+{
+public:
+ path( const char * )
+ {
+ std::cout << "path( const char * )\n";
+ }
+ path( const std::string & )
+ {
+ std::cout << "path( std::string & )\n";
+ }
+
+// for maximum efficiency, either signature must work
+# ifdef BY_VALUE
+ operator const std::string() const
+# else
+ operator const std::string&() const
+# endif
+ {
+ std::cout << "operator string\n";
+ return m_path;
+ }
+
+#ifdef NAMED_CONVERSION
+ std::string string() const
+ {
+ std::cout << "std::string string() const\n";
+ return m_path;
+ }
+#endif
+
+private:
+ std::string m_path;
+};
+
+bool operator==( const path &, const path & )
+{
+ std::cout << "operator==( const path &, const path & )\n";
+ return true;
+}
+
+// These are the critical use cases. If any of these don't compile, usability
+// is unacceptably degraded.
+
+void f( const path & )
+{
+ std::cout << "f( const path & )\n";
+}
+
+int main()
+{
+ f( "foo" );
+ f( std::string( "foo" ) );
+ f( path( "foo" ) );
+
+ std::cout << '\n';
+
+ std::string s1( path( "foo" ) );
+ std::string s2 = path( "foo" );
+ s2 = path( "foo" );
+
+#ifdef NAMED_CONVERSION
+ s2 = path( "foo" ).string();
+#endif
+
+ std::cout << '\n';
+
+ // these must call bool path( const path &, const path & );
+ path( "foo" ) == path( "foo" );
+ path( "foo" ) == "foo";
+ path( "foo" ) == std::string( "foo" );
+ "foo" == path( "foo" );
+ std::string( "foo" ) == path( "foo" );
+
+ return 0;
+}
Added: sandbox/filesystem-v3/libs/filesystem/v3/test/equivalent.cpp
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/test/equivalent.cpp 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,39 @@
+// equivalent program -------------------------------------------------------//
+
+// Copyright (c) 2004 Beman Dawes
+
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy
+// at http://www.boost.org/LICENSE_1_0.txt)
+
+// See library home page at http://www.boost.org/libs/filesystem
+
+//----------------------------------------------------------------------------//
+
+#include <boost/filesystem/operations.hpp>
+#include <iostream>
+#include <exception>
+
+int main( int argc, char * argv[] )
+{
+ boost::filesystem::path::default_name_check( boost::filesystem::native );
+ if ( argc != 3 )
+ {
+ std::cout << "Usage: equivalent path1 path2\n";
+ return 2;
+ }
+
+ bool eq;
+ try
+ {
+ eq = boost::filesystem::equivalent( argv[1], argv[2] );
+ }
+ catch ( const std::exception & ex )
+ {
+ std::cout << ex.what() << "\n";
+ return 3;
+ }
+
+ std::cout << (eq ? "Paths are equivalent\n" : "Paths are not equivalent\n");
+ return !eq;
+}
Added: sandbox/filesystem-v3/libs/filesystem/v3/test/fstream_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/test/fstream_test.cpp 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,180 @@
+// fstream_test.cpp --------------------------------------------------------//
+
+// Copyright Beman Dawes 2002.
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See library home page at http://www.boost.org/libs/filesystem
+
+#include <boost/config/warning_disable.hpp>
+
+// See deprecated_test for tests of deprecated features
+#define BOOST_FILESYSTEM_NO_DEPRECATED
+
+#include <boost/filesystem/fstream.hpp>
+#include <boost/filesystem/operations.hpp>
+#include <string>
+#include <iostream>
+#include <cstdio> // for std::remove
+
+#include "../src/utf8_codecvt_facet.hpp"
+
+#ifndef BOOST_FILESYSTEM_NARROW_ONLY
+# include "lpath.hpp"
+#endif
+
+namespace fs = boost::filesystem;
+
+#include <boost/config.hpp>
+#ifdef BOOST_NO_STDC_NAMESPACE
+ namespace std { using ::remove; }
+#endif
+
+#include <boost/test/minimal.hpp>
+
+namespace
+{
+ bool cleanup = true;
+
+ template< class Path >
+ void test( const Path & p )
+ {
+# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle open
+ {
+ std::cout << " in test 1\n";
+ fs::filebuf fb;
+ fb.open( p, std::ios_base::in );
+ BOOST_CHECK( fb.is_open() == fs::exists( p ) );
+ }
+ {
+ std::cout << " in test 2\n";
+ fs::filebuf fb1;
+ fb1.open( p, std::ios_base::out );
+ BOOST_CHECK( fb1.is_open() );
+ }
+ {
+ std::cout << " in test 3\n";
+ fs::filebuf fb2;
+ fb2.open( p, std::ios_base::in );
+ BOOST_CHECK( fb2.is_open() );
+ }
+# else
+ std::cout << "<note>\n";
+ std::cout <<
+ "VC++6.0 does not support boost::filesystem open()\n";
+# endif
+ {
+ std::cout << " in test 4\n";
+ fs::ifstream tfs( p );
+ BOOST_CHECK( tfs.is_open() );
+ }
+ {
+ std::cout << " in test 4.1\n";
+ fs::ifstream tfs( p / p.filename() ); // should fail
+ BOOST_CHECK( !tfs.is_open() );
+ }
+ {
+ std::cout << " in test 5\n";
+ fs::ifstream tfs( p, std::ios_base::in );
+ BOOST_CHECK( tfs.is_open() );
+ }
+# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle open
+ {
+ std::cout << " in test 6\n";
+ fs::ifstream tfs;
+ tfs.open( p );
+ BOOST_CHECK( tfs.is_open() );
+ }
+ {
+ std::cout << " in test 7\n";
+ fs::ifstream tfs;
+ tfs.open( p, std::ios_base::in );
+ BOOST_CHECK( tfs.is_open() );
+ }
+# endif
+ {
+ std::cout << " in test 8\n";
+ fs::ofstream tfs( p );
+ BOOST_CHECK( tfs.is_open() );
+ }
+ {
+ std::cout << " in test 9\n";
+ fs::ofstream tfs( p, std::ios_base::out );
+ BOOST_CHECK( tfs.is_open() );
+ }
+# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle open
+ {
+ std::cout << " in test 10\n";
+ fs::ofstream tfs;
+ tfs.open( p );
+ BOOST_CHECK( tfs.is_open() );
+ }
+ {
+ std::cout << " in test 11\n";
+ fs::ofstream tfs;
+ tfs.open( p, std::ios_base::out );
+ BOOST_CHECK( tfs.is_open() );
+ }
+# endif
+ {
+ std::cout << " in test 12\n";
+ fs::fstream tfs( p );
+ BOOST_CHECK( tfs.is_open() );
+ }
+ {
+ std::cout << " in test 13\n";
+ fs::fstream tfs( p, std::ios_base::in|std::ios_base::out );
+ BOOST_CHECK( tfs.is_open() );
+ }
+# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle open
+ {
+ std::cout << " in test 14\n";
+ fs::fstream tfs;
+ tfs.open( p );
+ BOOST_CHECK( tfs.is_open() );
+ }
+ {
+ std::cout << " in test 15\n";
+ fs::fstream tfs;
+ tfs.open( p, std::ios_base::in|std::ios_base::out );
+ BOOST_CHECK( tfs.is_open() );
+ }
+# endif
+
+ if ( cleanup ) fs::remove( p );
+
+ } // test
+} // unnamed namespace
+
+int test_main( int argc, char*[] )
+{
+ if ( argc > 1 ) cleanup = false;
+
+ // test fs::path
+ std::cout << "path tests:\n";
+ test( fs::path( "fstream_test_foo" ) );
+
+#ifndef BOOST_FILESYSTEM_NARROW_ONLY
+
+ // So that tests are run with known encoding, use Boost UTF-8 codecvt
+ std::locale global_loc = std::locale();
+ std::locale loc( global_loc, new fs::detail::utf8_codecvt_facet );
+ fs::wpath_traits::imbue( loc );
+
+ // test fs::wpath
+ // x2780 is circled 1 against white background == e2 9e 80 in UTF-8
+ // x2781 is circled 2 against white background == e2 9e 81 in UTF-8
+ std::cout << "\nwpath tests:\n";
+ test( fs::wpath( L"fstream_test_\x2780" ) );
+
+ // test user supplied basic_path
+ const long lname[] = { 'f', 's', 'r', 'e', 'a', 'm', '_', 't', 'e', 's',
+ 't', '_', 'l', 'p', 'a', 't', 'h', 0 };
+ std::cout << "\nlpath tests:\n";
+ test( user::lpath( lname ) );
+
+#endif
+
+ return 0;
+}
Added: sandbox/filesystem-v3/libs/filesystem/v3/test/gcc_operations_unit_test.bat
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/test/gcc_operations_unit_test.bat 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,4 @@
+@echo off
+g++ -DBOOST_ALL_NO_LIB -DBOOST_FILEYSTEM_INCLUDE_IOSTREAM -I../../.. -I%BOOST_TRUNK% operations_unit_test.cpp ../src/operations.cpp ../src/path.cpp ../src/portability.cpp ../src/utf8_codecvt_facet.cpp %BOOST_TRUNK%/libs/system/src/error_code.cpp 2>log
+firefox log
+
Added: sandbox/filesystem-v3/libs/filesystem/v3/test/gcc_path_unit_test.bat
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/test/gcc_path_unit_test.bat 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,4 @@
+@echo off
+g++ -DBOOST_ALL_NO_LIB -I../../.. -I%BOOST_TRUNK% path_unit_test.cpp ../src/path.cpp ../src/portability.cpp ../src/utf8_codecvt_facet.cpp %BOOST_TRUNK%/libs/system/src/error_code.cpp 2>log
+firefox log
+
Added: sandbox/filesystem-v3/libs/filesystem/v3/test/large_file_support_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/test/large_file_support_test.cpp 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,36 @@
+// Boost large_file_support_test.cpp ---------------------------------------//
+
+// Copyright Beman Dawes 2004.
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See library home page at http://www.boost.org/libs/filesystem
+
+
+// See deprecated_test for tests of deprecated features
+#define BOOST_FILESYSTEM_NO_DEPRECATED
+
+#include <boost/filesystem/operations.hpp>
+namespace fs = boost::filesystem;
+
+#include <iostream>
+
+int main()
+{
+ if ( fs::detail::possible_large_file_size_support() )
+ {
+ std::cout << "It appears that file sizes greater that 2 gigabytes are possible\n"
+ "for this configuration on this platform since the operating system\n"
+ "does use a large enough integer type to report large file sizes.\n\n"
+ "Whether or not such support is actually present depends on the OS\n";
+ return 0;
+ }
+ std::cout << "The operating system is using an integer type to report file sizes\n"
+ "that can not represent file sizes greater that 2 gigabytes (31-bits).\n"
+ "Thus the Filesystem Library will not correctly deal with such large\n"
+ "files. If you think that this operatiing system should be able to\n"
+ "support large files, please report the problem to the Boost developers\n"
+ "mailing list.\n";
+ return 1;
+}
Added: sandbox/filesystem-v3/libs/filesystem/v3/test/lpath.hpp
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/test/lpath.hpp 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,101 @@
+// Boost lpath.hpp ---------------------------------------------------------//
+
+// Copyright Beman Dawes 2005
+
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See library home page at http://www.boost.org/libs/filesystem
+
+#include <boost/filesystem/path.hpp>
+#include <cwchar> // for std::mbstate_t
+#include <string>
+#include <ios> // for std::streamoff
+
+namespace std
+{
+ // Note well: this specialization is meant only to support wide_test.cpp.
+ // It is not fully functional, fully correct, or efficient.
+ template<> struct char_traits<long>
+ {
+ typedef long char_type;
+ typedef long int_type;
+ typedef streamoff off_type;
+ typedef streampos pos_type;
+ typedef mbstate_t state_type;
+ static void assign(char_type& c1, const char_type& c2){c1=c2;}
+ static bool eq(const char_type& c1, const char_type& c2){return c1==c2;}
+ static bool lt(const char_type& c1, const char_type& c2){return c1<c2;}
+ static int compare(const char_type* s1, const char_type* s2, size_t n)
+ {
+ const char_type* e = s1 + n;
+ for ( ;s1 != e && *s1 == *s2; ++s1, ++s2 ) {}
+ return s1 == e ? 0 : (*s1<*s2 ? -1 : 1);
+ }
+ static size_t length(const char_type* s)
+ { const char_type* b=s; for(;*s!=0L;++s){} return s-b; }
+
+ static const char_type* find(const char_type* /*s*/, size_t /*n*/, const char_type& /*a*/)
+ { return 0; }
+
+ // copy semantics will do for wide_test
+ static char_type* move(char_type* s1, const char_type* s2, size_t n)
+ { char_type* b=s1; for(const char_type* e=s1+n;s1!=e;++s1,++s2) *s1=*s2; return b; }
+
+ static char_type* copy(char_type* s1, const char_type* s2, size_t n)
+ { char_type* b=s1; for(const char_type* e=s1+n;s1!=e;++s1,++s2) *s1=*s2; return b; }
+
+ static char_type* assign(char_type* s, size_t n, char_type a)
+ { char_type* b=s; for(char_type* e=s+n;s!=e;++s) *s=a; return b; }
+
+ static int_type not_eof(const int_type& c);
+ static char_type to_char_type(const int_type& c);
+ static int_type to_int_type(const char_type& c);
+ static bool eq_int_type(const int_type& c1, const int_type& c2);
+ static int_type eof();
+ };
+}
+
+namespace user
+{
+ typedef std::basic_string<long> lstring;
+ struct lpath_traits;
+ typedef boost::filesystem::basic_path<lstring, lpath_traits> lpath;
+
+ struct lpath_traits
+ {
+ typedef lstring internal_string_type;
+ typedef std::string external_string_type;
+
+ static external_string_type to_external( const lpath &,
+ const internal_string_type & src )
+ {
+ external_string_type tmp;
+ for ( internal_string_type::const_iterator it( src.begin() );
+ it != src.end(); ++it )
+ {
+ tmp += static_cast<external_string_type::value_type>(*it);
+ }
+ return tmp;
+ }
+
+ static internal_string_type to_internal( const external_string_type & src )
+ {
+ internal_string_type tmp;
+ for ( external_string_type::const_iterator it( src.begin() );
+ it != src.end(); ++it ) tmp += *it;
+ return tmp;
+ }
+ };
+
+} // namespace user
+
+namespace boost
+{
+ namespace filesystem
+ {
+ template<> struct is_basic_path<user::lpath>
+ { static const bool value = true; };
+ }
+}
Added: sandbox/filesystem-v3/libs/filesystem/v3/test/msvc/common.vsprops
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/test/msvc/common.vsprops 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="common"
+ OutputDirectory="$(TEMP)\$(SolutionName)\$(ConfigurationName)"
+ IntermediateDirectory="$(TEMP)\$(SolutionName)\$(ProjectName)\$(ConfigurationName)"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../../../../.."
+ PreprocessorDefinitions="BOOST_SYSTEM_NO_LIB;BOOST_FILESYSTEM_NO_LIB"
+ ExceptionHandling="2"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalLibraryDirectories="$(BOOST_TRUNK)/lib"
+ />
+</VisualStudioPropertySheet>
Added: sandbox/filesystem-v3/libs/filesystem/v3/test/msvc/convenience_test/convenience_test.vcproj
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/test/msvc/convenience_test/convenience_test.vcproj 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,209 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="convenience_test"
+ ProjectGUID="{08986FB5-0C83-4BC4-92DF-05E12E1C03C1}"
+ RootNamespace="convenience_test"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\common.vsprops"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ Description="Executing test $(TargetName).exe..."
+ CommandLine=""$(TargetDir)\$(TargetName).exe""
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\common.vsprops"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ Description="Executing test $(TargetName).exe..."
+ CommandLine=""$(TargetDir)\$(TargetName).exe""
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\convenience_test.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\system\src\error_code.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\src\operations.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\src\path.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
Added: sandbox/filesystem-v3/libs/filesystem/v3/test/msvc/operations_test/operations_test.vcproj
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/test/msvc/operations_test/operations_test.vcproj 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,206 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="operations_test"
+ ProjectGUID="{8BB7E604-46EF-42BE-ABB5-D7044B3E8A40}"
+ RootNamespace="operations_test"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\common.vsprops"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="BOOST_FILEYSTEM_INCLUDE_IOSTREAM"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ Description="Executing test $(TargetName).exe..."
+ CommandLine=""$(TargetDir)\$(TargetName).exe""
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\common.vsprops"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ Description="Executing test $(TargetName).exe..."
+ CommandLine=""$(TargetDir)\$(TargetName).exe""
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\..\..\system\src\error_code.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\src\operations.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\operations_test.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\src\path.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
Added: sandbox/filesystem-v3/libs/filesystem/v3/test/msvc/operations_unit_test/operations_unit_test.vcproj
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/test/msvc/operations_unit_test/operations_unit_test.vcproj 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,209 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="operations_unit_test"
+ ProjectGUID="{5DAF595A-4640-4F86-8A5F-E54E3E4CE7D0}"
+ RootNamespace="operations_unit_test"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\common.vsprops"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ Description="Executing test $(TargetName).exe..."
+ CommandLine=""$(TargetDir)\$(TargetName).exe""
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\common.vsprops"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ Description="Executing test $(TargetName).exe..."
+ CommandLine=""$(TargetDir)\$(TargetName).exe""
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\..\..\system\src\error_code.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\src\operations.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\operations_unit_test.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\src\path.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
Added: sandbox/filesystem-v3/libs/filesystem/v3/test/msvc/path_test/path_test.vcproj
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/test/msvc/path_test/path_test.vcproj 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,209 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="path_test"
+ ProjectGUID="{F3D230C4-9185-4C2B-AB0E-0F0D28D8268C}"
+ RootNamespace="path_test"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\common.vsprops"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ ExceptionHandling="1"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ Description="Executing test $(TargetName).exe..."
+ CommandLine=""$(TargetDir)\$(TargetName).exe""
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\common.vsprops"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ ExceptionHandling="1"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ Description="Executing test $(TargetName).exe..."
+ CommandLine=""$(TargetDir)\$(TargetName).exe""
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\..\..\system\src\error_code.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\src\operations.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\src\path.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\path_test.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
Added: sandbox/filesystem-v3/libs/filesystem/v3/test/msvc/path_unit_test/path_unit_test.vcproj
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/test/msvc/path_unit_test/path_unit_test.vcproj 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,210 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="path_unit_test"
+ ProjectGUID="{3C77F610-2E31-4087-9DF2-7CD45198A02D}"
+ RootNamespace="path_unit_test"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\common.vsprops"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ Description="Executing test $(TargetName).exe..."
+ CommandLine=""$(TargetDir)\$(TargetName).exe""
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\common.vsprops"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine=""$(TargetDir)\$(TargetName).exe""
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\..\..\system\src\error_code.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\src\path.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\path_unit_test.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\src\portability.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\src\utf8_codecvt_facet.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
Added: sandbox/filesystem-v3/libs/filesystem/v3/test/msvc/tchar_example/tchar_example.vcproj
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/test/msvc/tchar_example/tchar_example.vcproj 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,208 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="tchar_example"
+ ProjectGUID="{2D4CD761-6DF6-40AC-B4A5-F169D5F93226}"
+ RootNamespace="tchar_example"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(TEMP)\$(SolutionName)\$(ConfigurationName)"
+ IntermediateDirectory="$(TEMP)\$(SolutionName)\$(ProjectName)\$(ConfigurationName)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\common.vsprops"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(TEMP)\$(SolutionName)\$(ConfigurationName)"
+ IntermediateDirectory="$(TEMP)\$(SolutionName)\$(ProjectName)\$(ConfigurationName)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\common.vsprops"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\..\..\system\src\error_code.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\src\operations.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\src\path.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\example\tchar.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
Added: sandbox/filesystem-v3/libs/filesystem/v3/test/operations_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/test/operations_test.cpp 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,1056 @@
+// Boost operations_test.cpp -----------------------------------------------//
+
+// Copyright Beman Dawes 2002.
+
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See library home page at http://www.boost.org/libs/filesystem
+
+#include <boost/config/warning_disable.hpp>
+
+// See deprecated_test for tests of deprecated features
+#define BOOST_FILESYSTEM_NO_DEPRECATED
+
+#include <boost/filesystem/operations.hpp>
+#include <boost/filesystem/convenience.hpp>
+#include <boost/cerrno.hpp>
+namespace fs = boost::filesystem;
+
+#include <boost/config.hpp>
+#include <boost/test/minimal.hpp>
+//#include <boost/concept_check.hpp>
+
+using boost::system::error_code;
+using boost::system::system_category;
+using boost::system::system_error;
+
+#include <fstream>
+#include <iostream>
+#include <string>
+#include <cstring> // for strncmp, etc.
+#include <ctime>
+#include <cstdlib> // for system()
+
+// VC++ 7.0 and earlier has a serious namespace bug that causes a clash
+// between boost::filesystem::is_empty and the unrelated type trait
+// boost::is_empty.
+#if !defined( BOOST_MSVC ) || BOOST_MSVC > 1300
+# define BOOST_FS_IS_EMPTY fs::is_empty
+#else
+# define BOOST_FS_IS_EMPTY fs::_is_empty
+#endif
+
+# ifdef BOOST_NO_STDC_NAMESPACE
+ namespace std { using ::asctime; using ::gmtime; using ::localtime;
+ using ::difftime; using ::time; using ::tm; using ::mktime; using ::system; }
+# endif
+
+#ifdef BOOST_WINDOWS_API
+# include <windows.h>
+#endif
+
+#define CHECK_EXCEPTION(Functor,Expect) throws_fs_error(Functor,Expect,__LINE__)
+
+namespace
+{
+ typedef int errno_t;
+ std::string platform( BOOST_PLATFORM );
+ bool report_throws;
+ fs::directory_iterator end_itr;
+ fs::path dir;
+ fs::path d1;
+ fs::path d2;
+ bool create_symlink_ok( true );
+ fs::path ng( " no-way, Jose" );
+
+ unsigned short language_id; // 0 except for Windows
+
+ const char * temp_dir_name = "temp_fs_test_dir";
+
+ void create_file( const fs::path & ph, const std::string & contents )
+ {
+ std::ofstream f( ph.string().c_str() );
+ if ( !f )
+ throw fs::filesystem_error( "operations_test create_file",
+ ph, error_code(errno, system_category) );
+ if ( !contents.empty() ) f << contents;
+ }
+
+ void verify_file( const fs::path & ph, const std::string & expected )
+ {
+ std::ifstream f( ph.string().c_str() );
+ if ( !f )
+ throw fs::filesystem_error( "operations_test verify_file",
+ ph, error_code(errno, system_category) );
+ std::string contents;
+ f >> contents;
+ if ( contents != expected )
+ throw fs::filesystem_error( "operations_test verify_file contents \""
+ + contents + "\" != \"" + expected + "\"", ph, error_code() );
+ }
+
+ template< typename F >
+ bool throws_fs_error( F func, errno_t en, int line )
+ {
+ try { func(); }
+
+ catch ( const fs::filesystem_error & ex )
+ {
+ if ( report_throws )
+ {
+ // use the what() convenience function to display exceptions
+ std::cout << "\n" << ex.what() << "\n";
+ }
+ if ( en == 0
+ || en == ex.code().default_error_condition().value() ) return true;
+ std::cout
+ << "\nWarning: line " << line
+ << " exception reports default_error_condition().value() " << ex.code().default_error_condition().value()
+ << ", should be " << en
+ << "\n value() is " << ex.code().value()
+ << std::endl;
+ return true;
+ }
+ return false;
+ }
+
+ // compile-only two argument "do-the-right-thing" tests
+ // verifies that all overload combinations compile without error
+ void do_not_call()
+ {
+ fs::path p;
+ std::string s;
+ const char * a = 0;
+ fs::copy_file( p, p );
+ fs::copy_file( s, p );
+ fs::copy_file( a, p );
+ fs::copy_file( p, s );
+ fs::copy_file( p, a );
+ fs::copy_file( s, s );
+ fs::copy_file( a, s );
+ fs::copy_file( s, a );
+ fs::copy_file( a, a );
+ }
+
+ void bad_file_size()
+ {
+ fs::file_size( " No way, Jose" );
+ }
+
+ void bad_directory_size()
+ {
+ fs::file_size( fs::current_path() );
+ }
+
+ fs::path bad_create_directory_path;
+ void bad_create_directory()
+ {
+ fs::create_directory( bad_create_directory_path );
+ }
+
+ void bad_equivalent()
+ {
+ fs::equivalent( "no-such-path", "another-not-present-path" );
+ }
+
+ fs::path bad_remove_dir;
+ void bad_remove()
+ {
+ fs::remove( bad_remove_dir );
+ }
+
+ class renamer
+ {
+ public:
+ renamer( const fs::path & p1, const fs::path & p2 )
+ : from(p1), to(p2) {}
+ void operator()()
+ {
+ fs::rename( from, to );
+ }
+ private:
+ fs::path from;
+ fs::path to;
+ };
+
+ // exception_tests() -----------------------------------------------------//
+
+ void exception_tests()
+ {
+ std::cout << "exception_tests..." << std::endl;
+
+ // catch runtime_error
+
+ bool exception_thrown;
+ exception_thrown = false;
+ try
+ {
+ fs::create_directory( "no-such-dir/foo/bar" );
+ }
+ catch ( std::runtime_error x )
+ {
+ exception_thrown = true;
+ if ( report_throws ) std::cout << x.what() << std::endl;
+ if ( platform == "Windows" && language_id == 0x0409 ) // English (United States)
+ // the stdcxx standard library apparently appends additional info
+ // to what(), so check only the initial portion:
+ BOOST_CHECK( std::strncmp( x.what(),
+ "boost::filesystem::create_directory",
+ sizeof("boost::filesystem::create_directory")-1 ) == 0 );
+ }
+ BOOST_CHECK( exception_thrown );
+
+ // catch system_error
+
+ exception_thrown = false;
+ try
+ {
+ fs::create_directory( "no-such-dir/foo/bar" );
+ }
+ catch ( system_error x )
+ {
+ exception_thrown = true;
+ if ( report_throws ) std::cout << x.what() << std::endl;
+ if ( platform == "Windows" && language_id == 0x0409 ) // English (United States)
+ BOOST_CHECK( std::strcmp( x.what(),
+ "boost::filesystem::create_directory: The system cannot find the path specified" ) == 0 );
+ }
+ BOOST_CHECK( exception_thrown );
+
+ // catch filesystem_error by value
+
+ exception_thrown = false;
+ try
+ {
+ fs::create_directory( "no-such-dir/foo/bar" );
+ }
+ catch ( fs::filesystem_error x )
+ {
+ exception_thrown = true;
+ if ( report_throws ) std::cout << x.what() << std::endl;
+ if ( platform == "Windows" && language_id == 0x0409 ) // English (United States)
+ {
+ bool ok ( std::strcmp( x.what(),
+ "boost::filesystem::create_directory: The system cannot find the path specified: \"no-such-dir/foo/bar\"" ) == 0 );
+ BOOST_CHECK( ok );
+ if ( !ok )
+ {
+ std::cout << "what returns \"" << x.what() << "\"" << std::endl;
+ }
+ }
+ }
+ BOOST_CHECK( exception_thrown );
+
+ // catch filesystem_error by const reference
+
+ exception_thrown = false;
+ try
+ {
+ fs::create_directory( "no-such-dir/foo/bar" );
+ }
+ catch ( const fs::filesystem_error & x )
+ {
+ exception_thrown = true;
+ if ( report_throws ) std::cout << x.what() << std::endl;
+ if ( platform == "Windows" && language_id == 0x0409 ) // English (United States)
+ {
+ bool ok ( std::strcmp( x.what(),
+ "boost::filesystem::create_directory: The system cannot find the path specified: \"no-such-dir/foo/bar\"" ) == 0 );
+ BOOST_CHECK( ok );
+ if ( !ok )
+ {
+ std::cout << "what returns \"" << x.what() << "\"" << std::endl;
+ }
+ }
+ }
+ BOOST_CHECK( exception_thrown );
+ }
+
+ // directory_iterator_tests ----------------------------------------------//
+
+ void directory_iterator_tests()
+ {
+ std::cout << "directory_iterator_tests..." << std::endl;
+
+ bool dir_itr_exception(false);
+ try { fs::directory_iterator it( "" ); }
+ catch ( const fs::filesystem_error & ) { dir_itr_exception = true; }
+ BOOST_CHECK( dir_itr_exception );
+
+ dir_itr_exception = false;
+ try { fs::directory_iterator it( "nosuchdirectory" ); }
+ catch ( const fs::filesystem_error & ) { dir_itr_exception = true; }
+ BOOST_CHECK( dir_itr_exception );
+
+ dir_itr_exception = false;
+ try
+ {
+ error_code ec;
+ fs::directory_iterator it( "nosuchdirectory", ec );
+ BOOST_CHECK( ec );
+ BOOST_CHECK( ec == boost::system::errc::no_such_file_or_directory );
+ }
+ catch ( const fs::filesystem_error & ) { dir_itr_exception = true; }
+ BOOST_CHECK( !dir_itr_exception );
+
+ {
+ // probe query function overloads
+ fs::directory_iterator dir_itr( dir );
+ // BOOST_CHECK( fs::is_directory( *dir_itr ) );
+ BOOST_CHECK( fs::is_directory( dir_itr->status() ) );
+ // BOOST_CHECK( fs::is_directory( fs::symlink_status(*dir_itr) ) );
+ BOOST_CHECK( fs::is_directory( dir_itr->symlink_status() ) );
+ BOOST_CHECK( dir_itr->path().filename() == "d1" );
+ }
+
+ // create a second directory named d2
+ d2 = dir / "d2";
+ fs::create_directory(d2 );
+ BOOST_CHECK( fs::exists( d2 ) );
+ BOOST_CHECK( fs::is_directory( d2 ) );
+
+ // test the basic operation of directory_iterators, and test that
+ // stepping one iterator doesn't affect a different iterator.
+ {
+ fs::directory_iterator dir_itr( dir );
+ BOOST_CHECK( fs::exists(dir_itr->status()) );
+ BOOST_CHECK( fs::is_directory(dir_itr->status()) );
+ BOOST_CHECK( !fs::is_regular_file(dir_itr->status()) );
+ BOOST_CHECK( !fs::is_other(dir_itr->status()) );
+ BOOST_CHECK( !fs::is_symlink(dir_itr->status()) );
+
+ fs::directory_iterator dir_itr2( dir );
+ BOOST_CHECK( dir_itr->path().filename() == "d1"
+ || dir_itr->path().filename() == "d2" );
+ BOOST_CHECK( dir_itr2->path().filename() == "d1" || dir_itr2->path().filename() == "d2" );
+ if ( dir_itr->path().filename() == "d1" )
+ {
+ BOOST_CHECK( (++dir_itr)->path().filename() == "d2" );
+ BOOST_CHECK( dir_itr2->path().filename() == "d1" );
+ BOOST_CHECK( (++dir_itr2)->path().filename() == "d2" );
+ }
+ else
+ {
+ BOOST_CHECK( dir_itr->path().filename() == "d2" );
+ BOOST_CHECK( (++dir_itr)->path().filename() == "d1" );
+ BOOST_CHECK( (dir_itr2)->path().filename() == "d2" );
+ BOOST_CHECK( (++dir_itr2)->path().filename() == "d1" );
+ }
+ BOOST_CHECK( ++dir_itr == fs::directory_iterator() );
+ BOOST_CHECK( dir_itr2 != fs::directory_iterator() );
+ BOOST_CHECK( ++dir_itr2 == fs::directory_iterator() );
+ }
+
+ { // *i++ must work to meet the standard's InputIterator requirements
+ fs::directory_iterator dir_itr( dir );
+ BOOST_CHECK( dir_itr->path().filename() == "d1"
+ || dir_itr->path().filename() == "d2" );
+ if ( dir_itr->path().filename() == "d1" )
+ {
+ BOOST_CHECK( (*dir_itr++).path().filename() == "d1" );
+ BOOST_CHECK( dir_itr->path().filename() == "d2" );
+ }
+ else
+ {
+ // Check C++98 input iterator requirements
+ BOOST_CHECK( (*dir_itr++).path().filename() == "d2" );
+ // input iterator requirements in the current WP would require this check:
+ // BOOST_CHECK( implicit_cast<std::string const&>(*dir_itr++).filename() == "d1" );
+
+ BOOST_CHECK( dir_itr->path().filename() == "d1" );
+ }
+
+ // test case reported in comment to SourceForge bug tracker [937606]
+ fs::directory_iterator it( dir );
+ const fs::path p1 = *it++;
+ BOOST_CHECK( it != fs::directory_iterator() );
+ const fs::path p2 = *it++;
+ BOOST_CHECK( p1 != p2 );
+ BOOST_CHECK( it == fs::directory_iterator() );
+ }
+
+ // Windows has a tricky special case when just the root-name is given,
+ // causing the rest of the path to default to the current directory.
+ // Reported as S/F bug [ 1259176 ]
+ if ( platform == "Windows" )
+ {
+ fs::path root_name_path( fs::current_path().root_name() );
+ fs::directory_iterator it( root_name_path );
+ BOOST_CHECK( it != fs::directory_iterator() );
+ BOOST_CHECK( fs::exists( *it ) );
+ BOOST_CHECK( it->path().parent_path() == root_name_path );
+ bool found(false);
+ do
+ {
+ if ( it->path().filename() == temp_dir_name ) found = true;
+ } while ( ++it != fs::directory_iterator() );
+ BOOST_CHECK( found );
+ }
+
+ // there was an inital bug in directory_iterator that caused premature
+ // close of an OS handle. This block will detect regression.
+ {
+ fs::directory_iterator di;
+ {
+ di = fs::directory_iterator( dir );
+ }
+ BOOST_CHECK( ++di != fs::directory_iterator() );
+ }
+
+ std::cout << " directory_iterator_tests complete" << std::endl;
+ }
+
+ // create_hard_link_tests ------------------------------------------------//
+
+ void create_hard_link_tests()
+ {
+ std::cout << "create_hard_link_tests..." << std::endl;
+
+ fs::path from_ph( dir / "f3" );
+ fs::path file_ph( dir / "f1" );
+
+ BOOST_CHECK( !fs::exists( from_ph ) );
+ BOOST_CHECK( fs::exists( file_ph ) );
+ bool create_hard_link_ok(true);
+ try { fs::create_hard_link( file_ph, from_ph ); }
+ catch ( const fs::filesystem_error & ex )
+ {
+ create_hard_link_ok = false;
+ std::cout
+ << " *** For information only ***\n"
+ " create_hard_link() attempt failed\n"
+ " filesystem_error.what() reports: " << ex.what() << "\n"
+ " create_hard_link() may not be supported on this file system\n";
+ }
+
+ if ( create_hard_link_ok )
+ {
+ std::cout
+ << " *** For information only ***\n"
+ " create_hard_link() succeeded\n";
+ BOOST_CHECK( fs::exists( from_ph ) );
+ BOOST_CHECK( fs::exists( file_ph ) );
+ BOOST_CHECK( fs::equivalent( from_ph, file_ph ) );
+ }
+
+ // Although tests may be running on a FAT or other file system that does
+ // not support hard links, that is unusual enough that it is considered
+ // a test failure.
+ BOOST_CHECK( create_hard_link_ok );
+
+ error_code ec;
+ fs::create_hard_link( fs::path("doesnotexist"),
+ fs::path("shouldnotwork"), ec );
+ BOOST_CHECK( ec );
+ }
+
+ // create_symlink_tests --------------------------------------------------//
+
+ void create_symlink_tests()
+ {
+ std::cout << "create_symlink_tests..." << std::endl;
+
+ fs::path from_ph( dir / "f4" );
+ fs::path file_ph( dir / "f1" );
+ BOOST_CHECK( !fs::exists( from_ph ) );
+ BOOST_CHECK( fs::exists( file_ph ) );
+ try { fs::create_symlink( file_ph, from_ph ); }
+ catch ( const fs::filesystem_error & ex )
+ {
+ create_symlink_ok = false;
+ std::cout
+ << " *** For information only ***\n"
+ " create_symlink() attempt failed\n"
+ " filesystem_error.what() reports: " << ex.what() << "\n"
+ " create_symlink() may not be supported on this operating system or file system\n";
+ }
+
+ if ( create_symlink_ok )
+ {
+ std::cout
+ << " *** For information only ***\n"
+ " create_symlink() succeeded\n";
+ BOOST_CHECK( fs::exists( from_ph ) );
+ BOOST_CHECK( fs::is_symlink( from_ph ) );
+ BOOST_CHECK( fs::exists( file_ph ) );
+ BOOST_CHECK( fs::equivalent( from_ph, file_ph ) );
+
+ fs::file_status stat = fs::symlink_status( from_ph );
+ BOOST_CHECK( fs::exists( stat ) );
+ BOOST_CHECK( !fs::is_directory( stat ) );
+ BOOST_CHECK( !fs::is_regular_file( stat ) );
+ BOOST_CHECK( !fs::is_other( stat ) );
+ BOOST_CHECK( fs::is_symlink( stat ) );
+
+ stat = fs::status( from_ph );
+ BOOST_CHECK( fs::exists( stat ) );
+ BOOST_CHECK( !fs::is_directory( stat ) );
+ BOOST_CHECK( fs::is_regular_file( stat ) );
+ BOOST_CHECK( !fs::is_other( stat ) );
+ BOOST_CHECK( !fs::is_symlink( stat ) );
+ }
+
+ error_code ec = error_code();
+ fs::create_symlink( "doesnotexist", "", ec );
+ BOOST_CHECK( ec );
+ }
+
+ // rename_tests ----------------------------------------------------------//
+
+ void rename_tests()
+ {
+ std::cout << "rename_tests..." << std::endl;
+
+ // rename() test case numbers refer to operations.htm#rename table
+
+ fs::path file_ph( dir / "f1" );
+ BOOST_CHECK( fs::exists( file_ph ) );
+
+ // [case 1] make sure can't rename() a non-existent file
+ BOOST_CHECK( !fs::exists( d1 / "f99" ) );
+ BOOST_CHECK( !fs::exists( d1 / "f98" ) );
+ renamer n1a( d1 / "f99", d1 / "f98" );
+ BOOST_CHECK( CHECK_EXCEPTION( n1a, ENOENT ) );
+ renamer n1b( fs::path(""), d1 / "f98" );
+ BOOST_CHECK( CHECK_EXCEPTION( n1b, ENOENT ) );
+
+ // [case 2] rename() target.empty()
+ renamer n2( file_ph, "" );
+ BOOST_CHECK( CHECK_EXCEPTION( n2, ENOENT ) );
+
+ // [case 3] make sure can't rename() to an existent file or directory
+ BOOST_CHECK( fs::exists( dir / "f1" ) );
+ BOOST_CHECK( fs::exists( d1 / "f2" ) );
+ renamer n3a( dir / "f1", d1 / "f2" );
+ BOOST_CHECK( CHECK_EXCEPTION( n3a, EEXIST ) );
+ // several POSIX implementations (cygwin, openBSD) report ENOENT instead of EEXIST,
+ // so we don't verify error type on the above test.
+ renamer n3b( dir, d1 );
+ BOOST_CHECK( CHECK_EXCEPTION( n3b, 0 ) );
+
+ // [case 4A] can't rename() file to a nonexistent parent directory
+ BOOST_CHECK( !fs::is_directory( dir / "f1" ) );
+ BOOST_CHECK( !fs::exists( dir / "d3/f3" ) );
+ renamer n4a( dir / "f1", dir / "d3/f3" );
+ BOOST_CHECK( CHECK_EXCEPTION( n4a, ENOENT ) );
+
+ // [case 4B] rename() file in same directory
+ BOOST_CHECK( fs::exists( d1 / "f2" ) );
+ BOOST_CHECK( !fs::exists( d1 / "f50" ) );
+ fs::rename( d1 / "f2", d1 / "f50" );
+ BOOST_CHECK( !fs::exists( d1 / "f2" ) );
+ BOOST_CHECK( fs::exists( d1 / "f50" ) );
+ fs::rename( d1 / "f50", d1 / "f2" );
+ BOOST_CHECK( fs::exists( d1 / "f2" ) );
+ BOOST_CHECK( !fs::exists( d1 / "f50" ) );
+
+ // [case 4C] rename() file d1/f2 to d2/f3
+ fs::rename( d1 / "f2", d2 / "f3" );
+ BOOST_CHECK( !fs::exists( d1 / "f2" ) );
+ BOOST_CHECK( !fs::exists( d2 / "f2" ) );
+ BOOST_CHECK( fs::exists( d2 / "f3" ) );
+ BOOST_CHECK( !fs::is_directory( d2 / "f3" ) );
+ verify_file( d2 / "f3", "foobar1" );
+ fs::rename( d2 / "f3", d1 / "f2" );
+ BOOST_CHECK( fs::exists( d1 / "f2" ) );
+
+ // [case 5A] rename() directory to nonexistent parent directory
+ BOOST_CHECK( fs::exists( d1 ) );
+ BOOST_CHECK( !fs::exists( dir / "d3/d5" ) );
+ BOOST_CHECK( !fs::exists( dir / "d3" ) );
+ renamer n5a( d1, dir / "d3/d5" );
+ BOOST_CHECK( CHECK_EXCEPTION( n5a, ENOENT ) );
+
+ // [case 5B] rename() on directory
+ fs::path d3( dir / "d3" );
+ BOOST_CHECK( fs::exists( d1 ) );
+ BOOST_CHECK( fs::exists( d1 / "f2" ) );
+ BOOST_CHECK( !fs::exists( d3 ) );
+ fs::rename( d1, d3 );
+ BOOST_CHECK( !fs::exists( d1 ) );
+ BOOST_CHECK( fs::exists( d3 ) );
+ BOOST_CHECK( fs::is_directory( d3 ) );
+ BOOST_CHECK( !fs::exists( d1 / "f2" ) );
+ BOOST_CHECK( fs::exists( d3 / "f2" ) );
+ fs::rename( d3, d1 );
+ BOOST_CHECK( fs::exists( d1 ) );
+ BOOST_CHECK( fs::exists( d1 / "f2" ) );
+ BOOST_CHECK( !fs::exists( d3 ) );
+
+ // [case 5C] rename() rename and move d1 to d2 / "d20"
+ BOOST_CHECK( fs::exists( d1 ) );
+ BOOST_CHECK( !fs::exists( d2 / "d20" ) );
+ BOOST_CHECK( fs::exists( d1 / "f2" ) );
+ fs::rename( d1, d2 / "d20" );
+ BOOST_CHECK( !fs::exists( d1 ) );
+ BOOST_CHECK( fs::exists( d2 / "d20" ) );
+ BOOST_CHECK( fs::exists( d2 / "d20" / "f2" ) );
+ fs::rename( d2 / "d20", d1 );
+ BOOST_CHECK( fs::exists( d1 ) );
+ BOOST_CHECK( !fs::exists( d2 / "d20" ) );
+ BOOST_CHECK( fs::exists( d1 / "f2" ) );
+ }
+
+ // predicate_and_status_tests --------------------------------------------//
+
+ void predicate_and_status_tests()
+ {
+ std::cout << "predicate_and_status_tests..." << std::endl;
+
+ BOOST_CHECK( !fs::exists( ng ) );
+ BOOST_CHECK( !fs::is_directory( ng ) );
+ BOOST_CHECK( !fs::is_regular_file( ng ) );
+ BOOST_CHECK( !fs::is_symlink( ng ) );
+ fs::file_status stat( fs::status( ng ) );
+ BOOST_CHECK( fs::status_known( stat ) );
+ BOOST_CHECK( !fs::exists( stat ) );
+ BOOST_CHECK( !fs::is_directory( stat ) );
+ BOOST_CHECK( !fs::is_regular_file( stat ) );
+ BOOST_CHECK( !fs::is_other( stat ) );
+ BOOST_CHECK( !fs::is_symlink( stat ) );
+ stat = fs::status( "" );
+ BOOST_CHECK( fs::status_known( stat ) );
+ BOOST_CHECK( !fs::exists( stat ) );
+ BOOST_CHECK( !fs::is_directory( stat ) );
+ BOOST_CHECK( !fs::is_regular_file( stat ) );
+ BOOST_CHECK( !fs::is_other( stat ) );
+ BOOST_CHECK( !fs::is_symlink( stat ) );
+ }
+
+ // create_directory_tests ------------------------------------------------//
+
+ void create_directory_tests()
+ {
+ std::cout << "create_directory_tests..." << std::endl;
+
+ // create a directory, then check it for consistency
+ // take extra care to report problems, since if this fails
+ // many subsequent tests will fail
+ try
+ {
+ fs::create_directory( dir );
+ }
+
+ catch ( const fs::filesystem_error & x )
+ {
+ std::cout << x.what() << "\n\n"
+ "***** Creating directory " << dir.string() << " failed. *****\n"
+ "***** This is a serious error that will prevent further tests *****\n"
+ "***** from returning useful results. Further testing is aborted. *****\n\n";
+ std::exit(1);
+ }
+
+ catch ( ... )
+ {
+ std::cout << "\n\n"
+ "***** Creating directory " << dir.string() << " failed. *****\n"
+ "***** This is a serious error that will prevent further tests *****\n"
+ "***** from returning useful results. Further testing is aborted. *****\n\n";
+ std::exit(1);
+ }
+
+ BOOST_CHECK( fs::exists( dir ) );
+ BOOST_CHECK( BOOST_FS_IS_EMPTY( dir ) );
+ BOOST_CHECK( fs::is_directory( dir ) );
+ BOOST_CHECK( !fs::is_regular_file( dir ) );
+ BOOST_CHECK( !fs::is_other( dir ) );
+ BOOST_CHECK( !fs::is_symlink( dir ) );
+ fs::file_status stat = fs::status( dir );
+ BOOST_CHECK( fs::exists( stat ) );
+ BOOST_CHECK( fs::is_directory( stat ) );
+ BOOST_CHECK( !fs::is_regular_file( stat ) );
+ BOOST_CHECK( !fs::is_other( stat ) );
+ BOOST_CHECK( !fs::is_symlink( stat ) );
+
+ std::cout << " create_directory_tests complete" << std::endl;
+ }
+
+ // current_directory_tests -----------------------------------------------//
+
+ void current_directory_tests()
+ {
+ std::cout << "current_directory_tests..." << std::endl;
+
+ // set the current directory, then check it for consistency
+ fs::path original_dir = fs::current_path();
+ BOOST_CHECK( dir != original_dir );
+ fs::current_path( dir );
+ BOOST_CHECK( fs::current_path() == dir );
+ BOOST_CHECK( fs::current_path() != original_dir );
+ fs::current_path( original_dir );
+ BOOST_CHECK( fs::current_path() == original_dir );
+ BOOST_CHECK( fs::current_path() != dir );
+
+ // make sure the overloads work
+ fs::current_path( dir.string().c_str() );
+ BOOST_CHECK( fs::current_path() == dir );
+ BOOST_CHECK( fs::current_path() != original_dir );
+ fs::current_path( original_dir.string() );
+ BOOST_CHECK( fs::current_path() == original_dir );
+ BOOST_CHECK( fs::current_path() != dir );
+ }
+
+ // create_directories_tests ----------------------------------------------//
+
+ void create_directories_tests()
+ {
+ std::cout << "create_directories_tests..." << std::endl;
+
+ fs::path p = dir / "level1" / "level2";
+
+ BOOST_CHECK( !fs::exists( p ) );
+ BOOST_CHECK( fs::create_directories( p ) );
+ BOOST_CHECK( fs::exists( p ) );
+ BOOST_CHECK( fs::is_directory( p ) );
+ }
+
+ // _tests ----------------------------------------------------//
+
+ void _tests()
+ {
+ std::cout << "_tests..." << std::endl;
+ }
+
+} // unnamed namespace
+
+// test_main ---------------------------------------------------------------//
+
+int test_main( int argc, char * argv[] )
+{
+ if ( argc > 1 && *argv[1]=='-' && *(argv[1]+1)=='t' ) report_throws = true;
+
+ // The choice of platform is make at runtime rather than compile-time
+ // so that compile errors for all platforms will be detected even though
+ // only the current platform is runtime tested.
+# if defined( BOOST_POSIX_API )
+ platform = "POSIX";
+# elif defined( BOOST_WINDOWS_API )
+ platform = "Windows";
+# if !defined(__MINGW32__) && !defined(__CYGWIN__)
+ language_id = ::GetUserDefaultUILanguage();
+# else
+ language_id = 0x0409; // Assume US English
+# endif
+# else
+ platform = ( platform == "Win32" || platform == "Win64" || platform == "Cygwin" )
+ ? "Windows"
+ : "POSIX";
+# endif
+ std::cout << "API is " << platform << std::endl;
+
+ exception_tests();
+
+ std::cout << "\ninitial_path<path>().string() is\n \""
+ << fs::initial_path().string()
+ << "\"\n";
+ std::cout << "\ninitial_path().string() is\n \""
+ << fs::initial_path().string()
+ << "\"\n\n";
+ BOOST_CHECK( fs::initial_path().is_complete() );
+ BOOST_CHECK( fs::current_path().is_complete() );
+ BOOST_CHECK( fs::initial_path().string()
+ == fs::current_path().string() );
+
+ BOOST_CHECK( fs::complete( "" ).empty() );
+ BOOST_CHECK( fs::complete( "/" ) == fs::initial_path().root_path() );
+ BOOST_CHECK( fs::complete( "foo" ) == fs::initial_path().string()+"/foo" );
+ BOOST_CHECK( fs::complete( "/foo" ) == fs::initial_path().root_path().string()+"foo" );
+ BOOST_CHECK( fs::complete( "foo", fs::path( "//net/bar" ) )
+ == "//net/bar/foo" );
+
+ predicate_and_status_tests();
+
+ dir = fs::initial_path() / temp_dir_name;
+
+ if ( fs::exists( dir ) )
+ {
+ std::cout << "remove residue from prior failed tests..." << std::endl;
+ fs::remove_all( dir );
+ }
+ BOOST_CHECK( !fs::exists( dir ) );
+
+ create_directory_tests();
+
+ // Windows only tests
+ if ( platform == "Windows" )
+ {
+ std::cout << "Window specific tests..."
+ "\n (may take several seconds)" << std::endl;
+
+ BOOST_CHECK( !fs::exists( fs::path( "//share-not" ) ) );
+ BOOST_CHECK( !fs::exists( fs::path( "//share-not/" ) ) );
+ BOOST_CHECK( !fs::exists( fs::path( "//share-not/foo" ) ) );
+ BOOST_CHECK( !fs::exists( "tools/jam/src/:sys:stat.h" ) ); // !exists() if ERROR_INVALID_NAME
+ BOOST_CHECK( !fs::exists( ":sys:stat.h" ) ); // !exists() if ERROR_INVALID_PARAMETER
+ BOOST_CHECK( dir.string().size() > 1
+ && dir.string()[1] == ':' ); // verify path includes drive
+
+ BOOST_CHECK( fs::system_complete( "" ).empty() );
+ BOOST_CHECK( fs::system_complete( "/" ).string()
+ == fs::initial_path().root_path().string() );
+ BOOST_CHECK( fs::system_complete( "foo" )
+ == fs::initial_path() / "foo" );
+ BOOST_CHECK( fs::system_complete( "/foo" ).string()
+ == fs::initial_path().root_path().string()+"foo" );
+ BOOST_CHECK( fs::complete( fs::path( "c:/" ) ).string()
+ == "c:/" );
+ BOOST_CHECK( fs::complete( fs::path( "c:/foo" ) ).string()
+ == "c:/foo" );
+
+ BOOST_CHECK( fs::system_complete( fs::path( fs::initial_path().root_name() ) ).string() == fs::initial_path().string() );
+ BOOST_CHECK( fs::system_complete( fs::path( fs::initial_path().root_name().string()
+ + "foo" ) ).string() == fs::initial_path() / "foo" );
+ BOOST_CHECK( fs::system_complete( fs::path( "c:/" ) ).generic()
+ == "c:/" );
+ BOOST_CHECK( fs::system_complete( fs::path( "c:/foo" ) ).generic()
+ == "c:/foo" );
+ BOOST_CHECK( fs::system_complete( fs::path( "//share" ) ).generic()
+ == "//share" );
+ } // Windows
+
+ else if ( platform == "POSIX" )
+ {
+ std::cout << "POSIX specific tests..." << std::endl;
+ BOOST_CHECK( fs::system_complete( "" ).empty() );
+ BOOST_CHECK( fs::initial_path().root_path().string() == "/" );
+ BOOST_CHECK( fs::system_complete( "/" ).string() == "/" );
+ BOOST_CHECK( fs::system_complete( "foo" ).string()
+ == fs::initial_path().string()+"/foo" );
+ BOOST_CHECK( fs::system_complete( "/foo" ).string()
+ == fs::initial_path().root_path().string()+"foo" );
+ } // POSIX
+
+ // the bound functions should throw, so CHECK_EXCEPTION() should return true
+ BOOST_CHECK( CHECK_EXCEPTION( bad_file_size, ENOENT ) );
+
+ // test path::exception members
+ try { fs::file_size( ng ); } // will throw
+
+ catch ( const fs::filesystem_error & ex )
+ {
+ BOOST_CHECK( ex.path1().string() == " no-way, Jose" );
+ }
+ // several functions give unreasonable results if uintmax_t isn't 64-bits
+ std::cout << "sizeof(boost::uintmax_t) = " << sizeof(boost::uintmax_t) << '\n';
+ BOOST_CHECK( sizeof( boost::uintmax_t ) >= 8 );
+
+ current_directory_tests();
+
+ // make some reasonable assuptions for testing purposes
+ fs::space_info spi( fs::space( dir ) );
+ BOOST_CHECK( spi.capacity > 1000000 );
+ BOOST_CHECK( spi.free > 1000 );
+ BOOST_CHECK( spi.capacity > spi.free );
+ BOOST_CHECK( spi.free >= spi.available );
+
+ // it is convenient to display space, but older VC++ versions choke
+# if !defined(BOOST_MSVC) || _MSC_VER >= 1300 // 1300 == VC++ 7.0
+ std::cout << " capacity = " << spi.capacity << '\n';
+ std::cout << " free = " << spi.free << '\n';
+ std::cout << "available = " << spi.available << '\n';
+# endif
+
+ if ( platform == "Windows" )
+ BOOST_CHECK( CHECK_EXCEPTION( bad_directory_size, ENOENT ) );
+ else
+ BOOST_CHECK( CHECK_EXCEPTION( bad_directory_size, 0 ) );
+
+ BOOST_CHECK( !fs::create_directory( dir ) );
+
+ BOOST_CHECK( !fs::is_symlink( dir ) );
+ BOOST_CHECK( !fs::is_symlink( "nosuchfileordirectory" ) );
+
+ d1 = dir / "d1";
+ BOOST_CHECK( fs::create_directory( d1 ) );
+ BOOST_CHECK( fs::exists( d1 ) );
+ BOOST_CHECK( fs::is_directory( d1 ) );
+ BOOST_CHECK( BOOST_FS_IS_EMPTY( d1 ) );
+
+ directory_iterator_tests();
+ create_directories_tests(); // must run AFTER directory_iterator_tests
+
+ // create an empty file named "f0"
+ fs::path file_ph( dir / "f0");
+ create_file( file_ph, "" );
+ BOOST_CHECK( fs::exists( file_ph ) );
+ BOOST_CHECK( !fs::is_directory( file_ph ) );
+ BOOST_CHECK( fs::is_regular_file( file_ph ) );
+ BOOST_CHECK( BOOST_FS_IS_EMPTY( file_ph ) );
+ BOOST_CHECK( fs::file_size( file_ph ) == 0 );
+ bad_create_directory_path = file_ph;
+ BOOST_CHECK( CHECK_EXCEPTION( bad_create_directory, EEXIST ) );
+ fs::file_status stat = fs::status( file_ph );
+ BOOST_CHECK( fs::status_known( stat ) );
+ BOOST_CHECK( fs::exists( stat ) );
+ BOOST_CHECK( !fs::is_directory( stat ) );
+ BOOST_CHECK( fs::is_regular_file( stat ) );
+ BOOST_CHECK( !fs::is_other( stat ) );
+ BOOST_CHECK( !fs::is_symlink( stat ) );
+
+ // create a file named "f1"
+ file_ph = dir / "f1";
+ create_file( file_ph, "foobar1" );
+
+ BOOST_CHECK( fs::exists( file_ph ) );
+ BOOST_CHECK( !fs::is_directory( file_ph ) );
+ BOOST_CHECK( fs::is_regular_file( file_ph ) );
+ BOOST_CHECK( fs::file_size( file_ph ) == 7 );
+ verify_file( file_ph, "foobar1" );
+
+ // equivalence tests
+ BOOST_CHECK( CHECK_EXCEPTION( bad_equivalent, ENOENT ) );
+ BOOST_CHECK( fs::equivalent( file_ph, dir / "f1" ) );
+ BOOST_CHECK( fs::equivalent( dir, d1 / ".." ) );
+ BOOST_CHECK( !fs::equivalent( file_ph, dir ) );
+ BOOST_CHECK( !fs::equivalent( dir, file_ph ) );
+ BOOST_CHECK( !fs::equivalent( d1, d2 ) );
+ BOOST_CHECK( !fs::equivalent( dir, ng ) );
+ BOOST_CHECK( !fs::equivalent( ng, dir ) );
+ BOOST_CHECK( !fs::equivalent( file_ph, ng ) );
+ BOOST_CHECK( !fs::equivalent( ng, file_ph ) );
+
+ create_hard_link_tests();
+ create_symlink_tests();
+
+ // copy_file() tests
+ std::cout << "begin copy_file test..." << std::endl;
+ fs::copy_file( file_ph, d1 / "f2" );
+ std::cout << "copying complete" << std::endl;
+ BOOST_CHECK( fs::exists( file_ph ) );
+ BOOST_CHECK( fs::exists( d1 / "f2" ) );
+ BOOST_CHECK( !fs::is_directory( d1 / "f2" ) );
+ verify_file( d1 / "f2", "foobar1" );
+ std::cout << "copy_file test complete" << std::endl;
+
+ rename_tests();
+
+ // remove() file
+ file_ph = dir / "shortlife";
+ BOOST_CHECK( !fs::exists( file_ph ) );
+ create_file( file_ph, "" );
+ BOOST_CHECK( fs::exists( file_ph ) );
+ BOOST_CHECK( !fs::is_directory( file_ph ) );
+ BOOST_CHECK( fs::remove( file_ph ) );
+ BOOST_CHECK( !fs::exists( file_ph ) );
+ BOOST_CHECK( !fs::remove( "no-such-file" ) );
+ BOOST_CHECK( !fs::remove( "no-such-directory/no-such-file" ) );
+
+ // remove() directory
+ d1 = dir / "shortlife_dir";
+ BOOST_CHECK( !fs::exists( d1 ) );
+ fs::create_directory( d1 );
+ BOOST_CHECK( fs::exists( d1 ) );
+ BOOST_CHECK( fs::is_directory( d1 ) );
+ BOOST_CHECK( BOOST_FS_IS_EMPTY( d1 ) );
+ bad_remove_dir = dir;
+ BOOST_CHECK( CHECK_EXCEPTION( bad_remove, ENOTEMPTY ) );
+ BOOST_CHECK( fs::remove( d1 ) );
+ BOOST_CHECK( !fs::exists( d1 ) );
+
+ if ( create_symlink_ok ) // only if symlinks supported
+ {
+ // remove() dangling symbolic link
+ fs::path link( "dangling_link" );
+ fs::remove( link ); // remove any residue from past tests
+ BOOST_CHECK( !fs::is_symlink( link ) );
+ BOOST_CHECK( !fs::exists( link ) );
+ fs::create_symlink( "nowhere", link );
+ BOOST_CHECK( !fs::exists( link ) );
+ BOOST_CHECK( fs::is_symlink( link ) );
+ BOOST_CHECK( fs::remove( link ) );
+ BOOST_CHECK( !fs::is_symlink( link ) );
+
+ // remove() self-refering symbolic link
+ link = "link_to_self";
+ fs::remove( link ); // remove any residue from past tests
+ BOOST_CHECK( !fs::is_symlink( link ) );
+ BOOST_CHECK( !fs::exists( link ) );
+ fs::create_symlink( link, link );
+ BOOST_CHECK( fs::remove( link ) );
+ BOOST_CHECK( !fs::exists( link ) );
+ BOOST_CHECK( !fs::is_symlink( link ) );
+
+ // remove() cyclic symbolic link
+ link = "link_to_a";
+ fs::path link2( "link_to_b" );
+ fs::remove( link ); // remove any residue from past tests
+ fs::remove( link2 ); // remove any residue from past tests
+ BOOST_CHECK( !fs::is_symlink( link ) );
+ BOOST_CHECK( !fs::exists( link ) );
+ fs::create_symlink( link, link2 );
+ fs::create_symlink( link2, link );
+ BOOST_CHECK( fs::remove( link ) );
+ BOOST_CHECK( fs::remove( link2 ) );
+ BOOST_CHECK( !fs::exists( link ) );
+ BOOST_CHECK( !fs::exists( link2 ) );
+ BOOST_CHECK( !fs::is_symlink( link ) );
+
+ // remove() symbolic link to file
+ file_ph = "link_target";
+ fs::remove( file_ph ); // remove any residue from past tests
+ BOOST_CHECK( !fs::exists( file_ph ) );
+ create_file( file_ph, "" );
+ BOOST_CHECK( fs::exists( file_ph ) );
+ BOOST_CHECK( !fs::is_directory( file_ph ) );
+ BOOST_CHECK( fs::is_regular_file( file_ph ) );
+ link = "non_dangling_link";
+ fs::create_symlink( file_ph, link );
+ BOOST_CHECK( fs::exists( link ) );
+ BOOST_CHECK( !fs::is_directory( link ) );
+ BOOST_CHECK( fs::is_regular_file( link ) );
+ BOOST_CHECK( fs::is_symlink( link ) );
+ BOOST_CHECK( fs::remove( link ) );
+ BOOST_CHECK( fs::exists( file_ph ) );
+ BOOST_CHECK( !fs::exists( link ) );
+ BOOST_CHECK( !fs::is_symlink( link ) );
+ BOOST_CHECK( fs::remove( file_ph ) );
+ BOOST_CHECK( !fs::exists( file_ph ) );
+ }
+
+ // write time tests
+
+ file_ph = dir / "foobar2";
+ create_file( file_ph, "foobar2" );
+ BOOST_CHECK( fs::exists( file_ph ) );
+ BOOST_CHECK( !fs::is_directory( file_ph ) );
+ BOOST_CHECK( fs::is_regular_file( file_ph ) );
+ BOOST_CHECK( fs::file_size( file_ph ) == 7 );
+ verify_file( file_ph, "foobar2" );
+
+ // Some file system report last write time as local (FAT), while
+ // others (NTFS) report it as UTC. The C standard does not specify
+ // if time_t is local or UTC.
+
+ std::time_t ft = fs::last_write_time( file_ph );
+ std::cout << "\nUTC last_write_time() for a file just created is "
+ << std::asctime(std::gmtime(&ft)) << std::endl;
+
+ std::tm * tmp = std::localtime( &ft );
+ std::cout << "\nYear is " << tmp->tm_year << std::endl;
+ --tmp->tm_year;
+ std::cout << "Change year to " << tmp->tm_year << std::endl;
+ fs::last_write_time( file_ph, std::mktime( tmp ) );
+ std::time_t ft2 = fs::last_write_time( file_ph );
+ std::cout << "last_write_time() for the file is now "
+ << std::asctime(std::gmtime(&ft2)) << std::endl;
+ BOOST_CHECK( ft != fs::last_write_time( file_ph ) );
+
+
+ std::cout << "\nReset to current time" << std::endl;
+ fs::last_write_time( file_ph, ft );
+ double time_diff = std::difftime( ft, fs::last_write_time( file_ph ) );
+ std::cout
+ << "original last_write_time() - current last_write_time() is "
+ << time_diff << " seconds" << std::endl;
+ BOOST_CHECK( time_diff >= -60.0 && time_diff <= 60.0 );
+
+ // post-test cleanup
+ BOOST_CHECK( fs::remove_all( dir ) != 0 );
+ // above was added just to simplify testing, but it ended up detecting
+ // a bug (failure to close an internal search handle).
+ BOOST_CHECK( !fs::exists( dir ) );
+ BOOST_CHECK( fs::remove_all( dir ) == 0 );
+ return 0;
+} // main
+
Added: sandbox/filesystem-v3/libs/filesystem/v3/test/operations_unit_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/test/operations_unit_test.cpp 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,160 @@
+// operations_unit_test.cpp ------------------------------------------------//
+
+// Copyright Beman Dawes 2008
+
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See library home page at http://www.boost.org/libs/filesystem
+
+#include <iostream>
+#include <boost/filesystem/operations.hpp>
+#include <boost/system/error_code.hpp>
+
+using namespace boost::filesystem;
+using namespace boost::system;
+using std::cout;
+using std::string;
+
+#define CHECK(x) check( x, __FILE__, __LINE__ )
+
+namespace
+{
+ int errors;
+
+ std::string this_file;
+
+ void check( bool ok, const char* file, int line )
+ {
+ if ( ok ) return;
+
+ ++errors;
+
+ std::cout << file << '(' << line << "): test failed\n";
+ }
+
+ // query_test ------------------------------------------------------------//
+
+ void query_test()
+ {
+ std::cout << "query test..." << std::endl;
+
+ error_code ec;
+
+ CHECK( file_size( "no-such-file", ec ) == 0 );
+ CHECK( ec == errc::no_such_file_or_directory );
+
+ CHECK( status( "no-such-file" ) == file_status( file_not_found ) );
+
+ CHECK( exists( "/" ) );
+ CHECK( !exists( "no-such-file" ) );
+
+ CHECK( is_directory( "/" ) );
+ CHECK( !is_directory( this_file ) );
+
+ CHECK( is_regular_file( this_file ) );
+ CHECK( !is_empty( this_file ) );
+ CHECK( !is_other( this_file ) );
+
+ space_info info = space( "/" );
+
+ CHECK( info.available <= info.capacity );
+
+// CHECK( equivalent( "/", "/" ) );
+// CHECK( !equivalent( "/", "." ) );
+
+ std::time_t ft = last_write_time( "." );
+
+ last_write_time( ".", std::time_t(-1), ec );
+ }
+
+ // directory_iterator_test -----------------------------------------------//
+
+ void directory_iterator_test()
+ {
+ std::cout << "directory_iterator_test..." << std::endl;
+
+ directory_iterator end;
+
+ directory_iterator it( "." );
+
+// CHECK( !it->path().empty() );
+
+ if ( is_regular_file( it->status() ) )
+ {
+ CHECK( is_regular_file( it->symlink_status() ) );
+ CHECK( !is_directory( it->status() ) );
+ CHECK( !is_symlink( it->status() ) );
+ CHECK( !is_directory( it->symlink_status() ) );
+ CHECK( !is_symlink( it->symlink_status() ) );
+ }
+ else
+ {
+ CHECK( is_directory( it->status() ) );
+ CHECK( is_directory( it->symlink_status() ) );
+ CHECK( !is_regular_file( it->status() ) );
+ CHECK( !is_regular_file( it->symlink_status() ) );
+ CHECK( !is_symlink( it->status() ) );
+ CHECK( !is_symlink( it->symlink_status() ) );
+ }
+
+
+ for ( ; it != end; ++it )
+ {
+// cout << " " << it->path().string() << "\n";
+ }
+
+ std::cout << "directory_iterator_test complete" << std::endl;
+}
+
+
+ // operations_test -------------------------------------------------------//
+
+ void operations_test()
+ {
+ std::cout << "operations test..." << std::endl;
+
+ error_code ec;
+
+ CHECK( complete( "foo", "c:/" ) == "c:/foo" );
+
+ CHECK( !create_directory( "/", ec ) );
+
+ CHECK( !boost::filesystem::remove( "no-such-file-or-directory" ) );
+ CHECK( !remove_all( "no-such-file-or-directory" ) );
+
+ }
+
+} // unnamed namespace
+
+// -------------------------------- main -----------------------------------//
+
+int main( int argc, char * argv[] )
+{
+ this_file = argv[0];
+
+ cout << current_path().string() << std::endl;
+
+ // error handling tests
+
+ bool threw( false );
+ try { file_size( "no-such-file" ); }
+ catch ( const filesystem_error & ex )
+ {
+ threw = true;
+ cout << "\nas expected, attempt to get size of non-existent file threw a filesystem_error\n"
+ "what() returns " << ex.what() << "\n";
+ }
+
+ CHECK( threw );
+
+ error_code ec;
+ CHECK( !create_directory( "/", ec ) );
+
+ query_test();
+ directory_iterator_test();
+ operations_test();
+
+ cout << errors << " errors detected\n";
+ return errors;
+}
Added: sandbox/filesystem-v3/libs/filesystem/v3/test/path_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/test/path_test.cpp 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,1330 @@
+// path_test program -------------------------------------------------------//
+
+// Copyright Beman Dawes 2002
+// Copyright Vladimir Prus 2002
+
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See library home page at http://www.boost.org/libs/filesystem
+
+// basic_path's stem(), extension(), and replace_extension() tests are based
+// on basename(), extension(), and change_extension() tests from the original
+// convenience_test.cpp by Vladimir Prus.
+
+// See deprecated_test for tests of deprecated features
+#define BOOST_FILESYSTEM_NO_DEPRECATED
+
+#include <boost/filesystem/operations.hpp>
+#include <boost/utility.hpp>
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <vector>
+#include <cstring>
+#include <cassert>
+
+namespace fs = boost::filesystem;
+using boost::filesystem::path;
+using boost::next;
+using boost::prior;
+
+#include <boost/test/minimal.hpp>
+
+#define PATH_CHECK( a, b ) check( a, b, __FILE__, __LINE__ )
+#define DIR_CHECK( a, b ) check_dir( a, b, __FILE__, __LINE__ )
+#define CHECK_EQUAL( a,b ) check_equal( a, b, __FILE__, __LINE__ )
+
+
+namespace
+{
+ std::string platform( BOOST_PLATFORM );
+
+ int errors;
+
+ void check( const fs::path & source,
+ const std::string & expected, const char* file, int line )
+ {
+ if ( source.string()== expected ) return;
+
+ ++errors;
+
+ std::cout << file
+ << '(' << line << "): source.string(): \"" << source.string()
+ << "\" != expected: \"" << expected
+ << "\"" << std::endl;
+ }
+
+ void check_dir( const fs::path & source,
+ const std::string & expected, const char* file, int line )
+ {
+ if ( source.string()== expected ) return;
+
+ ++errors;
+
+ std::cout << file << '(' << line << "): source.directory_string(): \""
+ << source.string()
+ << "\" != expected: \"" << expected
+ << "\"" << std::endl;
+ }
+
+ void check_equal( const std::string & value,
+ const std::string & expected, const char* file, int line )
+ {
+ if ( value == expected ) return;
+
+ ++errors;
+
+ std::cout << file << '(' << line << "): value: \"" << value
+ << "\" != expected: \"" << expected
+ << "\"" << std::endl;
+ }
+
+ path p1( "fe/fi/fo/fum" );
+ path p2( p1 );
+ path p3;
+ path p4( "foobar" );
+ path p5;
+
+ // exception_tests -------------------------------------------------------//
+
+ void exception_tests()
+ {
+ std::cout << "exception_tests..." << std::endl;
+ const std::string str_1("string-1");
+ boost::system::error_code ec( 12345, boost::system::system_category);
+ try { throw fs::filesystem_error( str_1, ec ); }
+ catch ( const fs::filesystem_error & ex )
+ {
+ //std::cout << ex.what() << "*" << std::endl;
+ //BOOST_CHECK( std::strcmp( ex.what(),
+ // "string-1: Unknown error" ) == 0 );
+ BOOST_CHECK( ex.code() == ec );
+ }
+
+ try { throw fs::filesystem_error( str_1, "p1", "p2", ec ); }
+ catch ( const fs::filesystem_error & ex )
+ {
+ //std::cout << ex.what() << "*" << std::endl;
+ //BOOST_CHECK( std::strcmp( ex.what(),
+ // "string-1: Unknown error: \"p1\", \"p2\"" ) == 0 );
+ BOOST_CHECK( ex.code() == ec );
+ BOOST_CHECK( ex.path1().string() == "p1" );
+ BOOST_CHECK( ex.path2().string() == "p2" );
+ }
+ }
+
+ // overload_tests --------------------------------------------------------//
+
+ // These verify various overloads don't cause compiler errors
+ // They pre-date operations_unit_test.cpp
+
+ void overload_tests()
+ {
+ std::cout << "overload_tests..." << std::endl;
+
+ fs::exists( p1 );
+ fs::exists( "foo" );
+ fs::exists( std::string( "foo" ) );
+
+ fs::exists( p1 / path( "foo" ) );
+ fs::exists( p1 / "foo" );
+ fs::exists( p1 / std::string( "foo" ) );
+
+ fs::exists( "foo" / p1 );
+ fs::exists( std::string( "foo" ) / p1 );
+
+ p4 /= path( "foo" );
+ p4 /= "foo";
+ p4 /= std::string( "foo" );
+ }
+
+ // iterator_tests --------------------------------------------------------//
+
+ void iterator_tests()
+ {
+ std::cout << "iterator_tests..." << std::endl;
+
+ path itr_ck = "";
+ path::const_iterator itr = itr_ck.begin();
+ BOOST_CHECK( itr == itr_ck.end() );
+
+ itr_ck = "/";
+ itr = itr_ck.begin();
+ BOOST_CHECK( *itr == std::string( "/" ) );
+ BOOST_CHECK( ++itr == itr_ck.end() );
+ BOOST_CHECK( *--itr == std::string( "/" ) );
+
+ itr_ck = "foo";
+ BOOST_CHECK( *itr_ck.begin() == std::string( "foo" ) );
+ BOOST_CHECK( next( itr_ck.begin() ) == itr_ck.end() );
+ BOOST_CHECK( *prior( itr_ck.end() ) == std::string( "foo" ) );
+ BOOST_CHECK( prior( itr_ck.end() ) == itr_ck.begin() );
+
+ itr_ck = path( "/foo" );
+ BOOST_CHECK( *itr_ck.begin() == std::string( "/" ) );
+ BOOST_CHECK( *next( itr_ck.begin() ) == std::string( "foo" ) );
+ BOOST_CHECK( next(next( itr_ck.begin() )) == itr_ck.end() );
+ BOOST_CHECK( next( itr_ck.begin() ) == prior( itr_ck.end() ) );
+ BOOST_CHECK( *prior( itr_ck.end() ) == std::string( "foo" ) );
+ BOOST_CHECK( *prior(prior( itr_ck.end() )) == std::string( "/" ) );
+ BOOST_CHECK( prior(prior( itr_ck.end() )) == itr_ck.begin() );
+
+ itr_ck = "/foo/bar";
+ itr = itr_ck.begin();
+ BOOST_CHECK( *itr == std::string( "/" ) );
+ BOOST_CHECK( *++itr == std::string( "foo" ) );
+ BOOST_CHECK( *++itr == std::string( "bar" ) );
+ BOOST_CHECK( ++itr == itr_ck.end() );
+ CHECK_EQUAL( *--itr, "bar" );
+ CHECK_EQUAL( *--itr, "foo" );
+ CHECK_EQUAL( *--itr, "/" );
+
+ itr_ck = "../f"; // previously failed due to short name bug
+ itr = itr_ck.begin();
+ CHECK_EQUAL( *itr, ".." );
+ CHECK_EQUAL( *++itr, "f" );
+ BOOST_CHECK( ++itr == itr_ck.end() );
+ CHECK_EQUAL( *--itr, "f" );
+ CHECK_EQUAL( *--itr, ".." );
+
+ // POSIX says treat "/foo/bar/" as "/foo/bar/."
+ itr_ck = "/foo/bar/";
+ itr = itr_ck.begin();
+ CHECK_EQUAL( *itr, "/" );
+ CHECK_EQUAL( *++itr, "foo" );
+ CHECK_EQUAL( *++itr, "bar" );
+ CHECK_EQUAL( *++itr, "." );
+ BOOST_CHECK( ++itr == itr_ck.end() );
+ CHECK_EQUAL( *--itr, "." );
+ CHECK_EQUAL( *--itr, "bar" );
+ CHECK_EQUAL( *--itr, "foo" );
+ CHECK_EQUAL( *--itr, "/" );
+
+ // POSIX says treat "/f/b/" as "/f/b/."
+ itr_ck = "/f/b/";
+ itr = itr_ck.begin();
+ CHECK_EQUAL( *itr, "/" );
+ CHECK_EQUAL( *++itr, "f" );
+ CHECK_EQUAL( *++itr, "b" );
+ CHECK_EQUAL( *++itr, "." );
+ BOOST_CHECK( ++itr == itr_ck.end() );
+ CHECK_EQUAL( *--itr, "." );
+ CHECK_EQUAL( *--itr, "b" );
+ CHECK_EQUAL( *--itr, "f" );
+ CHECK_EQUAL( *--itr, "/" );
+
+ itr_ck = "//net";
+ itr = itr_ck.begin();
+ // two leading slashes are permitted by POSIX (as implementation defined),
+ // while for Windows it is always well defined (as a network name)
+ CHECK_EQUAL( *itr, "//net" );
+ BOOST_CHECK( ++itr == itr_ck.end() );
+ CHECK_EQUAL( *--itr, "//net" );
+
+ itr_ck = "//net/";
+ itr = itr_ck.begin();
+ CHECK_EQUAL( *itr, "//net" );
+ CHECK_EQUAL( *++itr, "/" );
+ BOOST_CHECK( ++itr == itr_ck.end() );
+ CHECK_EQUAL( *--itr, "/" );
+ CHECK_EQUAL( *--itr, "//net" );
+
+ itr_ck = "//foo///bar///";
+ itr = itr_ck.begin();
+ CHECK_EQUAL( *itr, "//foo" );
+ CHECK_EQUAL( *++itr, "/" );
+ CHECK_EQUAL( *++itr, "bar" );
+ CHECK_EQUAL( *++itr, "." );
+ BOOST_CHECK( ++itr == itr_ck.end() );
+ CHECK_EQUAL( *--itr, "." );
+ CHECK_EQUAL( *--itr, "bar" );
+ CHECK_EQUAL( *--itr, "/" );
+ CHECK_EQUAL( *--itr, "//foo" );
+
+ itr_ck = "///foo///bar///";
+ itr = itr_ck.begin();
+ // three or more leading slashes are to be treated as a single slash
+ CHECK_EQUAL( *itr, "/" );
+ CHECK_EQUAL( *++itr, "foo" );
+ CHECK_EQUAL( *++itr, "bar" );
+ CHECK_EQUAL( *++itr, "." );
+ BOOST_CHECK( ++itr == itr_ck.end() );
+ CHECK_EQUAL( *--itr, "." );
+ CHECK_EQUAL( *--itr, "bar" );
+ CHECK_EQUAL( *--itr, "foo" );
+ CHECK_EQUAL( *--itr, "/" );
+
+ if ( platform == "Windows" )
+ {
+ itr_ck = "c:/";
+ itr = itr_ck.begin();
+ CHECK_EQUAL( *itr, "c:" );
+ CHECK_EQUAL( *++itr, "/" );
+ BOOST_CHECK( ++itr == itr_ck.end() );
+ CHECK_EQUAL( *--itr, "/" );
+ CHECK_EQUAL( *--itr, "c:" );
+
+ itr_ck = "c:\\foo";
+ itr = itr_ck.begin();
+ BOOST_CHECK( *itr == std::string( "c:" ) );
+ BOOST_CHECK( *++itr == std::string( "/" ) );
+ BOOST_CHECK( *++itr == std::string( "foo" ) );
+ BOOST_CHECK( ++itr == itr_ck.end() );
+ BOOST_CHECK( *--itr == std::string( "foo" ) );
+ BOOST_CHECK( *--itr == std::string( "/" ) );
+ BOOST_CHECK( *--itr == std::string( "c:" ) );
+
+ itr_ck = "\\\\\\foo\\\\\\bar\\\\\\";
+ itr = itr_ck.begin();
+ // three or more leading slashes are to be treated as a single slash
+ CHECK_EQUAL( *itr, "/" );
+ CHECK_EQUAL( *++itr, "foo" );
+ CHECK_EQUAL( *++itr, "bar" );
+ CHECK_EQUAL( *++itr, "." );
+ BOOST_CHECK( ++itr == itr_ck.end() );
+ CHECK_EQUAL( *--itr, "." );
+ CHECK_EQUAL( *--itr, "bar" );
+ CHECK_EQUAL( *--itr, "foo" );
+ CHECK_EQUAL( *--itr, "/" );
+
+ itr_ck = "c:foo";
+ itr = itr_ck.begin();
+ BOOST_CHECK( *itr == std::string( "c:" ) );
+ BOOST_CHECK( *++itr == std::string( "foo" ) );
+ BOOST_CHECK( ++itr == itr_ck.end() );
+ BOOST_CHECK( *--itr == std::string( "foo" ) );
+ BOOST_CHECK( *--itr == std::string( "c:" ) );
+
+ itr_ck = "c:foo/";
+ itr = itr_ck.begin();
+ BOOST_CHECK( *itr == std::string( "c:" ) );
+ BOOST_CHECK( *++itr == std::string( "foo" ) );
+ BOOST_CHECK( *++itr == std::string( "." ) );
+ BOOST_CHECK( ++itr == itr_ck.end() );
+ BOOST_CHECK( *--itr == std::string( "." ) );
+ BOOST_CHECK( *--itr == std::string( "foo" ) );
+ BOOST_CHECK( *--itr == std::string( "c:" ) );
+
+ itr_ck = path( "c:" );
+ BOOST_CHECK( *itr_ck.begin() == std::string( "c:" ) );
+ BOOST_CHECK( next( itr_ck.begin() ) == itr_ck.end() );
+ BOOST_CHECK( prior( itr_ck.end() ) == itr_ck.begin() );
+ BOOST_CHECK( *prior( itr_ck.end() ) == std::string( "c:" ) );
+
+ itr_ck = path( "c:/" );
+ BOOST_CHECK( *itr_ck.begin() == std::string( "c:" ) );
+ BOOST_CHECK( *next( itr_ck.begin() ) == std::string( "/" ) );
+ BOOST_CHECK( next( next( itr_ck.begin() )) == itr_ck.end() );
+ BOOST_CHECK( prior( prior( itr_ck.end() )) == itr_ck.begin() );
+ BOOST_CHECK( *prior( itr_ck.end() ) == std::string( "/" ) );
+ BOOST_CHECK( *prior( prior( itr_ck.end() )) == std::string( "c:" ) );
+
+ itr_ck = path( "c:foo" );
+ BOOST_CHECK( *itr_ck.begin() == std::string( "c:" ) );
+ BOOST_CHECK( *next( itr_ck.begin() ) == std::string( "foo" ) );
+ BOOST_CHECK( next(next( itr_ck.begin() )) == itr_ck.end() );
+ BOOST_CHECK( prior(prior( itr_ck.end() )) == itr_ck.begin() );
+ BOOST_CHECK( *prior( itr_ck.end() ) == std::string( "foo" ) );
+ BOOST_CHECK( *prior(prior( itr_ck.end() )) == std::string( "c:" ) );
+
+ itr_ck = path( "c:/foo" );
+ BOOST_CHECK( *itr_ck.begin() == std::string( "c:" ) );
+ BOOST_CHECK( *next( itr_ck.begin() ) == std::string( "/" ) );
+ BOOST_CHECK( *next( next( itr_ck.begin() )) == std::string( "foo" ) );
+ BOOST_CHECK( next( next( next( itr_ck.begin() ))) == itr_ck.end() );
+ BOOST_CHECK( prior( prior( prior( itr_ck.end() ))) == itr_ck.begin() );
+ BOOST_CHECK( *prior( itr_ck.end() ) == std::string( "foo" ) );
+ BOOST_CHECK( *prior( prior( itr_ck.end() )) == std::string( "/" ) );
+ BOOST_CHECK( *prior( prior( prior( itr_ck.end() ))) == std::string( "c:" ) );
+
+ itr_ck = path( "//net" );
+ BOOST_CHECK( *itr_ck.begin() == std::string( "//net" ) );
+ BOOST_CHECK( next( itr_ck.begin() ) == itr_ck.end() );
+ BOOST_CHECK( prior( itr_ck.end() ) == itr_ck.begin() );
+ BOOST_CHECK( *prior( itr_ck.end() ) == std::string( "//net" ) );
+
+ itr_ck = path( "//net/" );
+ CHECK_EQUAL( *itr_ck.begin(), "//net" );
+ CHECK_EQUAL( *next( itr_ck.begin() ), "/" );
+ BOOST_CHECK( next(next( itr_ck.begin() )) == itr_ck.end() );
+ BOOST_CHECK( prior(prior( itr_ck.end() )) == itr_ck.begin() );
+ CHECK_EQUAL( *prior( itr_ck.end() ), "/" );
+ CHECK_EQUAL( *prior(prior( itr_ck.end() )), "//net" );
+
+ itr_ck = path( "//net/foo" );
+ BOOST_CHECK( *itr_ck.begin() == std::string( "//net" ) );
+ BOOST_CHECK( *next( itr_ck.begin() ) == std::string( "/" ) );
+ BOOST_CHECK( *next(next( itr_ck.begin() )) == std::string( "foo" ) );
+ BOOST_CHECK( next(next(next( itr_ck.begin() ))) == itr_ck.end() );
+ BOOST_CHECK( prior(prior(prior( itr_ck.end() ))) == itr_ck.begin() );
+ BOOST_CHECK( *prior( itr_ck.end() ) == std::string( "foo" ) );
+ BOOST_CHECK( *prior(prior( itr_ck.end() )) == std::string( "/" ) );
+ BOOST_CHECK( *prior(prior(prior( itr_ck.end() ))) == std::string( "//net" ) );
+
+ itr_ck = path( "prn:" );
+ BOOST_CHECK( *itr_ck.begin() == std::string( "prn:" ) );
+ BOOST_CHECK( next( itr_ck.begin() ) == itr_ck.end() );
+ BOOST_CHECK( prior( itr_ck.end() ) == itr_ck.begin() );
+ BOOST_CHECK( *prior( itr_ck.end() ) == std::string( "prn:" ) );
+ }
+ else
+ {
+ itr_ck = "///";
+ itr = itr_ck.begin();
+ CHECK_EQUAL( *itr, "/" );
+ BOOST_CHECK( ++itr == itr_ck.end() );
+ }
+ }
+
+ // non_member_tests ------------------------------------------------------//
+
+ void non_member_tests()
+ {
+ std::cout << "non_member_tests..." << std::endl;
+
+ // test non-member functions, particularly operator overloads
+
+ path e, e2;
+ std::string es, es2;
+ char ecs[] = "";
+ char ecs2[] = "";
+
+ char acs[] = "a";
+ std::string as(acs);
+ path a( as );
+
+ char acs2[] = "a";
+ std::string as2(acs2);
+ path a2( as2 );
+
+ char bcs[] = "b";
+ std::string bs(bcs);
+ path b( bs );
+
+ // swap
+ a.swap( b );
+ BOOST_CHECK( a.string() == "b" );
+ BOOST_CHECK( b.string() == "a" );
+ fs::swap( a, b );
+ BOOST_CHECK( a.string() == "a" );
+ BOOST_CHECK( b.string() == "b" );
+
+ // probe operator /
+ PATH_CHECK( path("") / ".", "." );
+ PATH_CHECK( path("") / "..", ".." );
+ if ( platform == "Windows" )
+ {
+ BOOST_CHECK( (b / a).string() == "b\\a" );
+ BOOST_CHECK( (bs / a).string() == "b\\a" );
+ BOOST_CHECK( (bcs / a).string() == "b\\a" );
+ BOOST_CHECK( (b / as).string() == "b\\a" );
+ BOOST_CHECK( (b / acs).string() == "b\\a" );
+ PATH_CHECK( path("a") / "b", "a\\b" );
+ PATH_CHECK( path("..") / "", "..\\" );
+ PATH_CHECK( path("foo") / path("bar"), "foo\\bar" ); // path arg
+ PATH_CHECK( path("foo") / "bar", "foo\\bar" ); // const char * arg
+ PATH_CHECK( path("foo") / path("woo/bar").filename(), "foo\\bar" ); // const std::string & arg
+ PATH_CHECK( "foo" / path("bar"), "foo\\bar" );
+ PATH_CHECK( path("..") / ".." , "..\\.." );
+ PATH_CHECK( path("/") / ".." , "/.." );
+ PATH_CHECK( path("/..") / ".." , "/..\\.." );
+ PATH_CHECK( path("..") / "foo" , "..\\foo" );
+ PATH_CHECK( path("foo") / ".." , "foo\\.." );
+ PATH_CHECK( path("..") / "f" , "..\\f" );
+ PATH_CHECK( path("/..") / "f" , "/..\\f" );
+ PATH_CHECK( path("f") / ".." , "f\\.." );
+ PATH_CHECK( path("foo") / ".." / ".." , "foo\\..\\.." );
+ PATH_CHECK( path("foo") / ".." / ".." / ".." , "foo\\..\\..\\.." );
+ PATH_CHECK( path("f") / ".." / "b" , "f\\..\\b" );
+ PATH_CHECK( path("foo") / ".." / "bar" , "foo\\..\\bar" );
+ PATH_CHECK( path("foo") / "bar" / ".." , "foo\\bar\\.." );
+ PATH_CHECK( path("foo") / "bar" / ".." / "..", "foo\\bar\\..\\.." );
+ PATH_CHECK( path("foo") / "bar" / ".." / "blah", "foo\\bar\\..\\blah" );
+ PATH_CHECK( path("f") / "b" / ".." , "f\\b\\.." );
+ PATH_CHECK( path("f") / "b" / ".." / "a", "f\\b\\..\\a" );
+ PATH_CHECK( path("foo") / "bar" / "blah" / ".." / "..", "foo\\bar\\blah\\..\\.." );
+ PATH_CHECK( path("foo") / "bar" / "blah" / ".." / ".." / "bletch", "foo\\bar\\blah\\..\\..\\bletch" );
+
+ PATH_CHECK( path(".") / "foo", ".\\foo" );
+ PATH_CHECK( path(".") / "..", ".\\.." );
+ PATH_CHECK( path("foo") / ".", "foo\\." );
+ PATH_CHECK( path("..") / ".", "..\\." );
+ PATH_CHECK( path(".") / ".", ".\\." );
+ PATH_CHECK( path(".") / "." / ".", ".\\.\\." );
+ PATH_CHECK( path(".") / "foo" / ".", ".\\foo\\." );
+ PATH_CHECK( path("foo") / "." / "bar", "foo\\.\\bar" );
+ PATH_CHECK( path("foo") / "." / ".", "foo\\.\\." );
+ PATH_CHECK( path("foo") / "." / "..", "foo\\.\\.." );
+ PATH_CHECK( path(".") / "." / "..", ".\\.\\.." );
+ PATH_CHECK( path(".") / ".." / ".", ".\\..\\." );
+ PATH_CHECK( path("..") / "." / ".", "..\\.\\." );
+ }
+ else
+ {
+ BOOST_CHECK( (b / a).string() == "b/a" );
+ BOOST_CHECK( (bs / a).string() == "b/a" );
+ BOOST_CHECK( (bcs / a).string() == "b/a" );
+ BOOST_CHECK( (b / as).string() == "b/a" );
+ BOOST_CHECK( (b / acs).string() == "b/a" );
+ PATH_CHECK( path("a") / "b", "a/b" );
+ PATH_CHECK( path("..") / "", ".." );
+ PATH_CHECK( path("") / "..", ".." );
+ PATH_CHECK( path("foo") / path("bar"), "foo/bar" ); // path arg
+ PATH_CHECK( path("foo") / "bar", "foo/bar" ); // const char * arg
+ PATH_CHECK( path("foo") / path("woo/bar").filename(), "foo/bar" ); // const std::string & arg
+ PATH_CHECK( "foo" / path("bar"), "foo/bar" );
+ PATH_CHECK( path("..") / ".." , "../.." );
+ PATH_CHECK( path("/") / ".." , "/.." );
+ PATH_CHECK( path("/..") / ".." , "/../.." );
+ PATH_CHECK( path("..") / "foo" , "../foo" );
+ PATH_CHECK( path("foo") / ".." , "foo/.." );
+ PATH_CHECK( path("..") / "f" , "../f" );
+ PATH_CHECK( path("/..") / "f" , "/../f" );
+ PATH_CHECK( path("f") / ".." , "f/.." );
+ PATH_CHECK( path("foo") / ".." / ".." , "foo/../.." );
+ PATH_CHECK( path("foo") / ".." / ".." / ".." , "foo/../../.." );
+ PATH_CHECK( path("f") / ".." / "b" , "f/../b" );
+ PATH_CHECK( path("foo") / ".." / "bar" , "foo/../bar" );
+ PATH_CHECK( path("foo") / "bar" / ".." , "foo/bar/.." );
+ PATH_CHECK( path("foo") / "bar" / ".." / "..", "foo/bar/../.." );
+ PATH_CHECK( path("foo") / "bar" / ".." / "blah", "foo/bar/../blah" );
+ PATH_CHECK( path("f") / "b" / ".." , "f/b/.." );
+ PATH_CHECK( path("f") / "b" / ".." / "a", "f/b/../a" );
+ PATH_CHECK( path("foo") / "bar" / "blah" / ".." / "..", "foo/bar/blah/../.." );
+ PATH_CHECK( path("foo") / "bar" / "blah" / ".." / ".." / "bletch", "foo/bar/blah/../../bletch" );
+
+ PATH_CHECK( path(".") / "foo", "./foo" );
+ PATH_CHECK( path(".") / "..", "./.." );
+ PATH_CHECK( path("foo") / ".", "foo/." );
+ PATH_CHECK( path("..") / ".", "../." );
+ PATH_CHECK( path(".") / ".", "./." );
+ PATH_CHECK( path(".") / "." / ".", "././." );
+ PATH_CHECK( path(".") / "foo" / ".", "./foo/." );
+ PATH_CHECK( path("foo") / "." / "bar", "foo/./bar" );
+ PATH_CHECK( path("foo") / "." / ".", "foo/./." );
+ PATH_CHECK( path("foo") / "." / "..", "foo/./.." );
+ PATH_CHECK( path(".") / "." / "..", "././.." );
+ PATH_CHECK( path(".") / ".." / ".", "./../." );
+ PATH_CHECK( path("..") / "." / ".", ".././." );
+ }
+
+ // probe operator <
+ BOOST_CHECK( !(e < e2) );
+ BOOST_CHECK( !(es < e2) );
+ BOOST_CHECK( !(ecs < e2) );
+ BOOST_CHECK( !(e < es2) );
+ BOOST_CHECK( !(e < ecs2) );
+
+ BOOST_CHECK( e < a );
+ BOOST_CHECK( es < a );
+ BOOST_CHECK( ecs < a );
+ BOOST_CHECK( e < as );
+ BOOST_CHECK( e < acs );
+
+ BOOST_CHECK( a < b );
+ BOOST_CHECK( as < b );
+ BOOST_CHECK( acs < b );
+ BOOST_CHECK( a < bs );
+ BOOST_CHECK( a < bcs );
+
+ BOOST_CHECK( !(a < a2) );
+ BOOST_CHECK( !(as < a2) );
+ BOOST_CHECK( !(acs < a2) );
+ BOOST_CHECK( !(a < as2) );
+ BOOST_CHECK( !(a < acs2) );
+
+ // make sure basic_path overloads don't conflict with std::string overloads
+
+ BOOST_CHECK( !(as < as) );
+ BOOST_CHECK( !(as < acs) );
+ BOOST_CHECK( !(acs < as) );
+
+ // reality check character set is as expected
+ BOOST_CHECK( std::string("a.b") < std::string("a/b") );
+ // verify compare is actually lexicographical
+ BOOST_CHECK( path("a/b") < path("a.b") );
+
+ // make sure the derivative operators also work
+ BOOST_CHECK( a == a2 );
+ BOOST_CHECK( as == a2 );
+ BOOST_CHECK( acs == a2 );
+ BOOST_CHECK( a == as2 );
+ BOOST_CHECK( a == acs2 );
+
+ BOOST_CHECK( a != b );
+ BOOST_CHECK( as != b );
+ BOOST_CHECK( acs != b );
+ BOOST_CHECK( a != bs );
+ BOOST_CHECK( a != bcs );
+
+ BOOST_CHECK( b > a );
+ BOOST_CHECK( b > as );
+ BOOST_CHECK( b > acs );
+ BOOST_CHECK( bs > a);
+ BOOST_CHECK( bcs > a);
+
+ BOOST_CHECK( !(a2 > a) );
+ BOOST_CHECK( !(a2 > as) );
+ BOOST_CHECK( !(a2 > acs) );
+ BOOST_CHECK( !(as2 > a) );
+ BOOST_CHECK( !(acs2 > a) );
+
+ BOOST_CHECK( a <= b );
+ BOOST_CHECK( as <= b );
+ BOOST_CHECK( acs <= b );
+ BOOST_CHECK( a <= bs );
+ BOOST_CHECK( a <= bcs );
+
+ BOOST_CHECK( a <= a2 );
+ BOOST_CHECK( as <= a2 );
+ BOOST_CHECK( acs <= a2 );
+ BOOST_CHECK( a <= as2 );
+ BOOST_CHECK( a <= acs2 );
+
+ BOOST_CHECK( b >= a );
+ BOOST_CHECK( bs >= a );
+ BOOST_CHECK( bcs >= a );
+ BOOST_CHECK( b >= as );
+ BOOST_CHECK( b >= acs );
+
+ BOOST_CHECK( a2 >= a );
+ BOOST_CHECK( as2 >= a );
+ BOOST_CHECK( acs2 >= a );
+ BOOST_CHECK( a2 >= as );
+ BOOST_CHECK( a2 >= acs );
+ }
+
+ // query_and_decomposition_tests -----------------------------------------//
+
+ void query_and_decomposition_tests()
+ {
+ std::cout << "query_and_decomposition_tests..." << std::endl;
+
+ path p;
+
+ p = "";
+ BOOST_CHECK( p.relative_path().string() == "" );
+ BOOST_CHECK( p.parent_path().string() == "" );
+ BOOST_CHECK( p.filename() == "" );
+ BOOST_CHECK( p.root_name() == "" );
+ BOOST_CHECK( p.root_directory() == "" );
+ BOOST_CHECK( p.root_path().string() == "" );
+ BOOST_CHECK( !p.has_root_path() );
+ BOOST_CHECK( !p.has_root_name() );
+ BOOST_CHECK( !p.has_root_directory() );
+ BOOST_CHECK( !p.has_relative_path() );
+ BOOST_CHECK( !p.has_filename() );
+ BOOST_CHECK( !p.has_parent_path() );
+ BOOST_CHECK( !p.is_complete() );
+
+ p = "/";
+ BOOST_CHECK( p.relative_path().string() == "" );
+ BOOST_CHECK( p.parent_path().string() == "" );
+ BOOST_CHECK( p.filename() == "/" );
+ BOOST_CHECK( p.root_name() == "" );
+ BOOST_CHECK( p.root_directory() == "/" );
+ BOOST_CHECK( p.root_path().string() == "/" );
+ BOOST_CHECK( p.has_root_path() );
+ BOOST_CHECK( !p.has_root_name() );
+ BOOST_CHECK( p.has_root_directory() );
+ BOOST_CHECK( !p.has_relative_path() );
+ BOOST_CHECK( p.has_filename() );
+ BOOST_CHECK( !p.has_parent_path() );
+ if ( platform == "POSIX" )
+ BOOST_CHECK( p.is_complete() );
+ else
+ BOOST_CHECK( !p.is_complete() );
+
+ p = "//";
+ CHECK_EQUAL( p.relative_path().string(), "" );
+ CHECK_EQUAL( p.parent_path().string(), "" );
+ CHECK_EQUAL( p.filename(), "//" );
+ CHECK_EQUAL( p.root_name(), "//" );
+ CHECK_EQUAL( p.root_directory(), "" );
+ CHECK_EQUAL( p.root_path().string(), "//" );
+ BOOST_CHECK( p.has_root_path() );
+ BOOST_CHECK( p.has_root_name() );
+ BOOST_CHECK( !p.has_root_directory() );
+ BOOST_CHECK( !p.has_relative_path() );
+ BOOST_CHECK( p.has_filename() );
+ BOOST_CHECK( !p.has_parent_path() );
+ BOOST_CHECK( !p.is_complete() );
+
+
+ p = "///";
+ CHECK_EQUAL( p.relative_path().string(), "" );
+ CHECK_EQUAL( p.parent_path().string(), "" );
+ CHECK_EQUAL( p.filename(), "/" );
+ CHECK_EQUAL( p.root_name(), "" );
+ CHECK_EQUAL( p.root_directory(), "/" );
+ CHECK_EQUAL( p.root_path().string(), "/" );
+ BOOST_CHECK( p.has_root_path() );
+ BOOST_CHECK( !p.has_root_name() );
+ BOOST_CHECK( p.has_root_directory() );
+ BOOST_CHECK( !p.has_relative_path() );
+ BOOST_CHECK( p.has_filename() );
+ BOOST_CHECK( !p.has_parent_path() );
+ if ( platform == "POSIX" )
+ BOOST_CHECK( p.is_complete() );
+ else
+ BOOST_CHECK( !p.is_complete() );
+
+ p = ".";
+ BOOST_CHECK( p.relative_path().string() == "." );
+ BOOST_CHECK( p.parent_path().string() == "" );
+ BOOST_CHECK( p.filename() == "." );
+ BOOST_CHECK( p.root_name() == "" );
+ BOOST_CHECK( p.root_directory() == "" );
+ BOOST_CHECK( p.root_path().string() == "" );
+ BOOST_CHECK( !p.has_root_path() );
+ BOOST_CHECK( !p.has_root_name() );
+ BOOST_CHECK( !p.has_root_directory() );
+ BOOST_CHECK( p.has_relative_path() );
+ BOOST_CHECK( p.has_filename() );
+ BOOST_CHECK( !p.has_parent_path() );
+ BOOST_CHECK( !p.is_complete() );
+
+ p = "..";
+ BOOST_CHECK( p.relative_path().string() == ".." );
+ BOOST_CHECK( p.parent_path().string() == "" );
+ BOOST_CHECK( p.filename() == ".." );
+ BOOST_CHECK( p.root_name() == "" );
+ BOOST_CHECK( p.root_directory() == "" );
+ BOOST_CHECK( p.root_path().string() == "" );
+ BOOST_CHECK( !p.has_root_path() );
+ BOOST_CHECK( !p.has_root_name() );
+ BOOST_CHECK( !p.has_root_directory() );
+ BOOST_CHECK( p.has_relative_path() );
+ BOOST_CHECK( p.has_filename() );
+ BOOST_CHECK( !p.has_parent_path() );
+ BOOST_CHECK( !p.is_complete() );
+
+ p = "foo";
+ BOOST_CHECK( p.relative_path().string() == "foo" );
+ BOOST_CHECK( p.parent_path().string() == "" );
+ BOOST_CHECK( p.filename() == "foo" );
+ BOOST_CHECK( p.root_name() == "" );
+ BOOST_CHECK( p.root_directory() == "" );
+ BOOST_CHECK( p.root_path().string() == "" );
+ BOOST_CHECK( !p.has_root_path() );
+ BOOST_CHECK( !p.has_root_name() );
+ BOOST_CHECK( !p.has_root_directory() );
+ BOOST_CHECK( p.has_relative_path() );
+ BOOST_CHECK( p.has_filename() );
+ BOOST_CHECK( !p.has_parent_path() );
+ BOOST_CHECK( !p.is_complete() );
+
+ p = "/foo";
+ CHECK_EQUAL( p.relative_path().string(), "foo" );
+ CHECK_EQUAL( p.parent_path().string(), "/" );
+ CHECK_EQUAL( p.filename(), "foo" );
+ CHECK_EQUAL( p.root_name(), "" );
+ CHECK_EQUAL( p.root_directory(), "/" );
+ CHECK_EQUAL( p.root_path().string(), "/" );
+ BOOST_CHECK( p.has_root_path() );
+ BOOST_CHECK( !p.has_root_name() );
+ BOOST_CHECK( p.has_root_directory() );
+ BOOST_CHECK( p.has_relative_path() );
+ BOOST_CHECK( p.has_filename() );
+ BOOST_CHECK( p.has_parent_path() );
+ if ( platform == "POSIX" )
+ BOOST_CHECK( p.is_complete() );
+ else
+ BOOST_CHECK( !p.is_complete() );
+
+ p = "/foo/";
+ CHECK_EQUAL( p.relative_path().string(), "foo/" );
+ CHECK_EQUAL( p.parent_path().string(), "/foo" );
+ CHECK_EQUAL( p.filename(), "." );
+ CHECK_EQUAL( p.root_name(), "" );
+ CHECK_EQUAL( p.root_directory(), "/" );
+ CHECK_EQUAL( p.root_path().string(), "/" );
+ BOOST_CHECK( p.has_root_path() );
+ BOOST_CHECK( !p.has_root_name() );
+ BOOST_CHECK( p.has_root_directory() );
+ BOOST_CHECK( p.has_relative_path() );
+ BOOST_CHECK( p.has_filename() );
+ BOOST_CHECK( p.has_parent_path() );
+ if ( platform == "POSIX" )
+ BOOST_CHECK( p.is_complete() );
+ else
+ BOOST_CHECK( !p.is_complete() );
+
+ p = "///foo";
+ CHECK_EQUAL( p.relative_path().string(), "foo" );
+ CHECK_EQUAL( p.parent_path().string(), "/" );
+ CHECK_EQUAL( p.filename(), "foo" );
+ CHECK_EQUAL( p.root_name(), "" );
+ CHECK_EQUAL( p.root_directory(), "/" );
+ CHECK_EQUAL( p.root_path().string(), "/" );
+ BOOST_CHECK( p.has_root_path() );
+ BOOST_CHECK( !p.has_root_name() );
+ BOOST_CHECK( p.has_root_directory() );
+ BOOST_CHECK( p.has_relative_path() );
+ BOOST_CHECK( p.has_filename() );
+ BOOST_CHECK( p.has_parent_path() );
+ if ( platform == "POSIX" )
+ BOOST_CHECK( p.is_complete() );
+ else
+ BOOST_CHECK( !p.is_complete() );
+
+ p = "foo/bar";
+ BOOST_CHECK( p.relative_path().string() == "foo/bar" );
+ BOOST_CHECK( p.parent_path().string() == "foo" );
+ BOOST_CHECK( p.filename() == "bar" );
+ BOOST_CHECK( p.root_name() == "" );
+ BOOST_CHECK( p.root_directory() == "" );
+ BOOST_CHECK( p.root_path().string() == "" );
+ BOOST_CHECK( !p.has_root_path() );
+ BOOST_CHECK( !p.has_root_name() );
+ BOOST_CHECK( !p.has_root_directory() );
+ BOOST_CHECK( p.has_relative_path() );
+ BOOST_CHECK( p.has_filename() );
+ BOOST_CHECK( p.has_parent_path() );
+ BOOST_CHECK( !p.is_complete() );
+
+ p = "../foo";
+ BOOST_CHECK( p.relative_path().string() == "../foo" );
+ BOOST_CHECK( p.parent_path().string() == ".." );
+ BOOST_CHECK( p.filename() == "foo" );
+ BOOST_CHECK( p.root_name() == "" );
+ BOOST_CHECK( p.root_directory() == "" );
+ BOOST_CHECK( p.root_path().string() == "" );
+ BOOST_CHECK( !p.has_root_path() );
+ BOOST_CHECK( !p.has_root_name() );
+ BOOST_CHECK( !p.has_root_directory() );
+ BOOST_CHECK( p.has_relative_path() );
+ BOOST_CHECK( p.has_filename() );
+ BOOST_CHECK( p.has_parent_path() );
+ BOOST_CHECK( !p.is_complete() );
+
+ p = "..///foo";
+ CHECK_EQUAL( p.relative_path().string(), "..///foo" );
+ CHECK_EQUAL( p.parent_path().string(), ".." );
+ CHECK_EQUAL( p.filename(), "foo" );
+ CHECK_EQUAL( p.root_name(), "" );
+ CHECK_EQUAL( p.root_directory(), "" );
+ CHECK_EQUAL( p.root_path().string(), "" );
+ BOOST_CHECK( !p.has_root_path() );
+ BOOST_CHECK( !p.has_root_name() );
+ BOOST_CHECK( !p.has_root_directory() );
+ BOOST_CHECK( p.has_relative_path() );
+ BOOST_CHECK( p.has_filename() );
+ BOOST_CHECK( p.has_parent_path() );
+ BOOST_CHECK( !p.is_complete() );
+
+ p = "/foo/bar";
+ BOOST_CHECK( p.relative_path().string() == "foo/bar" );
+ BOOST_CHECK( p.parent_path().string() == "/foo" );
+ BOOST_CHECK( p.filename() == "bar" );
+ BOOST_CHECK( p.root_name() == "" );
+ BOOST_CHECK( p.root_directory() == "/" );
+ BOOST_CHECK( p.root_path().string() == "/" );
+ BOOST_CHECK( p.has_root_path() );
+ BOOST_CHECK( !p.has_root_name() );
+ BOOST_CHECK( p.has_root_directory() );
+ BOOST_CHECK( p.has_relative_path() );
+ BOOST_CHECK( p.has_filename() );
+ BOOST_CHECK( p.has_parent_path() );
+ if ( platform == "POSIX" )
+ BOOST_CHECK( p.is_complete() );
+ else
+ BOOST_CHECK( !p.is_complete() );
+
+ // Both POSIX and Windows allow two leading slashs
+ // (POSIX meaning is implementation defined)
+ PATH_CHECK( path( "//resource" ), "//resource" );
+ PATH_CHECK( path( "//resource/" ), "//resource/" );
+ PATH_CHECK( path( "//resource/foo" ), "//resource/foo" );
+
+ p = path( "//net" );
+ CHECK_EQUAL( p.string(), "//net" );
+ CHECK_EQUAL( p.relative_path().string(), "" );
+ CHECK_EQUAL( p.parent_path().string(), "" );
+ CHECK_EQUAL( p.filename(), "//net" );
+ CHECK_EQUAL( p.root_name(), "//net" );
+ CHECK_EQUAL( p.root_directory(), "" );
+ CHECK_EQUAL( p.root_path().string(), "//net" );
+ BOOST_CHECK( p.has_root_path() );
+ BOOST_CHECK( p.has_root_name() );
+ BOOST_CHECK( !p.has_root_directory() );
+ BOOST_CHECK( !p.has_relative_path() );
+ BOOST_CHECK( p.has_filename() );
+ BOOST_CHECK( !p.has_parent_path() );
+ BOOST_CHECK( !p.is_complete() );
+
+ p = path( "//net/" );
+ BOOST_CHECK( p.relative_path().string() == "" );
+ BOOST_CHECK( p.parent_path().string() == "//net" );
+ BOOST_CHECK( p.filename() == "/" );
+ BOOST_CHECK( p.root_name() == "//net" );
+ BOOST_CHECK( p.root_directory() == "/" );
+ BOOST_CHECK( p.root_path().string() == "//net/" );
+ BOOST_CHECK( p.has_root_path() );
+ BOOST_CHECK( p.has_root_name() );
+ BOOST_CHECK( p.has_root_directory() );
+ BOOST_CHECK( !p.has_relative_path() );
+ BOOST_CHECK( p.has_filename() );
+ BOOST_CHECK( p.has_parent_path() );
+ BOOST_CHECK( p.is_complete() );
+
+ p = path( "//net/foo" );
+ BOOST_CHECK( p.relative_path().string() == "foo" );
+ BOOST_CHECK( p.parent_path().string() == "//net/" );
+ BOOST_CHECK( p.filename() == "foo" );
+ BOOST_CHECK( p.root_name() == "//net" );
+ BOOST_CHECK( p.root_directory() == "/" );
+ BOOST_CHECK( p.root_path().string() == "//net/" );
+ BOOST_CHECK( p.has_root_path() );
+ BOOST_CHECK( p.has_root_name() );
+ BOOST_CHECK( p.has_root_directory() );
+ BOOST_CHECK( p.has_relative_path() );
+ BOOST_CHECK( p.has_filename() );
+ BOOST_CHECK( p.has_parent_path() );
+ BOOST_CHECK( p.is_complete() );
+
+ p = path( "//net///foo" );
+ CHECK_EQUAL( p.relative_path().string(), "foo" );
+ CHECK_EQUAL( p.parent_path().string(), "//net/" );
+ CHECK_EQUAL( p.filename(), "foo" );
+ CHECK_EQUAL( p.root_name(), "//net" );
+ CHECK_EQUAL( p.root_directory(), "/" );
+ CHECK_EQUAL( p.root_path().string(), "//net/" );
+ BOOST_CHECK( p.has_root_path() );
+ BOOST_CHECK( p.has_root_name() );
+ BOOST_CHECK( p.has_root_directory() );
+ BOOST_CHECK( p.has_relative_path() );
+ BOOST_CHECK( p.has_filename() );
+ BOOST_CHECK( p.has_parent_path() );
+ BOOST_CHECK( p.is_complete() );
+
+ if ( platform == "Windows" )
+ {
+
+ p = path( "c:" );
+ BOOST_CHECK( p.relative_path().string() == "" );
+ BOOST_CHECK( p.parent_path().string() == "" );
+ BOOST_CHECK( p.filename() == "c:" );
+ BOOST_CHECK( p.root_name() == "c:" );
+ BOOST_CHECK( p.root_directory() == "" );
+ BOOST_CHECK( p.root_path().string() == "c:" );
+ BOOST_CHECK( p.has_root_path() );
+ BOOST_CHECK( p.has_root_name() );
+ BOOST_CHECK( !p.has_root_directory() );
+ BOOST_CHECK( !p.has_relative_path() );
+ BOOST_CHECK( p.has_filename() );
+ BOOST_CHECK( !p.has_parent_path() );
+ BOOST_CHECK( !p.is_complete() );
+
+ p = path( "c:foo" );
+ BOOST_CHECK( p.relative_path().string() == "foo" );
+ BOOST_CHECK( p.parent_path().string() == "c:" );
+ BOOST_CHECK( p.filename() == "foo" );
+ BOOST_CHECK( p.root_name() == "c:" );
+ BOOST_CHECK( p.root_directory() == "" );
+ BOOST_CHECK( p.root_path().string() == "c:" );
+ BOOST_CHECK( p.has_root_path() );
+ BOOST_CHECK( p.has_root_name() );
+ BOOST_CHECK( !p.has_root_directory() );
+ BOOST_CHECK( p.has_relative_path() );
+ BOOST_CHECK( p.has_filename() );
+ BOOST_CHECK( p.has_parent_path() );
+ BOOST_CHECK( !p.is_complete() );
+
+ p = path( "c:/" );
+ BOOST_CHECK( p.relative_path().string() == "" );
+ BOOST_CHECK( p.parent_path().string() == "c:" );
+ BOOST_CHECK( p.filename() == "/" );
+ BOOST_CHECK( p.root_name() == "c:" );
+ BOOST_CHECK( p.root_directory() == "/" );
+ BOOST_CHECK( p.root_path().string() == "c:/" );
+ BOOST_CHECK( p.has_root_path() );
+ BOOST_CHECK( p.has_root_name() );
+ BOOST_CHECK( p.has_root_directory() );
+ BOOST_CHECK( !p.has_relative_path() );
+ BOOST_CHECK( p.has_filename() );
+ BOOST_CHECK( p.has_parent_path() );
+ BOOST_CHECK( p.is_complete() );
+
+ p = path( "c:.." );
+ BOOST_CHECK( p.relative_path().string() == ".." );
+ BOOST_CHECK( p.parent_path().string() == "c:" );
+ BOOST_CHECK( p.filename() == ".." );
+ BOOST_CHECK( p.root_name() == "c:" );
+ BOOST_CHECK( p.root_directory() == "" );
+ BOOST_CHECK( p.root_path().string() == "c:" );
+ BOOST_CHECK( p.has_root_path() );
+ BOOST_CHECK( p.has_root_name() );
+ BOOST_CHECK( !p.has_root_directory() );
+ BOOST_CHECK( p.has_relative_path() );
+ BOOST_CHECK( p.has_filename() );
+ BOOST_CHECK( p.has_parent_path() );
+ BOOST_CHECK( !p.is_complete() );
+
+ p = path( "c:/foo" );
+ CHECK_EQUAL( p.relative_path().string(), "foo" );
+ CHECK_EQUAL( p.parent_path().string(), "c:/" );
+ CHECK_EQUAL( p.filename(), "foo" );
+ CHECK_EQUAL( p.root_name(), "c:" );
+ CHECK_EQUAL( p.root_directory(), "/" );
+ CHECK_EQUAL( p.root_path().string(), "c:/" );
+ BOOST_CHECK( p.has_root_path() );
+ BOOST_CHECK( p.has_root_name() );
+ BOOST_CHECK( p.has_root_directory() );
+ BOOST_CHECK( p.has_relative_path() );
+ BOOST_CHECK( p.has_filename() );
+ BOOST_CHECK( p.has_parent_path() );
+ BOOST_CHECK( p.is_complete() );
+
+ p = path( "c://foo" );
+ CHECK_EQUAL( p.relative_path().string(), "foo" );
+ CHECK_EQUAL( p.parent_path().string(), "c:/" );
+ CHECK_EQUAL( p.filename(), "foo" );
+ CHECK_EQUAL( p.root_name(), "c:" );
+ CHECK_EQUAL( p.root_directory(), "/" );
+ CHECK_EQUAL( p.root_path().string(), "c:/" );
+ BOOST_CHECK( p.has_root_path() );
+ BOOST_CHECK( p.has_root_name() );
+ BOOST_CHECK( p.has_root_directory() );
+ BOOST_CHECK( p.has_relative_path() );
+ BOOST_CHECK( p.has_filename() );
+ BOOST_CHECK( p.has_parent_path() );
+ BOOST_CHECK( p.is_complete() );
+
+ p = path( "c:\\foo\\bar" );
+ CHECK_EQUAL( p.relative_path().string(), "foo\\bar" );
+ CHECK_EQUAL( p.parent_path().string(), "c:\\foo" );
+ CHECK_EQUAL( p.filename(), "bar" );
+ CHECK_EQUAL( p.root_name(), "c:" );
+ CHECK_EQUAL( p.root_directory(), "\\" );
+ CHECK_EQUAL( p.root_path().string(), "c:\\" );
+ BOOST_CHECK( p.has_root_path() );
+ BOOST_CHECK( p.has_root_name() );
+ BOOST_CHECK( p.has_root_directory() );
+ BOOST_CHECK( p.has_relative_path() );
+ BOOST_CHECK( p.has_filename() );
+ BOOST_CHECK( p.has_parent_path() );
+ BOOST_CHECK( p.is_complete() );
+
+ p = path( "prn:" );
+ BOOST_CHECK( p.relative_path().string() == "" );
+ BOOST_CHECK( p.parent_path().string() == "" );
+ BOOST_CHECK( p.filename() == "prn:" );
+ BOOST_CHECK( p.root_name() == "prn:" );
+ BOOST_CHECK( p.root_directory() == "" );
+ BOOST_CHECK( p.root_path().string() == "prn:" );
+ BOOST_CHECK( p.has_root_path() );
+ BOOST_CHECK( p.has_root_name() );
+ BOOST_CHECK( !p.has_root_directory() );
+ BOOST_CHECK( !p.has_relative_path() );
+ BOOST_CHECK( p.has_filename() );
+ BOOST_CHECK( !p.has_parent_path() );
+ BOOST_CHECK( !p.is_complete() );
+
+ p = path( "\\\\net\\\\\\foo" );
+ CHECK_EQUAL( p.relative_path().string(), "foo" );
+ CHECK_EQUAL( p.parent_path().string(), "\\\\net\\" );
+ CHECK_EQUAL( p.filename(), "foo" );
+ CHECK_EQUAL( p.root_name(), "\\\\net" );
+ CHECK_EQUAL( p.root_directory(), "\\" );
+ CHECK_EQUAL( p.root_path().string(), "\\\\net\\" );
+ BOOST_CHECK( p.has_root_path() );
+ BOOST_CHECK( p.has_root_name() );
+ BOOST_CHECK( p.has_root_directory() );
+ BOOST_CHECK( p.has_relative_path() );
+ BOOST_CHECK( p.has_filename() );
+ BOOST_CHECK( p.has_parent_path() );
+ BOOST_CHECK( p.is_complete() );
+ } // Windows
+
+ else
+ { // POSIX
+ DIR_CHECK( path( "/foo/bar/" ), "/foo/bar/" );
+ DIR_CHECK( path( "//foo//bar//" ), "//foo//bar//" );
+ DIR_CHECK( path( "///foo///bar///" ), "///foo///bar///" );
+
+ p = path( "/usr/local/bin:/usr/bin:/bin" );
+ BOOST_CHECK( p.string() == "/usr/local/bin:/usr/bin:/bin" );
+ } // POSIX
+ }
+
+ // construction_tests ----------------------------------------------------//
+
+ void construction_tests()
+ {
+ std::cout << "construction_tests..." << std::endl;
+
+ PATH_CHECK( "", "" );
+
+ PATH_CHECK( "foo", "foo" );
+ PATH_CHECK( "f", "f" );
+
+ PATH_CHECK( "foo/", "foo/" );
+ PATH_CHECK( "f/", "f/" );
+ PATH_CHECK( "foo/..", "foo/.." );
+ PATH_CHECK( "foo/../", "foo/../" );
+ PATH_CHECK( "foo/bar/../..", "foo/bar/../.." );
+ PATH_CHECK( "foo/bar/../../", "foo/bar/../../" );
+ PATH_CHECK( path("") / "foo", "foo" );
+ PATH_CHECK( path("") / "foo/", "foo/" );
+ PATH_CHECK( path("foo") / "", "foo\\" );
+ PATH_CHECK( path( "/" ), "/" );
+ PATH_CHECK( path( "/" ) / "", "/" );
+ PATH_CHECK( path( "/f" ), "/f" );
+
+ PATH_CHECK( "/foo", "/foo" );
+ PATH_CHECK( path("") / "/foo", "/foo" );
+ PATH_CHECK( path("/foo") / "", "/foo\\" );
+ DIR_CHECK( path( "/foo/bar/" ), "/foo/bar/" );
+ DIR_CHECK( path( "//foo//bar//" ), "//foo//bar//" );
+ DIR_CHECK( path( "///foo///bar///" ), "///foo///bar///" );
+ DIR_CHECK( path( "\\/foo\\/bar\\/" ), "\\/foo\\/bar\\/" );
+ DIR_CHECK( path( "\\//foo\\//bar\\//" ), "\\//foo\\//bar\\//" );
+
+ if ( platform == "Windows" )
+ {
+ PATH_CHECK( path("c:") / "foo", "c:foo" );
+ PATH_CHECK( path("c:") / "/foo", "c:/foo" );
+
+ DIR_CHECK( path( "\\foo\\bar\\" ), "\\foo\\bar\\" );
+ DIR_CHECK( path( "\\\\foo\\\\bar\\\\" ), "\\\\foo\\\\bar\\\\" );
+ DIR_CHECK( path( "\\\\\\foo\\\\\\bar\\\\\\" ), "\\\\\\foo\\\\\\bar\\\\\\" );
+
+ PATH_CHECK( path( "\\" ), "\\" );
+ PATH_CHECK( path( "\\f" ), "\\f" );
+ PATH_CHECK( path( "\\foo" ), "\\foo" );
+ PATH_CHECK( path( "foo\\bar" ), "foo\\bar" );
+ PATH_CHECK( path( "foo bar" ), "foo bar" );
+ PATH_CHECK( path( "c:" ), "c:" );
+ PATH_CHECK( path( "c:/" ), "c:/" );
+ PATH_CHECK( path( "c:." ), "c:." );
+ PATH_CHECK( path( "c:./foo" ), "c:./foo" );
+ PATH_CHECK( path( "c:.\\foo" ), "c:.\\foo" );
+ PATH_CHECK( path( "c:.." ), "c:.." );
+ PATH_CHECK( path( "c:/." ), "c:/." );
+ PATH_CHECK( path( "c:/.." ), "c:/.." );
+ PATH_CHECK( path( "c:/../" ), "c:/../" );
+ PATH_CHECK( path( "c:\\..\\" ), "c:\\..\\" );
+ PATH_CHECK( path( "c:/../.." ), "c:/../.." );
+ PATH_CHECK( path( "c:/../foo" ), "c:/../foo" );
+ PATH_CHECK( path( "c:\\..\\foo" ), "c:\\..\\foo" );
+ PATH_CHECK( path( "c:../foo" ), "c:../foo" );
+ PATH_CHECK( path( "c:..\\foo" ), "c:..\\foo" );
+ PATH_CHECK( path( "c:/../../foo" ), "c:/../../foo" );
+ PATH_CHECK( path( "c:\\..\\..\\foo" ), "c:\\..\\..\\foo" );
+ PATH_CHECK( path( "c:foo/.." ), "c:foo/.." );
+ PATH_CHECK( path( "c:/foo/.." ), "c:/foo/.." );
+ PATH_CHECK( path( "c:/..foo" ), "c:/..foo" );
+ PATH_CHECK( path( "c:foo" ), "c:foo" );
+ PATH_CHECK( path( "c:/foo" ), "c:/foo" );
+ PATH_CHECK( path( "\\\\netname" ), "\\\\netname" );
+ PATH_CHECK( path( "\\\\netname\\" ), "\\\\netname\\" );
+ PATH_CHECK( path( "\\\\netname\\foo" ), "\\\\netname\\foo" );
+ PATH_CHECK( path( "c:/foo" ), "c:/foo" );
+ PATH_CHECK( path( "prn:" ), "prn:" );
+ }
+ else
+ {
+ }
+
+ PATH_CHECK( "foo/bar", "foo/bar" );
+ PATH_CHECK( "a/b", "a/b" ); // probe for length effects
+ PATH_CHECK( "..", ".." );
+ PATH_CHECK( "../..", "../.." );
+ PATH_CHECK( "/..", "/.." );
+ PATH_CHECK( "/../..", "/../.." );
+ PATH_CHECK( "../foo", "../foo" );
+ PATH_CHECK( "foo/..", "foo/.." );
+ PATH_CHECK( path( "foo/..bar"), "foo/..bar" );
+ PATH_CHECK( "../f", "../f" );
+ PATH_CHECK( "/../f", "/../f" );
+ PATH_CHECK( "f/..", "f/.." );
+ PATH_CHECK( "foo/../..", "foo/../.." );
+ PATH_CHECK( "foo/../../..", "foo/../../.." );
+ PATH_CHECK( "foo/../bar", "foo/../bar" );
+ PATH_CHECK( "foo/bar/..", "foo/bar/.." );
+ PATH_CHECK( "foo/bar/../..", "foo/bar/../.." );
+ PATH_CHECK( "foo/bar/../blah", "foo/bar/../blah" );
+ PATH_CHECK( "f/../b", "f/../b" );
+ PATH_CHECK( "f/b/..", "f/b/.." );
+ PATH_CHECK( "f/b/../a", "f/b/../a" );
+ PATH_CHECK( "foo/bar/blah/../..", "foo/bar/blah/../.." );
+ PATH_CHECK( "foo/bar/blah/../../bletch", "foo/bar/blah/../../bletch" );
+ PATH_CHECK( "...", "..." );
+ PATH_CHECK( "....", "...." );
+ PATH_CHECK( "foo/...", "foo/..." );
+ PATH_CHECK( "abc.", "abc." );
+ PATH_CHECK( "abc..", "abc.." );
+ PATH_CHECK( "foo/abc.", "foo/abc." );
+ PATH_CHECK( "foo/abc..", "foo/abc.." );
+
+ PATH_CHECK( path(".abc"), ".abc" );
+ PATH_CHECK( "a.c", "a.c" );
+ PATH_CHECK( path("..abc"), "..abc" );
+ PATH_CHECK( "a..c", "a..c" );
+ PATH_CHECK( path("foo/.abc"), "foo/.abc" );
+ PATH_CHECK( "foo/a.c", "foo/a.c" );
+ PATH_CHECK( path("foo/..abc"), "foo/..abc" );
+ PATH_CHECK( "foo/a..c", "foo/a..c" );
+
+ PATH_CHECK( ".", "." );
+ PATH_CHECK( "./foo", "./foo" );
+ PATH_CHECK( "./..", "./.." );
+ PATH_CHECK( "./../foo", "./../foo" );
+ PATH_CHECK( "foo/.", "foo/." );
+ PATH_CHECK( "../.", "../." );
+ PATH_CHECK( "./.", "./." );
+ PATH_CHECK( "././.", "././." );
+ PATH_CHECK( "./foo/.", "./foo/." );
+ PATH_CHECK( "foo/./bar", "foo/./bar" );
+ PATH_CHECK( "foo/./.", "foo/./." );
+ PATH_CHECK( "foo/./..", "foo/./.." );
+ PATH_CHECK( "foo/./../bar", "foo/./../bar" );
+ PATH_CHECK( "foo/../.", "foo/../." );
+ PATH_CHECK( "././..", "././.." );
+ PATH_CHECK( "./../.", "./../." );
+ PATH_CHECK( ".././.", ".././." );
+ }
+
+} // unnamed namespace
+
+int test_main( int, char*[] )
+{
+ // The choice of platform is make at runtime rather than compile-time
+ // so that compile errors for all platforms will be detected even though
+ // only the current platform is runtime tested.
+ platform = ( platform == "Win32" || platform == "Win64" || platform == "Cygwin" )
+ ? "Windows"
+ : "POSIX";
+ std::cout << "Platform is " << platform << '\n';
+
+ BOOST_CHECK( p1.string() != p3.string() );
+ p3 = p2;
+ BOOST_CHECK( p1.string() == p3.string() );
+
+ path p4( "foobar" );
+ BOOST_CHECK( p4.string() == "foobar" );
+ p4 = p4; // self-assignment
+ BOOST_CHECK( p4.string() == "foobar" );
+
+ construction_tests();
+ overload_tests();
+ query_and_decomposition_tests();
+ iterator_tests();
+ non_member_tests();
+ exception_tests();
+
+ // verify deprecated names still available
+
+# ifndef BOOST_FILESYSTEM_NO_DEPRECATED
+
+ p1.branch_path();
+ p1.leaf();
+ path p_remove_leaf;
+ p_remove_leaf.remove_leaf();
+
+# endif
+
+ std::string s1( "//:somestring" ); // this used to be treated specially
+
+# ifndef BOOST_NO_MEMBER_TEMPLATES
+
+ // check the path member templates
+ p5.assign( s1.begin(), s1.end() );
+
+ PATH_CHECK( p5, "//:somestring" );
+ p5 = s1;
+ PATH_CHECK( p5, "//:somestring" );
+
+ char c0 = 'a';
+ p5.assign( &c0, &c0 );
+ PATH_CHECK( p5, "" );
+ p5 /= "";
+ PATH_CHECK( p5, "" );
+ p5 /= "foo/bar";
+ PATH_CHECK( p5, "foo/bar" );
+ p5 /= "";
+ PATH_CHECK( p5, "foo/bar\\" );
+ p5.append( &c0, &c0 );
+ PATH_CHECK( p5, "foo/bar\\" );
+ p5 /= "";
+ PATH_CHECK( p5, "foo/bar\\" );
+ char bf[]= "bar/foo";
+ p5.assign( bf, bf + sizeof(bf) );
+ PATH_CHECK( p5, bf );
+ p5.append( bf, bf + sizeof(bf) );
+ PATH_CHECK( p5, "bar/foo\\bar/foo" );
+
+ // this code, courtesy of David Whetstone, detected a now fixed bug that
+ // derefereced the end iterator (assuming debug build with checked itors)
+ std::vector<char> v1;
+ p5.assign( v1.begin(), v1.end() );
+ std::string s2( v1.begin(), v1.end() );
+ PATH_CHECK( p5, s2 );
+ p5.assign( s1.begin(), s1.begin() + 1 );
+ PATH_CHECK( p5, "/" );
+
+# endif
+
+ BOOST_CHECK( p1 != p4 );
+ BOOST_CHECK( p1.string() == p2.string() );
+ BOOST_CHECK( p1.string() == p3.string() );
+ BOOST_CHECK( path( "foo" ).filename() == "foo" );
+ BOOST_CHECK( path( "foo" ).parent_path().string() == "" );
+ BOOST_CHECK( p1.filename() == "fum" );
+ BOOST_CHECK( p1.parent_path().string() == "fe/fi/fo" );
+ BOOST_CHECK( path( "" ).empty() == true );
+ BOOST_CHECK( path( "foo" ).empty() == false );
+
+
+// extension() tests
+
+ BOOST_CHECK( path("a/b").extension() == "" );
+ BOOST_CHECK( path("a/b.txt").extension() == ".txt" );
+ BOOST_CHECK( path("a/b.").extension() == "." );
+ BOOST_CHECK( path("a.b.c").extension() == ".c" );
+ BOOST_CHECK( path("a.b.c.").extension() == "." );
+ BOOST_CHECK( path("").extension() == "" );
+ BOOST_CHECK( path("a/").extension() == "." );
+
+// stem() tests
+
+ BOOST_CHECK( path("b").stem() == "b" );
+ BOOST_CHECK( path("a/b.txt").stem() == "b" );
+ BOOST_CHECK( path("a/b.").stem() == "b" );
+ BOOST_CHECK( path("a.b.c").stem() == "a.b" );
+ BOOST_CHECK( path("a.b.c.").stem() == "a.b.c" );
+ BOOST_CHECK( path("").stem() == "" );
+
+//// replace_extension() tests
+//
+// BOOST_CHECK( path("a.txt").replace_extension("").string() == "a" );
+// BOOST_CHECK( path("a.txt").replace_extension(".").string() == "a." );
+// BOOST_CHECK( path("a.txt").replace_extension(".tex").string() == "a.tex" );
+// BOOST_CHECK( path("a.txt").replace_extension("tex").string() == "a.tex" );
+// BOOST_CHECK( path("a.").replace_extension(".tex").string() == "a.tex" );
+// BOOST_CHECK( path("a.").replace_extension("tex").string() == "a.tex" );
+// BOOST_CHECK( path("a").replace_extension(".txt").string() == "a.txt" );
+// BOOST_CHECK( path("a").replace_extension("txt").string() == "a.txt" );
+// BOOST_CHECK( path("a.b.txt" ).replace_extension(".tex").string() == "a.b.tex" );
+// BOOST_CHECK( path("a.b.txt" ).replace_extension("tex").string() == "a.b.tex" );
+// // see the rationale in html docs for explanation why this works
+// BOOST_CHECK( path("").replace_extension(".png").string() == ".png" );
+
+ // inserter and extractor tests
+# if !defined( BOOST_MSVC ) || BOOST_MSVC > 1300 // bypass VC++ 7.0 and earlier
+ std::cout << "\nInserter and extractor test...";
+ std::stringstream ss;
+ ss << fs::path( "foo/bar" ) << std::endl;
+ fs::path round_trip;
+ ss >> round_trip;
+ BOOST_CHECK( round_trip.string() == "foo/bar" );
+ std::cout << round_trip.string() << "..." << round_trip << " complete\n";
+# endif
+
+ std::cout << errors << " errors detected\n";
+
+ return errors;
+}
Added: sandbox/filesystem-v3/libs/filesystem/v3/test/path_unit_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/test/path_unit_test.cpp 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,545 @@
+// filesystem3 path_unit_test.cpp ---------------------------------------- //
+
+// Copyright Beman Dawes 2008
+
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See library home page at http://www.boost.org/libs/filesystem
+
+// ------------------------------------------------------------------------ //
+//
+// The purpose of this test is to ensure that each function in the public
+// interface can be called with arguments of the appropriate types. It does
+// not attempt to verify that the full range of values for each argument
+// are processed correctly.
+//
+// For full functionality tests, including probes with many different argument
+// values, see path_test.cpp and other test programs.
+//
+// ------------------------------------------------------------------------ //
+
+#include <boost/filesystem/path.hpp>
+
+#include <iostream>
+#include <string>
+
+namespace fs = boost::filesystem;
+using boost::filesystem::path;
+using std::cout;
+using std::string;
+
+# ifndef BOOST_FILESYSTEM_NARROW_ONLY
+
+ using std::wstring;
+ typedef std::wstring bstring;
+# define BOO_LIT( lit ) L##lit
+# define BOO_COUT std::wcout
+
+# else
+
+ typedef std::string bstring;
+# define BOO_LIT( lit ) lit
+# define BOO_COUT std::cout
+
+# endif
+
+#define CHECK(x) check( x, __FILE__, __LINE__ )
+#define PATH_IS( a, b ) check_path( a, b, __FILE__, __LINE__ )
+#define IS( a,b ) check_equal( a, b, __FILE__, __LINE__ )
+
+// It is convenient for editing to have these ready to copy and paste
+# ifdef BOOST_WINDOWS_PATH
+# else // BOOST_POSIX_PATH
+# endif
+
+# ifndef BOOST_FILESYSTEM_NARROW_ONLY
+# endif // narrow only
+
+namespace
+{
+ int errors;
+
+ boost::system::error_code ec;
+ const boost::system::error_code ok;
+ const boost::system::error_code ng(-1, boost::system::system_category);
+
+ std::string platform( BOOST_PLATFORM );
+
+ void check_path( const path & source,
+ const bstring & expected, const char* file, int line )
+ {
+ if ( source == expected ) return;
+
+ ++errors;
+
+ std::cout << file;
+# ifndef BOOST_FILESYSTEM_NARROW_ONLY
+ std::wcout << L'(' << line << L"): source.wstring(): \"" << source.wstring()
+ << L"\" != expected: \"" << expected
+ << L"\"\n" ;
+# else
+ std::cout << '(' << line << "): source.string(): \"" << source.string()
+ << "\" != expected: \"" << expected
+ << "\"\n" ;
+# endif
+ }
+
+ template< class T1, class T2 >
+ void check_equal( const T1 & value,
+ const T2 & expected, const char* file, int line )
+ {
+ if ( value == expected ) return;
+
+ ++errors;
+
+ std::cout << file;
+
+# ifndef BOOST_FILESYSTEM_NARROW_ONLY
+ std::wcout << L'(' << line << L"): value: \"" << value
+ << L"\" != expected: \"" << expected
+ << L"\"\n" ;
+# else
+ std::cout << '(' << line << "): value: \"" << value
+ << "\" != expected: \"" << expected
+ << "\"\n" ;
+# endif
+ }
+
+ void check( bool ok, const char* file, int line )
+ {
+ if ( ok ) return;
+
+ ++errors;
+
+ std::cout << file << '(' << line << "): test failed\n";
+ }
+
+ path x;
+ path y;
+ string s("string iterators");
+# ifndef BOOST_FILESYSTEM_NARROW_ONLY
+ wstring ws(L"wstring iterators");
+# endif // narrow only
+
+ // test_constructors -----------------------------------------------------//
+
+ void test_constructors()
+ {
+ std::cout << "testing constructors..." << std::endl;
+
+ path x0; // #1
+ PATH_IS(x0, BOO_LIT(""));
+
+ path x1("path x1"); // #3
+ PATH_IS(x1, BOO_LIT("path x1"));
+
+ path x2(x1); // #2
+ PATH_IS(x2, BOO_LIT("path x1"));
+
+ path x4(string("std::string::iterator").begin()); // #3
+ PATH_IS(x4, BOO_LIT("std::string::iterator"));
+
+ path x7(s.begin(), s.end()); // #4
+ PATH_IS(x7, BOO_LIT("string iterators"));
+
+ path x10(string("std::string")); // #5
+ PATH_IS(x10, BOO_LIT("std::string"));
+
+# ifndef BOOST_FILESYSTEM_NARROW_ONLY
+ path x3(L"const wchar_t *"); // #3
+ PATH_IS(x3, L"const wchar_t *");
+
+ path x5(wstring(L"std::wstring::iterator").begin()); // #3
+ PATH_IS(x5, L"std::wstring::iterator");
+
+ path x8(ws.begin(), ws.end()); // #4
+ PATH_IS(x8, L"wstring iterators");
+
+ path x11(wstring(L"std::wstring")); // #5
+ PATH_IS(x11, L"std::wstring");
+# endif
+ }
+
+ // test_use_cases --------------------------------------------------------//
+
+ string use( const path & p ) { return p; }
+
+ void test_use_cases()
+ {
+ std::cout << "testing use cases..." << std::endl;
+
+ CHECK( use("foo") == "foo" );
+ CHECK( use(string("foo")) == "foo" );
+ CHECK( "foo" == use("foo") );
+ CHECK( "foo" == use(string("foo")) );
+
+# ifndef BOOST_FILESYSTEM_NARROW_ONLY
+ CHECK( use(L"foo") == "foo" );
+ CHECK( use(wstring(L"foo")) == "foo" );
+ CHECK( "foo" == use(L"foo") );
+ CHECK( "foo" == use(wstring(L"foo")) );
+# endif
+ }
+
+ // test_conversion_operators ---------------------------------------------//
+
+ void test_conversion_operators()
+ {
+ std::cout << "testing test_conversion_operators..." << std::endl;
+
+ path p( "foo" );
+
+ string s1( p );
+ CHECK( s1 == "foo" );
+
+ string s2 = p;
+ CHECK( s2 == "foo" );
+
+ s2.clear();
+ s2 = p;
+ CHECK( s2 == "foo" );
+
+# ifndef BOOST_FILESYSTEM_NARROW_ONLY
+ wstring ws1( p );
+ CHECK( ws1 == L"foo" );
+
+ wstring ws2 = p;
+ CHECK( ws2 == L"foo" );
+
+ ws2.clear();
+ ws2 = p;
+ CHECK( ws2 == L"foo" );
+# endif
+
+ }
+
+// // test_assignments ------------------------------------------------------//
+//
+// void test_assignments()
+// {
+// std::cout << "testing assignments..." << std::endl;
+//
+// y = "path y"; // #2
+// PATH_IS(y, L"path y");
+//
+// x = y; // #1
+// PATH_IS(x, L"path y");
+//
+// x = "const char *"; // #2
+// PATH_IS(x, L"const char *");
+//
+// x = L"const wchar_t *"; // #2
+// PATH_IS(x, L"const wchar_t *");
+//
+// x = string("std::string::iterator").begin(); // #2 w/iterator
+// PATH_IS(x, L"std::string::iterator");
+//
+// x = wstring(L"std::wstring::iterator").begin(); // #2 w/iterator
+// PATH_IS(x, L"std::wstring::iterator");
+//
+// y.assign("path y w/o ec"); // #3 w/o ec
+// PATH_IS(y, L"path y w/o ec");
+//
+// ec = ng;
+// y.assign("path y w/ec", ec); // #3 w/ec
+// PATH_IS(y, L"path y w/ec");
+// IS(ec, ok);
+//
+// x.assign(s.begin(), s.end()); // #4
+// PATH_IS(x, L"string iterators");
+//
+// ec = ng;
+// x.assign(s.begin(), s.end(), ec); // #4 w/ec
+// PATH_IS(x, L"string iterators");
+// IS(ec, ok);
+//
+// x.assign(ws.begin(), ws.end()); // #4
+// PATH_IS(x, L"wstring iterators");
+//
+// x = string("std::string"); // #5
+// PATH_IS(x, L"std::string");
+//
+// x = wstring(L"std::wstring"); // #5
+// PATH_IS(x, L"std::wstring");
+//
+// x.assign(string("std::string")); // #6
+// PATH_IS(x, L"std::string");
+//
+// x.assign(wstring(L"std::wstring")); // #6
+// PATH_IS(x, L"std::wstring");
+//
+// ec = ng;
+// x.assign(string("std::string"), ec); // #6 w/ec
+// PATH_IS(x, L"std::string");
+// IS(ec, ok);
+//
+// }
+//
+// // test_observers --------------------------------------------------------//
+//
+// void test_observers()
+// {
+// std::cout << "testing observers..." << std::endl;
+//
+//# ifdef BOOST_WINDOWS_PATH
+//
+// path p( "abc\\def/ghi" );
+//
+// CHECK( wstring( p.c_str() ) == L"abc\\def/ghi" );
+//
+// CHECK( p.string() == "abc\\def/ghi" );
+// CHECK( p.wstring() == L"abc\\def/ghi" );
+//
+// CHECK( p.generic().string() == "abc/def/ghi" );
+// CHECK( p.generic().wstring() == L"abc/def/ghi" );
+//
+// CHECK( p.native().string() == "abc\\def\\ghi" );
+// CHECK( p.native().wstring() == L"abc\\def\\ghi" );
+//
+//# else // BOOST_POSIX_PATH
+//
+//
+//# endif
+// }
+//
+// // test_appends ----------------------------------------------------------//
+//
+// void test_appends()
+// {
+// std::cout << "testing appends..." << std::endl;
+//
+// }
+//
+// // test_relationals ------------------------------------------------------//
+//
+// void test_relationals()
+// {
+// std::cout << "testing relationals..." << std::endl;
+//
+// const path p( "bar" );
+// const path p2( "baz" );
+//
+// CHECK( !(p < p) );
+// CHECK( p < p2 );
+// CHECK( !(p2 < p) );
+// CHECK( p < "baz" );
+// CHECK( p < string("baz") );
+// CHECK( p < L"baz" );
+// CHECK( p < wstring(L"baz") );
+// CHECK( !("baz" < p) );
+// CHECK( !(string("baz") < p) );
+// CHECK( !(L"baz" < p) );
+// CHECK( !(wstring(L"baz") < p) );
+//
+// CHECK( p == p );
+// CHECK( !(p == p2) );
+// CHECK( !(p2 == p) );
+// CHECK( p2 == "baz" );
+// CHECK( p2 == string("baz") );
+// CHECK( p2 == L"baz" );
+// CHECK( p2 == wstring(L"baz") );
+// CHECK( "baz" == p2 );
+// CHECK( string("baz") == p2 );
+// CHECK( L"baz" == p2 );
+// CHECK( wstring(L"baz") == p2 );
+//
+// CHECK( !(p != p) );
+// CHECK( p != p2 );
+// CHECK( p2 != p );
+//
+// CHECK( p <= p );
+// CHECK( p <= p2 );
+// CHECK( !(p2 <= p) );
+//
+// CHECK( !(p > p) );
+// CHECK( !(p > p2) );
+// CHECK( p2 > p );
+//
+// CHECK( p >= p );
+// CHECK( !(p >= p2) );
+// CHECK( p2 >= p );
+//}
+//
+// // test_other_non_members ------------------------------------------------//
+//
+// void test_other_non_members()
+// {
+// std::cout << "testing other_non_members..." << std::endl;
+//
+// path p1("foo");
+// path p2("bar");
+//
+// // operator /
+//
+// CHECK( p1 / p2 == path( "foo/bar" ).native() );
+// CHECK( "foo" / p2 == path( "foo/bar" ).native() );
+// CHECK( L"foo" / p2 == path( "foo/bar" ).native() );
+// CHECK( string( "foo" ) / p2 == path( "foo/bar" ).native() );
+// CHECK( wstring( L"foo" ) / p2 == path( "foo/bar" ).native() );
+// CHECK( p1 / "bar" == path( "foo/bar" ).native() );
+// CHECK( p1 / L"bar" == path( "foo/bar" ).native() );
+// CHECK( p1 / string( "bar" ) == path( "foo/bar" ).native() );
+// CHECK( p1 / wstring( L"bar" ) == path( "foo/bar" ).native() );
+//
+// swap( p1, p2 );
+// // swap
+//
+// CHECK( p1 == "bar" );
+// CHECK( p2 == "foo" );
+//
+// // swap( p1, "baz" ); // should fail to compile
+// // swap( p1, L"baz" ); // should fail to compile
+//
+// CHECK( path( "" ).remove_filename() == "" );
+// CHECK( path( "foo" ).remove_filename() == "" );
+// CHECK( path( "foo/bar" ).remove_filename() == "foo/" );
+//
+// }
+//
+// // test_modifiers --------------------------------------------------------//
+//
+// void test_modifiers()
+// {
+// std::cout << "testing modifiers..." << std::endl;
+//
+// }
+//
+// // test_iterators --------------------------------------------------------//
+//
+// void test_iterators()
+// {
+// std::cout << "testing iterators..." << std::endl;
+//
+// path p1;
+// CHECK( p1.begin() == p1.end() );
+//
+// path p2("/");
+// CHECK( p2.begin() != p2.end() );
+// CHECK( *p2.begin() == "/" );
+// CHECK( ++p2.begin() == p2.end() );
+//
+// path p3("foo/bar/baz");
+//
+// path::iterator it(p3.begin());
+// CHECK( p3.begin() != p3.end() );
+// CHECK( *it == "foo" );
+// CHECK( *++it == "bar" );
+// CHECK( *++it == "baz" );
+// CHECK( *--it == "bar" );
+// CHECK( *--it == "foo" );
+// CHECK( *++it == "bar" );
+// CHECK( *++it == "baz" );
+// CHECK( ++it == p3.end() );
+//
+// }
+//
+// // test_decompositions ---------------------------------------------------//
+//
+// void test_decompositions()
+// {
+// std::cout << "testing decompositions..." << std::endl;
+//
+// CHECK( path("").root_name().string() == "" );
+// CHECK( path("foo").root_name().string() == "" );
+// CHECK( path("/").root_name().string() == "" );
+// CHECK( path("/foo").root_name().string() == "" );
+// CHECK( path("//netname").root_name().string() == "//netname" );
+// CHECK( path("//netname/foo").root_name().string() == "//netname" );
+//
+// CHECK( path("").root_directory().string() == "" );
+// CHECK( path("foo").root_directory().string() == "" );
+// CHECK( path("/").root_directory().string() == "/" );
+// CHECK( path("/foo").root_directory().string() == "/" );
+// CHECK( path("//netname").root_directory().string() == "" );
+// CHECK( path("//netname/foo").root_directory().string() == "/" );
+//
+// CHECK( path("").root_path().string() == "" );
+// CHECK( path("/").root_path().string() == "/" );
+// CHECK( path("/foo").root_path().string() == "/" );
+// CHECK( path("//netname").root_path().string() == "//netname" );
+// CHECK( path("//netname/foo").root_path().string() == "//netname/" );
+//
+//# ifdef BOOST_WINDOWS_API
+// CHECK( path("c:/foo").root_path().string() == "c:/" );
+//# endif
+//
+// CHECK( path("").relative_path().string() == "" );
+// CHECK( path("/").relative_path().string() == "" );
+// CHECK( path("/foo").relative_path().string() == "foo" );
+//
+// CHECK( path("").parent_path().string() == "" );
+// CHECK( path("/").parent_path().string() == "" );
+// CHECK( path("/foo").parent_path().string() == "/" );
+// CHECK( path("/foo/bar").parent_path().string() == "/foo" );
+//
+// CHECK( path("/foo/bar/baz.zoo").filename().string() == "baz.zoo" );
+//
+// CHECK( path("/foo/bar/baz.zoo").stem().string() == "baz" );
+// CHECK( path("/foo/bar.woo/baz").stem().string() == "baz" );
+//
+// CHECK( path("/foo/bar/baz.zoo").extension().string() == ".zoo" );
+// CHECK( path("/foo/bar.woo/baz").extension().string() == "" );
+// }
+//
+// // test_queries ----------------------------------------------------------//
+//
+// void test_queries()
+// {
+// std::cout << "testing queries..." << std::endl;
+//
+// path p1( "" );
+// path p2( "//netname/foo" );
+//
+// CHECK( p1.empty() );
+// CHECK( !p1.has_root_path() );
+// CHECK( !p1.has_root_name() );
+// CHECK( !p1.has_root_directory() );
+// CHECK( !p1.has_relative_path() );
+// CHECK( !p1.has_parent_path() );
+// CHECK( !p1.has_filename() );
+// CHECK( !p1.is_complete() );
+//
+// CHECK( !p2.empty() );
+// CHECK( p2.has_root_path() );
+// CHECK( p2.has_root_name() );
+// CHECK( p2.has_root_directory() );
+// CHECK( p2.has_relative_path() );
+// CHECK( p2.has_parent_path() );
+// CHECK( p2.has_filename() );
+// CHECK( p2.is_complete() );
+//
+// }
+//
+// // test_locales ----------------------------------------------------------//
+//
+// void test_locales()
+// {
+// std::cout << "testing locales..." << std::endl;
+//
+// }
+
+} // unnamed namespace
+
+// -------------------------------- main -----------------------------------//
+
+int main( int, char*[] )
+{
+ test_constructors();
+ test_use_cases();
+ test_conversion_operators();
+ //test_assignments();
+ //test_observers();
+ ////test_appends();
+ //test_relationals();
+ //test_other_non_members();
+ //test_modifiers();
+ //test_iterators();
+ //test_decompositions();
+ //test_queries();
+ ////test_locales();
+
+ cout << errors << " errors detected\n";
+
+ return errors;
+}
Added: sandbox/filesystem-v3/libs/filesystem/v3/test/wide_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/filesystem-v3/libs/filesystem/v3/test/wide_test.cpp 2008-12-24 08:50:37 EST (Wed, 24 Dec 2008)
@@ -0,0 +1,161 @@
+// Boost wide_test.cpp -----------------------------------------------------//
+
+// Copyright Beman Dawes 2005
+
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See library home page at http://www.boost.org/libs/filesystem
+
+#include <boost/config/warning_disable.hpp>
+
+// See deprecated_test for tests of deprecated features
+#define BOOST_FILESYSTEM_NO_DEPRECATED
+
+#include <boost/filesystem/config.hpp>
+# ifdef BOOST_FILESYSTEM_NARROW_ONLY
+# error This compiler or standard library does not support wide-character strings or paths
+# endif
+
+#include <boost/filesystem/operations.hpp>
+#include <boost/filesystem/fstream.hpp>
+#include <boost/scoped_array.hpp>
+#include <boost/test/minimal.hpp>
+
+#include "../src/utf8_codecvt_facet.hpp"
+
+namespace fs = boost::filesystem;
+
+#include <iostream>
+#include <iomanip>
+#include <ios>
+#include <string>
+#include <cerrno>
+
+#include "lpath.hpp"
+
+namespace
+{
+ bool cleanup = true;
+
+ template< class Path >
+ void create_file( const Path & ph, const std::string & contents )
+ {
+ // TODO: why missing symbol error on Darwin
+# ifndef __APPLE__
+ fs::ofstream f( ph );
+# else
+ std::ofstream f( ph.external_file_string().c_str() );
+# endif
+ if ( !f )
+ throw fs::basic_filesystem_error<Path>( "wide_test create_file",
+ ph,
+ boost::system::error_code( errno, boost::system::errno_ecat ) );
+ if ( !contents.empty() ) f << contents;
+ }
+
+ template< class Path >
+ void test( const Path & dir, const Path & file, const Path & dot )
+ {
+ Path tmp;
+ tmp = file;
+ BOOST_CHECK( tmp == file );
+ tmp = file.string();
+ BOOST_CHECK( tmp == file );
+ tmp = file.string().c_str();
+ BOOST_CHECK( tmp == file );
+ fs::initial_path<Path>();
+ fs::current_path<Path>();
+ fs::remove( dir / file );
+ fs::remove( dir );
+ BOOST_CHECK( !fs::exists( dir / file ) );
+ BOOST_CHECK( !fs::exists( dir ) );
+ BOOST_CHECK( fs::create_directory( dir ) );
+ BOOST_CHECK( fs::exists( dir ) );
+ BOOST_CHECK( fs::is_directory( dir ) );
+ BOOST_CHECK( fs::is_empty( dir ) );
+ create_file( dir / file, "wide_test file contents" );
+ BOOST_CHECK( fs::exists( dir / file ) );
+ BOOST_CHECK( !fs::is_directory( dir / file ) );
+ BOOST_CHECK( !fs::is_empty( dir / file ) );
+ BOOST_CHECK( fs::file_size( dir / file ) == 23 || fs::file_size( dir / file ) == 24 );
+ BOOST_CHECK( fs::equivalent( dir / file, dot / dir / file ) );
+ BOOST_CHECK( fs::last_write_time( dir / file ) );
+ typedef fs::basic_directory_iterator<Path> it_t;
+ int count(0);
+ for ( it_t it( dir ); it != it_t(); ++it )
+ {
+ BOOST_CHECK( it->path() == dir / file );
+ BOOST_CHECK( !fs::is_empty( it->path() ) );
+ ++count;
+ }
+ BOOST_CHECK( count == 1 );
+ if ( cleanup )
+ {
+ fs::remove( dir / file );
+ fs::remove( dir );
+ }
+ }
+
+ // test boost::detail::utf8_codecvt_facet - even though it is not used by
+ // Boost.Filesystem on Windows, early detection of problems is worthwhile.
+ std::string to_external( const std::wstring & src )
+ {
+ fs::detail::utf8_codecvt_facet convertor;
+ std::size_t work_size( convertor.max_length() * (src.size()+1) );
+ boost::scoped_array<char> work( new char[ work_size ] );
+ std::mbstate_t state;
+ const wchar_t * from_next;
+ char * to_next;
+ if ( convertor.out(
+ state, src.c_str(), src.c_str()+src.size(), from_next, work.get(),
+ work.get()+work_size, to_next ) != std::codecvt_base::ok )
+ boost::throw_exception( std::runtime_error("to_external conversion error") );
+ *to_next = '\0';
+ return std::string( work.get() );
+ }
+
+} // unnamed namespace
+
+// test_main ---------------------------------------------------------------//
+
+int test_main( int argc, char * /*argv*/[] )
+{
+
+ if ( argc > 1 ) cleanup = false;
+
+ // So that tests are run with known encoding, use Boost UTF-8 codecvt
+ std::locale global_loc = std::locale();
+ std::locale loc( global_loc, new fs::detail::utf8_codecvt_facet );
+ fs::wpath_traits::imbue( loc );
+
+ std::string s( to_external( L"\x2780" ) );
+ for (std::size_t i = 0; i < s.size(); ++i )
+ std::cout << std::hex << int( static_cast<unsigned char>(s[i]) ) << " ";
+ std::cout << std::dec << std::endl;
+ BOOST_CHECK( to_external( L"\x2780" ).size() == 3 );
+ BOOST_CHECK( to_external( L"\x2780" ) == "\xE2\x9E\x80" );
+
+ // test fs::path
+ std::cout << "begin path test..." << std::endl;
+ test( fs::path( "foo" ), fs::path( "bar" ), fs::path( "." ) );
+ std::cout << "complete\n\n";
+
+ // test fs::wpath
+ // x2780 is circled 1 against white background == e2 9e 80 in UTF-8
+ // x2781 is circled 2 against white background == e2 9e 81 in UTF-8
+ std::cout << "begin wpath test..." << std::endl;
+ test( fs::wpath( L"\x2780" ), fs::wpath( L"\x2781" ), fs::wpath( L"." ) );
+ std::cout << "complete\n\n";
+
+ // test user supplied basic_path
+ const long dir[] = { 'b', 'o', 'o', 0 };
+ const long file[] = { 'f', 'a', 'r', 0 };
+ const long dot[] = { '.', 0 };
+ std::cout << "begin lpath test..." << std::endl;
+ test( ::user::lpath( dir ), ::user::lpath( file ), ::user::lpath( dot ) );
+ std::cout << "complete\n\n";
+
+ return 0;
+}
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk