void path::m_path_iterator_decrement(path::iterator & it) { BOOST_ASSERT(it.m_pos && "path::iterator decrement past begin()"); size_type end_pos(it.m_pos); // if at end and there was a trailing non-root '/', return "." if (it.m_pos == it.m_path_ptr->m_pathname.size() && it.m_path_ptr->m_pathname.size() > 1 && is_separator(it.m_path_ptr->m_pathname[it.m_pos-1]) && is_non_root_separator(it.m_path_ptr->m_pathname, it.m_pos-1) ) { --it.m_pos; it.m_element = dot_path; return; } size_type root_dir_pos(root_directory_start(it.m_path_ptr->m_pathname, end_pos)); // skip separators unless root directory for ( ; end_pos > 0 && (end_pos-1) != root_dir_pos && is_separator(it.m_path_ptr->m_pathname[end_pos-1]) ; --end_pos) {} it.m_pos = filename_pos(it.m_path_ptr->m_pathname, end_pos); it.m_element = it.m_path_ptr->m_pathname.substr(it.m_pos, end_pos - it.m_pos); if (it.m_element.m_pathname == preferred_separator_string) it.m_element.m_pathname = separator_string; // needed for Windows, harmless on POSIX }
void path::m_path_iterator_increment(path::iterator & it) { BOOST_ASSERT(it.m_pos < it.m_path_ptr->m_pathname.size() && "path::basic_iterator increment past end()"); // increment to position past current element it.m_pos += it.m_element.m_pathname.size(); // if end reached, create end basic_iterator if (it.m_pos == it.m_path_ptr->m_pathname.size()) { it.m_element.clear(); return; } // both POSIX and Windows treat paths that begin with exactly two separators specially bool was_net(it.m_element.m_pathname.size() > 2 && is_separator(it.m_element.m_pathname[0]) && is_separator(it.m_element.m_pathname[1]) && !is_separator(it.m_element.m_pathname[2])); // process separator (Windows drive spec is only case not a separator) if (is_separator(it.m_path_ptr->m_pathname[it.m_pos])) { // detect root directory if (was_net # ifdef BOOST_WINDOWS_API // case "c:/" || it.m_element.m_pathname[it.m_element.m_pathname.size()-1] == colon # endif ) { it.m_element.m_pathname = separator; return; } // bypass separators while (it.m_pos != it.m_path_ptr->m_pathname.size() && is_separator(it.m_path_ptr->m_pathname[it.m_pos])) { ++it.m_pos; } // detect trailing separator, and treat it as ".", per POSIX spec if (it.m_pos == it.m_path_ptr->m_pathname.size() && is_non_root_separator(it.m_path_ptr->m_pathname, it.m_pos-1)) { --it.m_pos; it.m_element = dot_path; return; } } // get next element size_type end_pos(it.m_path_ptr->m_pathname.find_first_of(separators, it.m_pos)); if (end_pos == string_type::npos) end_pos = it.m_path_ptr->m_pathname.size(); it.m_element = it.m_path_ptr->m_pathname.substr(it.m_pos, end_pos - it.m_pos); }
path path::filename() const { size_type pos(filename_pos(m_pathname, m_pathname.size())); return (m_pathname.size() && pos && is_separator(m_pathname[pos]) && is_non_root_separator(m_pathname, pos)) ? dot_path : path(m_pathname.c_str() + pos); }