From 6dbaaa99a880f356277525c8630491b80d6d2e56 Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Mon, 10 Mar 2014 21:36:36 +0000 Subject: [PATCH] Add tests for LWG issue #2356. Stability of erasure in unordered associative containers. Libc++ already does this, but now we have tests for it. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@203494 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../unorder.map.modifiers/erase_key.pass.cpp | 36 ++++++++++++++++++ .../erase_key.pass.cpp | 37 +++++++++++++++++++ .../unord/unord.multiset/erase_key.pass.cpp | 35 ++++++++++++++++++ .../unord/unord.set/erase_key.pass.cpp | 35 ++++++++++++++++++ www/cxx1y_status.html | 2 +- 5 files changed, 144 insertions(+), 1 deletion(-) diff --git a/test/containers/unord/unord.map/unorder.map.modifiers/erase_key.pass.cpp b/test/containers/unord/unord.map/unorder.map.modifiers/erase_key.pass.cpp index e6741a80..0e8ef8b8 100644 --- a/test/containers/unord/unord.map/unorder.map.modifiers/erase_key.pass.cpp +++ b/test/containers/unord/unord.map/unorder.map.modifiers/erase_key.pass.cpp @@ -21,6 +21,23 @@ #include "min_allocator.h" +#if __cplusplus >= 201103L +template +bool only_deletions ( const Unordered &whole, const Unordered &part ) { + typename Unordered::const_iterator w = whole.begin(); + typename Unordered::const_iterator p = part.begin(); + + while ( w != whole.end () && p != part.end()) { + if ( *w == *p ) + p++; + w++; + } + + return p == part.end(); +} +#endif + + int main() { { @@ -137,5 +154,24 @@ int main() assert(c.erase(3) == 0); assert(c.size() == 0); } + { + typedef std::unordered_map C; + C m, m2; + for ( int i = 0; i < 10; ++i ) { + m[i] = i; + m2[i] = i; + } + + C::iterator i = m2.begin(); + int ctr = 0; + while (i != m2.end()) { + if (ctr++ % 2 == 0) + m2.erase(i++); + else + ++i; + } + + assert (only_deletions (m, m2)); + } #endif } diff --git a/test/containers/unord/unord.multimap/unord.multimap.modifiers/erase_key.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.modifiers/erase_key.pass.cpp index 3c099f32..892f8a24 100644 --- a/test/containers/unord/unord.multimap/unord.multimap.modifiers/erase_key.pass.cpp +++ b/test/containers/unord/unord.multimap/unord.multimap.modifiers/erase_key.pass.cpp @@ -21,6 +21,22 @@ #include "min_allocator.h" +#if __cplusplus >= 201103L +template +bool only_deletions ( const Unordered &whole, const Unordered &part ) { + typename Unordered::const_iterator w = whole.begin(); + typename Unordered::const_iterator p = part.begin(); + + while ( w != whole.end () && p != part.end()) { + if ( *w == *p ) + p++; + w++; + } + + return p == part.end(); +} +#endif + int main() { { @@ -347,5 +363,26 @@ int main() assert(std::distance(c.begin(), c.end()) == c.size()); assert(std::distance(c.cbegin(), c.cend()) == c.size()); } + { + typedef std::unordered_multimap C; + C m, m2; + for ( int i = 0; i < 10; ++i ) { + for (int j = 0; j < 2; ++j ) { + m.insert (std::make_pair(i,j)); + m2.insert(std::make_pair(i,j)); + } + } + + C::iterator i = m2.begin(); + int ctr = 0; + while (i != m2.end()) { + if (ctr++ % 2 == 0) + m2.erase(i++); + else + ++i; + } + + assert (only_deletions (m, m2)); + } #endif } diff --git a/test/containers/unord/unord.multiset/erase_key.pass.cpp b/test/containers/unord/unord.multiset/erase_key.pass.cpp index 646d3562..7c243973 100644 --- a/test/containers/unord/unord.multiset/erase_key.pass.cpp +++ b/test/containers/unord/unord.multiset/erase_key.pass.cpp @@ -21,6 +21,22 @@ #include "min_allocator.h" +#if __cplusplus >= 201103L +template +bool only_deletions ( const Unordered &whole, const Unordered &part ) { + typename Unordered::const_iterator w = whole.begin(); + typename Unordered::const_iterator p = part.begin(); + + while ( w != whole.end () && p != part.end()) { + if ( *w == *p ) + p++; + w++; + } + + return p == part.end(); +} +#endif + int main() { { @@ -137,5 +153,24 @@ int main() assert(c.erase(3) == 0); assert(c.size() == 0); } + { + typedef std::unordered_multiset C; + C m, m2; + for ( int i = 0; i < 10; ++i ) { + m.insert(i); m.insert(i); + m2.insert(i); m2.insert(i); + } + + C::iterator i = m2.begin(); + int ctr = 0; + while (i != m2.end()) { + if (ctr++ % 2 == 0) + m2.erase(i++); + else + ++i; + } + + assert (only_deletions (m, m2)); + } #endif } diff --git a/test/containers/unord/unord.set/erase_key.pass.cpp b/test/containers/unord/unord.set/erase_key.pass.cpp index d97374a4..ca165083 100644 --- a/test/containers/unord/unord.set/erase_key.pass.cpp +++ b/test/containers/unord/unord.set/erase_key.pass.cpp @@ -21,6 +21,22 @@ #include "min_allocator.h" +#if __cplusplus >= 201103L +template +bool only_deletions ( const Unordered &whole, const Unordered &part ) { + typename Unordered::const_iterator w = whole.begin(); + typename Unordered::const_iterator p = part.begin(); + + while ( w != whole.end () && p != part.end()) { + if ( *w == *p ) + p++; + w++; + } + + return p == part.end(); +} +#endif + int main() { { @@ -136,5 +152,24 @@ int main() assert(c.erase(3) == 0); assert(c.size() == 0); } + { + typedef std::unordered_set C; + C m, m2; + for ( int i = 0; i < 10; ++i ) { + m.insert(i); + m2.insert(i); + } + + C::iterator i = m2.begin(); + int ctr = 0; + while (i != m2.end()) { + if (ctr++ % 2 == 0) + m2.erase(i++); + else + ++i; + } + + assert (only_deletions (m, m2)); + } #endif } diff --git a/www/cxx1y_status.html b/www/cxx1y_status.html index 118963a6..287c754e 100644 --- a/www/cxx1y_status.html +++ b/www/cxx1y_status.html @@ -262,7 +262,7 @@ 2344quoted()'s interaction with padding is unclearIssaquahComplete 2346integral_constant's member functions should be marked noexceptIssaquahComplete 2350min, max, and minmax should be constexprIssaquahComplete - 2356Stability of erasure in unordered associative containersIssaquah + 2356Stability of erasure in unordered associative containersIssaquahComplete 2357Remaining "Assignable" requirementIssaquahComplete 2359How does regex_constants::nosubs affect basic_regex::mark_count()?IssaquahComplete 2360reverse_iterator::operator*() is unimplementableIssaquah