7 #ifndef JLM_UTIL_INTRUSIVE_HASH_HPP
8 #define JLM_UTIL_INTRUSIVE_HASH_HPP
103 noexcept(noexcept(std::declval<const T &>() == std::declval<const T &>()))
113 operator()(
const std::string & a,
const std::string & b)
const noexcept
125 typename ElementType,
127 typename KeyHash = std::hash<KeyType>,
128 typename KeyEqual = SafeEqual<KeyType>>
144 static_assert(noexcept(KeyHash()(std::declval<KeyType &>())),
"require noexcept hash");
145 static_assert(noexcept(Accessor().get_key(
nullptr)),
"require noexcept get_key");
146 static_assert(noexcept(Accessor().get_prev(
nullptr)),
"require noexcept get_prev");
147 static_assert(noexcept(Accessor().get_next(
nullptr)),
"require noexcept get_next");
148 static_assert(noexcept(Accessor().set_prev(
nullptr,
nullptr)),
"require noexcept set_prev");
149 static_assert(noexcept(Accessor().set_next(
nullptr,
nullptr)),
"require noexcept set_next");
151 noexcept(KeyEqual()(std::declval<KeyType &>(), std::declval<KeyType &>())),
152 "require noexcept key equality");
183 while (next ==
nullptr && index < map_->
buckets_.size())
272 while (next ==
nullptr && index < map_->
buckets_.size())
290 inline const ElementType &
296 inline const ElementType *
314 inline const ElementType *
350 std::swap(
size_, other.size_);
351 std::swap(
mask_, other.mask_);
359 bucket.first =
nullptr;
360 bucket.last =
nullptr;
379 erase(ElementType * element) noexcept
383 ElementType * prev =
accessor_.get_prev(element);
384 ElementType * next =
accessor_.get_next(element);
425 ElementType * element =
begin.
ptr();
464 return const_iterator(
this,
nullptr);
480 find(
const KeyType & key) noexcept
486 find(
const KeyType & key)
const noexcept
488 return const_iterator(
this,
lookup(key));
511 std::vector<BucketType> & bucket_types,
513 ElementType * element) noexcept
516 accessor_.set_prev(element, bucket_types[index].last);
518 if (bucket_types[index].last)
520 accessor_.set_next(bucket_types[index].last, element);
524 bucket_types[index].first = element;
526 bucket_types[index].last = element;
532 std::vector<BucketType> new_buckets(
535 size_t new_mask = new_buckets.size() - 1;
539 ElementType * element = old_bucket_type.first;
542 ElementType * next =
accessor_.get_next(element);
553 lookup(
const KeyType & key)
const noexcept
561 ElementType * element =
buckets_[index].first;
575 template<
typename ElementType>
585 typename ElementType,
586 KeyType ElementType::*key_member,
592 get_key(
const ElementType * element)
const noexcept
594 return element->*key_member;
598 get_prev(
const ElementType * element)
const noexcept
600 return (element->*anchor_member).prev;
604 set_prev(ElementType * element, ElementType * prev)
const noexcept
606 (element->*anchor_member).prev = prev;
610 get_next(
const ElementType * element)
const noexcept
612 return (element->*anchor_member).next;
616 set_next(ElementType * element, ElementType * next)
const noexcept
618 (element->*anchor_member).next = next;
624 typename ElementType,
626 typename KeyHash = std::hash<KeyType>,
627 typename KeyEqual = SafeEqual<KeyType>>
634 noexcept(std::declval<ElementType &>().~ElementType()),
635 "Require noexcept destructor for ElementType");
637 typedef typename internal_hash_type::iterator
iterator;
679 insert(std::unique_ptr<ElementType> element)
687 erase(ElementType * element) noexcept
709 inline std::unique_ptr<ElementType>
712 std::unique_ptr<ElementType> e = i.ptr();
772 find(
const KeyType & key) noexcept
778 find(
const KeyType & key)
const noexcept
void set_next(ElementType *element, ElementType *next) const noexcept
KeyType get_key(const ElementType *element) const noexcept
ElementType * get_next(const ElementType *element) const noexcept
void set_prev(ElementType *element, ElementType *prev) const noexcept
ElementType * get_prev(const ElementType *element) const noexcept
const IntrusiveHash * map_
const ElementType * pointer
const ConstIterator & operator++() noexcept
const ElementType * operator->() const noexcept
const ElementType & reference
const ElementType value_type
std::forward_iterator_tag iterator_category
const ElementType & operator*() const noexcept
bool operator==(const ConstIterator &other) const noexcept
ConstIterator operator++(int) noexcept
constexpr ConstIterator() noexcept
constexpr ConstIterator(const IntrusiveHash *map, const ElementType *object)
bool operator!=(const ConstIterator &other) const noexcept
constexpr ConstIterator(const ConstIterator &other) noexcept=default
const ElementType * element_
constexpr ConstIterator(const Iterator &other) noexcept
const ElementType * ptr() const noexcept
ElementType & operator*() const noexcept
Iterator operator++(int) noexcept
ElementType * operator->() const noexcept
ElementType * ptr() const noexcept
const Iterator & operator++() noexcept
constexpr Iterator() noexcept
std::forward_iterator_tag iterator_category
bool operator==(const Iterator &other) const noexcept
bool operator!=(const Iterator &other) const noexcept
constexpr Iterator(const IntrusiveHash *map, ElementType *object)
const IntrusiveHash * map_
ConstIterator cend() const noexcept
Iterator begin() noexcept
ConstIterator cbegin() const noexcept
ConstIterator find(const KeyType &key) const noexcept
size_type size() const noexcept
ElementType * first_object() const noexcept
void private_insert_into(std::vector< BucketType > &bucket_types, size_t mask, ElementType *element) noexcept
std::vector< BucketType > buckets_
void swap(IntrusiveHash &other) noexcept
ConstIterator end() const noexcept
IntrusiveHash(IntrusiveHash &&other) noexcept
ConstIterator begin() const noexcept
Iterator insert(ElementType *element)
void erase(ElementType *element) noexcept
void erase(const KeyType &key) noexcept
Iterator find(const KeyType &key) noexcept
void erase(Iterator i) noexcept
void operator=(const IntrusiveHash &other)=delete
bool empty() const noexcept
constexpr IntrusiveHash() noexcept
void erase(Iterator begin, Iterator end) noexcept
ElementType * lookup(const KeyType &key) const noexcept
IntrusiveHash(const IntrusiveHash &other)=delete
iterator find(const KeyType &key) noexcept
bool empty() const noexcept
void operator=(const OwnerIntrusiveHash &other)=delete
internal_hash_type::value_type value_type
iterator begin() noexcept
OwnerIntrusiveHash(const OwnerIntrusiveHash &other)=delete
void erase(ElementType *element) noexcept
IntrusiveHash< KeyType, ElementType, Accessor, KeyHash, KeyEqual > internal_hash_type
const_iterator cbegin() const noexcept
const_iterator cend() const noexcept
const_iterator find(const KeyType &key) const noexcept
void erase(iterator i) noexcept
const_iterator end() const noexcept
~OwnerIntrusiveHash() noexcept
internal_hash_type::size_type size_type
internal_hash_type::key_type key_type
internal_hash_type::iterator iterator
internal_hash_type::mapped_type mapped_type
void swap(OwnerIntrusiveHash &other) noexcept
OwnerIntrusiveHash(OwnerIntrusiveHash &&other) noexcept
void erase(const KeyType &key) noexcept
const_iterator begin() const noexcept
size_type size() const noexcept
std::unique_ptr< ElementType > unlink(iterator i) noexcept
internal_hash_type internal_hash_
internal_hash_type::const_iterator const_iterator
void erase(iterator begin, iterator end) noexcept
iterator insert(std::unique_ptr< ElementType > element)
constexpr OwnerIntrusiveHash() noexcept
constexpr BucketType() noexcept
bool operator()(const std::string &a, const std::string &b) const noexcept
bool operator()(const T &a, const T &b) const noexcept(noexcept(std::declval< const T & >()==std::declval< const T & >()))