1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/ossrv_pub/boost_apis/boost/filesystem/convenience.hpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,331 @@
1.4 +// boost/filesystem/convenience.hpp ----------------------------------------//
1.5 +
1.6 +// Copyright Beman Dawes, 2002-2005
1.7 +// Copyright Vladimir Prus, 2002
1.8 +// Use, modification, and distribution is subject to the Boost Software
1.9 +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
1.10 +// http://www.boost.org/LICENSE_1_0.txt)
1.11 +
1.12 +// See library home page at http://www.boost.org/libs/filesystem
1.13 +
1.14 +//----------------------------------------------------------------------------//
1.15 +
1.16 +#ifndef BOOST_FILESYSTEM_CONVENIENCE_HPP
1.17 +#define BOOST_FILESYSTEM_CONVENIENCE_HPP
1.18 +
1.19 +#include <boost/filesystem/operations.hpp>
1.20 +#include <vector>
1.21 +#include <stack>
1.22 +
1.23 +#include <boost/config/abi_prefix.hpp> // must be the last #include
1.24 +
1.25 +# ifndef BOOST_FILESYSTEM_NARROW_ONLY
1.26 +# define BOOST_FS_FUNC(BOOST_FS_TYPE) \
1.27 + template<class Path> typename boost::enable_if<is_basic_path<Path>, \
1.28 + BOOST_FS_TYPE>::type
1.29 +# define BOOST_FS_FUNC_STRING BOOST_FS_FUNC(typename Path::string_type)
1.30 +# define BOOST_FS_TYPENAME typename
1.31 +# else
1.32 +# define BOOST_FS_FUNC(BOOST_FS_TYPE) inline BOOST_FS_TYPE
1.33 + typedef boost::filesystem::path Path;
1.34 +# define BOOST_FS_FUNC_STRING std::string
1.35 +# define BOOST_FS_TYPENAME
1.36 +# endif
1.37 +
1.38 +namespace boost
1.39 +{
1.40 + namespace filesystem
1.41 + {
1.42 +
1.43 + BOOST_FS_FUNC(bool) create_directories(const Path& ph)
1.44 + {
1.45 + if (ph.empty() || exists(ph))
1.46 + {
1.47 + if ( !ph.empty() && !is_directory(ph) )
1.48 + boost::throw_exception( basic_filesystem_error<Path>(
1.49 + "boost::filesystem::create_directories", ph, -1 ) );
1.50 + return false;
1.51 + }
1.52 +
1.53 + // First create branch, by calling ourself recursively
1.54 + create_directories(ph.branch_path());
1.55 + // Now that parent's path exists, create the directory
1.56 + create_directory(ph);
1.57 + return true;
1.58 + }
1.59 +
1.60 + BOOST_FS_FUNC_STRING extension(const Path& ph)
1.61 + {
1.62 + typedef BOOST_FS_TYPENAME Path::string_type string_type;
1.63 + string_type leaf = ph.leaf();
1.64 +
1.65 + BOOST_FS_TYPENAME string_type::size_type n = leaf.rfind('.');
1.66 + if (n != string_type::npos)
1.67 + return leaf.substr(n);
1.68 + else
1.69 + return string_type();
1.70 + }
1.71 +
1.72 + BOOST_FS_FUNC_STRING basename(const Path& ph)
1.73 + {
1.74 + typedef BOOST_FS_TYPENAME Path::string_type string_type;
1.75 + string_type leaf = ph.leaf();
1.76 + BOOST_FS_TYPENAME string_type::size_type n = leaf.rfind('.');
1.77 + return leaf.substr(0, n);
1.78 + }
1.79 +
1.80 + BOOST_FS_FUNC(Path) change_extension( const Path & ph,
1.81 + const BOOST_FS_TYPENAME Path::string_type & new_extension )
1.82 + { return ph.branch_path() / (basename(ph) + new_extension); }
1.83 +
1.84 +# ifndef BOOST_FILESYSTEM_NARROW_ONLY
1.85 +
1.86 + // "do-the-right-thing" overloads ---------------------------------------//
1.87 +
1.88 + inline bool create_directories(const path& ph)
1.89 + { return create_directories<path>(ph); }
1.90 + inline bool create_directories(const wpath& ph)
1.91 + { return create_directories<wpath>(ph); }
1.92 +
1.93 + inline std::string extension(const path& ph)
1.94 + { return extension<path>(ph); }
1.95 + inline std::wstring extension(const wpath& ph)
1.96 + { return extension<wpath>(ph); }
1.97 +
1.98 + inline std::string basename(const path& ph)
1.99 + { return basename<path>( ph ); }
1.100 + inline std::wstring basename(const wpath& ph)
1.101 + { return basename<wpath>( ph ); }
1.102 +
1.103 + inline path change_extension( const path & ph, const std::string& new_ex )
1.104 + { return change_extension<path>( ph, new_ex ); }
1.105 + inline wpath change_extension( const wpath & ph, const std::wstring& new_ex )
1.106 + { return change_extension<wpath>( ph, new_ex ); }
1.107 +
1.108 +# endif
1.109 +
1.110 +
1.111 + // basic_recursive_directory_iterator helpers --------------------------//
1.112 +
1.113 + namespace detail
1.114 + {
1.115 + template< class Path >
1.116 + struct recur_dir_itr_imp
1.117 + {
1.118 + typedef basic_directory_iterator< Path > element_type;
1.119 + std::stack< element_type, std::vector< element_type > > m_stack;
1.120 + int m_level;
1.121 + bool m_no_push;
1.122 + bool m_no_throw;
1.123 +
1.124 + recur_dir_itr_imp() : m_level(0), m_no_push(false), m_no_throw(false) {}
1.125 + };
1.126 +
1.127 + } // namespace detail
1.128 +
1.129 + // basic_recursive_directory_iterator ----------------------------------//
1.130 +
1.131 + template< class Path >
1.132 + class basic_recursive_directory_iterator
1.133 + : public boost::iterator_facade<
1.134 + basic_recursive_directory_iterator<Path>,
1.135 + basic_directory_entry<Path>,
1.136 + boost::single_pass_traversal_tag >
1.137 + {
1.138 + public:
1.139 + typedef Path path_type;
1.140 +
1.141 + basic_recursive_directory_iterator(){} // creates the "end" iterator
1.142 +
1.143 + explicit basic_recursive_directory_iterator( const Path & dir_path );
1.144 + basic_recursive_directory_iterator( const Path & dir_path, system_error_type & ec );
1.145 +
1.146 + int level() const { return m_imp->m_level; }
1.147 +
1.148 + void pop();
1.149 + void no_push()
1.150 + {
1.151 + BOOST_ASSERT( m_imp.get() && "attempt to no_push() on end iterator" );
1.152 + m_imp->m_no_push = true;
1.153 + }
1.154 +
1.155 + file_status status() const
1.156 + {
1.157 + BOOST_ASSERT( m_imp.get()
1.158 + && "attempt to call status() on end recursive_iterator" );
1.159 + return m_imp->m_stack.top()->status();
1.160 + }
1.161 +
1.162 + file_status symlink_status() const
1.163 + {
1.164 + BOOST_ASSERT( m_imp.get()
1.165 + && "attempt to call symlink_status() on end recursive_iterator" );
1.166 + return m_imp->m_stack.top()->symlink_status();
1.167 + }
1.168 +
1.169 + private:
1.170 +
1.171 + // shared_ptr provides shallow-copy semantics required for InputIterators.
1.172 + // m_imp.get()==0 indicates the end iterator.
1.173 + boost::shared_ptr< detail::recur_dir_itr_imp< Path > > m_imp;
1.174 +
1.175 + friend class boost::iterator_core_access;
1.176 +
1.177 + typename boost::iterator_facade<
1.178 + basic_recursive_directory_iterator<Path>,
1.179 + basic_directory_entry<Path>,
1.180 + boost::single_pass_traversal_tag >::reference
1.181 + dereference() const
1.182 + {
1.183 + BOOST_ASSERT( m_imp.get() && "attempt to dereference end iterator" );
1.184 + return *m_imp->m_stack.top();
1.185 + }
1.186 +
1.187 + void increment();
1.188 +
1.189 + bool equal( const basic_recursive_directory_iterator & rhs ) const
1.190 + { return m_imp == rhs.m_imp; }
1.191 + };
1.192 +
1.193 + typedef basic_recursive_directory_iterator<path> recursive_directory_iterator;
1.194 +# ifndef BOOST_FILESYSTEM_NARROW_ONLY
1.195 + typedef basic_recursive_directory_iterator<wpath> wrecursive_directory_iterator;
1.196 +# endif
1.197 +
1.198 + // basic_recursive_directory_iterator implementation -------------------//
1.199 +
1.200 + // constructors
1.201 + template<class Path>
1.202 + basic_recursive_directory_iterator<Path>::
1.203 + basic_recursive_directory_iterator( const Path & dir_path )
1.204 + : m_imp( new detail::recur_dir_itr_imp<Path> )
1.205 + {
1.206 + m_imp->m_stack.push( basic_directory_iterator<Path>( dir_path ) );
1.207 + }
1.208 +
1.209 + template<class Path>
1.210 + basic_recursive_directory_iterator<Path>::
1.211 + basic_recursive_directory_iterator( const Path & dir_path, system_error_type & ec )
1.212 + : m_imp( new detail::recur_dir_itr_imp<Path> )
1.213 + {
1.214 + m_imp->m_stack.push( basic_directory_iterator<Path>( dir_path, std::nothrow ) );
1.215 + m_imp->m_no_throw = true;
1.216 + }
1.217 +
1.218 + // increment
1.219 + template<class Path>
1.220 + void basic_recursive_directory_iterator<Path>::increment()
1.221 + {
1.222 + BOOST_ASSERT( m_imp.get() && "increment on end iterator" );
1.223 +
1.224 + static const basic_directory_iterator<Path> end_itr;
1.225 +
1.226 + if ( m_imp->m_no_push ) m_imp->m_no_push = false;
1.227 + else if ( is_directory( m_imp->m_stack.top()->status() ) )
1.228 + {
1.229 + system_error_type ec;
1.230 + m_imp->m_stack.push(
1.231 + m_imp->m_no_throw
1.232 + ? basic_directory_iterator<Path>( *m_imp->m_stack.top(), ec )
1.233 + : basic_directory_iterator<Path>( *m_imp->m_stack.top() )
1.234 + );
1.235 + if ( m_imp->m_stack.top() != end_itr )
1.236 + {
1.237 + ++m_imp->m_level;
1.238 + return;
1.239 + }
1.240 + m_imp->m_stack.pop();
1.241 + }
1.242 +
1.243 + while ( !m_imp->m_stack.empty()
1.244 + && ++m_imp->m_stack.top() == end_itr )
1.245 + {
1.246 + m_imp->m_stack.pop();
1.247 + --m_imp->m_level;
1.248 + }
1.249 +
1.250 + if ( m_imp->m_stack.empty() ) m_imp.reset(); // done, so make end iterator
1.251 + }
1.252 +
1.253 + // pop
1.254 + template<class Path>
1.255 + void basic_recursive_directory_iterator<Path>::pop()
1.256 + {
1.257 + BOOST_ASSERT( m_imp.get() && "pop on end iterator" );
1.258 + BOOST_ASSERT( m_imp->m_level > 0 && "pop with level < 1" );
1.259 +
1.260 + m_imp->m_stack.pop();
1.261 + --m_imp->m_level;
1.262 + }
1.263 +
1.264 + // what() basic_filesystem_error_decoder -------------------------------//
1.265 +
1.266 + namespace detail
1.267 + {
1.268 +
1.269 +# if BOOST_WORKAROUND(__BORLANDC__,BOOST_TESTED_AT(0x581))
1.270 + using boost::filesystem::system_message;
1.271 +# endif
1.272 +
1.273 + inline void decode_system_message( system_error_type ec, std::string & target )
1.274 + {
1.275 + system_message( ec, target );
1.276 + }
1.277 +
1.278 +# if defined(BOOST_WINDOWS_API) && !defined(BOOST_FILESYSTEM_NARROW_ONLY)
1.279 + inline void decode_system_message( system_error_type ec, std::wstring & target )
1.280 + {
1.281 + system_message( ec, target );
1.282 + }
1.283 +# endif
1.284 +
1.285 + template<class String>
1.286 + void decode_system_message( system_error_type ec, String & target )
1.287 + {
1.288 + std::string temp;
1.289 + system_message( ec, temp );
1.290 + for ( const char * p = temp.c_str(); *p != 0; ++p )
1.291 + { target += static_cast<typename String::value_type>( *p ); }
1.292 + }
1.293 + }
1.294 +
1.295 + template<class Path>
1.296 + typename Path::string_type what( const basic_filesystem_error<Path> & ex )
1.297 + {
1.298 + typename Path::string_type s;
1.299 + for ( const char * p = ex.what(); *p != 0; ++p )
1.300 + { s += static_cast<typename Path::string_type::value_type>( *p ); }
1.301 +
1.302 + if ( !ex.path1().empty() )
1.303 + {
1.304 + s += static_cast<typename Path::string_type::value_type>( ':' );
1.305 + s += static_cast<typename Path::string_type::value_type>( ' ' );
1.306 + s += static_cast<typename Path::string_type::value_type>( '\"' );
1.307 + s += ex.path1().file_string();
1.308 + s += static_cast<typename Path::string_type::value_type>( '\"' );
1.309 + }
1.310 + if ( !ex.path2().empty() )
1.311 + {
1.312 + s += static_cast<typename Path::string_type::value_type>( ',' );
1.313 + s += static_cast<typename Path::string_type::value_type>( ' ' );
1.314 + s += static_cast<typename Path::string_type::value_type>( '\"' );
1.315 + s += ex.path2().file_string();
1.316 + s += static_cast<typename Path::string_type::value_type>( '\"' );
1.317 + }
1.318 + if ( ex.system_error() )
1.319 + {
1.320 + s += static_cast<typename Path::string_type::value_type>( ' ' );
1.321 +
1.322 + detail::decode_system_message( ex.system_error(), s );
1.323 + }
1.324 + return s;
1.325 + }
1.326 +
1.327 + } // namespace filesystem
1.328 +} // namespace boost
1.329 +
1.330 +#undef BOOST_FS_FUNC_STRING
1.331 +#undef BOOST_FS_FUNC
1.332 +
1.333 +#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas
1.334 +#endif // BOOST_FILESYSTEM_CONVENIENCE_HPP