📄 path.hpp
字号:
// boost/filesystem/path.hpp -----------------------------------------------//
// Copyright Beman Dawes 2002-2005
// Use, modification, and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See library home page at http://www.boost.org/libs/filesystem
//----------------------------------------------------------------------------//
#ifndef BOOST_FILESYSTEM_PATH_HPP
#define BOOST_FILESYSTEM_PATH_HPP
#include <boost/filesystem/config.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <boost/throw_exception.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/static_assert.hpp>
#include <string>
#include <algorithm> // for lexicographical_compare
#include <iosfwd> // needed by basic_path inserter and extractor
#include <stdexcept>
#include <cassert>
# ifndef BOOST_FILESYSTEM_NARROW_ONLY
# include <locale>
# endif
#include <boost/config/abi_prefix.hpp> // must be the last #include
//----------------------------------------------------------------------------//
namespace boost
{
namespace BOOST_FILESYSTEM_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_FILESYSTEM_NARROW_ONLY
struct wpath_traits;
typedef basic_path< std::wstring, wpath_traits > wpath;
struct 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_FILESYSTEM_NARROW_ONLY
// error reporting support -------------------------------------------------//
typedef int errno_type; // determined by C standard
# ifdef BOOST_WINDOWS_API
typedef unsigned system_error_type;
BOOST_FILESYSTEM_DECL
errno_type lookup_errno( system_error_type sys_err_code );
# else
typedef int system_error_type;
inline errno_type lookup_errno( system_error_type sys_err_code )
{ return sys_err_code; }
# endif
// deprecated support for legacy function name
inline errno_type lookup_error_code( system_error_type sys_err_code )
{ return lookup_errno( sys_err_code ); }
BOOST_FILESYSTEM_DECL
void system_message( system_error_type sys_err_code, std::string & target );
// Effects: appends error message to target
# if defined(BOOST_WINDOWS_API) && !defined(BOOST_FILESYSTEM_NARROW_ONLY)
BOOST_FILESYSTEM_DECL void
system_message( system_error_type sys_err_code, std::wstring & target );
# endif
// filesystem_error ----------------------------------------------------//
class filesystem_error : public std::runtime_error
// see http://www.boost.org/more/error_handling.html for design rationale
{
public:
filesystem_error()
: std::runtime_error("filesystem error"), m_sys_err(0) {}
explicit filesystem_error(
const std::string & what_arg, system_error_type sys_ec = 0 )
: std::runtime_error(what_arg), m_sys_err(sys_ec) {}
system_error_type system_error() const { return m_sys_err; }
// Note: system_error() == 0 implies a library (rather than system) error
private:
system_error_type m_sys_err;
};
// basic_filesystem_error ----------------------------------------------//
template<class Path>
class basic_filesystem_error : public filesystem_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,
system_error_type sys_err_code );
basic_filesystem_error( const std::string & what,
const path_type & path1, system_error_type sys_err_code );
basic_filesystem_error( const std::string & what, const path_type & path1,
const path_type & path2, system_error_type sys_err_code );
~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 ;
}
private:
struct m_imp
{
path_type m_path1; // may be empty()
path_type m_path2; // may be empty()
};
boost::shared_ptr<m_imp> m_imp_ptr;
};
typedef basic_filesystem_error<path> filesystem_path_error;
# ifndef BOOST_FILESYSTEM_NARROW_ONLY
typedef basic_filesystem_error<wpath> filesystem_wpath_error;
# endif
// 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_FILESYSTEM_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
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 = ':' ); };
# ifdef BOOST_WINDOWS_PATH
template<class Path> struct path_alt_separator
{ BOOST_STATIC_CONSTANT( char, value = '\\' ); };
# 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 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_leaf();
// 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;
string_type leaf() const;
basic_path branch_path() const;
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_leaf() const { return !m_path.empty(); }
bool has_branch_path() const { return !branch_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_FILESYSTEM_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_FILESYSTEM_NAMESPACE::detail::iterator_helper<path_type>;
void increment()
{
boost::BOOST_FILESYSTEM_NAMESPACE::detail::iterator_helper<path_type>::do_increment(
*this );
}
void decrement()
{
boost::BOOST_FILESYSTEM_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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -