|
4 | 4 | #include <atomic>
|
5 | 5 | #include <cassert>
|
6 | 6 | #include <concepts>
|
| 7 | +#include <deque> |
7 | 8 | #include <flat_map>
|
8 | 9 | #include <functional>
|
9 | 10 | #include <memory>
|
@@ -269,38 +270,45 @@ void test_pointer_to_incomplete_type() {
|
269 | 270 | flat_map<MyType<Incomplete>, shared_ptr<MyType<Incomplete>>> fmap;
|
270 | 271 | }
|
271 | 272 |
|
272 |
| -void test_insert_unique() { |
| 273 | +void test_insert() { |
273 | 274 | flat_map<int, char> fm;
|
274 | 275 |
|
275 |
| - const auto p1 = fm.insert({10, 'm'}); |
276 |
| - assert(p1.first->first == 10); |
277 |
| - assert(p1.first->second == 'm'); |
278 |
| - assert(p1.second); |
| 276 | + const auto res1 = fm.insert({10, 'm'}); |
| 277 | + assert(res1.first->first == 10); |
| 278 | + assert(res1.first->second == 'm'); |
| 279 | + assert(res1.second); |
| 280 | + |
| 281 | + const auto res2 = fm.insert({10, 'n'}); |
| 282 | + assert(res2.first->first == 10); |
| 283 | + assert(res2.first->second == 'm'); |
| 284 | + assert(!res2.second); |
279 | 285 |
|
280 | 286 | const flat_map<int, char>::value_type val_pair{90, 'w'};
|
281 |
| - const auto p2 = fm.insert(val_pair); |
282 |
| - assert(p2.first->first == 90); |
283 |
| - assert(p2.first->second == 'w'); |
284 |
| - assert(p2.second); |
| 287 | + const auto res3 = fm.insert(val_pair); |
| 288 | + assert(res3.first->first == 90); |
| 289 | + assert(res3.first->second == 'w'); |
| 290 | + assert(res3.second); |
285 | 291 |
|
286 | 292 | assert(check_key_content(fm, {10, 90}));
|
287 | 293 | assert(check_value_content(fm, {'m', 'w'}));
|
288 |
| -} |
289 | 294 |
|
290 |
| -void test_insert_multi() { |
291 | 295 | flat_multimap<int, char> fmm;
|
292 | 296 |
|
293 | 297 | const auto it1 = fmm.insert({10, 'm'});
|
294 | 298 | assert(it1->first == 10);
|
295 | 299 | assert(it1->second == 'm');
|
296 | 300 |
|
297 |
| - const flat_multimap<int, char>::value_type val_pair{90, 'w'}; |
298 |
| - const auto it2 = fmm.insert(val_pair); |
299 |
| - assert(it2->first == 90); |
300 |
| - assert(it2->second == 'w'); |
| 301 | + const auto it2 = fmm.insert({10, 'n'}); |
| 302 | + assert(it2->first == 10); |
| 303 | + assert(it2->second == 'n'); |
301 | 304 |
|
302 |
| - assert(check_key_content(fmm, {10, 90})); |
303 |
| - assert(check_value_content(fmm, {'m', 'w'})); |
| 305 | + const flat_multimap<int, char>::value_type val_pair2{90, 'w'}; |
| 306 | + const auto it3 = fmm.insert(val_pair2); |
| 307 | + assert(it3->first == 90); |
| 308 | + assert(it3->second == 'w'); |
| 309 | + |
| 310 | + assert(check_key_content(fmm, {10, 10, 90})); |
| 311 | + assert(check_value_content(fmm, {'n', 'm', 'w'})); |
304 | 312 | }
|
305 | 313 |
|
306 | 314 | // GH-4344 <flat_map> Fix compile errors
|
@@ -410,29 +418,52 @@ void test_insert_or_assign() {
|
410 | 418 | }
|
411 | 419 |
|
412 | 420 | // Test MSVC STL-specific SCARY-ness
|
| 421 | + |
| 422 | +template <bool> |
| 423 | +struct flat_map_unique_if_impl; |
| 424 | +template <> |
| 425 | +struct flat_map_unique_if_impl<true> { |
| 426 | + template <class Key, class Mapped, class Comp, class KeyCont, class MappedCont> |
| 427 | + using type = flat_map<Key, Mapped, Comp, KeyCont, MappedCont>; |
| 428 | +}; |
| 429 | +template <> |
| 430 | +struct flat_map_unique_if_impl<false> { |
| 431 | + template <class Key, class Mapped, class Comp, class KeyCont, class MappedCont> |
| 432 | + using type = flat_multimap<Key, Mapped, Comp, KeyCont, MappedCont>; |
| 433 | +}; |
| 434 | + |
| 435 | +template <bool IsUnique, class Key, class Mapped, class Comp, class KeyCont, class MappedCont> |
| 436 | +using flat_map_unique_if = flat_map_unique_if_impl<IsUnique>::template type<Key, Mapped, Comp, KeyCont, MappedCont>; |
| 437 | + |
413 | 438 | template <bool IsUnique, class Comparator, class Alloc1, class Alloc2>
|
414 | 439 | void test_scary_ness_one() { // COMPILE-ONLY
|
415 |
| - using Iter = flat_map<int, int>::iterator; |
416 |
| - using OtherIter = conditional_t<IsUnique, flat_map<int, int, Comparator, vector<int, Alloc1>, vector<int, Alloc2>>, |
417 |
| - flat_multimap<int, int, Comparator, vector<int, Alloc1>, vector<int, Alloc2>>>::iterator; |
| 440 | + using Iter = flat_map<int, int>::iterator; |
| 441 | + using OtherIter = |
| 442 | + flat_map_unique_if<IsUnique, int, int, Comparator, vector<int, Alloc1>, vector<int, Alloc2>>::iterator; |
418 | 443 | static_assert(is_same_v<Iter, OtherIter>);
|
419 | 444 |
|
420 | 445 | using ConstIter = flat_map<int, int>::const_iterator;
|
421 | 446 | using OtherConstIter =
|
422 |
| - conditional_t<IsUnique, flat_map<int, int, Comparator, vector<int, Alloc1>, vector<int, Alloc2>>, |
423 |
| - flat_multimap<int, int, Comparator, vector<int, Alloc1>, vector<int, Alloc2>>>::const_iterator; |
| 447 | + flat_map_unique_if<IsUnique, int, int, Comparator, vector<int, Alloc1>, vector<int, Alloc2>>::const_iterator; |
424 | 448 | static_assert(is_same_v<ConstIter, OtherConstIter>);
|
425 | 449 |
|
426 |
| - using Cont = flat_map<int, int, less<int>, vector<int, Alloc1>, vector<int, Alloc2>>::containers; |
427 |
| - using OtherCont = conditional_t<IsUnique, flat_map<int, int, Comparator, vector<int, Alloc1>, vector<int, Alloc2>>, |
428 |
| - flat_multimap<int, int, Comparator, vector<int, Alloc1>, vector<int, Alloc2>>>::containers; |
| 450 | + using Cont = flat_map<int, int, less<int>, vector<int, Alloc1>, vector<int, Alloc2>>::containers; |
| 451 | + using OtherCont = |
| 452 | + flat_map_unique_if<IsUnique, int, int, Comparator, vector<int, Alloc1>, vector<int, Alloc2>>::containers; |
429 | 453 | static_assert(is_same_v<Cont, OtherCont>);
|
430 | 454 |
|
431 | 455 | using ValueComp = flat_map<int, int, Comparator, vector<int, Alloc1>, vector<int, Alloc2>>::value_compare;
|
432 |
| - using OtherValueComp = |
433 |
| - conditional_t<IsUnique, flat_map<int, int, Comparator, vector<int, Alloc1>, vector<int, Alloc2>>, |
434 |
| - flat_multimap<int, int, Comparator, vector<int, Alloc1>, vector<int, Alloc2>>>::value_compare; |
435 |
| - static_assert(is_same_v<ValueComp, OtherValueComp>); |
| 456 | + using OtherValueComp1 = |
| 457 | + flat_map_unique_if<IsUnique, int, int, Comparator, vector<int, Alloc1>, vector<int, Alloc2>>::value_compare; |
| 458 | + using OtherValueComp2 = flat_map_unique_if<IsUnique, int, int, Comparator, vector<int>, vector<int>>::value_compare; |
| 459 | + using OtherValueComp3 = |
| 460 | + flat_map_unique_if<IsUnique, int, int, Comparator, vector<int, Alloc1>, deque<int, Alloc2>>::value_compare; |
| 461 | + using OtherValueComp4 = |
| 462 | + flat_map_unique_if<IsUnique, int, int, Comparator, deque<int, Alloc1>, vector<int, Alloc2>>::value_compare; |
| 463 | + static_assert(is_same_v<ValueComp, OtherValueComp1>); |
| 464 | + static_assert(is_same_v<ValueComp, OtherValueComp2>); |
| 465 | + static_assert(is_same_v<ValueComp, OtherValueComp3>); |
| 466 | + static_assert(is_same_v<ValueComp, OtherValueComp4>); |
436 | 467 | }
|
437 | 468 |
|
438 | 469 | void test_scary_ness() { // COMPILE-ONLY
|
@@ -465,8 +496,7 @@ int main() {
|
465 | 496 | test_construction();
|
466 | 497 | test_pointer_to_incomplete_type();
|
467 | 498 | test_erase_if();
|
468 |
| - test_insert_unique(); |
469 |
| - test_insert_multi(); |
| 499 | + test_insert(); |
470 | 500 | test_gh_4344();
|
471 | 501 | test_insert_or_assign();
|
472 | 502 | }
|
0 commit comments