| //===----------------------------------------------------------------------===// |
| // |
| // 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. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| // <map> |
| |
| // class map |
| |
| // map& operator=(const map& m); |
| |
| #include <map> |
| #include <cassert> |
| #include <vector> |
| #include <algorithm> |
| #include <iterator> |
| |
| #include <iostream> |
| |
| #include "../../../test_compare.h" |
| #include "test_allocator.h" |
| #include "min_allocator.h" |
| |
| #if TEST_STD_VER >= 11 |
| std::vector<int> ca_allocs; |
| std::vector<int> ca_deallocs; |
| |
| template <class T> |
| class counting_allocatorT { |
| public: |
| typedef T value_type; |
| int foo{0}; |
| counting_allocatorT(int f) noexcept : foo(f) {} |
| |
| using propagate_on_container_copy_assignment = std::true_type; |
| template <class U> counting_allocatorT(const counting_allocatorT<U>& other) noexcept {foo = other.foo;} |
| template <class U> bool operator==(const counting_allocatorT<U>& other) const noexcept { return foo == other.foo; } |
| template <class U> bool operator!=(const counting_allocatorT<U>& other) const noexcept { return foo != other.foo; } |
| |
| T * allocate(const size_t n) const { |
| ca_allocs.push_back(foo); |
| void * const pv = ::malloc(n * sizeof(T)); |
| return static_cast<T *>(pv); |
| } |
| void deallocate(T * const p, size_t) const noexcept { |
| ca_deallocs.push_back(foo); |
| free(p); |
| } |
| }; |
| |
| template <class T> |
| class counting_allocatorF { |
| public: |
| typedef T value_type; |
| int foo{0}; |
| counting_allocatorF(int f) noexcept : foo(f) {} |
| |
| using propagate_on_container_copy_assignment = std::false_type; |
| template <class U> counting_allocatorF(const counting_allocatorF<U>& other) noexcept {foo = other.foo;} |
| template <class U> bool operator==(const counting_allocatorF<U>& other) const noexcept { return foo == other.foo; } |
| template <class U> bool operator!=(const counting_allocatorF<U>& other) const noexcept { return foo != other.foo; } |
| |
| T * allocate(const size_t n) const { |
| ca_allocs.push_back(foo); |
| void * const pv = ::malloc(n * sizeof(T)); |
| return static_cast<T *>(pv); |
| } |
| void deallocate(T * const p, size_t) const noexcept { |
| ca_deallocs.push_back(foo); |
| free(p); |
| } |
| }; |
| |
| bool balanced_allocs() { |
| std::vector<int> temp1, temp2; |
| |
| std::cout << "Allocations = " << ca_allocs.size() << ", deallocatons = " << ca_deallocs.size() << std::endl; |
| if (ca_allocs.size() != ca_deallocs.size()) |
| return false; |
| |
| temp1 = ca_allocs; |
| std::sort(temp1.begin(), temp1.end()); |
| temp2.clear(); |
| std::unique_copy(temp1.begin(), temp1.end(), std::back_inserter<std::vector<int>>(temp2)); |
| std::cout << "There were " << temp2.size() << " different allocators\n"; |
| |
| for (std::vector<int>::const_iterator it = temp2.begin(); it != temp2.end(); ++it ) { |
| std::cout << *it << ": " << std::count(ca_allocs.begin(), ca_allocs.end(), *it) << " vs " << std::count(ca_deallocs.begin(), ca_deallocs.end(), *it) << std::endl; |
| if ( std::count(ca_allocs.begin(), ca_allocs.end(), *it) != std::count(ca_deallocs.begin(), ca_deallocs.end(), *it)) |
| return false; |
| } |
| |
| temp1 = ca_allocs; |
| std::sort(temp1.begin(), temp1.end()); |
| temp2.clear(); |
| std::unique_copy(temp1.begin(), temp1.end(), std::back_inserter<std::vector<int>>(temp2)); |
| std::cout << "There were " << temp2.size() << " different (de)allocators\n"; |
| for (std::vector<int>::const_iterator it = ca_deallocs.begin(); it != ca_deallocs.end(); ++it ) { |
| std::cout << *it << ": " << std::count(ca_allocs.begin(), ca_allocs.end(), *it) << " vs " << std::count(ca_deallocs.begin(), ca_deallocs.end(), *it) << std::endl; |
| if ( std::count(ca_allocs.begin(), ca_allocs.end(), *it) != std::count(ca_deallocs.begin(), ca_deallocs.end(), *it)) |
| return false; |
| } |
| |
| return true; |
| } |
| #endif |
| |
| int main() |
| { |
| { |
| typedef std::pair<const int, double> V; |
| V ar[] = |
| { |
| V(1, 1), |
| V(1, 1.5), |
| V(1, 2), |
| V(2, 1), |
| V(2, 1.5), |
| V(2, 2), |
| V(3, 1), |
| V(3, 1.5), |
| V(3, 2) |
| }; |
| typedef test_compare<std::less<int> > C; |
| typedef test_allocator<V> A; |
| std::map<int, double, C, A> mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A(2)); |
| std::map<int, double, C, A> m(ar, ar+sizeof(ar)/sizeof(ar[0])/2, C(3), A(7)); |
| m = mo; |
| assert(m.get_allocator() == A(7)); |
| assert(m.key_comp() == C(5)); |
| assert(m.size() == 3); |
| assert(distance(m.begin(), m.end()) == 3); |
| assert(*m.begin() == V(1, 1)); |
| assert(*next(m.begin()) == V(2, 1)); |
| assert(*next(m.begin(), 2) == V(3, 1)); |
| |
| assert(mo.get_allocator() == A(2)); |
| assert(mo.key_comp() == C(5)); |
| assert(mo.size() == 3); |
| assert(distance(mo.begin(), mo.end()) == 3); |
| assert(*mo.begin() == V(1, 1)); |
| assert(*next(mo.begin()) == V(2, 1)); |
| assert(*next(mo.begin(), 2) == V(3, 1)); |
| } |
| { |
| typedef std::pair<const int, double> V; |
| const V ar[] = |
| { |
| V(1, 1), |
| V(2, 1), |
| V(3, 1), |
| }; |
| std::map<int, double> m(ar, ar+sizeof(ar)/sizeof(ar[0])); |
| std::map<int, double> *p = &m; |
| m = *p; |
| |
| assert(m.size() == 3); |
| assert(std::equal(m.begin(), m.end(), ar)); |
| } |
| { |
| typedef std::pair<const int, double> V; |
| V ar[] = |
| { |
| V(1, 1), |
| V(1, 1.5), |
| V(1, 2), |
| V(2, 1), |
| V(2, 1.5), |
| V(2, 2), |
| V(3, 1), |
| V(3, 1.5), |
| V(3, 2) |
| }; |
| typedef test_compare<std::less<int> > C; |
| typedef other_allocator<V> A; |
| std::map<int, double, C, A> mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A(2)); |
| std::map<int, double, C, A> m(ar, ar+sizeof(ar)/sizeof(ar[0])/2, C(3), A(7)); |
| m = mo; |
| assert(m.get_allocator() == A(2)); |
| assert(m.key_comp() == C(5)); |
| assert(m.size() == 3); |
| assert(distance(m.begin(), m.end()) == 3); |
| assert(*m.begin() == V(1, 1)); |
| assert(*next(m.begin()) == V(2, 1)); |
| assert(*next(m.begin(), 2) == V(3, 1)); |
| |
| assert(mo.get_allocator() == A(2)); |
| assert(mo.key_comp() == C(5)); |
| assert(mo.size() == 3); |
| assert(distance(mo.begin(), mo.end()) == 3); |
| assert(*mo.begin() == V(1, 1)); |
| assert(*next(mo.begin()) == V(2, 1)); |
| assert(*next(mo.begin(), 2) == V(3, 1)); |
| } |
| #if TEST_STD_VER >= 11 |
| { |
| typedef std::pair<const int, double> V; |
| V ar[] = |
| { |
| V(1, 1), |
| V(1, 1.5), |
| V(1, 2), |
| V(2, 1), |
| V(2, 1.5), |
| V(2, 2), |
| V(3, 1), |
| V(3, 1.5), |
| V(3, 2) |
| }; |
| typedef test_compare<std::less<int> > C; |
| typedef min_allocator<V> A; |
| std::map<int, double, C, A> mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A()); |
| std::map<int, double, C, A> m(ar, ar+sizeof(ar)/sizeof(ar[0])/2, C(3), A()); |
| m = mo; |
| assert(m.get_allocator() == A()); |
| assert(m.key_comp() == C(5)); |
| assert(m.size() == 3); |
| assert(distance(m.begin(), m.end()) == 3); |
| assert(*m.begin() == V(1, 1)); |
| assert(*next(m.begin()) == V(2, 1)); |
| assert(*next(m.begin(), 2) == V(3, 1)); |
| |
| assert(mo.get_allocator() == A()); |
| assert(mo.key_comp() == C(5)); |
| assert(mo.size() == 3); |
| assert(distance(mo.begin(), mo.end()) == 3); |
| assert(*mo.begin() == V(1, 1)); |
| assert(*next(mo.begin()) == V(2, 1)); |
| assert(*next(mo.begin(), 2) == V(3, 1)); |
| } |
| { |
| typedef std::pair<const int, double> V; |
| V ar[] = |
| { |
| V(1, 1), |
| V(1, 1.5), |
| V(1, 2), |
| V(2, 1), |
| V(2, 1.5), |
| V(2, 2), |
| V(3, 1), |
| V(3, 1.5), |
| V(3, 2) |
| }; |
| typedef test_compare<std::less<int> > C; |
| typedef min_allocator<V> A; |
| std::map<int, double, C, A> mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A()); |
| std::map<int, double, C, A> m(ar, ar+sizeof(ar)/sizeof(ar[0])/2, C(3), A()); |
| m = mo; |
| assert(m.get_allocator() == A()); |
| assert(m.key_comp() == C(5)); |
| assert(m.size() == 3); |
| assert(distance(m.begin(), m.end()) == 3); |
| assert(*m.begin() == V(1, 1)); |
| assert(*next(m.begin()) == V(2, 1)); |
| assert(*next(m.begin(), 2) == V(3, 1)); |
| |
| assert(mo.get_allocator() == A()); |
| assert(mo.key_comp() == C(5)); |
| assert(mo.size() == 3); |
| assert(distance(mo.begin(), mo.end()) == 3); |
| assert(*mo.begin() == V(1, 1)); |
| assert(*next(mo.begin()) == V(2, 1)); |
| assert(*next(mo.begin(), 2) == V(3, 1)); |
| } |
| |
| assert(balanced_allocs()); |
| { |
| typedef std::pair<const int, double> V; |
| V ar[] = |
| { |
| V(1, 1), |
| V(1, 1.5), |
| V(1, 2), |
| V(2, 1), |
| V(2, 1.5), |
| V(2, 2), |
| V(3, 1), |
| V(3, 1.5), |
| V(3, 2) |
| }; |
| typedef test_compare<std::less<int> > C; |
| typedef counting_allocatorT<V> A; |
| std::map<int, double, C, A> mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A(1)); |
| std::map<int, double, C, A> m(ar, ar+sizeof(ar)/sizeof(ar[0])/2, C(3), A(2)); |
| m = mo; |
| assert(m.key_comp() == C(5)); |
| assert(m.size() == 3); |
| assert(distance(m.begin(), m.end()) == 3); |
| assert(*m.begin() == V(1, 1)); |
| assert(*next(m.begin()) == V(2, 1)); |
| assert(*next(m.begin(), 2) == V(3, 1)); |
| |
| assert(mo.key_comp() == C(5)); |
| assert(mo.size() == 3); |
| assert(distance(mo.begin(), mo.end()) == 3); |
| assert(*mo.begin() == V(1, 1)); |
| assert(*next(mo.begin()) == V(2, 1)); |
| assert(*next(mo.begin(), 2) == V(3, 1)); |
| } |
| assert(balanced_allocs()); |
| { |
| typedef std::pair<const int, double> V; |
| V ar[] = |
| { |
| V(1, 1), |
| V(1, 1.5), |
| V(1, 2), |
| V(2, 1), |
| V(2, 1.5), |
| V(2, 2), |
| V(3, 1), |
| V(3, 1.5), |
| V(3, 2) |
| }; |
| typedef test_compare<std::less<int> > C; |
| typedef counting_allocatorF<V> A; |
| std::map<int, double, C, A> mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A(100)); |
| std::map<int, double, C, A> m(ar, ar+sizeof(ar)/sizeof(ar[0])/2, C(3), A(200)); |
| m = mo; |
| assert(m.key_comp() == C(5)); |
| assert(m.size() == 3); |
| assert(distance(m.begin(), m.end()) == 3); |
| assert(*m.begin() == V(1, 1)); |
| assert(*next(m.begin()) == V(2, 1)); |
| assert(*next(m.begin(), 2) == V(3, 1)); |
| |
| assert(mo.key_comp() == C(5)); |
| assert(mo.size() == 3); |
| assert(distance(mo.begin(), mo.end()) == 3); |
| assert(*mo.begin() == V(1, 1)); |
| assert(*next(mo.begin()) == V(2, 1)); |
| assert(*next(mo.begin(), 2) == V(3, 1)); |
| } |
| assert(balanced_allocs()); |
| #endif |
| } |