Title
Path comparison is defined in terms of the generic format
Status
c++20
Section
[fs.path.compare]
Submitter
Billy Robert O'Neal III

Created on 2017-02-21.00:00:00 last changed 45 months ago

Messages

Date: 2018-11-12.04:39:29

Proposed resolution:

This wording is relative to N4750.

  1. Make the following edits to [fs.path.compare]:

    int compare(const path& p) const noexcept;
    

    -1- Returns:

    — Let rootNameComparison be the result of this->root_name().native().compare(p.root_name().native()). If rootNameComparison is not 0, rootNameComparison; otherwise,

    — If !this->has_root_directory() and p.has_root_directory(), a value less than 0; otherwise,

    — If this->has_root_directory() and !p.has_root_directory(), a value greater than 0; otherwise,

    a value less than 0, iIf native() for the elements of *this->relative_path() are lexicographically less than native() for the elements of p.relative_path(), a value less than 0; otherwise,

    a value greater than 0, iIf native() for the elements of *this->relative_path() are lexicographically greater than native() for the elements of p.relative_path(), a value greater than 0; otherwise,

    0.

    -2- Remarks: The elements are determined as if by iteration over the half-open range [begin(), end()) for *this and p.

    int compare(const string_type& s) const
    int compare(basic_string_view<value_type> s) const;
    

    -3- Returns: compare(path(s))

    [Editor's note: Delete paragraph 3 entirely and merge the value_type overload with those above.]

    int compare(const value_type* s) const
    

    -4- ReturnsEffects: Equivalent to: return compare(path(s));.

Date: 2018-11-12.04:39:29

[ 2018-11, Adopted in San Diego ]

Date: 2018-06-07.11:21:36

[ 2018-06, Rapperswil Wednesday evening ]

Agreement to move that to Ready, Daniel rebased to N4750.

Date: 2018-02-13.00:00:00

[ 2018-02-13 Billy improves wording ]

The revised wording has the effect to invert the ordering of the added new bullets (2) and (3), the effect of this change is that

path("c:/").compare("c:")

compares greater, not less.

Date: 2018-01-26.00:00:00

[ 2018-01-26 issues processing telecon ]

Status set to 'Review'. We like the wording, but would like to see some implementation experience.

Previous resolution [SUPERSEDED]:

This wording is relative to N4659.

  1. Make the following edits to [fs.path.compare]:

    int compare(const path& p) const noexcept;
    

    -1- Returns:

    — Let rootNameComparison be the result of this->root_name().native().compare(p.root_name().native()). If rootNameComparison is not 0, rootNameComparison; otherwise,

    — If this->has_root_directory() and !p.has_root_directory(), a value less than 0; otherwise,

    — If !this->has_root_directory() and p.has_root_directory(), a value greater than 0; otherwise,

    a value less than 0, iIf native() for the elements of *this->relative_path() are lexicographically less than native() for the elements of p.relative_path(), a value less than 0; otherwise,

    a value greater than 0, iIf native() for the elements of *this->relative_path() are lexicographically greater than native() for the elements of p.relative_path(), a value greater than 0; otherwise,

    0.

    -2- Remarks: The elements are determined as if by iteration over the half-open range [begin(), end()) for *this and p.

    int compare(const string_type& s) const
    int compare(basic_string_view<value_type> s) const;
    

    -3- Returns: compare(path(s))

    [Editor's note: Delete paragraph 3 entirely and merge the value_type overload with those above.]

    int compare(const value_type* s) const
    

    -4- ReturnsEffects: Equivalent to return compare(path(s));.

Date: 2017-07-17.18:06:52

[ 2016-07, Toronto Saturday afternoon issues processing ]

Billy to reword after Davis researches history about ordering. Status to Open.

Previous resolution [SUPERSEDED]:

This wording is relative to N4640.

  1. Make the following edits to [fs.path.compare]:

    int compare(const path& p) const noexcept;
    

    -1- Returns:

    — Let rootNameComparison be the result of this->root_name().native().compare(p.root_name().native()). If rootNameComparison is not 0, rootNameComparison; otherwise,

    — If this->has_root_directory() and !p.has_root_directory(), a value less than 0; otherwise,

    — If !this->has_root_directory() and p.has_root_directory(), a value greater than 0; otherwise,

    — A value greater than, less than, or equal to 0, ordering the paths in a depth-first traversal order.

    -?- [Note: For POSIX and Windows platforms, this is accomplished by lexicographically ordering the half-open ranges [begin(), end()) of this->relative_path() and p.relative_path() as follows:

    — A value less than 0, if native() for the elements of *this->relative_path() are lexicographically less than native() for the elements of p.relative_path(); otherwise,

    — a value greater than 0, if native() for the elements of *this->relative_path() are lexicographically greater than native() for the elements of p.relative_path(); otherwise,

    0.

    end note]

    -2- Remarks: The elements are determined as if by iteration over the half-open range [begin(), end()) for *this and p.

    int compare(const string_type& s) const
    int compare(basic_string_view<value_type> s) const;
    

    -3- Returns: compare(path(s))

    [Editor's note: Delete paragraph 3 entirely and merge the value_type overload with those above.]

    int compare(const value_type* s) const
    

    -4- ReturnsEffects: Equivalent to return compare(path(s));.

Date: 2017-07-15.23:15:19

[ 2017-07 Toronto Thurs Issue Prioritization ]

Priority 2

Date: 2017-03-15.00:00:00

[ 2017-03-04, Kona Saturday morning ]

We decided that this had seen so much churn that we would postpone looking at this until Toronto

Date: 2017-02-21.00:00:00

Currently, path comparison is defined elementwise, which implies a conversion from the native format (implied by native() returning const string&). However, the conversion from the native format to the generic format might not be information preserving. This would allow two paths a and b to say a.compare(b) == 0, but a.native().compare(b.native()) != 0 as a result of this missing information, which is undesirable. We only want that condition to happen if there are redundant directory separators. We also don't want to change the path comparison to be in terms of the native format, due to Peter Dimov's example where we want path("a/b") to sort earlier than path("a.b"), and we want path("a/b") == path("a//////b").

Citing a Windows example, conversion to the generic format is going to have to drop alternate data streams. This might give path("a/b:ads") == path("a/b"). I think I should consider the alternate data streams as part of the path element though, so this case might be fine, so long as I make path("b:ads").native() be "b:ads". This might not work for our z/OS friends though, or for folks where the native format looks nothing like the generic format.

Additionally, this treats root-directory specially. For example, the current spec wants path("c:/a/b") == path("c:/a////b"), but path("c:/a/b") != path("c:///a/b"), because native() for the root-directory path element will literally be the slashes or preferred separators.

This addresses similar issues to those raised in US 57 — it won't make absolute paths sort at the beginning or end but it will make paths of the same kind sort together.

History
Date User Action Args
2021-02-25 10:48:01adminsetstatus: wp -> c++20
2018-11-12 04:39:29adminsetmessages: + msg10181
2018-11-12 04:39:29adminsetstatus: voting -> wp
2018-10-08 05:13:59adminsetstatus: ready -> voting
2018-06-07 11:21:36adminsetmessages: + msg9871
2018-06-07 11:21:36adminsetstatus: review -> ready
2018-02-13 19:33:08adminsetmessages: + msg9679
2018-01-28 19:43:07adminsetmessages: + msg9653
2018-01-28 19:43:07adminsetstatus: open -> review
2017-07-16 20:43:29adminsetmessages: + msg9424
2017-07-16 20:43:29adminsetstatus: new -> open
2017-07-15 23:15:19adminsetmessages: + msg9400
2017-06-02 05:40:10adminsetmessages: + msg9195
2017-02-22 18:35:24adminsetmessages: + msg8977
2017-02-21 00:00:00admincreate