| 487 | // Advantage: doesn't move key if element already exists |
| 488 | template<typename... Args> |
| 489 | pair<iterator, bool> try_emplace(const Key& k, Args&&... args) { |
| 490 | const bool will_rehash = needs_rehash(); |
| 491 | if (will_rehash) { |
| 492 | if (_tombstones > _size) { |
| 493 | rehash_inline_no_resize(); |
| 494 | } else { |
| 495 | rehash_internal(_buckets.size() * 2); |
| 496 | } |
| 497 | } |
| 498 | fl::size idx; |
| 499 | bool is_new; |
| 500 | fl::pair<fl::size, bool> p = find_slot(k); |
| 501 | idx = p.first; |
| 502 | is_new = p.second; |
| 503 | if (is_new) { |
| 504 | // Key doesn't exist, construct in place |
| 505 | _buckets[idx].key = k; |
| 506 | _buckets[idx].value = T(fl::forward<Args>(args)...); |
| 507 | mark_occupied(idx); |
| 508 | ++_size; |
| 509 | } |
| 510 | // If not new, key already exists - don't construct value, just return existing iterator |
| 511 | return {iterator(this, idx), is_new}; |
| 512 | } |
| 513 | |
| 514 | // try_emplace() with move key - C++17 |
| 515 | template<typename... Args> |
no test coverage detected