2929#include < __cstddef/ptrdiff_t.h>
3030#include < __flat_map/key_value_iterator.h>
3131#include < __flat_map/sorted_unique.h>
32+ #include < __flat_map/utils.h>
3233#include < __functional/invoke.h>
3334#include < __functional/is_transparent.h>
3435#include < __functional/operations.h>
@@ -862,22 +863,10 @@ class flat_map {
862863 __containers_.values .erase (__containers_.values .begin () + __dist, __containers_.values .end ());
863864 }
864865
865- template <class _InputIterator , class _Sentinel >
866- _LIBCPP_HIDE_FROM_ABI size_type __append (_InputIterator __first, _Sentinel __last) {
867- size_type __num_of_appended = 0 ;
868- for (; __first != __last; ++__first) {
869- value_type __kv = *__first;
870- __containers_.keys .insert (__containers_.keys .end (), std::move (__kv.first ));
871- __containers_.values .insert (__containers_.values .end (), std::move (__kv.second ));
872- ++__num_of_appended;
873- }
874- return __num_of_appended;
875- }
876-
877866 template <bool _WasSorted, class _InputIterator , class _Sentinel >
878867 _LIBCPP_HIDE_FROM_ABI void __append_sort_merge_unique (_InputIterator __first, _Sentinel __last) {
879868 auto __on_failure = std::__make_exception_guard ([&]() noexcept { clear () /* noexcept */ ; });
880- size_t __num_of_appended = __append (std::move (__first), std::move (__last));
869+ size_t __num_of_appended = __flat_map_utils:: __append (* this , std::move (__first), std::move (__last));
881870 if (__num_of_appended != 0 ) {
882871 auto __zv = ranges::views::zip (__containers_.keys , __containers_.values );
883872 auto __append_start_offset = __containers_.keys .size () - __num_of_appended;
@@ -965,7 +954,8 @@ class flat_map {
965954
966955 if (__key_it == __containers_.keys .end () || __compare_ (__key, *__key_it)) {
967956 return pair<iterator, bool >(
968- __try_emplace_exact_hint (
957+ __flat_map_utils::__emplace_exact_pos (
958+ *this ,
969959 std::move (__key_it),
970960 std::move (__mapped_it),
971961 std::forward<_KeyArg>(__key),
@@ -991,10 +981,13 @@ class flat_map {
991981 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool > __try_emplace_hint (const_iterator __hint, _Kp&& __key, _Args&&... __args) {
992982 if (__is_hint_correct (__hint, __key)) {
993983 if (__hint == cend () || __compare_ (__key, __hint->first )) {
994- return {
995- __try_emplace_exact_hint (
996- __hint.__key_iter_ , __hint.__mapped_iter_ , std::forward<_Kp>(__key), std::forward<_Args>(__args)...),
997- true };
984+ return {__flat_map_utils::__emplace_exact_pos (
985+ *this ,
986+ __hint.__key_iter_ ,
987+ __hint.__mapped_iter_ ,
988+ std::forward<_Kp>(__key),
989+ std::forward<_Args>(__args)...),
990+ true };
998991 } else {
999992 // key equals
1000993 auto __dist = __hint - cbegin ();
@@ -1005,49 +998,6 @@ class flat_map {
1005998 }
1006999 }
10071000
1008- template <class _IterK , class _IterM , class _KeyArg , class ... _MArgs>
1009- _LIBCPP_HIDE_FROM_ABI iterator
1010- __try_emplace_exact_hint (_IterK&& __it_key, _IterM&& __it_mapped, _KeyArg&& __key, _MArgs&&... __mapped_args) {
1011- auto __on_key_failed = std::__make_exception_guard ([&]() noexcept {
1012- if constexpr (__container_traits<_KeyContainer>::__emplacement_has_strong_exception_safety_guarantee) {
1013- // Nothing to roll back!
1014- } else {
1015- // we need to clear both because we don't know the state of our keys anymore
1016- clear () /* noexcept */ ;
1017- }
1018- });
1019- auto __key_it = __containers_.keys .emplace (__it_key, std::forward<_KeyArg>(__key));
1020- __on_key_failed.__complete ();
1021-
1022- auto __on_value_failed = std::__make_exception_guard ([&]() noexcept {
1023- if constexpr (!__container_traits<_MappedContainer>::__emplacement_has_strong_exception_safety_guarantee) {
1024- // we need to clear both because we don't know the state of our values anymore
1025- clear () /* noexcept */ ;
1026- } else {
1027- // In this case, we know the values are just like before we attempted emplacement,
1028- // and we also know that the keys have been emplaced successfully. Just roll back the keys.
1029- # if _LIBCPP_HAS_EXCEPTIONS
1030- try {
1031- # endif // _LIBCPP_HAS_EXCEPTIONS
1032- __containers_.keys .erase (__key_it);
1033- # if _LIBCPP_HAS_EXCEPTIONS
1034- } catch (...) {
1035- // Now things are funky for real. We're failing to rollback the keys.
1036- // Just give up and clear the whole thing.
1037- //
1038- // Also, swallow the exception that happened during the rollback and let the
1039- // original value-emplacement exception propagate normally.
1040- clear () /* noexcept */ ;
1041- }
1042- # endif // _LIBCPP_HAS_EXCEPTIONS
1043- }
1044- });
1045- auto __mapped_it = __containers_.values .emplace (__it_mapped, std::forward<_MArgs>(__mapped_args)...);
1046- __on_value_failed.__complete ();
1047-
1048- return iterator (std::move (__key_it), std::move (__mapped_it));
1049- }
1050-
10511001 template <class _Kp , class _Mapped >
10521002 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool > __insert_or_assign (_Kp&& __key, _Mapped&& __mapped) {
10531003 auto __r = try_emplace (std::forward<_Kp>(__key), std::forward<_Mapped>(__mapped));
@@ -1089,6 +1039,8 @@ class flat_map {
10891039 friend typename flat_map<_Key2, _Tp2, _Compare2, _KeyContainer2, _MappedContainer2>::size_type
10901040 erase_if (flat_map<_Key2, _Tp2, _Compare2, _KeyContainer2, _MappedContainer2>&, _Predicate);
10911041
1042+ friend __flat_map_utils;
1043+
10921044 containers __containers_;
10931045 [[no_unique_address]] key_compare __compare_;
10941046
@@ -1189,22 +1141,20 @@ template <ranges::input_range _Range,
11891141 class _Compare = less<__range_key_type<_Range>>,
11901142 class _Allocator = allocator<byte>,
11911143 class = __enable_if_t <!__is_allocator<_Compare>::value && __is_allocator<_Allocator>::value>>
1192- flat_map (from_range_t , _Range&&, _Compare = _Compare (), _Allocator = _Allocator ())
1193- ->flat_map <
1194- __range_key_type<_Range>,
1195- __range_mapped_type<_Range>,
1196- _Compare,
1197- vector<__range_key_type<_Range>, __allocator_traits_rebind_t <_Allocator, __range_key_type<_Range>>>,
1198- vector<__range_mapped_type<_Range>, __allocator_traits_rebind_t <_Allocator, __range_mapped_type<_Range>>>>;
1144+ flat_map (from_range_t , _Range&&, _Compare = _Compare (), _Allocator = _Allocator ()) -> flat_map<
1145+ __range_key_type<_Range>,
1146+ __range_mapped_type<_Range>,
1147+ _Compare,
1148+ vector<__range_key_type<_Range>, __allocator_traits_rebind_t <_Allocator, __range_key_type<_Range>>>,
1149+ vector<__range_mapped_type<_Range>, __allocator_traits_rebind_t <_Allocator, __range_mapped_type<_Range>>>>;
11991150
12001151template <ranges::input_range _Range, class _Allocator , class = __enable_if_t <__is_allocator<_Allocator>::value>>
1201- flat_map (from_range_t , _Range&&, _Allocator)
1202- ->flat_map <
1203- __range_key_type<_Range>,
1204- __range_mapped_type<_Range>,
1205- less<__range_key_type<_Range>>,
1206- vector<__range_key_type<_Range>, __allocator_traits_rebind_t <_Allocator, __range_key_type<_Range>>>,
1207- vector<__range_mapped_type<_Range>, __allocator_traits_rebind_t <_Allocator, __range_mapped_type<_Range>>>>;
1152+ flat_map (from_range_t , _Range&&, _Allocator) -> flat_map<
1153+ __range_key_type<_Range>,
1154+ __range_mapped_type<_Range>,
1155+ less<__range_key_type<_Range>>,
1156+ vector<__range_key_type<_Range>, __allocator_traits_rebind_t <_Allocator, __range_key_type<_Range>>>,
1157+ vector<__range_mapped_type<_Range>, __allocator_traits_rebind_t <_Allocator, __range_mapped_type<_Range>>>>;
12081158
12091159template <class _Key , class _Tp , class _Compare = less<_Key>>
12101160 requires (!__is_allocator<_Compare>::value)
0 commit comments