29
29
#include < __cstddef/ptrdiff_t.h>
30
30
#include < __flat_map/key_value_iterator.h>
31
31
#include < __flat_map/sorted_unique.h>
32
+ #include < __flat_map/utils.h>
32
33
#include < __functional/invoke.h>
33
34
#include < __functional/is_transparent.h>
34
35
#include < __functional/operations.h>
36
+ #include < __fwd/vector.h>
35
37
#include < __iterator/concepts.h>
36
38
#include < __iterator/distance.h>
37
39
#include < __iterator/iterator_traits.h>
@@ -131,7 +133,7 @@ class flat_map {
131
133
_LIBCPP_HIDE_FROM_ABI static constexpr bool __allocator_ctor_constraint =
132
134
_And<uses_allocator<key_container_type, _Allocator>, uses_allocator<mapped_container_type, _Allocator>>::value;
133
135
134
- _LIBCPP_HIDE_FROM_ABI static constexpr bool __is_compare_transparent = __is_transparent_v<_Compare, _Compare >;
136
+ _LIBCPP_HIDE_FROM_ABI static constexpr bool __is_compare_transparent = __is_transparent_v<_Compare>;
135
137
136
138
public:
137
139
// [flat.map.cons], construct/copy/destroy
@@ -153,7 +155,7 @@ class flat_map {
153
155
# if _LIBCPP_HAS_EXCEPTIONS
154
156
} catch (...) {
155
157
__other.clear ();
156
- // gcc does not like the `throw` keyword in a conditional noexcept function
158
+ // gcc does not like the `throw` keyword in a conditionally noexcept function
157
159
if constexpr (!(is_nothrow_move_constructible_v<_KeyContainer> &&
158
160
is_nothrow_move_constructible_v<_MappedContainer> && is_nothrow_move_constructible_v<_Compare>)) {
159
161
throw ;
@@ -518,16 +520,16 @@ class flat_map {
518
520
return emplace_hint (__hint, std::move (__x));
519
521
}
520
522
521
- template <class _Pp >
522
- requires is_constructible_v<pair<key_type, mapped_type>, _Pp >
523
- _LIBCPP_HIDE_FROM_ABI pair<iterator, bool > insert (_Pp && __x) {
524
- return emplace (std::forward<_Pp >(__x));
523
+ template <class _PairLike >
524
+ requires is_constructible_v<pair<key_type, mapped_type>, _PairLike >
525
+ _LIBCPP_HIDE_FROM_ABI pair<iterator, bool > insert (_PairLike && __x) {
526
+ return emplace (std::forward<_PairLike >(__x));
525
527
}
526
528
527
- template <class _Pp >
528
- requires is_constructible_v<pair<key_type, mapped_type>, _Pp >
529
- _LIBCPP_HIDE_FROM_ABI iterator insert (const_iterator __hint, _Pp && __x) {
530
- return emplace_hint (__hint, std::forward<_Pp >(__x));
529
+ template <class _PairLike >
530
+ requires is_constructible_v<pair<key_type, mapped_type>, _PairLike >
531
+ _LIBCPP_HIDE_FROM_ABI iterator insert (const_iterator __hint, _PairLike && __x) {
532
+ return emplace_hint (__hint, std::forward<_PairLike >(__x));
531
533
}
532
534
533
535
template <class _InputIterator >
@@ -860,22 +862,10 @@ class flat_map {
860
862
__containers_.values .erase (__containers_.values .begin () + __dist, __containers_.values .end ());
861
863
}
862
864
863
- template <class _InputIterator , class _Sentinel >
864
- _LIBCPP_HIDE_FROM_ABI size_type __append (_InputIterator __first, _Sentinel __last) {
865
- size_type __num_of_appended = 0 ;
866
- for (; __first != __last; ++__first) {
867
- value_type __kv = *__first;
868
- __containers_.keys .insert (__containers_.keys .end (), std::move (__kv.first ));
869
- __containers_.values .insert (__containers_.values .end (), std::move (__kv.second ));
870
- ++__num_of_appended;
871
- }
872
- return __num_of_appended;
873
- }
874
-
875
865
template <bool _WasSorted, class _InputIterator , class _Sentinel >
876
866
_LIBCPP_HIDE_FROM_ABI void __append_sort_merge_unique (_InputIterator __first, _Sentinel __last) {
877
867
auto __on_failure = std::__make_exception_guard ([&]() noexcept { clear () /* noexcept */ ; });
878
- size_t __num_of_appended = __append (std::move (__first), std::move (__last));
868
+ size_t __num_of_appended = __flat_map_utils:: __append (* this , std::move (__first), std::move (__last));
879
869
if (__num_of_appended != 0 ) {
880
870
auto __zv = ranges::views::zip (__containers_.keys , __containers_.values );
881
871
auto __append_start_offset = __containers_.keys .size () - __num_of_appended;
@@ -963,7 +953,8 @@ class flat_map {
963
953
964
954
if (__key_it == __containers_.keys .end () || __compare_ (__key, *__key_it)) {
965
955
return pair<iterator, bool >(
966
- __try_emplace_exact_hint (
956
+ __flat_map_utils::__emplace_exact_pos (
957
+ *this ,
967
958
std::move (__key_it),
968
959
std::move (__mapped_it),
969
960
std::forward<_KeyArg>(__key),
@@ -989,10 +980,13 @@ class flat_map {
989
980
_LIBCPP_HIDE_FROM_ABI pair<iterator, bool > __try_emplace_hint (const_iterator __hint, _Kp&& __key, _Args&&... __args) {
990
981
if (__is_hint_correct (__hint, __key)) {
991
982
if (__hint == cend () || __compare_ (__key, __hint->first )) {
992
- return {
993
- __try_emplace_exact_hint (
994
- __hint.__key_iter_ , __hint.__mapped_iter_ , std::forward<_Kp>(__key), std::forward<_Args>(__args)...),
995
- true };
983
+ return {__flat_map_utils::__emplace_exact_pos (
984
+ *this ,
985
+ __hint.__key_iter_ ,
986
+ __hint.__mapped_iter_ ,
987
+ std::forward<_Kp>(__key),
988
+ std::forward<_Args>(__args)...),
989
+ true };
996
990
} else {
997
991
// key equals
998
992
auto __dist = __hint - cbegin ();
@@ -1003,49 +997,6 @@ class flat_map {
1003
997
}
1004
998
}
1005
999
1006
- template <class _IterK , class _IterM , class _KeyArg , class ... _MArgs>
1007
- _LIBCPP_HIDE_FROM_ABI iterator
1008
- __try_emplace_exact_hint (_IterK&& __it_key, _IterM&& __it_mapped, _KeyArg&& __key, _MArgs&&... __mapped_args) {
1009
- auto __on_key_failed = std::__make_exception_guard ([&]() noexcept {
1010
- if constexpr (__container_traits<_KeyContainer>::__emplacement_has_strong_exception_safety_guarantee) {
1011
- // Nothing to roll back!
1012
- } else {
1013
- // we need to clear both because we don't know the state of our keys anymore
1014
- clear () /* noexcept */ ;
1015
- }
1016
- });
1017
- auto __key_it = __containers_.keys .emplace (__it_key, std::forward<_KeyArg>(__key));
1018
- __on_key_failed.__complete ();
1019
-
1020
- auto __on_value_failed = std::__make_exception_guard ([&]() noexcept {
1021
- if constexpr (!__container_traits<_MappedContainer>::__emplacement_has_strong_exception_safety_guarantee) {
1022
- // we need to clear both because we don't know the state of our values anymore
1023
- clear () /* noexcept */ ;
1024
- } else {
1025
- // In this case, we know the values are just like before we attempted emplacement,
1026
- // and we also know that the keys have been emplaced successfully. Just roll back the keys.
1027
- # if _LIBCPP_HAS_EXCEPTIONS
1028
- try {
1029
- # endif // _LIBCPP_HAS_EXCEPTIONS
1030
- __containers_.keys .erase (__key_it);
1031
- # if _LIBCPP_HAS_EXCEPTIONS
1032
- } catch (...) {
1033
- // Now things are funky for real. We're failing to rollback the keys.
1034
- // Just give up and clear the whole thing.
1035
- //
1036
- // Also, swallow the exception that happened during the rollback and let the
1037
- // original value-emplacement exception propagate normally.
1038
- clear () /* noexcept */ ;
1039
- }
1040
- # endif // _LIBCPP_HAS_EXCEPTIONS
1041
- }
1042
- });
1043
- auto __mapped_it = __containers_.values .emplace (__it_mapped, std::forward<_MArgs>(__mapped_args)...);
1044
- __on_value_failed.__complete ();
1045
-
1046
- return iterator (std::move (__key_it), std::move (__mapped_it));
1047
- }
1048
-
1049
1000
template <class _Kp , class _Mapped >
1050
1001
_LIBCPP_HIDE_FROM_ABI pair<iterator, bool > __insert_or_assign (_Kp&& __key, _Mapped&& __mapped) {
1051
1002
auto __r = try_emplace (std::forward<_Kp>(__key), std::forward<_Mapped>(__mapped));
@@ -1087,8 +1038,10 @@ class flat_map {
1087
1038
friend typename flat_map<_Key2, _Tp2, _Compare2, _KeyContainer2, _MappedContainer2>::size_type
1088
1039
erase_if (flat_map<_Key2, _Tp2, _Compare2, _KeyContainer2, _MappedContainer2>&, _Predicate);
1089
1040
1041
+ friend __flat_map_utils;
1042
+
1090
1043
containers __containers_;
1091
- [[no_unique_address]] key_compare __compare_;
1044
+ _LIBCPP_NO_UNIQUE_ADDRESS key_compare __compare_;
1092
1045
1093
1046
struct __key_equiv {
1094
1047
_LIBCPP_HIDE_FROM_ABI __key_equiv (key_compare __c) : __comp_(__c) {}
@@ -1187,22 +1140,20 @@ template <ranges::input_range _Range,
1187
1140
class _Compare = less<__range_key_type<_Range>>,
1188
1141
class _Allocator = allocator<byte>,
1189
1142
class = __enable_if_t <!__is_allocator<_Compare>::value && __is_allocator<_Allocator>::value>>
1190
- flat_map (from_range_t , _Range&&, _Compare = _Compare (), _Allocator = _Allocator ())
1191
- -> flat_map<
1192
- __range_key_type<_Range>,
1193
- __range_mapped_type<_Range>,
1194
- _Compare,
1195
- vector<__range_key_type<_Range>, __allocator_traits_rebind_t <_Allocator, __range_key_type<_Range>>>,
1196
- vector<__range_mapped_type<_Range>, __allocator_traits_rebind_t <_Allocator, __range_mapped_type<_Range>>>>;
1143
+ flat_map (from_range_t , _Range&&, _Compare = _Compare (), _Allocator = _Allocator ()) -> flat_map<
1144
+ __range_key_type<_Range>,
1145
+ __range_mapped_type<_Range>,
1146
+ _Compare,
1147
+ vector<__range_key_type<_Range>, __allocator_traits_rebind_t <_Allocator, __range_key_type<_Range>>>,
1148
+ vector<__range_mapped_type<_Range>, __allocator_traits_rebind_t <_Allocator, __range_mapped_type<_Range>>>>;
1197
1149
1198
1150
template <ranges::input_range _Range, class _Allocator , class = __enable_if_t <__is_allocator<_Allocator>::value>>
1199
- flat_map (from_range_t , _Range&&, _Allocator)
1200
- -> flat_map<
1201
- __range_key_type<_Range>,
1202
- __range_mapped_type<_Range>,
1203
- less<__range_key_type<_Range>>,
1204
- vector<__range_key_type<_Range>, __allocator_traits_rebind_t <_Allocator, __range_key_type<_Range>>>,
1205
- vector<__range_mapped_type<_Range>, __allocator_traits_rebind_t <_Allocator, __range_mapped_type<_Range>>>>;
1151
+ flat_map (from_range_t , _Range&&, _Allocator) -> flat_map<
1152
+ __range_key_type<_Range>,
1153
+ __range_mapped_type<_Range>,
1154
+ less<__range_key_type<_Range>>,
1155
+ vector<__range_key_type<_Range>, __allocator_traits_rebind_t <_Allocator, __range_key_type<_Range>>>,
1156
+ vector<__range_mapped_type<_Range>, __allocator_traits_rebind_t <_Allocator, __range_mapped_type<_Range>>>>;
1206
1157
1207
1158
template <class _Key , class _Tp , class _Compare = less<_Key>>
1208
1159
requires (!__is_allocator<_Compare>::value)
0 commit comments