7#ifndef PXR_BASE_TF_DENSE_HASH_SET_H
8#define PXR_BASE_TF_DENSE_HASH_SET_H
14#include "pxr/base/tf/hashmap.h"
20PXR_NAMESPACE_OPEN_SCOPE
36 class EqualElement = std::equal_to<Element>,
37 unsigned Threshold = 128
43 using value_type = Element;
44 using pointer = value_type*;
45 using const_pointer =
const value_type*;
52 typedef std::vector<Element> _Vector;
55 typedef TfHashMap<Element, size_t, HashFn, EqualElement> _HashMap;
64 typedef typename _Vector::const_iterator
iterator;
77 const HashFn &hashFn = HashFn(),
78 const EqualElement &equalElement = EqualElement())
81 _equ() = equalElement;
87 : _storage(rhs._storage) {
89 _h = std::make_unique<_HashMap>(*rhs._h);
99 template <
class Iterator>
107 insert(l.begin(), l.end());
128 insert(l.begin(), l.end());
143 if (!rhs.
count(*iter))
151 return !(*
this == rhs);
164 _storage.swap(rhs._storage);
171 return _vec().empty();
177 return _vec().size();
183 return _vec().begin();
195 return _vec().cbegin();
201 return _vec().cend();
207 return _vec().empty() ? nullptr : &_vec().front();
213 return _vec().empty() ? nullptr : &_vec().front();
219 return _vec().empty() ? nullptr : &_vec().front();
227 typename _HashMap::const_iterator iter = _h->find(k);
228 if (iter == _h->end())
231 return _vec().begin() + iter->second;
234 typename _Vector::const_iterator iter,
end = _vec().end();
236 for(iter = _vec().
begin(); iter !=
end; ++iter)
237 if (_equ()(*iter, k))
245 size_t count(
const Element &k)
const {
259 std::pair<typename _HashMap::iterator, bool> res =
260 _h->insert(std::make_pair(v,
size()));
275 _CreateTableIfNeeded();
283 template<
class IteratorType>
284 void insert(IteratorType i0, IteratorType i1) {
289 if (
size() + std::distance(i0, i1) >= Threshold)
293 for (IteratorType iter = i0; iter != i1; ++iter)
300 template <
class Iterator>
305 _CreateTableIfNeeded();
333 if (iter != std::prev(
end())) {
339 swap(*
const_cast<Element *
>(&(*iter)), _vec().back());
343 (*_h)[*iter] = iter - _vec().begin();
361 for(; vremain != _vec().end(); ++vremain)
362 (*_h)[*vremain] = vremain - _vec().begin();
371 _vec().shrink_to_fit();
379 if (sz < Threshold) {
386 _h.reset(
new _HashMap(sz, _hash(), _equ()));
387 for(
size_t i=0; i<sz; ++i)
388 (*_h)[_vec()[i]] = i;
396 return _vec()[index];
405 return _storage.vector;
414 EqualElement &_equ() {
419 const _Vector &_vec()
const {
420 return _storage.vector;
424 const HashFn &_hash()
const {
429 const EqualElement &_equ()
const {
434 inline void _CreateTableIfNeeded() {
435 if (
size() >= Threshold) {
442 inline void _CreateTable() {
444 _h.reset(
new _HashMap(Threshold, _hash(), _equ()));
445 for(
size_t i=0; i <
size(); ++i)
446 (*_h)[_vec()[i]] = i;
455 private EqualElement,
private HashFn {
456 static_assert(!std::is_same<EqualElement, HashFn>::value,
457 "EqualElement and HashFn must be distinct types.");
458 _CompressedStorage() =
default;
459 _CompressedStorage(
const EqualElement& equal,
const HashFn& hashFn)
460 : EqualElement(equal), HashFn(hashFn) {}
462 void swap(_CompressedStorage& other) {
464 vector.swap(other.vector);
465 swap(
static_cast<EqualElement&
>(*
this),
466 static_cast<EqualElement&
>(other));
467 swap(
static_cast<HashFn&
>(*
this),
static_cast<HashFn&
>(other));
472 _CompressedStorage _storage;
475 std::unique_ptr<_HashMap> _h;
478PXR_NAMESPACE_CLOSE_SCOPE
Define function attributes.
#define ARCH_EMPTY_BASES
Macro to begin the definition of a class that is using private inheritance to take advantage of the e...
A hash set with contiguous storage, suitable for use with TfSpan, e.g.
size_t erase(const Element &k)
Erase element with key k.
const_pointer cdata() const
Returns a const pointer to the set's data.
size_t size() const
Returns the size of the set.
const_iterator begin() const
Returns a const_iterator pointing to the beginning of the set.
TfDenseHashSet(TfDenseHashSet &&rhs)=default
Move Ctor.
TfDenseHashSet(Iterator begin, Iterator end)
Construct from range.
const Element & operator[](size_t index) const
Index into set via index.
const_pointer data() const
Returns a const pointer to the set's data.
pointer data()
Returns a pointer to the set's data.
const_iterator cbegin() const
Returns a const_iterator pointing to the beginning of the set.
void insert(IteratorType i0, IteratorType i1)
Insert a range into the hash set.
size_t count(const Element &k) const
Returns the number of elements with key k.
TfDenseHashSet(const HashFn &hashFn=HashFn(), const EqualElement &equalElement=EqualElement())
Ctor.
void shrink_to_fit()
Optimize storage space.
bool empty() const
true if the set's size is 0.
void erase(const iterator &i0, const iterator &i1)
Erases a range from the set.
void erase(const iterator &iter)
Erases element pointed to by iter.
TfDenseHashSet & operator=(TfDenseHashSet &&rhs)=default
Move assignment operator.
_Vector::const_iterator iterator
An iterator type for this set.
void swap(TfDenseHashSet &rhs)
Swaps the contents of two sets.
const_iterator find(const Element &k) const
Finds the element with key k.
TfDenseHashSet(std::initializer_list< Element > l)
Construct from an initializer_list.
const_iterator cend() const
Returns a const_iterator pointing to the end of the set.
std::pair< const_iterator, bool > insert_result
Return type for insert() method.
bool operator==(const TfDenseHashSet &rhs) const
Equality operator.
insert_result insert(const value_type &v)
Returns a pair of <iterator, bool> where iterator points to the element in the list and bool is true ...
void clear()
Erases all of the elements.
TfDenseHashSet & operator=(const TfDenseHashSet &rhs)
Copy assignment operator.
void insert_unique(Iterator begin, Iterator end)
Insert a range of unique elements into the container.
const_iterator end() const
Returns a const_iterator pointing to the end of the set.
_Vector::const_iterator const_iterator
A const_iterator type for this set.
TfDenseHashSet(const TfDenseHashSet &rhs)
Copy Ctor.
TfDenseHashSet & operator=(std::initializer_list< Element > l)
Assignment from an initializer_list.
#define TF_VERIFY(cond, format,...)
Checks a condition and reports an error if it evaluates false.