aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/src/filesystem/path.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libstdc++-v3/src/filesystem/path.cc')
-rw-r--r--libstdc++-v3/src/filesystem/path.cc51
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)