📄 path.hpp
字号:
}
// 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.leaf() );
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_leaf();
// 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
// remove_leaf ----------------------------------------------------------//
template<class String, class Traits>
basic_path<String, Traits> & basic_path<String, Traits>::remove_leaf()
{
m_path.erase(
detail::leaf_pos<String, Traits>( m_path, m_path.size() ) );
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;
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 )
{
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::leaf_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, system_error_type sys_err_code )
: filesystem_error(what, sys_err_code)
{
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, const path_type & path1,
system_error_type sys_err_code )
: filesystem_error(what, sys_err_code)
{
try
{
m_imp_ptr.reset( new m_imp );
m_imp_ptr->m_path1 = path1;
}
catch (...) { m_imp_ptr.reset(); }
}
template<class Path>
basic_filesystem_error<Path>::basic_filesystem_error(
const std::string & what, const path_type & path1,
const path_type & path2, system_error_type sys_err_code )
: filesystem_error(what, sys_err_code)
{
try
{
m_imp_ptr.reset( new m_imp );
m_imp_ptr->m_path1 = path1;
m_imp_ptr->m_path2 = path2;
}
catch (...) { m_imp_ptr.reset(); }
}
} // namespace BOOST_FILESYSTEM_NAMESPACE
} // namespace boost
#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas
#endif // BOOST_FILESYSTEM_PATH_HPP
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -