diff options
Diffstat (limited to 'libstdc++-v3/src/filesystem/path.cc')
-rw-r--r-- | libstdc++-v3/src/filesystem/path.cc | 51 |
1 files changed, 49 insertions, 2 deletions
diff --git a/libstdc++-v3/src/filesystem/path.cc b/libstdc++-v3/src/filesystem/path.cc index 899d94e0067..e4d339a1208 100644 --- a/libstdc++-v3/src/filesystem/path.cc +++ b/libstdc++-v3/src/filesystem/path.cc @@ -334,6 +334,28 @@ path::_M_split_cmpts() if (_M_pathname.empty()) return; + { + // Approximate count of components, to reserve space in _M_cmpts vector: + int count = 1; + bool saw_sep_last = _S_is_dir_sep(_M_pathname[0]); + bool saw_non_sep = !saw_sep_last; + for (value_type c : _M_pathname) + { + if (_S_is_dir_sep(c)) + saw_sep_last = true; + else if (saw_sep_last) + { + ++count; + saw_sep_last = false; + saw_non_sep = true; + } + } + if (saw_non_sep && saw_sep_last) + ++count; // empty filename after trailing slash + if (count > 1) + _M_cmpts.reserve(count); + } + size_t pos = 0; const size_t len = _M_pathname.size(); @@ -356,9 +378,13 @@ path::_M_split_cmpts() pos = 3; while (pos < len && !_S_is_dir_sep(_M_pathname[pos])) ++pos; + if (pos == len) + { + _M_type = _Type::_Root_name; + return; + } _M_add_root_name(pos); - if (pos < len) // also got root directory - _M_add_root_dir(pos); + _M_add_root_dir(pos); } else { @@ -367,6 +393,11 @@ path::_M_split_cmpts() _M_add_root_dir(0); } } + else if (len == 1) // got root directory only + { + _M_type = _Type::_Root_dir; + return; + } else // got root directory _M_add_root_dir(0); ++pos; @@ -375,12 +406,28 @@ path::_M_split_cmpts() else if (len > 1 && _M_pathname[1] == L':') { // got disk designator + if (len == 2) + { + _M_type = _Type::_Root_name; + return; + } _M_add_root_name(2); if (len > 2 && _S_is_dir_sep(_M_pathname[2])) _M_add_root_dir(2); pos = 2; } #endif + else + { + size_t n = 1; + for (; n < _M_pathname.size() && !_S_is_dir_sep(_M_pathname[n]); ++n) + { } + if (n == _M_pathname.size()) + { + _M_type = _Type::_Filename; + return; + } + } size_t back = pos; while (pos < len) |