File indexing completed on 2025-01-30 09:44:25
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef BOOST_INTRUSIVE_TREAP_HPP
0013 #define BOOST_INTRUSIVE_TREAP_HPP
0014
0015 #include <boost/intrusive/detail/config_begin.hpp>
0016 #include <boost/intrusive/intrusive_fwd.hpp>
0017
0018 #include <boost/intrusive/detail/assert.hpp>
0019 #include <boost/intrusive/bs_set_hook.hpp>
0020 #include <boost/intrusive/bstree.hpp>
0021 #include <boost/intrusive/detail/tree_node.hpp>
0022 #include <boost/intrusive/detail/ebo_functor_holder.hpp>
0023 #include <boost/intrusive/pointer_traits.hpp>
0024 #include <boost/intrusive/detail/get_value_traits.hpp>
0025 #include <boost/intrusive/detail/mpl.hpp>
0026 #include <boost/intrusive/treap_algorithms.hpp>
0027 #include <boost/intrusive/link_mode.hpp>
0028 #include <boost/intrusive/priority_compare.hpp>
0029 #include <boost/intrusive/detail/node_cloner_disposer.hpp>
0030 #include <boost/intrusive/detail/key_nodeptr_comp.hpp>
0031
0032 #include <boost/static_assert.hpp>
0033 #include <boost/move/utility_core.hpp>
0034 #include <boost/move/adl_move_swap.hpp>
0035
0036 #include <cstddef>
0037 #include <boost/intrusive/detail/minimal_less_equal_header.hpp>
0038 #include <boost/intrusive/detail/minimal_pair_header.hpp> //std::pair
0039
0040 #if defined(BOOST_HAS_PRAGMA_ONCE)
0041 # pragma once
0042 #endif
0043
0044 namespace boost {
0045 namespace intrusive {
0046
0047
0048
0049 struct treap_defaults
0050 : bstree_defaults
0051 {
0052 typedef void priority;
0053 typedef void priority_of_value;
0054 };
0055
0056 template<class ValuePtr, class VoidOrPrioOfValue, class VoidOrPrioComp>
0057 struct treap_prio_types
0058 {
0059 typedef typename
0060 boost::movelib::pointer_element<ValuePtr>::type value_type;
0061 typedef typename get_key_of_value
0062 < VoidOrPrioOfValue, value_type>::type priority_of_value;
0063 typedef typename priority_of_value::type priority_type;
0064 typedef typename get_prio_comp< VoidOrPrioComp
0065 , priority_type
0066 >::type priority_compare;
0067 };
0068
0069 struct treap_tag;
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
0087 template<class T, class ...Options>
0088 #else
0089 template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, class VoidOrPrioOfValue, class VoidOrPrioComp, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
0090 #endif
0091 class treap_impl
0092
0093 : public bstree_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType, ConstantTimeSize, BsTreeAlgorithms, HeaderHolder>
0094
0095 , public detail::ebo_functor_holder
0096 < typename treap_prio_types<typename ValueTraits::pointer, VoidOrPrioOfValue, VoidOrPrioComp>::priority_compare
0097 , treap_tag>
0098
0099 {
0100 public:
0101 typedef ValueTraits value_traits;
0102
0103 typedef bstree_impl< ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType
0104 , ConstantTimeSize, BsTreeAlgorithms
0105 , HeaderHolder> tree_type;
0106 typedef tree_type implementation_defined;
0107 typedef treap_prio_types
0108 < typename ValueTraits::pointer
0109 , VoidOrPrioOfValue, VoidOrPrioComp> treap_prio_types_t;
0110
0111 typedef detail::ebo_functor_holder
0112 <typename treap_prio_types_t::priority_compare, treap_tag> prio_base;
0113
0114
0115
0116 typedef typename implementation_defined::pointer pointer;
0117 typedef typename implementation_defined::const_pointer const_pointer;
0118 typedef typename implementation_defined::value_type value_type;
0119 typedef typename implementation_defined::key_type key_type;
0120 typedef typename implementation_defined::key_of_value key_of_value;
0121 typedef typename implementation_defined::reference reference;
0122 typedef typename implementation_defined::const_reference const_reference;
0123 typedef typename implementation_defined::difference_type difference_type;
0124 typedef typename implementation_defined::size_type size_type;
0125 typedef typename implementation_defined::value_compare value_compare;
0126 typedef typename implementation_defined::key_compare key_compare;
0127 typedef typename implementation_defined::iterator iterator;
0128 typedef typename implementation_defined::const_iterator const_iterator;
0129 typedef typename implementation_defined::reverse_iterator reverse_iterator;
0130 typedef typename implementation_defined::const_reverse_iterator const_reverse_iterator;
0131 typedef typename implementation_defined::node_traits node_traits;
0132 typedef typename implementation_defined::node node;
0133 typedef typename implementation_defined::node_ptr node_ptr;
0134 typedef typename implementation_defined::const_node_ptr const_node_ptr;
0135 typedef BOOST_INTRUSIVE_IMPDEF(treap_algorithms<node_traits>) node_algorithms;
0136 typedef BOOST_INTRUSIVE_IMPDEF
0137 (typename treap_prio_types_t::priority_type) priority_type;
0138 typedef BOOST_INTRUSIVE_IMPDEF
0139 (typename treap_prio_types_t::priority_of_value) priority_of_value;
0140 typedef BOOST_INTRUSIVE_IMPDEF
0141 (typename treap_prio_types_t::priority_compare) priority_compare;
0142
0143 static const bool constant_time_size = implementation_defined::constant_time_size;
0144 static const bool stateful_value_traits = implementation_defined::stateful_value_traits;
0145 static const bool safemode_or_autounlink = is_safe_autounlink<value_traits::link_mode>::value;
0146
0147 typedef detail::key_nodeptr_comp<priority_compare, value_traits, priority_of_value> prio_node_prio_comp_t;
0148
0149 template<class PrioPrioComp>
0150 detail::key_nodeptr_comp<PrioPrioComp, value_traits, priority_of_value> prio_node_prio_comp(PrioPrioComp priopriocomp) const
0151 { return detail::key_nodeptr_comp<PrioPrioComp, value_traits, priority_of_value>(priopriocomp, &this->get_value_traits()); }
0152
0153
0154 private:
0155
0156
0157 BOOST_MOVABLE_BUT_NOT_COPYABLE(treap_impl)
0158
0159 const priority_compare &priv_pcomp() const
0160 { return static_cast<const prio_base&>(*this).get(); }
0161
0162 priority_compare &priv_pcomp()
0163 { return static_cast<prio_base&>(*this).get(); }
0164
0165
0166
0167 public:
0168 typedef typename node_algorithms::insert_commit_data insert_commit_data;
0169
0170
0171
0172
0173
0174
0175
0176
0177 treap_impl()
0178 : tree_type(), prio_base()
0179 {}
0180
0181
0182
0183
0184
0185
0186
0187
0188 explicit treap_impl( const key_compare &cmp
0189 , const priority_compare &pcmp = priority_compare()
0190 , const value_traits &v_traits = value_traits())
0191 : tree_type(cmp, v_traits), prio_base(pcmp)
0192 {}
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207 template<class Iterator>
0208 treap_impl( bool unique, Iterator b, Iterator e
0209 , const key_compare &cmp = key_compare()
0210 , const priority_compare &pcmp = priority_compare()
0211 , const value_traits &v_traits = value_traits())
0212 : tree_type(cmp, v_traits), prio_base(pcmp)
0213 {
0214 if(unique)
0215 this->insert_unique(b, e);
0216 else
0217 this->insert_equal(b, e);
0218 }
0219
0220
0221 treap_impl(BOOST_RV_REF(treap_impl) x)
0222 : tree_type(BOOST_MOVE_BASE(tree_type, x))
0223 , prio_base(::boost::move(x.priv_pcomp()))
0224 {}
0225
0226
0227 treap_impl& operator=(BOOST_RV_REF(treap_impl) x)
0228 { this->swap(x); return *this; }
0229
0230 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0231
0232 ~treap_impl();
0233
0234
0235 iterator begin() BOOST_NOEXCEPT;
0236
0237
0238 const_iterator begin() const BOOST_NOEXCEPT;
0239
0240
0241 const_iterator cbegin() const BOOST_NOEXCEPT;
0242
0243
0244 iterator end() BOOST_NOEXCEPT;
0245
0246
0247 const_iterator end() const BOOST_NOEXCEPT;
0248
0249
0250 const_iterator cend() const BOOST_NOEXCEPT;
0251 #endif
0252
0253
0254
0255
0256
0257
0258 BOOST_INTRUSIVE_FORCEINLINE iterator top() BOOST_NOEXCEPT
0259 { return this->tree_type::root(); }
0260
0261
0262
0263
0264
0265
0266 BOOST_INTRUSIVE_FORCEINLINE const_iterator top() const BOOST_NOEXCEPT
0267 { return this->ctop(); }
0268
0269
0270
0271
0272
0273
0274 BOOST_INTRUSIVE_FORCEINLINE const_iterator ctop() const BOOST_NOEXCEPT
0275 { return this->tree_type::root(); }
0276
0277 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0278
0279 reverse_iterator rbegin() BOOST_NOEXCEPT;
0280
0281
0282 const_reverse_iterator rbegin() const BOOST_NOEXCEPT;
0283
0284
0285 const_reverse_iterator crbegin() const BOOST_NOEXCEPT;
0286
0287
0288 reverse_iterator rend() BOOST_NOEXCEPT;
0289
0290
0291 const_reverse_iterator rend() const BOOST_NOEXCEPT;
0292
0293
0294 const_reverse_iterator crend() const BOOST_NOEXCEPT;
0295
0296
0297 iterator root() BOOST_NOEXCEPT;
0298
0299
0300 const_iterator root() const BOOST_NOEXCEPT;
0301
0302
0303 const_iterator croot() const BOOST_NOEXCEPT;
0304
0305 #endif
0306
0307
0308
0309
0310
0311
0312
0313 BOOST_INTRUSIVE_FORCEINLINE reverse_iterator rtop() BOOST_NOEXCEPT
0314 { return reverse_iterator(this->top()); }
0315
0316
0317
0318
0319
0320
0321
0322 BOOST_INTRUSIVE_FORCEINLINE const_reverse_iterator rtop() const BOOST_NOEXCEPT
0323 { return const_reverse_iterator(this->top()); }
0324
0325
0326
0327
0328
0329
0330
0331 BOOST_INTRUSIVE_FORCEINLINE const_reverse_iterator crtop() const BOOST_NOEXCEPT
0332 { return const_reverse_iterator(this->top()); }
0333
0334 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0335
0336 static treap_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT;
0337
0338
0339 static const treap_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT;
0340
0341
0342 static treap_impl &container_from_iterator(iterator it) BOOST_NOEXCEPT;
0343
0344
0345 static const treap_impl &container_from_iterator(const_iterator it) BOOST_NOEXCEPT;
0346
0347
0348 key_compare key_comp() const;
0349
0350
0351 value_compare value_comp() const;
0352
0353
0354 bool empty() const BOOST_NOEXCEPT;
0355
0356
0357 size_type size() const BOOST_NOEXCEPT;
0358 #endif
0359
0360
0361
0362
0363
0364
0365 priority_compare priority_comp() const
0366 { return this->priv_pcomp(); }
0367
0368
0369
0370
0371
0372
0373 void swap(treap_impl& other)
0374 {
0375
0376 ::boost::adl_move_swap(this->priv_pcomp(), other.priv_pcomp());
0377 tree_type::swap(other);
0378 }
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394 template <class Cloner, class Disposer>
0395 void clone_from(const treap_impl &src, Cloner cloner, Disposer disposer)
0396 {
0397 tree_type::clone_from(src, cloner, disposer);
0398 this->priv_pcomp() = src.priv_pcomp();
0399 }
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415 template <class Cloner, class Disposer>
0416 void clone_from(BOOST_RV_REF(treap_impl) src, Cloner cloner, Disposer disposer)
0417 {
0418 tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer);
0419 this->priv_pcomp() = ::boost::move(src.priv_pcomp());
0420 }
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432
0433 iterator insert_equal(reference value)
0434 {
0435 node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
0436 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
0437 iterator ret
0438 ( node_algorithms::insert_equal_upper_bound
0439 ( this->tree_type::header_ptr()
0440 , to_insert
0441 , this->key_node_comp(this->key_comp())
0442 , this->prio_node_prio_comp(this->priv_pcomp()))
0443 , this->priv_value_traits_ptr());
0444 this->tree_type::sz_traits().increment();
0445 return ret;
0446 }
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461
0462 iterator insert_equal(const_iterator hint, reference value)
0463 {
0464 node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
0465 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
0466 iterator ret
0467 (node_algorithms::insert_equal
0468 ( this->tree_type::header_ptr()
0469 , hint.pointed_node()
0470 , to_insert
0471 , this->key_node_comp(this->key_comp())
0472 , this->prio_node_prio_comp(this->priv_pcomp()))
0473 , this->priv_value_traits_ptr());
0474 this->tree_type::sz_traits().increment();
0475 return ret;
0476 }
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493 template<class Iterator>
0494 void insert_equal(Iterator b, Iterator e)
0495 {
0496 iterator iend(this->end());
0497 for (; b != e; ++b)
0498 this->insert_equal(iend, *b);
0499 }
0500
0501
0502
0503
0504
0505
0506
0507
0508
0509
0510
0511
0512
0513
0514 std::pair<iterator, bool> insert_unique(reference value)
0515 {
0516 insert_commit_data commit_data;
0517 std::pair<iterator, bool> ret = this->insert_unique_check(key_of_value()(value), priority_of_value()(value), commit_data);
0518 if(!ret.second)
0519 return ret;
0520 return std::pair<iterator, bool> (this->insert_unique_commit(value, commit_data), true);
0521 }
0522
0523
0524
0525
0526
0527
0528
0529
0530
0531
0532
0533
0534
0535
0536
0537
0538 iterator insert_unique(const_iterator hint, reference value)
0539 {
0540 insert_commit_data commit_data;
0541 std::pair<iterator, bool> ret = this->insert_unique_check(hint, key_of_value()(value), priority_of_value()(value), commit_data);
0542 if(!ret.second)
0543 return ret.first;
0544 return this->insert_unique_commit(value, commit_data);
0545 }
0546
0547
0548
0549
0550
0551
0552
0553
0554
0555
0556
0557
0558
0559
0560
0561 template<class Iterator>
0562 void insert_unique(Iterator b, Iterator e)
0563 {
0564 if(this->empty()){
0565 iterator iend(this->end());
0566 for (; b != e; ++b)
0567 this->insert_unique(iend, *b);
0568 }
0569 else{
0570 for (; b != e; ++b)
0571 this->insert_unique(*b);
0572 }
0573 }
0574
0575
0576
0577
0578
0579
0580
0581
0582
0583
0584
0585
0586
0587
0588
0589
0590
0591
0592
0593
0594
0595
0596
0597
0598
0599
0600
0601 std::pair<iterator, bool> insert_unique_check
0602 ( const key_type &key, const priority_type &prio, insert_commit_data &commit_data)
0603 { return this->insert_unique_check(key, this->key_comp(), prio, this->priv_pcomp(), commit_data); }
0604
0605
0606
0607
0608
0609
0610
0611
0612
0613
0614
0615
0616
0617
0618
0619
0620
0621
0622
0623
0624
0625
0626
0627
0628
0629
0630
0631
0632
0633 std::pair<iterator, bool> insert_unique_check
0634 ( const_iterator hint, const key_type &key, const priority_type &prio, insert_commit_data &commit_data)
0635 { return this->insert_unique_check(hint, key, this->key_comp(), prio, this->priv_pcomp(), commit_data); }
0636
0637
0638
0639
0640
0641
0642
0643
0644
0645
0646
0647
0648
0649
0650
0651
0652
0653
0654
0655
0656
0657
0658
0659
0660
0661
0662
0663
0664
0665
0666
0667
0668
0669
0670 template<class KeyType, class KeyTypeKeyCompare, class PrioType, class PrioValuePrioCompare>
0671 BOOST_INTRUSIVE_DOC1ST(std::pair<iterator BOOST_INTRUSIVE_I bool>
0672 , typename detail::disable_if_convertible
0673 <KeyType BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I
0674 std::pair<iterator BOOST_INTRUSIVE_I bool> >::type)
0675 insert_unique_check
0676 ( const KeyType &key, KeyTypeKeyCompare comp
0677 , const PrioType &prio, PrioValuePrioCompare prio_value_pcomp, insert_commit_data &commit_data)
0678 {
0679 std::pair<node_ptr, bool> const ret =
0680 (node_algorithms::insert_unique_check
0681 ( this->tree_type::header_ptr()
0682 , key, this->key_node_comp(comp)
0683 , prio, this->prio_node_prio_comp(prio_value_pcomp)
0684 , commit_data));
0685 return std::pair<iterator, bool>(iterator(ret.first, this->priv_value_traits_ptr()), ret.second);
0686 }
0687
0688
0689
0690
0691
0692
0693
0694
0695
0696
0697
0698
0699
0700
0701
0702
0703
0704
0705
0706
0707
0708
0709
0710
0711
0712
0713
0714
0715
0716
0717
0718
0719
0720
0721
0722
0723 template<class KeyType, class KeyTypeKeyCompare, class PrioType, class PrioValuePrioCompare>
0724 std::pair<iterator, bool> insert_unique_check
0725 ( const_iterator hint
0726 , const KeyType &key
0727 , KeyTypeKeyCompare comp
0728 , const PrioType &prio
0729 , PrioValuePrioCompare prio_value_pcomp
0730 , insert_commit_data &commit_data)
0731 {
0732 std::pair<node_ptr, bool> const ret =
0733 (node_algorithms::insert_unique_check
0734 ( this->tree_type::header_ptr(), hint.pointed_node()
0735 , key, this->key_node_comp(comp)
0736 , prio, this->prio_node_prio_comp(prio_value_pcomp)
0737 , commit_data));
0738 return std::pair<iterator, bool>(iterator(ret.first, this->priv_value_traits_ptr()), ret.second);
0739 }
0740
0741
0742
0743
0744
0745
0746
0747
0748
0749
0750
0751
0752
0753
0754
0755
0756
0757
0758 iterator insert_unique_commit(reference value, const insert_commit_data &commit_data) BOOST_NOEXCEPT
0759 {
0760 node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
0761 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
0762 node_algorithms::insert_unique_commit(this->tree_type::header_ptr(), to_insert, commit_data);
0763 this->tree_type::sz_traits().increment();
0764 return iterator(to_insert, this->priv_value_traits_ptr());
0765 }
0766
0767
0768
0769
0770
0771
0772
0773
0774
0775
0776
0777
0778
0779
0780
0781 iterator insert_before(const_iterator pos, reference value) BOOST_NOEXCEPT
0782 {
0783 node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
0784 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
0785 iterator ret
0786 ( node_algorithms::insert_before
0787 ( this->tree_type::header_ptr()
0788 , pos.pointed_node()
0789 , to_insert
0790 , this->prio_node_prio_comp(this->priv_pcomp())
0791 )
0792 , this->priv_value_traits_ptr());
0793 this->tree_type::sz_traits().increment();
0794 return ret;
0795 }
0796
0797
0798
0799
0800
0801
0802
0803
0804
0805
0806
0807
0808
0809
0810
0811 void push_back(reference value) BOOST_NOEXCEPT
0812 {
0813 node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
0814 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
0815 node_algorithms::push_back
0816 (this->tree_type::header_ptr(), to_insert, this->prio_node_prio_comp(this->priv_pcomp()));
0817 this->tree_type::sz_traits().increment();
0818 }
0819
0820
0821
0822
0823
0824
0825
0826
0827
0828
0829
0830
0831
0832
0833
0834 void push_front(reference value) BOOST_NOEXCEPT
0835 {
0836 node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
0837 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
0838 node_algorithms::push_front
0839 (this->tree_type::header_ptr(), to_insert, this->prio_node_prio_comp(this->priv_pcomp()));
0840 this->tree_type::sz_traits().increment();
0841 }
0842
0843
0844
0845
0846
0847
0848
0849
0850
0851 iterator erase(const_iterator i) BOOST_NOEXCEPT
0852 {
0853 const_iterator ret(i);
0854 ++ret;
0855 node_ptr to_erase(i.pointed_node());
0856 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || !node_algorithms::unique(to_erase));
0857 node_algorithms::erase
0858 (this->tree_type::header_ptr(), to_erase, this->prio_node_prio_comp(this->priv_pcomp()));
0859 this->tree_type::sz_traits().decrement();
0860 BOOST_IF_CONSTEXPR(safemode_or_autounlink)
0861 node_algorithms::init(to_erase);
0862 return ret.unconst();
0863 }
0864
0865
0866
0867
0868
0869
0870
0871
0872
0873
0874 iterator erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT
0875 { size_type n; return private_erase(b, e, n); }
0876
0877
0878
0879
0880
0881
0882
0883
0884
0885
0886
0887 size_type erase(const key_type &key)
0888 { return this->erase(key, this->key_comp()); }
0889
0890
0891
0892
0893
0894
0895
0896
0897
0898
0899
0900
0901
0902 template<class KeyType, class KeyTypeKeyCompare>
0903 BOOST_INTRUSIVE_DOC1ST(size_type
0904 , typename detail::disable_if_convertible<KeyTypeKeyCompare BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I size_type>::type)
0905 erase(const KeyType& key, KeyTypeKeyCompare comp)
0906 {
0907 std::pair<iterator,iterator> p = this->equal_range(key, comp);
0908 size_type n;
0909 private_erase(p.first, p.second, n);
0910 return n;
0911 }
0912
0913
0914
0915
0916
0917
0918
0919
0920
0921
0922
0923
0924 template<class Disposer>
0925 iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT
0926 {
0927 node_ptr to_erase(i.pointed_node());
0928 iterator ret(this->erase(i));
0929 disposer(this->get_value_traits().to_value_ptr(to_erase));
0930 return ret;
0931 }
0932
0933 #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
0934 template<class Disposer>
0935 iterator erase_and_dispose(iterator i, Disposer disposer) BOOST_NOEXCEPT
0936 { return this->erase_and_dispose(const_iterator(i), disposer); }
0937 #endif
0938
0939
0940
0941
0942
0943
0944
0945
0946
0947
0948
0949
0950
0951 template<class Disposer>
0952 iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT
0953 { size_type n; return private_erase(b, e, n, disposer); }
0954
0955
0956
0957
0958
0959
0960
0961
0962
0963
0964
0965
0966
0967
0968
0969 template<class Disposer>
0970 size_type erase_and_dispose(const key_type &key, Disposer disposer)
0971 {
0972 std::pair<iterator,iterator> p = this->equal_range(key);
0973 size_type n;
0974 private_erase(p.first, p.second, n, disposer);
0975 return n;
0976 }
0977
0978
0979
0980
0981
0982
0983
0984
0985
0986
0987
0988
0989
0990
0991
0992
0993 template<class KeyType, class KeyTypeKeyCompare, class Disposer>
0994 BOOST_INTRUSIVE_DOC1ST(size_type
0995 , typename detail::disable_if_convertible<KeyTypeKeyCompare BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I size_type>::type)
0996 erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer)
0997 {
0998 std::pair<iterator,iterator> p = this->equal_range(key, comp);
0999 size_type n;
1000 private_erase(p.first, p.second, n, disposer);
1001 return n;
1002 }
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013 void clear() BOOST_NOEXCEPT
1014 { tree_type::clear(); }
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025 template<class Disposer>
1026 void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT
1027 {
1028 node_algorithms::clear_and_dispose(this->tree_type::header_ptr()
1029 , detail::node_disposer<Disposer, value_traits, TreapAlgorithms>(disposer, &this->get_value_traits()));
1030 node_algorithms::init_header(this->tree_type::header_ptr());
1031 this->tree_type::sz_traits().set_size(0);
1032 }
1033
1034 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1035
1036 template<class T, class ...Options2> void merge_unique(sgtree<T, Options2...> &);
1037 #else
1038 template<class Compare2>
1039 void merge_unique(treap_impl
1040 <ValueTraits, VoidOrKeyOfValue, Compare2, VoidOrPrioOfValue, VoidOrPrioComp, SizeType, ConstantTimeSize, HeaderHolder> &source)
1041 #endif
1042 {
1043 node_ptr it (node_algorithms::begin_node(source.header_ptr()))
1044 , itend(node_algorithms::end_node (source.header_ptr()));
1045
1046 while(it != itend){
1047 node_ptr const p(it);
1048 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || !node_algorithms::unique(p));
1049 it = node_algorithms::next_node(it);
1050
1051 if( node_algorithms::transfer_unique
1052 ( this->header_ptr(), this->key_node_comp(this->key_comp())
1053 , this->prio_node_prio_comp(this->priv_pcomp()), source.header_ptr(), p) ){
1054 this->sz_traits().increment();
1055 source.sz_traits().decrement();
1056 }
1057 }
1058 }
1059
1060 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1061
1062 template<class T, class ...Options2> void merge_equal(sgtree<T, Options2...> &);
1063 #else
1064 template<class Compare2>
1065 void merge_equal(treap_impl
1066 <ValueTraits, VoidOrKeyOfValue, Compare2, VoidOrPrioOfValue, VoidOrPrioComp, SizeType, ConstantTimeSize, HeaderHolder> &source)
1067 #endif
1068 {
1069 node_ptr it (node_algorithms::begin_node(source.header_ptr()))
1070 , itend(node_algorithms::end_node (source.header_ptr()));
1071
1072 while(it != itend){
1073 node_ptr const p(it);
1074 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || !node_algorithms::unique(p));
1075 it = node_algorithms::next_node(it);
1076 node_algorithms::transfer_equal
1077 ( this->header_ptr(), this->key_node_comp(this->key_comp())
1078 , this->prio_node_prio_comp(this->priv_pcomp()), source.header_ptr(), p);
1079 this->sz_traits().increment();
1080 source.sz_traits().decrement();
1081 }
1082 }
1083
1084
1085 template <class ExtraChecker>
1086 void check(ExtraChecker extra_checker) const
1087 {
1088 typedef detail::key_nodeptr_comp<priority_compare, value_traits, priority_of_value> nodeptr_prio_comp_t;
1089 tree_type::check(detail::treap_node_extra_checker
1090 <ValueTraits, nodeptr_prio_comp_t, ExtraChecker>
1091 (this->prio_node_prio_comp(this->priv_pcomp()), extra_checker));
1092 }
1093
1094
1095 void check() const
1096 { check(detail::empty_node_checker<ValueTraits>()); }
1097
1098 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
1099
1100 size_type count(const key_type &key) const;
1101
1102
1103 template<class KeyType, class KeyTypeKeyCompare>
1104 size_type count(const KeyType& key, KeyTypeKeyCompare comp) const;
1105
1106
1107 iterator lower_bound(const key_type &key);
1108
1109
1110 template<class KeyType, class KeyTypeKeyCompare>
1111 iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
1112
1113
1114 const_iterator lower_bound(const key_type &key) const;
1115
1116
1117 template<class KeyType, class KeyTypeKeyCompare>
1118 const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
1119
1120
1121 iterator upper_bound(const key_type &key);
1122
1123
1124 template<class KeyType, class KeyTypeKeyCompare>
1125 iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
1126
1127
1128 const_iterator upper_bound(const key_type &key) const;
1129
1130
1131 template<class KeyType, class KeyTypeKeyCompare>
1132 const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
1133
1134
1135 iterator find(const key_type &key);
1136
1137
1138 template<class KeyType, class KeyTypeKeyCompare>
1139 iterator find(const KeyType& key, KeyTypeKeyCompare comp);
1140
1141
1142 const_iterator find(const key_type &key) const;
1143
1144
1145 template<class KeyType, class KeyTypeKeyCompare>
1146 const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
1147
1148
1149 std::pair<iterator,iterator> equal_range(const key_type &key);
1150
1151
1152 template<class KeyType, class KeyTypeKeyCompare>
1153 std::pair<iterator,iterator> equal_range(const KeyType& key, KeyTypeKeyCompare comp);
1154
1155
1156 std::pair<const_iterator, const_iterator>
1157 equal_range(const key_type &key) const;
1158
1159
1160 template<class KeyType, class KeyTypeKeyCompare>
1161 std::pair<const_iterator, const_iterator>
1162 equal_range(const KeyType& key, KeyTypeKeyCompare comp) const;
1163
1164
1165 std::pair<iterator,iterator> bounded_range
1166 (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed);
1167
1168
1169 template<class KeyType, class KeyTypeKeyCompare>
1170 std::pair<iterator,iterator> bounded_range
1171 (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
1172
1173
1174 std::pair<const_iterator, const_iterator>
1175 bounded_range(const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
1176
1177
1178 template<class KeyType, class KeyTypeKeyCompare>
1179 std::pair<const_iterator, const_iterator> bounded_range
1180 (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
1181
1182
1183 static iterator s_iterator_to(reference value) BOOST_NOEXCEPT;
1184
1185
1186 static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT;
1187
1188
1189 iterator iterator_to(reference value) BOOST_NOEXCEPT;
1190
1191
1192 const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT;
1193
1194
1195 static void init_node(reference value) BOOST_NOEXCEPT;
1196
1197
1198 pointer unlink_leftmost_without_rebalance() BOOST_NOEXCEPT;
1199
1200
1201 void replace_node(iterator replace_this, reference with_this) BOOST_NOEXCEPT;
1202
1203
1204 void remove_node(reference value) BOOST_NOEXCEPT;
1205
1206 friend bool operator< (const treap_impl &x, const treap_impl &y);
1207
1208 friend bool operator==(const treap_impl &x, const treap_impl &y);
1209
1210 friend bool operator!= (const treap_impl &x, const treap_impl &y);
1211
1212 friend bool operator>(const treap_impl &x, const treap_impl &y);
1213
1214 friend bool operator<=(const treap_impl &x, const treap_impl &y);
1215
1216 friend bool operator>=(const treap_impl &x, const treap_impl &y);
1217
1218 friend void swap(treap_impl &x, treap_impl &y);
1219
1220 #endif
1221
1222
1223 private:
1224 template<class Disposer>
1225 iterator private_erase(const_iterator b, const_iterator e, size_type &n, Disposer disposer)
1226 {
1227 for(n = 0; b != e; ++n)
1228 this->erase_and_dispose(b++, disposer);
1229 return b.unconst();
1230 }
1231
1232 iterator private_erase(const_iterator b, const_iterator e, size_type &n)
1233 {
1234 for(n = 0; b != e; ++n)
1235 this->erase(b++);
1236 return b.unconst();
1237 }
1238
1239 };
1240
1241
1242
1243
1244 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1245 template<class T, class ...Options>
1246 #else
1247 template<class T, class O1 = void, class O2 = void
1248 , class O3 = void, class O4 = void
1249 , class O5 = void, class O6 = void
1250 , class O7 = void>
1251 #endif
1252 struct make_treap
1253 {
1254 typedef typename pack_options
1255 < treap_defaults,
1256 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1257 O1, O2, O3, O4, O5, O6, O7
1258 #else
1259 Options...
1260 #endif
1261 >::type packed_options;
1262
1263 typedef typename detail::get_value_traits
1264 <T, typename packed_options::proto_value_traits>::type value_traits;
1265
1266 typedef treap_impl
1267 < value_traits
1268 , typename packed_options::key_of_value
1269 , typename packed_options::compare
1270 , typename packed_options::priority_of_value
1271 , typename packed_options::priority
1272 , typename packed_options::size_type
1273 , packed_options::constant_time_size
1274 , typename packed_options::header_holder_type
1275 > implementation_defined;
1276
1277 typedef implementation_defined type;
1278 };
1279
1280 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
1281
1282 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1283 template<class T, class O1, class O2, class O3, class O4, class O5, class O6, class O7>
1284 #else
1285 template<class T, class ...Options>
1286 #endif
1287 class treap
1288 : public make_treap<T,
1289 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1290 O1, O2, O3, O4, O5, O6, O7
1291 #else
1292 Options...
1293 #endif
1294 >::type
1295 {
1296 typedef typename make_treap
1297 <T,
1298 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1299 O1, O2, O3, O4, O5, O6, O7
1300 #else
1301 Options...
1302 #endif
1303 >::type Base;
1304 BOOST_MOVABLE_BUT_NOT_COPYABLE(treap)
1305
1306 public:
1307 typedef typename Base::key_compare key_compare;
1308 typedef typename Base::priority_compare priority_compare;
1309 typedef typename Base::value_traits value_traits;
1310 typedef typename Base::iterator iterator;
1311 typedef typename Base::const_iterator const_iterator;
1312 typedef typename Base::reverse_iterator reverse_iterator;
1313 typedef typename Base::const_reverse_iterator const_reverse_iterator;
1314
1315
1316 BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
1317
1318 BOOST_INTRUSIVE_FORCEINLINE treap()
1319 : Base()
1320 {}
1321
1322 BOOST_INTRUSIVE_FORCEINLINE explicit treap( const key_compare &cmp
1323 , const priority_compare &pcmp = priority_compare()
1324 , const value_traits &v_traits = value_traits())
1325 : Base(cmp, pcmp, v_traits)
1326 {}
1327
1328 template<class Iterator>
1329 BOOST_INTRUSIVE_FORCEINLINE treap( bool unique, Iterator b, Iterator e
1330 , const key_compare &cmp = key_compare()
1331 , const priority_compare &pcmp = priority_compare()
1332 , const value_traits &v_traits = value_traits())
1333 : Base(unique, b, e, cmp, pcmp, v_traits)
1334 {}
1335
1336 BOOST_INTRUSIVE_FORCEINLINE treap(BOOST_RV_REF(treap) x)
1337 : Base(BOOST_MOVE_BASE(Base, x))
1338 {}
1339
1340 BOOST_INTRUSIVE_FORCEINLINE treap& operator=(BOOST_RV_REF(treap) x)
1341 { return static_cast<treap&>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
1342
1343 template <class Cloner, class Disposer>
1344 BOOST_INTRUSIVE_FORCEINLINE void clone_from(const treap &src, Cloner cloner, Disposer disposer)
1345 { Base::clone_from(src, cloner, disposer); }
1346
1347 template <class Cloner, class Disposer>
1348 BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(treap) src, Cloner cloner, Disposer disposer)
1349 { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
1350
1351 BOOST_INTRUSIVE_FORCEINLINE static treap &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT
1352 { return static_cast<treap &>(Base::container_from_end_iterator(end_iterator)); }
1353
1354 BOOST_INTRUSIVE_FORCEINLINE static const treap &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT
1355 { return static_cast<const treap &>(Base::container_from_end_iterator(end_iterator)); }
1356
1357 BOOST_INTRUSIVE_FORCEINLINE static treap &container_from_iterator(iterator it) BOOST_NOEXCEPT
1358 { return static_cast<treap &>(Base::container_from_iterator(it)); }
1359
1360 BOOST_INTRUSIVE_FORCEINLINE static const treap &container_from_iterator(const_iterator it) BOOST_NOEXCEPT
1361 { return static_cast<const treap &>(Base::container_from_iterator(it)); }
1362 };
1363
1364 #endif
1365
1366 }
1367 }
1368
1369 #include <boost/intrusive/detail/config_end.hpp>
1370
1371 #endif