mirror of
https://github.com/boostorg/unordered.git
synced 2025-07-31 03:47:16 +02:00
refactored to provide equality comparison from table_core
This commit is contained in:
@ -766,6 +766,25 @@ namespace boost {
|
|||||||
|
|
||||||
hasher hash_function() const { return table_.hash_function(); }
|
hasher hash_function() const { return table_.hash_function(); }
|
||||||
key_equal key_eq() const { return table_.key_eq(); }
|
key_equal key_eq() const { return table_.key_eq(); }
|
||||||
|
|
||||||
|
/// Equality
|
||||||
|
///
|
||||||
|
|
||||||
|
template <class Key, class Hash, class KeyEqual, class Allocator>
|
||||||
|
friend bool operator==(
|
||||||
|
concurrent_flat_map<Key, Hash, KeyEqual, Allocator> const& lhs,
|
||||||
|
concurrent_flat_map<Key, Hash, KeyEqual, Allocator> const& rhs)
|
||||||
|
{
|
||||||
|
return lhs.table_ == rhs.table_;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Key, class Hash, class KeyEqual, class Allocator>
|
||||||
|
friend bool operator!=(
|
||||||
|
concurrent_flat_map<Key, Hash, KeyEqual, Allocator> const& lhs,
|
||||||
|
concurrent_flat_map<Key, Hash, KeyEqual, Allocator> const& rhs)
|
||||||
|
{
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
} // namespace unordered
|
} // namespace unordered
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
@ -697,13 +697,13 @@ public:
|
|||||||
boost::ignore_unused<super2>();
|
boost::ignore_unused<super2>();
|
||||||
|
|
||||||
auto lck=exclusive_access(*this,x);
|
auto lck=exclusive_access(*this,x);
|
||||||
size_type s=unprotected_size();
|
size_type s=super::size();
|
||||||
x.super2::for_all_elements( /* super2::for_all_elements -> unprotected */
|
x.super2::for_all_elements( /* super2::for_all_elements -> unprotected */
|
||||||
[&,this](group_type* pg,unsigned int n,element_type* p){
|
[&,this](group_type* pg,unsigned int n,element_type* p){
|
||||||
typename merge_table_type::erase_on_exit e{x,pg,n,p};
|
typename merge_table_type::erase_on_exit e{x,pg,n,p};
|
||||||
if(!unprotected_emplace(type_policy::move(*p)))e.rollback();
|
if(!unprotected_emplace(type_policy::move(*p)))e.rollback();
|
||||||
});
|
});
|
||||||
return size_type{unprotected_size()-s};
|
return size_type{super::size()-s};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Hash2,typename Pred2>
|
template<typename Hash2,typename Pred2>
|
||||||
@ -773,6 +773,17 @@ public:
|
|||||||
return x.erase_if(std::forward<Predicate>(pr));
|
return x.erase_if(std::forward<Predicate>(pr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
friend bool operator==(const concurrent_table& x,const concurrent_table& y)
|
||||||
|
{
|
||||||
|
auto lck=exclusive_access(x,y);
|
||||||
|
return static_cast<const super&>(x)==static_cast<const super&>(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator!=(const concurrent_table& x,const concurrent_table& y)
|
||||||
|
{
|
||||||
|
return !(x==y);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using mutex_type=cacheline_protected<rw_spinlock>;
|
using mutex_type=cacheline_protected<rw_spinlock>;
|
||||||
using multimutex_type=multimutex<mutex_type,128>; // TODO: adapt 128 to the machine
|
using multimutex_type=multimutex<mutex_type,128>; // TODO: adapt 128 to the machine
|
||||||
@ -806,14 +817,14 @@ private:
|
|||||||
return exclusive_lock_guard{mutexes};
|
return exclusive_lock_guard{mutexes};
|
||||||
}
|
}
|
||||||
|
|
||||||
inline exclusive_bilock_guard exclusive_access(
|
static inline exclusive_bilock_guard exclusive_access(
|
||||||
const concurrent_table& x,const concurrent_table& y)
|
const concurrent_table& x,const concurrent_table& y)
|
||||||
{
|
{
|
||||||
return {x.mutexes,y.mutexes};
|
return {x.mutexes,y.mutexes};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Hash2,typename Pred2>
|
template<typename Hash2,typename Pred2>
|
||||||
inline exclusive_bilock_guard exclusive_access(
|
static inline exclusive_bilock_guard exclusive_access(
|
||||||
const concurrent_table& x,
|
const concurrent_table& x,
|
||||||
const concurrent_table<TypePolicy,Hash2,Pred2,Allocator>& y)
|
const concurrent_table<TypePolicy,Hash2,Pred2,Allocator>& y)
|
||||||
{
|
{
|
||||||
@ -1079,9 +1090,7 @@ private:
|
|||||||
auto hash=this->hash_for(k);
|
auto hash=this->hash_for(k);
|
||||||
auto pos0=this->position_for(hash);
|
auto pos0=this->position_for(hash);
|
||||||
|
|
||||||
// TODO: could be made more efficient (nonconcurrent scenario)
|
if(!this->find(k,pos0,hash))return false;
|
||||||
if(unprotected_visit(
|
|
||||||
group_shared{},k,pos0,hash,[](const value_type&){}))return false;
|
|
||||||
|
|
||||||
if(BOOST_LIKELY(this->size_<this->ml)){
|
if(BOOST_LIKELY(this->size_<this->ml)){
|
||||||
this->unchecked_emplace_at(pos0,hash,std::forward<Args>(args)...);
|
this->unchecked_emplace_at(pos0,hash,std::forward<Args>(args)...);
|
||||||
|
@ -1097,9 +1097,14 @@ static constexpr float mlf=0.875f;
|
|||||||
template<typename Group,typename Element>
|
template<typename Group,typename Element>
|
||||||
struct table_locator
|
struct table_locator
|
||||||
{
|
{
|
||||||
Group *pg;
|
table_locator()=default;
|
||||||
unsigned int n;
|
table_locator(Group* pg_,unsigned int n_,Element* p_):pg{pg_},n{n_},p{p_}{}
|
||||||
Element *p;
|
|
||||||
|
explicit operator bool()const noexcept{return p!=nullptr;}
|
||||||
|
|
||||||
|
Group *pg=nullptr;
|
||||||
|
unsigned int n=0;
|
||||||
|
Element *p=nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct try_emplace_args_t{};
|
struct try_emplace_args_t{};
|
||||||
@ -1425,6 +1430,52 @@ public:
|
|||||||
recover_slot(pc);
|
recover_slot(pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Key>
|
||||||
|
BOOST_FORCEINLINE locator find(const Key& x)const
|
||||||
|
{
|
||||||
|
auto hash=hash_for(x);
|
||||||
|
return find(x,position_for(hash),hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(BOOST_MSVC)
|
||||||
|
/* warning: forcing value to bool 'true' or 'false' in bool(pred()...) */
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable:4800)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<typename Key>
|
||||||
|
BOOST_FORCEINLINE locator find(
|
||||||
|
const Key& x,std::size_t pos0,std::size_t hash)const
|
||||||
|
{
|
||||||
|
prober pb(pos0);
|
||||||
|
do{
|
||||||
|
auto pos=pb.get();
|
||||||
|
auto pg=arrays.groups+pos;
|
||||||
|
auto mask=pg->match(hash);
|
||||||
|
if(mask){
|
||||||
|
BOOST_UNORDERED_ASSUME(arrays.elements!=nullptr);
|
||||||
|
auto p=arrays.elements+pos*N;
|
||||||
|
prefetch_elements(p);
|
||||||
|
do{
|
||||||
|
auto n=unchecked_countr_zero(mask);
|
||||||
|
if(BOOST_LIKELY(bool(pred()(x,key_from(p[n]))))){
|
||||||
|
return {pg,n,p+n};
|
||||||
|
}
|
||||||
|
mask&=mask-1;
|
||||||
|
}while(mask);
|
||||||
|
}
|
||||||
|
if(BOOST_LIKELY(pg->is_not_overflowed(hash))){
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while(BOOST_LIKELY(pb.next(arrays.groups_size_mask)));
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(BOOST_MSVC)
|
||||||
|
#pragma warning(pop) /* C4800 */
|
||||||
|
#endif
|
||||||
|
|
||||||
void swap(table_core& x)
|
void swap(table_core& x)
|
||||||
noexcept(
|
noexcept(
|
||||||
alloc_traits::propagate_on_container_swap::value||
|
alloc_traits::propagate_on_container_swap::value||
|
||||||
@ -1503,6 +1554,23 @@ public:
|
|||||||
rehash(std::size_t(std::ceil(float(n)/mlf)));
|
rehash(std::size_t(std::ceil(float(n)/mlf)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
friend bool operator==(const table_core& x,const table_core& y)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
x.size()==y.size()&&
|
||||||
|
x.for_all_elements_while([&](element_type* p){
|
||||||
|
auto loc=y.find(key_from(*p));
|
||||||
|
return loc&&
|
||||||
|
const_cast<const value_type&>(type_policy::value_from(*p))==
|
||||||
|
const_cast<const value_type&>(type_policy::value_from(*loc.p));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator!=(const table_core& x,const table_core& y)
|
||||||
|
{
|
||||||
|
return !(x==y);
|
||||||
|
}
|
||||||
|
|
||||||
struct clear_on_exit
|
struct clear_on_exit
|
||||||
{
|
{
|
||||||
~clear_on_exit(){x.clear();}
|
~clear_on_exit(){x.clear();}
|
||||||
@ -1683,34 +1751,36 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
void for_all_elements_while(F f)const
|
bool for_all_elements_while(F f)const
|
||||||
{
|
{
|
||||||
for_all_elements_while(arrays,f);
|
return for_all_elements_while(arrays,f);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
static auto for_all_elements_while(const arrays_type& arrays_,F f)
|
static auto for_all_elements_while(const arrays_type& arrays_,F f)
|
||||||
->decltype(f(nullptr),void())
|
->decltype(f(nullptr),bool())
|
||||||
{
|
{
|
||||||
for_all_elements_while(
|
return for_all_elements_while(
|
||||||
arrays_,[&](group_type*,unsigned int,element_type* p){return f(p);});
|
arrays_,[&](group_type*,unsigned int,element_type* p){return f(p);});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
static auto for_all_elements_while(const arrays_type& arrays_,F f)
|
static auto for_all_elements_while(const arrays_type& arrays_,F f)
|
||||||
->decltype(f(nullptr,0,nullptr),void())
|
->decltype(f(nullptr,0,nullptr),bool())
|
||||||
{
|
{
|
||||||
auto p=arrays_.elements;
|
auto p=arrays_.elements;
|
||||||
if(!p){return;}
|
if(p){
|
||||||
for(auto pg=arrays_.groups,last=pg+arrays_.groups_size_mask+1;
|
for(auto pg=arrays_.groups,last=pg+arrays_.groups_size_mask+1;
|
||||||
pg!=last;++pg,p+=N){
|
pg!=last;++pg,p+=N){
|
||||||
auto mask=match_really_occupied(pg,last);
|
auto mask=match_really_occupied(pg,last);
|
||||||
while(mask){
|
while(mask){
|
||||||
auto n=unchecked_countr_zero(mask);
|
auto n=unchecked_countr_zero(mask);
|
||||||
if(!f(pg,n,p+n))return;
|
if(!f(pg,n,p+n))return false;
|
||||||
mask&=mask-1;
|
mask&=mask-1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
arrays_type arrays;
|
arrays_type arrays;
|
||||||
|
@ -404,8 +404,7 @@ public:
|
|||||||
template<typename Key>
|
template<typename Key>
|
||||||
BOOST_FORCEINLINE iterator find(const Key& x)
|
BOOST_FORCEINLINE iterator find(const Key& x)
|
||||||
{
|
{
|
||||||
auto hash=this->hash_for(x);
|
return make_iterator(super::find(x));
|
||||||
return find_impl(x,this->position_for(hash),hash);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Key>
|
template<typename Key>
|
||||||
@ -440,6 +439,13 @@ public:
|
|||||||
return std::size_t(s-x.size());
|
return std::size_t(s-x.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
friend bool operator==(const table& x,const table& y)
|
||||||
|
{
|
||||||
|
return static_cast<const super&>(x)==static_cast<const super&>(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator!=(const table& x,const table& y){return !(x==y);}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct erase_on_exit
|
struct erase_on_exit
|
||||||
{
|
{
|
||||||
@ -458,55 +464,16 @@ private:
|
|||||||
return {l.pg,l.n,l.p};
|
return {l.pg,l.n,l.p};
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(BOOST_MSVC)
|
|
||||||
/* warning: forcing value to bool 'true' or 'false' in bool(pred()...) */
|
|
||||||
#pragma warning(push)
|
|
||||||
#pragma warning(disable:4800)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<typename Key>
|
|
||||||
BOOST_FORCEINLINE iterator find_impl(
|
|
||||||
const Key& x,std::size_t pos0,std::size_t hash)const
|
|
||||||
{
|
|
||||||
prober pb(pos0);
|
|
||||||
do{
|
|
||||||
auto pos=pb.get();
|
|
||||||
auto pg=this->arrays.groups+pos;
|
|
||||||
auto mask=pg->match(hash);
|
|
||||||
if(mask){
|
|
||||||
BOOST_UNORDERED_ASSUME(this->arrays.elements!=nullptr);
|
|
||||||
auto p=this->arrays.elements+pos*N;
|
|
||||||
this->prefetch_elements(p);
|
|
||||||
do{
|
|
||||||
auto n=unchecked_countr_zero(mask);
|
|
||||||
if(BOOST_LIKELY(bool(this->pred()(x,this->key_from(p[n]))))){
|
|
||||||
return {pg,n,p+n};
|
|
||||||
}
|
|
||||||
mask&=mask-1;
|
|
||||||
}while(mask);
|
|
||||||
}
|
|
||||||
if(BOOST_LIKELY(pg->is_not_overflowed(hash))){
|
|
||||||
return {}; /* end() */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while(BOOST_LIKELY(pb.next(this->arrays.groups_size_mask)));
|
|
||||||
return {}; /* end() */
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(BOOST_MSVC)
|
|
||||||
#pragma warning(pop) /* C4800 */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
BOOST_FORCEINLINE std::pair<iterator,bool> emplace_impl(Args&&... args)
|
BOOST_FORCEINLINE std::pair<iterator,bool> emplace_impl(Args&&... args)
|
||||||
{
|
{
|
||||||
const auto &k=this->key_from(std::forward<Args>(args)...);
|
const auto &k=this->key_from(std::forward<Args>(args)...);
|
||||||
auto hash=this->hash_for(k);
|
auto hash=this->hash_for(k);
|
||||||
auto pos0=this->position_for(hash);
|
auto pos0=this->position_for(hash);
|
||||||
auto it=find_impl(k,pos0,hash);
|
auto loc=super::find(k,pos0,hash);
|
||||||
|
|
||||||
if(it!=end()){
|
if(loc){
|
||||||
return {it,false};
|
return {make_iterator(loc),false};
|
||||||
}
|
}
|
||||||
if(BOOST_LIKELY(this->size_<this->ml)){
|
if(BOOST_LIKELY(this->size_<this->ml)){
|
||||||
return {
|
return {
|
||||||
|
@ -695,35 +695,26 @@ namespace boost {
|
|||||||
hasher hash_function() const { return table_.hash_function(); }
|
hasher hash_function() const { return table_.hash_function(); }
|
||||||
|
|
||||||
key_equal key_eq() const { return table_.key_eq(); }
|
key_equal key_eq() const { return table_.key_eq(); }
|
||||||
};
|
|
||||||
|
|
||||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
/// Equality
|
||||||
bool operator==(
|
///
|
||||||
unordered_flat_map<Key, T, Hash, KeyEqual, Allocator> const& lhs,
|
|
||||||
unordered_flat_map<Key, T, Hash, KeyEqual, Allocator> const& rhs)
|
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||||
{
|
friend bool operator==(
|
||||||
if (&lhs == &rhs) {
|
unordered_flat_map<Key, T, Hash, KeyEqual, Allocator> const& lhs,
|
||||||
return true;
|
unordered_flat_map<Key, T, Hash, KeyEqual, Allocator> const& rhs)
|
||||||
|
{
|
||||||
|
return lhs.table_ == rhs.table_;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (lhs.size() == rhs.size()) && ([&] {
|
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||||
for (auto const& kvp : lhs) {
|
friend bool operator!=(
|
||||||
auto pos = rhs.find(kvp.first);
|
unordered_flat_map<Key, T, Hash, KeyEqual, Allocator> const& lhs,
|
||||||
if ((pos == rhs.end()) || (*pos != kvp)) {
|
unordered_flat_map<Key, T, Hash, KeyEqual, Allocator> const& rhs)
|
||||||
return false;
|
{
|
||||||
}
|
return !(lhs == rhs);
|
||||||
}
|
}
|
||||||
return true;
|
};
|
||||||
})();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
|
||||||
bool operator!=(
|
|
||||||
unordered_flat_map<Key, T, Hash, KeyEqual, Allocator> const& lhs,
|
|
||||||
unordered_flat_map<Key, T, Hash, KeyEqual, Allocator> const& rhs)
|
|
||||||
{
|
|
||||||
return !(lhs == rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||||
void swap(unordered_flat_map<Key, T, Hash, KeyEqual, Allocator>& lhs,
|
void swap(unordered_flat_map<Key, T, Hash, KeyEqual, Allocator>& lhs,
|
||||||
|
@ -492,35 +492,26 @@ namespace boost {
|
|||||||
hasher hash_function() const { return table_.hash_function(); }
|
hasher hash_function() const { return table_.hash_function(); }
|
||||||
|
|
||||||
key_equal key_eq() const { return table_.key_eq(); }
|
key_equal key_eq() const { return table_.key_eq(); }
|
||||||
};
|
|
||||||
|
|
||||||
template <class Key, class Hash, class KeyEqual, class Allocator>
|
/// Equality
|
||||||
bool operator==(
|
///
|
||||||
unordered_flat_set<Key, Hash, KeyEqual, Allocator> const& lhs,
|
|
||||||
unordered_flat_set<Key, Hash, KeyEqual, Allocator> const& rhs)
|
template <class Key, class Hash, class KeyEqual, class Allocator>
|
||||||
{
|
friend bool operator==(
|
||||||
if (&lhs == &rhs) {
|
unordered_flat_set<Key, Hash, KeyEqual, Allocator> const& lhs,
|
||||||
return true;
|
unordered_flat_set<Key, Hash, KeyEqual, Allocator> const& rhs)
|
||||||
|
{
|
||||||
|
return lhs.table_ == rhs.table_;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (lhs.size() == rhs.size()) && ([&] {
|
template <class Key, class Hash, class KeyEqual, class Allocator>
|
||||||
for (auto const& key : lhs) {
|
friend bool operator!=(
|
||||||
auto pos = rhs.find(key);
|
unordered_flat_set<Key, Hash, KeyEqual, Allocator> const& lhs,
|
||||||
if ((pos == rhs.end()) || (key != *pos)) {
|
unordered_flat_set<Key, Hash, KeyEqual, Allocator> const& rhs)
|
||||||
return false;
|
{
|
||||||
}
|
return !(lhs == rhs);
|
||||||
}
|
}
|
||||||
return true;
|
};
|
||||||
})();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Key, class Hash, class KeyEqual, class Allocator>
|
|
||||||
bool operator!=(
|
|
||||||
unordered_flat_set<Key, Hash, KeyEqual, Allocator> const& lhs,
|
|
||||||
unordered_flat_set<Key, Hash, KeyEqual, Allocator> const& rhs)
|
|
||||||
{
|
|
||||||
return !(lhs == rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Key, class Hash, class KeyEqual, class Allocator>
|
template <class Key, class Hash, class KeyEqual, class Allocator>
|
||||||
void swap(unordered_flat_set<Key, Hash, KeyEqual, Allocator>& lhs,
|
void swap(unordered_flat_set<Key, Hash, KeyEqual, Allocator>& lhs,
|
||||||
|
@ -847,35 +847,26 @@ namespace boost {
|
|||||||
hasher hash_function() const { return table_.hash_function(); }
|
hasher hash_function() const { return table_.hash_function(); }
|
||||||
|
|
||||||
key_equal key_eq() const { return table_.key_eq(); }
|
key_equal key_eq() const { return table_.key_eq(); }
|
||||||
};
|
|
||||||
|
|
||||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
/// Equality
|
||||||
bool operator==(
|
///
|
||||||
unordered_node_map<Key, T, Hash, KeyEqual, Allocator> const& lhs,
|
|
||||||
unordered_node_map<Key, T, Hash, KeyEqual, Allocator> const& rhs)
|
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||||
{
|
friend bool operator==(
|
||||||
if (&lhs == &rhs) {
|
unordered_node_map<Key, T, Hash, KeyEqual, Allocator> const& lhs,
|
||||||
return true;
|
unordered_node_map<Key, T, Hash, KeyEqual, Allocator> const& rhs)
|
||||||
|
{
|
||||||
|
return lhs.table_ == rhs.table_;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (lhs.size() == rhs.size()) && ([&] {
|
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||||
for (auto const& kvp : lhs) {
|
friend bool operator!=(
|
||||||
auto pos = rhs.find(kvp.first);
|
unordered_node_map<Key, T, Hash, KeyEqual, Allocator> const& lhs,
|
||||||
if ((pos == rhs.end()) || (*pos != kvp)) {
|
unordered_node_map<Key, T, Hash, KeyEqual, Allocator> const& rhs)
|
||||||
return false;
|
{
|
||||||
}
|
return !(lhs == rhs);
|
||||||
}
|
}
|
||||||
return true;
|
};
|
||||||
})();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
|
||||||
bool operator!=(
|
|
||||||
unordered_node_map<Key, T, Hash, KeyEqual, Allocator> const& lhs,
|
|
||||||
unordered_node_map<Key, T, Hash, KeyEqual, Allocator> const& rhs)
|
|
||||||
{
|
|
||||||
return !(lhs == rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||||
void swap(unordered_node_map<Key, T, Hash, KeyEqual, Allocator>& lhs,
|
void swap(unordered_node_map<Key, T, Hash, KeyEqual, Allocator>& lhs,
|
||||||
|
@ -631,35 +631,26 @@ namespace boost {
|
|||||||
hasher hash_function() const { return table_.hash_function(); }
|
hasher hash_function() const { return table_.hash_function(); }
|
||||||
|
|
||||||
key_equal key_eq() const { return table_.key_eq(); }
|
key_equal key_eq() const { return table_.key_eq(); }
|
||||||
};
|
|
||||||
|
|
||||||
template <class Key, class Hash, class KeyEqual, class Allocator>
|
/// Equality
|
||||||
bool operator==(
|
///
|
||||||
unordered_node_set<Key, Hash, KeyEqual, Allocator> const& lhs,
|
|
||||||
unordered_node_set<Key, Hash, KeyEqual, Allocator> const& rhs)
|
template <class Key, class Hash, class KeyEqual, class Allocator>
|
||||||
{
|
friend bool operator==(
|
||||||
if (&lhs == &rhs) {
|
unordered_node_set<Key, Hash, KeyEqual, Allocator> const& lhs,
|
||||||
return true;
|
unordered_node_set<Key, Hash, KeyEqual, Allocator> const& rhs)
|
||||||
|
{
|
||||||
|
return lhs.table_ == rhs.table_;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (lhs.size() == rhs.size()) && ([&] {
|
template <class Key, class Hash, class KeyEqual, class Allocator>
|
||||||
for (auto const& key : lhs) {
|
friend bool operator!=(
|
||||||
auto pos = rhs.find(key);
|
unordered_node_set<Key, Hash, KeyEqual, Allocator> const& lhs,
|
||||||
if ((pos == rhs.end()) || (key != *pos)) {
|
unordered_node_set<Key, Hash, KeyEqual, Allocator> const& rhs)
|
||||||
return false;
|
{
|
||||||
}
|
return !(lhs == rhs);
|
||||||
}
|
}
|
||||||
return true;
|
};
|
||||||
})();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Key, class Hash, class KeyEqual, class Allocator>
|
|
||||||
bool operator!=(
|
|
||||||
unordered_node_set<Key, Hash, KeyEqual, Allocator> const& lhs,
|
|
||||||
unordered_node_set<Key, Hash, KeyEqual, Allocator> const& rhs)
|
|
||||||
{
|
|
||||||
return !(lhs == rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Key, class Hash, class KeyEqual, class Allocator>
|
template <class Key, class Hash, class KeyEqual, class Allocator>
|
||||||
void swap(unordered_node_set<Key, Hash, KeyEqual, Allocator>& lhs,
|
void swap(unordered_node_set<Key, Hash, KeyEqual, Allocator>& lhs,
|
||||||
|
Reference in New Issue
Block a user