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>
@@ -860,22 +861,10 @@ class flat_map {
860861 __containers_.values .erase (__containers_.values .begin () + __dist, __containers_.values .end ());
861862 }
862863
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-
875864 template <bool _WasSorted, class _InputIterator , class _Sentinel >
876865 _LIBCPP_HIDE_FROM_ABI void __append_sort_merge_unique (_InputIterator __first, _Sentinel __last) {
877866 auto __on_failure = std::__make_exception_guard ([&]() noexcept { clear () /* noexcept */ ; });
878- size_t __num_of_appended = __append (std::move (__first), std::move (__last));
867+ size_t __num_of_appended = __flat_map_utils:: __append (* this , std::move (__first), std::move (__last));
879868 if (__num_of_appended != 0 ) {
880869 auto __zv = ranges::views::zip (__containers_.keys , __containers_.values );
881870 auto __append_start_offset = __containers_.keys .size () - __num_of_appended;
@@ -963,7 +952,8 @@ class flat_map {
963952
964953 if (__key_it == __containers_.keys .end () || __compare_ (__key, *__key_it)) {
965954 return pair<iterator, bool >(
966- __try_emplace_exact_hint (
955+ __flat_map_utils::__emplace_exact_pos (
956+ *this ,
967957 std::move (__key_it),
968958 std::move (__mapped_it),
969959 std::forward<_KeyArg>(__key),
@@ -989,10 +979,13 @@ class flat_map {
989979 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool > __try_emplace_hint (const_iterator __hint, _Kp&& __key, _Args&&... __args) {
990980 if (__is_hint_correct (__hint, __key)) {
991981 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 };
982+ return {__flat_map_utils::__emplace_exact_pos (
983+ *this ,
984+ __hint.__key_iter_ ,
985+ __hint.__mapped_iter_ ,
986+ std::forward<_Kp>(__key),
987+ std::forward<_Args>(__args)...),
988+ true };
996989 } else {
997990 // key equals
998991 auto __dist = __hint - cbegin ();
@@ -1003,49 +996,6 @@ class flat_map {
1003996 }
1004997 }
1005998
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-
1049999 template <class _Kp , class _Mapped >
10501000 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool > __insert_or_assign (_Kp&& __key, _Mapped&& __mapped) {
10511001 auto __r = try_emplace (std::forward<_Kp>(__key), std::forward<_Mapped>(__mapped));
@@ -1087,6 +1037,8 @@ class flat_map {
10871037 friend typename flat_map<_Key2, _Tp2, _Compare2, _KeyContainer2, _MappedContainer2>::size_type
10881038 erase_if (flat_map<_Key2, _Tp2, _Compare2, _KeyContainer2, _MappedContainer2>&, _Predicate);
10891039
1040+ friend __flat_map_utils;
1041+
10901042 containers __containers_;
10911043 [[no_unique_address]] key_compare __compare_;
10921044
@@ -1187,22 +1139,20 @@ template <ranges::input_range _Range,
11871139 class _Compare = less<__range_key_type<_Range>>,
11881140 class _Allocator = allocator<byte>,
11891141 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>>>>;
1142+ flat_map (from_range_t , _Range&&, _Compare = _Compare (), _Allocator = _Allocator ()) -> flat_map<
1143+ __range_key_type<_Range>,
1144+ __range_mapped_type<_Range>,
1145+ _Compare,
1146+ vector<__range_key_type<_Range>, __allocator_traits_rebind_t <_Allocator, __range_key_type<_Range>>>,
1147+ vector<__range_mapped_type<_Range>, __allocator_traits_rebind_t <_Allocator, __range_mapped_type<_Range>>>>;
11971148
11981149template <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>>>>;
1150+ flat_map (from_range_t , _Range&&, _Allocator) -> flat_map<
1151+ __range_key_type<_Range>,
1152+ __range_mapped_type<_Range>,
1153+ less<__range_key_type<_Range>>,
1154+ vector<__range_key_type<_Range>, __allocator_traits_rebind_t <_Allocator, __range_key_type<_Range>>>,
1155+ vector<__range_mapped_type<_Range>, __allocator_traits_rebind_t <_Allocator, __range_mapped_type<_Range>>>>;
12061156
12071157template <class _Key , class _Tp , class _Compare = less<_Key>>
12081158 requires (!__is_allocator<_Compare>::value)
0 commit comments