diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2018-12-18 15:52:33 +0000 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2018-12-18 15:52:33 +0000 |
commit | 36313a6bce37f7eabc64c66f216ff0b2adb12ed7 (patch) | |
tree | 6bfdee3d10c2cddd259f3e27e75aa615b7fd5170 /libstdc++-v3/testsuite/27_io/filesystem/path | |
parent | 49cefcf3f084dabc327914269e5787bac8b20f46 (diff) |
LWG 2936: update path::compare logic and optimize string comparisons
The resolution for LWG 2936 defines the comparison more precisely, which
this patch implements. The patch also defines comparisons with strings
to work without constructing a temporary path object (so avoids any
memory allocations).
* include/bits/fs_path.h (path::compare(const string_type&))
(path::compare(const value_type*)): Add noexcept and construct a
string view to compare to instead of a path.
(path::compare(basic_string_view<value_type>)): Add noexcept. Remove
inline definition.
* src/filesystem/std-path.cc (path::_Parser): Track last type read
from input.
(path::_Parser::next()): Return a final empty component when the
input ends in a non-root directory separator.
(path::_M_append(basic_string_view<value_type>)): Remove special cases
for trailing non-root directory separator.
(path::_M_concat(basic_string_view<value_type>)): Likewise.
(path::compare(const path&)): Implement LWG 2936.
(path::compare(basic_string_view<value_type>)): Define in terms of
components returned by parser, consistent with LWG 2936.
* testsuite/27_io/filesystem/path/compare/lwg2936.cc: New.
* testsuite/27_io/filesystem/path/compare/path.cc: Test more cases.
* testsuite/27_io/filesystem/path/compare/strings.cc: Likewise.
From-SVN: r267235
Diffstat (limited to 'libstdc++-v3/testsuite/27_io/filesystem/path')
3 files changed, 102 insertions, 0 deletions
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/compare/lwg2936.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/compare/lwg2936.cc new file mode 100644 index 00000000000..8a11043f143 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/filesystem/path/compare/lwg2936.cc @@ -0,0 +1,80 @@ +// { dg-options "-std=gnu++17 -lstdc++fs" } +// { dg-do run { target c++17 } } +// { dg-require-filesystem-ts "" } + +// Copyright (C) 2014-2018 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// 8.4.8 path compare [path.compare] + +#include <filesystem> +#include <testsuite_hooks.h> +#include <testsuite_fs.h> + +using std::filesystem::path; + +int norm(int i) +{ + if (i < 0) + return -1; + else if (i > 0) + return +1; + else + return 0; +} + +void +check(const path& lhs, const path& rhs, int sense) +{ + VERIFY( lhs.compare(lhs) == 0 ); + VERIFY( rhs.compare(rhs) == 0 ); + + VERIFY( norm(lhs.compare(rhs)) == sense ); + VERIFY( norm(lhs.compare(rhs.c_str())) == sense ); + + VERIFY( norm(rhs.compare(lhs)) == -sense ); + VERIFY( norm(rhs.compare(lhs.c_str())) == -sense ); +} + +void +test01() +{ + check("", "", 0); + + // These are root names on Windows (just relative paths elsewhere) + check("", "c:", -1); + check("c:", "d:", -1); + check("c:", "c:/", -1); + check("d:", "c:/", +1); + check("c:/a/b", "c:a/b", -1); + + // These are root names on Cygwin (just relative paths elsewhere) + check("", "//c", -1); + check("//c", "//d", -1); + check("//c", "//c/", -1); + check("//d", "//c/", +1); + + check("/a", "/b", -1); + check("a", "/b", -1); + check("/b", "b", +1); +} + +int +main() +{ + test01(); +} diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/compare/path.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/compare/path.cc index 4aa2cd387c5..159a96c6597 100644 --- a/libstdc++-v3/testsuite/27_io/filesystem/path/compare/path.cc +++ b/libstdc++-v3/testsuite/27_io/filesystem/path/compare/path.cc @@ -44,8 +44,19 @@ test01() } } +void +test02() +{ + VERIFY( path("/").compare(path("////")) == 0 ); + VERIFY( path("/a").compare(path("/")) > 0 ); + VERIFY( path("/").compare(path("/a")) < 0 ); + VERIFY( path("/ab").compare(path("/a")) > 0 ); + VERIFY( path("/ab").compare(path("/a/b")) > 0 ); +} + int main() { test01(); + test02(); } diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/compare/strings.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/compare/strings.cc index cfd73ad9e4a..a3fcb800dbf 100644 --- a/libstdc++-v3/testsuite/27_io/filesystem/path/compare/strings.cc +++ b/libstdc++-v3/testsuite/27_io/filesystem/path/compare/strings.cc @@ -42,8 +42,19 @@ test01() } } +void +test02() +{ + VERIFY( path("/").compare("////") == 0 ); + VERIFY( path("/a").compare("/") > 0 ); + VERIFY( path("/").compare("/a") < 0 ); + VERIFY( path("/ab").compare("/a") > 0 ); + VERIFY( path("/ab").compare("/a/b") > 0 ); +} + int main() { test01(); + test02(); } |