llvm-project

Форк
0
185 строк · 6.5 Кб
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
// UNSUPPORTED: c++03, c++11, c++14
10

11
// <map>
12

13
// class map
14

15
// template <class... Args>
16
//  pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);          // C++17
17
// template <class... Args>
18
//  pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);               // C++17
19
// template <class... Args>
20
//  iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); // C++17
21
// template <class... Args>
22
//  iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);      // C++17
23

24
#include <map>
25
#include <cassert>
26
#include <tuple>
27

28
#include "test_macros.h"
29

30
class Moveable
31
{
32
    Moveable(const Moveable&);
33
    Moveable& operator=(const Moveable&);
34

35
    int int_;
36
    double double_;
37
public:
38
    Moveable() : int_(0), double_(0) {}
39
    Moveable(int i, double d) : int_(i), double_(d) {}
40
    Moveable(Moveable&& x)
41
        : int_(x.int_), double_(x.double_)
42
            {x.int_ = -1; x.double_ = -1;}
43
    Moveable& operator=(Moveable&& x)
44
        {int_ = x.int_; x.int_ = -1;
45
         double_ = x.double_; x.double_ = -1;
46
         return *this;
47
        }
48

49
    bool operator==(const Moveable& x) const
50
        {return int_ == x.int_ && double_ == x.double_;}
51
    bool operator<(const Moveable& x) const
52
        {return int_ < x.int_ || (int_ == x.int_ && double_ < x.double_);}
53

54
    int get() const {return int_;}
55
    bool moved() const {return int_ == -1;}
56
};
57

58

59
int main(int, char**)
60
{
61
    { // pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
62
        typedef std::map<int, Moveable> M;
63
        typedef std::pair<M::iterator, bool> R;
64
        M m;
65
        R r;
66
        for (int i = 0; i < 20; i += 2)
67
            m.emplace (i, Moveable(i, (double) i));
68
        assert(m.size() == 10);
69

70
        Moveable mv1(3, 3.0);
71
        for (int i=0; i < 20; i += 2)
72
        {
73
            r = m.try_emplace(i, std::move(mv1));
74
            assert(m.size() == 10);
75
            assert(!r.second);              // was not inserted
76
            assert(!mv1.moved());           // was not moved from
77
            assert(r.first->first == i);    // key
78
        }
79

80
        r = m.try_emplace(-1, std::move(mv1));
81
        assert(m.size() == 11);
82
        assert(r.second);                   // was inserted
83
        assert(mv1.moved());                // was moved from
84
        assert(r.first->first == -1);       // key
85
        assert(r.first->second.get() == 3); // value
86

87
        Moveable mv2(5, 3.0);
88
        r = m.try_emplace(5, std::move(mv2));
89
        assert(m.size() == 12);
90
        assert(r.second);                   // was inserted
91
        assert(mv2.moved());                // was moved from
92
        assert(r.first->first == 5);        // key
93
        assert(r.first->second.get() == 5); // value
94

95
        Moveable mv3(-1, 3.0);
96
        r = m.try_emplace(117, std::move(mv2));
97
        assert(m.size() == 13);
98
        assert(r.second);                    // was inserted
99
        assert(mv2.moved());                 // was moved from
100
        assert(r.first->first == 117);       // key
101
        assert(r.first->second.get() == -1); // value
102
    }
103

104
    {  // pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);
105
        typedef std::map<Moveable, Moveable> M;
106
        typedef std::pair<M::iterator, bool> R;
107
        M m;
108
        R r;
109
        for ( int i = 0; i < 20; i += 2 )
110
            m.emplace ( Moveable(i, (double) i), Moveable(i+1, (double) i+1));
111
        assert(m.size() == 10);
112

113
        Moveable mvkey1(2, 2.0);
114
        Moveable mv1(4, 4.0);
115
        r = m.try_emplace(std::move(mvkey1), std::move(mv1));
116
        assert(m.size() == 10);
117
        assert(!r.second);                 // was not inserted
118
        assert(!mv1.moved());              // was not moved from
119
        assert(!mvkey1.moved());           // was not moved from
120
        assert(r.first->first == mvkey1);  // key
121

122
        Moveable mvkey2(3, 3.0);
123
        r = m.try_emplace(std::move(mvkey2), std::move(mv1));
124
        assert(m.size() == 11);
125
        assert(r.second);                   // was inserted
126
        assert(mv1.moved());                // was moved from
127
        assert(mvkey2.moved());             // was moved from
128
        assert(r.first->first.get()  == 3); // key
129
        assert(r.first->second.get() == 4); // value
130
    }
131

132
    {  // iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
133
        typedef std::map<int, Moveable> M;
134
        M m;
135
        M::iterator r;
136
        for ( int i = 0; i < 20; i += 2 )
137
            m.try_emplace ( i, Moveable(i, (double) i));
138
        assert(m.size() == 10);
139
        M::const_iterator it = m.find(2);
140

141
        Moveable mv1(3, 3.0);
142
        for (int i=0; i < 20; i += 2)
143
        {
144
            r = m.try_emplace(it, i, std::move(mv1));
145
            assert(m.size() == 10);
146
            assert(!mv1.moved());         // was not moved from
147
            assert(r->first == i);        // key
148
            assert(r->second.get() == i); // value
149
        }
150

151
        r = m.try_emplace(it, 3, std::move(mv1));
152
        assert(m.size() == 11);
153
        assert(mv1.moved());          // was moved from
154
        assert(r->first == 3);        // key
155
        assert(r->second.get() == 3); // value
156
    }
157

158
    {  // iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
159
        typedef std::map<Moveable, Moveable> M;
160
        M m;
161
        M::iterator r;
162
        for ( int i = 0; i < 20; i += 2 )
163
            m.emplace ( Moveable(i, (double) i), Moveable(i+1, (double) i+1));
164
        assert(m.size() == 10);
165
        M::const_iterator it = std::next(m.cbegin());
166

167
        Moveable mvkey1(2, 2.0);
168
        Moveable mv1(4, 4.0);
169
        r = m.try_emplace(it, std::move(mvkey1), std::move(mv1));
170
        assert(m.size() == 10);
171
        assert(!mv1.moved());        // was not moved from
172
        assert(!mvkey1.moved());     // was not moved from
173
        assert(r->first == mvkey1);  // key
174

175
        Moveable mvkey2(3, 3.0);
176
        r = m.try_emplace(it, std::move(mvkey2), std::move(mv1));
177
        assert(m.size() == 11);
178
        assert(mv1.moved());          // was moved from
179
        assert(mvkey2.moved());       // was moved from
180
        assert(r->first.get()  == 3); // key
181
        assert(r->second.get() == 4); // value
182
    }
183

184
  return 0;
185
}
186

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.