diff options
| author | Erik Pilkington <erik.pilkington@gmail.com> | 2018-10-31 17:31:35 +0000 |
|---|---|---|
| committer | Erik Pilkington <erik.pilkington@gmail.com> | 2018-10-31 17:31:35 +0000 |
| commit | 5c4e07ae5c6f7f467b436f1b24f41ef4cf9897b3 (patch) | |
| tree | 69a408ee04a99d007a9471160c16bea24433d296 /libcxx/test | |
| parent | 3b39040ad44d921e1b273fe3bbfeeaa280d0cb8f (diff) | |
| download | bcm5719-llvm-5c4e07ae5c6f7f467b436f1b24f41ef4cf9897b3.tar.gz bcm5719-llvm-5c4e07ae5c6f7f467b436f1b24f41ef4cf9897b3.zip | |
Second half of C++17's splicing maps and sets
This commit adds a merge member function to all the map and set containers,
which splices nodes from the source container. This completes support for
P0083r3.
Differential revision: https://reviews.llvm.org/D48896
llvm-svn: 345744
Diffstat (limited to 'libcxx/test')
8 files changed, 1232 insertions, 0 deletions
diff --git a/libcxx/test/std/containers/associative/map/map.modifiers/merge.pass.cpp b/libcxx/test/std/containers/associative/map/map.modifiers/merge.pass.cpp new file mode 100644 index 00000000000..4fef2425a39 --- /dev/null +++ b/libcxx/test/std/containers/associative/map/map.modifiers/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 + +// <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 "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/libcxx/test/std/containers/associative/multimap/multimap.modifiers/merge.pass.cpp b/libcxx/test/std/containers/associative/multimap/multimap.modifiers/merge.pass.cpp new file mode 100644 index 00000000000..71f3c0b393b --- /dev/null +++ b/libcxx/test/std/containers/associative/multimap/multimap.modifiers/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 + +// <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 "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/libcxx/test/std/containers/associative/multiset/merge.pass.cpp b/libcxx/test/std/containers/associative/multiset/merge.pass.cpp new file mode 100644 index 00000000000..516e27de3a0 --- /dev/null +++ b/libcxx/test/std/containers/associative/multiset/merge.pass.cpp @@ -0,0 +1,148 @@ +//===----------------------------------------------------------------------===// +// +// 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 "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/libcxx/test/std/containers/associative/set/merge.pass.cpp b/libcxx/test/std/containers/associative/set/merge.pass.cpp new file mode 100644 index 00000000000..0896596d94f --- /dev/null +++ b/libcxx/test/std/containers/associative/set/merge.pass.cpp @@ -0,0 +1,148 @@ +//===----------------------------------------------------------------------===// +// +// 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 "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/libcxx/test/std/containers/unord/unord.map/unord.map.modifiers/merge.pass.cpp b/libcxx/test/std/containers/unord/unord.map/unord.map.modifiers/merge.pass.cpp new file mode 100644 index 00000000000..d525b1addfb --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.map/unord.map.modifiers/merge.pass.cpp @@ -0,0 +1,161 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <unordered_map> + +// class unordered_map + +// template <class H2, class P2> +// void merge(unordered_map<key_type, value_type, H2, P2, allocator_type>& source); +// template <class H2, class P2> +// void merge(unordered_map<key_type, value_type, H2, P2, allocator_type>&& source); +// template <class H2, class P2> +// void merge(unordered_multimap<key_type, value_type, H2, P2, allocator_type>& source); +// template <class H2, class P2> +// void merge(unordered_multimap<key_type, value_type, H2, P2, allocator_type>&& source); + +#include <unordered_map> +#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 +template <class T> +struct throw_hasher +{ + bool& should_throw_; + + throw_hasher(bool& should_throw) : should_throw_(should_throw) {} + + typedef size_t result_type; + typedef T argument_type; + + size_t operator()(const T& p) const + { + if (should_throw_) + throw 0; + return std::hash<T>()(p); + } +}; +#endif + +int main() +{ + { + std::unordered_map<int, int> src{{1, 0}, {3, 0}, {5, 0}}; + std::unordered_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::unordered_map<Counter<int>, int, throw_hasher<Counter<int>>> map_type; + map_type src({{1, 0}, {3, 0}, {5, 0}}, 0, throw_hasher<Counter<int>>(do_throw)); + map_type dst({{2, 0}, {4, 0}, {5, 0}}, 0, throw_hasher<Counter<int>>(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}}, 0, throw_hasher<Counter<int>>(do_throw)))); + assert(map_equal(dst, map_type({{2, 0}, {4, 0}, {5, 0}}, 0, throw_hasher<Counter<int>>(do_throw)))); + } +#endif + assert(Counter_base::gConstructed == 0); + struct equal + { + equal() = default; + + bool operator()(const Counter<int>& lhs, const Counter<int>& rhs) const + { + return lhs == rhs; + } + }; + struct hasher + { + hasher() = default; + typedef Counter<int> argument_type; + typedef size_t result_type; + size_t operator()(const Counter<int>& p) const + { + return std::hash<Counter<int>>()(p); + } + }; + { + typedef std::unordered_map<Counter<int>, int, std::hash<Counter<int>>, std::equal_to<Counter<int>>> first_map_type; + typedef std::unordered_map<Counter<int>, int, hasher, equal> second_map_type; + typedef std::unordered_multimap<Counter<int>, int, hasher, equal> 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); + } + { + std::unordered_map<int, int> first; + { + std::unordered_map<int, int> second; + first.merge(second); + first.merge(std::move(second)); + } + { + std::unordered_multimap<int, int> second; + first.merge(second); + first.merge(std::move(second)); + } + } +} diff --git a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/merge.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/merge.pass.cpp new file mode 100644 index 00000000000..d018620947b --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/merge.pass.cpp @@ -0,0 +1,161 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <unordered_map> + +// class unordered_multimap + +// template <class H2, class P2> +// void merge(unordered_map<key_type, value_type, H2, P2, allocator_type>& source); +// template <class H2, class P2> +// void merge(unordered_map<key_type, value_type, H2, P2, allocator_type>&& source); +// template <class H2, class P2> +// void merge(unordered_multimap<key_type, value_type, H2, P2, allocator_type>& source); +// template <class H2, class P2> +// void merge(unordered_multimap<key_type, value_type, H2, P2, allocator_type>&& source); + +#include <unordered_map> +#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 +template <class T> +struct throw_hasher +{ + bool& should_throw_; + + throw_hasher(bool& should_throw) : should_throw_(should_throw) {} + + typedef size_t result_type; + typedef T argument_type; + + size_t operator()(const T& p) const + { + if (should_throw_) + throw 0; + return std::hash<T>()(p); + } +}; +#endif + +int main() +{ + { + std::unordered_multimap<int, int> src{{1, 0}, {3, 0}, {5, 0}}; + std::unordered_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::unordered_multimap<Counter<int>, int, throw_hasher<Counter<int>>> map_type; + map_type src({{1, 0}, {3, 0}, {5, 0}}, 0, throw_hasher<Counter<int>>(do_throw)); + map_type dst({{2, 0}, {4, 0}, {5, 0}}, 0, throw_hasher<Counter<int>>(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}}, 0, throw_hasher<Counter<int>>(do_throw)))); + assert(map_equal(dst, map_type({{2, 0}, {4, 0}, {5, 0}}, 0, throw_hasher<Counter<int>>(do_throw)))); + } +#endif + assert(Counter_base::gConstructed == 0); + struct equal + { + equal() = default; + + bool operator()(const Counter<int>& lhs, const Counter<int>& rhs) const + { + return lhs == rhs; + } + }; + struct hasher + { + hasher() = default; + typedef Counter<int> argument_type; + typedef size_t result_type; + size_t operator()(const Counter<int>& p) const + { + return std::hash<Counter<int>>()(p); + } + }; + { + typedef std::unordered_multimap<Counter<int>, int, std::hash<Counter<int>>, std::equal_to<Counter<int>>> first_map_type; + typedef std::unordered_multimap<Counter<int>, int, hasher, equal> second_map_type; + typedef std::unordered_map<Counter<int>, int, hasher, equal> 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}, {2, 0}, {3, 0}, {1, 0}, {3, 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}, {2, 0}, {3, 0}, {4, 0}, {2, 0}, {3, 0}, {1, 0}, {3, 0}})); + assert(map_equal(second, {})); + assert(map_equal(third, {})); + + assert(Counter_base::gConstructed == 8); + } + assert(Counter_base::gConstructed == 0); + } + { + std::unordered_multimap<int, int> first; + { + std::unordered_multimap<int, int> second; + first.merge(second); + first.merge(std::move(second)); + } + { + std::unordered_map<int, int> second; + first.merge(second); + first.merge(std::move(second)); + } + } +} diff --git a/libcxx/test/std/containers/unord/unord.multiset/merge.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/merge.pass.cpp new file mode 100644 index 00000000000..0bf8d358f44 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.multiset/merge.pass.cpp @@ -0,0 +1,158 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <unordered_set> + +// class unordered_multiset + +// template <class H2, class P2> +// void merge(unordered_set<key_type, H2, P2, allocator_type>& source); +// template <class H2, class P2> +// void merge(unordered_set<key_type, H2, P2, allocator_type>&& source); +// template <class H2, class P2> +// void merge(unordered_multiset<key_type, H2, P2, allocator_type>& source); +// template <class H2, class P2> +// void merge(unordered_multiset<key_type, H2, P2, allocator_type>&& source); + +#include <unordered_set> +#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 +template <class T> +struct throw_hasher +{ + bool& should_throw_; + + throw_hasher(bool& should_throw) : should_throw_(should_throw) {} + + typedef size_t result_type; + typedef T argument_type; + + size_t operator()(const T& p) const + { + if (should_throw_) + throw 0; + return std::hash<T>()(p); + } +}; +#endif + +int main() +{ + { + std::unordered_multiset<int> src{1, 3, 5}; + std::unordered_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::unordered_multiset<Counter<int>, throw_hasher<Counter<int>>> set_type; + set_type src({1, 3, 5}, 0, throw_hasher<Counter<int>>(do_throw)); + set_type dst({2, 4, 5}, 0, throw_hasher<Counter<int>>(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}, 0, throw_hasher<Counter<int>>(do_throw)))); + assert(set_equal(dst, set_type({2, 4, 5}, 0, throw_hasher<Counter<int>>(do_throw)))); + } +#endif + assert(Counter_base::gConstructed == 0); + struct equal + { + equal() = default; + + bool operator()(const Counter<int>& lhs, const Counter<int>& rhs) const + { + return lhs == rhs; + } + }; + struct hasher + { + hasher() = default; + typedef Counter<int> argument_type; + typedef size_t result_type; + size_t operator()(const Counter<int>& p) const { return std::hash<Counter<int>>()(p); } + }; + { + typedef std::unordered_multiset<Counter<int>, std::hash<Counter<int>>, std::equal_to<Counter<int>>> first_set_type; + typedef std::unordered_multiset<Counter<int>, hasher, equal> second_set_type; + typedef std::unordered_set<Counter<int>, hasher, equal> 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, 2, 3, 1, 3})); + 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, 2, 3, 4, 2, 3, 1, 3})); + assert(set_equal(second, {})); + assert(set_equal(third, {})); + + assert(Counter_base::gConstructed == 8); + } + assert(Counter_base::gConstructed == 0); + } + { + std::unordered_multiset<int> first; + { + std::unordered_multiset<int> second; + first.merge(second); + first.merge(std::move(second)); + } + { + std::unordered_set<int> second; + first.merge(second); + first.merge(std::move(second)); + } + } +} diff --git a/libcxx/test/std/containers/unord/unord.set/merge.pass.cpp b/libcxx/test/std/containers/unord/unord.set/merge.pass.cpp new file mode 100644 index 00000000000..ebf03cd565a --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.set/merge.pass.cpp @@ -0,0 +1,158 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <unordered_set> + +// class unordered_set + +// template <class H2, class P2> +// void merge(unordered_set<key_type, H2, P2, allocator_type>& source); +// template <class H2, class P2> +// void merge(unordered_set<key_type, H2, P2, allocator_type>&& source); +// template <class H2, class P2> +// void merge(unordered_multiset<key_type, H2, P2, allocator_type>& source); +// template <class H2, class P2> +// void merge(unordered_multiset<key_type, H2, P2, allocator_type>&& source); + +#include <unordered_set> +#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 +template <class T> +struct throw_hasher +{ + bool& should_throw_; + + throw_hasher(bool& should_throw) : should_throw_(should_throw) {} + + typedef size_t result_type; + typedef T argument_type; + + size_t operator()(const T& p) const + { + if (should_throw_) + throw 0; + return std::hash<T>()(p); + } +}; +#endif + +int main() +{ + { + std::unordered_set<int> src{1, 3, 5}; + std::unordered_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::unordered_set<Counter<int>, throw_hasher<Counter<int>>> set_type; + set_type src({1, 3, 5}, 0, throw_hasher<Counter<int>>(do_throw)); + set_type dst({2, 4, 5}, 0, throw_hasher<Counter<int>>(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}, 0, throw_hasher<Counter<int>>(do_throw)))); + assert(set_equal(dst, set_type({2, 4, 5}, 0, throw_hasher<Counter<int>>(do_throw)))); + } +#endif + assert(Counter_base::gConstructed == 0); + struct equal + { + equal() = default; + + bool operator()(const Counter<int>& lhs, const Counter<int>& rhs) const + { + return lhs == rhs; + } + }; + struct hasher + { + hasher() = default; + typedef Counter<int> argument_type; + typedef size_t result_type; + size_t operator()(const Counter<int>& p) const { return std::hash<Counter<int>>()(p); } + }; + { + typedef std::unordered_set<Counter<int>, std::hash<Counter<int>>, std::equal_to<Counter<int>>> first_set_type; + typedef std::unordered_set<Counter<int>, hasher, equal> second_set_type; + typedef std::unordered_multiset<Counter<int>, hasher, equal> 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::unordered_set<int> first; + { + std::unordered_set<int> second; + first.merge(second); + first.merge(std::move(second)); + } + { + std::unordered_multiset<int> second; + first.merge(second); + first.merge(std::move(second)); + } + } +} |

