diff options
Diffstat (limited to 'test/std/containers/associative')
20 files changed, 960 insertions, 37 deletions
diff --git a/test/std/containers/associative/map/map.access/at.pass.cpp b/test/std/containers/associative/map/map.access/at.pass.cpp index 5822706fbfb33..76eda046c0df3 100644 --- a/test/std/containers/associative/map/map.access/at.pass.cpp +++ b/test/std/containers/associative/map/map.access/at.pass.cpp @@ -14,8 +14,9 @@ // mapped_type& at(const key_type& k); // const mapped_type& at(const key_type& k) const; -#include <map> #include <cassert> +#include <map> +#include <stdexcept> #include "min_allocator.h" #include "test_macros.h" diff --git a/test/std/containers/associative/map/map.access/index_key.pass.cpp b/test/std/containers/associative/map/map.access/index_key.pass.cpp index 3b1c21fd5da44..5f3d109d1ef77 100644 --- a/test/std/containers/associative/map/map.access/index_key.pass.cpp +++ b/test/std/containers/associative/map/map.access/index_key.pass.cpp @@ -84,7 +84,6 @@ int main() using Container = TCT::map<>; using Key = Container::key_type; using MappedType = Container::mapped_type; - using ValueTp = Container::value_type; ConstructController* cc = getConstructController(); cc->reset(); { diff --git a/test/std/containers/associative/map/map.access/index_rv_key.pass.cpp b/test/std/containers/associative/map/map.access/index_rv_key.pass.cpp index e5580bca3955d..bc91475c26b76 100644 --- a/test/std/containers/associative/map/map.access/index_rv_key.pass.cpp +++ b/test/std/containers/associative/map/map.access/index_rv_key.pass.cpp @@ -61,7 +61,6 @@ int main() using Container = TCT::map<>; using Key = Container::key_type; using MappedType = Container::mapped_type; - using ValueTp = Container::value_type; ConstructController* cc = getConstructController(); cc->reset(); { diff --git a/test/std/containers/associative/map/map.access/max_size.pass.cpp b/test/std/containers/associative/map/map.access/max_size.pass.cpp index 82a817a1f4ae3..9df3b074e40fe 100644 --- a/test/std/containers/associative/map/map.access/max_size.pass.cpp +++ b/test/std/containers/associative/map/map.access/max_size.pass.cpp @@ -34,18 +34,18 @@ int main() { typedef limited_allocator<KV, (size_t)-1> A; typedef std::map<int, int, std::less<int>, A> C; - const C::difference_type max_dist = - std::numeric_limits<C::difference_type>::max(); + const C::size_type max_dist = + static_cast<C::size_type>(std::numeric_limits<C::difference_type>::max()); C c; assert(c.max_size() <= max_dist); LIBCPP_ASSERT(c.max_size() == max_dist); - } - { - typedef std::map<char, int> C; - const C::difference_type max_dist = - std::numeric_limits<C::difference_type>::max(); - C c; - assert(c.max_size() <= max_dist); - assert(c.max_size() <= alloc_max_size(c.get_allocator())); - } + } + { + typedef std::map<char, int> C; + const C::size_type max_dist = + static_cast<C::size_type>(std::numeric_limits<C::difference_type>::max()); + C c; + assert(c.max_size() <= max_dist); + assert(c.max_size() <= alloc_max_size(c.get_allocator())); + } } diff --git a/test/std/containers/associative/map/map.erasure/erase_if.pass.cpp b/test/std/containers/associative/map/map.erasure/erase_if.pass.cpp new file mode 100644 index 0000000000000..f8cbc15d1645f --- /dev/null +++ b/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/test/std/containers/associative/map/map.modifiers/clear.pass.cpp b/test/std/containers/associative/map/map.modifiers/clear.pass.cpp index 1f36a6f10cb0b..ab4642fa88e68 100644 --- a/test/std/containers/associative/map/map.modifiers/clear.pass.cpp +++ b/test/std/containers/associative/map/map.modifiers/clear.pass.cpp @@ -11,11 +11,12 @@ // class map -// void clear(); +// void clear() noexcept; #include <map> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" int main() @@ -36,6 +37,7 @@ int main() }; M m(ar, ar + sizeof(ar)/sizeof(ar[0])); assert(m.size() == 8); + ASSERT_NOEXCEPT(m.clear()); m.clear(); assert(m.size() == 0); } @@ -56,6 +58,7 @@ int main() }; M m(ar, ar + sizeof(ar)/sizeof(ar[0])); assert(m.size() == 8); + ASSERT_NOEXCEPT(m.clear()); m.clear(); assert(m.size() == 0); } diff --git a/test/std/containers/associative/map/map.modifiers/merge.pass.cpp b/test/std/containers/associative/map/map.modifiers/merge.pass.cpp new file mode 100644 index 0000000000000..bb75e1d602938 --- /dev/null +++ b/test/std/containers/associative/map/map.modifiers/merge.pass.cpp @@ -0,0 +1,150 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <map> + +// class map + +// template <class C2> +// void merge(map<key_type, value_type, C2, allocator_type>& source); +// template <class C2> +// void merge(map<key_type, value_type, C2, allocator_type>&& source); +// template <class C2> +// void merge(multimap<key_type, value_type, C2, allocator_type>& source); +// template <class C2> +// void merge(multimap<key_type, value_type, C2, allocator_type>&& source); + +#include <map> +#include <cassert> +#include "test_macros.h" +#include "Counter.h" + +template <class Map> +bool map_equal(const Map& map, Map other) +{ + return map == other; +} + +#ifndef TEST_HAS_NO_EXCEPTIONS +struct throw_comparator +{ + bool& should_throw_; + + throw_comparator(bool& should_throw) : should_throw_(should_throw) {} + + template <class T> + bool operator()(const T& lhs, const T& rhs) const + { + if (should_throw_) + throw 0; + return lhs < rhs; + } +}; +#endif + +int main() +{ + { + std::map<int, int> src{{1, 0}, {3, 0}, {5, 0}}; + std::map<int, int> dst{{2, 0}, {4, 0}, {5, 0}}; + dst.merge(src); + assert(map_equal(src, {{5,0}})); + assert(map_equal(dst, {{1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}})); + } + +#ifndef TEST_HAS_NO_EXCEPTIONS + { + bool do_throw = false; + typedef std::map<Counter<int>, int, throw_comparator> map_type; + map_type src({{1, 0}, {3, 0}, {5, 0}}, throw_comparator(do_throw)); + map_type dst({{2, 0}, {4, 0}, {5, 0}}, throw_comparator(do_throw)); + + assert(Counter_base::gConstructed == 6); + + do_throw = true; + try + { + dst.merge(src); + } + catch (int) + { + do_throw = false; + } + assert(!do_throw); + assert(map_equal(src, map_type({{1, 0}, {3, 0}, {5, 0}}, throw_comparator(do_throw)))); + assert(map_equal(dst, map_type({{2, 0}, {4, 0}, {5, 0}}, throw_comparator(do_throw)))); + } +#endif + assert(Counter_base::gConstructed == 0); + struct comparator + { + comparator() = default; + + bool operator()(const Counter<int>& lhs, const Counter<int>& rhs) const + { + return lhs < rhs; + } + }; + { + typedef std::map<Counter<int>, int, std::less<Counter<int>>> first_map_type; + typedef std::map<Counter<int>, int, comparator> second_map_type; + typedef std::multimap<Counter<int>, int, comparator> third_map_type; + + { + first_map_type first{{1, 0}, {2, 0}, {3, 0}}; + second_map_type second{{2, 0}, {3, 0}, {4, 0}}; + third_map_type third{{1, 0}, {3, 0}}; + + assert(Counter_base::gConstructed == 8); + + first.merge(second); + first.merge(third); + + assert(map_equal(first, {{1, 0}, {2, 0}, {3, 0}, {4, 0}})); + assert(map_equal(second, {{2, 0}, {3, 0}})); + assert(map_equal(third, {{1, 0}, {3, 0}})); + + assert(Counter_base::gConstructed == 8); + } + assert(Counter_base::gConstructed == 0); + { + first_map_type first{{1, 0}, {2, 0}, {3, 0}}; + second_map_type second{{2, 0}, {3, 0}, {4, 0}}; + third_map_type third{{1, 0}, {3, 0}}; + + assert(Counter_base::gConstructed == 8); + + first.merge(std::move(second)); + first.merge(std::move(third)); + + assert(map_equal(first, {{1, 0}, {2, 0}, {3, 0}, {4, 0}})); + assert(map_equal(second, {{2, 0}, {3, 0}})); + assert(map_equal(third, {{1, 0}, {3, 0}})); + + assert(Counter_base::gConstructed == 8); + } + assert(Counter_base::gConstructed == 0); + } + assert(Counter_base::gConstructed == 0); + { + std::map<int, int> first; + { + std::map<int, int> second; + first.merge(second); + first.merge(std::move(second)); + } + { + std::multimap<int, int> second; + first.merge(second); + first.merge(std::move(second)); + } + } +} diff --git a/test/std/containers/associative/multimap/max_size.pass.cpp b/test/std/containers/associative/multimap/max_size.pass.cpp index 8d5ec1148a222..c836a182356f3 100644 --- a/test/std/containers/associative/multimap/max_size.pass.cpp +++ b/test/std/containers/associative/multimap/max_size.pass.cpp @@ -34,18 +34,18 @@ int main() { typedef limited_allocator<KV, (size_t)-1> A; typedef std::multimap<int, int, std::less<int>, A> C; - const C::difference_type max_dist = - std::numeric_limits<C::difference_type>::max(); + const C::size_type max_dist = + static_cast<C::size_type>(std::numeric_limits<C::difference_type>::max()); C c; assert(c.max_size() <= max_dist); LIBCPP_ASSERT(c.max_size() == max_dist); - } - { - typedef std::multimap<char, int> C; - const C::difference_type max_dist = - std::numeric_limits<C::difference_type>::max(); - C c; - assert(c.max_size() <= max_dist); - assert(c.max_size() <= alloc_max_size(c.get_allocator())); - } + } + { + typedef std::multimap<char, int> C; + const C::size_type max_dist = + static_cast<C::size_type>(std::numeric_limits<C::difference_type>::max()); + C c; + assert(c.max_size() <= max_dist); + assert(c.max_size() <= alloc_max_size(c.get_allocator())); + } } diff --git a/test/std/containers/associative/multimap/multimap.erasure/erase_if.pass.cpp b/test/std/containers/associative/multimap/multimap.erasure/erase_if.pass.cpp new file mode 100644 index 0000000000000..8e786fdc94761 --- /dev/null +++ b/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/test/std/containers/associative/multimap/multimap.modifiers/clear.pass.cpp b/test/std/containers/associative/multimap/multimap.modifiers/clear.pass.cpp index 321f4d0bd000c..546a406fe1bf6 100644 --- a/test/std/containers/associative/multimap/multimap.modifiers/clear.pass.cpp +++ b/test/std/containers/associative/multimap/multimap.modifiers/clear.pass.cpp @@ -11,11 +11,12 @@ // class multimap -// void clear(); +// void clear() noexcept; #include <map> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" int main() @@ -36,6 +37,7 @@ int main() }; M m(ar, ar + sizeof(ar)/sizeof(ar[0])); assert(m.size() == 8); + ASSERT_NOEXCEPT(m.clear()); m.clear(); assert(m.size() == 0); } @@ -56,6 +58,7 @@ int main() }; M m(ar, ar + sizeof(ar)/sizeof(ar[0])); assert(m.size() == 8); + ASSERT_NOEXCEPT(m.clear()); m.clear(); assert(m.size() == 0); } diff --git a/test/std/containers/associative/multimap/multimap.modifiers/merge.pass.cpp b/test/std/containers/associative/multimap/multimap.modifiers/merge.pass.cpp new file mode 100644 index 0000000000000..f0e38c255b8e2 --- /dev/null +++ b/test/std/containers/associative/multimap/multimap.modifiers/merge.pass.cpp @@ -0,0 +1,150 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <map> + +// class multimap + +// template <class C2> +// void merge(map<key_type, value_type, C2, allocator_type>& source); +// template <class C2> +// void merge(map<key_type, value_type, C2, allocator_type>&& source); +// template <class C2> +// void merge(multimap<key_type, value_type, C2, allocator_type>& source); +// template <class C2> +// void merge(multimap<key_type, value_type, C2, allocator_type>&& source); + +#include <map> +#include <cassert> +#include "test_macros.h" +#include "Counter.h" + +template <class Map> +bool map_equal(const Map& map, Map other) +{ + return map == other; +} + +#ifndef TEST_HAS_NO_EXCEPTIONS +struct throw_comparator +{ + bool& should_throw_; + + throw_comparator(bool& should_throw) : should_throw_(should_throw) {} + + template <class T> + bool operator()(const T& lhs, const T& rhs) const + { + if (should_throw_) + throw 0; + return lhs < rhs; + } +}; +#endif + +int main() +{ + { + std::multimap<int, int> src{{1, 0}, {3, 0}, {5, 0}}; + std::multimap<int, int> dst{{2, 0}, {4, 0}, {5, 0}}; + dst.merge(src); + assert(map_equal(src, {})); + assert(map_equal(dst, {{1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}, {5, 0}})); + } + +#ifndef TEST_HAS_NO_EXCEPTIONS + { + bool do_throw = false; + typedef std::multimap<Counter<int>, int, throw_comparator> map_type; + map_type src({{1, 0}, {3, 0}, {5, 0}}, throw_comparator(do_throw)); + map_type dst({{2, 0}, {4, 0}, {5, 0}}, throw_comparator(do_throw)); + + assert(Counter_base::gConstructed == 6); + + do_throw = true; + try + { + dst.merge(src); + } + catch (int) + { + do_throw = false; + } + assert(!do_throw); + assert(map_equal(src, map_type({{1, 0}, {3, 0}, {5, 0}}, throw_comparator(do_throw)))); + assert(map_equal(dst, map_type({{2, 0}, {4, 0}, {5, 0}}, throw_comparator(do_throw)))); + } +#endif + assert(Counter_base::gConstructed == 0); + struct comparator + { + comparator() = default; + + bool operator()(const Counter<int>& lhs, const Counter<int>& rhs) const + { + return lhs < rhs; + } + }; + { + typedef std::multimap<Counter<int>, int, std::less<Counter<int>>> first_map_type; + typedef std::multimap<Counter<int>, int, comparator> second_map_type; + typedef std::map<Counter<int>, int, comparator> third_map_type; + + { + first_map_type first{{1, 0}, {2, 0}, {3, 0}}; + second_map_type second{{2, 0}, {3, 0}, {4, 0}}; + third_map_type third{{1, 0}, {3, 0}}; + + assert(Counter_base::gConstructed == 8); + + first.merge(second); + first.merge(third); + + assert(map_equal(first, {{1, 0}, {1, 0}, {2, 0}, {2, 0}, {3, 0}, {3, 0}, {3, 0}, {4, 0}})); + assert(map_equal(second, {})); + assert(map_equal(third, {})); + + assert(Counter_base::gConstructed == 8); + } + assert(Counter_base::gConstructed == 0); + { + first_map_type first{{1, 0}, {2, 0}, {3, 0}}; + second_map_type second{{2, 0}, {3, 0}, {4, 0}}; + third_map_type third{{1, 0}, {3, 0}}; + + assert(Counter_base::gConstructed == 8); + + first.merge(std::move(second)); + first.merge(std::move(third)); + + assert(map_equal(first, {{1, 0}, {1, 0}, {2, 0}, {2, 0}, {3, 0}, {3, 0}, {3, 0}, {4, 0}})); + assert(map_equal(second, {})); + assert(map_equal(third, {})); + + assert(Counter_base::gConstructed == 8); + } + assert(Counter_base::gConstructed == 0); + } + assert(Counter_base::gConstructed == 0); + { + std::multimap<int, int> first; + { + std::multimap<int, int> second; + first.merge(second); + first.merge(std::move(second)); + } + { + std::multimap<int, int> second; + first.merge(second); + first.merge(std::move(second)); + } + } +} diff --git a/test/std/containers/associative/multiset/clear.pass.cpp b/test/std/containers/associative/multiset/clear.pass.cpp index f762ef7d35044..59ee02ece1d20 100644 --- a/test/std/containers/associative/multiset/clear.pass.cpp +++ b/test/std/containers/associative/multiset/clear.pass.cpp @@ -11,11 +11,12 @@ // class multiset -// void clear(); +// void clear() noexcept; #include <set> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" int main() @@ -36,6 +37,7 @@ int main() }; M m(ar, ar + sizeof(ar)/sizeof(ar[0])); assert(m.size() == 8); + ASSERT_NOEXCEPT(m.clear()); m.clear(); assert(m.size() == 0); } @@ -56,6 +58,7 @@ int main() }; M m(ar, ar + sizeof(ar)/sizeof(ar[0])); assert(m.size() == 8); + ASSERT_NOEXCEPT(m.clear()); m.clear(); assert(m.size() == 0); } diff --git a/test/std/containers/associative/multiset/insert_allocator_requirements.pass.cpp b/test/std/containers/associative/multiset/insert_emplace_allocator_requirements.pass.cpp index a280d10d5ab21..4bd2c88f8a357 100644 --- a/test/std/containers/associative/multiset/insert_allocator_requirements.pass.cpp +++ b/test/std/containers/associative/multiset/insert_emplace_allocator_requirements.pass.cpp @@ -23,4 +23,5 @@ int main() { testMultisetInsert<TCT::multiset<> >(); + testMultisetEmplace<TCT::multiset<> >(); } diff --git a/test/std/containers/associative/multiset/max_size.pass.cpp b/test/std/containers/associative/multiset/max_size.pass.cpp index 8ca34ba827393..8c5b15e39c11a 100644 --- a/test/std/containers/associative/multiset/max_size.pass.cpp +++ b/test/std/containers/associative/multiset/max_size.pass.cpp @@ -33,16 +33,16 @@ int main() { typedef limited_allocator<int, (size_t)-1> A; typedef std::multiset<int, std::less<int>, A> C; - const C::difference_type max_dist = - std::numeric_limits<C::difference_type>::max(); + const C::size_type max_dist = + static_cast<C::size_type>(std::numeric_limits<C::difference_type>::max()); C c; assert(c.max_size() <= max_dist); LIBCPP_ASSERT(c.max_size() == max_dist); } { typedef std::multiset<char> C; - const C::difference_type max_dist = - std::numeric_limits<C::difference_type>::max(); + const C::size_type max_dist = + static_cast<C::size_type>(std::numeric_limits<C::difference_type>::max()); C c; assert(c.max_size() <= max_dist); assert(c.max_size() <= alloc_max_size(c.get_allocator())); diff --git a/test/std/containers/associative/multiset/merge.pass.cpp b/test/std/containers/associative/multiset/merge.pass.cpp new file mode 100644 index 0000000000000..8ab992889e41e --- /dev/null +++ b/test/std/containers/associative/multiset/merge.pass.cpp @@ -0,0 +1,149 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <set> + +// class multiset + +// template <class C2> +// void merge(set<Key, C2, Allocator>& source); +// template <class C2> +// void merge(set<Key, C2, Allocator>&& source); +// template <class C2> +// void merge(multiset<Key, C2, Allocator>& source); +// template <class C2> +// void merge(multiset<Key, C2, Allocator>&& source); + +#include <set> +#include <cassert> +#include "test_macros.h" +#include "Counter.h" + +template <class Set> +bool set_equal(const Set& set, Set other) +{ + return set == other; +} + +#ifndef TEST_HAS_NO_EXCEPTIONS +struct throw_comparator +{ + bool& should_throw_; + + throw_comparator(bool& should_throw) : should_throw_(should_throw) {} + + template <class T> + bool operator()(const T& lhs, const T& rhs) const + { + if (should_throw_) + throw 0; + return lhs < rhs; + } +}; +#endif + +int main() +{ + { + std::multiset<int> src{1, 3, 5}; + std::multiset<int> dst{2, 4, 5}; + dst.merge(src); + assert(set_equal(src, {})); + assert(set_equal(dst, {1, 2, 3, 4, 5, 5})); + } + +#ifndef TEST_HAS_NO_EXCEPTIONS + { + bool do_throw = false; + typedef std::multiset<Counter<int>, throw_comparator> set_type; + set_type src({1, 3, 5}, throw_comparator(do_throw)); + set_type dst({2, 4, 5}, throw_comparator(do_throw)); + + assert(Counter_base::gConstructed == 6); + + do_throw = true; + try + { + dst.merge(src); + } + catch (int) + { + do_throw = false; + } + assert(!do_throw); + assert(set_equal(src, set_type({1, 3, 5}, throw_comparator(do_throw)))); + assert(set_equal(dst, set_type({2, 4, 5}, throw_comparator(do_throw)))); + } +#endif + assert(Counter_base::gConstructed == 0); + struct comparator + { + comparator() = default; + + bool operator()(const Counter<int>& lhs, const Counter<int>& rhs) const + { + return lhs < rhs; + } + }; + { + typedef std::multiset<Counter<int>, std::less<Counter<int>>> first_set_type; + typedef std::multiset<Counter<int>, comparator> second_set_type; + typedef std::set<Counter<int>, comparator> third_set_type; + + { + first_set_type first{1, 2, 3}; + second_set_type second{2, 3, 4}; + third_set_type third{1, 3}; + + assert(Counter_base::gConstructed == 8); + + first.merge(second); + first.merge(third); + + assert(set_equal(first, {1, 1, 2, 2, 3, 3, 3, 4})); + assert(set_equal(second, {})); + assert(set_equal(third, {})); + + assert(Counter_base::gConstructed == 8); + } + assert(Counter_base::gConstructed == 0); + { + first_set_type first{1, 2, 3}; + second_set_type second{2, 3, 4}; + third_set_type third{1, 3}; + + assert(Counter_base::gConstructed == 8); + + first.merge(std::move(second)); + first.merge(std::move(third)); + + assert(set_equal(first, {1, 1, 2, 2, 3, 3, 3, 4})); + assert(set_equal(second, {})); + assert(set_equal(third, {})); + + assert(Counter_base::gConstructed == 8); + } + assert(Counter_base::gConstructed == 0); + } + { + std::multiset<int> first; + { + std::multiset<int> second; + first.merge(second); + first.merge(std::move(second)); + } + { + std::set<int> second; + first.merge(second); + first.merge(std::move(second)); + } + } +} diff --git a/test/std/containers/associative/multiset/multiset.erasure/erase_if.pass.cpp b/test/std/containers/associative/multiset/multiset.erasure/erase_if.pass.cpp new file mode 100644 index 0000000000000..3c619bb687f4d --- /dev/null +++ b/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/test/std/containers/associative/set/clear.pass.cpp b/test/std/containers/associative/set/clear.pass.cpp index 7a5bf4b14a71a..1be3ed2b88773 100644 --- a/test/std/containers/associative/set/clear.pass.cpp +++ b/test/std/containers/associative/set/clear.pass.cpp @@ -11,11 +11,12 @@ // class set -// void clear(); +// void clear() noexcept; #include <set> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" int main() @@ -36,6 +37,7 @@ int main() }; M m(ar, ar + sizeof(ar)/sizeof(ar[0])); assert(m.size() == 8); + ASSERT_NOEXCEPT(m.clear()); m.clear(); assert(m.size() == 0); } @@ -56,6 +58,7 @@ int main() }; M m(ar, ar + sizeof(ar)/sizeof(ar[0])); assert(m.size() == 8); + ASSERT_NOEXCEPT(m.clear()); m.clear(); assert(m.size() == 0); } diff --git a/test/std/containers/associative/set/max_size.pass.cpp b/test/std/containers/associative/set/max_size.pass.cpp index c894eb51b1ee6..8be84046e1ac4 100644 --- a/test/std/containers/associative/set/max_size.pass.cpp +++ b/test/std/containers/associative/set/max_size.pass.cpp @@ -33,16 +33,16 @@ int main() { typedef limited_allocator<int, (size_t)-1> A; typedef std::set<int, std::less<int>, A> C; - const C::difference_type max_dist = - std::numeric_limits<C::difference_type>::max(); + const C::size_type max_dist = + static_cast<C::size_type>(std::numeric_limits<C::difference_type>::max()); C c; assert(c.max_size() <= max_dist); LIBCPP_ASSERT(c.max_size() == max_dist); } { typedef std::set<char> C; - const C::difference_type max_dist = - std::numeric_limits<C::difference_type>::max(); + const C::size_type max_dist = + static_cast<C::size_type>(std::numeric_limits<C::difference_type>::max()); C c; assert(c.max_size() <= max_dist); assert(c.max_size() <= alloc_max_size(c.get_allocator())); diff --git a/test/std/containers/associative/set/merge.pass.cpp b/test/std/containers/associative/set/merge.pass.cpp new file mode 100644 index 0000000000000..bbae22c77ea53 --- /dev/null +++ b/test/std/containers/associative/set/merge.pass.cpp @@ -0,0 +1,149 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <set> + +// class set + +// template <class C2> +// void merge(set<key_type, C2, allocator_type>& source); +// template <class C2> +// void merge(set<key_type, C2, allocator_type>&& source); +// template <class C2> +// void merge(multiset<key_type, C2, allocator_type>& source); +// template <class C2> +// void merge(multiset<key_type, C2, allocator_type>&& source); + +#include <set> +#include <cassert> +#include "test_macros.h" +#include "Counter.h" + +template <class Set> +bool set_equal(const Set& set, Set other) +{ + return set == other; +} + +#ifndef TEST_HAS_NO_EXCEPTIONS +struct throw_comparator +{ + bool& should_throw_; + + throw_comparator(bool& should_throw) : should_throw_(should_throw) {} + + template <class T> + bool operator()(const T& lhs, const T& rhs) const + { + if (should_throw_) + throw 0; + return lhs < rhs; + } +}; +#endif + +int main() +{ + { + std::set<int> src{1, 3, 5}; + std::set<int> dst{2, 4, 5}; + dst.merge(src); + assert(set_equal(src, {5})); + assert(set_equal(dst, {1, 2, 3, 4, 5})); + } + +#ifndef TEST_HAS_NO_EXCEPTIONS + { + bool do_throw = false; + typedef std::set<Counter<int>, throw_comparator> set_type; + set_type src({1, 3, 5}, throw_comparator(do_throw)); + set_type dst({2, 4, 5}, throw_comparator(do_throw)); + + assert(Counter_base::gConstructed == 6); + + do_throw = true; + try + { + dst.merge(src); + } + catch (int) + { + do_throw = false; + } + assert(!do_throw); + assert(set_equal(src, set_type({1, 3, 5}, throw_comparator(do_throw)))); + assert(set_equal(dst, set_type({2, 4, 5}, throw_comparator(do_throw)))); + } +#endif + assert(Counter_base::gConstructed == 0); + struct comparator + { + comparator() = default; + + bool operator()(const Counter<int>& lhs, const Counter<int>& rhs) const + { + return lhs < rhs; + } + }; + { + typedef std::set<Counter<int>, std::less<Counter<int>>> first_set_type; + typedef std::set<Counter<int>, comparator> second_set_type; + typedef std::multiset<Counter<int>, comparator> third_set_type; + + { + first_set_type first{1, 2, 3}; + second_set_type second{2, 3, 4}; + third_set_type third{1, 3}; + + assert(Counter_base::gConstructed == 8); + + first.merge(second); + first.merge(third); + + assert(set_equal(first, {1, 2, 3, 4})); + assert(set_equal(second, {2, 3})); + assert(set_equal(third, {1, 3})); + + assert(Counter_base::gConstructed == 8); + } + assert(Counter_base::gConstructed == 0); + { + first_set_type first{1, 2, 3}; + second_set_type second{2, 3, 4}; + third_set_type third{1, 3}; + + assert(Counter_base::gConstructed == 8); + + first.merge(std::move(second)); + first.merge(std::move(third)); + + assert(set_equal(first, {1, 2, 3, 4})); + assert(set_equal(second, {2, 3})); + assert(set_equal(third, {1, 3})); + + assert(Counter_base::gConstructed == 8); + } + assert(Counter_base::gConstructed == 0); + } + { + std::set<int> first; + { + std::set<int> second; + first.merge(second); + first.merge(std::move(second)); + } + { + std::multiset<int> second; + first.merge(second); + first.merge(std::move(second)); + } + } +} diff --git a/test/std/containers/associative/set/set.erasure/erase_if.pass.cpp b/test/std/containers/associative/set/set.erasure/erase_if.pass.cpp new file mode 100644 index 0000000000000..a55a38c2d5683 --- /dev/null +++ b/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>>(); +} |
