summaryrefslogtreecommitdiff
path: root/boost/filesystem/v2/convenience.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/filesystem/v2/convenience.hpp')
-rw-r--r--boost/filesystem/v2/convenience.hpp339
1 files changed, 339 insertions, 0 deletions
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