27 const char separator =
'/';
28 const char*
const separators =
"/";
29 const char colon =
':';
32 inline bool is_separator(
char c) {
return c == separator; }
34 bool is_root_separator(
const std::string& str,
size_t pos)
37 if ( str.empty() || is_separator(str[pos]) ) {
38 throw std::runtime_error(
"precondition violation");
41 while (pos > 0 && is_separator(str[pos-1]))
48 if (pos < 3 || !is_separator(str[0]) || !is_separator(str[1]))
51 return str.find_first_of(separators, 2) == pos;
54 size_t filename_pos(
const std::string& str,
size_t end_pos)
59 && is_separator(str[0])
60 && is_separator(str[1]))
return 0;
63 if (end_pos && is_separator(str[end_pos-1]))
67 size_t pos(str.find_last_of(separators, end_pos-1));
69 return (pos == std::string::npos
70 || (pos == 1 && is_separator(str[0])))
76 size_t root_directory_start(
const std::string& path,
size_t size) {
79 && is_separator(path[0])
80 && is_separator(path[1]))
return std::string::npos;
83 && is_separator(path[0])
84 && is_separator(path[1])
85 && !is_separator(path[2]))
87 std::string::size_type pos(path.find_first_of(separators, 2));
88 return pos < size ? pos : std::string::npos;
92 if (size > 0 && is_separator(path[0]))
return 0;
93 return std::string::npos;
109 insert(end(),separator);
110 insert(end(),c.begin(),c.end());
118 std::vector<std::string> pathes;
121 tmp[
sizeof(tmp)-1] = 0;
122 char *token, *save=0;
123 token = ::strtok_r(tmp,separators,&save);
125 pathes.emplace_back(token);
126 token = ::strtok_r(0,separators,&save);
129 std::vector<std::string>::const_iterator start(pathes.begin());
130 std::vector<std::string>::const_iterator last(pathes.end());
131 std::vector<std::string>::const_iterator stop(last--);
132 for (std::vector<std::string>::const_iterator itr(start); itr != stop; ++itr) {
135 if (itr_path.
native().size() == 1
136 && (itr_path.
native())[0] == dot
138 && itr != last)
continue;
141 if ( temp.empty() && itr_path.find(colon) != std::string::npos ) {
142 temp = std::move(itr_path);
145 else if (!temp.empty()
146 && itr_path.
native().size() == 2
147 && (itr_path.
native())[0] == dot
148 && (itr_path.
native())[1] == dot)
152 && (lf.size() != 1 || (lf[0] != dot && lf[0] != separator))
153 && (lf.size() != 2 || (lf[0] != dot && lf[1] != dot)) )
170 std::vector<std::string>::const_iterator next(itr);
171 if (temp.empty() && ++next != stop && next == last && *last ==
detail::dot_path()) {
186 size_t end_pos(filename_pos(
native(),this->size()));
187 bool filename_was_separator(this->size() && is_separator(at(end_pos)));
190 size_t root_dir_pos(root_directory_start(
native(), end_pos));
192 && (end_pos-1) != root_dir_pos
193 && is_separator(this->at(end_pos-1))
197 return (end_pos == 1 && root_dir_pos == 0 && filename_was_separator) ? std::string::npos : end_pos;
216 && is_separator(at(pos))
217 && !is_root_separator(
native(), pos))
226 && is_separator(at(pos))
227 && !is_root_separator(
native(), pos))