mirror of
https://github.com/gcc-mirror/gcc.git
synced 2026-05-06 14:59:39 +02:00
libstdc++: Fix availability of std::erase_if(std::flat_foo) [PR119427]
These std::erase_if overloads were wrongly implemented as hidden friends, visible only via ADL, so erase_if(x) would work but not std::erase_if(x). PR libstdc++/119427 libstdc++-v3/ChangeLog: * include/std/flat_map (_Flat_map_impl::erase_if): Replace this hidden friend with ... (_Flat_map_impl::_M_erase_if): ... this member function. (flat_map): Export _Flat_map_impl::_M_erase_if. (erase_if(flat_map)): Define. (flat_multimap): Export _Flat_map_impl::_M_erase_if. (erase_if(flat_multimap)): Define. * include/std/flat_set (_Flat_set_impl::erase_if): Replace with ... (_Flat_set_impl::_M_erase_if): ... this member function. (flat_set): Export _Flat_set_impl::_M_erase_if. (erase_if(flat_set)): Define. (flat_multiset): Export _Flat_set_impl::_M_erase_if. (erase_if(flat_multiset)): Define. * testsuite/23_containers/flat_map/1.cc (test07): New test. * testsuite/23_containers/flat_multimap/1.cc (test07): New test. * testsuite/23_containers/flat_multiset/1.cc (test09): New test. * testsuite/23_containers/flat_set/1.cc (test09): New test. Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
This commit is contained in:
@@ -890,14 +890,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
{ return __x.swap(__y); }
|
||||
|
||||
template<typename _Predicate>
|
||||
friend size_type
|
||||
erase_if(_Derived& __c, _Predicate __pred)
|
||||
size_type
|
||||
_M_erase_if(_Predicate __pred)
|
||||
{
|
||||
auto __guard = __c._M_make_clear_guard();
|
||||
auto __zv = views::zip(__c._M_cont.keys, __c._M_cont.values);
|
||||
auto __guard = _M_make_clear_guard();
|
||||
auto __zv = views::zip(_M_cont.keys, _M_cont.values);
|
||||
auto __sr = ranges::remove_if(__zv, __pred);
|
||||
auto __erased = __sr.size();
|
||||
__c.erase(__c.end() - __erased, __c.end());
|
||||
erase(end() - __erased, end());
|
||||
__guard._M_disable();
|
||||
return __erased;
|
||||
}
|
||||
@@ -1329,6 +1329,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
using _Impl::lower_bound;
|
||||
using _Impl::upper_bound;
|
||||
using _Impl::equal_range;
|
||||
|
||||
using _Impl::_M_erase_if;
|
||||
};
|
||||
|
||||
template<typename _KeyContainer, typename _MappedContainer,
|
||||
@@ -1412,6 +1414,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
&& uses_allocator_v<_MappedContainer, _Alloc>>
|
||||
{ };
|
||||
|
||||
template<typename _Key, typename _Tp, typename _Compare,
|
||||
typename _KeyContainer, typename _MappedContainer, typename _Predicate>
|
||||
typename flat_map<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>::size_type
|
||||
erase_if(flat_map<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>& __c,
|
||||
_Predicate __pred)
|
||||
{ return __c._M_erase_if(std::move(__pred)); }
|
||||
|
||||
/* Class template flat_multimap - container adaptor
|
||||
*
|
||||
* @ingroup
|
||||
@@ -1487,6 +1496,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
using _Impl::lower_bound;
|
||||
using _Impl::upper_bound;
|
||||
using _Impl::equal_range;
|
||||
|
||||
using _Impl::_M_erase_if;
|
||||
};
|
||||
|
||||
template<typename _KeyContainer, typename _MappedContainer,
|
||||
@@ -1571,6 +1582,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
&& uses_allocator_v<_MappedContainer, _Alloc>>
|
||||
{ };
|
||||
|
||||
template<typename _Key, typename _Tp, typename _Compare,
|
||||
typename _KeyContainer, typename _MappedContainer, typename _Predicate>
|
||||
typename flat_multimap<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>::size_type
|
||||
erase_if(flat_multimap<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>& __c,
|
||||
_Predicate __pred)
|
||||
{ return __c._M_erase_if(std::move(__pred)); }
|
||||
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace std
|
||||
#endif // __cpp_lib_flat_map
|
||||
|
||||
@@ -745,15 +745,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
{ return __x.swap(__y); }
|
||||
|
||||
template<typename _Predicate>
|
||||
friend size_type
|
||||
erase_if(_Derived& __c, _Predicate __pred)
|
||||
size_type
|
||||
_M_erase_if(_Predicate __pred)
|
||||
{
|
||||
auto __guard = __c._M_make_clear_guard();
|
||||
auto __first = __c._M_cont.begin();
|
||||
auto __last = __c._M_cont.end();
|
||||
auto __guard = _M_make_clear_guard();
|
||||
auto __first = _M_cont.begin();
|
||||
auto __last = _M_cont.end();
|
||||
__first = std::remove_if(__first, __last, __pred);
|
||||
auto __n = __last - __first;
|
||||
__c.erase(__first, __last);
|
||||
erase(__first, __last);
|
||||
__guard._M_disable();
|
||||
return __n;
|
||||
}
|
||||
@@ -860,6 +860,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
using _Impl::lower_bound;
|
||||
using _Impl::upper_bound;
|
||||
using _Impl::equal_range;
|
||||
|
||||
using _Impl::_M_erase_if;
|
||||
};
|
||||
|
||||
template<typename _KeyContainer,
|
||||
@@ -930,6 +932,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
: bool_constant<uses_allocator_v<_KeyContainer, _Alloc>>
|
||||
{ };
|
||||
|
||||
template<typename _Key, typename _Compare, typename _KeyContainer,
|
||||
typename _Predicate>
|
||||
typename flat_set<_Key, _Compare, _KeyContainer>::size_type
|
||||
erase_if(flat_set<_Key, _Compare, _KeyContainer>& __c, _Predicate __pred)
|
||||
{ return __c._M_erase_if(std::move(__pred)); }
|
||||
|
||||
/* Class template flat_multiset - container adaptor
|
||||
*
|
||||
* @ingroup
|
||||
@@ -999,6 +1007,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
using _Impl::lower_bound;
|
||||
using _Impl::upper_bound;
|
||||
using _Impl::equal_range;
|
||||
|
||||
using _Impl::_M_erase_if;
|
||||
};
|
||||
|
||||
template<typename _KeyContainer,
|
||||
@@ -1069,6 +1079,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
: bool_constant<uses_allocator_v<_KeyContainer, _Alloc>>
|
||||
{ };
|
||||
|
||||
template<typename _Key, typename _Compare, typename _KeyContainer,
|
||||
typename _Predicate>
|
||||
typename flat_multiset<_Key, _Compare, _KeyContainer>::size_type
|
||||
erase_if(flat_multiset<_Key, _Compare, _KeyContainer>& __c, _Predicate __pred)
|
||||
{ return __c._M_erase_if(std::move(__pred)); }
|
||||
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace std
|
||||
#endif // __cpp_lib_flat_set
|
||||
|
||||
@@ -243,6 +243,16 @@ test06()
|
||||
VERIFY( std::ranges::equal(m | std::views::values, (int[]){2, 3, 4, 5, 6}) );
|
||||
}
|
||||
|
||||
void
|
||||
test07()
|
||||
{
|
||||
// PR libstdc++/119427 - std::erase_if(std::flat_foo) does not work
|
||||
std::flat_map<int, int> m = {std::pair{1, 2}, {3, 4}, {5, 6}};
|
||||
auto n = std::erase_if(m, [](auto x) { auto [k,v] = x; return k == 1 || v == 6; });
|
||||
VERIFY( n == 2 );
|
||||
VERIFY( std::ranges::equal(m, (std::pair<int,int>[]){{3,4}}) );
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
@@ -255,4 +265,5 @@ main()
|
||||
test04();
|
||||
test05();
|
||||
test06();
|
||||
test07();
|
||||
}
|
||||
|
||||
@@ -221,6 +221,16 @@ test06()
|
||||
VERIFY( std::ranges::equal(m | std::views::values, (int[]){2, 3, 4, 5, 6}) );
|
||||
}
|
||||
|
||||
void
|
||||
test07()
|
||||
{
|
||||
// PR libstdc++/119427 - std::erase_if(std::flat_foo) does not work
|
||||
std::flat_multimap<int, int> m = {std::pair{1, 2}, {3, 4}, {3, 3}, {5, 6}, {6, 6}};
|
||||
auto n = std::erase_if(m, [](auto x) { auto [k,v] = x; return k == 1 || v == 6; });
|
||||
VERIFY( n == 3 );
|
||||
VERIFY( std::ranges::equal(m, (std::pair<int,int>[]){{3,4},{3,3}}) );
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
@@ -233,4 +243,5 @@ main()
|
||||
test04();
|
||||
test05();
|
||||
test06();
|
||||
test07();
|
||||
}
|
||||
|
||||
@@ -235,6 +235,16 @@ test08()
|
||||
VERIFY( copy_counter == 2 );
|
||||
}
|
||||
|
||||
void
|
||||
test09()
|
||||
{
|
||||
// PR libstdc++/119427 - std::erase_if(std::flat_foo) does not work
|
||||
std::flat_multiset<int> s = {1,1,2,2,3,4,5};
|
||||
auto n = std::erase_if(s, [](int x) { return x % 2 != 0; });
|
||||
VERIFY( n == 4 );
|
||||
VERIFY( std::ranges::equal(s, (int[]){2,2,4}) );
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
@@ -247,4 +257,5 @@ main()
|
||||
test06();
|
||||
test07();
|
||||
test08();
|
||||
test09();
|
||||
}
|
||||
|
||||
@@ -248,6 +248,16 @@ test08()
|
||||
VERIFY( copy_counter == 1 );
|
||||
}
|
||||
|
||||
void
|
||||
test09()
|
||||
{
|
||||
// PR libstdc++/119427 - std::erase_if(std::flat_foo) does not work
|
||||
std::flat_set<int> s = {1,2,3,4,5};
|
||||
auto n = std::erase_if(s, [](int x) { return x % 2 != 0; });
|
||||
VERIFY( n == 3 );
|
||||
VERIFY( std::ranges::equal(s, (int[]){2,4}) );
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
@@ -260,4 +270,5 @@ main()
|
||||
test06();
|
||||
test07();
|
||||
test08();
|
||||
test09();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user