diff options
author | Marshall Clow <mclow.lists@gmail.com> | 2018-12-14 18:49:35 +0000 |
---|---|---|
committer | Marshall Clow <mclow.lists@gmail.com> | 2018-12-14 18:49:35 +0000 |
commit | 24e08de7d4cadd75d694439a6685585c8e983488 (patch) | |
tree | 5b3d3042fb19d73d19f1957ba82aa5fb8f6dd2f9 /libcxx/test | |
parent | be00641467fb8ba217bb2f92b2a3e6a8cb5ec2d6 (diff) |
Implement P1209 - Adopt Consistent Container Erasure from Library Fundamentals 2 for C++20. Reviewed as https://reviews.llvm.org/D55532
Diffstat (limited to 'libcxx/test')
27 files changed, 1531 insertions, 0 deletions
diff --git a/libcxx/test/std/containers/associative/map/map.erasure/erase_if.pass.cpp b/libcxx/test/std/containers/associative/map/map.erasure/erase_if.pass.cpp new file mode 100644 index 00000000000..f8cbc15d164 --- /dev/null +++ b/libcxx/test/std/containers/associative/map/map.erasure/erase_if.pass.cpp @@ -0,0 +1,79 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// <map> + +// template <class Key, class T, class Compare, class Allocator, class Predicate> +// void erase_if(map<Key, T, Compare, Allocator>& c, Predicate pred); + +#include <map> + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +using Init = std::initializer_list<int>; +template <typename M> +M make (Init vals) +{ + M ret; + for (int v : vals) + ret[v] = v + 10; + return ret; +} + +template <typename M, typename Pred> +void +test0(Init vals, Pred p, Init expected) +{ + M s = make<M> (vals); + ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p))); + std::erase_if(s, p); + assert(s == make<M>(expected)); +} + +template <typename S> +void test() +{ + auto is1 = [](auto v) { return v.first == 1;}; + auto is2 = [](auto v) { return v.first == 2;}; + auto is3 = [](auto v) { return v.first == 3;}; + auto is4 = [](auto v) { return v.first == 4;}; + auto True = [](auto) { return true; }; + auto False = [](auto) { return false; }; + + test0<S>({}, is1, {}); + + test0<S>({1}, is1, {}); + test0<S>({1}, is2, {1}); + + test0<S>({1,2}, is1, {2}); + test0<S>({1,2}, is2, {1}); + test0<S>({1,2}, is3, {1,2}); + + test0<S>({1,2,3}, is1, {2,3}); + test0<S>({1,2,3}, is2, {1,3}); + test0<S>({1,2,3}, is3, {1,2}); + test0<S>({1,2,3}, is4, {1,2,3}); + + test0<S>({1,2,3}, True, {}); + test0<S>({1,2,3}, False, {1,2,3}); +} + +int main() +{ + test<std::map<int, int>>(); + test<std::map<int, int, std::less<int>, min_allocator<std::pair<const int, int>>>> (); + test<std::map<int, int, std::less<int>, test_allocator<std::pair<const int, int>>>> (); + + test<std::map<long, short>>(); + test<std::map<short, double>>(); +} + diff --git a/libcxx/test/std/containers/associative/multimap/multimap.erasure/erase_if.pass.cpp b/libcxx/test/std/containers/associative/multimap/multimap.erasure/erase_if.pass.cpp new file mode 100644 index 00000000000..8e786fdc947 --- /dev/null +++ b/libcxx/test/std/containers/associative/multimap/multimap.erasure/erase_if.pass.cpp @@ -0,0 +1,89 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// <map> + +// template <class Key, class T, class Compare, class Allocator, class Predicate> +// void erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred); + +#include <map> + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +using Init = std::initializer_list<int>; +template <typename M> +M make (Init vals) +{ + M ret; + for (int v : vals) + ret.insert(typename M::value_type(v, v + 10)); + return ret; +} + +template <typename M, typename Pred> +void +test0(Init vals, Pred p, Init expected) +{ + M s = make<M> (vals); + ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p))); + std::erase_if(s, p); + assert(s == make<M>(expected)); +} + +template <typename S> +void test() +{ + auto is1 = [](auto v) { return v.first == 1;}; + auto is2 = [](auto v) { return v.first == 2;}; + auto is3 = [](auto v) { return v.first == 3;}; + auto is4 = [](auto v) { return v.first == 4;}; + auto True = [](auto) { return true; }; + auto False = [](auto) { return false; }; + + test0<S>({}, is1, {}); + + test0<S>({1}, is1, {}); + test0<S>({1}, is2, {1}); + + test0<S>({1,2}, is1, {2}); + test0<S>({1,2}, is2, {1}); + test0<S>({1,2}, is3, {1,2}); + test0<S>({1,1}, is1, {}); + test0<S>({1,1}, is3, {1,1}); + + test0<S>({1,2,3}, is1, {2,3}); + test0<S>({1,2,3}, is2, {1,3}); + test0<S>({1,2,3}, is3, {1,2}); + test0<S>({1,2,3}, is4, {1,2,3}); + + test0<S>({1,1,1}, is1, {}); + test0<S>({1,1,1}, is2, {1,1,1}); + test0<S>({1,1,2}, is1, {2}); + test0<S>({1,1,2}, is2, {1,1}); + test0<S>({1,1,2}, is3, {1,1,2}); + test0<S>({1,2,2}, is1, {2,2}); + test0<S>({1,2,2}, is2, {1}); + test0<S>({1,2,2}, is3, {1,2,2}); + + test0<S>({1,2,3}, True, {}); + test0<S>({1,2,3}, False, {1,2,3}); +} + +int main() +{ + test<std::multimap<int, int>>(); + test<std::multimap<int, int, std::less<int>, min_allocator<std::pair<const int, int>>>> (); + test<std::multimap<int, int, std::less<int>, test_allocator<std::pair<const int, int>>>> (); + + test<std::multimap<long, short>>(); + test<std::multimap<short, double>>(); +} diff --git a/libcxx/test/std/containers/associative/multiset/multiset.erasure/erase_if.pass.cpp b/libcxx/test/std/containers/associative/multiset/multiset.erasure/erase_if.pass.cpp new file mode 100644 index 00000000000..3c619bb687f --- /dev/null +++ b/libcxx/test/std/containers/associative/multiset/multiset.erasure/erase_if.pass.cpp @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// <set> + +// template <class T, class Compare, class Allocator, class Predicate> +// void erase_if(multiset<T, Compare, Allocator>& c, Predicate pred); + +#include <set> + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template <class S, class Pred> +void +test0(S s, Pred p, S expected) +{ + ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p))); + std::erase_if(s, p); + assert(s == expected); +} + +template <typename S> +void test() +{ + auto is1 = [](auto v) { return v == 1;}; + auto is2 = [](auto v) { return v == 2;}; + auto is3 = [](auto v) { return v == 3;}; + auto is4 = [](auto v) { return v == 4;}; + auto True = [](auto) { return true; }; + auto False = [](auto) { return false; }; + + test0(S(), is1, S()); + + test0(S({1}), is1, S()); + test0(S({1}), is2, S({1})); + + test0(S({1,2}), is1, S({2})); + test0(S({1,2}), is2, S({1})); + test0(S({1,2}), is3, S({1,2})); + test0(S({1,1}), is1, S()); + test0(S({1,1}), is3, S({1,1})); + + test0(S({1,2,3}), is1, S({2,3})); + test0(S({1,2,3}), is2, S({1,3})); + test0(S({1,2,3}), is3, S({1,2})); + test0(S({1,2,3}), is4, S({1,2,3})); + + test0(S({1,1,1}), is1, S()); + test0(S({1,1,1}), is2, S({1,1,1})); + test0(S({1,1,2}), is1, S({2})); + test0(S({1,1,2}), is2, S({1,1})); + test0(S({1,1,2}), is3, S({1,1,2})); + test0(S({1,2,2}), is1, S({2,2})); + test0(S({1,2,2}), is2, S({1})); + test0(S({1,2,2}), is3, S({1,2,2})); + + test0(S({1,2,3}), True, S()); + test0(S({1,2,3}), False, S({1,2,3})); +} + +int main() +{ + test<std::multiset<int>>(); + test<std::multiset<int, std::less<int>, min_allocator<int>>> (); + test<std::multiset<int, std::less<int>, test_allocator<int>>> (); + + test<std::multiset<long>>(); + test<std::multiset<double>>(); +} diff --git a/libcxx/test/std/containers/associative/set/set.erasure/erase_if.pass.cpp b/libcxx/test/std/containers/associative/set/set.erasure/erase_if.pass.cpp new file mode 100644 index 00000000000..a55a38c2d56 --- /dev/null +++ b/libcxx/test/std/containers/associative/set/set.erasure/erase_if.pass.cpp @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// <set> + +// template <class T, class Compare, class Allocator, class Predicate> +// void erase_if(set<T, Compare, Allocator>& c, Predicate pred); + +#include <set> + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template <class S, class Pred> +void +test0(S s, Pred p, S expected) +{ + ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p))); + std::erase_if(s, p); + assert(s == expected); +} + +template <typename S> +void test() +{ + auto is1 = [](auto v) { return v == 1;}; + auto is2 = [](auto v) { return v == 2;}; + auto is3 = [](auto v) { return v == 3;}; + auto is4 = [](auto v) { return v == 4;}; + auto True = [](auto) { return true; }; + auto False = [](auto) { return false; }; + + test0(S(), is1, S()); + + test0(S({1}), is1, S()); + test0(S({1}), is2, S({1})); + + test0(S({1,2}), is1, S({2})); + test0(S({1,2}), is2, S({1})); + test0(S({1,2}), is3, S({1,2})); + + test0(S({1,2,3}), is1, S({2,3})); + test0(S({1,2,3}), is2, S({1,3})); + test0(S({1,2,3}), is3, S({1,2})); + test0(S({1,2,3}), is4, S({1,2,3})); + + test0(S({1,2,3}), True, S()); + test0(S({1,2,3}), False, S({1,2,3})); +} + +int main() +{ + test<std::set<int>>(); + test<std::set<int, std::less<int>, min_allocator<int>>> (); + test<std::set<int, std::less<int>, test_allocator<int>>> (); + + test<std::set<long>>(); + test<std::set<double>>(); +} diff --git a/libcxx/test/std/containers/sequences/deque/deque.erasure/erase.pass.cpp b/libcxx/test/std/containers/sequences/deque/deque.erasure/erase.pass.cpp new file mode 100644 index 00000000000..9a8c698a5ff --- /dev/null +++ b/libcxx/test/std/containers/sequences/deque/deque.erasure/erase.pass.cpp @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// <deque> + +// template <class T, class Allocator, class U> +// void erase(deque<T, Allocator>& c, const U& value); + + +#include <deque> +#include <optional> + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template <class S, class U> +void +test0(S s, U val, S expected) +{ + ASSERT_SAME_TYPE(void, decltype(std::erase(s, val))); + std::erase(s, val); + assert(s == expected); +} + +template <class S> +void test() +{ + + test0(S(), 1, S()); + + test0(S({1}), 1, S()); + test0(S({1}), 2, S({1})); + + test0(S({1,2}), 1, S({2})); + test0(S({1,2}), 2, S({1})); + test0(S({1,2}), 3, S({1,2})); + test0(S({1,1}), 1, S()); + test0(S({1,1}), 3, S({1,1})); + + test0(S({1,2,3}), 1, S({2,3})); + test0(S({1,2,3}), 2, S({1,3})); + test0(S({1,2,3}), 3, S({1,2})); + test0(S({1,2,3}), 4, S({1,2,3})); + + test0(S({1,1,1}), 1, S()); + test0(S({1,1,1}), 2, S({1,1,1})); + test0(S({1,1,2}), 1, S({2})); + test0(S({1,1,2}), 2, S({1,1})); + test0(S({1,1,2}), 3, S({1,1,2})); + test0(S({1,2,2}), 1, S({2,2})); + test0(S({1,2,2}), 2, S({1})); + test0(S({1,2,2}), 3, S({1,2,2})); + +// Test cross-type erasure + using opt = std::optional<typename S::value_type>; + test0(S({1,2,1}), opt(), S({1,2,1})); + test0(S({1,2,1}), opt(1), S({2})); + test0(S({1,2,1}), opt(2), S({1,1})); + test0(S({1,2,1}), opt(3), S({1,2,1})); +} + +int main() +{ + test<std::deque<int>>(); + test<std::deque<int, min_allocator<int>>> (); + test<std::deque<int, test_allocator<int>>> (); + + test<std::deque<long>>(); + test<std::deque<double>>(); +} diff --git a/libcxx/test/std/containers/sequences/deque/deque.erasure/erase_if.pass.cpp b/libcxx/test/std/containers/sequences/deque/deque.erasure/erase_if.pass.cpp new file mode 100644 index 00000000000..a090eb6947d --- /dev/null +++ b/libcxx/test/std/containers/sequences/deque/deque.erasure/erase_if.pass.cpp @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// <deque> + +// template <class T, class Allocator, class Predicate> +// void erase_if(deque<T, Allocator>& c, Predicate pred); + +#include <deque> + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template <class S, class Pred> +void +test0(S s, Pred p, S expected) +{ + ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p))); + std::erase_if(s, p); + assert(s == expected); +} + +template <typename S> +void test() +{ + auto is1 = [](auto v) { return v == 1;}; + auto is2 = [](auto v) { return v == 2;}; + auto is3 = [](auto v) { return v == 3;}; + auto is4 = [](auto v) { return v == 4;}; + auto True = [](auto) { return true; }; + auto False = [](auto) { return false; }; + + test0(S(), is1, S()); + + test0(S({1}), is1, S()); + test0(S({1}), is2, S({1})); + + test0(S({1,2}), is1, S({2})); + test0(S({1,2}), is2, S({1})); + test0(S({1,2}), is3, S({1,2})); + test0(S({1,1}), is1, S()); + test0(S({1,1}), is3, S({1,1})); + + test0(S({1,2,3}), is1, S({2,3})); + test0(S({1,2,3}), is2, S({1,3})); + test0(S({1,2,3}), is3, S({1,2})); + test0(S({1,2,3}), is4, S({1,2,3})); + + test0(S({1,1,1}), is1, S()); + test0(S({1,1,1}), is2, S({1,1,1})); + test0(S({1,1,2}), is1, S({2})); + test0(S({1,1,2}), is2, S({1,1})); + test0(S({1,1,2}), is3, S({1,1,2})); + test0(S({1,2,2}), is1, S({2,2})); + test0(S({1,2,2}), is2, S({1})); + test0(S({1,2,2}), is3, S({1,2,2})); + + test0(S({1,2,3}), True, S()); + test0(S({1,2,3}), False, S({1,2,3})); +} + +int main() +{ + test<std::deque<int>>(); + test<std::deque<int, min_allocator<int>>> (); + test<std::deque<int, test_allocator<int>>> (); + + test<std::deque<long>>(); + test<std::deque<double>>(); +} diff --git a/libcxx/test/std/containers/sequences/forwardlist/forwardlist.erasure/erase.pass.cpp b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.erasure/erase.pass.cpp new file mode 100644 index 00000000000..0163b8607cb --- /dev/null +++ b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.erasure/erase.pass.cpp @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// <forward_list> + +// template <class T, class Allocator, class U> +// void erase(forward_list<T, Allocator>& c, const U& value); + + +#include <forward_list> +#include <optional> + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template <class S, class U> +void +test0(S s, U val, S expected) +{ + ASSERT_SAME_TYPE(void, decltype(std::erase(s, val))); + std::erase(s, val); + assert(s == expected); +} + +template <class S> +void test() +{ + + test0(S(), 1, S()); + + test0(S({1}), 1, S()); + test0(S({1}), 2, S({1})); + + test0(S({1,2}), 1, S({2})); + test0(S({1,2}), 2, S({1})); + test0(S({1,2}), 3, S({1,2})); + test0(S({1,1}), 1, S()); + test0(S({1,1}), 3, S({1,1})); + + test0(S({1,2,3}), 1, S({2,3})); + test0(S({1,2,3}), 2, S({1,3})); + test0(S({1,2,3}), 3, S({1,2})); + test0(S({1,2,3}), 4, S({1,2,3})); + + test0(S({1,1,1}), 1, S()); + test0(S({1,1,1}), 2, S({1,1,1})); + test0(S({1,1,2}), 1, S({2})); + test0(S({1,1,2}), 2, S({1,1})); + test0(S({1,1,2}), 3, S({1,1,2})); + test0(S({1,2,2}), 1, S({2,2})); + test0(S({1,2,2}), 2, S({1})); + test0(S({1,2,2}), 3, S({1,2,2})); + +// Test cross-type erasure + using opt = std::optional<typename S::value_type>; + test0(S({1,2,1}), opt(), S({1,2,1})); + test0(S({1,2,1}), opt(1), S({2})); + test0(S({1,2,1}), opt(2), S({1,1})); + test0(S({1,2,1}), opt(3), S({1,2,1})); +} + +int main() +{ + test<std::forward_list<int>>(); + test<std::forward_list<int, min_allocator<int>>> (); + test<std::forward_list<int, test_allocator<int>>> (); + + test<std::forward_list<long>>(); + test<std::forward_list<double>>(); +} diff --git a/libcxx/test/std/containers/sequences/forwardlist/forwardlist.erasure/erase_if.pass.cpp b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.erasure/erase_if.pass.cpp new file mode 100644 index 00000000000..69685d2d35f --- /dev/null +++ b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.erasure/erase_if.pass.cpp @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// <forward_list> + +// template <class T, class Allocator, class Predicate> +// void erase_if(forward_list<T, Allocator>& c, Predicate pred); + +#include <forward_list> + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template <class S, class Pred> +void +test0(S s, Pred p, S expected) +{ + ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p))); + std::erase_if(s, p); + assert(s == expected); +} + +template <typename S> +void test() +{ + auto is1 = [](auto v) { return v == 1;}; + auto is2 = [](auto v) { return v == 2;}; + auto is3 = [](auto v) { return v == 3;}; + auto is4 = [](auto v) { return v == 4;}; + auto True = [](auto) { return true; }; + auto False = [](auto) { return false; }; + + test0(S(), is1, S()); + + test0(S({1}), is1, S()); + test0(S({1}), is2, S({1})); + + test0(S({1,2}), is1, S({2})); + test0(S({1,2}), is2, S({1})); + test0(S({1,2}), is3, S({1,2})); + test0(S({1,1}), is1, S()); + test0(S({1,1}), is3, S({1,1})); + + test0(S({1,2,3}), is1, S({2,3})); + test0(S({1,2,3}), is2, S({1,3})); + test0(S({1,2,3}), is3, S({1,2})); + test0(S({1,2,3}), is4, S({1,2,3})); + + test0(S({1,1,1}), is1, S()); + test0(S({1,1,1}), is2, S({1,1,1})); + test0(S({1,1,2}), is1, S({2})); + test0(S({1,1,2}), is2, S({1,1})); + test0(S({1,1,2}), is3, S({1,1,2})); + test0(S({1,2,2}), is1, S({2,2})); + test0(S({1,2,2}), is2, S({1})); + test0(S({1,2,2}), is3, S({1,2,2})); + + test0(S({1,2,3}), True, S()); + test0(S({1,2,3}), False, S({1,2,3})); +} + +int main() +{ + test<std::forward_list<int>>(); + test<std::forward_list<int, min_allocator<int>>> (); + test<std::forward_list<int, test_allocator<int>>> (); + + test<std::forward_list<long>>(); + test<std::forward_list<double>>(); +} diff --git a/libcxx/test/std/containers/sequences/list/list.erasure/erase.pass.cpp b/libcxx/test/std/containers/sequences/list/list.erasure/erase.pass.cpp new file mode 100644 index 00000000000..a9f65c0537e --- /dev/null +++ b/libcxx/test/std/containers/sequences/list/list.erasure/erase.pass.cpp @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// <list> + +// template <class T, class Allocator, class U> +// void erase(list<T, Allocator>& c, const U& value); + + +#include <list> +#include <optional> + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template <class S, class U> +void +test0(S s, U val, S expected) +{ + ASSERT_SAME_TYPE(void, decltype(std::erase(s, val))); + std::erase(s, val); + assert(s == expected); +} + +template <class S> +void test() +{ + + test0(S(), 1, S()); + + test0(S({1}), 1, S()); + test0(S({1}), 2, S({1})); + + test0(S({1,2}), 1, S({2})); + test0(S({1,2}), 2, S({1})); + test0(S({1,2}), 3, S({1,2})); + test0(S({1,1}), 1, S()); + test0(S({1,1}), 3, S({1,1})); + + test0(S({1,2,3}), 1, S({2,3})); + test0(S({1,2,3}), 2, S({1,3})); + test0(S({1,2,3}), 3, S({1,2})); + test0(S({1,2,3}), 4, S({1,2,3})); + + test0(S({1,1,1}), 1, S()); + test0(S({1,1,1}), 2, S({1,1,1})); + test0(S({1,1,2}), 1, S({2})); + test0(S({1,1,2}), 2, S({1,1})); + test0(S({1,1,2}), 3, S({1,1,2})); + test0(S({1,2,2}), 1, S({2,2})); + test0(S({1,2,2}), 2, S({1})); + test0(S({1,2,2}), 3, S({1,2,2})); + +// Test cross-type erasure + using opt = std::optional<typename S::value_type>; + test0(S({1,2,1}), opt(), S({1,2,1})); + test0(S({1,2,1}), opt(1), S({2})); + test0(S({1,2,1}), opt(2), S({1,1})); + test0(S({1,2,1}), opt(3), S({1,2,1})); +} + +int main() +{ + test<std::list<int>>(); + test<std::list<int, min_allocator<int>>> (); + test<std::list<int, test_allocator<int>>> (); + + test<std::list<long>>(); + test<std::list<double>>(); +} diff --git a/libcxx/test/std/containers/sequences/list/list.erasure/erase_if.pass.cpp b/libcxx/test/std/containers/sequences/list/list.erasure/erase_if.pass.cpp new file mode 100644 index 00000000000..99b1c6530f9 --- /dev/null +++ b/libcxx/test/std/containers/sequences/list/list.erasure/erase_if.pass.cpp @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// <list> + +// template <class T, class Allocator, class Predicate> +// void erase_if(list<T, Allocator>& c, Predicate pred); + +#include <list> + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template <class S, class Pred> +void +test0(S s, Pred p, S expected) +{ + ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p))); + std::erase_if(s, p); + assert(s == expected); +} + +template <typename S> +void test() +{ + auto is1 = [](auto v) { return v == 1;}; + auto is2 = [](auto v) { return v == 2;}; + auto is3 = [](auto v) { return v == 3;}; + auto is4 = [](auto v) { return v == 4;}; + auto True = [](auto) { return true; }; + auto False = [](auto) { return false; }; + + test0(S(), is1, S()); + + test0(S({1}), is1, S()); + test0(S({1}), is2, S({1})); + + test0(S({1,2}), is1, S({2})); + test0(S({1,2}), is2, S({1})); + test0(S({1,2}), is3, S({1,2})); + test0(S({1,1}), is1, S()); + test0(S({1,1}), is3, S({1,1})); + + test0(S({1,2,3}), is1, S({2,3})); + test0(S({1,2,3}), is2, S({1,3})); + test0(S({1,2,3}), is3, S({1,2})); + test0(S({1,2,3}), is4, S({1,2,3})); + + test0(S({1,1,1}), is1, S()); + test0(S({1,1,1}), is2, S({1,1,1})); + test0(S({1,1,2}), is1, S({2})); + test0(S({1,1,2}), is2, S({1,1})); + test0(S({1,1,2}), is3, S({1,1,2})); + test0(S({1,2,2}), is1, S({2,2})); + test0(S({1,2,2}), is2, S({1})); + test0(S({1,2,2}), is3, S({1,2,2})); + + test0(S({1,2,3}), True, S()); + test0(S({1,2,3}), False, S({1,2,3})); +} + +int main() +{ + test<std::list<int>>(); + test<std::list<int, min_allocator<int>>> (); + test<std::list<int, test_allocator<int>>> (); + + test<std::list<long>>(); + test<std::list<double>>(); +} diff --git a/libcxx/test/std/containers/sequences/vector/vector.erasure/erase.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.erasure/erase.pass.cpp new file mode 100644 index 00000000000..e88252f1d92 --- /dev/null +++ b/libcxx/test/std/containers/sequences/vector/vector.erasure/erase.pass.cpp @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// <vector> + +// template <class T, class Allocator, class U> +// void erase(vector<T, Allocator>& c, const U& value); + + +#include <vector> +#include <optional> + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template <class S, class U> +void +test0(S s, U val, S expected) +{ + ASSERT_SAME_TYPE(void, decltype(std::erase(s, val))); + std::erase(s, val); + assert(s == expected); +} + +template <class S> +void test() +{ + + test0(S(), 1, S()); + + test0(S({1}), 1, S()); + test0(S({1}), 2, S({1})); + + test0(S({1,2}), 1, S({2})); + test0(S({1,2}), 2, S({1})); + test0(S({1,2}), 3, S({1,2})); + test0(S({1,1}), 1, S()); + test0(S({1,1}), 3, S({1,1})); + + test0(S({1,2,3}), 1, S({2,3})); + test0(S({1,2,3}), 2, S({1,3})); + test0(S({1,2,3}), 3, S({1,2})); + test0(S({1,2,3}), 4, S({1,2,3})); + + test0(S({1,1,1}), 1, S()); + test0(S({1,1,1}), 2, S({1,1,1})); + test0(S({1,1,2}), 1, S({2})); + test0(S({1,1,2}), 2, S({1,1})); + test0(S({1,1,2}), 3, S({1,1,2})); + test0(S({1,2,2}), 1, S({2,2})); + test0(S({1,2,2}), 2, S({1})); + test0(S({1,2,2}), 3, S({1,2,2})); + +// Test cross-type erasure + using opt = std::optional<typename S::value_type>; + test0(S({1,2,1}), opt(), S({1,2,1})); + test0(S({1,2,1}), opt(1), S({2})); + test0(S({1,2,1}), opt(2), S({1,1})); + test0(S({1,2,1}), opt(3), S({1,2,1})); +} + +int main() +{ + test<std::vector<int>>(); + test<std::vector<int, min_allocator<int>>> (); + test<std::vector<int, test_allocator<int>>> (); + + test<std::vector<long>>(); + test<std::vector<double>>(); +} diff --git a/libcxx/test/std/containers/sequences/vector/vector.erasure/erase_if.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.erasure/erase_if.pass.cpp new file mode 100644 index 00000000000..8025a34071f --- /dev/null +++ b/libcxx/test/std/containers/sequences/vector/vector.erasure/erase_if.pass.cpp @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// <vector> + +// template <class T, class Allocator, class Predicate> +// void erase_if(vector<T, Allocator>& c, Predicate pred); + +#include <vector> + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template <class S, class Pred> +void +test0(S s, Pred p, S expected) +{ + ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p))); + std::erase_if(s, p); + assert(s == expected); +} + +template <typename S> +void test() +{ + auto is1 = [](auto v) { return v == 1;}; + auto is2 = [](auto v) { return v == 2;}; + auto is3 = [](auto v) { return v == 3;}; + auto is4 = [](auto v) { return v == 4;}; + auto True = [](auto) { return true; }; + auto False = [](auto) { return false; }; + + test0(S(), is1, S()); + + test0(S({1}), is1, S()); + test0(S({1}), is2, S({1})); + + test0(S({1,2}), is1, S({2})); + test0(S({1,2}), is2, S({1})); + test0(S({1,2}), is3, S({1,2})); + test0(S({1,1}), is1, S()); + test0(S({1,1}), is3, S({1,1})); + + test0(S({1,2,3}), is1, S({2,3})); + test0(S({1,2,3}), is2, S({1,3})); + test0(S({1,2,3}), is3, S({1,2})); + test0(S({1,2,3}), is4, S({1,2,3})); + + test0(S({1,1,1}), is1, S()); + test0(S({1,1,1}), is2, S({1,1,1})); + test0(S({1,1,2}), is1, S({2})); + test0(S({1,1,2}), is2, S({1,1})); + test0(S({1,1,2}), is3, S({1,1,2})); + test0(S({1,2,2}), is1, S({2,2})); + test0(S({1,2,2}), is2, S({1})); + test0(S({1,2,2}), is3, S({1,2,2})); + + test0(S({1,2,3}), True, S()); + test0(S({1,2,3}), False, S({1,2,3})); +} + +int main() +{ + test<std::vector<int>>(); + test<std::vector<int, min_allocator<int>>> (); + test<std::vector<int, test_allocator<int>>> (); + + test<std::vector<long>>(); + test<std::vector<double>>(); +} diff --git a/libcxx/test/std/containers/unord/unord.map/erase_if.pass.cpp b/libcxx/test/std/containers/unord/unord.map/erase_if.pass.cpp new file mode 100644 index 00000000000..f6a580c2160 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.map/erase_if.pass.cpp @@ -0,0 +1,80 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// <unordered_map> + +// template <class Key, class T, class Hash, class Pred, class Allocator, class Predicate> +// void erase_if(unordered_map<Key, T, Hash, Pred, Allocator>& c, Predicate pred); + +#include <unordered_map> + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +using Init = std::initializer_list<int>; +template <typename M> +M make (Init vals) +{ + M ret; + for (int v : vals) + ret[v] = v + 10; + return ret; +} + +template <typename M, typename Pred> +void +test0(Init vals, Pred p, Init expected) +{ + M s = make<M> (vals); + ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p))); + std::erase_if(s, p); + M e = make<M>(expected); + assert((std::is_permutation(s.begin(), s.end(), e.begin(), e.end()))); +} + +template <typename S> +void test() +{ + auto is1 = [](auto v) { return v.first == 1;}; + auto is2 = [](auto v) { return v.first == 2;}; + auto is3 = [](auto v) { return v.first == 3;}; + auto is4 = [](auto v) { return v.first == 4;}; + auto True = [](auto) { return true; }; + auto False = [](auto) { return false; }; + + test0<S>({}, is1, {}); + + test0<S>({1}, is1, {}); + test0<S>({1}, is2, {1}); + + test0<S>({1,2}, is1, {2}); + test0<S>({1,2}, is2, {1}); + test0<S>({1,2}, is3, {1,2}); + + test0<S>({1,2,3}, is1, {2,3}); + test0<S>({1,2,3}, is2, {1,3}); + test0<S>({1,2,3}, is3, {1,2}); + test0<S>({1,2,3}, is4, {1,2,3}); + + test0<S>({1,2,3}, True, {}); + test0<S>({1,2,3}, False, {1,2,3}); +} + +int main() +{ + test<std::unordered_map<int, int>>(); + test<std::unordered_map<int, int, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, int>>>> (); + test<std::unordered_map<int, int, std::hash<int>, std::equal_to<int>, test_allocator<std::pair<const int, int>>>> (); + + test<std::unordered_map<long, short>>(); + test<std::unordered_map<short, double>>(); +} + diff --git a/libcxx/test/std/containers/unord/unord.multimap/erase_if.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/erase_if.pass.cpp new file mode 100644 index 00000000000..dc613269a35 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.multimap/erase_if.pass.cpp @@ -0,0 +1,90 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// <unordered_map> + +// template <class Key, class T, class Hash, class Pred, class Allocator, class Predicate> +// void erase_if(unordered_multimap<Key, T, Hash, Pred, Allocator>& c, Predicate pred); + +#include <unordered_map> + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +using Init = std::initializer_list<int>; +template <typename M> +M make (Init vals) +{ + M ret; + for (int v : vals) + ret.insert(typename M::value_type(v, v + 10)); + return ret; +} + +template <typename M, typename Pred> +void +test0(Init vals, Pred p, Init expected) +{ + M s = make<M> (vals); + ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p))); + std::erase_if(s, p); + M e = make<M>(expected); + assert((std::is_permutation(s.begin(), s.end(), e.begin(), e.end()))); +} + +template <typename S> +void test() +{ + auto is1 = [](auto v) { return v.first == 1;}; + auto is2 = [](auto v) { return v.first == 2;}; + auto is3 = [](auto v) { return v.first == 3;}; + auto is4 = [](auto v) { return v.first == 4;}; + auto True = [](auto) { return true; }; + auto False = [](auto) { return false; }; + + test0<S>({}, is1, {}); + + test0<S>({1}, is1, {}); + test0<S>({1}, is2, {1}); + + test0<S>({1,2}, is1, {2}); + test0<S>({1,2}, is2, {1}); + test0<S>({1,2}, is3, {1,2}); + test0<S>({1,1}, is1, {}); + test0<S>({1,1}, is3, {1,1}); + + test0<S>({1,2,3}, is1, {2,3}); + test0<S>({1,2,3}, is2, {1,3}); + test0<S>({1,2,3}, is3, {1,2}); + test0<S>({1,2,3}, is4, {1,2,3}); + + test0<S>({1,1,1}, is1, {}); + test0<S>({1,1,1}, is2, {1,1,1}); + test0<S>({1,1,2}, is1, {2}); + test0<S>({1,1,2}, is2, {1,1}); + test0<S>({1,1,2}, is3, {1,1,2}); + test0<S>({1,2,2}, is1, {2,2}); + test0<S>({1,2,2}, is2, {1}); + test0<S>({1,2,2}, is3, {1,2,2}); + + test0<S>({1,2,3}, True, {}); + test0<S>({1,2,3}, False, {1,2,3}); +} + +int main() +{ + test<std::unordered_multimap<int, int>>(); + test<std::unordered_multimap<int, int, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, int>>>> (); + test<std::unordered_multimap<int, int, std::hash<int>, std::equal_to<int>, test_allocator<std::pair<const int, int>>>> (); + + test<std::unordered_multimap<long, short>>(); + test<std::unordered_multimap<short, double>>(); +} diff --git a/libcxx/test/std/containers/unord/unord.multiset/erase_if.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/erase_if.pass.cpp new file mode 100644 index 00000000000..7a9d93d432f --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.multiset/erase_if.pass.cpp @@ -0,0 +1,91 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// <set> + +// template <class T, class Hash, class Compare, class Allocator, class Predicate> +// void erase_if(unordered_multiset<T, Hash, Compare, Allocator>& c, Predicate pred); + +#include <unordered_set> + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +using Init = std::initializer_list<int>; + +template <typename M> +M make (Init vals) +{ + M ret; + for (int v : vals) + ret.insert(v); + return ret; +} + +template <typename M, typename Pred> +void +test0(Init vals, Pred p, Init expected) +{ + M s = make<M> (vals); + ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p))); + std::erase_if(s, p); + M e = make<M>(expected); + assert((std::is_permutation(s.begin(), s.end(), e.begin(), e.end()))); +} + +template <typename S> +void test() +{ + auto is1 = [](auto v) { return v == 1;}; + auto is2 = [](auto v) { return v == 2;}; + auto is3 = [](auto v) { return v == 3;}; + auto is4 = [](auto v) { return v == 4;}; + auto True = [](auto) { return true; }; + auto False = [](auto) { return false; }; + + test0<S>({}, is1, {}); + + test0<S>({1}, is1, {}); + test0<S>({1}, is2, {1}); + + test0<S>({1,2}, is1, {2}); + test0<S>({1,2}, is2, {1}); + test0<S>({1,2}, is3, {1,2}); + test0<S>({1,1}, is1, {}); + test0<S>({1,1}, is3, {1,1}); + + test0<S>({1,2,3}, is1, {2,3}); + test0<S>({1,2,3}, is2, {1,3}); + test0<S>({1,2,3}, is3, {1,2}); + test0<S>({1,2,3}, is4, {1,2,3}); + + test0<S>({1,1,1}, is1, {}); + test0<S>({1,1,1}, is2, {1,1,1}); + test0<S>({1,1,2}, is1, {2}); + test0<S>({1,1,2}, is2, {1,1}); + test0<S>({1,1,2}, is3, {1,1,2}); + test0<S>({1,2,2}, is1, {2,2}); + test0<S>({1,2,2}, is2, {1}); + test0<S>({1,2,2}, is3, {1,2,2}); + + test0<S>({1,2,3}, True, {}); + test0<S>({1,2,3}, False, {1,2,3}); +} + +int main() +{ + test<std::unordered_multiset<int>>(); + test<std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, min_allocator<int>>> (); + test<std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, test_allocator<int>>> (); + + test<std::unordered_multiset<long>>(); + test<std::unordered_multiset<double>>(); +} diff --git a/libcxx/test/std/containers/unord/unord.set/erase_if.pass.cpp b/libcxx/test/std/containers/unord/unord.set/erase_if.pass.cpp new file mode 100644 index 00000000000..e060fda1fe8 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.set/erase_if.pass.cpp @@ -0,0 +1,81 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// <unordered_set> + +// template <class T, class Hash, class Compare, class Allocator, class Predicate> +// void erase_if(unorderd_set<T, Hash, Compare, Allocator>& c, Predicate pred); + +#include <unordered_set> + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +using Init = std::initializer_list<int>; + +template <typename M> +M make (Init vals) +{ + M ret; + for (int v : vals) + ret.insert(v); + return ret; +} + +template <typename M, typename Pred> +void +test0(Init vals, Pred p, Init expected) +{ + M s = make<M> (vals); + ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p))); + std::erase_if(s, p); + M e = make<M>(expected); + assert((std::is_permutation(s.begin(), s.end(), e.begin(), e.end()))); +} + + +template <typename S> +void test() +{ + auto is1 = [](auto v) { return v == 1;}; + auto is2 = [](auto v) { return v == 2;}; + auto is3 = [](auto v) { return v == 3;}; + auto is4 = [](auto v) { return v == 4;}; + auto True = [](auto) { return true; }; + auto False = [](auto) { return false; }; + + test0<S>({}, is1, {}); + + test0<S>({1}, is1, {}); + test0<S>({1}, is2, {1}); + + test0<S>({1,2}, is1, {2}); + test0<S>({1,2}, is2, {1}); + test0<S>({1,2}, is3, {1,2}); + + test0<S>({1,2,3}, is1, {2,3}); + test0<S>({1,2,3}, is2, {1,3}); + test0<S>({1,2,3}, is3, {1,2}); + test0<S>({1,2,3}, is4, {1,2,3}); + + test0<S>({1,2,3}, True, {}); + test0<S>({1,2,3}, False, {1,2,3}); +} + +int main() +{ + test<std::unordered_set<int>>(); + test<std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>>> (); + test<std::unordered_set<int, std::hash<int>, std::equal_to<int>, test_allocator<int>>> (); + + test<std::unordered_set<long>>(); + test<std::unordered_set<double>>(); +} diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/deque.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/deque.version.pass.cpp index d3ca7d9b02c..188d2f3c0ac 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/deque.version.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/deque.version.pass.cpp @@ -12,6 +12,7 @@ /* Constant Value __cpp_lib_allocator_traits_is_always_equal 201411L + __cpp_lib_erase_if 201811L __cpp_lib_nonmember_container_access 201411L */ @@ -24,6 +25,16 @@ int main() { // ensure that the macros that are supposed to be defined in <deque> are defined. +#if TEST_STD_VER > 17 +# if !defined(__cpp_lib_erase_if) + LIBCPP_STATIC_ASSERT(false, "__cpp_lib_erase_if is not defined"); +# else +# if __cpp_lib_erase_if < 201811L +# error "__cpp_lib_erase_if has an invalid value" +# endif +# endif +#endif + /* #if !defined(__cpp_lib_fooby) # error "__cpp_lib_fooby is not defined" diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/forward_list.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/forward_list.version.pass.cpp index 73c8462ca3f..9b44f6e2c46 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/forward_list.version.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/forward_list.version.pass.cpp @@ -12,6 +12,7 @@ /* Constant Value __cpp_lib_allocator_traits_is_always_equal 201411L + __cpp_lib_erase_if 201811L __cpp_lib_incomplete_container_elements 201505L __cpp_lib_list_remove_return_type 201806L __cpp_lib_nonmember_container_access 201411L @@ -26,6 +27,16 @@ int main() { // ensure that the macros that are supposed to be defined in <forward_list> are defined. +#if TEST_STD_VER > 17 +# if !defined(__cpp_lib_erase_if) + LIBCPP_STATIC_ASSERT(false, "__cpp_lib_erase_if is not defined"); +# else +# if __cpp_lib_erase_if < 201811L +# error "__cpp_lib_erase_if has an invalid value" +# endif +# endif +#endif + /* #if !defined(__cpp_lib_fooby) # error "__cpp_lib_fooby is not defined" diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/list.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/list.version.pass.cpp index 3db7995633f..e6e65655b92 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/list.version.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/list.version.pass.cpp @@ -12,6 +12,7 @@ /* Constant Value __cpp_lib_allocator_traits_is_always_equal 201411L + __cpp_lib_erase_if 201811L __cpp_lib_incomplete_container_elements 201505L __cpp_lib_list_remove_return_type 201806L __cpp_lib_nonmember_container_access 201411L @@ -26,6 +27,16 @@ int main() { // ensure that the macros that are supposed to be defined in <list> are defined. +#if TEST_STD_VER > 17 +# if !defined(__cpp_lib_erase_if) + LIBCPP_STATIC_ASSERT(false, "__cpp_lib_erase_if is not defined"); +# else +# if __cpp_lib_erase_if < 201811L +# error "__cpp_lib_erase_if has an invalid value" +# endif +# endif +#endif + /* #if !defined(__cpp_lib_fooby) # error "__cpp_lib_fooby is not defined" diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/map.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/map.version.pass.cpp index ffcc003e3a0..e7dbf7d20f0 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/map.version.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/map.version.pass.cpp @@ -12,6 +12,7 @@ /* Constant Value __cpp_lib_allocator_traits_is_always_equal 201411L + __cpp_lib_erase_if 201811L __cpp_lib_generic_associative_lookup 201304L __cpp_lib_map_try_emplace 201411L __cpp_lib_node_extract 201606L @@ -27,6 +28,16 @@ int main() { // ensure that the macros that are supposed to be defined in <map> are defined. +#if TEST_STD_VER > 17 +# if !defined(__cpp_lib_erase_if) + LIBCPP_STATIC_ASSERT(false, "__cpp_lib_erase_if is not defined"); +# else +# if __cpp_lib_erase_if < 201811L +# error "__cpp_lib_erase_if has an invalid value" +# endif +# endif +#endif + /* #if !defined(__cpp_lib_fooby) # error "__cpp_lib_fooby is not defined" diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/set.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/set.version.pass.cpp index 96918031d37..716eae6d9f0 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/set.version.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/set.version.pass.cpp @@ -12,6 +12,7 @@ /* Constant Value __cpp_lib_allocator_traits_is_always_equal 201411L + __cpp_lib_erase_if 201811L __cpp_lib_generic_associative_lookup 201304L __cpp_lib_node_extract 201606L __cpp_lib_nonmember_container_access 201411L @@ -26,6 +27,16 @@ int main() { // ensure that the macros that are supposed to be defined in <set> are defined. +#if TEST_STD_VER > 17 +# if !defined(__cpp_lib_erase_if) + LIBCPP_STATIC_ASSERT(false, "__cpp_lib_erase_if is not defined"); +# else +# if __cpp_lib_erase_if < 201811L +# error "__cpp_lib_erase_if has an invalid value" +# endif +# endif +#endif + /* #if !defined(__cpp_lib_fooby) # error "__cpp_lib_fooby is not defined" diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/string.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/string.version.pass.cpp index 2f408b9886e..87e8c8f96c3 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/string.version.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/string.version.pass.cpp @@ -12,6 +12,7 @@ /* Constant Value __cpp_lib_allocator_traits_is_always_equal 201411L + __cpp_lib_erase_if 201811L __cpp_lib_char8_t 201811L __cpp_lib_nonmember_container_access 201411L __cpp_lib_string_udls 201304L @@ -27,6 +28,16 @@ int main() { // ensure that the macros that are supposed to be defined in <string> are defined. +#if TEST_STD_VER > 17 +# if !defined(__cpp_lib_erase_if) + LIBCPP_STATIC_ASSERT(false, "__cpp_lib_erase_if is not defined"); +# else +# if __cpp_lib_erase_if < 201811L +# error "__cpp_lib_erase_if has an invalid value" +# endif +# endif +#endif + #if TEST_STD_VER > 17 && defined(__cpp_char8_t) # if !defined(__cpp_lib_char8_t) LIBCPP_STATIC_ASSERT(false, "__cpp_lib_char8_t is not defined"); diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/unordered_map.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/unordered_map.version.pass.cpp index 38e01171731..d23a91a3091 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/unordered_map.version.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/unordered_map.version.pass.cpp @@ -12,6 +12,7 @@ /* Constant Value __cpp_lib_allocator_traits_is_always_equal 201411L + __cpp_lib_erase_if 201811L __cpp_lib_node_extract 201606L __cpp_lib_nonmember_container_access 201411L __cpp_lib_unordered_map_try_emplace 201411L @@ -26,6 +27,17 @@ int main() { // ensure that the macros that are supposed to be defined in <unordered_map> are defined. +#if TEST_STD_VER > 17 +# if !defined(__cpp_lib_erase_if) + LIBCPP_STATIC_ASSERT(false, "__cpp_lib_erase_if is not defined"); +# else +# if __cpp_lib_erase_if < 201811L +# error "__cpp_lib_erase_if has an invalid value" +# endif +# endif +#endif + + /* #if !defined(__cpp_lib_fooby) # error "__cpp_lib_fooby is not defined" diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/unordered_set.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/unordered_set.version.pass.cpp index 762a07c372a..c4dbed14b9c 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/unordered_set.version.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/unordered_set.version.pass.cpp @@ -12,6 +12,7 @@ /* Constant Value __cpp_lib_allocator_traits_is_always_equal 201411L + __cpp_lib_erase_if 201811L __cpp_lib_node_extract 201606L __cpp_lib_nonmember_container_access 201411L @@ -25,6 +26,16 @@ int main() { // ensure that the macros that are supposed to be defined in <unordered_set> are defined. +#if TEST_STD_VER > 17 +# if !defined(__cpp_lib_erase_if) + LIBCPP_STATIC_ASSERT(false, "__cpp_lib_erase_if is not defined"); +# else +# if __cpp_lib_erase_if < 201811L +# error "__cpp_lib_erase_if has an invalid value" +# endif +# endif +#endif + /* #if !defined(__cpp_lib_fooby) # error "__cpp_lib_fooby is not defined" diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/vector.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/vector.version.pass.cpp index 9932a61c56d..e7cb1942c0b 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/vector.version.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/vector.version.pass.cpp @@ -12,6 +12,7 @@ /* Constant Value __cpp_lib_allocator_traits_is_always_equal 201411L + __cpp_lib_erase_if 201811L __cpp_lib_incomplete_container_elements 201505L __cpp_lib_nonmember_container_access 201411L @@ -25,6 +26,16 @@ int main() { // ensure that the macros that are supposed to be defined in <vector> are defined. +#if TEST_STD_VER > 17 +# if !defined(__cpp_lib_erase_if) + LIBCPP_STATIC_ASSERT(false, "__cpp_lib_erase_if is not defined"); +# else +# if __cpp_lib_erase_if < 201811L +# error "__cpp_lib_erase_if has an invalid value" +# endif +# endif +#endif + /* #if !defined(__cpp_lib_fooby) # error "__cpp_lib_fooby is not defined" diff --git a/libcxx/test/std/strings/strings.erasure/erase.pass.cpp b/libcxx/test/std/strings/strings.erasure/erase.pass.cpp new file mode 100644 index 00000000000..657a56c7315 --- /dev/null +++ b/libcxx/test/std/strings/strings.erasure/erase.pass.cpp @@ -0,0 +1,76 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// <string> + +// template <class charT, class traits, class Allocator, class U> +// void erase(basic_string<charT, traits, Allocator>& c, const U& value); + + +#include <string> +#include <optional> + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template <class S, class U> +void +test0(S s, U val, S expected) +{ + ASSERT_SAME_TYPE(void, decltype(std::erase(s, val))); + std::erase(s, val); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); +} + +template <class S> +void test() +{ + + test0(S(""), 'a', S("")); + + test0(S("a"), 'a', S("")); + test0(S("a"), 'b', S("a")); + + test0(S("ab"), 'a', S("b")); + test0(S("ab"), 'b', S("a")); + test0(S("ab"), 'c', S("ab")); + test0(S("aa"), 'a', S("")); + test0(S("aa"), 'c', S("aa")); + + test0(S("abc"), 'a', S("bc")); + test0(S("abc"), 'b', S("ac")); + test0(S("abc"), 'c', S("ab")); + test0(S("abc"), 'd', S("abc")); + + test0(S("aab"), 'a', S("b")); + test0(S("aab"), 'b', S("aa")); + test0(S("aab"), 'c', S("aab")); + test0(S("abb"), 'a', S("bb")); + test0(S("abb"), 'b', S("a")); + test0(S("abb"), 'c', S("abb")); + test0(S("aaa"), 'a', S("")); + test0(S("aaa"), 'b', S("aaa")); + +// Test cross-type erasure + using opt = std::optional<typename S::value_type>; + test0(S("aba"), opt(), S("aba")); + test0(S("aba"), opt('a'), S("b")); + test0(S("aba"), opt('b'), S("aa")); + test0(S("aba"), opt('c'), S("aba")); +} + +int main() +{ + test<std::string>(); + test<std::basic_string<char, std::char_traits<char>, min_allocator<char>>> (); + test<std::basic_string<char, std::char_traits<char>, test_allocator<char>>> (); +} diff --git a/libcxx/test/std/strings/strings.erasure/erase_if.pass.cpp b/libcxx/test/std/strings/strings.erasure/erase_if.pass.cpp new file mode 100644 index 00000000000..d7014868fd3 --- /dev/null +++ b/libcxx/test/std/strings/strings.erasure/erase_if.pass.cpp @@ -0,0 +1,76 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// <string> + +// template <class charT, class traits, class Allocator, class Predicate> +// void erase_if(basic_string<charT, traits, Allocator>& c, Predicate pred); + +#include <string> + +#include "test_macros.h" +#include "test_allocator.h" +#include "min_allocator.h" + +template <class S, class Pred> +void +test0(S s, Pred p, S expected) +{ + ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p))); + std::erase_if(s, p); + LIBCPP_ASSERT(s.__invariants()); + assert(s == expected); +} + +template <typename S> +void test() +{ + auto isA = [](auto ch) { return ch == 'a';}; + auto isB = [](auto ch) { return ch == 'b';}; + auto isC = [](auto ch) { return ch == 'c';}; + auto isD = [](auto ch) { return ch == 'd';}; + auto True = [](auto) { return true; }; + auto False = [](auto) { return false; }; + + test0(S(""), isA, S("")); + + test0(S("a"), isA, S("")); + test0(S("a"), isB, S("a")); + + test0(S("ab"), isA, S("b")); + test0(S("ab"), isB, S("a")); + test0(S("ab"), isC, S("ab")); + test0(S("aa"), isA, S("")); + test0(S("aa"), isC, S("aa")); + + test0(S("abc"), isA, S("bc")); + test0(S("abc"), isB, S("ac")); + test0(S("abc"), isC, S("ab")); + test0(S("abc"), isD, S("abc")); + + test0(S("aab"), isA, S("b")); + test0(S("aab"), isB, S("aa")); + test0(S("aab"), isC, S("aab")); + test0(S("abb"), isA, S("bb")); + test0(S("abb"), isB, S("a")); + test0(S("abb"), isC, S("abb")); + test0(S("aaa"), isA, S("")); + test0(S("aaa"), isB, S("aaa")); + + test0(S("aba"), False, S("aba")); + test0(S("aba"), True, S("")); +} + +int main() +{ + test<std::string>(); + test<std::basic_string<char, std::char_traits<char>, min_allocator<char>>> (); + test<std::basic_string<char, std::char_traits<char>, test_allocator<char>>> (); +} |