mirror of
https://github.com/boostorg/unordered.git
synced 2025-07-29 10:57:16 +02:00
refactored proxy_erase to reduce template instantiations and strengthen misuse avoidance
This commit is contained in:
committed by
Christian Mazakas
parent
2b6cfe4f3c
commit
2eebe157fd
@ -123,6 +123,7 @@ public:
|
||||
|
||||
private:
|
||||
template<typename,typename,bool> friend class table_iterator;
|
||||
template<typename> friend class table_erase_return_type;
|
||||
template<typename,typename,typename,typename> friend class table;
|
||||
|
||||
table_iterator(Group* pg,std::size_t n,const table_element_type* p_):
|
||||
@ -198,6 +199,45 @@ private:
|
||||
table_element_type *p=nullptr;
|
||||
};
|
||||
|
||||
/* Returned by table::erase([const_]iterator) to avoid iterator increment
|
||||
* if discarded.
|
||||
*/
|
||||
|
||||
template<typename Iterator>
|
||||
class table_erase_return_type;
|
||||
|
||||
template<typename TypePolicy,typename Group,bool Const>
|
||||
class table_erase_return_type<table_iterator<TypePolicy,Group,Const>>
|
||||
{
|
||||
using iterator=table_iterator<TypePolicy,Group,Const>;
|
||||
using const_iterator=table_iterator<TypePolicy,Group,true>;
|
||||
|
||||
public:
|
||||
/* can't delete it because VS in pre-C++17 mode needs to see it for RVO */
|
||||
table_erase_return_type(const table_erase_return_type&);
|
||||
|
||||
operator iterator()const noexcept
|
||||
{
|
||||
auto it=pos;
|
||||
it.increment(); /* valid even if *it was erased */
|
||||
return iterator(const_iterator_cast_tag{},it);
|
||||
}
|
||||
|
||||
template<
|
||||
bool dependent_value=false,
|
||||
typename std::enable_if<!Const||dependent_value>::type* =nullptr
|
||||
>
|
||||
operator const_iterator()const noexcept{return this->operator iterator();}
|
||||
|
||||
private:
|
||||
template<typename,typename,typename,typename> friend class table;
|
||||
|
||||
table_erase_return_type(const_iterator pos_):pos{pos_}{}
|
||||
table_erase_return_type& operator=(const table_erase_return_type&)=delete;
|
||||
|
||||
const_iterator pos;
|
||||
};
|
||||
|
||||
/* foa::table interface departs in a number of ways from that of C++ unordered
|
||||
* associative containers because it's not for end-user consumption
|
||||
* (boost::unordered_(flat|node)_(map|set) wrappers complete it as
|
||||
@ -271,6 +311,7 @@ public:
|
||||
has_mutable_iterator,
|
||||
table_iterator<type_policy,group_type,false>,
|
||||
const_iterator>::type;
|
||||
using erase_return_type=table_erase_return_type<iterator>;
|
||||
|
||||
table(
|
||||
std::size_t n=default_bucket_count,const Hash& h_=Hash(),
|
||||
@ -348,40 +389,19 @@ public:
|
||||
>::type
|
||||
insert(element_type&& x){return emplace_impl(std::move(x));}
|
||||
|
||||
struct proxy_erase {
|
||||
const_iterator pos;
|
||||
operator iterator()const noexcept
|
||||
{
|
||||
auto it=pos;
|
||||
it.increment();
|
||||
return iterator(const_iterator_cast_tag{},it);
|
||||
}
|
||||
|
||||
template<
|
||||
bool dependent_value=false,
|
||||
typename std::enable_if<
|
||||
has_mutable_iterator||dependent_value>::type* =nullptr
|
||||
>
|
||||
operator const_iterator()const noexcept
|
||||
{
|
||||
auto it=pos;
|
||||
it.increment();
|
||||
return it;
|
||||
}
|
||||
};
|
||||
|
||||
template<
|
||||
bool dependent_value=false,
|
||||
typename std::enable_if<
|
||||
has_mutable_iterator||dependent_value>::type* =nullptr
|
||||
>
|
||||
proxy_erase erase(iterator pos)noexcept{return erase(const_iterator(pos));}
|
||||
erase_return_type erase(iterator pos)noexcept
|
||||
{return erase(const_iterator(pos));}
|
||||
|
||||
BOOST_FORCEINLINE
|
||||
proxy_erase erase(const_iterator pos)noexcept
|
||||
erase_return_type erase(const_iterator pos)noexcept
|
||||
{
|
||||
super::erase(pos.pc,pos.p);
|
||||
return proxy_erase{pos};
|
||||
return {pos};
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
|
@ -381,12 +381,13 @@ namespace boost {
|
||||
.first;
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE typename table_type::proxy_erase erase(iterator pos)
|
||||
BOOST_FORCEINLINE typename table_type::erase_return_type erase(
|
||||
iterator pos)
|
||||
{
|
||||
return table_.erase(pos);
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE typename table_type::proxy_erase erase(
|
||||
BOOST_FORCEINLINE typename table_type::erase_return_type erase(
|
||||
const_iterator pos)
|
||||
{
|
||||
return table_.erase(pos);
|
||||
|
@ -282,7 +282,7 @@ namespace boost {
|
||||
return table_.emplace(std::forward<Args>(args)...).first;
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE typename table_type::proxy_erase erase(
|
||||
BOOST_FORCEINLINE typename table_type::erase_return_type erase(
|
||||
const_iterator pos)
|
||||
{
|
||||
return table_.erase(pos);
|
||||
|
@ -458,12 +458,13 @@ namespace boost {
|
||||
.first;
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE typename table_type::proxy_erase erase(iterator pos)
|
||||
BOOST_FORCEINLINE typename table_type::erase_return_type erase(
|
||||
iterator pos)
|
||||
{
|
||||
return table_.erase(pos);
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE typename table_type::proxy_erase erase(
|
||||
BOOST_FORCEINLINE typename table_type::erase_return_type erase(
|
||||
const_iterator pos)
|
||||
{
|
||||
return table_.erase(pos);
|
||||
|
@ -352,7 +352,7 @@ namespace boost {
|
||||
return table_.emplace(std::forward<Args>(args)...).first;
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE typename table_type::proxy_erase erase(
|
||||
BOOST_FORCEINLINE typename table_type::erase_return_type erase(
|
||||
const_iterator pos)
|
||||
{
|
||||
return table_.erase(pos);
|
||||
|
Reference in New Issue
Block a user