diff options
author | Anas Nashif <anas.nashif@intel.com> | 2012-10-30 19:57:26 (GMT) |
---|---|---|
committer | Anas Nashif <anas.nashif@intel.com> | 2012-10-30 19:57:26 (GMT) |
commit | 1a78a62555be32868418fe52f8e330c9d0f95d5a (patch) | |
tree | d3765a80e7d3b9640ec2e930743630cd6b9fce2b /boost/filesystem | |
download | boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.zip boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.tar.gz boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.tar.bz2 |
Imported Upstream version 1.49.0upstream/1.49.0
Diffstat (limited to 'boost/filesystem')
-rw-r--r-- | boost/filesystem/config.hpp | 35 | ||||
-rw-r--r-- | boost/filesystem/convenience.hpp | 35 | ||||
-rw-r--r-- | boost/filesystem/detail/utf8_codecvt_facet.hpp | 24 | ||||
-rw-r--r-- | boost/filesystem/exception.hpp | 35 | ||||
-rw-r--r-- | boost/filesystem/fstream.hpp | 35 | ||||
-rw-r--r-- | boost/filesystem/operations.hpp | 35 | ||||
-rw-r--r-- | boost/filesystem/path.hpp | 35 | ||||
-rw-r--r-- | boost/filesystem/v2/config.hpp | 106 | ||||
-rw-r--r-- | boost/filesystem/v2/convenience.hpp | 339 | ||||
-rw-r--r-- | boost/filesystem/v2/exception.hpp | 9 | ||||
-rw-r--r-- | boost/filesystem/v2/fstream.hpp | 613 | ||||
-rw-r--r-- | boost/filesystem/v2/operations.hpp | 1245 | ||||
-rw-r--r-- | boost/filesystem/v2/path.hpp | 1571 | ||||
-rw-r--r-- | boost/filesystem/v3/config.hpp | 85 | ||||
-rw-r--r-- | boost/filesystem/v3/convenience.hpp | 74 | ||||
-rw-r--r-- | boost/filesystem/v3/exception.hpp | 9 | ||||
-rw-r--r-- | boost/filesystem/v3/fstream.hpp | 208 | ||||
-rw-r--r-- | boost/filesystem/v3/operations.hpp | 1199 | ||||
-rw-r--r-- | boost/filesystem/v3/path.hpp | 760 | ||||
-rw-r--r-- | boost/filesystem/v3/path_traits.hpp | 247 |
20 files changed, 6699 insertions, 0 deletions
diff --git a/boost/filesystem/config.hpp b/boost/filesystem/config.hpp new file mode 100644 index 0000000..c813bf5 --- /dev/null +++ b/boost/filesystem/config.hpp @@ -0,0 +1,35 @@ +// boost/filesystem/config.hpp -------------------------------------------------------// + +// Copyright Beman Dawes 2010 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// Library home page: http://www.boost.org/libs/filesystem + +//--------------------------------------------------------------------------------------// + +#ifndef BOOST_FILESYSTEM_CONFIGX_HPP +#define BOOST_FILESYSTEM_CONFIGX_HPP + +#include <boost/config.hpp> // for <boost/config/user.hpp>, in case + // BOOST_FILESYSTEM_VERSION defined there + +# if defined(BOOST_FILESYSTEM_VERSION) \ + && BOOST_FILESYSTEM_VERSION != 2 && BOOST_FILESYSTEM_VERSION != 3 +# error BOOST_FILESYSTEM_VERSION defined, but not as 2 or 3 +# endif + +# if !defined(BOOST_FILESYSTEM_VERSION) +# define BOOST_FILESYSTEM_VERSION 3 +# endif + +#if BOOST_FILESYSTEM_VERSION == 2 +# include <boost/filesystem/v2/config.hpp> + +# else +# include <boost/filesystem/v3/config.hpp> + +# endif + +#endif // BOOST_FILESYSTEM_CONFIGX_HPP diff --git a/boost/filesystem/convenience.hpp b/boost/filesystem/convenience.hpp new file mode 100644 index 0000000..a132e17 --- /dev/null +++ b/boost/filesystem/convenience.hpp @@ -0,0 +1,35 @@ +// boost/filesystem/convenience.hpp --------------------------------------------------// + +// Copyright Beman Dawes 2010 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// Library home page: http://www.boost.org/libs/filesystem + +//--------------------------------------------------------------------------------------// + +#ifndef BOOST_FILESYSTEM_CONVENIENCEX_HPP +#define BOOST_FILESYSTEM_CONVENIENCEX_HPP + +#include <boost/config.hpp> // for <boost/config/user.hpp>, in case + // BOOST_FILESYSTEM_VERSION defined there + +# if defined(BOOST_FILESYSTEM_VERSION) \ + && BOOST_FILESYSTEM_VERSION != 2 && BOOST_FILESYSTEM_VERSION != 3 +# error BOOST_FILESYSTEM_VERSION defined, but not as 2 or 3 +# endif + +# if !defined(BOOST_FILESYSTEM_VERSION) +# define BOOST_FILESYSTEM_VERSION 3 +# endif + +#if BOOST_FILESYSTEM_VERSION == 2 +# include <boost/filesystem/v2/convenience.hpp> + +# else +# include <boost/filesystem/v3/convenience.hpp> + +# endif + +#endif // BOOST_FILESYSTEM_CONVENIENCEX_HPP diff --git a/boost/filesystem/detail/utf8_codecvt_facet.hpp b/boost/filesystem/detail/utf8_codecvt_facet.hpp new file mode 100644 index 0000000..3b78fb1 --- /dev/null +++ b/boost/filesystem/detail/utf8_codecvt_facet.hpp @@ -0,0 +1,24 @@ +// Copyright (c) 2001 Ronald Garcia, Indiana University (garcia@osl.iu.edu) +// Andrew Lumsdaine, Indiana University (lums@osl.iu.edu). + +// 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 diff --git a/boost/filesystem/exception.hpp b/boost/filesystem/exception.hpp new file mode 100644 index 0000000..6ba8466 --- /dev/null +++ b/boost/filesystem/exception.hpp @@ -0,0 +1,35 @@ +// boost/filesystem/exception.hpp ----------------------------------------------------// + +// Copyright Beman Dawes 2010 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// Library home page: http://www.boost.org/libs/filesystem + +//--------------------------------------------------------------------------------------// + +#ifndef BOOST_FILESYSTEM_EXCEPTIONX_HPP +#define BOOST_FILESYSTEM_EXCEPTIONX_HPP + +#include <boost/config.hpp> // for <boost/config/user.hpp>, in case + // BOOST_FILESYSTEM_VERSION defined there + +# if defined(BOOST_FILESYSTEM_VERSION) \ + && BOOST_FILESYSTEM_VERSION != 2 && BOOST_FILESYSTEM_VERSION != 3 +# error BOOST_FILESYSTEM_VERSION defined, but not as 2 or 3 +# endif + +# if !defined(BOOST_FILESYSTEM_VERSION) +# define BOOST_FILESYSTEM_VERSION 3 +# endif + +#if BOOST_FILESYSTEM_VERSION == 2 +# include <boost/filesystem/v2/exception.hpp> + +# else +# include <boost/filesystem/v3/exception.hpp> + +# endif + +#endif // BOOST_FILESYSTEM_EXCEPTIONX_HPP diff --git a/boost/filesystem/fstream.hpp b/boost/filesystem/fstream.hpp new file mode 100644 index 0000000..e159e58 --- /dev/null +++ b/boost/filesystem/fstream.hpp @@ -0,0 +1,35 @@ +// boost/filesystem/fstream.hpp ------------------------------------------------------// + +// Copyright Beman Dawes 2010 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// Library home page: http://www.boost.org/libs/filesystem + +//--------------------------------------------------------------------------------------// + +#ifndef BOOST_FILESYSTEM_FSTREAMX_HPP +#define BOOST_FILESYSTEM_FSTREAMX_HPP + +#include <boost/config.hpp> // for <boost/config/user.hpp>, in case + // BOOST_FILESYSTEM_VERSION defined there + +# if defined(BOOST_FILESYSTEM_VERSION) \ + && BOOST_FILESYSTEM_VERSION != 2 && BOOST_FILESYSTEM_VERSION != 3 +# error BOOST_FILESYSTEM_VERSION defined, but not as 2 or 3 +# endif + +# if !defined(BOOST_FILESYSTEM_VERSION) +# define BOOST_FILESYSTEM_VERSION 3 +# endif + +#if BOOST_FILESYSTEM_VERSION == 2 +# include <boost/filesystem/v2/fstream.hpp> + +# else +# include <boost/filesystem/v3/fstream.hpp> + +# endif + +#endif // BOOST_FILESYSTEM_FSTREAMX_HPP diff --git a/boost/filesystem/operations.hpp b/boost/filesystem/operations.hpp new file mode 100644 index 0000000..db7b123 --- /dev/null +++ b/boost/filesystem/operations.hpp @@ -0,0 +1,35 @@ +// boost/filesystem/operations.hpp ---------------------------------------------------// + +// Copyright Beman Dawes 2010 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// Library home page: http://www.boost.org/libs/filesystem + +//--------------------------------------------------------------------------------------// + +#ifndef BOOST_FILESYSTEM_OPERATIONSX_HPP +#define BOOST_FILESYSTEM_OPERATIONSX_HPP + +#include <boost/config.hpp> // for <boost/config/user.hpp>, in case + // BOOST_FILESYSTEM_VERSION defined there + +# if defined(BOOST_FILESYSTEM_VERSION) \ + && BOOST_FILESYSTEM_VERSION != 2 && BOOST_FILESYSTEM_VERSION != 3 +# error BOOST_FILESYSTEM_VERSION defined, but not as 2 or 3 +# endif + +# if !defined(BOOST_FILESYSTEM_VERSION) +# define BOOST_FILESYSTEM_VERSION 3 +# endif + +#if BOOST_FILESYSTEM_VERSION == 2 +# include <boost/filesystem/v2/operations.hpp> + +# else +# include <boost/filesystem/v3/operations.hpp> + +# endif + +#endif // BOOST_FILESYSTEM_OPERATIONSX_HPP diff --git a/boost/filesystem/path.hpp b/boost/filesystem/path.hpp new file mode 100644 index 0000000..3bed7d2 --- /dev/null +++ b/boost/filesystem/path.hpp @@ -0,0 +1,35 @@ +// boost/filesystem/path.hpp ---------------------------------------------------------// + +// Copyright Beman Dawes 2010 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// Library home page: http://www.boost.org/libs/filesystem + +//--------------------------------------------------------------------------------------// + +#ifndef BOOST_FILESYSTEM_PATHX_HPP +#define BOOST_FILESYSTEM_PATHX_HPP + +#include <boost/config.hpp> // for <boost/config/user.hpp>, in case + // BOOST_FILESYSTEM_VERSION defined there + +# if defined(BOOST_FILESYSTEM_VERSION) \ + && BOOST_FILESYSTEM_VERSION != 2 && BOOST_FILESYSTEM_VERSION != 3 +# error BOOST_FILESYSTEM_VERSION defined, but not as 2 or 3 +# endif + +# if !defined(BOOST_FILESYSTEM_VERSION) +# define BOOST_FILESYSTEM_VERSION 3 +# endif + +#if BOOST_FILESYSTEM_VERSION == 2 +# include <boost/filesystem/v2/path.hpp> + +# else +# include <boost/filesystem/v3/path.hpp> + +# endif + +#endif // BOOST_FILESYSTEM_PATHX_HPP diff --git a/boost/filesystem/v2/config.hpp b/boost/filesystem/v2/config.hpp new file mode 100644 index 0000000..7116de5 --- /dev/null +++ b/boost/filesystem/v2/config.hpp @@ -0,0 +1,106 @@ +// boost/filesystem/v2/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_FILESYSTEM2_CONFIG_HPP +#define BOOST_FILESYSTEM2_CONFIG_HPP + +# if defined(BOOST_FILESYSTEM_VERSION) && BOOST_FILESYSTEM_VERSION != 2 +# error Compiling Filesystem version 2 file with BOOST_FILESYSTEM_VERSION defined != 2 +# endif + +# if !defined(BOOST_FILESYSTEM_VERSION) +# define BOOST_FILESYSTEM_VERSION 2 +# endif + +#define BOOST_FILESYSTEM_I18N // aid users wishing to compile several versions + +// ability to change namespace aids path_table.cpp ------------------------// +#ifndef BOOST_FILESYSTEM2_NAMESPACE +# define BOOST_FILESYSTEM2_NAMESPACE filesystem2 +#endif + +#include <boost/config.hpp> +#include <boost/system/api_config.hpp> // for BOOST_POSIX_API or BOOST_WINDOWS_API +#include <boost/detail/workaround.hpp> + +// BOOST_POSIX_PATH or BOOST_WINDOWS_PATH specify which path syntax to recognise + +# if defined(BOOST_WINDOWS_API) && defined(BOOST_POSIX_PATH) +# error builds with Windows API do not support BOOST_POSIX_PATH +# endif + +# if !defined(_WIN32) && !defined(__CYGWIN__) && defined(BOOST_WINDOWS_PATH) +# error builds on non-Windows platforms do not support BOOST_WINDOWS_PATH +# endif + +# if defined(BOOST_WINDOWS_PATH) && defined(BOOST_POSIX_PATH) +# error both BOOST_WINDOWS_PATH and BOOST_POSIX_PATH are defined +# elif !defined(BOOST_WINDOWS_PATH) && !defined(BOOST_POSIX_PATH) +# if !defined(BOOST_POSIX_PATH) && (defined(_WIN32) || defined(__CYGWIN__)) +# define BOOST_WINDOWS_PATH +# else +# define BOOST_POSIX_PATH +# endif +# endif + +// throw an exception ----------------------------------------------------------------// +// +// Exceptions were originally thrown via boost::throw_exception(). +// As throw_exception() became more complex, it caused user error reporting +// to be harder to interpret, since the exception reported became much more complex. +// The immediate fix was to throw directly, wrapped in a macro to make any later change +// easier. + +#define BOOST_FILESYSTEM_THROW(EX) throw EX + +// 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__, <0x610) +# define BOOST_FILESYSTEM2_NARROW_ONLY +# endif + +// This header implements separate compilation features as described in +// http://www.boost.org/more/separate_compilation.html + +// enable dynamic linking ---------------------------------------------------// + +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_FILESYSTEM_DYN_LINK) +# if defined(BOOST_FILESYSTEM_SOURCE) +# define BOOST_FILESYSTEM_DECL BOOST_SYMBOL_EXPORT +# else +# define BOOST_FILESYSTEM_DECL BOOST_SYMBOL_IMPORT +# endif +#else +# 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_FILESYSTEM2_CONFIG_HPP diff --git a/boost/filesystem/v2/convenience.hpp b/boost/filesystem/v2/convenience.hpp new file mode 100644 index 0000000..30b6ade --- /dev/null +++ b/boost/filesystem/v2/convenience.hpp @@ -0,0 +1,339 @@ +// 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_FILESYSTEM2_CONVENIENCE_HPP +#define BOOST_FILESYSTEM2_CONVENIENCE_HPP + +#include <boost/filesystem/v2/config.hpp> +#include <boost/filesystem/v2/operations.hpp> +#include <boost/system/error_code.hpp> +#include <vector> +#include <stack> + +#include <boost/config/abi_prefix.hpp> // must be the last #include + +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY +# define BOOST_FS_FUNC(BOOST_FS_TYPE) \ + template<class Path> typename boost::enable_if<is_basic_path<Path>, \ + BOOST_FS_TYPE>::type +# define BOOST_FS_FUNC_STRING BOOST_FS_FUNC(typename Path::string_type) +# define BOOST_FS_TYPENAME typename +# else +# define BOOST_FS_FUNC(BOOST_FS_TYPE) inline BOOST_FS_TYPE + typedef boost::filesystem::path Path; +# define BOOST_FS_FUNC_STRING inline std::string +# define BOOST_FS_TYPENAME +# endif + +namespace boost +{ + namespace filesystem2 + { + + BOOST_FS_FUNC(bool) create_directories(const Path& ph) + { + if (ph.empty() || exists(ph)) + { + if ( !ph.empty() && !is_directory(ph) ) + boost::throw_exception( basic_filesystem_error<Path>( + "boost::filesystem::create_directories", ph, + make_error_code( boost::system::errc::file_exists ) ) ); + return false; + } + + // First create branch, by calling ourself recursively + create_directories(ph.parent_path()); + // Now that parent's path exists, create the directory + create_directory(ph); + return true; + } + +# 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 ) + { +# if !defined(_STLPORT_VERSION) + return ph.parent_path() / (basename(ph) + new_extension); +# else + typedef BOOST_FS_TYPENAME Path::string_type string_type; + string_type filename = basename(ph) + new_extension; + return ph.parent_path() / filename; +# endif + } +# endif + +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY + + // "do-the-right-thing" overloads ---------------------------------------// + + inline bool create_directories(const path& ph) + { return create_directories<path>(ph); } + inline bool create_directories(const wpath& ph) + { return create_directories<wpath>(ph); } + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + 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 + +# endif + + + // basic_recursive_directory_iterator helpers --------------------------// + + namespace detail + { + template< class Path > + struct recur_dir_itr_imp + { + typedef basic_directory_iterator< Path > 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 + + // basic_recursive_directory_iterator ----------------------------------// + + template< class Path > + class basic_recursive_directory_iterator + : public boost::iterator_facade< + basic_recursive_directory_iterator<Path>, + basic_directory_entry<Path>, + boost::single_pass_traversal_tag > + { + public: + typedef Path path_type; + + basic_recursive_directory_iterator(){} // creates the "end" iterator + + explicit basic_recursive_directory_iterator( const Path & dir_path ); + basic_recursive_directory_iterator( const Path & dir_path, + system::error_code & ec ); + + int level() const { return m_imp->m_level; } + + void pop(); + void no_push() + { + BOOST_ASSERT( m_imp.get() && "attempt to no_push() on end iterator" ); + m_imp->m_no_push = true; + } + + file_status status() const + { + BOOST_ASSERT( m_imp.get() + && "attempt to call status() on end recursive_iterator" ); + return m_imp->m_stack.top()->status(); + } + + file_status symlink_status() const + { + BOOST_ASSERT( m_imp.get() + && "attempt to call symlink_status() on end recursive_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< Path > > m_imp; + + friend class boost::iterator_core_access; + + typename boost::iterator_facade< + basic_recursive_directory_iterator<Path>, + basic_directory_entry<Path>, + boost::single_pass_traversal_tag >::reference + dereference() const + { + BOOST_ASSERT( m_imp.get() && "attempt to dereference end iterator" ); + return *m_imp->m_stack.top(); + } + + void increment(); + + bool equal( const basic_recursive_directory_iterator & rhs ) const + { return m_imp == rhs.m_imp; } + + }; + + typedef basic_recursive_directory_iterator<path> recursive_directory_iterator; +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY + typedef basic_recursive_directory_iterator<wpath> wrecursive_directory_iterator; +# endif + + // basic_recursive_directory_iterator implementation -------------------// + + // constructors + template<class Path> + basic_recursive_directory_iterator<Path>:: + basic_recursive_directory_iterator( const Path & dir_path ) + : m_imp( new detail::recur_dir_itr_imp<Path> ) + { + m_imp->m_stack.push( basic_directory_iterator<Path>( dir_path ) ); + if ( m_imp->m_stack.top () == basic_directory_iterator<Path>() ) + { m_imp.reset (); } + } + + template<class Path> + basic_recursive_directory_iterator<Path>:: + basic_recursive_directory_iterator( const Path & dir_path, + system::error_code & ec ) + : m_imp( new detail::recur_dir_itr_imp<Path> ) + { + m_imp->m_no_throw = true; + m_imp->m_stack.push( basic_directory_iterator<Path>( dir_path, ec ) ); + if ( m_imp->m_stack.top () == basic_directory_iterator<Path>() ) + { m_imp.reset (); } + } + + // increment + template<class Path> + void basic_recursive_directory_iterator<Path>::increment() + { + BOOST_ASSERT( m_imp.get() && "increment on end iterator" ); + + static const basic_directory_iterator<Path> 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; +#if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x610)) + if( m_imp->m_no_throw ) { + m_imp->m_stack.push( + basic_directory_iterator<Path>( *m_imp->m_stack.top(), ec ) + ); + } + else { + m_imp->m_stack.push( + basic_directory_iterator<Path>( *m_imp->m_stack.top() ) + ); + } +#else + m_imp->m_stack.push( + m_imp->m_no_throw + ? basic_directory_iterator<Path>( *m_imp->m_stack.top(), ec ) + : basic_directory_iterator<Path>( *m_imp->m_stack.top() ) ); +#endif + 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 + template<class Path> + void basic_recursive_directory_iterator<Path>::pop() + { + BOOST_ASSERT( m_imp.get() && "pop on end iterator" ); + BOOST_ASSERT( m_imp->m_level > 0 && "pop with level < 1" ); + + static const basic_directory_iterator<Path> 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 filesystem2 +} // namespace boost + +#undef BOOST_FS_FUNC_STRING +#undef BOOST_FS_FUNC + +//----------------------------------------------------------------------------// + +namespace boost +{ + namespace filesystem + { + using filesystem2::create_directories; + using filesystem2::basic_recursive_directory_iterator; + using filesystem2::recursive_directory_iterator; + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + using filesystem2::extension; + using filesystem2::basename; + using filesystem2::change_extension; +# endif + +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY + using filesystem2::wrecursive_directory_iterator; +# endif + + } +} + +//----------------------------------------------------------------------------// + +#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas +#endif // BOOST_FILESYSTEM2_CONVENIENCE_HPP diff --git a/boost/filesystem/v2/exception.hpp b/boost/filesystem/v2/exception.hpp new file mode 100644 index 0000000..edea663 --- /dev/null +++ b/boost/filesystem/v2/exception.hpp @@ -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. diff --git a/boost/filesystem/v2/fstream.hpp b/boost/filesystem/v2/fstream.hpp new file mode 100644 index 0000000..887d59d --- /dev/null +++ b/boost/filesystem/v2/fstream.hpp @@ -0,0 +1,613 @@ +// 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_FILESYSTEM2_FSTREAM_HPP +#define BOOST_FILESYSTEM2_FSTREAM_HPP + +#include <boost/filesystem/v2/config.hpp> +#include <boost/filesystem/v2/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 filesystem2 + { + namespace detail + { +# if defined(BOOST_WINDOWS_API) && !defined(BOOST_FILESYSTEM2_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_FILESYSTEM2_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_FILESYSTEM2_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_FILESYSTEM2_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_FILESYSTEM2_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_FILESYSTEM2_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_FILESYSTEM2_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 ) {} + + 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 ) {} + + 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 ); + } + + 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 ); + } + +// 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 ) {} + + 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 ) {} + + 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 ); + } + + 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 ); + } + +// 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 ) {} + + 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 ) {} + + 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 ); + } + + 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 ); + } + +# 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 filesystem2 +} // namespace boost + +//----------------------------------------------------------------------------// + +namespace boost +{ + namespace filesystem + { +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY + using filesystem2::wfilebuf; + using filesystem2::wifstream; + using filesystem2::wfstream; + using filesystem2::wofstream; +# endif + using filesystem2::filebuf; + using filesystem2::ifstream; + using filesystem2::ofstream; + using filesystem2::fstream; + using filesystem2::basic_filebuf; + using filesystem2::basic_ifstream; + using filesystem2::basic_ofstream; + using filesystem2::basic_fstream; + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED +# endif + } +} + +//----------------------------------------------------------------------------// + +#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas +#endif // BOOST_FILESYSTEM2_FSTREAM_HPP diff --git a/boost/filesystem/v2/operations.hpp b/boost/filesystem/v2/operations.hpp new file mode 100644 index 0000000..57c406d --- /dev/null +++ b/boost/filesystem/v2/operations.hpp @@ -0,0 +1,1245 @@ +// boost/filesystem/operations.hpp -----------------------------------------// + +// Copyright 2002-2005 Beman Dawes +// Copyright 2002 Jan Langer +// Copyright 2001 Dietmar Kuehl +// +// 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_FILESYSTEM2_OPERATIONS_HPP +#define BOOST_FILESYSTEM2_OPERATIONS_HPP + +#include <boost/filesystem/v2/config.hpp> +#include <boost/filesystem/v2/path.hpp> +#include <boost/detail/scoped_enum_emulation.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) || _WIN32_WINNT >= 0x0500 +# define BOOST_FS_HARD_LINK // Default for Windows 2K or later +# 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 filesystem2 + { + +// typedef boost::filesystem::path Path; needs to be in namespace boost::filesystem +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY +# define BOOST_FS_FUNC(BOOST_FS_TYPE) \ + template<class Path> typename boost::enable_if<is_basic_path<Path>, \ + BOOST_FS_TYPE>::type +# define BOOST_INLINE_FS_FUNC(BOOST_FS_TYPE) \ + template<class Path> inline typename boost::enable_if<is_basic_path<Path>, \ + BOOST_FS_TYPE>::type +# define BOOST_FS_TYPENAME typename +# else +# define BOOST_FS_FUNC(BOOST_FS_TYPE) inline BOOST_FS_TYPE +# define BOOST_INLINE_FS_FUNC(BOOST_FS_TYPE) inline BOOST_FS_TYPE + typedef boost::filesystem2::path Path; +# define BOOST_FS_TYPENAME +# endif + + template<class Path> class basic_directory_iterator; + + // BOOST_FILESYSTEM2_NARROW_ONLY needs this: + typedef basic_directory_iterator<path> directory_iterator; + + template<class Path> class basic_directory_entry; + + 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 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; } + + 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 + }; + + namespace detail + { + typedef std::pair< system::error_code, bool > + query_pair; + + typedef std::pair< system::error_code, boost::uintmax_t > + uintmax_pair; + + typedef std::pair< system::error_code, std::time_t > + time_pair; + + typedef std::pair< system::error_code, space_info > + space_pair; + + template< class Path > + struct directory_pair + { + typedef std::pair< system::error_code, + typename Path::external_string_type > type; + }; + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + BOOST_FILESYSTEM_DECL bool + symbolic_link_exists_api( const std::string & ); // deprecated +# endif + + BOOST_FILESYSTEM_DECL file_status + status_api( const std::string & ph, system::error_code & ec ); +# ifndef BOOST_WINDOWS_API + BOOST_FILESYSTEM_DECL file_status + symlink_status_api( const std::string & ph, system::error_code & ec ); +# endif + BOOST_FILESYSTEM_DECL query_pair + is_empty_api( const std::string & ph ); + BOOST_FILESYSTEM_DECL query_pair + equivalent_api( const std::string & ph1, const std::string & ph2 ); + BOOST_FILESYSTEM_DECL uintmax_pair + file_size_api( const std::string & ph ); + BOOST_FILESYSTEM_DECL space_pair + space_api( const std::string & ph ); + BOOST_FILESYSTEM_DECL time_pair + last_write_time_api( const std::string & ph ); + BOOST_FILESYSTEM_DECL system::error_code + last_write_time_api( const std::string & ph, std::time_t new_value ); + BOOST_FILESYSTEM_DECL system::error_code + get_current_path_api( std::string & ph ); + BOOST_FILESYSTEM_DECL system::error_code + set_current_path_api( const std::string & ph ); + BOOST_FILESYSTEM_DECL query_pair + create_directory_api( const std::string & ph ); + BOOST_FILESYSTEM_DECL system::error_code + create_hard_link_api( const std::string & to_ph, + const std::string & from_ph ); + BOOST_FILESYSTEM_DECL system::error_code + create_symlink_api( const std::string & to_ph, + const std::string & from_ph ); + BOOST_FILESYSTEM_DECL system::error_code + remove_api( const std::string & ph ); + BOOST_FILESYSTEM_DECL system::error_code + rename_api( const std::string & from, const std::string & to ); + BOOST_FILESYSTEM_DECL system::error_code + copy_file_api( const std::string & from, const std::string & to, bool fail_if_exists ); + +# if defined(BOOST_WINDOWS_API) + + BOOST_FILESYSTEM_DECL system::error_code + get_full_path_name_api( const std::string & ph, std::string & target ); + +# if !defined(BOOST_FILESYSTEM2_NARROW_ONLY) + + BOOST_FILESYSTEM_DECL boost::filesystem2::file_status + status_api( const std::wstring & ph, system::error_code & ec ); + BOOST_FILESYSTEM_DECL query_pair + is_empty_api( const std::wstring & ph ); + BOOST_FILESYSTEM_DECL query_pair + equivalent_api( const std::wstring & ph1, const std::wstring & ph2 ); + BOOST_FILESYSTEM_DECL uintmax_pair + file_size_api( const std::wstring & ph ); + BOOST_FILESYSTEM_DECL space_pair + space_api( const std::wstring & ph ); + BOOST_FILESYSTEM_DECL system::error_code + get_full_path_name_api( const std::wstring & ph, std::wstring & target ); + BOOST_FILESYSTEM_DECL time_pair + last_write_time_api( const std::wstring & ph ); + BOOST_FILESYSTEM_DECL system::error_code + last_write_time_api( const std::wstring & ph, std::time_t new_value ); + BOOST_FILESYSTEM_DECL system::error_code + get_current_path_api( std::wstring & ph ); + BOOST_FILESYSTEM_DECL system::error_code + set_current_path_api( const std::wstring & ph ); + BOOST_FILESYSTEM_DECL query_pair + create_directory_api( const std::wstring & ph ); +# ifdef BOOST_FS_HARD_LINK + BOOST_FILESYSTEM_DECL system::error_code + create_hard_link_api( const std::wstring & existing_ph, + const std::wstring & new_ph ); +# endif + BOOST_FILESYSTEM_DECL system::error_code + create_symlink_api( const std::wstring & to_ph, + const std::wstring & from_ph ); + BOOST_FILESYSTEM_DECL system::error_code + remove_api( const std::wstring & ph ); + BOOST_FILESYSTEM_DECL system::error_code + rename_api( const std::wstring & from, const std::wstring & to ); + BOOST_FILESYSTEM_DECL system::error_code + copy_file_api( const std::wstring & from, const std::wstring & to, bool fail_if_exists ); + +# endif +# endif + + template<class Path> + bool remove_aux( const Path & ph, file_status f ); + + template<class Path> + unsigned long remove_all_aux( const Path & ph, file_status f ); + + } // namespace detail + +// operations functions ----------------------------------------------------// + + // The non-template overloads enable automatic conversion from std and + // C-style strings. See basic_path constructors. The enable_if for the + // templates implements the famous "do-the-right-thing" rule. + +// query functions ---------------------------------------------------------// + + BOOST_INLINE_FS_FUNC(file_status) + status( const Path & ph, system::error_code & ec ) + { return detail::status_api( ph.external_file_string(), ec ); } + + BOOST_FS_FUNC(file_status) + status( const Path & ph ) + { + system::error_code ec; + file_status result( detail::status_api( ph.external_file_string(), ec ) ); + if ( ec ) + BOOST_FILESYSTEM_THROW( basic_filesystem_error<Path>( + "boost::filesystem::status", ph, ec ) ); + return result; + } + + BOOST_INLINE_FS_FUNC(file_status) + symlink_status( const Path & ph, system::error_code & ec ) +# ifdef BOOST_WINDOWS_API + { return detail::status_api( ph.external_file_string(), ec ); } +# else + { return detail::symlink_status_api( ph.external_file_string(), ec ); } +# endif + + BOOST_FS_FUNC(file_status) + symlink_status( const Path & ph ) + { + system::error_code ec; + file_status result( symlink_status( ph, ec ) ); + if ( ec ) + BOOST_FILESYSTEM_THROW( basic_filesystem_error<Path>( + "boost::filesystem::symlink_status", ph, ec ) ); + return result; + } + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + inline bool symbolic_link_exists( const path & ph ) + { return is_symlink( symlink_status(ph) ); } +# endif + + BOOST_FS_FUNC(bool) exists( const Path & ph ) + { + system::error_code ec; + file_status result( detail::status_api( ph.external_file_string(), ec ) ); + if ( ec ) + BOOST_FILESYSTEM_THROW( basic_filesystem_error<Path>( + "boost::filesystem::exists", ph, ec ) ); + return exists( result ); + } + + BOOST_FS_FUNC(bool) is_directory( const Path & ph ) + { + system::error_code ec; + file_status result( detail::status_api( ph.external_file_string(), ec ) ); + if ( ec ) + BOOST_FILESYSTEM_THROW( basic_filesystem_error<Path>( + "boost::filesystem::is_directory", ph, ec ) ); + return is_directory( result ); + } + + BOOST_FS_FUNC(bool) is_regular_file( const Path & ph ) + { + system::error_code ec; + file_status result( detail::status_api( ph.external_file_string(), ec ) ); + if ( ec ) + BOOST_FILESYSTEM_THROW( basic_filesystem_error<Path>( + "boost::filesystem::is_regular_file", ph, ec ) ); + return is_regular_file( result ); + } + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + BOOST_FS_FUNC(bool) is_regular( const Path & ph ) + { + system::error_code ec; + file_status result( detail::status_api( ph.external_file_string(), ec ) ); + if ( ec ) + BOOST_FILESYSTEM_THROW( basic_filesystem_error<Path>( + "boost::filesystem::is_regular", ph, ec ) ); + return is_regular( result ); + } +# endif + + BOOST_FS_FUNC(bool) is_other( const Path & ph ) + { + system::error_code ec; + file_status result( detail::status_api( ph.external_file_string(), ec ) ); + if ( ec ) + BOOST_FILESYSTEM_THROW( basic_filesystem_error<Path>( + "boost::filesystem::is_other", ph, ec ) ); + return is_other( result ); + } + + BOOST_FS_FUNC(bool) is_symlink( +# ifdef BOOST_WINDOWS_API + const Path & ) + { + return false; +# else + const Path & ph) + { + system::error_code ec; + file_status result( detail::symlink_status_api( ph.external_file_string(), ec ) ); + if ( ec ) + BOOST_FILESYSTEM_THROW( basic_filesystem_error<Path>( + "boost::filesystem::is_symlink", ph, ec ) ); + return is_symlink( result ); +# endif + } + + // VC++ 7.0 and earlier has a serious namespace bug that causes a clash + // between boost::filesystem2::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_FILESYSTEM_THROW( basic_filesystem_error<Path>( + "boost::filesystem::is_empty", ph, result.first ) ); + return result.second; + } + + BOOST_FS_FUNC(bool) equivalent( const Path & ph1, const Path & ph2 ) + { + detail::query_pair result( detail::equivalent_api( + ph1.external_file_string(), ph2.external_file_string() ) ); + if ( result.first ) + BOOST_FILESYSTEM_THROW( basic_filesystem_error<Path>( + "boost::filesystem::equivalent", ph1, ph2, result.first ) ); + return result.second; + } + + BOOST_FS_FUNC(boost::uintmax_t) file_size( const Path & ph ) + { + detail::uintmax_pair result + ( detail::file_size_api( ph.external_file_string() ) ); + if ( result.first ) + BOOST_FILESYSTEM_THROW( basic_filesystem_error<Path>( + "boost::filesystem::file_size", ph, result.first ) ); + return result.second; + } + + BOOST_FS_FUNC(space_info) space( const Path & ph ) + { + detail::space_pair result + ( detail::space_api( ph.external_file_string() ) ); + if ( result.first ) + BOOST_FILESYSTEM_THROW( basic_filesystem_error<Path>( + "boost::filesystem::space", ph, result.first ) ); + return result.second; + } + + BOOST_FS_FUNC(std::time_t) last_write_time( const Path & ph ) + { + detail::time_pair result + ( detail::last_write_time_api( ph.external_file_string() ) ); + if ( result.first ) + BOOST_FILESYSTEM_THROW( basic_filesystem_error<Path>( + "boost::filesystem::last_write_time", ph, result.first ) ); + return result.second; + } + + +// operations --------------------------------------------------------------// + + BOOST_FS_FUNC(bool) create_directory( const Path & dir_ph ) + { + detail::query_pair result( + detail::create_directory_api( dir_ph.external_directory_string() ) ); + if ( result.first ) + BOOST_FILESYSTEM_THROW( basic_filesystem_error<Path>( + "boost::filesystem::create_directory", + dir_ph, result.first ) ); + return result.second; + } + +#if !defined(BOOST_WINDOWS_API) || defined(BOOST_FS_HARD_LINK) + BOOST_FS_FUNC(void) + create_hard_link( const Path & to_ph, const Path & from_ph ) + { + system::error_code ec( + detail::create_hard_link_api( + to_ph.external_file_string(), + from_ph.external_file_string() ) ); + if ( ec ) + BOOST_FILESYSTEM_THROW( basic_filesystem_error<Path>( + "boost::filesystem::create_hard_link", + to_ph, from_ph, ec ) ); + } + + BOOST_FS_FUNC(system::error_code) + create_hard_link( const Path & to_ph, const Path & from_ph, + system::error_code & ec ) + { + ec = detail::create_hard_link_api( + to_ph.external_file_string(), + from_ph.external_file_string() ); + return ec; + } +#endif + + BOOST_FS_FUNC(void) + create_symlink( const Path & to_ph, const Path & from_ph ) + { + system::error_code ec( + detail::create_symlink_api( + to_ph.external_file_string(), + from_ph.external_file_string() ) ); + if ( ec ) + BOOST_FILESYSTEM_THROW( basic_filesystem_error<Path>( + "boost::filesystem::create_symlink", + to_ph, from_ph, ec ) ); + } + + BOOST_FS_FUNC(system::error_code) + create_symlink( const Path & to_ph, const Path & from_ph, + system::error_code & ec ) + { + ec = detail::create_symlink_api( + to_ph.external_file_string(), + from_ph.external_file_string() ); + return ec; + } + + BOOST_FS_FUNC(bool) remove( const Path & ph ) + { + system::error_code ec; + file_status f = symlink_status( ph, ec ); + if ( ec ) + BOOST_FILESYSTEM_THROW( basic_filesystem_error<Path>( + "boost::filesystem::remove", ph, ec ) ); + return detail::remove_aux( ph, f ); + } + + BOOST_FS_FUNC(unsigned long) remove_all( const Path & ph ) + { + system::error_code ec; + file_status f = symlink_status( ph, ec ); + if ( ec ) + BOOST_FILESYSTEM_THROW( basic_filesystem_error<Path>( + "boost::filesystem::remove_all", ph, ec ) ); + return exists( f ) ? detail::remove_all_aux( ph, f ) : 0; + } + + BOOST_FS_FUNC(void) rename( const Path & from_path, const Path & to_path ) + { + system::error_code ec( detail::rename_api( + from_path.external_directory_string(), + to_path.external_directory_string() ) ); + if ( ec ) + BOOST_FILESYSTEM_THROW( basic_filesystem_error<Path>( + "boost::filesystem::rename", + from_path, to_path, ec ) ); + } + + BOOST_SCOPED_ENUM_START(copy_option) + { fail_if_exists, overwrite_if_exists }; + BOOST_SCOPED_ENUM_END + + BOOST_FS_FUNC(void) copy_file( const Path & from_path, const Path & to_path, + BOOST_SCOPED_ENUM(copy_option) option = copy_option::fail_if_exists ) + { + system::error_code ec( detail::copy_file_api( + from_path.external_directory_string(), + to_path.external_directory_string(), option == copy_option::fail_if_exists ) ); + if ( ec ) + BOOST_FILESYSTEM_THROW( basic_filesystem_error<Path>( + "boost::filesystem::copy_file", + from_path, to_path, ec ) ); + } + + template< class Path > + Path current_path() + { + typename Path::external_string_type ph; + system::error_code ec( detail::get_current_path_api( ph ) ); + if ( ec ) + BOOST_FILESYSTEM_THROW( basic_filesystem_error<Path>( + "boost::filesystem::current_path", ec ) ); + return Path( Path::traits_type::to_internal( ph ) ); + } + + BOOST_FS_FUNC(void) current_path( const Path & ph ) + { + system::error_code ec( detail::set_current_path_api( + ph.external_directory_string() ) ); + if ( ec ) + BOOST_FILESYSTEM_THROW( basic_filesystem_error<Path>( + "boost::filesystem::current_path", ph, ec ) ); + } + + template< class Path > + const Path & initial_path() + { + static Path init_path; + if ( init_path.empty() ) init_path = current_path<Path>(); + return init_path; + } + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + // legacy support + inline path current_path() // overload supports pre-i18n apps + { return current_path<boost::filesystem2::path>(); } + inline const path & initial_path() // overload supports pre-i18n apps + { return initial_path<boost::filesystem2::path>(); } +# endif + + BOOST_FS_FUNC(Path) system_complete( const Path & ph ) + { +# ifdef BOOST_WINDOWS_API + if ( ph.empty() ) return ph; + BOOST_FS_TYPENAME Path::external_string_type sys_ph; + system::error_code ec( detail::get_full_path_name_api( ph.external_file_string(), + sys_ph ) ); + if ( ec ) + BOOST_FILESYSTEM_THROW( basic_filesystem_error<Path>( + "boost::filesystem::system_complete", ph, ec ) ); + return Path( Path::traits_type::to_internal( sys_ph ) ); +# else + return (ph.empty() || ph.is_complete()) + ? ph : current_path<Path>() / ph; +# endif + } + + BOOST_FS_FUNC(Path) + complete( const Path & ph, + const Path & base/* = initial_path<Path>() */) + { + BOOST_ASSERT( base.is_complete() + && (ph.is_complete() || !ph.has_root_name()) + && "boost::filesystem::complete() precondition not met" ); +# ifdef BOOST_WINDOWS_PATH + if (ph.empty() || ph.is_complete()) return ph; + if ( !ph.has_root_name() ) + return ph.has_root_directory() + ? Path( base.root_name() ) / ph + : base / ph; + return base / ph; +# else + return (ph.empty() || ph.is_complete()) ? ph : base / ph; +# endif + } + + // VC++ 7.1 had trouble with default arguments, so separate one argument + // signatures are provided as workarounds; the effect is the same. + BOOST_FS_FUNC(Path) complete( const Path & ph ) + { return complete( ph, initial_path<Path>() ); } + + BOOST_FS_FUNC(void) + last_write_time( const Path & ph, const std::time_t new_time ) + { + system::error_code ec( detail::last_write_time_api( ph.external_file_string(), + new_time ) ); + if ( ec ) + BOOST_FILESYSTEM_THROW( basic_filesystem_error<Path>( + "boost::filesystem::last_write_time", ph, ec ) ); + } + +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY + + // "do-the-right-thing" overloads ---------------------------------------// + + inline file_status status( const path & ph ) + { return status<path>( ph ); } + inline file_status status( const wpath & ph ) + { return status<wpath>( ph ); } + + inline file_status status( const path & ph, system::error_code & ec ) + { return status<path>( ph, ec ); } + inline file_status status( const wpath & ph, system::error_code & ec ) + { return status<wpath>( ph, ec ); } + + inline file_status symlink_status( const path & ph ) + { return symlink_status<path>( ph ); } + inline file_status symlink_status( const wpath & ph ) + { return symlink_status<wpath>( ph ); } + + inline file_status symlink_status( const path & ph, system::error_code & ec ) + { return symlink_status<path>( ph, ec ); } + inline file_status symlink_status( const wpath & ph, system::error_code & ec ) + { return symlink_status<wpath>( ph, ec ); } + + inline bool exists( const path & ph ) { return exists<path>( ph ); } + inline bool exists( const wpath & ph ) { return exists<wpath>( ph ); } + + inline bool is_directory( const path & ph ) + { return is_directory<path>( ph ); } + inline bool is_directory( const wpath & ph ) + { return is_directory<wpath>( ph ); } + + inline bool is_regular_file( const path & ph ) + { return is_regular_file<path>( ph ); } + inline bool is_regular_file( const wpath & ph ) + { return is_regular_file<wpath>( ph ); } + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + inline bool is_regular( const path & ph ) + { return is_regular<path>( ph ); } + inline bool is_regular( const wpath & ph ) + { return is_regular<wpath>( ph ); } +# endif + + inline bool is_other( const path & ph ) + { return is_other<path>( ph ); } + inline bool is_other( const wpath & ph ) + { return is_other<wpath>( ph ); } + + inline bool is_symlink( const path & ph ) + { return is_symlink<path>( ph ); } + inline bool is_symlink( const wpath & ph ) + { return is_symlink<wpath>( ph ); } + + inline bool is_empty( const path & ph ) + { return boost::filesystem2::is_empty<path>( ph ); } + inline bool is_empty( const wpath & ph ) + { return boost::filesystem2::is_empty<wpath>( ph ); } + + inline bool equivalent( const path & ph1, const path & ph2 ) + { return equivalent<path>( ph1, ph2 ); } + inline bool equivalent( const wpath & ph1, const wpath & ph2 ) + { return equivalent<wpath>( ph1, ph2 ); } + + inline boost::uintmax_t file_size( const path & ph ) + { return file_size<path>( ph ); } + inline boost::uintmax_t file_size( const wpath & ph ) + { return file_size<wpath>( ph ); } + + inline space_info space( const path & ph ) + { return space<path>( ph ); } + inline space_info space( const wpath & ph ) + { return space<wpath>( ph ); } + + inline std::time_t last_write_time( const path & ph ) + { return last_write_time<path>( ph ); } + inline std::time_t last_write_time( const wpath & ph ) + { return last_write_time<wpath>( ph ); } + + inline bool create_directory( const path & dir_ph ) + { return create_directory<path>( dir_ph ); } + inline bool create_directory( const wpath & dir_ph ) + { return create_directory<wpath>( dir_ph ); } + +#if !defined(BOOST_WINDOWS_API) || defined(BOOST_FS_HARD_LINK) + inline void create_hard_link( const path & to_ph, + const path & from_ph ) + { return create_hard_link<path>( to_ph, from_ph ); } + inline void create_hard_link( const wpath & to_ph, + const wpath & from_ph ) + { return create_hard_link<wpath>( to_ph, from_ph ); } + + inline system::error_code create_hard_link( const path & to_ph, + const path & from_ph, system::error_code & ec ) + { return create_hard_link<path>( to_ph, from_ph, ec ); } + inline system::error_code create_hard_link( const wpath & to_ph, + const wpath & from_ph, system::error_code & ec ) + { return create_hard_link<wpath>( to_ph, from_ph, ec ); } +#endif + + inline void create_symlink( const path & to_ph, + const path & from_ph ) + { return create_symlink<path>( to_ph, from_ph ); } + inline void create_symlink( const wpath & to_ph, + const wpath & from_ph ) + { return create_symlink<wpath>( to_ph, from_ph ); } + + inline system::error_code create_symlink( const path & to_ph, + const path & from_ph, system::error_code & ec ) + { return create_symlink<path>( to_ph, from_ph, ec ); } + inline system::error_code create_symlink( const wpath & to_ph, + const wpath & from_ph, system::error_code & ec ) + { return create_symlink<wpath>( to_ph, from_ph, ec ); } + + inline bool remove( const path & ph ) + { return remove<path>( ph ); } + inline bool remove( const wpath & ph ) + { return remove<wpath>( ph ); } + + inline unsigned long remove_all( const path & ph ) + { return remove_all<path>( ph ); } + inline unsigned long remove_all( const wpath & ph ) + { return remove_all<wpath>( ph ); } + + inline void rename( const path & from_path, const path & to_path ) + { return rename<path>( from_path, to_path ); } + inline void rename( const wpath & from_path, const wpath & to_path ) + { return rename<wpath>( from_path, to_path ); } + + inline void copy_file( const path & from_path, const path & to_path ) + { return copy_file<path>( from_path, to_path ); } + inline void copy_file( const wpath & from_path, const wpath & to_path ) + { return copy_file<wpath>( from_path, to_path ); } + + inline path system_complete( const path & ph ) + { return system_complete<path>( ph ); } + inline wpath system_complete( const wpath & ph ) + { return system_complete<wpath>( ph ); } + + inline path complete( const path & ph, + const path & base/* = initial_path<path>()*/ ) + { return complete<path>( ph, base ); } + inline wpath complete( const wpath & ph, + const wpath & base/* = initial_path<wpath>()*/ ) + { return complete<wpath>( ph, base ); } + + inline path complete( const path & ph ) + { return complete<path>( ph, initial_path<path>() ); } + inline wpath complete( const wpath & ph ) + { return complete<wpath>( ph, initial_path<wpath>() ); } + + inline void last_write_time( const path & ph, const std::time_t new_time ) + { last_write_time<path>( ph, new_time ); } + inline void last_write_time( const wpath & ph, const std::time_t new_time ) + { last_write_time<wpath>( ph, new_time ); } + + inline void current_path( const path & ph ) + { current_path<path>( ph ); } + inline void current_path( const wpath & ph ) + { current_path<wpath>( ph ); } + +# endif // ifndef BOOST_FILESYSTEM2_NARROW_ONLY + + namespace detail + { + template<class Path> + bool remove_aux( const Path & ph, file_status f ) + { + if ( exists( f ) ) + { + system::error_code ec = remove_api( ph.external_file_string() ); + if ( ec ) + BOOST_FILESYSTEM_THROW( basic_filesystem_error<Path>( + "boost::filesystem::remove", ph, ec ) ); + return true; + } + return false; + } + + template<class Path> + unsigned long remove_all_aux( const Path & ph, file_status f ) + { + static const boost::filesystem2::basic_directory_iterator<Path> end_itr; + unsigned long count = 1; + if ( !boost::filesystem2::is_symlink( f ) // don't recurse symbolic links + && boost::filesystem2::is_directory( f ) ) + { + for ( boost::filesystem2::basic_directory_iterator<Path> itr( ph ); + itr != end_itr; ++itr ) + { + boost::system::error_code ec; + boost::filesystem2::file_status fn = boost::filesystem2::symlink_status( itr->path(), ec ); + if ( ec ) + BOOST_FILESYSTEM_THROW( basic_filesystem_error<Path>( + "boost::filesystem:remove_all", ph, ec ) ); + count += remove_all_aux( itr->path(), fn ); + } + } + remove_aux( ph, f ); + return count; + } + +// test helper -------------------------------------------------------------// + + // not part of the documented interface because false positives are possible; + // there is no law that says that an OS that has large stat.st_size + // actually supports large file sizes. + BOOST_FILESYSTEM_DECL bool possible_large_file_size_support(); + +// directory_iterator helpers ----------------------------------------------// + +// forwarding functions avoid need for BOOST_FILESYSTEM_DECL for class +// basic_directory_iterator, and so avoid iterator_facade DLL template +// problems. They also overload to the proper external path character type. + + BOOST_FILESYSTEM_DECL system::error_code + dir_itr_first( void *& handle, +#if defined(BOOST_POSIX_API) + void *& buffer, +#endif + const std::string & dir_path, + std::string & target, file_status & fs, file_status & symlink_fs ); + // eof: return==0 && handle==0 + + BOOST_FILESYSTEM_DECL system::error_code + dir_itr_increment( void *& handle, +#if defined(BOOST_POSIX_API) + void *& buffer, +#endif + std::string & target, file_status & fs, file_status & symlink_fs ); + // eof: return==0 && handle==0 + + BOOST_FILESYSTEM_DECL system::error_code + dir_itr_close( void *& handle +#if defined(BOOST_POSIX_API) + , void *& buffer +#endif + ); + // Effects: none if handle==0, otherwise close handle, set handle=0 + +# if defined(BOOST_WINDOWS_API) && !defined(BOOST_FILESYSTEM2_NARROW_ONLY) + BOOST_FILESYSTEM_DECL system::error_code + dir_itr_first( void *& handle, const std::wstring & ph, + std::wstring & target, file_status & fs, file_status & symlink_fs ); + BOOST_FILESYSTEM_DECL system::error_code + dir_itr_increment( void *& handle, std::wstring & target, + file_status & fs, file_status & symlink_fs ); +# endif + + template< class Path > + class dir_itr_imp + { + public: + basic_directory_entry<Path> m_directory_entry; + void * m_handle; +# ifdef BOOST_POSIX_API + void * m_buffer; // see dir_itr_increment implementation +# endif + dir_itr_imp() : m_handle(0) +# ifdef BOOST_POSIX_API + , m_buffer(0) +# endif + {} + + ~dir_itr_imp() { dir_itr_close( m_handle +#if defined(BOOST_POSIX_API) + , m_buffer +#endif + ); } + }; + + BOOST_FILESYSTEM_DECL system::error_code not_found_error(); + + } // namespace detail + +// basic_directory_iterator ------------------------------------------------// + + template< class Path > + class basic_directory_iterator + : public boost::iterator_facade< + basic_directory_iterator<Path>, + basic_directory_entry<Path>, + boost::single_pass_traversal_tag > + { + public: + typedef Path path_type; + + basic_directory_iterator(){} // creates the "end" iterator + + explicit basic_directory_iterator( const Path & dir_path ); + basic_directory_iterator( const Path & dir_path, system::error_code & ec ); + + private: + + // shared_ptr provides shallow-copy semantics required for InputIterators. + // m_imp.get()==0 indicates the end iterator. + boost::shared_ptr< detail::dir_itr_imp< Path > > m_imp; + + friend class boost::iterator_core_access; + + typename boost::iterator_facade< + basic_directory_iterator<Path>, + basic_directory_entry<Path>, + boost::single_pass_traversal_tag >::reference dereference() const + { + BOOST_ASSERT( m_imp.get() && "attempt to dereference end iterator" ); + return m_imp->m_directory_entry; + } + + void increment(); + + bool equal( const basic_directory_iterator & rhs ) const + { return m_imp == rhs.m_imp; } + + system::error_code m_init( const Path & dir_path ); + }; + + typedef basic_directory_iterator< path > directory_iterator; +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY + typedef basic_directory_iterator< wpath > wdirectory_iterator; +# endif + + // basic_directory_iterator implementation ---------------------------// + + template<class Path> + system::error_code basic_directory_iterator<Path>::m_init( + const Path & dir_path ) + { + if ( dir_path.empty() ) + { + m_imp.reset(); + return detail::not_found_error(); + } + typename Path::external_string_type name; + file_status fs, symlink_fs; + system::error_code ec( detail::dir_itr_first( m_imp->m_handle, +#if defined(BOOST_POSIX_API) + m_imp->m_buffer, +#endif + dir_path.external_directory_string(), + name, fs, symlink_fs ) ); + + if ( ec ) + { + m_imp.reset(); + return ec; + } + + if ( m_imp->m_handle == 0 ) m_imp.reset(); // eof, so make end iterator + else // not eof + { + m_imp->m_directory_entry.assign( dir_path + / Path::traits_type::to_internal( name ), fs, symlink_fs ); + if ( name[0] == dot<Path>::value // dot or dot-dot + && (name.size() == 1 + || (name[1] == dot<Path>::value + && name.size() == 2)) ) + { increment(); } + } + return boost::system::error_code(); + } + + template<class Path> + basic_directory_iterator<Path>::basic_directory_iterator( + const Path & dir_path ) + : m_imp( new detail::dir_itr_imp<Path> ) + { + system::error_code ec( m_init(dir_path) ); + if ( ec ) + { + BOOST_FILESYSTEM_THROW( basic_filesystem_error<Path>( + "boost::filesystem::basic_directory_iterator constructor", + dir_path, ec ) ); + } + } + + template<class Path> + basic_directory_iterator<Path>::basic_directory_iterator( + const Path & dir_path, system::error_code & ec ) + : m_imp( new detail::dir_itr_imp<Path> ) + { + ec = m_init(dir_path); + } + + template<class Path> + void basic_directory_iterator<Path>::increment() + { + BOOST_ASSERT( m_imp.get() && "attempt to increment end iterator" ); + BOOST_ASSERT( m_imp->m_handle != 0 && "internal program error" ); + + typename Path::external_string_type name; + file_status fs, symlink_fs; + system::error_code ec; + + for (;;) + { + ec = detail::dir_itr_increment( m_imp->m_handle, +#if defined(BOOST_POSIX_API) + m_imp->m_buffer, +#endif + name, fs, symlink_fs ); + if ( ec ) + { + BOOST_FILESYSTEM_THROW( basic_filesystem_error<Path>( + "boost::filesystem::basic_directory_iterator increment", + m_imp->m_directory_entry.path().parent_path(), ec ) ); + } + if ( m_imp->m_handle == 0 ) { m_imp.reset(); return; } // eof, make end + if ( !(name[0] == dot<Path>::value // !(dot or dot-dot) + && (name.size() == 1 + || (name[1] == dot<Path>::value + && name.size() == 2))) ) + { + m_imp->m_directory_entry.replace_filename( + Path::traits_type::to_internal( name ), fs, symlink_fs ); + return; + } + } + } + + // basic_directory_entry -----------------------------------------------// + + template<class Path> + class basic_directory_entry + { + public: + typedef Path path_type; + typedef typename Path::string_type string_type; + + // compiler generated copy-ctor, copy assignment, and destructor apply + + basic_directory_entry() {} + explicit basic_directory_entry( const path_type & 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 path_type & p, + file_status st, file_status symlink_st ) + { m_path = p; m_status = st; m_symlink_status = symlink_st; } + + void replace_filename( const string_type & s, + file_status st, file_status symlink_st ) + { + m_path.remove_filename(); + m_path /= s; + m_status = st; + m_symlink_status = symlink_st; + } + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + void replace_leaf( const string_type & s, + file_status st, file_status symlink_st ) + { replace_filename( s, st, symlink_st ); } +# endif + + const Path & path() const { return m_path; } + file_status status() const; + file_status status( system::error_code & ec ) const; + file_status symlink_status() const; + file_status symlink_status( system::error_code & ec ) const; + + // conversion simplifies the most common use of basic_directory_entry + operator const path_type &() 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: + path_type m_path; + mutable file_status m_status; // stat()-like + mutable file_status m_symlink_status; // lstat()-like + // note: m_symlink_status is not used by Windows implementation + + }; // basic_directory_status + + typedef basic_directory_entry<path> directory_entry; +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY + typedef basic_directory_entry<wpath> wdirectory_entry; +# endif + + // basic_directory_entry implementation --------------------------------// + + template<class Path> + file_status + basic_directory_entry<Path>::status() const + { + if ( !status_known( m_status ) ) + { +# ifndef BOOST_WINDOWS_API + if ( status_known( m_symlink_status ) + && !is_symlink( m_symlink_status ) ) + { m_status = m_symlink_status; } + else { m_status = boost::filesystem2::status( m_path ); } +# else + m_status = boost::filesystem2::status( m_path ); +# endif + } + return m_status; + } + + template<class Path> + file_status + basic_directory_entry<Path>::status( system::error_code & ec ) const + { + if ( !status_known( m_status ) ) + { +# ifndef BOOST_WINDOWS_API + if ( status_known( m_symlink_status ) + && !is_symlink( m_symlink_status ) ) + { ec = boost::system::error_code();; m_status = m_symlink_status; } + else { m_status = boost::filesystem2::status( m_path, ec ); } +# else + m_status = boost::filesystem2::status( m_path, ec ); +# endif + } + else ec = boost::system::error_code();; + return m_status; + } + + template<class Path> + file_status + basic_directory_entry<Path>::symlink_status() const + { +# ifndef BOOST_WINDOWS_API + if ( !status_known( m_symlink_status ) ) + { m_symlink_status = boost::filesystem2::symlink_status( m_path ); } + return m_symlink_status; +# else + return status(); +# endif + } + + template<class Path> + file_status + basic_directory_entry<Path>::symlink_status( system::error_code & ec ) const + { +# ifndef BOOST_WINDOWS_API + if ( !status_known( m_symlink_status ) ) + { m_symlink_status = boost::filesystem2::symlink_status( m_path, ec ); } + else ec = boost::system::error_code();; + return m_symlink_status; +# else + return status( ec ); +# endif + } + } // namespace filesystem2 +} // namespace boost + +#undef BOOST_FS_FUNC + +//----------------------------------------------------------------------------// + +namespace boost +{ + namespace filesystem + { + using filesystem2::basic_directory_entry; + using filesystem2::basic_directory_iterator; + using filesystem2::block_file; + using filesystem2::character_file; + using filesystem2::complete; + using filesystem2::copy_file; + using filesystem2::copy_option; + using filesystem2::create_directory; +# if !defined(BOOST_WINDOWS_API) || defined(BOOST_FS_HARD_LINK) + using filesystem2::create_hard_link; +# endif + using filesystem2::create_symlink; + using filesystem2::current_path; + using filesystem2::directory_entry; + using filesystem2::directory_file; + using filesystem2::directory_iterator; + using filesystem2::equivalent; + using filesystem2::exists; + using filesystem2::fifo_file; + using filesystem2::file_not_found; + using filesystem2::file_size; + using filesystem2::file_status; + using filesystem2::file_type; + using filesystem2::initial_path; + using filesystem2::is_directory; + using filesystem2::is_directory; + using filesystem2::is_empty; + using filesystem2::is_other; + using filesystem2::is_regular_file; + using filesystem2::is_symlink; + using filesystem2::last_write_time; + using filesystem2::regular_file; + using filesystem2::remove; + using filesystem2::remove_all; + using filesystem2::rename; + using filesystem2::socket_file; + using filesystem2::space; + using filesystem2::space_info; + using filesystem2::status; + using filesystem2::status_known; + using filesystem2::symlink_file; + using filesystem2::symlink_status; + using filesystem2::system_complete; + using filesystem2::type_unknown; +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + using filesystem2::is_regular; + using filesystem2::symbolic_link_exists; +# endif +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY + using filesystem2::wdirectory_iterator; + using filesystem2::wdirectory_entry; +# endif + namespace detail + { + using filesystem2::detail::not_found_error; + using filesystem2::detail::possible_large_file_size_support; + } + } +} + +#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas +#endif // BOOST_FILESYSTEM2_OPERATIONS_HPP diff --git a/boost/filesystem/v2/path.hpp b/boost/filesystem/v2/path.hpp new file mode 100644 index 0000000..615b89c --- /dev/null +++ b/boost/filesystem/v2/path.hpp @@ -0,0 +1,1571 @@ +// boost/filesystem/path.hpp -----------------------------------------------// + +// Copyright Beman Dawes 2002-2005 +// 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. + +//----------------------------------------------------------------------------// + +#ifndef BOOST_FILESYSTEM2_PATH_HPP +#define BOOST_FILESYSTEM2_PATH_HPP + +#include <boost/filesystem/v2/config.hpp> +#include <boost/system/system_error.hpp> +#include <boost/iterator/iterator_facade.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/static_assert.hpp> +#include <boost/assert.hpp> + +#include <string> +#include <algorithm> // for lexicographical_compare +#include <iosfwd> // needed by basic_path inserter and extractor +#include <stdexcept> + +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY +# include <locale> +# endif + +#include <boost/config/abi_prefix.hpp> // must be the last #include + +namespace boost +{ + namespace BOOST_FILESYSTEM2_NAMESPACE + { + template<class String, class Traits> class basic_path; + + struct path_traits; + typedef basic_path< std::string, path_traits > path; + + struct path_traits + { + typedef std::string internal_string_type; + typedef std::string external_string_type; + static external_string_type to_external( const path &, + const internal_string_type & src ) { return src; } + static internal_string_type to_internal( + const external_string_type & src ) { return src; } + }; + +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY + + struct BOOST_FILESYSTEM_DECL wpath_traits; + + typedef basic_path< std::wstring, wpath_traits > wpath; + + struct BOOST_FILESYSTEM_DECL wpath_traits + { + typedef std::wstring internal_string_type; +# ifdef BOOST_WINDOWS_API + typedef std::wstring external_string_type; + static external_string_type to_external( const wpath &, + const internal_string_type & src ) { return src; } + static internal_string_type to_internal( + const external_string_type & src ) { return src; } +# else + typedef std::string external_string_type; + static external_string_type to_external( const wpath & ph, + const internal_string_type & src ); + static internal_string_type to_internal( + const external_string_type & src ); +# endif + static void imbue( const std::locale & loc ); + static bool imbue( const std::locale & loc, const std::nothrow_t & ); + }; + +# endif // ifndef BOOST_FILESYSTEM2_NARROW_ONLY + + // path traits ---------------------------------------------------------// + + template<class Path> struct is_basic_path + { BOOST_STATIC_CONSTANT( bool, value = false ); }; + template<> struct is_basic_path<path> + { BOOST_STATIC_CONSTANT( bool, value = true ); }; +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY + template<> struct is_basic_path<wpath> + { BOOST_STATIC_CONSTANT( bool, value = true ); }; +# endif + + // These only have to be specialized if Path::string_type::value_type + // is not convertible from char, although specializations may eliminate + // compiler warnings. See ticket 2543. + template<class Path> struct slash + { BOOST_STATIC_CONSTANT( char, value = '/' ); }; + + template<class Path> struct dot + { BOOST_STATIC_CONSTANT( char, value = '.' ); }; + + template<class Path> struct colon + { BOOST_STATIC_CONSTANT( char, value = ':' ); }; + +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY + template<> struct slash<wpath> + { BOOST_STATIC_CONSTANT( wchar_t, value = L'/' ); }; + template<> struct dot<wpath> + { BOOST_STATIC_CONSTANT( wchar_t, value = L'.' ); }; + template<> struct colon<wpath> + { BOOST_STATIC_CONSTANT( wchar_t, value = L':' ); }; +# endif + +# ifdef BOOST_WINDOWS_PATH + template<class Path> struct path_alt_separator + { BOOST_STATIC_CONSTANT( char, value = '\\' ); }; +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY + template<> struct path_alt_separator<wpath> + { BOOST_STATIC_CONSTANT( wchar_t, value = L'\\' ); }; +# endif +# endif + + // workaround for VC++ 7.0 and earlier issues with nested classes + namespace detail + { + template<class Path> + class iterator_helper + { + public: + typedef typename Path::iterator iterator; + static void do_increment( iterator & ph ); + static void do_decrement( iterator & ph ); + }; + } + + // basic_path ----------------------------------------------------------// + + template<class String, class Traits> + class basic_path + { + // invariant: m_path valid according to the portable generic path grammar + + // validate template arguments +// TODO: get these working +// BOOST_STATIC_ASSERT( ::boost::is_same<String,typename Traits::internal_string_type>::value ); +// BOOST_STATIC_ASSERT( ::boost::is_same<typename Traits::external_string_type,std::string>::value || ::boost::is_same<typename Traits::external_string_type,std::wstring>::value ); + + public: + // compiler generates copy constructor and copy assignment + + 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 string_type & s ) { operator/=( s ); } + basic_path( const value_type * s ) { operator/=( s ); } +# ifndef BOOST_NO_MEMBER_TEMPLATES + template <class InputIterator> + basic_path( InputIterator first, InputIterator last ) + { append( first, last ); } +# endif + ~basic_path() {} + + // assignments + basic_path & operator=( const string_type & s ) + { +# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, >= 310) + m_path.clear(); +# else + m_path.erase( m_path.begin(), m_path.end() ); +# endif + operator/=( s ); + return *this; + } + basic_path & operator=( const value_type * s ) + { +# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, >= 310) + m_path.clear(); +# else + m_path.erase( m_path.begin(), m_path.end() ); +# endif + operator/=( s ); + return *this; + } +# ifndef BOOST_NO_MEMBER_TEMPLATES + template <class InputIterator> + basic_path & assign( InputIterator first, InputIterator last ) + { m_path.clear(); append( first, last ); return *this; } +# endif + + // modifiers + basic_path & operator/=( const basic_path & rhs ) { return operator /=( rhs.string().c_str() ); } + basic_path & operator/=( const string_type & rhs ) { return operator /=( rhs.c_str() ); } + basic_path & operator/=( const value_type * s ); +# ifndef BOOST_NO_MEMBER_TEMPLATES + template <class InputIterator> + basic_path & append( InputIterator first, InputIterator last ); +# endif + + void clear() + { +# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, >= 310) + m_path.clear(); +# else + m_path.erase( m_path.begin(), m_path.end() ); +# endif + } + + void swap( basic_path & rhs ) + { + m_path.swap( rhs.m_path ); +# ifdef BOOST_CYGWIN_PATH + std::swap( m_cygwin_root, rhs.m_cygwin_root ); +# endif + } + + basic_path & remove_filename(); + basic_path & replace_extension( const string_type & new_extension = string_type() ); + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + basic_path & remove_leaf() { return remove_filename(); } +# endif + + // observers + const string_type & string() const { return m_path; } + const string_type file_string() const; + const string_type directory_string() const { return file_string(); } + + const external_string_type external_file_string() const { return Traits::to_external( *this, file_string() ); } + const external_string_type external_directory_string() const { return Traits::to_external( *this, directory_string() ); } + + basic_path root_path() const; + string_type root_name() const; + string_type root_directory() const; + basic_path relative_path() const; + basic_path parent_path() const; + string_type filename() const; + string_type stem() const; + string_type extension() const; + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + string_type leaf() const { return filename(); } + basic_path branch_path() const { return parent_path(); } + bool has_leaf() const { return !m_path.empty(); } + bool has_branch_path() const { return !parent_path().empty(); } +# endif + + bool empty() const { return m_path.empty(); } // name consistent with std containers + bool is_complete() const; + bool has_root_path() const; + bool has_root_name() const; + bool has_root_directory() const; + 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(); } + + // iterators + class iterator : public boost::iterator_facade< + iterator, + string_type const, + boost::bidirectional_traversal_tag > + { + private: + friend class boost::iterator_core_access; + friend class boost::BOOST_FILESYSTEM2_NAMESPACE::basic_path<String, Traits>; + + const string_type & dereference() const + { return m_name; } + bool equal( const iterator & rhs ) const + { return m_path_ptr == rhs.m_path_ptr && m_pos == rhs.m_pos; } + + friend class boost::BOOST_FILESYSTEM2_NAMESPACE::detail::iterator_helper<path_type>; + + void increment() + { + boost::BOOST_FILESYSTEM2_NAMESPACE::detail::iterator_helper<path_type>::do_increment( + *this ); + } + void decrement() + { + boost::BOOST_FILESYSTEM2_NAMESPACE::detail::iterator_helper<path_type>::do_decrement( + *this ); + } + + string_type m_name; // current element + const basic_path * m_path_ptr; // path being iterated over + typename string_type::size_type m_pos; // position of name in + // path_ptr->string(). The + // end() iterator is indicated by + // pos == path_ptr->m_path.size() + }; // iterator + + typedef iterator const_iterator; + + iterator begin() const; + iterator end() const; + + private: + // Note: This is an implementation for POSIX and Windows, where there + // are only minor differences between generic and native path grammars. + // Private members might be quite different in other implementations, + // particularly where there were wide differences between portable and + // native path formats, or between file_string() and + // directory_string() formats, or simply that the implementation + // was willing expend additional memory to achieve greater speed for + // some operations at the expense of other operations. + + string_type m_path; // invariant: portable path grammar + // on Windows, backslashes converted to slashes + +# ifdef BOOST_CYGWIN_PATH + bool m_cygwin_root; // if present, m_path[0] was slash. note: initialization + // done by append +# endif + + void m_append_separator_if_needed(); + void m_append( value_type value ); // converts Windows alt_separator + + // Was qualified; como433beta8 reports: + // warning #427-D: qualified name is not allowed in member declaration + friend class iterator; + friend class boost::BOOST_FILESYSTEM2_NAMESPACE::detail::iterator_helper<path_type>; + + // Deprecated features ease transition for existing code. Don't use these + // in new code. +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + public: + typedef bool (*name_check)( const std::string & name ); + basic_path( const string_type & str, name_check ) { operator/=( str ); } + basic_path( const typename string_type::value_type * s, name_check ) + { operator/=( s );} + string_type native_file_string() const { return file_string(); } + string_type native_directory_string() const { return directory_string(); } + static bool default_name_check_writable() { return false; } + static void default_name_check( name_check ) {} + static name_check default_name_check() { return 0; } + basic_path & canonize(); + basic_path & normalize(); +# endif + }; + + // basic_path non-member functions ---------------------------------------// + + template< class String, class Traits > + inline void swap( basic_path<String, Traits> & lhs, + basic_path<String, Traits> & rhs ) { lhs.swap( rhs ); } + + template< class String, class Traits > + bool operator<( const basic_path<String, Traits> & lhs, const basic_path<String, Traits> & rhs ) + { + return std::lexicographical_compare( + lhs.begin(), lhs.end(), rhs.begin(), rhs.end() ); + } + + template< class String, class Traits > + bool operator<( const typename basic_path<String, Traits>::string_type::value_type * lhs, + const basic_path<String, Traits> & rhs ) + { + basic_path<String, Traits> tmp( lhs ); + return std::lexicographical_compare( + tmp.begin(), tmp.end(), rhs.begin(), rhs.end() ); + } + + template< class String, class Traits > + bool operator<( const typename basic_path<String, Traits>::string_type & lhs, + const basic_path<String, Traits> & rhs ) + { + basic_path<String, Traits> tmp( lhs ); + return std::lexicographical_compare( + tmp.begin(), tmp.end(), rhs.begin(), rhs.end() ); + } + + template< class String, class Traits > + bool operator<( const basic_path<String, Traits> & lhs, + const typename basic_path<String, Traits>::string_type::value_type * rhs ) + { + basic_path<String, Traits> tmp( rhs ); + return std::lexicographical_compare( + lhs.begin(), lhs.end(), tmp.begin(), tmp.end() ); + } + + template< class String, class Traits > + bool operator<( const basic_path<String, Traits> & lhs, + const typename basic_path<String, Traits>::string_type & rhs ) + { + basic_path<String, Traits> tmp( rhs ); + return std::lexicographical_compare( + lhs.begin(), lhs.end(), tmp.begin(), tmp.end() ); + } + + // operator == uses hand-written compare rather than !(lhs < rhs) && !(rhs < lhs) + // because the result is the same yet the direct compare is much more efficient + // than lexicographical_compare, which would also be called twice. + + template< class String, class Traits > + inline bool operator==( const basic_path<String, Traits> & lhs, + const typename basic_path<String, Traits>::string_type::value_type * rhs ) + { + typedef typename + boost::BOOST_FILESYSTEM2_NAMESPACE::basic_path<String, Traits> path_type; + const typename path_type::string_type::value_type * l (lhs.string().c_str()); + while ( (*l == *rhs +# ifdef BOOST_WINDOWS_PATH + || (*l == path_alt_separator<path_type>::value && *rhs == slash<path_type>::value) + || (*l == slash<path_type>::value && *rhs == path_alt_separator<path_type>::value) +# endif + ) && *l ) { ++l; ++rhs; } + return *l == *rhs +# ifdef BOOST_WINDOWS_PATH + || (*l == path_alt_separator<path_type>::value && *rhs == slash<path_type>::value) + || (*l == slash<path_type>::value && *rhs == path_alt_separator<path_type>::value) +# endif + ; + } + + template< class String, class Traits > + inline bool operator==( const basic_path<String, Traits> & lhs, + const basic_path<String, Traits> & rhs ) + { + return lhs == rhs.string().c_str(); + } + + template< class String, class Traits > + inline bool operator==( const typename basic_path<String, Traits>::string_type::value_type * lhs, + const basic_path<String, Traits> & rhs ) + { + return rhs == lhs; + } + + template< class String, class Traits > + inline bool operator==( const typename basic_path<String, Traits>::string_type & lhs, + const basic_path<String, Traits> & rhs ) + { + return rhs == lhs.c_str(); + } + + template< class String, class Traits > + inline bool operator==( const basic_path<String, Traits> & lhs, + const typename basic_path<String, Traits>::string_type & rhs ) + { + return lhs == rhs.c_str(); + } + + template< class String, class Traits > + inline bool operator!=( const basic_path<String, Traits> & lhs, + const basic_path<String, Traits> & rhs ) + { return !(lhs == rhs); } + + template< class String, class Traits > + inline bool operator!=( const typename basic_path<String, + Traits>::string_type::value_type * lhs, + const basic_path<String, Traits> & rhs ) + { return !(lhs == rhs); } + + template< class String, class Traits > + inline bool operator!=( const typename basic_path<String, Traits>::string_type & lhs, + const basic_path<String, Traits> & rhs ) + { return !(lhs == rhs); } + + template< class String, class Traits > + inline bool operator!=( const basic_path<String, Traits> & lhs, + const typename basic_path<String, Traits>::string_type::value_type * rhs ) + { return !(lhs == rhs); } + + template< class String, class Traits > + inline bool operator!=( const basic_path<String, Traits> & lhs, + const typename basic_path<String, Traits>::string_type & rhs ) + { return !(lhs == rhs); } + + template< class String, class Traits > + inline bool operator>( const basic_path<String, Traits> & lhs, const basic_path<String, Traits> & rhs ) { return rhs < lhs; } + + template< class String, class Traits > + inline bool operator>( const typename basic_path<String, Traits>::string_type::value_type * lhs, + const basic_path<String, Traits> & rhs ) { return rhs < basic_path<String, Traits>(lhs); } + + template< class String, class Traits > + inline bool operator>( const typename basic_path<String, Traits>::string_type & lhs, + const basic_path<String, Traits> & rhs ) { return rhs < basic_path<String, Traits>(lhs); } + + template< class String, class Traits > + inline bool operator>( const basic_path<String, Traits> & lhs, + const typename basic_path<String, Traits>::string_type::value_type * rhs ) + { return basic_path<String, Traits>(rhs) < lhs; } + + template< class String, class Traits > + inline bool operator>( const basic_path<String, Traits> & lhs, + const typename basic_path<String, Traits>::string_type & rhs ) + { return basic_path<String, Traits>(rhs) < lhs; } + + template< class String, class Traits > + inline bool operator<=( const basic_path<String, Traits> & lhs, const basic_path<String, Traits> & rhs ) { return !(rhs < lhs); } + + template< class String, class Traits > + inline bool operator<=( const typename basic_path<String, Traits>::string_type::value_type * lhs, + const basic_path<String, Traits> & rhs ) { return !(rhs < basic_path<String, Traits>(lhs)); } + + template< class String, class Traits > + inline bool operator<=( const typename basic_path<String, Traits>::string_type & lhs, + const basic_path<String, Traits> & rhs ) { return !(rhs < basic_path<String, Traits>(lhs)); } + + template< class String, class Traits > + inline bool operator<=( const basic_path<String, Traits> & lhs, + const typename basic_path<String, Traits>::string_type::value_type * rhs ) + { return !(basic_path<String, Traits>(rhs) < lhs); } + + template< class String, class Traits > + inline bool operator<=( const basic_path<String, Traits> & lhs, + const typename basic_path<String, Traits>::string_type & rhs ) + { return !(basic_path<String, Traits>(rhs) < lhs); } + + template< class String, class Traits > + inline bool operator>=( const basic_path<String, Traits> & lhs, const basic_path<String, Traits> & rhs ) { return !(lhs < rhs); } + + template< class String, class Traits > + inline bool operator>=( const typename basic_path<String, Traits>::string_type::value_type * lhs, + const basic_path<String, Traits> & rhs ) { return !(lhs < basic_path<String, Traits>(rhs)); } + + template< class String, class Traits > + inline bool operator>=( const typename basic_path<String, Traits>::string_type & lhs, + const basic_path<String, Traits> & rhs ) { return !(lhs < basic_path<String, Traits>(rhs)); } + + template< class String, class Traits > + inline bool operator>=( const basic_path<String, Traits> & lhs, + const typename basic_path<String, Traits>::string_type::value_type * rhs ) + { return !(basic_path<String, Traits>(lhs) < rhs); } + + template< class String, class Traits > + inline bool operator>=( const basic_path<String, Traits> & lhs, + const typename basic_path<String, Traits>::string_type & rhs ) + { return !(basic_path<String, Traits>(lhs) < rhs); } + + // operator / + + template< class String, class Traits > + inline basic_path<String, Traits> operator/( + const basic_path<String, Traits> & lhs, + const basic_path<String, Traits> & rhs ) + { return basic_path<String, Traits>( lhs ) /= rhs; } + + template< class String, class Traits > + inline basic_path<String, Traits> operator/( + const basic_path<String, Traits> & lhs, + const typename String::value_type * rhs ) + { return basic_path<String, Traits>( lhs ) /= + basic_path<String, Traits>( rhs ); } + + template< class String, class Traits > + inline basic_path<String, Traits> operator/( + const basic_path<String, Traits> & lhs, const String & rhs ) + { return basic_path<String, Traits>( lhs ) /= + basic_path<String, Traits>( rhs ); } + + template< class String, class Traits > + inline basic_path<String, Traits> operator/( + const typename String::value_type * lhs, + const basic_path<String, Traits> & rhs ) + { return basic_path<String, Traits>( lhs ) /= rhs; } + + template< class String, class Traits > + inline basic_path<String, Traits> operator/( + const String & lhs, const basic_path<String, Traits> & rhs ) + { return basic_path<String, Traits>( lhs ) /= rhs; } + + // inserters and extractors --------------------------------------------// + +// bypass VC++ 7.0 and earlier, and broken Borland compilers +# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) && !BOOST_WORKAROUND(__BORLANDC__, < 0x610) + template< class Path > + std::basic_ostream< typename Path::string_type::value_type, + typename Path::string_type::traits_type > & + operator<< + ( std::basic_ostream< typename Path::string_type::value_type, + typename Path::string_type::traits_type >& os, const Path & ph ) + { + os << ph.string(); + return os; + } + + template< class Path > + std::basic_istream< typename Path::string_type::value_type, + typename Path::string_type::traits_type > & + operator>> + ( std::basic_istream< typename Path::string_type::value_type, + typename Path::string_type::traits_type >& is, Path & ph ) + { + typename Path::string_type str; + std::getline(is, str); // See ticket 3863 + ph = str; + return is; + } +# elif BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) + template< class String, class Traits > + std::basic_ostream< BOOST_DEDUCED_TYPENAME String::value_type, + BOOST_DEDUCED_TYPENAME String::traits_type > & + operator<< + ( std::basic_ostream< BOOST_DEDUCED_TYPENAME String::value_type, + BOOST_DEDUCED_TYPENAME String::traits_type >& os, + const basic_path< String, Traits > & ph ) + { + os << ph.string(); + return os; + } + + template< class String, class Traits > + std::basic_istream< BOOST_DEDUCED_TYPENAME String::value_type, + BOOST_DEDUCED_TYPENAME String::traits_type > & + operator>> + ( std::basic_istream< BOOST_DEDUCED_TYPENAME String::value_type, + BOOST_DEDUCED_TYPENAME String::traits_type> & is, + basic_path< String, Traits > & ph ) + { + String str; + std::getline(is, str); // See ticket 3863 + ph = str; + return is; + } +# endif + + // basic_filesystem_error helpers --------------------------------------// + + // Originally choice of implementation was done via specialization of + // basic_filesystem_error::what(). Several compilers (GCC, aCC, etc.) + // couldn't handle that, so the choice is now accomplished by overloading. + + namespace detail + { + // BOOST_FILESYSTEM_DECL version works for VC++ but not GCC. Go figure! + inline + const char * what( const char * sys_err_what, + const path & path1_arg, const path & path2_arg, std::string & target ) + { + try + { + if ( target.empty() ) + { + target = sys_err_what; + if ( !path1_arg.empty() ) + { + target += ": \""; + target += path1_arg.file_string(); + target += "\""; + } + if ( !path2_arg.empty() ) + { + target += ", \""; + target += path2_arg.file_string(); + target += "\""; + } + } + return target.c_str(); + } + catch (...) + { + return sys_err_what; + } + } + + template<class Path> + const char * what( const char * sys_err_what, + const Path & /*path1_arg*/, const Path & /*path2_arg*/, std::string & /*target*/ ) + { + return sys_err_what; + } + } + + // basic_filesystem_error ----------------------------------------------// + + template<class Path> + class basic_filesystem_error : public system::system_error + { + // see http://www.boost.org/more/error_handling.html for design rationale + public: + // compiler generates copy constructor and copy assignment + + typedef Path path_type; + + basic_filesystem_error( const std::string & what_arg, + system::error_code ec ); + + basic_filesystem_error( const std::string & what_arg, + const path_type & path1_arg, system::error_code ec ); + + basic_filesystem_error( const std::string & what_arg, const path_type & path1_arg, + const path_type & path2_arg, system::error_code ec ); + + ~basic_filesystem_error() throw() {} + + const path_type & path1() const + { + static const path_type empty_path; + return m_imp_ptr.get() ? m_imp_ptr->m_path1 : empty_path ; + } + const path_type & path2() const + { + static const path_type empty_path; + return m_imp_ptr.get() ? m_imp_ptr->m_path2 : empty_path ; + } + + const char * what() const throw() + { + if ( !m_imp_ptr.get() ) + return system::system_error::what(); + return detail::what( system::system_error::what(), m_imp_ptr->m_path1, + m_imp_ptr->m_path2, m_imp_ptr->m_what ); + } + + private: + struct m_imp + { + path_type m_path1; // may be empty() + path_type m_path2; // may be empty() + std::string m_what; // not built until needed + }; + boost::shared_ptr<m_imp> m_imp_ptr; + }; + + typedef basic_filesystem_error<path> filesystem_error; + +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY + typedef basic_filesystem_error<wpath> wfilesystem_error; +# endif + + // path::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 ); + inline bool no_check( const std::string & ) + { return true; } + +// implementation -----------------------------------------------------------// + + namespace detail + { + + // is_separator helper ------------------------------------------------// + + template<class Path> + inline bool is_separator( typename Path::string_type::value_type c ) + { + return c == slash<Path>::value +# ifdef BOOST_WINDOWS_PATH + || c == path_alt_separator<Path>::value +# endif + ; + } + + // filename_pos helper ----------------------------------------------------// + + template<class String, class Traits> + typename String::size_type filename_pos( + const String & str, // precondition: portable generic path grammar + typename String::size_type end_pos ) // end_pos is past-the-end position + // return 0 if str itself is filename (or empty) + { + typedef typename + boost::BOOST_FILESYSTEM2_NAMESPACE::basic_path<String, Traits> path_type; + + // case: "//" + if ( end_pos == 2 + && str[0] == slash<path_type>::value + && str[1] == slash<path_type>::value ) return 0; + + // case: ends in "/" + if ( end_pos && str[end_pos-1] == slash<path_type>::value ) + return end_pos-1; + + // set pos to start of last element + typename String::size_type pos( + str.find_last_of( slash<path_type>::value, end_pos-1 ) ); +# ifdef BOOST_WINDOWS_PATH + if ( pos == String::npos ) + pos = str.find_last_of( path_alt_separator<path_type>::value, end_pos-1 ); + if ( pos == String::npos ) + pos = str.find_last_of( colon<path_type>::value, end_pos-2 ); +# endif + + return ( pos == String::npos // path itself must be a filename (or empty) + || (pos == 1 && str[0] == slash<path_type>::value) ) // or net + ? 0 // so filename is entire string + : pos + 1; // or starts after delimiter + } + + // first_element helper -----------------------------------------------// + // sets pos and len of first element, excluding extra separators + // if src.empty(), sets pos,len, to 0,0. + + template<class String, class Traits> + void first_element( + const String & src, // precondition: portable generic path grammar + typename String::size_type & element_pos, + typename String::size_type & element_size, +# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1310 ) // VC++ 7.1 + typename String::size_type size = String::npos +# else + typename String::size_type size = -1 +# endif + ) + { + if ( size == String::npos ) size = src.size(); + element_pos = 0; + element_size = 0; + if ( src.empty() ) return; + + typedef typename boost::BOOST_FILESYSTEM2_NAMESPACE::basic_path<String, Traits> path_type; + + typename String::size_type cur(0); + + // deal with // [network] + if ( size >= 2 && src[0] == slash<path_type>::value + && src[1] == slash<path_type>::value + && (size == 2 + || src[2] != slash<path_type>::value) ) + { + cur += 2; + element_size += 2; + } + + // leading (not non-network) separator + else if ( src[0] == slash<path_type>::value ) + { + ++element_size; + // bypass extra leading separators + while ( cur+1 < size + && src[cur+1] == slash<path_type>::value ) + { + ++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<path_type>::value +# endif + && src[cur] != slash<path_type>::value ) + { + ++cur; + ++element_size; + } + +# ifdef BOOST_WINDOWS_PATH + if ( cur == size ) return; + // include device delimiter + if ( src[cur] == colon<path_type>::value ) + { ++element_size; } +# endif + + return; + } + + // root_directory_start helper ----------------------------------------// + + template<class String, class Traits> + typename String::size_type root_directory_start( + const String & s, // precondition: portable generic path grammar + typename String::size_type size ) + // return npos if no root_directory found + { + typedef typename boost::BOOST_FILESYSTEM2_NAMESPACE::basic_path<String, Traits> path_type; + +# ifdef BOOST_WINDOWS_PATH + // case "c:/" + if ( size > 2 + && s[1] == colon<path_type>::value + && s[2] == slash<path_type>::value ) return 2; +# endif + + // case "//" + if ( size == 2 + && s[0] == slash<path_type>::value + && s[1] == slash<path_type>::value ) return String::npos; + + // case "//net {/}" + if ( size > 3 + && s[0] == slash<path_type>::value + && s[1] == slash<path_type>::value + && s[2] != slash<path_type>::value ) + { + typename String::size_type pos( + s.find( slash<path_type>::value, 2 ) ); + return pos < size ? pos : String::npos; + } + + // case "/" + if ( size > 0 && s[0] == slash<path_type>::value ) return 0; + + return String::npos; + } + + // is_non_root_slash helper -------------------------------------------// + + template<class String, class Traits> + bool is_non_root_slash( const String & str, + typename String::size_type pos ) // pos is position of the slash + { + typedef typename + boost::BOOST_FILESYSTEM2_NAMESPACE::basic_path<String, Traits> + path_type; + + BOOST_ASSERT( !str.empty() && str[pos] == slash<path_type>::value + && "precondition violation" ); + + // subsequent logic expects pos to be for leftmost slash of a set + while ( pos > 0 && str[pos-1] == slash<path_type>::value ) + --pos; + + return pos != 0 + && (pos <= 2 || str[1] != slash<path_type>::value + || str.find( slash<path_type>::value, 2 ) != pos) +# ifdef BOOST_WINDOWS_PATH + && (pos !=2 || str[1] != colon<path_type>::value) +# endif + ; + } + } // namespace detail + + // decomposition functions ----------------------------------------------// + + template<class String, class Traits> + String basic_path<String, Traits>::filename() const + { + typename String::size_type end_pos( + detail::filename_pos<String, Traits>( m_path, m_path.size() ) ); + return (m_path.size() + && end_pos + && m_path[end_pos] == slash<path_type>::value + && detail::is_non_root_slash< String, Traits >(m_path, end_pos)) + ? String( 1, dot<path_type>::value ) + : m_path.substr( end_pos ); + } + + template<class String, class Traits> + String basic_path<String, Traits>::stem() const + { + string_type name = filename(); + typename string_type::size_type n = name.rfind(dot<path_type>::value); + return name.substr(0, n); + } + + template<class String, class Traits> + String basic_path<String, Traits>::extension() const + { + string_type name = filename(); + typename string_type::size_type n = name.rfind(dot<path_type>::value); + if (n != string_type::npos) + return name.substr(n); + else + return string_type(); + } + + template<class String, class Traits> + basic_path<String, Traits> basic_path<String, Traits>::parent_path() const + { + typename String::size_type end_pos( + detail::filename_pos<String, Traits>( m_path, m_path.size() ) ); + + bool filename_was_separator( m_path.size() + && m_path[end_pos] == slash<path_type>::value ); + + // skip separators unless root directory + typename string_type::size_type root_dir_pos( detail::root_directory_start + <string_type, traits_type>( m_path, end_pos ) ); + for ( ; + end_pos > 0 + && (end_pos-1) != root_dir_pos + && m_path[end_pos-1] == slash<path_type>::value + ; + --end_pos ) {} + + return (end_pos == 1 && root_dir_pos == 0 && filename_was_separator) + ? path_type() + : path_type( m_path.substr( 0, end_pos ) ); + } + + template<class String, class Traits> + basic_path<String, Traits> basic_path<String, Traits>::relative_path() const + { + iterator itr( begin() ); + for ( ; itr.m_pos != m_path.size() + && (itr.m_name[0] == slash<path_type>::value +# ifdef BOOST_WINDOWS_PATH + || itr.m_name[itr.m_name.size()-1] + == colon<path_type>::value +# endif + ); ++itr ) {} + + return basic_path<String, Traits>( m_path.substr( itr.m_pos ) ); + } + + template<class String, class Traits> + String basic_path<String, Traits>::root_name() const + { + iterator itr( begin() ); + + return ( itr.m_pos != m_path.size() + && ( + ( itr.m_name.size() > 1 + && itr.m_name[0] == slash<path_type>::value + && itr.m_name[1] == slash<path_type>::value + ) +# ifdef BOOST_WINDOWS_PATH + || itr.m_name[itr.m_name.size()-1] + == colon<path_type>::value +# endif + ) ) + ? *itr + : String(); + } + + template<class String, class Traits> + String basic_path<String, Traits>::root_directory() const + { + typename string_type::size_type start( + detail::root_directory_start<String, Traits>( m_path, m_path.size() ) ); + + return start == string_type::npos + ? string_type() + : m_path.substr( start, 1 ); + } + + template<class String, class Traits> + basic_path<String, Traits> basic_path<String, Traits>::root_path() const + { + // even on POSIX, root_name() is non-empty() on network paths + return basic_path<String, Traits>( root_name() ) /= root_directory(); + } + + // path query functions -------------------------------------------------// + + template<class String, class Traits> + inline bool basic_path<String, Traits>::is_complete() const + { +# ifdef BOOST_WINDOWS_PATH + return has_root_name() && has_root_directory(); +# else + return has_root_directory(); +# endif + } + + template<class String, class Traits> + inline bool basic_path<String, Traits>::has_root_path() const + { + return !root_path().empty(); + } + + template<class String, class Traits> + inline bool basic_path<String, Traits>::has_root_name() const + { + return !root_name().empty(); + } + + template<class String, class Traits> + inline bool basic_path<String, Traits>::has_root_directory() const + { + return !root_directory().empty(); + } + + // append ---------------------------------------------------------------// + + template<class String, class Traits> + void basic_path<String, Traits>::m_append_separator_if_needed() + // requires: !empty() + { + if ( +# ifdef BOOST_WINDOWS_PATH + *(m_path.end()-1) != colon<path_type>::value && +# endif + *(m_path.end()-1) != slash<path_type>::value ) + { + m_path += slash<path_type>::value; + } + } + + template<class String, class Traits> + void basic_path<String, Traits>::m_append( value_type value ) + { +# ifdef BOOST_CYGWIN_PATH + if ( m_path.empty() ) m_cygwin_root = (value == slash<path_type>::value); +# endif + +# ifdef BOOST_WINDOWS_PATH + // for BOOST_WINDOWS_PATH, convert alt_separator ('\') to separator ('/') + m_path += ( value == path_alt_separator<path_type>::value + ? slash<path_type>::value + : value ); +# else + m_path += value; +# endif + } + + // except that it wouldn't work for BOOST_NO_MEMBER_TEMPLATES compilers, + // the append() member template could replace this code. + template<class String, class Traits> + basic_path<String, Traits> & basic_path<String, Traits>::operator /= + ( const value_type * next_p ) + { + // ignore escape sequence on POSIX or Windows + if ( *next_p == slash<path_type>::value + && *(next_p+1) == slash<path_type>::value + && *(next_p+2) == colon<path_type>::value ) next_p += 3; + + // append slash<path_type>::value if needed + if ( !empty() && *next_p != 0 + && !detail::is_separator<path_type>( *next_p ) ) + { m_append_separator_if_needed(); } + + for ( ; *next_p != 0; ++next_p ) m_append( *next_p ); + return *this; + } + +# ifndef BOOST_NO_MEMBER_TEMPLATES + template<class String, class Traits> template <class InputIterator> + basic_path<String, Traits> & basic_path<String, Traits>::append( + InputIterator first, InputIterator last ) + { + // append slash<path_type>::value if needed + if ( !empty() && first != last + && !detail::is_separator<path_type>( *first ) ) + { m_append_separator_if_needed(); } + + // song-and-dance to avoid violating InputIterator requirements + // (which prohibit lookahead) in detecting a possible escape sequence + // (escape sequences are simply ignored on POSIX and Windows) + bool was_escape_sequence(true); + std::size_t append_count(0); + typename String::size_type initial_pos( m_path.size() ); + + for ( ; first != last && *first; ++first ) + { + if ( append_count == 0 && *first != slash<path_type>::value ) + was_escape_sequence = false; + if ( append_count == 1 && *first != slash<path_type>::value ) + was_escape_sequence = false; + if ( append_count == 2 && *first != colon<path_type>::value ) + was_escape_sequence = false; + m_append( *first ); + ++append_count; + } + + // erase escape sequence if any + if ( was_escape_sequence && append_count >= 3 ) + m_path.erase( initial_pos, 3 ); + + return *this; + } +# endif + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + + // canonize ------------------------------------------------------------// + + template<class String, class Traits> + basic_path<String, Traits> & basic_path<String, Traits>::canonize() + { + static const typename string_type::value_type dot_str[] + = { dot<path_type>::value, 0 }; + + if ( m_path.empty() ) return *this; + + path_type temp; + + for ( iterator itr( begin() ); itr != end(); ++itr ) + { + temp /= *itr; + }; + + if ( temp.empty() ) temp /= dot_str; + m_path = temp.m_path; + return *this; + } + + // normalize ------------------------------------------------------------// + + template<class String, class Traits> + basic_path<String, Traits> & basic_path<String, Traits>::normalize() + { + static const typename string_type::value_type dot_str[] + = { dot<path_type>::value, 0 }; + + if ( m_path.empty() ) return *this; + + path_type temp; + iterator start( begin() ); + iterator last( end() ); + iterator stop( last-- ); + for ( iterator itr( start ); itr != stop; ++itr ) + { + // ignore "." except at start and last + if ( itr->size() == 1 + && (*itr)[0] == dot<path_type>::value + && itr != start + && itr != last ) continue; + + // ignore a name and following ".." + if ( !temp.empty() + && itr->size() == 2 + && (*itr)[0] == dot<path_type>::value + && (*itr)[1] == dot<path_type>::value ) // dot dot + { + string_type lf( temp.filename() ); + if ( lf.size() > 0 + && (lf.size() != 1 + || (lf[0] != dot<path_type>::value + && lf[0] != slash<path_type>::value)) + && (lf.size() != 2 + || (lf[0] != dot<path_type>::value + && lf[1] != dot<path_type>::value +# ifdef BOOST_WINDOWS_PATH + && lf[1] != colon<path_type>::value +# endif + ) + ) + ) + { + temp.remove_filename(); + // if not root directory, must also remove "/" if any + if ( temp.m_path.size() > 0 + && temp.m_path[temp.m_path.size()-1] + == slash<path_type>::value ) + { + typename string_type::size_type rds( + detail::root_directory_start<String,Traits>( temp.m_path, + temp.m_path.size() ) ); + if ( rds == string_type::npos + || rds != temp.m_path.size()-1 ) + { temp.m_path.erase( temp.m_path.size()-1 ); } + } + + iterator next( itr ); + if ( temp.empty() && ++next != stop + && next == last && *last == dot_str ) temp /= dot_str; + continue; + } + } + + temp /= *itr; + }; + + if ( temp.empty() ) temp /= dot_str; + m_path = temp.m_path; + return *this; + } + +# endif + + // modifiers ------------------------------------------------------------// + + template<class String, class Traits> + basic_path<String, Traits> & basic_path<String, Traits>::remove_filename() + { + m_path.erase( + detail::filename_pos<String, Traits>( m_path, m_path.size() ) ); + return *this; + } + + template<class String, class Traits> + basic_path<String, Traits> & + basic_path<String, Traits>::replace_extension( const string_type & new_ext ) + { + // erase existing extension if any + string_type old_ext = extension(); + if ( !old_ext.empty() ) + m_path.erase( m_path.size() - old_ext.size() ); + + if ( !new_ext.empty() && new_ext[0] != dot<path_type>::value ) + m_path += dot<path_type>::value; + + m_path += new_ext; + + return *this; + } + + + // path conversion functions --------------------------------------------// + + template<class String, class Traits> + const String + basic_path<String, Traits>::file_string() const + { +# ifdef BOOST_WINDOWS_PATH + // for Windows, use the alternate separator, and bypass extra + // root separators + + typename string_type::size_type root_dir_start( + detail::root_directory_start<String, Traits>( m_path, m_path.size() ) ); + bool in_root( root_dir_start != string_type::npos ); + String s; + for ( typename string_type::size_type pos( 0 ); + pos != m_path.size(); ++pos ) + { + // special case // [net] + if ( pos == 0 && m_path.size() > 1 + && m_path[0] == slash<path_type>::value + && m_path[1] == slash<path_type>::value + && ( m_path.size() == 2 + || !detail::is_separator<path_type>( m_path[2] ) + ) ) + { + ++pos; + s += path_alt_separator<path_type>::value; + s += path_alt_separator<path_type>::value; + continue; + } + + // bypass extra root separators + if ( in_root ) + { + if ( s.size() > 0 + && s[s.size()-1] == path_alt_separator<path_type>::value + && m_path[pos] == slash<path_type>::value + ) continue; + } + + if ( m_path[pos] == slash<path_type>::value ) + s += path_alt_separator<path_type>::value; + else + s += m_path[pos]; + + if ( pos > root_dir_start + && m_path[pos] == slash<path_type>::value ) + { in_root = false; } + } +# ifdef BOOST_CYGWIN_PATH + if ( m_cygwin_root ) s[0] = slash<path_type>::value; +# endif + return s; +# else + return m_path; +# endif + } + + // iterator functions ---------------------------------------------------// + + template<class String, class Traits> + typename basic_path<String, Traits>::iterator basic_path<String, Traits>::begin() const + { + iterator itr; + itr.m_path_ptr = this; + typename string_type::size_type element_size; + detail::first_element<String, Traits>( m_path, itr.m_pos, element_size ); + itr.m_name = m_path.substr( itr.m_pos, element_size ); + return itr; + } + + template<class String, class Traits> + typename basic_path<String, Traits>::iterator basic_path<String, Traits>::end() const + { + iterator itr; + itr.m_path_ptr = this; + itr.m_pos = m_path.size(); + return itr; + } + + namespace detail + { + // do_increment ------------------------------------------------------// + + template<class Path> + void iterator_helper<Path>::do_increment( iterator & itr ) + { + typedef typename Path::string_type string_type; + typedef typename Path::traits_type traits_type; + + BOOST_ASSERT( itr.m_pos < itr.m_path_ptr->m_path.size() && "basic_path::iterator increment past end()" ); + + bool was_net( itr.m_name.size() > 2 + && itr.m_name[0] == slash<Path>::value + && itr.m_name[1] == slash<Path>::value + && itr.m_name[2] != slash<Path>::value ); + + // increment to position past current element + itr.m_pos += itr.m_name.size(); + + // if end reached, create end iterator + if ( itr.m_pos == itr.m_path_ptr->m_path.size() ) + { + itr.m_name.erase( itr.m_name.begin(), itr.m_name.end() ); // VC++ 6.0 lib didn't supply clear() + return; + } + + // process separator (Windows drive spec is only case not a separator) + if ( itr.m_path_ptr->m_path[itr.m_pos] == slash<Path>::value ) + { + // detect root directory + if ( was_net + # ifdef BOOST_WINDOWS_PATH + // case "c:/" + || itr.m_name[itr.m_name.size()-1] == colon<Path>::value + # endif + ) + { + itr.m_name = slash<Path>::value; + return; + } + + // bypass separators + while ( itr.m_pos != itr.m_path_ptr->m_path.size() + && itr.m_path_ptr->m_path[itr.m_pos] == slash<Path>::value ) + { ++itr.m_pos; } + + // detect trailing separator, and treat it as ".", per POSIX spec + if ( itr.m_pos == itr.m_path_ptr->m_path.size() + && detail::is_non_root_slash< string_type, traits_type >( + itr.m_path_ptr->m_path, itr.m_pos-1 ) ) + { + --itr.m_pos; + itr.m_name = dot<Path>::value; + return; + } + } + + // get next element + typename string_type::size_type end_pos( + itr.m_path_ptr->m_path.find( slash<Path>::value, itr.m_pos ) ); + itr.m_name = itr.m_path_ptr->m_path.substr( itr.m_pos, end_pos - itr.m_pos ); + } + + // do_decrement ------------------------------------------------------// + + template<class Path> + void iterator_helper<Path>::do_decrement( iterator & itr ) + { + BOOST_ASSERT( itr.m_pos && "basic_path::iterator decrement past begin()" ); + + typedef typename Path::string_type string_type; + typedef typename Path::traits_type traits_type; + + typename string_type::size_type end_pos( itr.m_pos ); + + typename string_type::size_type root_dir_pos( + detail::root_directory_start<string_type, traits_type>( + itr.m_path_ptr->m_path, end_pos ) ); + + // if at end and there was a trailing non-root '/', return "." + if ( itr.m_pos == itr.m_path_ptr->m_path.size() + && itr.m_path_ptr->m_path.size() > 1 + && itr.m_path_ptr->m_path[itr.m_pos-1] == slash<Path>::value + && detail::is_non_root_slash< string_type, traits_type >( + itr.m_path_ptr->m_path, itr.m_pos-1 ) + ) + { + --itr.m_pos; + itr.m_name = dot<Path>::value; + return; + } + + // skip separators unless root directory + for ( + ; + end_pos > 0 + && (end_pos-1) != root_dir_pos + && itr.m_path_ptr->m_path[end_pos-1] == slash<Path>::value + ; + --end_pos ) {} + + itr.m_pos = detail::filename_pos<string_type, traits_type> + ( itr.m_path_ptr->m_path, end_pos ); + itr.m_name = itr.m_path_ptr->m_path.substr( itr.m_pos, end_pos - itr.m_pos ); + } + } // namespace detail + + // basic_filesystem_error implementation --------------------------------// + + template<class Path> + basic_filesystem_error<Path>::basic_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(); } + } + + template<class Path> + basic_filesystem_error<Path>::basic_filesystem_error( + const std::string & what_arg, const path_type & 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(); } + } + + template<class Path> + basic_filesystem_error<Path>::basic_filesystem_error( + const std::string & what_arg, const path_type & path1_arg, + const path_type & 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(); } + } + + } // namespace BOOST_FILESYSTEM2_NAMESPACE +} // namespace boost + +//----------------------------------------------------------------------------// + +namespace boost +{ + namespace filesystem + { + using filesystem2::basic_path; + using filesystem2::path_traits; + + using filesystem2::slash; + using filesystem2::dot; + using filesystem2::colon; + + using filesystem2::path; +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY + using filesystem2::wpath_traits; + using filesystem2::wpath; + using filesystem2::wfilesystem_error; +# endif + using filesystem2::basic_filesystem_error; + using filesystem2::filesystem_error; + using filesystem2::portable_posix_name; + using filesystem2::windows_name; + using filesystem2::portable_name; + using filesystem2::portable_directory_name; + using filesystem2::portable_file_name; + using filesystem2::native; + using filesystem2::no_check; + using filesystem2::swap; + using filesystem2::operator<; + using filesystem2::operator==; + using filesystem2::operator!=; + using filesystem2::operator>; + using filesystem2::operator<=; + using filesystem2::operator>=; + using filesystem2::operator/; + using filesystem2::operator<<; + using filesystem2::operator>>; + } +} + +//----------------------------------------------------------------------------// + +#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas + +#endif // BOOST_FILESYSTEM2_PATH_HPP diff --git a/boost/filesystem/v3/config.hpp b/boost/filesystem/v3/config.hpp new file mode 100644 index 0000000..13fc308 --- /dev/null +++ b/boost/filesystem/v3/config.hpp @@ -0,0 +1,85 @@ +// boost/filesystem/v3/config.hpp ----------------------------------------------------// + +// Copyright Beman Dawes 2003 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// Library home page: http://www.boost.org/libs/filesystem + +//--------------------------------------------------------------------------------------// + +#ifndef BOOST_FILESYSTEM3_CONFIG_HPP +#define BOOST_FILESYSTEM3_CONFIG_HPP + +# if defined(BOOST_FILESYSTEM_VERSION) && BOOST_FILESYSTEM_VERSION != 3 +# error Compiling Filesystem version 3 file with BOOST_FILESYSTEM_VERSION defined != 3 +# endif + +# if !defined(BOOST_FILESYSTEM_VERSION) +# define BOOST_FILESYSTEM_VERSION 3 +# endif + +#define BOOST_FILESYSTEM_I18N // aid users wishing to compile several versions + +// This header implements separate compilation features as described in +// http://www.boost.org/more/separate_compilation.html + +#include <boost/config.hpp> +#include <boost/system/api_config.hpp> // for BOOST_POSIX_API or BOOST_WINDOWS_API +#include <boost/detail/workaround.hpp> + +// BOOST_FILESYSTEM_DEPRECATED needed for source compiles -----------------------------// + +# ifdef BOOST_FILESYSTEM_SOURCE +# define BOOST_FILESYSTEM_DEPRECATED +# endif + +// throw an exception ----------------------------------------------------------------// +// +// Exceptions were originally thrown via boost::throw_exception(). +// As throw_exception() became more complex, it caused user error reporting +// to be harder to interpret, since the exception reported became much more complex. +// The immediate fix was to throw directly, wrapped in a macro to make any later change +// easier. + +#define BOOST_FILESYSTEM_THROW(EX) throw EX + +# if defined( BOOST_NO_STD_WSTRING ) +# error Configuration not supported: Boost.Filesystem V3 and later requires std::wstring support +# endif + +// enable dynamic linking -------------------------------------------------------------// + +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_FILESYSTEM_DYN_LINK) +# if defined(BOOST_FILESYSTEM_SOURCE) +# define BOOST_FILESYSTEM_DECL BOOST_SYMBOL_EXPORT +# else +# define BOOST_FILESYSTEM_DECL BOOST_SYMBOL_IMPORT +# endif +#else +# 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_FILESYSTEM3_CONFIG_HPP diff --git a/boost/filesystem/v3/convenience.hpp b/boost/filesystem/v3/convenience.hpp new file mode 100644 index 0000000..1a1f943 --- /dev/null +++ b/boost/filesystem/v3/convenience.hpp @@ -0,0 +1,74 @@ +// 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_FILESYSTEM3_CONVENIENCE_HPP +#define BOOST_FILESYSTEM3_CONVENIENCE_HPP + +#include <boost/config.hpp> + +# if defined( BOOST_NO_STD_WSTRING ) +# error Configuration not supported: Boost.Filesystem V3 and later requires std::wstring support +# endif + +#include <boost/filesystem/v3/operations.hpp> +#include <boost/system/error_code.hpp> + +#include <boost/config/abi_prefix.hpp> // must be the last #include + +namespace boost +{ + namespace filesystem3 + { + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + + inline std::string extension(const path & p) + { + return p.extension().string(); + } + + inline std::string basename(const path & p) + { + return p.stem().string(); + } + + inline path change_extension( const path & p, const path & new_extension ) + { + path new_p( p ); + new_p.replace_extension( new_extension ); + return new_p; + } + +# endif + + + } // namespace filesystem3 +} // namespace boost + +//----------------------------------------------------------------------------// + +namespace boost +{ + namespace filesystem + { +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + using filesystem3::extension; + using filesystem3::basename; + using filesystem3::change_extension; +# endif + } +} + +//----------------------------------------------------------------------------// + +#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas +#endif // BOOST_FILESYSTEM3_CONVENIENCE_HPP diff --git a/boost/filesystem/v3/exception.hpp b/boost/filesystem/v3/exception.hpp new file mode 100644 index 0000000..985cd8f --- /dev/null +++ b/boost/filesystem/v3/exception.hpp @@ -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 longer used. The contents have been moved to path.hpp. +// It is provided so that user code #includes do not have to be changed. diff --git a/boost/filesystem/v3/fstream.hpp b/boost/filesystem/v3/fstream.hpp new file mode 100644 index 0000000..60a2a3b --- /dev/null +++ b/boost/filesystem/v3/fstream.hpp @@ -0,0 +1,208 @@ +// boost/filesystem/fstream.hpp ------------------------------------------------------// + +// Copyright Beman Dawes 2002 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// Library home page: http://www.boost.org/libs/filesystem + +//--------------------------------------------------------------------------------------// + +#ifndef BOOST_FILESYSTEM3_FSTREAM_HPP +#define BOOST_FILESYSTEM3_FSTREAM_HPP + +#include <boost/config.hpp> + +# if defined( BOOST_NO_STD_WSTRING ) +# error Configuration not supported: Boost.Filesystem V3 and later requires std::wstring support +# endif + +#include <boost/filesystem/v3/path.hpp> +#include <iosfwd> +#include <fstream> + +#include <boost/config/abi_prefix.hpp> // must be the last #include + +// on Windows, except for standard libaries known to have wchar_t overloads for +// file stream I/O, use path::string() to get a narrow character c_str() +#if defined(BOOST_WINDOWS_API) \ + && (!defined(_CPPLIB_VER) || _CPPLIB_VER < 405 || defined(_STLPORT_VERSION)) + // !Dinkumware || early Dinkumware || STLPort masquerading as Dinkumware +# define BOOST_FILESYSTEM_C_STR string().c_str() // use narrow, since wide not available +#else // use the native c_str, which will be narrow on POSIX, wide on Windows +# define BOOST_FILESYSTEM_C_STR c_str() +#endif + +namespace boost +{ +namespace filesystem3 +{ + +//--------------------------------------------------------------------------------------// +// basic_filebuf // +//--------------------------------------------------------------------------------------// + + 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() {} + + basic_filebuf<charT,traits>* + open(const path& p, std::ios_base::openmode mode) + { + return std::basic_filebuf<charT,traits>::open(p.BOOST_FILESYSTEM_C_STR, mode) + ? this : 0; + } + }; + +//--------------------------------------------------------------------------------------// +// basic_ifstream // +//--------------------------------------------------------------------------------------// + + 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) + + explicit basic_ifstream(const path& p) + : std::basic_ifstream<charT,traits>(p.BOOST_FILESYSTEM_C_STR, std::ios_base::in) {} + + basic_ifstream(const path& p, std::ios_base::openmode mode) + : std::basic_ifstream<charT,traits>(p.BOOST_FILESYSTEM_C_STR, mode) {} + + void open(const path& p) + { std::basic_ifstream<charT,traits>::open(p.BOOST_FILESYSTEM_C_STR, std::ios_base::in); } + + void open(const path& p, std::ios_base::openmode mode) + { std::basic_ifstream<charT,traits>::open(p.BOOST_FILESYSTEM_C_STR, mode); } + + virtual ~basic_ifstream() {} + }; + +//--------------------------------------------------------------------------------------// +// basic_ofstream // +//--------------------------------------------------------------------------------------// + + 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) + + explicit basic_ofstream(const path& p) + : std::basic_ofstream<charT,traits>(p.BOOST_FILESYSTEM_C_STR, std::ios_base::out) {} + + basic_ofstream(const path& p, std::ios_base::openmode mode) + : std::basic_ofstream<charT,traits>(p.BOOST_FILESYSTEM_C_STR, mode) {} + + void open(const path& p) + { std::basic_ofstream<charT,traits>::open(p.BOOST_FILESYSTEM_C_STR, std::ios_base::out); } + + void open(const path& p, std::ios_base::openmode mode) + { std::basic_ofstream<charT,traits>::open(p.BOOST_FILESYSTEM_C_STR, mode); } + + virtual ~basic_ofstream() {} + }; + +//--------------------------------------------------------------------------------------// +// basic_fstream // +//--------------------------------------------------------------------------------------// + + 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) + + explicit basic_fstream(const path& p) + : std::basic_fstream<charT,traits>(p.BOOST_FILESYSTEM_C_STR, + std::ios_base::in | std::ios_base::out) {} + + basic_fstream(const path& p, std::ios_base::openmode mode) + : std::basic_fstream<charT,traits>(p.BOOST_FILESYSTEM_C_STR, mode) {} + + void open(const path& p) + { std::basic_fstream<charT,traits>::open(p.BOOST_FILESYSTEM_C_STR, + std::ios_base::in | std::ios_base::out); } + + void open(const path& p, std::ios_base::openmode mode) + { std::basic_fstream<charT,traits>::open(p.BOOST_FILESYSTEM_C_STR, mode); } + + virtual ~basic_fstream() {} + + }; + +//--------------------------------------------------------------------------------------// +// typedefs // +//--------------------------------------------------------------------------------------// + + typedef basic_filebuf<char> filebuf; + typedef basic_ifstream<char> ifstream; + typedef basic_ofstream<char> ofstream; + typedef basic_fstream<char> fstream; + + typedef basic_filebuf<wchar_t> wfilebuf; + typedef basic_ifstream<wchar_t> wifstream; + typedef basic_ofstream<wchar_t> wofstream; + typedef basic_fstream<wchar_t> wfstream; + +} // namespace filesystem3 +} // namespace boost + +//----------------------------------------------------------------------------// + +namespace boost +{ + namespace filesystem + { + using filesystem3::filebuf; + using filesystem3::ifstream; + using filesystem3::ofstream; + using filesystem3::fstream; + using filesystem3::wfilebuf; + using filesystem3::wifstream; + using filesystem3::wfstream; + using filesystem3::wofstream; + using filesystem3::basic_filebuf; + using filesystem3::basic_ifstream; + using filesystem3::basic_ofstream; + using filesystem3::basic_fstream; + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED +# endif + } +} + +//----------------------------------------------------------------------------// + +#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas +#endif // BOOST_FILESYSTEM3_FSTREAM_HPP diff --git a/boost/filesystem/v3/operations.hpp b/boost/filesystem/v3/operations.hpp new file mode 100644 index 0000000..ace3bc8 --- /dev/null +++ b/boost/filesystem/v3/operations.hpp @@ -0,0 +1,1199 @@ +// boost/filesystem/operations.hpp ---------------------------------------------------// + +// Copyright Beman Dawes 2002-2009 +// 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 + +// Library home page: http://www.boost.org/libs/filesystem + +//--------------------------------------------------------------------------------------// + +#ifndef BOOST_FILESYSTEM3_OPERATIONS_HPP +#define BOOST_FILESYSTEM3_OPERATIONS_HPP + +#include <boost/config.hpp> + +# if defined( BOOST_NO_STD_WSTRING ) +# error Configuration not supported: Boost.Filesystem V3 and later requires std::wstring support +# endif + +#include <boost/filesystem/v3/config.hpp> +#include <boost/filesystem/v3/path.hpp> + +#include <boost/detail/scoped_enum_emulation.hpp> +#include <boost/detail/bitmask.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> +#include <vector> +#include <stack> + +#ifdef BOOST_WINDOWS_API +# include <fstream> +#endif + +#include <boost/config/abi_prefix.hpp> // must be the last #include + +//--------------------------------------------------------------------------------------// + +namespace boost +{ + namespace filesystem3 + { + +//--------------------------------------------------------------------------------------// +// file_type // +//--------------------------------------------------------------------------------------// + + enum file_type + { + status_error, +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + status_unknown = status_error, +# endif + file_not_found, + regular_file, + directory_file, + // the following may not apply to some operating systems or file systems + symlink_file, + block_file, + character_file, + fifo_file, + socket_file, + reparse_file, // Windows: FILE_ATTRIBUTE_REPARSE_POINT that is not a symlink + 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 + + _detail_directory_symlink // internal use only; never exposed to users + }; + +//--------------------------------------------------------------------------------------// +// perms // +//--------------------------------------------------------------------------------------// + + enum perms + { + no_perms = 0, // file_not_found is no_perms rather than perms_not_known + + // POSIX equivalent macros given in comments. + // Values are from POSIX and are given in octal per the POSIX standard. + + // permission bits + + owner_read = 0400, // S_IRUSR, Read permission, owner + owner_write = 0200, // S_IWUSR, Write permission, owner + owner_exe = 0100, // S_IXUSR, Execute/search permission, owner + owner_all = 0700, // S_IRWXU, Read, write, execute/search by owner + + group_read = 040, // S_IRGRP, Read permission, group + group_write = 020, // S_IWGRP, Write permission, group + group_exe = 010, // S_IXGRP, Execute/search permission, group + group_all = 070, // S_IRWXG, Read, write, execute/search by group + + others_read = 04, // S_IROTH, Read permission, others + others_write = 02, // S_IWOTH, Write permission, others + others_exe = 01, // S_IXOTH, Execute/search permission, others + others_all = 07, // S_IRWXO, Read, write, execute/search by others + + all_all = owner_all|group_all|others_all, // 0777 + + // other POSIX bits + + set_uid_on_exe = 04000, // S_ISUID, Set-user-ID on execution + set_gid_on_exe = 02000, // S_ISGID, Set-group-ID on execution + sticky_bit = 01000, // S_ISVTX, + // (POSIX XSI) On directories, restricted deletion flag + // (V7) 'sticky bit': save swapped text even after use + // (SunOS) On non-directories: don't cache this file + // (SVID-v4.2) On directories: restricted deletion flag + // Also see http://en.wikipedia.org/wiki/Sticky_bit + + perms_mask = all_all|set_uid_on_exe|set_gid_on_exe|sticky_bit, // 07777 + + perms_not_known = 0xFFFF, // present when directory_entry cache not loaded + + // options for permissions() function + + add_perms = 0x1000, // adds the given permission bits to the current bits + remove_perms = 0x2000, // removes the given permission bits from the current bits; + // choose add_perms or remove_perms, not both; if neither add_perms + // nor remove_perms is given, replace the current bits with + // the given bits. + + symlink_perms = 0x4000 // on POSIX, don't resolve symlinks; implied on Windows + }; + + BOOST_BITMASK(perms) + +//--------------------------------------------------------------------------------------// +// file_status // +//--------------------------------------------------------------------------------------// + + class BOOST_FILESYSTEM_DECL file_status + { + public: + file_status() : m_value(status_error), m_perms(perms_not_known) {} + explicit file_status(file_type v, perms prms = perms_not_known) + : m_value(v), m_perms(prms) {} + + // observers + file_type type() const { return m_value; } + perms permissions() const { return m_perms; } + + // modifiers + void type(file_type v) { m_value = v; } + void permissions(perms prms) { m_perms = prms; } + + bool operator==(const file_status& rhs) const { return type() == rhs.type() && + permissions() == rhs.permissions(); } + bool operator!=(const file_status& rhs) const { return !(*this == rhs); } + + private: + file_type m_value; + enum perms m_perms; + }; + + inline bool type_present(file_status f) { return f.type() != status_error; } + inline bool permissions_present(file_status f) + {return f.permissions() != perms_not_known;} + inline bool status_known(file_status f) { return type_present(f) && permissions_present(f); } + inline bool exists(file_status f) { return f.type() != status_error + && 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 + }; + + BOOST_SCOPED_ENUM_START(copy_option) + {none, fail_if_exists = none, overwrite_if_exists}; + BOOST_SCOPED_ENUM_END + +//--------------------------------------------------------------------------------------// +// implementation details // +//--------------------------------------------------------------------------------------// + + namespace detail + { + BOOST_FILESYSTEM_DECL + file_status status(const path&p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + file_status symlink_status(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + bool is_empty(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + path initial_path(system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + path canonical(const path& p, const path& base, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + void copy(const path& from, const path& to, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + void copy_directory(const path& from, const path& to, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + void copy_file(const path& from, const path& to, + BOOST_SCOPED_ENUM(copy_option) option, // See ticket #2925 + system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + void copy_symlink(const path& existing_symlink, const path& new_symlink, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + bool create_directories(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + bool create_directory(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + void create_directory_symlink(const path& to, const path& from, + system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + void create_hard_link(const path& to, const path& from, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + void create_symlink(const path& to, const path& from, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + path current_path(system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + void current_path(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + bool equivalent(const path& p1, const path& p2, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + boost::uintmax_t file_size(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + boost::uintmax_t hard_link_count(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + std::time_t last_write_time(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + void last_write_time(const path& p, const std::time_t new_time, + system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + void permissions(const path& p, perms prms, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + path read_symlink(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + // For standardization, if the committee doesn't like "remove", consider "eliminate" + bool remove(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + boost::uintmax_t remove_all(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + void rename(const path& old_p, const path& new_p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + void resize_file(const path& p, uintmax_t size, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + space_info space(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + path system_complete(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + path temp_directory_path(system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + path unique_path(const path& p, system::error_code* ec=0); + } // namespace detail + +//--------------------------------------------------------------------------------------// +// // +// status query functions // +// // +//--------------------------------------------------------------------------------------// + + inline + file_status status(const path& p) {return detail::status(p);} + inline + file_status status(const path& p, system::error_code& ec) + {return detail::status(p, &ec);} + inline + file_status symlink_status(const path& p) {return detail::symlink_status(p);} + inline + file_status symlink_status(const path& p, system::error_code& ec) + {return detail::symlink_status(p, &ec);} + inline + bool exists(const path& p) {return exists(detail::status(p));} + inline + bool exists(const path& p, system::error_code& ec) + {return exists(detail::status(p, &ec));} + inline + bool is_directory(const path& p) {return is_directory(detail::status(p));} + inline + bool is_directory(const path& p, system::error_code& ec) + {return is_directory(detail::status(p, &ec));} + inline + bool is_regular_file(const path& p) {return is_regular_file(detail::status(p));} + inline + bool is_regular_file(const path& p, system::error_code& ec) + {return is_regular_file(detail::status(p, &ec));} + inline + bool is_other(const path& p) {return is_other(detail::status(p));} + inline + bool is_other(const path& p, system::error_code& ec) + {return is_other(detail::status(p, &ec));} + inline + bool is_symlink(const path& p) {return is_symlink(detail::symlink_status(p));} + inline + bool is_symlink(const path& p, system::error_code& ec) + {return is_symlink(detail::symlink_status(p, &ec));} +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + inline + bool is_regular(const path& p) {return is_regular(detail::status(p));} + inline + bool is_regular(const path& p, system::error_code& ec) + {return is_regular(detail::status(p, &ec));} +# endif + + inline + bool is_empty(const path& p) {return detail::is_empty(p);} + inline + bool is_empty(const path& p, system::error_code& ec) + {return detail::is_empty(p, &ec);} + +//--------------------------------------------------------------------------------------// +// // +// operational functions // +// in alphabetical order, unless otherwise noted // +// // +//--------------------------------------------------------------------------------------// + + // forward declarations + path current_path(); // fwd declaration + path initial_path(); + + BOOST_FILESYSTEM_DECL + path absolute(const path& p, const path& base=current_path()); + // If base.is_absolute(), throws nothing. Thus no need for ec argument + + inline + path canonical(const path& p, const path& base=current_path()) + {return detail::canonical(p, base);} + inline + path canonical(const path& p, system::error_code& ec) + {return detail::canonical(p, current_path(), &ec);} + inline + path canonical(const path& p, const path& base, system::error_code& ec) + {return detail::canonical(p, base, &ec);} + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + inline + path complete(const path& p) + { + return absolute(p, initial_path()); + } + + inline + path complete(const path& p, const path& base) + { + return absolute(p, base); + } +# endif + + inline + void copy(const path& from, const path& to) {detail::copy(from, to);} + + inline + void copy(const path& from, const path& to, system::error_code& ec) + {detail::copy(from, to, &ec);} + inline + void copy_directory(const path& from, const path& to) + {detail::copy_directory(from, to);} + inline + void copy_directory(const path& from, const path& to, system::error_code& ec) + {detail::copy_directory(from, to, &ec);} + inline + void copy_file(const path& from, const path& to, // See ticket #2925 + BOOST_SCOPED_ENUM(copy_option) option) + {detail::copy_file(from, to, option);} + inline + void copy_file(const path& from, const path& to) + {detail::copy_file(from, to, copy_option::fail_if_exists);} + inline + void copy_file(const path& from, const path& to, // See ticket #2925 + BOOST_SCOPED_ENUM(copy_option) option, system::error_code& ec) + {detail::copy_file(from, to, option, &ec);} + inline + void copy_file(const path& from, const path& to, system::error_code& ec) + {detail::copy_file(from, to, copy_option::fail_if_exists, &ec);} + inline + void copy_symlink(const path& existing_symlink, const path& new_symlink) {detail::copy_symlink(existing_symlink, new_symlink);} + + inline + void copy_symlink(const path& existing_symlink, const path& new_symlink, system::error_code& ec) + {detail::copy_symlink(existing_symlink, new_symlink, &ec);} + inline + bool create_directories(const path& p) {return detail::create_directories(p);} + + inline + bool create_directories(const path& p, system::error_code& ec) + {return detail::create_directories(p, &ec);} + inline + bool create_directory(const path& p) {return detail::create_directory(p);} + + inline + bool create_directory(const path& p, system::error_code& ec) + {return detail::create_directory(p, &ec);} + inline + void create_directory_symlink(const path& to, const path& from) + {detail::create_directory_symlink(to, from);} + inline + void create_directory_symlink(const path& to, const path& from, system::error_code& ec) + {detail::create_directory_symlink(to, from, &ec);} + inline + void create_hard_link(const path& to, const path& new_hard_link) {detail::create_hard_link(to, new_hard_link);} + + inline + void create_hard_link(const path& to, const path& new_hard_link, system::error_code& ec) + {detail::create_hard_link(to, new_hard_link, &ec);} + inline + void create_symlink(const path& to, const path& new_symlink) {detail::create_symlink(to, new_symlink);} + + inline + void create_symlink(const path& to, const path& new_symlink, system::error_code& ec) + {detail::create_symlink(to, new_symlink, &ec);} + inline + path current_path() {return detail::current_path();} + + inline + path current_path(system::error_code& ec) {return detail::current_path(&ec);} + + inline + void current_path(const path& p) {detail::current_path(p);} + + inline + void current_path(const path& p, system::error_code& ec) {detail::current_path(p, &ec);} + + inline + bool equivalent(const path& p1, const path& p2) {return detail::equivalent(p1, p2);} + + inline + bool equivalent(const path& p1, const path& p2, system::error_code& ec) + {return detail::equivalent(p1, p2, &ec);} + inline + boost::uintmax_t file_size(const path& p) {return detail::file_size(p);} + + inline + boost::uintmax_t file_size(const path& p, system::error_code& ec) + {return detail::file_size(p, &ec);} + inline + boost::uintmax_t hard_link_count(const path& p) {return detail::hard_link_count(p);} + + inline + boost::uintmax_t hard_link_count(const path& p, system::error_code& ec) + {return detail::hard_link_count(p, &ec);} + inline + path initial_path() {return detail::initial_path();} + + inline + path initial_path(system::error_code& ec) {return detail::initial_path(&ec);} + + template <class Path> + path initial_path() {return initial_path();} + template <class Path> + path initial_path(system::error_code& ec) {return detail::initial_path(&ec);} + + inline + std::time_t last_write_time(const path& p) {return detail::last_write_time(p);} + + inline + std::time_t last_write_time(const path& p, system::error_code& ec) + {return detail::last_write_time(p, &ec);} + inline + void last_write_time(const path& p, const std::time_t new_time) + {detail::last_write_time(p, new_time);} + inline + void last_write_time(const path& p, const std::time_t new_time, system::error_code& ec) + {detail::last_write_time(p, new_time, &ec);} + inline + void permissions(const path& p, perms prms) + {detail::permissions(p, prms);} + inline + void permissions(const path& p, perms prms, system::error_code& ec) + {detail::permissions(p, prms, &ec);} + + inline + path read_symlink(const path& p) {return detail::read_symlink(p);} + + inline + path read_symlink(const path& p, system::error_code& ec) + {return detail::read_symlink(p, &ec);} + inline + // For standardization, if the committee doesn't like "remove", consider "eliminate" + bool remove(const path& p) {return detail::remove(p);} + + inline + bool remove(const path& p, system::error_code& ec) {return detail::remove(p, &ec);} + + inline + boost::uintmax_t remove_all(const path& p) {return detail::remove_all(p);} + + inline + boost::uintmax_t remove_all(const path& p, system::error_code& ec) + {return detail::remove_all(p, &ec);} + inline + void rename(const path& old_p, const path& new_p) {detail::rename(old_p, new_p);} + + inline + void rename(const path& old_p, const path& new_p, system::error_code& ec) + {detail::rename(old_p, new_p, &ec);} + inline // name suggested by Scott McMurray + void resize_file(const path& p, uintmax_t size) {detail::resize_file(p, size);} + + inline + void resize_file(const path& p, uintmax_t size, system::error_code& ec) + {detail::resize_file(p, size, &ec);} + inline + space_info space(const path& p) {return detail::space(p);} + + inline + space_info space(const path& p, system::error_code& ec) {return detail::space(p, &ec);} + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + inline bool symbolic_link_exists(const path& p) + { return is_symlink(symlink_status(p)); } +# endif + + inline + path system_complete(const path& p) {return detail::system_complete(p);} + + inline + path system_complete(const path& p, system::error_code& ec) + {return detail::system_complete(p, &ec);} + inline + path temp_directory_path() {return detail::temp_directory_path();} + + inline + path temp_directory_path(system::error_code& ec) + {return detail::temp_directory_path(&ec);} + inline + path unique_path(const path& p="%%%%-%%%%-%%%%-%%%%") + { return detail::unique_path(p); } + inline + path unique_path(const path& p, system::error_code& ec) + { return detail::unique_path(p, &ec); } + +//--------------------------------------------------------------------------------------// +// // +// 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 constructor, 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(), file_status symlink_st = file_status()) + { m_path = p; m_status = st; m_symlink_status = symlink_st; } + + void replace_filename(const boost::filesystem::path& p, + file_status st = file_status(), file_status symlink_st = file_status()) + { + 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() const {return m_get_status();} + file_status status(system::error_code& ec) const {return m_get_status(&ec);} + file_status symlink_status() const {return m_get_symlink_status();} + file_status symlink_status(system::error_code& ec) const {return m_get_symlink_status(&ec);} + + bool operator==(const directory_entry& rhs) {return m_path == rhs.m_path;} + bool operator!=(const directory_entry& rhs) {return m_path != rhs.m_path;} + bool operator< (const directory_entry& rhs) {return m_path < rhs.m_path;} + bool operator<=(const directory_entry& rhs) {return m_path <= rhs.m_path;} + bool operator> (const directory_entry& rhs) {return m_path > rhs.m_path;} + bool operator>=(const directory_entry& rhs) {return m_path >= rhs.m_path;} + +private: + boost::filesystem::path m_path; + mutable file_status m_status; // stat()-like + mutable file_status m_symlink_status; // lstat()-like + + file_status m_get_status(system::error_code* ec=0) const; + file_status m_get_symlink_status(system::error_code* ec=0) const; +}; // 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 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, + system::error_code* ec); + +} // 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 + explicit directory_iterator(const path& p) + : m_imp(new detail::dir_itr_imp) + { detail::directory_iterator_construct(*this, p, 0); } + + directory_iterator(const path& p, system::error_code& ec) + : m_imp(new detail::dir_itr_imp) + { detail::directory_iterator_construct(*this, p, &ec); } + + ~directory_iterator() {} // never throws + + directory_iterator& increment(system::error_code& ec) + { + detail::directory_iterator_increment(*this, &ec); + return *this; + } + + private: + friend struct detail::dir_itr_imp; + friend BOOST_FILESYSTEM_DECL void detail::directory_iterator_construct(directory_iterator& it, + const path& p, system::error_code* ec); + friend BOOST_FILESYSTEM_DECL void detail::directory_iterator_increment(directory_iterator& it, + system::error_code* ec); + + // 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_MSG(m_imp.get(), "attempt to dereference end iterator"); + return m_imp->dir_entry; + } + + void increment() { detail::directory_iterator_increment(*this, 0); } + + bool equal(const directory_iterator& rhs) const + { return m_imp == rhs.m_imp; } + }; + +//--------------------------------------------------------------------------------------// +// // +// recursive_directory_iterator helpers // +// // +//--------------------------------------------------------------------------------------// + + BOOST_SCOPED_ENUM_START(symlink_option) + { + none, + no_recurse = none, // don't follow directory symlinks (default behavior) + recurse, // follow directory symlinks + _detail_no_push = recurse << 1 // internal use only + }; + BOOST_SCOPED_ENUM_END + + BOOST_BITMASK(BOOST_SCOPED_ENUM(symlink_option)) + + 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; + BOOST_SCOPED_ENUM(symlink_option) m_options; + + recur_dir_itr_imp() : m_level(0), m_options(symlink_option::none) {} + + void increment(system::error_code* ec); // ec == 0 means throw on error + + void pop(); + + }; + + // Implementation is inline to avoid dynamic linking difficulties with m_stack: + // Microsoft warning C4251, m_stack needs to have dll-interface to be used by + // clients of struct 'boost::filesystem::detail::recur_dir_itr_imp' + + inline + void recur_dir_itr_imp::increment(system::error_code* ec) + // ec == 0 means throw on error + { + if ((m_options & symlink_option::_detail_no_push) == symlink_option::_detail_no_push) + m_options &= ~symlink_option::_detail_no_push; + + else + { + // Logic for following predicate was contributed by Daniel Aarno to handle cyclic + // symlinks correctly and efficiently, fixing ticket #5652. + // if (((m_options & symlink_option::recurse) == symlink_option::recurse + // || !is_symlink(m_stack.top()->symlink_status())) + // && is_directory(m_stack.top()->status())) ... + // The predicate code has since been rewritten to pass error_code arguments, + // per ticket #5653. + bool or_pred = (m_options & symlink_option::recurse) == symlink_option::recurse + || (ec == 0 ? !is_symlink(m_stack.top()->symlink_status()) + : !is_symlink(m_stack.top()->symlink_status(*ec))); + if (ec != 0 && *ec) + return; + bool and_pred = or_pred && (ec == 0 ? is_directory(m_stack.top()->status()) + : is_directory(m_stack.top()->status(*ec))); + if (ec != 0 && *ec) + return; + + if (and_pred) + { + if (ec == 0) + m_stack.push(directory_iterator(m_stack.top()->path())); + else + { + m_stack.push(directory_iterator(m_stack.top()->path(), *ec)); + if (*ec) + return; + } + if (m_stack.top() != directory_iterator()) + { + ++m_level; + return; + } + m_stack.pop(); + } + } + + while (!m_stack.empty() && ++m_stack.top() == directory_iterator()) + { + m_stack.pop(); + --m_level; + } + } + + inline + void recur_dir_itr_imp::pop() + { + BOOST_ASSERT_MSG(m_level > 0, + "pop() on recursive_directory_iterator with level < 1"); + + do + { + m_stack.pop(); + --m_level; + } + while (!m_stack.empty() && ++m_stack.top() == directory_iterator()); + } + } // 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, + BOOST_SCOPED_ENUM(symlink_option) opt = symlink_option::none) + : m_imp(new detail::recur_dir_itr_imp) + { + m_imp->m_options = opt; + 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, + BOOST_SCOPED_ENUM(symlink_option) opt, + system::error_code & ec) + : m_imp(new detail::recur_dir_itr_imp) + { + m_imp->m_options = opt; + m_imp->m_stack.push(directory_iterator(dir_path, ec)); + 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_options = symlink_option::none; + m_imp->m_stack.push(directory_iterator(dir_path, ec)); + if (m_imp->m_stack.top() == directory_iterator()) + { m_imp.reset (); } + } + + recursive_directory_iterator& increment(system::error_code& ec) + { + BOOST_ASSERT_MSG(m_imp.get(), + "increment() on end recursive_directory_iterator"); + m_imp->increment(&ec); + if (m_imp->m_stack.empty()) + m_imp.reset(); // done, so make end iterator + return *this; + } + + int level() const + { + BOOST_ASSERT_MSG(m_imp.get(), + "level() on end recursive_directory_iterator"); + return m_imp->m_level; + } + + bool no_push_pending() const + { + BOOST_ASSERT_MSG(m_imp.get(), + "is_no_push_requested() on end recursive_directory_iterator"); + return (m_imp->m_options & symlink_option::_detail_no_push) + == symlink_option::_detail_no_push; + } + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + bool no_push_request() const { return no_push_pending(); } +# endif + + void pop() + { + BOOST_ASSERT_MSG(m_imp.get(), + "pop() on end recursive_directory_iterator"); + m_imp->pop(); + if (m_imp->m_stack.empty()) m_imp.reset(); // done, so make end iterator + } + + void no_push(bool value=true) + { + BOOST_ASSERT_MSG(m_imp.get(), + "no_push() on end recursive_directory_iterator"); + if (value) + m_imp->m_options |= symlink_option::_detail_no_push; + else + m_imp->m_options &= ~symlink_option::_detail_no_push; + } + + file_status status() const + { + BOOST_ASSERT_MSG(m_imp.get(), + "status() on end recursive_directory_iterator"); + return m_imp->m_stack.top()->status(); + } + + file_status symlink_status() const + { + BOOST_ASSERT_MSG(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_MSG(m_imp.get(), + "dereference of end recursive_directory_iterator"); + return *m_imp->m_stack.top(); + } + + void increment() + { + BOOST_ASSERT_MSG(m_imp.get(), + "increment of end recursive_directory_iterator"); + m_imp->increment(0); + if (m_imp->m_stack.empty()) + m_imp.reset(); // done, so make end iterator + } + + bool equal(const recursive_directory_iterator& rhs) const + { return m_imp == rhs.m_imp; } + + }; + +# if !defined(BOOST_FILESYSTEM_NO_DEPRECATED) + typedef recursive_directory_iterator wrecursive_directory_iterator; +# endif + +//--------------------------------------------------------------------------------------// +// // +// class filesystem_error // +// // +//--------------------------------------------------------------------------------------// + + class BOOST_SYMBOL_VISIBLE 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 + + 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( + 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( + 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() 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* 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 filesystem3 +} // namespace boost + +//----------------------------------------------------------------------------// + +namespace boost +{ + namespace filesystem + { + // permissions + using filesystem3::no_perms; + using filesystem3::owner_read; + using filesystem3::owner_write; + using filesystem3::owner_exe; + using filesystem3::owner_all; + using filesystem3::group_read; + using filesystem3::group_write; + using filesystem3::group_exe; + using filesystem3::group_all; + using filesystem3::others_read; + using filesystem3::others_write; + using filesystem3::others_exe; + using filesystem3::others_all; + using filesystem3::all_all; + using filesystem3::set_uid_on_exe; + using filesystem3::set_gid_on_exe; + using filesystem3::sticky_bit; + using filesystem3::perms_mask; + using filesystem3::perms_not_known; + using filesystem3::add_perms; + using filesystem3::remove_perms; + using filesystem3::symlink_perms; + + using filesystem3::absolute; + using filesystem3::block_file; + using filesystem3::canonical; + using filesystem3::character_file; +// using filesystem3::copy; + using filesystem3::copy_file; + using filesystem3::copy_option; + using filesystem3::copy_symlink; + using filesystem3::create_directories; + using filesystem3::create_directory; + using filesystem3::create_hard_link; + using filesystem3::create_symlink; + using filesystem3::create_directory_symlink; + using filesystem3::current_path; + using filesystem3::directory_entry; + using filesystem3::directory_file; + using filesystem3::directory_iterator; + using filesystem3::equivalent; + using filesystem3::exists; + using filesystem3::fifo_file; + using filesystem3::file_not_found; + using filesystem3::file_size; + using filesystem3::file_status; + using filesystem3::file_type; + using filesystem3::filesystem_error; + using filesystem3::hard_link_count; + using filesystem3::initial_path; + using filesystem3::is_directory; + using filesystem3::is_directory; + using filesystem3::is_empty; + using filesystem3::is_other; + using filesystem3::is_regular_file; + using filesystem3::is_symlink; + using filesystem3::last_write_time; + using filesystem3::permissions; + using filesystem3::permissions_present; + using filesystem3::perms; + using filesystem3::read_symlink; + using filesystem3::recursive_directory_iterator; + using filesystem3::regular_file; + using filesystem3::reparse_file; + using filesystem3::remove; + using filesystem3::remove_all; + using filesystem3::rename; + using filesystem3::resize_file; + using filesystem3::socket_file; + using filesystem3::space; + using filesystem3::space_info; + using filesystem3::status; + using filesystem3::status_error; + using filesystem3::status_known; + using filesystem3::symlink_file; + using filesystem3::symlink_option; + using filesystem3::symlink_status; + using filesystem3::system_complete; + using filesystem3::temp_directory_path; + using filesystem3::type_present; + using filesystem3::type_unknown; + using filesystem3::unique_path; +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + using filesystem3::is_regular; + using filesystem3::status_unknown; + using filesystem3::symbolic_link_exists; + //using filesystem3::wdirectory_iterator; + //using filesystem3::wdirectory_entry; +# endif + namespace detail + { + using filesystem3::detail::possible_large_file_size_support; + } + } +} + +#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas +#endif // BOOST_FILESYSTEM3_OPERATIONS_HPP diff --git a/boost/filesystem/v3/path.hpp b/boost/filesystem/v3/path.hpp new file mode 100644 index 0000000..c483671 --- /dev/null +++ b/boost/filesystem/v3/path.hpp @@ -0,0 +1,760 @@ +// filesystem path.hpp ---------------------------------------------------------------// + +// Copyright Beman Dawes 2002-2005, 2009 +// Copyright Vladimir Prus 2002 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// Library home page: http://www.boost.org/libs/filesystem + +// path::stem(), extension(), and replace_extension() are based on +// basename(), extension(), and change_extension() from the original +// filesystem/convenience.hpp header by Vladimir Prus. + +#ifndef BOOST_FILESYSTEM_PATH_HPP +#define BOOST_FILESYSTEM_PATH_HPP + +#include <boost/config.hpp> + +# if defined( BOOST_NO_STD_WSTRING ) +# error Configuration not supported: Boost.Filesystem V3 and later requires std::wstring support +# endif + +#include <boost/filesystem/v3/config.hpp> +#include <boost/filesystem/v3/path_traits.hpp> // includes <cwchar> +#include <boost/system/error_code.hpp> +#include <boost/system/system_error.hpp> +#include <boost/iterator/iterator_facade.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/io/detail/quoted_manip.hpp> +#include <boost/static_assert.hpp> +#include <boost/functional/hash_fwd.hpp> +#include <string> +#include <iterator> +#include <cstring> +#include <iosfwd> +#include <stdexcept> +#include <cassert> +#include <locale> +#include <algorithm> + +#include <boost/config/abi_prefix.hpp> // must be the last #include + +namespace boost +{ +namespace filesystem3 +{ + //------------------------------------------------------------------------------------// + // // + // class path // + // // + //------------------------------------------------------------------------------------// + + class BOOST_FILESYSTEM_DECL path + { + public: + + // value_type is the character type used by the operating system API to + // represent paths. + +# ifdef BOOST_WINDOWS_API + typedef wchar_t value_type; +# else + typedef char value_type; +# endif + typedef std::basic_string<value_type> string_type; + typedef std::codecvt<wchar_t, char, std::mbstate_t> codecvt_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_pathname comments for further important rationale. + + // 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 + // + // ********************************************************************************** + + // Supported source arguments: half-open iterator range, container, c-array, + // and single pointer to null terminated string. + + // All source arguments except pointers to null terminated byte strings support + // multi-byte character strings which may have embedded nulls. Embedded null + // support is required for some Asian languages on Windows. + + // [defaults] "const codecvt_type& cvt=codecvt()" default arguments are not used + // because some compilers, such as Microsoft prior to VC++ 10, do not handle defaults + // correctly in templates. + + // ----- constructors ----- + + path(){} + + path(const path& p) : m_pathname(p.m_pathname) {} + + template <class Source> + path(Source const& source, + typename boost::enable_if<path_traits::is_pathable< + typename boost::decay<Source>::type> >::type* =0) + { + path_traits::dispatch(source, m_pathname, codecvt()); + } + + // Overloads for the operating system API's native character type. Rationale: + // - Avoids use of codecvt() for native value_type strings. This limits the + // impact of locale("") initialization failures on POSIX systems to programs + // that actually depend on locale(""). It further ensures that exceptions thrown + // as a result of such failues occur after main() has started, so can be caught. + // This is a partial resolution of tickets 4688, 5100, and 5289. + // - A slight optimization for a common use case, particularly on POSIX since + // value_type is char and that is the most common useage. + path(const value_type* s) : m_pathname(s) {} + path(const std::basic_string<value_type>& s) : m_pathname(s) {} + + template <class Source> + path(Source const& source, const codecvt_type& cvt) + // see [defaults] note above explaining why codecvt() default arguments are not used + { + path_traits::dispatch(source, m_pathname, cvt); + } + + template <class InputIterator> + path(InputIterator begin, InputIterator end) + { + if (begin != end) + { + std::basic_string<typename std::iterator_traits<InputIterator>::value_type> + s(begin, end); + path_traits::convert(s.c_str(), s.c_str()+s.size(), m_pathname, codecvt()); + } + } + + template <class InputIterator> + path(InputIterator begin, InputIterator end, const codecvt_type& cvt) + { + if (begin != end) + { + std::basic_string<typename std::iterator_traits<InputIterator>::value_type> + s(begin, end); + path_traits::convert(s.c_str(), s.c_str()+s.size(), m_pathname, cvt); + } + } + + // ----- assignments ----- + + path& operator=(const path& p) + { + m_pathname = p.m_pathname; + return *this; + } + + path& operator=(const value_type* ptr) // required in case ptr overlaps *this + { + m_pathname = ptr; + return *this; + } + + template <class Source> + typename boost::enable_if<path_traits::is_pathable< + typename boost::decay<Source>::type>, path&>::type + operator=(Source const& source) + { + m_pathname.clear(); + path_traits::dispatch(source, m_pathname, codecvt()); + return *this; + } + + path& assign(const value_type* ptr, const codecvt_type&) // required in case ptr overlaps *this + { + m_pathname = ptr; + return *this; + } + + template <class Source> + path& assign(Source const& source, const codecvt_type& cvt) + { + m_pathname.clear(); + path_traits::dispatch(source, m_pathname, cvt); + return *this; + } + + template <class InputIterator> + path& assign(InputIterator begin, InputIterator end) + { + return assign(begin, end, codecvt()); + } + + template <class InputIterator> + path& assign(InputIterator begin, InputIterator end, const codecvt_type& cvt) + { + m_pathname.clear(); + if (begin != end) + { + std::basic_string<typename std::iterator_traits<InputIterator>::value_type> + s(begin, end); + path_traits::convert(s.c_str(), s.c_str()+s.size(), m_pathname, cvt); + } + return *this; + } + + // ----- appends ----- + + // if a separator is added, it is the preferred separator for the platform; + // slash for POSIX, backslash for Windows + + path& operator/=(const path& p); + + path& operator/=(const value_type* ptr); + + template <class Source> + typename boost::enable_if<path_traits::is_pathable< + typename boost::decay<Source>::type>, path&>::type + operator/=(Source const& source) + { + return append(source, codecvt()); + } + + path& append(const value_type* ptr, const codecvt_type&) // required in case ptr overlaps *this + { + this->operator/=(ptr); + return *this; + } + + template <class Source> + path& append(Source const& source, const codecvt_type& cvt); + + template <class InputIterator> + path& append(InputIterator begin, InputIterator end) + { + return append(begin, end, codecvt()); + } + + template <class InputIterator> + path& append(InputIterator begin, InputIterator end, const codecvt_type& cvt); + + // ----- modifiers ----- + + void clear() { m_pathname.clear(); } + path& make_preferred() +# ifdef BOOST_POSIX_API + { return *this; } // POSIX no effect +# else // BOOST_WINDOWS_API + ; // change slashes to backslashes +# endif + path& remove_filename(); + path& replace_extension(const path& new_extension = path()); + void swap(path& rhs) { m_pathname.swap(rhs.m_pathname); } + + // ----- observers ----- + + // For operating systems that format file paths differently than directory + // paths, return values 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. + + // The string or path returned by an observer are specified as being formatted + // as "native" or "generic". + // + // For POSIX, these are all the same format; slashes and backslashes are as input and + // are not modified. + // + // For Windows, native: as input; slashes and backslashes are not modified; + // this is the format of the internally stored string. + // generic: backslashes are converted to slashes + + // ----- native format observers ----- + + const string_type& native() const { return m_pathname; } // Throws: nothing + const value_type* c_str() const { return m_pathname.c_str(); } // Throws: nothing + + template <class String> + String string() const; + + template <class String> + String string(const codecvt_type& cvt) const; + +# ifdef BOOST_WINDOWS_API + const std::string string() const { return string(codecvt()); } + const std::string string(const codecvt_type& cvt) const + { + std::string tmp; + if (!m_pathname.empty()) + path_traits::convert(&*m_pathname.begin(), &*m_pathname.begin()+m_pathname.size(), + tmp, cvt); + return tmp; + } + + // string_type is std::wstring, so there is no conversion + const std::wstring& wstring() const { return m_pathname; } + const std::wstring& wstring(const codecvt_type&) const { return m_pathname; } + +# else // BOOST_POSIX_API + // string_type is std::string, so there is no conversion + const std::string& string() const { return m_pathname; } + const std::string& string(const codecvt_type&) const { return m_pathname; } + + const std::wstring wstring() const { return wstring(codecvt()); } + const std::wstring wstring(const codecvt_type& cvt) const + { + std::wstring tmp; + if (!m_pathname.empty()) + path_traits::convert(&*m_pathname.begin(), &*m_pathname.begin()+m_pathname.size(), + tmp, cvt); + return tmp; + } + +# endif + + // ----- generic format observers ----- + + template <class String> + String generic_string() const; + + template <class String> + String generic_string(const codecvt_type& cvt) const; + +# ifdef BOOST_WINDOWS_API + const std::string generic_string() const { return generic_string(codecvt()); } + const std::string generic_string(const codecvt_type& cvt) const; + const std::wstring generic_wstring() const; + const std::wstring generic_wstring(const codecvt_type&) const { return generic_wstring(); }; + +# else // BOOST_POSIX_API + // On POSIX-like systems, the generic format is the same as the native format + const std::string& generic_string() const { return m_pathname; } + const std::string& generic_string(const codecvt_type&) const { return m_pathname; } + const std::wstring generic_wstring() const { return wstring(codecvt()); } + const std::wstring generic_wstring(const codecvt_type& cvt) const { return wstring(cvt); } + +# endif + + // ----- 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_pathname.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_parent_path() const { return !parent_path().empty(); } + bool has_filename() const { return !m_pathname.empty(); } + bool has_stem() const { return !stem().empty(); } + bool has_extension() const { return !extension().empty(); } + bool is_absolute() const + { +# ifdef BOOST_WINDOWS_API + return has_root_name() && has_root_directory(); +# else + return has_root_directory(); +# endif + } + bool is_relative() const { return !is_absolute(); } + + // ----- iterators ----- + + class iterator; + typedef iterator const_iterator; + + iterator begin() const; + iterator end() const; + + // ----- static members ----- + + // ----- imbue ----- + + static std::locale imbue(const std::locale& loc); + + // ----- codecvt ----- + + static const codecvt_type& codecvt() + { + return *wchar_t_codecvt_facet(); + } + + // ----- deprecated functions ----- + +# if defined(BOOST_FILESYSTEM_DEPRECATED) && defined(BOOST_FILESYSTEM_NO_DEPRECATED) +# error both BOOST_FILESYSTEM_DEPRECATED and BOOST_FILESYSTEM_NO_DEPRECATED are defined +# endif + +# if !defined(BOOST_FILESYSTEM_NO_DEPRECATED) + // recently deprecated functions supplied by default + path& normalize() { return m_normalize(); } + path& remove_leaf() { return remove_filename(); } + path leaf() const { return filename(); } + path branch_path() const { return parent_path(); } + bool has_leaf() const { return !m_pathname.empty(); } + bool has_branch_path() const { return !parent_path().empty(); } + bool is_complete() const { return is_absolute(); } +# endif + +# if defined(BOOST_FILESYSTEM_DEPRECATED) + // deprecated functions with enough signature or semantic changes that they are + // not supplied by default + const std::string file_string() const { return string(); } + const std::string directory_string() const { return string(); } + const std::string native_file_string() const { return string(); } + const std::string native_directory_string() const { return string(); } + const string_type external_file_string() const { return native(); } + const string_type external_directory_string() const { return native(); } + + // older functions no longer supported + //typedef bool (*name_check)(const std::string & name); + //basic_path(const string_type& str, name_check) { operator/=(str); } + //basic_path(const typename string_type::value_type* s, name_check) + // { operator/=(s);} + //static bool default_name_check_writable() { return false; } + //static void default_name_check(name_check) {} + //static name_check default_name_check() { return 0; } + //basic_path& canonize(); +# endif + +//--------------------------------------------------------------------------------------// +// class path private members // +//--------------------------------------------------------------------------------------// + + private: +# if defined(_MSC_VER) +# pragma warning(push) // Save warning settings +# pragma warning(disable : 4251) // disable warning: class 'std::basic_string<_Elem,_Traits,_Ax>' +# endif // needs to have dll-interface... +/* + m_pathname has the type, encoding, and format required by the native + operating system. Thus for POSIX and Windows there is no conversion for + passing m_pathname.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_pathname; // Windows: as input; backslashes NOT converted to slashes, + // slashes NOT converted to backslashes +# if defined(_MSC_VER) +# pragma warning(pop) // restore warning settings. +# endif + + string_type::size_type m_append_separator_if_needed(); + // Returns: If separator is to be appended, m_pathname.size() before append. Otherwise 0. + // Note: An append is never performed if size()==0, so a returned 0 is unambiguous. + + void m_erase_redundant_separator(string_type::size_type sep_pos); + string_type::size_type m_parent_path_end() const; + + path& m_normalize(); + + // 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); + + // 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); + + static const codecvt_type *& wchar_t_codecvt_facet(); + + }; // class path + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + typedef path wpath; +# endif + + //------------------------------------------------------------------------------------// + // class path::iterator // + //------------------------------------------------------------------------------------// + + class path::iterator + : public boost::iterator_facade< + path::iterator, + path const, + boost::bidirectional_traversal_tag > + { + private: + friend class boost::iterator_core_access; + friend class boost::filesystem3::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_pathname. The + // end() iterator is indicated by + // m_pos == m_path_ptr->m_pathname.size() + }; // path::iterator + + //------------------------------------------------------------------------------------// + // // + // non-member functions // + // // + //------------------------------------------------------------------------------------// + + // std::lexicographical_compare would infinately recurse because path iterators + // yield paths, so provide a path aware version + inline bool lexicographical_compare(path::iterator first1, path::iterator last1, + path::iterator first2, path::iterator last2) + { + for (; first1 != last1 && first2 != last2 ; ++first1, ++first2) + { + if (first1->native() < first2->native()) return true; + if (first2->native() < first1->native()) return false; + } + return first1 == last1 && first2 != last2; + } + + inline bool operator<(const path& lhs, const path& rhs) + { + return lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); + } + + 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); } + + // equality operators act as if comparing generic format strings, to achieve the + // effect of lexicographical_compare element by element compare. + // operator==() efficiency is a concern; a user reported the original version 2 + // !(lhs < rhs) && !(rhs < lhs) implementation caused a serious performance problem + // for a map of 10,000 paths. + +# ifdef BOOST_WINDOWS_API + inline bool operator==(const path& lhs, const path::value_type* rhs) + { + const path::value_type* l(lhs.c_str()); + while ((*l == *rhs || (*l == L'\\' && *rhs == L'/') || (*l == L'/' && *rhs == L'\\')) + && *l) { ++l; ++rhs; } + return *l == *rhs; + } + inline bool operator==(const path& lhs, const path& rhs) { return lhs == rhs.c_str(); } + inline bool operator==(const path& lhs, const path::string_type& rhs) { return lhs == rhs.c_str(); } + inline bool operator==(const path::string_type& lhs, const path& rhs) { return rhs == lhs.c_str(); } + inline bool operator==(const path::value_type* lhs, const path& rhs) { return rhs == lhs; } + + inline std::size_t hash_value(const path& x) + { + std::size_t seed = 0; + for(const path::value_type* it = x.c_str(); *it; ++it) + hash_combine(seed, *it == '/' ? L'\\' : *it); + return seed; + } +# else // BOOST_POSIX_API + inline bool operator==(const path& lhs, const path& rhs) { return lhs.native() == rhs.native(); } + inline bool operator==(const path& lhs, const path::string_type& rhs) { return lhs.native() == rhs; } + inline bool operator==(const path& lhs, const path::value_type* rhs) { return lhs.native() == rhs; } + inline bool operator==(const path::string_type& lhs, const path& rhs) { return lhs == rhs.native(); } + inline bool operator==(const path::value_type* lhs, const path& rhs) { return lhs == rhs.native(); } + + inline std::size_t hash_value(const path& x) + { + return hash_range(x.native().begin(), x.native().end()); + } +# endif + + inline bool operator!=(const path& lhs, const path& rhs) { return !(lhs == rhs); } + inline bool operator!=(const path& lhs, const path::string_type& rhs) { return !(lhs == rhs); } + inline bool operator!=(const path& lhs, const path::value_type* rhs) { return !(lhs == rhs); } + inline bool operator!=(const path::string_type& lhs, const path& rhs) { return !(lhs == rhs); } + inline bool operator!=(const path::value_type* 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 + // use boost::io::quoted() to handle spaces in paths + // use '&' as escape character to ease use for Windows paths + + template <class Char, class Traits> + inline std::basic_ostream<Char, Traits>& + operator<<(std::basic_ostream<Char, Traits>& os, const path& p) + { + return os + << boost::io::quoted(p.template string<std::basic_string<Char> >(), static_cast<Char>('&')); + } + + template <class Char, class Traits> + inline std::basic_istream<Char, Traits>& + operator>>(std::basic_istream<Char, Traits>& is, path& p) + { + std::basic_string<Char> str; + is >> boost::io::quoted(str, static_cast<Char>('&')); + p = str; + return is; + } + + // name_checks + + // These functions are holdovers from version 1. It isn't clear they have much + // usefulness, or how to generalize them for later versions. + + 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); + +//--------------------------------------------------------------------------------------// +// class path member template implementation // +//--------------------------------------------------------------------------------------// + + template <class InputIterator> + path& path::append(InputIterator begin, InputIterator end, const codecvt_type& cvt) + { + if (begin == end) + return *this; + string_type::size_type sep_pos(m_append_separator_if_needed()); + std::basic_string<typename std::iterator_traits<InputIterator>::value_type> + s(begin, end); + path_traits::convert(s.c_str(), s.c_str()+s.size(), m_pathname, cvt); + if (sep_pos) + m_erase_redundant_separator(sep_pos); + return *this; + } + + template <class Source> + path& path::append(Source const& source, const codecvt_type& cvt) + { + if (path_traits::empty(source)) + return *this; + string_type::size_type sep_pos(m_append_separator_if_needed()); + path_traits::dispatch(source, m_pathname, cvt); + if (sep_pos) + m_erase_redundant_separator(sep_pos); + return *this; + } + +//--------------------------------------------------------------------------------------// +// class path member template specializations // +//--------------------------------------------------------------------------------------// + + template <> inline + std::string path::string<std::string>() const + { return string(); } + + template <> inline + std::wstring path::string<std::wstring>() const + { return wstring(); } + + template <> inline + std::string path::string<std::string>(const codecvt_type& cvt) const + { return string(cvt); } + + template <> inline + std::wstring path::string<std::wstring>(const codecvt_type& cvt) const + { return wstring(cvt); } + + template <> inline + std::string path::generic_string<std::string>() const + { return generic_string(); } + + template <> inline + std::wstring path::generic_string<std::wstring>() const + { return generic_wstring(); } + + template <> inline + std::string path::generic_string<std::string>(const codecvt_type& cvt) const + { return generic_string(cvt); } + + template <> inline + std::wstring path::generic_string<std::wstring>(const codecvt_type& cvt) const + { return generic_wstring(cvt); } + + +} // namespace filesystem3 +} // namespace boost + +//----------------------------------------------------------------------------// + +namespace boost +{ + namespace filesystem + { + using filesystem3::path; +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + using filesystem3::wpath; +# endif + using filesystem3::lexicographical_compare; + using filesystem3::portable_posix_name; + using filesystem3::windows_name; + using filesystem3::portable_name; + using filesystem3::portable_directory_name; + using filesystem3::portable_file_name; + using filesystem3::native; + using filesystem3::swap; + using filesystem3::operator<; + using filesystem3::operator==; + using filesystem3::operator!=; + using filesystem3::operator>; + using filesystem3::operator<=; + using filesystem3::operator>=; + using filesystem3::operator/; + using filesystem3::operator<<; + using filesystem3::operator>>; + } +} + +//----------------------------------------------------------------------------// + +#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas + +#endif // BOOST_FILESYSTEM_PATH_HPP diff --git a/boost/filesystem/v3/path_traits.hpp b/boost/filesystem/v3/path_traits.hpp new file mode 100644 index 0000000..13f1b20 --- /dev/null +++ b/boost/filesystem/v3/path_traits.hpp @@ -0,0 +1,247 @@ +// filesystem path_traits.hpp --------------------------------------------------------// + +// Copyright Beman Dawes 2009 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// Library home page: http://www.boost.org/libs/filesystem + +#ifndef BOOST_FILESYSTEM_PATH_TRAITS_HPP +#define BOOST_FILESYSTEM_PATH_TRAITS_HPP + +#include <boost/config.hpp> + +# if defined( BOOST_NO_STD_WSTRING ) +# error Configuration not supported: Boost.Filesystem V3 and later requires std::wstring support +# endif + +#include <boost/filesystem/v3/config.hpp> +#include <boost/utility/enable_if.hpp> +#include <boost/type_traits/is_array.hpp> +#include <boost/type_traits/decay.hpp> +#include <boost/system/error_code.hpp> +#include <cwchar> // for mbstate_t +#include <string> +#include <vector> +#include <list> +#include <iterator> +#include <locale> +#include <boost/assert.hpp> +// #include <iostream> //**** comment me out **** + +#include <boost/config/abi_prefix.hpp> // must be the last #include + +namespace boost { namespace filesystem3 { + + BOOST_FILESYSTEM_DECL const system::error_category& codecvt_error_category(); + // uses std::codecvt_base::result used for error codes: + // + // ok: Conversion successful. + // partial: Not all source characters converted; one or more additional source + // characters are needed to produce the final target character, or the + // size of the target intermediate buffer was too small to hold the result. + // error: A character in the source could not be converted to the target encoding. + // noconv: The source and target characters have the same type and encoding, so no + // conversion was necessary. + + class directory_entry; + +namespace path_traits { + + typedef std::codecvt<wchar_t, char, std::mbstate_t> codecvt_type; + + // is_pathable type trait; allows disabling over-agressive class path member templates + + template <class T> + struct is_pathable { static const bool value = false; }; + + template<> struct is_pathable<char*> { static const bool value = true; }; + template<> struct is_pathable<const char*> { static const bool value = true; }; + template<> struct is_pathable<wchar_t*> { static const bool value = true; }; + template<> struct is_pathable<const wchar_t*> { static const bool value = true; }; + template<> struct is_pathable<std::string> { static const bool value = true; }; + template<> struct is_pathable<std::wstring> { static const bool value = true; }; + template<> struct is_pathable<std::vector<char> > { static const bool value = true; }; + template<> struct is_pathable<std::vector<wchar_t> > { static const bool value = true; }; + template<> struct is_pathable<std::list<char> > { static const bool value = true; }; + template<> struct is_pathable<std::list<wchar_t> > { static const bool value = true; }; + template<> struct is_pathable<directory_entry> { static const bool value = true; }; + + // Pathable empty + + template <class Container> inline + // disable_if aids broken compilers (IBM, old GCC, etc.) and is harmless for + // conforming compilers. Replace by plain "bool" at some future date (2012?) + typename boost::disable_if<boost::is_array<Container>, bool>::type + empty(const Container & c) + { return c.begin() == c.end(); } + + template <class T> inline + bool empty(T * const & c_str) + { + BOOST_ASSERT(c_str); + return !*c_str; + } + + template <typename T, size_t N> inline + bool empty(T (&)[N]) + { return N <= 1; } + + // value types differ ---------------------------------------------------------------// + // + // A from_end argument of 0 is less efficient than a known end, so use only if needed + + BOOST_FILESYSTEM_DECL + void convert(const char* from, + const char* from_end, // 0 for null terminated MBCS + std::wstring & to, + const codecvt_type& cvt); + + BOOST_FILESYSTEM_DECL + void convert(const wchar_t* from, + const wchar_t* from_end, // 0 for null terminated MBCS + std::string & to, + const codecvt_type& cvt); + + inline + void convert(const char* from, + std::wstring & to, + const codecvt_type& cvt) + { + BOOST_ASSERT(from); + convert(from, 0, to, cvt); + } + + inline + void convert(const wchar_t* from, + std::string & to, + const codecvt_type& cvt) + { + BOOST_ASSERT(from); + convert(from, 0, to, cvt); + } + + // value types same -----------------------------------------------------------------// + + // char + + inline + void convert(const char* from, const char* from_end, std::string & to, + const codecvt_type&) + { + BOOST_ASSERT(from); + BOOST_ASSERT(from_end); + to.append(from, from_end); + } + + inline + void convert(const char* from, + std::string & to, + const codecvt_type&) + { + BOOST_ASSERT(from); + to += from; + } + + // wchar_t + + inline + void convert(const wchar_t* from, const wchar_t* from_end, std::wstring & to, + const codecvt_type&) + { + BOOST_ASSERT(from); + BOOST_ASSERT(from_end); + to.append(from, from_end); + } + + inline + void convert(const wchar_t* from, + std::wstring & to, + const codecvt_type&) + { + BOOST_ASSERT(from); + to += from; + } + + // Source dispatch -----------------------------------------------------------------// + + // contiguous containers + template <class U> inline + void dispatch(const std::string& c, U& to, const codecvt_type& cvt) + { + if (c.size()) + convert(&*c.begin(), &*c.begin() + c.size(), to, cvt); + } + template <class U> inline + void dispatch(const std::wstring& c, U& to, const codecvt_type& cvt) + { + if (c.size()) + convert(&*c.begin(), &*c.begin() + c.size(), to, cvt); + } + template <class U> inline + void dispatch(const std::vector<char>& c, U& to, const codecvt_type& cvt) + { + if (c.size()) + convert(&*c.begin(), &*c.begin() + c.size(), to, cvt); + } + template <class U> inline + void dispatch(const std::vector<wchar_t>& c, U& to, const codecvt_type& cvt) + { + if (c.size()) + convert(&*c.begin(), &*c.begin() + c.size(), to, cvt); + } + + // non-contiguous containers + template <class Container, class U> inline + // disable_if aids broken compilers (IBM, old GCC, etc.) and is harmless for + // conforming compilers. Replace by plain "void" at some future date (2012?) + typename boost::disable_if<boost::is_array<Container>, void>::type + dispatch(const Container & c, U& to, const codecvt_type& cvt) + { + if (c.size()) + { + std::basic_string<typename Container::value_type> s(c.begin(), c.end()); + convert(s.c_str(), s.c_str()+s.size(), to, cvt); + } + } + + // c_str + template <class T, class U> inline + void dispatch(T * const & c_str, U& to, const codecvt_type& cvt) + { +// std::cout << "dispatch() const T *\n"; + BOOST_ASSERT(c_str); + convert(c_str, to, cvt); + } + + // Note: there is no dispatch on C-style arrays because the array may + // contain a string smaller than the array size. + + BOOST_FILESYSTEM_DECL + void dispatch(const directory_entry & de, +# ifdef BOOST_WINDOWS_API + std::wstring & to, +# else + std::string & to, +# endif + const codecvt_type&); + + +}}} // namespace boost::filesystem::path_traits + +//----------------------------------------------------------------------------// + +namespace boost +{ + namespace filesystem + { + using filesystem3::codecvt_error_category; +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED +# endif + } +} + +#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas + +#endif // BOOST_FILESYSTEM_PATH_TRAITS_HPP |