21
21
#include < __algorithm/ranges_upper_bound.h>
22
22
#include < __compare/synth_three_way.h>
23
23
#include < __concepts/convertible_to.h>
24
+ #include < __concepts/swappable.h>
24
25
#include < __config>
25
26
#include < __flat_map/container_traits.h>
26
27
#include < __flat_map/sorted_unique.h>
@@ -539,8 +540,8 @@ class flat_map {
539
540
}
540
541
541
542
template <class _Kp >
542
- requires __is_compare_transparent && is_constructible_v<key_type, _Kp> && is_constructible_v<mapped_type> &&
543
- is_convertible_v<_Kp&&, const_iterator> && is_convertible_v<_Kp&&, iterator>
543
+ requires ( __is_compare_transparent && is_constructible_v<key_type, _Kp> && is_constructible_v<mapped_type> &&
544
+ ! is_convertible_v<_Kp &&, const_iterator> && ! is_convertible_v<_Kp &&, iterator>)
544
545
_LIBCPP_HIDE_FROM_ABI mapped_type& operator [](_Kp&& __x) {
545
546
return try_emplace (std::forward<_Kp>(__x)).first ->second ;
546
547
}
@@ -597,7 +598,7 @@ class flat_map {
597
598
requires is_constructible_v<pair<key_type, mapped_type>, _Args...>
598
599
_LIBCPP_HIDE_FROM_ABI iterator emplace_hint (const_iterator __hint, _Args&&... __args) {
599
600
std::pair<key_type, mapped_type> __pair (std::forward<_Args>(__args)...);
600
- return __try_emplace_hint (__hint, std::move (__pair.first ), std::move (__pair.second ));
601
+ return __try_emplace_hint (__hint, std::move (__pair.first ), std::move (__pair.second )). first ;
601
602
}
602
603
603
604
_LIBCPP_HIDE_FROM_ABI pair<iterator, bool > insert (const value_type& __x) { return emplace (__x); }
@@ -689,67 +690,67 @@ class flat_map {
689
690
}
690
691
691
692
template <class _Kp , class ... _Args>
692
- requires __is_compare_transparent && is_constructible_v<key_type, _Kp> &&
693
- is_constructible_v<mapped_type, _Args...> && is_convertible_v<_Kp&&, const_iterator> &&
694
- is_convertible_v<_Kp&&, iterator>
693
+ requires ( __is_compare_transparent && is_constructible_v<key_type, _Kp> &&
694
+ is_constructible_v<mapped_type, _Args...> && ! is_convertible_v<_Kp &&, const_iterator> &&
695
+ ! is_convertible_v<_Kp &&, iterator>)
695
696
_LIBCPP_HIDE_FROM_ABI pair<iterator, bool > try_emplace (_Kp&& __key, _Args&&... __args) {
696
697
return __try_emplace (std::forward<_Kp>(__key), std::forward<_Args>(__args)...);
697
698
}
698
699
699
700
template <class ... _Args>
700
701
requires is_constructible_v<mapped_type, _Args...>
701
702
_LIBCPP_HIDE_FROM_ABI iterator try_emplace (const_iterator __hint, const key_type& __key, _Args&&... __args) {
702
- return __try_emplace_hint (__hint, __key, std::forward<_Args>(__args)...);
703
+ return __try_emplace_hint (__hint, __key, std::forward<_Args>(__args)...). first ;
703
704
}
704
705
705
706
template <class ... _Args>
706
707
requires is_constructible_v<mapped_type, _Args...>
707
708
_LIBCPP_HIDE_FROM_ABI iterator try_emplace (const_iterator __hint, key_type&& __key, _Args&&... __args) {
708
- return __try_emplace_hint (__hint, std::move (__key), std::forward<_Args>(__args)...);
709
+ return __try_emplace_hint (__hint, std::move (__key), std::forward<_Args>(__args)...). first ;
709
710
}
710
711
711
712
template <class _Kp , class ... _Args>
712
713
requires __is_compare_transparent && is_constructible_v<key_type, _Kp> && is_constructible_v<mapped_type, _Args...>
713
714
_LIBCPP_HIDE_FROM_ABI iterator try_emplace (const_iterator __hint, _Kp&& __key, _Args&&... __args) {
714
- return __try_emplace_hint (__hint, std::forward<_Kp>(__key), std::forward<_Args>(__args)...);
715
+ return __try_emplace_hint (__hint, std::forward<_Kp>(__key), std::forward<_Args>(__args)...). first ;
715
716
}
716
717
717
718
template <class _Mapped >
718
719
requires is_assignable_v<mapped_type&, _Mapped> && is_constructible_v<mapped_type, _Mapped>
719
720
_LIBCPP_HIDE_FROM_ABI pair<iterator, bool > insert_or_assign (const key_type& __key, _Mapped&& __obj) {
720
- return __insert_or_assign_impl (__key, std::forward<_Mapped>(__obj));
721
+ return __insert_or_assign (__key, std::forward<_Mapped>(__obj));
721
722
}
722
723
723
724
template <class _Mapped >
724
725
requires is_assignable_v<mapped_type&, _Mapped> && is_constructible_v<mapped_type, _Mapped>
725
726
_LIBCPP_HIDE_FROM_ABI pair<iterator, bool > insert_or_assign (key_type&& __key, _Mapped&& __obj) {
726
- return __insert_or_assign_impl (std::move (__key), std::forward<_Mapped>(__obj));
727
+ return __insert_or_assign (std::move (__key), std::forward<_Mapped>(__obj));
727
728
}
728
729
729
730
template <class _Kp , class _Mapped >
730
731
requires __is_compare_transparent && is_constructible_v<key_type, _Kp> && is_assignable_v<mapped_type&, _Mapped> &&
731
732
is_constructible_v<mapped_type, _Mapped>
732
733
_LIBCPP_HIDE_FROM_ABI pair<iterator, bool > insert_or_assign (_Kp&& __key, _Mapped&& __obj) {
733
- return __insert_or_assign_impl (std::forward<_Kp>(__key), std::forward<_Mapped>(__obj));
734
+ return __insert_or_assign (std::forward<_Kp>(__key), std::forward<_Mapped>(__obj));
734
735
}
735
736
736
737
template <class _Mapped >
737
738
requires is_assignable_v<mapped_type&, _Mapped> && is_constructible_v<mapped_type, _Mapped>
738
739
_LIBCPP_HIDE_FROM_ABI iterator insert_or_assign (const_iterator __hint, const key_type& __key, _Mapped&& __obj) {
739
- return __insert_or_assign_impl ( __key, std::forward<_Mapped>(__obj), __hint). first ;
740
+ return __insert_or_assign (__hint, __key, std::forward<_Mapped>(__obj)) ;
740
741
}
741
742
742
743
template <class _Mapped >
743
744
requires is_assignable_v<mapped_type&, _Mapped> && is_constructible_v<mapped_type, _Mapped>
744
745
_LIBCPP_HIDE_FROM_ABI iterator insert_or_assign (const_iterator __hint, key_type&& __key, _Mapped&& __obj) {
745
- return __insert_or_assign_impl ( std::move (__key), std::forward<_Mapped>(__obj), __hint). first ;
746
+ return __insert_or_assign (__hint, std::move (__key), std::forward<_Mapped>(__obj)) ;
746
747
}
747
748
748
749
template <class _Kp , class _Mapped >
749
750
requires __is_compare_transparent && is_constructible_v<key_type, _Kp> && is_assignable_v<mapped_type&, _Mapped> &&
750
751
is_constructible_v<mapped_type, _Mapped>
751
752
_LIBCPP_HIDE_FROM_ABI iterator insert_or_assign (const_iterator __hint, _Kp&& __key, _Mapped&& __obj) {
752
- return __insert_or_assign_impl ( std::forward<_Kp>(__key), std::forward<_Mapped>(__obj), __hint). first ;
753
+ return __insert_or_assign (__hint, std::forward<_Kp>(__key), std::forward<_Mapped>(__obj)) ;
753
754
}
754
755
755
756
_LIBCPP_HIDE_FROM_ABI iterator erase (iterator __position) {
@@ -788,15 +789,20 @@ class flat_map {
788
789
}
789
790
790
791
_LIBCPP_HIDE_FROM_ABI void swap (flat_map& __y) noexcept {
791
- auto __guard = std::__make_exception_guard ([&]() noexcept {
792
+ # ifndef _LIBCPP_HAS_NO_EXCEPTIONS
793
+ try {
794
+ # endif
795
+ ranges::swap (__compare_, __y.__compare_ );
796
+ ranges::swap (__containers_.keys , __y.__containers_ .keys );
797
+ ranges::swap (__containers_.values , __y.__containers_ .values );
798
+ # ifndef _LIBCPP_HAS_NO_EXCEPTIONS
799
+ } catch (...) {
800
+ // todo: how can we tell the user that the swap is unsuccessful?
801
+ // need to swallow the exception because the function is noexcept
792
802
clear () /* noexcept */ ;
793
803
__y.clear () /* noexcept*/ ;
794
- });
795
- using std::swap;
796
- swap (__compare_, __y.__compare_ );
797
- swap (__containers_.keys , __y.__containers_ .keys );
798
- swap (__containers_.values , __y.__containers_ .values );
799
- __guard.__complete ();
804
+ }
805
+ # endif
800
806
}
801
807
802
808
_LIBCPP_HIDE_FROM_ABI void clear () noexcept {
@@ -807,6 +813,8 @@ class flat_map {
807
813
// observers
808
814
_LIBCPP_HIDE_FROM_ABI key_compare key_comp () const { return __compare_; }
809
815
_LIBCPP_HIDE_FROM_ABI value_compare value_comp () const { return value_compare (__compare_); }
816
+
817
+ // todo: can flat_map | std::views::keys be specialised?
810
818
_LIBCPP_HIDE_FROM_ABI const key_container_type& keys () const noexcept { return __containers_.keys ; }
811
819
_LIBCPP_HIDE_FROM_ABI const mapped_container_type& values () const noexcept { return __containers_.values ; }
812
820
@@ -912,10 +920,10 @@ class flat_map {
912
920
913
921
private:
914
922
struct __ctor_uses_allocator_tag {
915
- explicit __ctor_uses_allocator_tag () = default;
923
+ explicit _LIBCPP_HIDE_FROM_ABI __ctor_uses_allocator_tag () = default;
916
924
};
917
925
struct __ctor_uses_allocator_empty_tag {
918
- explicit __ctor_uses_allocator_empty_tag () = default;
926
+ explicit _LIBCPP_HIDE_FROM_ABI __ctor_uses_allocator_empty_tag () = default;
919
927
};
920
928
921
929
template <class _Allocator , class _KeyCont , class _MappedCont , class ... _CompArg>
@@ -1085,18 +1093,20 @@ class flat_map {
1085
1093
}
1086
1094
1087
1095
template <class _Kp , class ... _Args>
1088
- _LIBCPP_HIDE_FROM_ABI iterator __try_emplace_hint (const_iterator __hint, _Kp&& __key, _Args&&... __args) {
1096
+ _LIBCPP_HIDE_FROM_ABI pair< iterator, bool > __try_emplace_hint (const_iterator __hint, _Kp&& __key, _Args&&... __args) {
1089
1097
if (__is_hint_correct (__hint, __key)) {
1090
1098
if (__hint == cend () || __compare_ (__key, __hint->first )) {
1091
- return __try_emplace_exact_hint (
1092
- __hint.__key_iter_ , __hint.__mapped_iter_ , std::forward<_Kp>(__key), std::forward<_Args>(__args)...);
1099
+ return {
1100
+ __try_emplace_exact_hint (
1101
+ __hint.__key_iter_ , __hint.__mapped_iter_ , std::forward<_Kp>(__key), std::forward<_Args>(__args)...),
1102
+ true };
1093
1103
} else {
1094
1104
// key equals
1095
1105
auto __dist = __hint - cbegin ();
1096
- return iterator (__containers_.keys .begin () + __dist, __containers_.values .begin () + __dist);
1106
+ return { iterator (__containers_.keys .begin () + __dist, __containers_.values .begin () + __dist), false } ;
1097
1107
}
1098
1108
} else {
1099
- return __try_emplace (std::forward<_Kp>(__key), std::forward<_Args>(__args)...). first ;
1109
+ return __try_emplace (std::forward<_Kp>(__key), std::forward<_Args>(__args)...);
1100
1110
}
1101
1111
}
1102
1112
@@ -1139,15 +1149,24 @@ class flat_map {
1139
1149
return iterator (std::move (__key_it), std::move (__mapped_it));
1140
1150
}
1141
1151
1142
- template <class _Kp , class _Mapped , class ... _Hint >
1143
- _LIBCPP_HIDE_FROM_ABI auto __insert_or_assign_impl (_Kp&& __key, _Mapped&& __mapped, _Hint&&... __hint ) {
1144
- auto __r = try_emplace (__hint..., std::forward<_Kp>(__key), std::forward<_Mapped>(__mapped));
1152
+ template <class _Kp , class _Mapped >
1153
+ _LIBCPP_HIDE_FROM_ABI pair<iterator, bool > __insert_or_assign (_Kp&& __key, _Mapped&& __mapped) {
1154
+ auto __r = try_emplace (std::forward<_Kp>(__key), std::forward<_Mapped>(__mapped));
1145
1155
if (!__r.second ) {
1146
1156
__r.first ->second = std::forward<_Mapped>(__mapped);
1147
1157
}
1148
1158
return __r;
1149
1159
}
1150
1160
1161
+ template <class _Kp , class _Mapped >
1162
+ _LIBCPP_HIDE_FROM_ABI iterator __insert_or_assign (const_iterator __hint, _Kp&& __key, _Mapped&& __mapped) {
1163
+ auto __r = __try_emplace_hint (__hint, std::forward<_Kp>(__key), std::forward<_Mapped>(__mapped));
1164
+ if (!__r.second ) {
1165
+ __r.first ->second = std::forward<_Mapped>(__mapped);
1166
+ }
1167
+ return __r.first ;
1168
+ }
1169
+
1151
1170
_LIBCPP_HIDE_FROM_ABI void __reserve (size_t __size) {
1152
1171
if constexpr (requires { __containers_.keys .reserve (__size); }) {
1153
1172
__containers_.keys .reserve (__size);
@@ -1175,8 +1194,8 @@ class flat_map {
1175
1194
[[no_unique_address]] key_compare __compare_;
1176
1195
1177
1196
struct __key_equiv {
1178
- __key_equiv (key_compare __c) : __comp_(__c) {}
1179
- bool operator ()(const_reference __x, const_reference __y) const {
1197
+ _LIBCPP_HIDE_FROM_ABI __key_equiv (key_compare __c) : __comp_(__c) {}
1198
+ _LIBCPP_HIDE_FROM_ABI bool operator ()(const_reference __x, const_reference __y) const {
1180
1199
// todo
1181
1200
// LWG issue ? spec uses __x.first but zip_view no longer uses pair
1182
1201
return !__comp_ (std::get<0 >(__x), std::get<0 >(__y)) && !__comp_ (std::get<0 >(__y), std::get<0 >(__x));
0 commit comments