EqualityComparable
for std::forward_list
Section: 23.2 [container.requirements] Status: C++11 Submitter: Daniel Krügler Opened: 2008-06-24 Last modified: 2016-01-28
Priority: Not Prioritized
View all other issues in [container.requirements].
View all issues with C++11 status.
Discussion:
Table 89, Container requirements, defines operator==
in terms of the container
member function size()
and the algorithm std::equal
:
==
is an equivalence relation.a.size() == b.size() && equal(a.begin(), a.end(), b.begin()
The new container forward_list
does not provide a size
member function
by design but does provide operator==
and operator!=
without specifying it's semantic.
Other parts of the (sequence) container requirements do also depend on
size()
, e.g. empty()
or clear()
, but this issue explicitly attempts to solve the missing
EqualityComparable
specification,
because of the special design choices of forward_list
.
I propose to apply one of the following resolutions, which are described as:
O(N)
calls of std::distance()
with the corresponding container ranges and instead uses a special
equals
implementation which takes two container ranges instead of 1 1/2.
size()
is replaced
by distance
with corresponding performance disadvantages.
Both proposal choices are discussed, the preferred choice of the author is to apply (A).
[ San Francisco: ]
There's an Option C: change the requirements table to use distance().
LWG found Option C acceptable.
Martin will draft the wording for Option C.
[ post San Francisco: ]
Martin provided wording for Option C.
[ 2009-07 Frankfurt ]
Other operational semantics (see, for example, Tables 82 and 83) are written in terms of a container's size() member. Daniel to update proposed resolution C.
[ Howard: Commented out options A and B. ]
[ 2009-07-26 Daniel updated proposed resolution C. ]
[ 2009-10 Santa Cruz: ]
Mark NAD Editorial. Addressed by N2986.
[ 2009-10 Santa Cruz: ]
Reopened. N2986 was rejected in full committee on procedural grounds.
[ 2010-01-30 Howard updated Table numbers. ]
[ 2010 Pittsburgh: ]
Moved to Ready for Pittsburgh.
Proposed resolution:
Option (C):
In 23.2.2 [container.requirements.general] change Table 90 -- Container requirements as indicated:
Change the text in the Assertion/note column in the row for "
X u
;" as follows:post:
u.
size() == 0empty() == trueChange the text in the Assertion/note column in the row for "
X();
" as follows:
X().
size() == 0empty() == trueChange the text in the Operational Semantics column in the row for "
a == b
" as follows:
==
is an equivalence relation.
a.size()distance(a.begin(), a.end()) ==b.size()distance(b.begin(), b.end()) && equal(a.begin(), a.end(), b.begin())Add text in the Ass./Note/pre-/post-condition column in the row for "
a == b
" as follows:Requires:
T
isEqualityComparable
Change the text in the Operational Semantics column in the row for "
a.size()
" as follows:
a.end() - a.begin()distance(a.begin(), a.end())Change the text in the Operational Semantics column in the row for "
a.max_size()
" as follows:
of the largest possible container
size()distance(begin(), end())Change the text in the Operational Semantics column in the row for "
a.empty()
" as follows:
a.size() == 0a.begin() == a.end()In 23.2.2 [container.requirements.general] change Table 93 — Allocator-aware container requirements as indicated:
Change the text in the Assertion/note column in the row for "
X() / X u;
" as follows:Requires:
A
isDefaultConstructible
post:,
u.size() == 0u.empty() == trueget_allocator() == A()
Change the text in the Assertion/note column in the row for "
X(m) / X u(m);
" as follows:post:
u.size() == 0u.empty() == true, get_allocator() == mIn 23.2.4 [sequence.reqmts] change Table 94 — Sequence container requirements as indicated:
Change the text in the Assertion/note column in the row for "
X(n, t) / X a(n, t)
" as follows:post:
size()distance(begin(), end()) == n [..]Change the text in the Assertion/note column in the row for "
X(i, j) / X a(i, j)
" as follows:[..] post:
size() ==
distance betweeni
andj
distance(begin(), end()) == distance(i, j)
[..]Change the text in the Assertion/note column in the row for "
a.clear()
" as follows:
a.erase(a.begin(), a.end())
post:
size() == 0a.empty() == trueIn 23.2.7 [associative.reqmts] change Table 96 — Associative container requirements as indicated:
[ Not every occurrence of
size()
was replaced, because all current associative containers have asize
. The following changes ensure consistency regarding the semantics of "erase
" for all tables and adds some missing objects ]
Change the text in the Complexity column in the row for
X(i,j,c)/Xa(i,j,c);
as follows:
N
logN
in general (N
== distance(i, j)
is the distance from); ...i
toj
Change the text in the Complexity column in the row for "
a.insert(i, j)
" as follows:
N log(a.size() + N)
(whereN
is the distance fromi
toj
)N == distance(i, j)
Change the text in the Complexity column in the row for "
a.erase(k)
" as follows:
log(a.size()) + a.count(k)
Change the text in the Complexity column in the row for "
a.erase(q1, q2)
" as follows:
log(a.size()) + N
whereN
is the distance fromq1
toq2
== distance(q1, q2)
.Change the text in the Assertion/note column in the row for "
a.clear()
" as follows:
a.erase(a.begin(),a.end())
post:
size() == 0a.empty() == trueChange the text in the Complexity column in the row for "
a.clear()
" as follows:linear in
a.size()
Change the text in the Complexity column in the row for "
a.count(k)
" as follows:
log(a.size()) + a.count(k)
In 23.2.8 [unord.req] change Table 98 — Unordered associative container requirements as indicated:
[ The same rational as for Table 96 applies here ]
Change the text in the Assertion/note column in the row for "
a.clear()
" as follows:[..] Post:
a.
size() == 0empty() == true