Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 24 additions & 22 deletions stl/inc/flat_map
Original file line number Diff line number Diff line change
Expand Up @@ -757,6 +757,28 @@ protected:
return _Old_size - size();
}

template <class _KeyTy, class... _MappedArgTypes>
pair<iterator, bool> _Try_emplace(_KeyTy&& _Key_val, _MappedArgTypes&&... _Mapped_args) {
auto _Key_it = _STD lower_bound(_Data.keys.begin(), _Data.keys.end(), _Key_val, _Key_compare);
if (_Key_it != _Data.keys.end() && _Key_equal(*_Key_it, _STD forward<_KeyTy>(_Key_val))) {
// Already exists
return {this->begin() + _STD distance(_Data.keys.begin(), _Key_it), false};
} else {
// Need to insert
auto _Index = _STD distance(_Data.keys.begin(), _Key_it);
this->_Insert_exact(this->cbegin() + _Index, key_type{_STD forward<_KeyTy>(_Key_val)},
mapped_type{_STD forward<_MappedArgTypes>(_Mapped_args)...});
return {this->begin() + _Index, true};
}
}

void _Insert_exact(const_iterator _Position, key_type&& _Key_val, mapped_type&& _Mapped_val) {
_Clear_flat_map_scope_guard _Guard{this};
_Data.keys.insert(_Position._Key_it, _STD move(_Key_val));
_Data.values.insert(_Position._Mapped_it, _STD move(_Mapped_val));
_Guard._Clearable = nullptr;
}

private:
template <class _KeyTy1, class _KeyTy2>
requires (same_as<remove_cvref_t<_KeyTy1 &&>, key_type> && same_as<remove_cvref_t<_KeyTy2 &&>, key_type>)
Expand Down Expand Up @@ -792,13 +814,6 @@ private:
_Guard._Clearable = nullptr;
}

void _Insert_exact(const_iterator _Position, key_type&& _Key_val, mapped_type&& _Mapped_val) {
_Clear_flat_map_scope_guard _Guard{this};
_Data.keys.insert(_Position._Key_it, _STD move(_Key_val));
_Data.values.insert(_Position._Mapped_it, _STD move(_Mapped_val));
_Guard._Clearable = nullptr;
}

template <bool _OverwriteIfExists, class _OtherKey, class... _MappedArgTypes>
iterator _Emplace_hint(const_iterator _Position, _OtherKey&& _Key_val, _MappedArgTypes&&... _Args)
requires is_constructible_v<mapped_type, _MappedArgTypes...>
Expand Down Expand Up @@ -1161,6 +1176,7 @@ public:

private:
using _MyBase::_Erase_if;
using _MyBase::_Try_emplace;

template <class _KTy, class _MTy, class _Comp, class _KeyCont, class _MappedCont, class _Pred>
friend typename flat_map<_KTy, _MTy, _Comp, _KeyCont, _MappedCont>::size_type erase_if(
Expand Down Expand Up @@ -1190,21 +1206,6 @@ private:
}
}

template <class _KeyTy, class... _MappedArgTypes>
pair<iterator, bool> _Try_emplace(_KeyTy&& _Key_val, _MappedArgTypes&&... _Mapped_args) {
auto _Key_it = _STD lower_bound(_Data.keys.begin(), _Data.keys.end(), _Key_val, _Key_compare);
if (_Key_it != _Data.keys.end() && _Key_equal(*_Key_it, _STD forward<_KeyTy>(_Key_val))) {
// Already exists
return {this->begin() + _STD distance(_Data.keys.begin(), _Key_it), false};
} else {
// Need to insert
auto _Index = _STD distance(_Data.keys.begin(), _Key_it);
this->_Insert_exact(this->cbegin() + _Index, key_type{_STD forward<_KeyTy>(_Key_val)},
mapped_type{_STD forward<_MappedArgTypes>(_Mapped_args)...});
return {this->begin() + _Index, true};
}
}

template <class _KeyTy, class _MappedTy>
pair<iterator, bool> _Insert_or_assign(_KeyTy&& _Key_val, _MappedTy&& _Mapped_val) {
auto _Res = _Try_emplace(_STD forward<_KeyTy>(_Key_val), _STD forward<_MappedTy>(_Mapped_val));
Expand Down Expand Up @@ -1328,6 +1329,7 @@ public:

private:
using _MyBase::_Erase_if;
using _MyBase::_Insert_exact;

template <class _KTy, class _MTy, class _Comp, class _KeyCont, class _MappedCont, class _Pred>
friend typename flat_multimap<_KTy, _MTy, _Comp, _KeyCont, _MappedCont>::size_type erase_if(
Expand Down
2 changes: 1 addition & 1 deletion tests/std/tests/P0429R9_flat_map/env.lst
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

RUNALL_INCLUDE ..\concepts_latest_matrix.lst
RUNALL_INCLUDE ..\strict_concepts_latest_matrix.lst
34 changes: 34 additions & 0 deletions tests/std/tests/P0429R9_flat_map/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -300,8 +300,42 @@ namespace scary_test {
static_assert(is_same_v<flat_map<int, int>::value_compare, flat_multimap<int, int>::value_compare>);
} // namespace scary_test

// GH-4344 <flat_map> Fix compile errors
void test_gh_4344() {
flat_map<int, char> fm;

const auto p1 = fm.try_emplace(10, 'm');
assert(p1.first->first == 10);
assert(p1.first->second == 'm');
assert(p1.second);

const auto p2 = fm.try_emplace(70, 'e');
assert(p2.first->first == 70);
assert(p2.first->second == 'e');
assert(p2.second);

const auto p3 = fm.try_emplace(20, 'o');
assert(p3.first->first == 20);
assert(p3.first->second == 'o');
assert(p3.second);

const auto p4 = fm.try_emplace(90, 'w');
assert(p4.first->first == 90);
assert(p4.first->second == 'w');
assert(p4.second);

const auto p5 = fm.try_emplace(70, 'X');
assert(p5.first->first == 70);
assert(p5.first->second == 'e');
assert(!p5.second);

assert(check_key_content(fm, {10, 20, 70, 90}));
assert(check_value_content(fm, {'m', 'o', 'e', 'w'}));
}

int main() {
test_construction();
test_pointer_to_incomplete_type();
test_erase_if();
test_gh_4344();
}