10 #include <boost/algorithm/string.hpp>
11 #include <boost/functional/hash.hpp>
23 auto join(path::iterator _first, path::iterator _last) -> path
27 for (; _first != _last; ++_first) {
42 if (!value_.empty() && preferred_separator != value_.back()) {
43 value_ += preferred_separator;
47 if (_p.is_absolute()) {
51 append_separator_if_needed(_p);
60 if (has_object_name()) {
61 const auto pos = value_.find_last_of(preferred_separator);
63 if (string_type::npos != pos) {
64 value_.erase(pos + 1);
74 return *
this /= _replacement;
79 if (has_extension()) {
80 const auto pos = value_.find_last_of(dot);
82 if (string_type::npos != pos) {
89 if (!_replacement.empty() && dot != _replacement.value_[0]) {
93 return *
this += _replacement;
106 for (
const auto& next_element : *
this)
108 if (next_element ==
dot) {
111 else if (next_element ==
dot_dot) {
112 if (
p.has_object_name() &&
p.object_name() !=
dot_dot) {
113 p.remove_object_name();
115 else if (root_separator !=
p) {
128 auto it = std::rbegin(
p);
140 auto base_b = _base.
begin();
141 auto base_e = _base.end();
142 auto mm = std::mismatch(
begin(),
end(), base_b, base_e);
144 if (mm.first ==
end() && mm.second == base_e) {
150 for (; mm.second != base_e; ++mm.second) {
154 for (; mm.first !=
end(); ++mm.first) {
163 auto p = lexically_relative(_base);
164 return !
p.empty() ?
p : *
this;
169 auto first1 =
begin();
170 const auto last1 =
end();
172 auto first2 = _p.begin();
173 const auto last2 = _p.end();
175 for (; first1 != last1 && first2 != last2; ++first1, ++first2) {
176 if (first1->value_ < first2->value_) {
180 if (first1->value_ > first2->value_) {
189 if (first1 == last1) {
190 if (first2 == last2) {
233 auto pos = n.value_.find_last_of(
dot);
235 if (string_type::npos != pos)
237 return n.value_.substr(0, pos);
252 auto pos = n.value_.find_last_of(
dot);
254 if (string_type::npos != pos)
256 return n.value_.substr(pos);
287 if (value_.empty() ||
288 preferred_separator == value_.back() ||
289 preferred_separator == _p.value_.front())
294 value_ += preferred_separator;
306 if (path_ptr_->empty())
312 if (path_ptr_->is_absolute())
318 const auto& full_path = path_ptr_->value_;
321 element_.value_ = (path::string_type::npos !=
end)
322 ? full_path.substr(0,
end)
329 const auto& fp = path_ptr_->value_;
330 auto&
e = element_.value_;
335 if (fp.size() - 1 == pos_ &&
e.empty()) {
344 if (fp.size() == pos_)
361 pos_ = fp.size() - 1;
368 if (path::string_type::npos !=
end)
371 e = fp.substr(pos_,
end - pos_);
376 e = fp.substr(pos_, fp.size() - pos_);
385 const auto& fp = path_ptr_->value_;
386 auto&
e = element_.value_;
391 if (fp.size() == pos_ &&
418 const auto end = pos_;
426 e = fp.substr(pos_,
end - pos_);
434 for (; (_first1 != _last1) && (_first2 != _last2); ++_first1, ++_first2) {
435 if (_first1->string() < _first2->string()) {
439 if (_first2->string() < _first1->string()) {
444 return (_first1 == _last1) && (_first2 != _last2);
449 return _os << std::quoted(_p.string());
455 _is >> std::quoted(t);
462 const auto pstr = _p.string();