llvm-project
348 строк · 11.2 Кб
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9// <map>
10
11// class map
12
13// map& operator=(const map& m);
14
15#include <map>16#include <algorithm>17#include <cassert>18#include <cstdio>19#include <iterator>20#include <vector>21
22#include "test_macros.h"23#include "../../../test_compare.h"24#include "test_allocator.h"25#include "min_allocator.h"26
27#if TEST_STD_VER >= 1128std::vector<int> ca_allocs;29std::vector<int> ca_deallocs;30
31template <class T>32class counting_allocatorT {33public:34typedef T value_type;35int foo{0};36counting_allocatorT(int f) noexcept : foo(f) {}37
38using propagate_on_container_copy_assignment = std::true_type;39template <class U> counting_allocatorT(const counting_allocatorT<U>& other) noexcept {foo = other.foo;}40template <class U> bool operator==(const counting_allocatorT<U>& other) const noexcept { return foo == other.foo; }41template <class U> bool operator!=(const counting_allocatorT<U>& other) const noexcept { return foo != other.foo; }42
43T* allocate(std::size_t n) const {44ca_allocs.push_back(foo);45void * const pv = ::malloc(n * sizeof(T));46return static_cast<T *>(pv);47}48void deallocate(T* p, std::size_t) const noexcept {49ca_deallocs.push_back(foo);50free(p);51}52};53
54template <class T>55class counting_allocatorF {56public:57typedef T value_type;58int foo{0};59counting_allocatorF(int f) noexcept : foo(f) {}60
61using propagate_on_container_copy_assignment = std::false_type;62template <class U> counting_allocatorF(const counting_allocatorF<U>& other) noexcept {foo = other.foo;}63template <class U> bool operator==(const counting_allocatorF<U>& other) const noexcept { return foo == other.foo; }64template <class U> bool operator!=(const counting_allocatorF<U>& other) const noexcept { return foo != other.foo; }65
66T* allocate(std::size_t n) const {67ca_allocs.push_back(foo);68void * const pv = ::malloc(n * sizeof(T));69return static_cast<T *>(pv);70}71void deallocate(T* p, std::size_t) const noexcept {72ca_deallocs.push_back(foo);73free(p);74}75};76
77bool balanced_allocs() {78std::vector<int> temp1, temp2;79
80std::printf("Allocations = %zu, deallocations = %zu\n", ca_allocs.size(),81ca_deallocs.size());82if (ca_allocs.size() != ca_deallocs.size())83return false;84
85temp1 = ca_allocs;86std::sort(temp1.begin(), temp1.end());87temp2.clear();88std::unique_copy(temp1.begin(), temp1.end(), std::back_inserter<std::vector<int>>(temp2));89std::printf("There were %zu different allocators\n", temp2.size());90
91for (std::vector<int>::const_iterator it = temp2.begin(); it != temp2.end(); ++it ) {92std::ptrdiff_t const allocs = std::count(ca_allocs.begin(), ca_allocs.end(), *it);93std::ptrdiff_t const deallocs = std::count(ca_deallocs.begin(), ca_deallocs.end(), *it);94std::printf("%d: %td vs %td\n", *it, allocs, deallocs);95if (allocs != deallocs)96return false;97}98
99temp1 = ca_allocs;100std::sort(temp1.begin(), temp1.end());101temp2.clear();102std::unique_copy(temp1.begin(), temp1.end(), std::back_inserter<std::vector<int>>(temp2));103std::printf("There were %zu different (de)allocators\n", temp2.size());104
105for (std::vector<int>::const_iterator it = ca_deallocs.begin(); it != ca_deallocs.end(); ++it ) {106std::ptrdiff_t const allocs = std::count(ca_allocs.begin(), ca_allocs.end(), *it);107std::ptrdiff_t const deallocs = std::count(ca_deallocs.begin(), ca_deallocs.end(), *it);108std::printf("%d: %td vs %td\n", *it, allocs, deallocs);109if (allocs != deallocs)110return false;111}112
113return true;114}
115#endif116
117int main(int, char**)118{
119{120typedef std::pair<const int, double> V;121V ar[] =122{123V(1, 1),124V(1, 1.5),125V(1, 2),126V(2, 1),127V(2, 1.5),128V(2, 2),129V(3, 1),130V(3, 1.5),131V(3, 2)132};133typedef test_less<int> C;134typedef test_allocator<V> A;135std::map<int, double, C, A> mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A(2));136std::map<int, double, C, A> m(ar, ar+sizeof(ar)/sizeof(ar[0])/2, C(3), A(7));137m = mo;138assert(m.get_allocator() == A(7));139assert(m.key_comp() == C(5));140assert(m.size() == 3);141assert(std::distance(m.begin(), m.end()) == 3);142assert(*m.begin() == V(1, 1));143assert(*std::next(m.begin()) == V(2, 1));144assert(*std::next(m.begin(), 2) == V(3, 1));145
146assert(mo.get_allocator() == A(2));147assert(mo.key_comp() == C(5));148assert(mo.size() == 3);149assert(std::distance(mo.begin(), mo.end()) == 3);150assert(*mo.begin() == V(1, 1));151assert(*std::next(mo.begin()) == V(2, 1));152assert(*std::next(mo.begin(), 2) == V(3, 1));153}154{155typedef std::pair<const int, double> V;156const V ar[] =157{158V(1, 1),159V(2, 1),160V(3, 1),161};162std::map<int, double> m(ar, ar+sizeof(ar)/sizeof(ar[0]));163std::map<int, double> *p = &m;164m = *p;165
166assert(m.size() == 3);167assert(std::equal(m.begin(), m.end(), ar));168}169{170typedef std::pair<const int, double> V;171V ar[] =172{173V(1, 1),174V(1, 1.5),175V(1, 2),176V(2, 1),177V(2, 1.5),178V(2, 2),179V(3, 1),180V(3, 1.5),181V(3, 2)182};183typedef test_less<int> C;184typedef other_allocator<V> A;185std::map<int, double, C, A> mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A(2));186std::map<int, double, C, A> m(ar, ar+sizeof(ar)/sizeof(ar[0])/2, C(3), A(7));187m = mo;188assert(m.get_allocator() == A(2));189assert(m.key_comp() == C(5));190assert(m.size() == 3);191assert(std::distance(m.begin(), m.end()) == 3);192assert(*m.begin() == V(1, 1));193assert(*std::next(m.begin()) == V(2, 1));194assert(*std::next(m.begin(), 2) == V(3, 1));195
196assert(mo.get_allocator() == A(2));197assert(mo.key_comp() == C(5));198assert(mo.size() == 3);199assert(std::distance(mo.begin(), mo.end()) == 3);200assert(*mo.begin() == V(1, 1));201assert(*std::next(mo.begin()) == V(2, 1));202assert(*std::next(mo.begin(), 2) == V(3, 1));203}204#if TEST_STD_VER >= 11205{206typedef std::pair<const int, double> V;207V ar[] =208{209V(1, 1),210V(1, 1.5),211V(1, 2),212V(2, 1),213V(2, 1.5),214V(2, 2),215V(3, 1),216V(3, 1.5),217V(3, 2)218};219typedef test_less<int> C;220typedef min_allocator<V> A;221std::map<int, double, C, A> mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A());222std::map<int, double, C, A> m(ar, ar+sizeof(ar)/sizeof(ar[0])/2, C(3), A());223m = mo;224assert(m.get_allocator() == A());225assert(m.key_comp() == C(5));226assert(m.size() == 3);227assert(std::distance(m.begin(), m.end()) == 3);228assert(*m.begin() == V(1, 1));229assert(*std::next(m.begin()) == V(2, 1));230assert(*std::next(m.begin(), 2) == V(3, 1));231
232assert(mo.get_allocator() == A());233assert(mo.key_comp() == C(5));234assert(mo.size() == 3);235assert(std::distance(mo.begin(), mo.end()) == 3);236assert(*mo.begin() == V(1, 1));237assert(*std::next(mo.begin()) == V(2, 1));238assert(*std::next(mo.begin(), 2) == V(3, 1));239}240{241typedef std::pair<const int, double> V;242V ar[] =243{244V(1, 1),245V(1, 1.5),246V(1, 2),247V(2, 1),248V(2, 1.5),249V(2, 2),250V(3, 1),251V(3, 1.5),252V(3, 2)253};254typedef test_less<int> C;255typedef min_allocator<V> A;256std::map<int, double, C, A> mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A());257std::map<int, double, C, A> m(ar, ar+sizeof(ar)/sizeof(ar[0])/2, C(3), A());258m = mo;259assert(m.get_allocator() == A());260assert(m.key_comp() == C(5));261assert(m.size() == 3);262assert(std::distance(m.begin(), m.end()) == 3);263assert(*m.begin() == V(1, 1));264assert(*std::next(m.begin()) == V(2, 1));265assert(*std::next(m.begin(), 2) == V(3, 1));266
267assert(mo.get_allocator() == A());268assert(mo.key_comp() == C(5));269assert(mo.size() == 3);270assert(std::distance(mo.begin(), mo.end()) == 3);271assert(*mo.begin() == V(1, 1));272assert(*std::next(mo.begin()) == V(2, 1));273assert(*std::next(mo.begin(), 2) == V(3, 1));274}275
276assert(balanced_allocs());277{278typedef std::pair<const int, double> V;279V ar[] =280{281V(1, 1),282V(1, 1.5),283V(1, 2),284V(2, 1),285V(2, 1.5),286V(2, 2),287V(3, 1),288V(3, 1.5),289V(3, 2)290};291typedef test_less<int> C;292typedef counting_allocatorT<V> A;293std::map<int, double, C, A> mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A(1));294std::map<int, double, C, A> m(ar, ar+sizeof(ar)/sizeof(ar[0])/2, C(3), A(2));295m = mo;296assert(m.key_comp() == C(5));297assert(m.size() == 3);298assert(std::distance(m.begin(), m.end()) == 3);299assert(*m.begin() == V(1, 1));300assert(*std::next(m.begin()) == V(2, 1));301assert(*std::next(m.begin(), 2) == V(3, 1));302
303assert(mo.key_comp() == C(5));304assert(mo.size() == 3);305assert(std::distance(mo.begin(), mo.end()) == 3);306assert(*mo.begin() == V(1, 1));307assert(*std::next(mo.begin()) == V(2, 1));308assert(*std::next(mo.begin(), 2) == V(3, 1));309}310assert(balanced_allocs());311{312typedef std::pair<const int, double> V;313V ar[] =314{315V(1, 1),316V(1, 1.5),317V(1, 2),318V(2, 1),319V(2, 1.5),320V(2, 2),321V(3, 1),322V(3, 1.5),323V(3, 2)324};325typedef test_less<int> C;326typedef counting_allocatorF<V> A;327std::map<int, double, C, A> mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A(100));328std::map<int, double, C, A> m(ar, ar+sizeof(ar)/sizeof(ar[0])/2, C(3), A(200));329m = mo;330assert(m.key_comp() == C(5));331assert(m.size() == 3);332assert(std::distance(m.begin(), m.end()) == 3);333assert(*m.begin() == V(1, 1));334assert(*std::next(m.begin()) == V(2, 1));335assert(*std::next(m.begin(), 2) == V(3, 1));336
337assert(mo.key_comp() == C(5));338assert(mo.size() == 3);339assert(std::distance(mo.begin(), mo.end()) == 3);340assert(*mo.begin() == V(1, 1));341assert(*std::next(mo.begin()) == V(2, 1));342assert(*std::next(mo.begin(), 2) == V(3, 1));343}344assert(balanced_allocs());345#endif346
347return 0;348}
349