Remove lexically_relative() free function. Add path::rel

This commit is contained in:
Beman
2015-08-07 16:15:06 -04:00
parent dc794ea95b
commit 6da5f657fb
5 changed files with 300 additions and 50 deletions

View File

@@ -388,7 +388,42 @@ namespace filesystem
: path(name.m_pathname.c_str() + pos);
}
// m_normalize ----------------------------------------------------------------------//
// lexical operations --------------------------------------------------------------//
namespace detail
{
// C++14 provide a mismatch algorithm with four iterator arguments(), but earlier
// standard libraries didn't, so provide this needed functionality.
inline
std::pair<path::iterator, path::iterator> mismatch(path::iterator it1,
path::iterator it1end, path::iterator it2, path::iterator it2end)
{
for (; it1 != it1end && it2 != it2end && *it1 == *it2;)
{
++it1;
++it2;
}
return std::make_pair(it1, it2);
}
}
path path::relative(const path& base) const
{
std::pair<path::iterator, path::iterator> mm
= detail::mismatch(begin(), end(), base.begin(), base.end());
if (mm.first == begin() && mm.second == base.begin())
return path();
if (mm.first == end() && mm.second == base.end())
return detail::dot_path();
path tmp;
for (; mm.second != base.end(); ++mm.second)
tmp /= detail::dot_dot_path();
for (; mm.first != end(); ++mm.first)
tmp /= *mm.first;
return tmp;
}
// m_normalize ---------------------------------------------------------------------//
path& path::m_normalize()
{
@@ -807,50 +842,6 @@ namespace filesystem
it.m_element.m_pathname = separator_string; // generic format; see docs
}
//--------------------------------------------------------------------------------------//
// //
// class path non-member functions implementation //
// //
//--------------------------------------------------------------------------------------//
namespace detail
{
// C++14 provide a mismatch algorithm with four iterator arguments(), but earlier
// standard libraries didn't, so provide the needed functionality here in detail.
inline
std::pair<path::iterator, path::iterator> mismatch(path::iterator it1,
path::iterator it1end, path::iterator it2, path::iterator it2end)
{
for (; it1 != it1end && it2 != it2end && *it1 == *it2;)
{
++it1;
++it2;
}
return std::make_pair(it1, it2);
}
}
BOOST_FILESYSTEM_DECL
path lexically_relative(const path& p, const path& base)
{
std::pair<path::iterator, path::iterator> mm
= detail::mismatch(p.begin(), p.end(), base.begin(), base.end());
if (mm.first == p.end()
|| mm.second != base.end())
{
throw filesystem_error(
"lexically_relative: p does not begin with base, so can not be made relative to base",
p, base, boost::system::error_code(boost::system::errc::invalid_argument,
boost::system::generic_category()));
}
path tmp(*mm.first++);
for (; mm.first != p.end(); ++mm.first)
{
tmp /= *mm.first;
}
return tmp;
}
} // namespace filesystem
} // namespace boost