JTC1/SC22/WG21
N4273
Document number: N4273
Date: 2014-11-06
Project: Programming Language C++, Library Working Group
Reply-to: Stephan T. Lavavej <stl@microsoft.com>
Uniform Container Erasure (Revision 2)
I. Introduction
This is a proposal to add erase_if(container, pred) and
erase(container, value), making it easier to eliminate unwanted elements
correctly and efficiently. This updates N4161 (see [2]) by removing the
overloads of erase() for associative containers and unordered associative
containers, adding a Note about the missing overloads, and updating
[general.feature.test]. The original proposal N4009 (see [1]) explains
the rationale for this feature, which is not repeated here.
II. Standardese
1. In 1.3 [general.namespaces] Table 1 "C++ library headers", add:
<experimental/deque>
<experimental/forward_list>
<experimental/list>
<experimental/map>
<experimental/set>
<experimental/string>
<experimental/unordered_map>
<experimental/unordered_set>
<experimental/vector>
2. In 1.5 [general.feature.test] Table 2 "Significant features in this
technical specification", add:
Doc. No.: N4273
Title: Uniform Container Erasure
Primary Section: [container.erasure]
Macro Name Suffix: erase_if
Value: 201411
Header: <experimental/vector>
3. Add a new section "Uniform container erasure" [container.erasure]
containing the following new sections.
4. Add a new section "Header synopsis" [container.erasure.syn] containing:
For brevity, this section specifies the contents of 9 headers, each of which
behaves as described by [general.namespaces].
namespace std {
namespace experimental {
inline namespace fundamentals_v2 {
// [container.erasure.erase_if], function template erase_if
// [container.erasure.erase], function template erase
// <experimental/string>
template <class charT, class traits, class A, class Predicate>
void erase_if(basic_string<charT, traits, A>& c, Predicate pred);
template <class charT, class traits, class A, class U>
void erase(basic_string<charT, traits, A>& c, const U& value);
// <experimental/deque>
template <class T, class A, class Predicate>
void erase_if(deque<T, A>& c, Predicate pred);
template <class T, class A, class U>
void erase(deque<T, A>& c, const U& value);
// <experimental/vector>
template <class T, class A, class Predicate>
void erase_if(vector<T, A>& c, Predicate pred);
template <class T, class A, class U>
void erase(vector<T, A>& c, const U& value);
// <experimental/forward_list>
template <class T, class A, class Predicate>
void erase_if(forward_list<T, A>& c, Predicate pred);
template <class T, class A, class U>
void erase(forward_list<T, A>& c, const U& value);
// <experimental/list>
template <class T, class A, class Predicate>
void erase_if(list<T, A>& c, Predicate pred);
template <class T, class A, class U>
void erase(list<T, A>& c, const U& value);
// <experimental/map>
template <class K, class T, class C, class A, class Predicate>
void erase_if(map<K, T, C, A>& c, Predicate pred);
template <class K, class T, class C, class A, class Predicate>
void erase_if(multimap<K, T, C, A>& c, Predicate pred);
// <experimental/set>
template <class K, class C, class A, class Predicate>
void erase_if(set<K, C, A>& c, Predicate pred);
template <class K, class C, class A, class Predicate>
void erase_if(multiset<K, C, A>& c, Predicate pred);
// <experimental/unordered_map>
template <class K, class T, class H, class P, class A, class Predicate>
void erase_if(unordered_map<K, T, H, P, A>& c, Predicate pred);
template <class K, class T, class H, class P, class A, class Predicate>
void erase_if(unordered_multimap<K, T, H, P, A>& c, Predicate pred);
// <experimental/unordered_set>
template <class K, class H, class P, class A, class Predicate>
void erase_if(unordered_set<K, H, P, A>& c, Predicate pred);
template <class K, class H, class P, class A, class Predicate>
void erase_if(unordered_multiset<K, H, P, A>& c, Predicate pred);
} // inline namespace fundamentals_v2
} // namespace experimental
} // namespace std
5. Add a new section "Function template erase_if" [container.erasure.erase_if]
containing:
template <class charT, class traits, class A, class Predicate>
void erase_if(basic_string<charT, traits, A>& c, Predicate pred);
template <class T, class A, class Predicate>
void erase_if(deque<T, A>& c, Predicate pred);
template <class T, class A, class Predicate>
void erase_if(vector<T, A>& c, Predicate pred);
Effects: Equivalent to:
c.erase(remove_if(c.begin(), c.end(), pred), c.end());
template <class T, class A, class Predicate>
void erase_if(forward_list<T, A>& c, Predicate pred);
template <class T, class A, class Predicate>
void erase_if(list<T, A>& c, Predicate pred);
Effects: Equivalent to:
c.remove_if(pred);
template <class K, class T, class C, class A, class Predicate>
void erase_if(map<K, T, C, A>& c, Predicate pred);
template <class K, class T, class C, class A, class Predicate>
void erase_if(multimap<K, T, C, A>& c, Predicate pred);
template <class K, class C, class A, class Predicate>
void erase_if(set<K, C, A>& c, Predicate pred);
template <class K, class C, class A, class Predicate>
void erase_if(multiset<K, C, A>& c, Predicate pred);
template <class K, class T, class H, class P, class A, class Predicate>
void erase_if(unordered_map<K, T, H, P, A>& c, Predicate pred);
template <class K, class T, class H, class P, class A, class Predicate>
void erase_if(unordered_multimap<K, T, H, P, A>& c, Predicate pred);
template <class K, class H, class P, class A, class Predicate>
void erase_if(unordered_set<K, H, P, A>& c, Predicate pred);
template <class K, class H, class P, class A, class Predicate>
void erase_if(unordered_multiset<K, H, P, A>& c, Predicate pred);
Effects: Equivalent to:
for (auto i = c.begin(), last = c.end(); i != last; ) {
if (pred(*i)) {
i = c.erase(i);
} else {
++i;
}
}
6. Add a new section "Function template erase" [container.erasure.erase]
containing:
template <class charT, class traits, class A, class U>
void erase(basic_string<charT, traits, A>& c, const U& value);
template <class T, class A, class U>
void erase(deque<T, A>& c, const U& value);
template <class T, class A, class U>
void erase(vector<T, A>& c, const U& value);
Effects: Equivalent to:
c.erase(remove(c.begin(), c.end(), value), c.end());
template <class T, class A, class U>
void erase(forward_list<T, A>& c, const U& value);
template <class T, class A, class U>
void erase(list<T, A>& c, const U& value);
Effects: Equivalent to:
erase_if(c, [&](auto& elem) { return elem == value; });
[ Note: Overloads of erase() for associative containers and
unordered associative containers are intentionally not provided. --end note ]
III. References
All of the Library Fundamentals v2 citations in this proposal are to
Working Draft N4084:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4084.html
[1] N4009 "Uniform Container Erasure" by Stephan T. Lavavej:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4009.htm
[2] N4161 "Uniform Container Erasure (Revision 1)" by Stephan T. Lavavej:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4161.htm
(end)