5 #ifndef CONFLUENT_SET_H_INCLUDED 6 #define CONFLUENT_SET_H_INCLUDED 11 #include <initializer_list> 22 template <
class T,
class Compare,
class Hash,
class Equal>
25 template <
class T,
class Compare,
class Hash,
class Equal>
40 inline std::uint32_t intmix(std::uint32_t key) {
41 key = ~key + (key << 15);
42 key = key ^ (key >> 12);
43 key = key + (key << 2);
44 key = key ^ (key >> 4);
46 key = key ^ (key >> 16);
51 inline std::uint64_t intmix(std::uint64_t key) {
52 key = (~key) + (key << 21);
53 key = key ^ (key >> 24);
54 key = (key + (key << 3)) + (key << 8);
55 key = key ^ (key >> 14);
56 key = (key + (key << 2)) + (key << 4);
57 key = key ^ (key >> 28);
58 key = key + (key << 31);
62 inline size_t hash_combine(
size_t h1,
size_t h2) {
63 return h1 ^ (h2 + 0x9e3779b9 + (h1 << 6) + (h1 >> 2));
66 inline size_t hash_combine(
size_t h1,
size_t h2,
size_t h3) {
67 return hash_combine(hash_combine(h1, h2), h3);
70 template <
class Traits,
class Category =
typename Traits::category>
73 template <
class Traits,
class Category =
typename Traits::category>
76 template <
class Traits>
79 template <
class Traits>
81 node_ptr() : node_(nullptr) {}
82 node_ptr(std::nullptr_t) : node_(nullptr) {}
84 explicit node_ptr(node<Traits>* p,
bool add_ref =
true) : node_(p) {
89 node_ptr(
const node_ptr& other) : node_(other.node_) {
94 node_ptr(node_ptr&& other) : node_(other.node_) { other.node_ =
nullptr; }
97 if (node_ && !decref(node_))
101 node_ptr& operator=(
const node_ptr& other) {
106 node_ptr& operator=(node_ptr&& other) {
107 if (node_ && !decref(node_))
110 other.node_ =
nullptr;
114 void reset(node<Traits>* p =
nullptr,
bool add_ref =
true) {
118 if (node_ && !decref(node_))
124 void swap(node_ptr& other) { std::swap(node_, other.node_); }
126 node<Traits>& operator*()
const {
return *node_; }
127 node<Traits>* operator->()
const {
return node_; }
129 bool operator==(
const node_ptr& other)
const {
return node_ == other.node_; }
131 bool operator!=(
const node_ptr& other)
const {
return node_ != other.node_; }
133 node<Traits>* get()
const {
return node_; }
135 explicit operator bool()
const {
return node_; }
137 void incref(node<Traits>* p)
const {
138 p->reference_count_.fetch_add(1, std::memory_order_relaxed);
141 size_t decref(node<Traits>* p)
const {
142 size_t count = p->reference_count_.load(std::memory_order_relaxed);
145 std::lock_guard<std::mutex> lock(env<Traits>::get_hash_table().mutex_);
146 if (p->reference_count_.compare_exchange_strong(
147 count, 0, std::memory_order_relaxed)) {
148 env<Traits>::get_hash_table().erase(p);
152 if (p->reference_count_.compare_exchange_weak(
153 count, count - 1, std::memory_order_relaxed))
159 static const node_ptr null_;
164 template <
class Traits>
165 const node_ptr<Traits> node_ptr<Traits>::null_;
167 template <
class Traits>
170 : buckets_(alloc(min_bucket_count_)),
171 bucket_count_(min_bucket_count_),
174 node<Traits>* insert(node<Traits>* key) {
176 node<Traits>** p = &buckets_[pos(key)];
178 if ((*p)->hash_ == key->hash_ && (*p)->left_ == key->left_ &&
179 (*p)->right_ == key->right_ &&
180 env<Traits>::equal((*p)->value(), key->value()))
185 key->next_ =
nullptr;
190 void erase(node<Traits>* key) {
191 node<Traits>** p = &buckets_[pos(key)];
199 if (size_ >= bucket_count_)
201 else if (size_ > min_bucket_count_ && (size_ << 1) < bucket_count_)
205 static std::unique_ptr<node<Traits>* []> alloc(
size_t bucket_count) {
206 std::unique_ptr<node<Traits>*[]> buckets(
new node<Traits>*[bucket_count]);
207 std::fill(buckets.get(), buckets.get() + bucket_count,
nullptr);
211 size_t pos(node<Traits>* key)
const {
212 return key->hash_ & (bucket_count_ - 1);
217 std::unique_ptr<node<Traits>*[]> new_buckets = alloc(bucket_count_);
218 std::fill(new_buckets.get(), new_buckets.get() + bucket_count_,
nullptr);
219 for (
size_t i = 0; i < bucket_count_ / 2; ++i) {
220 node<Traits>* head = buckets_[i];
222 node<Traits>* next = head->next_;
223 size_t j = pos(head);
224 head->next_ = new_buckets[j];
225 new_buckets[j] = head;
229 swap(buckets_, new_buckets);
234 std::unique_ptr<node<Traits>*[]> new_buckets(
235 new node<Traits>*[bucket_count_]);
236 for (
size_t i = 0; i < bucket_count_; ++i) {
237 node<Traits>* low_head = buckets_[i];
238 node<Traits>* high_head = buckets_[i + bucket_count_];
240 new_buckets[i] = low_head;
241 while (low_head->next_)
242 low_head = low_head->next_;
243 low_head->next_ = high_head;
245 new_buckets[i] = high_head;
248 swap(buckets_, new_buckets);
252 static constexpr
size_t min_bucket_count_ = 1 << 3;
254 mutable std::mutex mutex_;
255 std::unique_ptr<node<Traits>*[]> buckets_;
256 size_t bucket_count_;
260 template <
class Traits>
262 env_base(
typename Traits::provider* provider) : saved_provider_(provider_) {
263 provider_ = provider;
266 env_base(
const env_base&) =
delete;
268 ~env_base() { provider_ = saved_provider_; }
270 void silence_unused_warning()
const {}
272 static hash_table<Traits>& get_hash_table() {
return provider_->hash_table_; }
274 typename Traits::provider*
const saved_provider_;
276 static thread_local
typename Traits::provider* provider_;
279 template <
class Traits>
280 thread_local
typename Traits::provider* env_base<Traits>::provider_;
282 enum class ranking { LEFT = -1, SAME = 0, RIGHT = 1, NOT_SAME };
284 template <
class Traits>
285 size_t hash(
const node<Traits>* p) {
286 return p ? p->hash_ : 0;
289 template <
class Traits>
290 size_t hash(
const node_ptr<Traits>& p) {
291 return p ? p->hash_ : 0;
294 template <
class Traits>
295 size_t size(
const node<Traits>* p) {
296 return p ? p->size() : 0;
299 template <
class Traits>
300 size_t size(
const node_ptr<Traits>& p) {
301 return p ? p->size() : 0;
304 template <
class Traits>
305 const node<Traits>* at_index(
const node<Traits>* p,
size_t k) {
309 while (k > size(p->left_)) {
310 k -= size(p->left_) + 1;
313 while (k < size(p->left_))
315 if (k == size(p->left_))
320 template <
class Traits,
class Comparer>
321 std::pair<const node<Traits>*,
size_t> lower_bound(
const node<Traits>* p,
323 std::pair<const node<Traits>*,
size_t> best = {
nullptr, size(p)};
328 pos += size(p->left_) + 1;
331 best = {p, pos + size(p->left_)};
340 template <
class Traits>
341 void reset(
const env<Traits>& env, node_ptr<Traits>* p) {
342 env.silence_unused_warning();
346 template <
class Traits>
347 node_ptr<Traits> get_unique_node(
const env<Traits>& env,
348 std::unique_ptr<node<Traits>> p) {
349 std::lock_guard<std::mutex> lock(env.get_hash_table().mutex_);
350 node<Traits>* q = env.get_hash_table().insert(p.get());
351 return q == p.get() ? node_ptr<Traits>(p.release(),
false)
352 : node_ptr<Traits>(q);
355 template <
class Traits>
356 node_ptr<Traits> make_node(
const env<Traits, set_tag>& env,
357 const typename Traits::value_type& value,
358 node_ptr<Traits> left =
nullptr,
359 node_ptr<Traits> right =
nullptr) {
360 return node<Traits>::create(env, value, std::move(left), std::move(right),
361 intmix(env.hash(value)));
364 template <
class Traits>
365 node_ptr<Traits> make_node(
const env<Traits, set_tag>& env,
366 const node<Traits>& parent,
367 node_ptr<Traits> left,
368 node_ptr<Traits> right) {
369 return node<Traits>::create(env, parent.value(), std::move(left),
370 std::move(right), parent.priority());
373 template <
class Traits>
374 ranking rank(
const env<Traits>& env,
375 const node<Traits>& left,
376 const node<Traits>& right) {
377 if (left.priority() < right.priority())
378 return ranking::LEFT;
379 if (right.priority() < left.priority())
380 return ranking::RIGHT;
381 if (env.compare(left.key(), right.key()))
382 return ranking::LEFT;
383 if (env.compare(right.key(), left.key()))
384 return ranking::RIGHT;
385 return ranking::SAME;
388 template <
class Traits,
class Parent,
class Child>
389 node_ptr<Traits> replace_left(
const env<Traits>& env,
392 if (parent->left_ == child)
393 return std::forward<Parent>(parent);
394 return make_node(env, *parent, std::forward<Child>(child), parent->right_);
397 template <
class Traits,
class Parent,
class Child>
398 node_ptr<Traits> replace_right(
const env<Traits>& env,
401 if (parent->right_ == child)
402 return std::forward<Parent>(parent);
403 return make_node(env, *parent, parent->left_, std::forward<Child>(child));
406 template <
class Traits,
class Left,
class Right>
407 node_ptr<Traits> join(
const env<Traits>& env, Left&& left, Right&& right) {
409 return std::forward<Right>(right);
411 return std::forward<Left>(left);
412 switch (rank(env, *left, *right)) {
414 return replace_right(env, left,
415 join(env, left->right_, std::forward<Right>(right)));
417 return replace_left(env, right,
418 join(env, std::forward<Left>(left), right->left_));
427 template <
class Traits,
class NodePtr>
428 std::pair<node_ptr<Traits>, node_ptr<Traits>> split(
429 const env<Traits>& env,
431 const typename Traits::key_type& key) {
434 if (env.compare(p->key(), key)) {
435 auto s = split(env, p->right_, key);
436 return {replace_right(env, std::forward<NodePtr>(p), std::move(s.first)),
437 std::move(s.second)};
439 auto s = split(env, p->left_, key);
440 return {std::move(s.first),
441 replace_left(env, std::forward<NodePtr>(p), std::move(s.second))};
445 template <
class Traits,
class Left,
class Right>
446 node_ptr<Traits> set_union(
const env<Traits>& env, Left&& left, Right&& right) {
447 if (left == right || !right)
448 return std::forward<Left>(left);
450 return std::forward<Right>(right);
451 switch (rank(env, *left, *right)) {
452 case ranking::LEFT: {
453 auto s = split(env, std::forward<Right>(right), left->key());
454 return make_node(env, *left,
455 set_union(env, left->left_, std::move(s.first)),
456 set_union(env, left->right_, std::move(s.second)));
458 case ranking::RIGHT: {
459 auto s = split(env, std::forward<Left>(left), right->key());
460 return make_node(env, *right,
461 set_union(env, std::move(s.first), right->left_),
462 set_union(env, std::move(s.second), right->right_));
465 return make_node(env, *left, set_union(env, left->left_, right->left_),
466 set_union(env, left->right_, right->right_));
471 template <
class Traits,
class Rank,
class Left,
class Right>
472 node_ptr<Traits> set_intersection(
const env<Traits>& env,
479 return std::forward<Left>(left);
480 switch (ranker(env, *left, *right)) {
481 case ranking::LEFT: {
482 auto s = split(env, std::forward<Right>(right), left->key());
484 env, set_intersection(env, ranker, left->left_, std::move(s.first)),
485 set_intersection(env, ranker, left->right_, std::move(s.second)));
487 case ranking::RIGHT: {
488 auto s = split(env, std::forward<Left>(left), right->key());
490 env, set_intersection(env, ranker, std::move(s.first), right->left_),
491 set_intersection(env, ranker, std::move(s.second), right->right_));
493 case ranking::NOT_SAME: {
494 return join(env, set_intersection(env, ranker, left->left_, right->left_),
495 set_intersection(env, ranker, left->right_, right->right_));
499 env, *left, set_intersection(env, ranker, left->left_, right->left_),
500 set_intersection(env, ranker, left->right_, right->right_));
505 template <
class Traits,
class Rank,
class Left,
class Right>
506 node_ptr<Traits> set_difference(
const env<Traits>& env,
510 if (left == right || !left)
513 return std::forward<Left>(left);
514 switch (ranker(env, *left, *right)) {
515 case ranking::LEFT: {
516 auto s = split(env, std::forward<Right>(right), left->key());
519 set_difference(env, ranker, left->left_, std::move(s.first)),
520 set_difference(env, ranker, left->right_, std::move(s.second)));
522 case ranking::RIGHT: {
523 auto s = split(env, std::forward<Left>(left), right->key());
525 env, set_difference(env, ranker, std::move(s.first), right->left_),
526 set_difference(env, ranker, std::move(s.second), right->right_));
528 case ranking::NOT_SAME: {
530 env, *left, set_difference(env, ranker, left->left_, right->left_),
531 set_difference(env, ranker, left->right_, right->right_));
534 return join(env, set_difference(env, ranker, left->left_, right->left_),
535 set_difference(env, ranker, left->right_, right->right_));
540 template <
class Traits,
class Left,
class Right>
541 node_ptr<Traits> set_symmetric(
const env<Traits>& env,
545 return std::forward<Right>(right);
547 return std::forward<Left>(left);
550 switch (rank(env, *left, *right)) {
551 case ranking::LEFT: {
552 auto s = split(env, std::forward<Right>(right), left->key());
553 return make_node(env, *left,
554 set_symmetric(env, left->left_, std::move(s.first)),
555 set_symmetric(env, left->right_, std::move(s.second)));
557 case ranking::RIGHT: {
558 auto s = split(env, std::forward<Left>(left), right->key());
559 return make_node(env, *right,
560 set_symmetric(env, std::move(s.first), right->left_),
561 set_symmetric(env, std::move(s.second), right->right_));
564 return join(env, set_symmetric(env, left->left_, right->left_),
565 set_symmetric(env, left->right_, right->right_));
570 template <
class Traits,
class Rank,
class Left,
class Right>
571 bool includes(
const env<Traits>& env, Rank ranker, Left&& left, Right&& right) {
572 if (left == right || !right)
575 if (size(left) < size(right))
578 switch (ranker(env, *left, *right)) {
579 case ranking::LEFT: {
580 auto s = split(env, std::forward<Right>(right), left->key());
581 return includes(env, ranker, left->left_, std::move(s.first)) &&
582 includes(env, ranker, left->right_, std::move(s.second));
584 case ranking::SAME: {
585 return includes(env, ranker, left->left_, right->left_) &&
586 includes(env, ranker, left->right_, right->right_);
594 template <
class Traits,
class InputIterator>
595 node_ptr<Traits> make_node(
const env<Traits>& env,
596 InputIterator* first,
601 node_ptr<Traits> root = make_node(env, **first);
603 for (
size_t depth = 0; depth < max_depth; ++depth) {
604 node_ptr<Traits> branch = make_node(env, first, last, depth);
607 root = set_union(env, std::move(root), std::move(branch));
612 template <
class Traits,
class InputIterator>
613 node_ptr<Traits> make_node(
const env<Traits>& env,
615 InputIterator last) {
616 InputIterator it = first;
617 return make_node(env, &it, last, std::numeric_limits<size_t>::max());
620 template <
class Traits,
class NodePtr>
621 size_t add(
const env<Traits>& env, node_ptr<Traits>* p, NodePtr&& q) {
623 *p = set_union(env, *p, std::forward<NodePtr>(q));
627 template <
class Traits,
class Rank,
class NodePtr>
628 size_t diff(
const env<Traits>& env,
633 *p = set_difference(env, ranker, *p, std::forward<NodePtr>(q));
637 template <
class Traits>
638 size_t erase(
const env<Traits>& env,
643 *p = join(env, head(env, p, first), tail(env, p, last));
647 template <
class Traits,
class Rank,
class NodePtr>
648 size_t intersect(
const env<Traits>& env,
653 *p = set_intersection(env, ranker, *p, std::forward<NodePtr>(q));
657 template <
class Traits>
658 size_t insert(
const env<Traits>& env,
660 const typename Traits::value_type& value) {
661 return add(env, p, make_node(env, value));
664 template <
class Traits,
class InputIterator>
665 size_t insert(
const env<Traits>& env,
668 InputIterator last) {
669 return add(env, p, make_node(env, first, last));
672 template <
class Traits,
class InputIterator>
673 void assign(
const env<Traits>& env,
676 InputIterator last) {
677 *p = make_node(env, first, last);
680 template <
class Traits,
class Key>
681 std::pair<node_ptr<Traits>,
bool> erase(
const env<Traits>& env,
682 const node_ptr<Traits>& p,
685 return {
nullptr,
false};
686 if (env.compare(p->value(), key)) {
687 auto s = erase(env, p->right_, key);
689 return {replace_right(env, p, std::move(s.first)),
true};
692 auto s = erase(env, p->left_, key);
694 return {replace_left(env, p, std::move(s.first)),
true};
695 if (!env.equal(p->value(), key))
697 return {join(env, p->left_, p->right_),
true};
700 template <
class Traits,
class Key>
701 size_t erase(
const env<Traits>& env, node_ptr<Traits>* p,
const Key& key) {
703 *p = erase(env, *p, key).first;
707 template <
class Traits>
708 size_t retain(
const env<Traits>& env,
713 node_ptr<Traits> h = head(env, p, last);
714 *p = tail(env, &h, first);
718 template <
class Traits>
719 void symmetric(
const env<Traits>& env,
721 const node_ptr<Traits>& q) {
722 *p = set_symmetric(env, *p, q);
725 template <
class Traits>
726 node_ptr<Traits> tail(
const env<Traits>& env,
727 const node_ptr<Traits>* p,
729 while (*p && first > size((*p)->left_)) {
730 first -= size((*p)->left_) + 1;
733 return first ? replace_left(env, *p, tail(env, &(*p)->left_, first)) : *p;
736 template <
class Traits>
737 node_ptr<Traits> head(
const env<Traits>& env,
738 const node_ptr<Traits>* p,
740 while (*p && last <= size((*p)->left_)) {
743 return last == size(*p) ? *p
744 : replace_right(env, *p,
745 head(env, &(*p)->right_,
746 last - size((*p)->left_) - 1));
749 template <
class T,
class Compare,
class Hash,
class Equal>
751 typedef set_tag category;
753 typedef T value_type;
754 typedef set_provider<T, Compare, Hash, Equal> provider;
755 typedef set<T, Compare, Hash, Equal> container;
758 template <
class Traits>
759 struct node<Traits, set_tag> {
760 typedef typename Traits::key_type key_type;
761 typedef typename Traits::value_type value_type;
762 typedef node_ptr<Traits> ptr_type;
763 typedef env<Traits> env_type;
765 node(
const value_type& value,
771 : reference_count_(1),
776 left_(std::move(left)),
777 right_(std::move(right)) {}
779 static ptr_type create(
const env_type& env,
780 const value_type& value,
784 size_t sz = 1 + internal::size(left) + internal::size(right);
785 size_t h = hash_combine(hash(left), hash(right), priority);
786 std::unique_ptr<node> p(
787 new node(value, priority, sz, std::move(left), std::move(right), h));
788 return get_unique_node(env, std::move(p));
791 const key_type& key()
const {
return value_; }
792 const value_type& value()
const {
return value_; }
793 size_t priority()
const {
return priority_; }
794 size_t size()
const {
return size_; }
796 std::atomic<size_t> reference_count_;
798 const value_type value_;
799 const size_t priority_;
802 const ptr_type left_;
803 const ptr_type right_;
806 template <
class Traits>
807 struct env<Traits, set_tag> : env_base<Traits> {
808 typedef typename Traits::provider provider_type;
809 typedef typename Traits::key_type key_type;
810 typedef hash_table<Traits> hash_table_type;
812 using env_base<Traits>::env_base;
813 using env_base<Traits>::provider_;
815 static bool compare(
const key_type& lhs,
const key_type& rhs) {
816 return provider_->key_comp()(lhs, rhs);
819 static bool equal(
const key_type& lhs,
const key_type& rhs) {
820 return provider_->key_eq()(lhs, rhs);
823 static size_t hash(
const key_type& key) {
return provider_->key_hash()(key); }
828 template <
class Traits>
830 typedef internal::node<Traits> node_type;
831 typedef typename Traits::container container_type;
833 typedef std::ptrdiff_t difference_type;
834 typedef const typename Traits::value_type value_type;
835 typedef const value_type* pointer;
836 typedef const value_type& reference;
837 typedef std::bidirectional_iterator_tag iterator_category;
839 iterator() : container_(nullptr), pos_(0), node_(nullptr) {}
841 iterator(
const container_type* container,
843 const node_type* node =
nullptr)
844 : container_(container), pos_(pos), node_(node), decrementing_(false) {}
846 iterator(
const container_type* container,
847 std::pair<const node_type*, size_t> p)
848 : container_(container),
851 decrementing_(false) {}
853 iterator(
const iterator& other)
854 : container_(other.container_),
857 decrementing_(false) {}
859 reference operator*()
const {
return find_node()->value(); }
860 pointer operator->()
const {
return &find_node()->value(); }
862 iterator& operator++() {
867 iterator operator++(
int) {
868 iterator it(container_, pos_, node_);
873 iterator operator+(difference_type k)
const {
874 return iterator(container_, pos_ + k);
877 iterator& operator+=(difference_type k) {
882 iterator& operator--() {
887 iterator operator--(
int) {
888 iterator it(container_, pos_, node_);
893 iterator operator-(difference_type k)
const {
894 return iterator(container_, pos_ - k);
897 iterator& operator-=(difference_type k) {
902 void swap(iterator& other) {
903 std::swap(container_, other.container_);
904 std::swap(pos_, other.pos_);
905 std::swap(node_, other.node_);
906 std::swap(stack_, other.stack_);
907 std::swap(decrementing_, other.decrementing_);
910 iterator& operator=(
const iterator& other) {
911 container_ = other.container_;
918 iterator& operator=(iterator&& other) {
923 bool operator==(
const iterator& other)
const {
return pos_ == other.pos_; }
924 bool operator!=(
const iterator& other)
const {
return pos_ != other.pos_; }
925 bool operator<(
const iterator& other)
const {
return pos_ < other.pos_; }
926 bool operator<=(
const iterator& other)
const {
return pos_ <= other.pos_; }
927 bool operator>(
const iterator& other)
const {
return pos_ > other.pos_; }
928 bool operator>=(
const iterator& other)
const {
return pos_ >= other.pos_; }
934 decrementing_ =
false;
936 if (stack_.empty()) {
938 node_ = container_->node_.get();
940 while (k > size(node_->left_)) {
941 k -= size(node_->left_) + 1;
942 node_ = node_->right_.get();
944 while (k < size(node_->left_)) {
945 stack_.push_back(node_);
946 node_ = node_->left_.get();
948 }
while (k != size(node_->left_));
952 node_ = node_->right_.get();
953 while (node_->left_) {
954 stack_.push_back(node_);
955 node_ = node_->left_.get();
958 node_ = stack_.back();
965 if (!decrementing_) {
967 decrementing_ =
true;
969 if (stack_.empty()) {
971 node_ = container_->node_.get();
973 while (k > size(node_->left_)) {
974 k -= size(node_->left_) + 1;
975 stack_.push_back(node_);
976 node_ = node_->right_.get();
978 while (k < size(node_->left_)) {
979 node_ = node_->left_.get();
981 }
while (k != size(node_->left_));
985 node_ = node_->left_.get();
986 while (node_->right_) {
987 stack_.push_back(node_);
988 node_ = node_->right_.get();
991 node_ = stack_.back();
996 void reset(
size_t pos) {
997 if (pos == pos_ + 1 && pos != size(container_->node_)) {
1001 if (pos == pos_ - 1) {
1012 const node_type* find_node()
const {
1013 assert(pos_ < size(container_->node_));
1015 node_ = at_index(container_->node_.get(), pos_);
1019 const container_type* container_;
1021 mutable const node_type* node_;
1022 std::vector<const node_type*> stack_;
1026 template <
class Traits>
1027 std::ptrdiff_t distance(
const iterator<Traits>& from,
1028 const iterator<Traits>& to) {
1029 return to.pos_ - from.pos_;
1059 class Compare = std::less<T>,
1060 class Hash = std::hash<T>,
1061 class Equal = std::equal_to<T>>
1063 typedef internal::set_traits<T, Compare, Hash, Equal> traits;
1065 friend struct internal::env_base<traits>;
1076 const Hash& hash = Hash(),
1077 const Equal& equal = Equal())
1078 : compare_(compare), hash_(hash), equal_(equal) {}
1097 const Equal&
key_eq()
const {
return equal_; }
1103 std::lock_guard<std::mutex> lock(hash_table_.mutex_);
1104 return hash_table_.size_;
1111 static const std::shared_ptr<set_provider> provider =
1112 std::make_shared<set_provider>();
1117 const Compare compare_;
1120 internal::hash_table<traits> hash_table_;
1138 class Compare = std::less<T>,
1139 class Hash = std::hash<T>,
1140 class Equal = std::equal_to<T>>
1142 template <
class K,
class M,
class KC,
class KH,
class KE,
class MH,
class ME>
1145 typedef internal::set_traits<T, Compare, Hash, Equal> traits;
1146 typedef internal::env<traits> env_type;
1147 typedef typename internal::node<traits> node_type;
1149 friend struct confluent::iterator<traits>;
1153 typedef T value_type;
1155 typedef std::shared_ptr<provider_type> provider_ptr;
1156 typedef confluent::iterator<traits> iterator;
1157 typedef std::reverse_iterator<iterator> reverse_iterator;
1167 : provider_(std::move(
provider)) {}
1179 template <
class InputIterator>
1196 set(std::initializer_list<value_type> ilist,
1212 set(iterator first, iterator last) :
set(*first.container_) {
1225 set(
const set& other) : provider_(other.provider_), node_(other.node_) {}
1239 : provider_(std::move(other.provider_)), node_(std::move(other.node_)) {}
1254 return internal::insert(env(), &node_, value);
1269 template <
class InputIterator>
1270 size_t insert(InputIterator first, InputIterator last) {
1271 return internal::insert(env(), &node_, first, last);
1285 size_t insert(std::initializer_list<value_type> ilist) {
1286 return internal::insert(env(), &node_, ilist.begin(), ilist.end());
1307 return internal::add(env(), &node_, other.node_);
1321 return internal::erase(env(), &node_, key);
1338 size_t erase(iterator first, iterator last) {
1340 return internal::erase(env(), &node_, first.pos_, last.pos_);
1365 return internal::diff(env(), &internal::rank<traits>, &node_, other.node_);
1384 size_t retain(iterator first, iterator last) {
1386 return internal::retain(env(), &node_, first.pos_, last.pos_);
1411 return internal::intersect(env(), &internal::rank<traits>, &node_,
1425 reset(env(), &node_);
1434 provider_.swap(other.provider_);
1435 node_.swap(other.node_);
1452 provider_ = other.provider_;
1453 node_ = other.node_;
1487 internal::assign(env(), &node_, ilist.begin(), ilist.end());
1507 return set(provider_, set_union(env(), node_, rhs.node_));
1550 return set(provider_, set_intersection(env(), &internal::rank<traits>,
1597 return set(provider_, set_difference(env(), &internal::rank<traits>, node_,
1644 return set(provider_, set_symmetric(env(), node_, rhs.node_));
1667 symmetric(env(), &node_, rhs.node_);
1674 iterator
begin()
const {
return iterator(
this, 0); }
1679 iterator
end()
const {
return iterator(
this,
size()); }
1694 reverse_iterator
rbegin()
const {
return reverse_iterator(
end()); }
1699 reverse_iterator
rend()
const {
return reverse_iterator(
begin()); }
1709 iterator
find(
const key_type& key)
const {
1710 std::pair<const node_type*, size_t> bound = internal::lower_bound(
1712 [&](
const node_type& p) {
return key_comp(p.key(), key); });
1713 if (bound.first && key_eq(bound.first->key(), key))
1714 return iterator(
this, bound);
1728 return iterator(
this,
1729 internal::lower_bound(node_.get(), [&](
const node_type& p) {
1730 return key_comp(p.key(), key);
1743 return iterator(
this,
1744 internal::lower_bound(node_.get(), [&](
const node_type& p) {
1745 return !key_comp(key, p.key());
1760 std::pair<iterator, iterator>
equal_range(
const key_type& key)
const {
1773 return internal::at_index(node_.get(), k)->value();
1784 size_t count(
const key_type& key)
const {
1785 const node_type* p =
1786 internal::lower_bound(node_.get(), [&](
const node_type& p) {
1787 return key_comp(p.key(), key);
1789 return p && key_eq(p->key(), key) ? 1 : 0;
1810 return internal::includes(env(), &internal::rank<traits>, node_,
1817 const provider_ptr&
provider()
const {
return provider_; }
1833 size_t size()
const {
return internal::size(node_); }
1840 size_t hash()
const {
return internal::hash(node_); }
1854 return node_ == rhs.node_;
1870 typedef typename internal::node_ptr<traits> node_ptr;
1873 : provider_(std::move(
provider)), node_(std::move(node)) {}
1875 void check(
const set& other)
const { assert(provider_ == other.provider_); }
1877 void check(
const iterator& first,
const iterator& last)
const {
1878 assert(provider_ == first.container_->provider_);
1879 assert(provider_ == last.container_->provider_);
1880 assert(first.pos_ <= last.pos_);
1881 assert(last.pos_ <=
size());
1884 bool key_comp(
const key_type& lhs,
const key_type& rhs)
const {
1885 return provider_->key_comp()(lhs, rhs);
1888 bool key_eq(
const key_type& lhs,
const key_type& rhs)
const {
1889 return provider_->key_eq()(lhs, rhs);
1892 env_type env()
const {
return {provider_.get()}; }
1894 provider_ptr provider_;
1907 template <
class T,
class Compare,
class Hash,
class Equal>
1908 void swap(set<T, Compare, Hash, Equal>& x, set<T, Compare, Hash, Equal>& y) {
1921 template <
class T,
class Compare,
class Hash,
class Equal>
1922 size_t hash(
const set<T, Compare, Hash, Equal>& x) {
1928 #endif // CONFLUENT_SET_H_INCLUDED set & operator-=(const set &rhs)
Definition: set.h:1619
set(InputIterator first, InputIterator last, provider_ptr provider=provider_type::default_provider())
Definition: set.h:1180
iterator cend() const
Definition: set.h:1689
reverse_iterator rbegin() const
Definition: set.h:1694
const provider_ptr & provider() const
Definition: set.h:1817
iterator lower_bound(const key_type &key) const
Definition: set.h:1727
set & operator=(set &&other)
Definition: set.h:1470
size_t size() const
Definition: set.h:1833
size_t insert(const set &other)
Definition: set.h:1305
size_t size() const
Definition: set.h:1102
iterator end() const
Definition: set.h:1679
size_t count(const key_type &key) const
Definition: set.h:1784
iterator find(const key_type &key) const
Definition: set.h:1709
size_t retain(iterator first, iterator last)
Definition: set.h:1384
set & operator&=(const set &rhs)
Definition: set.h:1572
size_t insert(const value_type &value)
Definition: set.h:1253
std::pair< iterator, iterator > equal_range(const key_type &key) const
Definition: set.h:1760
size_t insert(InputIterator first, InputIterator last)
Definition: set.h:1270
static const std::shared_ptr< set_provider > & default_provider()
Definition: set.h:1110
set & operator=(std::initializer_list< value_type > ilist)
Definition: set.h:1486
size_t erase(const key_type &key)
Definition: set.h:1320
size_t erase(const set &other)
Definition: set.h:1363
set(const set &other)
Definition: set.h:1225
size_t insert(std::initializer_list< value_type > ilist)
Definition: set.h:1285
size_t retain(const set &other)
Definition: set.h:1409
set & operator^=(const set &rhs)
Definition: set.h:1665
void clear()
Definition: set.h:1423
void swap(set &other)
Definition: set.h:1433
iterator upper_bound(const key_type &key) const
Definition: set.h:1742
set operator-(const set &rhs) const
Definition: set.h:1595
const Equal & key_eq() const
Definition: set.h:1097
set(set &&other)
Definition: set.h:1238
iterator cbegin() const
Definition: set.h:1684
reverse_iterator rend() const
Definition: set.h:1699
bool operator!=(const set &rhs) const
Definition: set.h:1867
const value_type & at_index(size_t k) const
Definition: set.h:1772
bool empty() const
Definition: set.h:1826
set operator^(const set &rhs) const
Definition: set.h:1642
size_t erase(iterator first, iterator last)
Definition: set.h:1338
set operator&(const set &rhs) const
Definition: set.h:1548
iterator begin() const
Definition: set.h:1674
set operator|(const set &rhs) const
Definition: set.h:1505
const Compare & key_comp() const
Definition: set.h:1087
bool includes(const set &other) const
Definition: set.h:1808
set(iterator first, iterator last)
Definition: set.h:1212
set & operator|=(const set &rhs)
Definition: set.h:1525
bool operator==(const set &rhs) const
Definition: set.h:1852
size_t hash() const
Definition: set.h:1840
set(std::initializer_list< value_type > ilist, provider_ptr provider=provider_type::default_provider())
Definition: set.h:1196
const Hash & key_hash() const
Definition: set.h:1092
set_provider(const Compare &compare=Compare(), const Hash &hash=Hash(), const Equal &equal=Equal())
Definition: set.h:1075
set & operator=(const set &other)
Definition: set.h:1450
set(provider_ptr provider=provider_type::default_provider())
Definition: set.h:1166