File indexing completed on 2025-01-18 09:30:19
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_CONTAINER_SET_HPP
0012 #define BOOST_CONTAINER_SET_HPP
0013
0014 #ifndef BOOST_CONFIG_HPP
0015 # include <boost/config.hpp>
0016 #endif
0017
0018 #if defined(BOOST_HAS_PRAGMA_ONCE)
0019 # pragma once
0020 #endif
0021
0022 #include <boost/container/detail/config_begin.hpp>
0023 #include <boost/container/detail/workaround.hpp>
0024
0025 #include <boost/container/container_fwd.hpp>
0026
0027 #include <boost/container/detail/mpl.hpp>
0028 #include <boost/container/detail/tree.hpp>
0029 #include <boost/container/new_allocator.hpp> //new_allocator
0030
0031 #include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
0032 #include <boost/intrusive/detail/minimal_less_equal_header.hpp>//less, equal
0033
0034 #include <boost/move/traits.hpp>
0035 #include <boost/move/utility_core.hpp>
0036
0037 #include <boost/move/detail/move_helpers.hpp>
0038 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0039 #include <boost/move/detail/fwd_macros.hpp>
0040 #endif
0041
0042 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
0043 #include <initializer_list>
0044 #endif
0045
0046 namespace boost {
0047 namespace container {
0048
0049 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063 template <class Key, class Compare = std::less<Key>, class Allocator = new_allocator<Key>, class Options = void>
0064 #else
0065 template <class Key, class Compare, class Allocator, class Options>
0066 #endif
0067 class set
0068
0069 : public dtl::tree
0070 < Key, void, Compare, Allocator, Options>
0071
0072 {
0073 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0074 private:
0075 BOOST_COPYABLE_AND_MOVABLE(set)
0076 typedef dtl::tree
0077 < Key, void, Compare, Allocator, Options> base_t;
0078 #endif
0079
0080 public:
0081
0082
0083
0084
0085
0086 typedef Key key_type;
0087 typedef Key value_type;
0088 typedef Compare key_compare;
0089 typedef key_compare value_compare;
0090 typedef typename base_t::allocator_type allocator_type;
0091 typedef ::boost::container::allocator_traits<allocator_type> allocator_traits_type;
0092 typedef typename ::boost::container::allocator_traits<allocator_type>::pointer pointer;
0093 typedef typename ::boost::container::allocator_traits<allocator_type>::const_pointer const_pointer;
0094 typedef typename ::boost::container::allocator_traits<allocator_type>::reference reference;
0095 typedef typename ::boost::container::allocator_traits<allocator_type>::const_reference const_reference;
0096 typedef typename ::boost::container::allocator_traits<allocator_type>::size_type size_type;
0097 typedef typename ::boost::container::allocator_traits<allocator_type>::difference_type difference_type;
0098 typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type) stored_allocator_type;
0099 typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator) iterator;
0100 typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_iterator) const_iterator;
0101 typedef typename BOOST_CONTAINER_IMPDEF(base_t::reverse_iterator) reverse_iterator;
0102 typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator;
0103 typedef typename BOOST_CONTAINER_IMPDEF(base_t::node_type) node_type;
0104 typedef typename BOOST_CONTAINER_IMPDEF(base_t::insert_return_type) insert_return_type;
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116 BOOST_CONTAINER_FORCEINLINE set()
0117 BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<allocator_type>::value &&
0118 dtl::is_nothrow_default_constructible<Compare>::value)
0119 : base_t()
0120 {}
0121
0122
0123
0124
0125 BOOST_CONTAINER_FORCEINLINE explicit set(const allocator_type& a)
0126 : base_t(a)
0127 {}
0128
0129
0130
0131
0132 BOOST_CONTAINER_FORCEINLINE explicit set(const Compare& comp)
0133 : base_t(comp)
0134 {}
0135
0136
0137
0138
0139
0140 BOOST_CONTAINER_FORCEINLINE set(const Compare& comp, const allocator_type& a)
0141 : base_t(comp, a)
0142 {}
0143
0144
0145
0146
0147
0148
0149 template <class InputIterator>
0150 BOOST_CONTAINER_FORCEINLINE set(InputIterator first, InputIterator last)
0151 : base_t(true, first, last)
0152 {}
0153
0154
0155
0156
0157
0158
0159 template <class InputIterator>
0160 BOOST_CONTAINER_FORCEINLINE set(InputIterator first, InputIterator last, const allocator_type& a)
0161 : base_t(true, first, last, key_compare(), a)
0162 {}
0163
0164
0165
0166
0167
0168
0169 template <class InputIterator>
0170 BOOST_CONTAINER_FORCEINLINE set(InputIterator first, InputIterator last, const Compare& comp)
0171 : base_t(true, first, last, comp)
0172 {}
0173
0174
0175
0176
0177
0178
0179 template <class InputIterator>
0180 BOOST_CONTAINER_FORCEINLINE set(InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
0181 : base_t(true, first, last, comp, a)
0182 {}
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194 template <class InputIterator>
0195 BOOST_CONTAINER_FORCEINLINE set( ordered_unique_range_t, InputIterator first, InputIterator last)
0196 : base_t(ordered_range, first, last)
0197 {}
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209 template <class InputIterator>
0210 BOOST_CONTAINER_FORCEINLINE set( ordered_unique_range_t, InputIterator first, InputIterator last, const Compare& comp )
0211 : base_t(ordered_range, first, last, comp)
0212 {}
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224 template <class InputIterator>
0225 BOOST_CONTAINER_FORCEINLINE set( ordered_unique_range_t, InputIterator first, InputIterator last
0226 , const Compare& comp, const allocator_type& a)
0227 : base_t(ordered_range, first, last, comp, a)
0228 {}
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240 template <class InputIterator>
0241 BOOST_CONTAINER_FORCEINLINE set(ordered_unique_range_t, InputIterator first, InputIterator last, const allocator_type& a)
0242 : base_t(ordered_range, first, last, Compare(), a)
0243 {}
0244
0245 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
0246
0247
0248
0249
0250
0251 BOOST_CONTAINER_FORCEINLINE set(std::initializer_list<value_type> il)
0252 : base_t(true, il.begin(), il.end())
0253 {}
0254
0255
0256
0257
0258
0259
0260 BOOST_CONTAINER_FORCEINLINE set(std::initializer_list<value_type> il, const allocator_type& a)
0261 : base_t(true, il.begin(), il.end(), Compare(), a)
0262 {}
0263
0264
0265
0266
0267
0268
0269 BOOST_CONTAINER_FORCEINLINE set(std::initializer_list<value_type> il, const Compare& comp )
0270 : base_t(true, il.begin(), il.end(), comp)
0271 {}
0272
0273
0274
0275
0276
0277
0278 BOOST_CONTAINER_FORCEINLINE set(std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
0279 : base_t(true, il.begin(), il.end(), comp, a)
0280 {}
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292 BOOST_CONTAINER_FORCEINLINE set( ordered_unique_range_t, std::initializer_list<value_type> il)
0293 : base_t(ordered_range, il.begin(), il.end())
0294 {}
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306 BOOST_CONTAINER_FORCEINLINE set( ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp)
0307 : base_t(ordered_range, il.begin(), il.end(), comp)
0308 {}
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320 BOOST_CONTAINER_FORCEINLINE set( ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
0321 : base_t(ordered_range, il.begin(), il.end(), comp, a)
0322 {}
0323 #endif
0324
0325
0326
0327
0328 BOOST_CONTAINER_FORCEINLINE set(const set& x)
0329 : base_t(static_cast<const base_t&>(x))
0330 {}
0331
0332
0333
0334
0335
0336
0337 BOOST_CONTAINER_FORCEINLINE set(BOOST_RV_REF(set) x)
0338 BOOST_NOEXCEPT_IF(boost::container::dtl::is_nothrow_move_constructible<Compare>::value)
0339 : base_t(BOOST_MOVE_BASE(base_t, x))
0340 {}
0341
0342
0343
0344
0345 BOOST_CONTAINER_FORCEINLINE set(const set& x, const allocator_type &a)
0346 : base_t(static_cast<const base_t&>(x), a)
0347 {}
0348
0349
0350
0351
0352
0353 BOOST_CONTAINER_FORCEINLINE set(BOOST_RV_REF(set) x, const allocator_type &a)
0354 : base_t(BOOST_MOVE_BASE(base_t, x), a)
0355 {}
0356
0357
0358
0359
0360 BOOST_CONTAINER_FORCEINLINE set& operator=(BOOST_COPY_ASSIGN_REF(set) x)
0361 { return static_cast<set&>(this->base_t::operator=(static_cast<const base_t&>(x))); }
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371 BOOST_CONTAINER_FORCEINLINE set& operator=(BOOST_RV_REF(set) x)
0372 BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value ||
0373 allocator_traits_type::is_always_equal::value) &&
0374 boost::container::dtl::is_nothrow_move_assignable<Compare>::value)
0375 { return static_cast<set&>(this->base_t::operator=(BOOST_MOVE_BASE(base_t, x))); }
0376
0377 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
0378
0379
0380
0381 set& operator=(std::initializer_list<value_type> il)
0382 {
0383 this->clear();
0384 insert(il.begin(), il.end());
0385 return *this;
0386 }
0387 #endif
0388
0389 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0390
0391
0392
0393
0394
0395 allocator_type get_allocator() const;
0396
0397
0398
0399
0400
0401
0402
0403
0404 stored_allocator_type &get_stored_allocator();
0405
0406
0407
0408
0409
0410
0411
0412
0413 const stored_allocator_type &get_stored_allocator() const;
0414
0415
0416
0417
0418
0419
0420 iterator begin();
0421
0422
0423
0424
0425
0426
0427 const_iterator begin() const;
0428
0429
0430
0431
0432
0433
0434 const_iterator cbegin() const;
0435
0436
0437
0438
0439
0440
0441 iterator end();
0442
0443
0444
0445
0446
0447
0448 const_iterator end() const;
0449
0450
0451
0452
0453
0454
0455 const_iterator cend() const;
0456
0457
0458
0459
0460
0461
0462
0463 reverse_iterator rbegin();
0464
0465
0466
0467
0468
0469
0470
0471 const_reverse_iterator rbegin() const;
0472
0473
0474
0475
0476
0477
0478
0479 const_reverse_iterator crbegin() const;
0480
0481
0482
0483
0484
0485
0486
0487 reverse_iterator rend();
0488
0489
0490
0491
0492
0493
0494
0495 const_reverse_iterator rend() const;
0496
0497
0498
0499
0500
0501
0502
0503 const_reverse_iterator crend() const;
0504
0505
0506
0507
0508
0509
0510 bool empty() const;
0511
0512
0513
0514
0515
0516
0517 size_type size() const;
0518
0519
0520
0521
0522
0523
0524 size_type max_size() const;
0525 #endif
0526
0527 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0528
0529
0530
0531
0532
0533
0534
0535
0536
0537
0538
0539
0540
0541
0542
0543 template <class... Args>
0544 BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> emplace(BOOST_FWD_REF(Args)... args)
0545 { return this->base_t::emplace_unique(boost::forward<Args>(args)...); }
0546
0547
0548
0549
0550
0551
0552
0553
0554
0555
0556 template <class... Args>
0557 BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args)
0558 { return this->base_t::emplace_hint_unique(p, boost::forward<Args>(args)...); }
0559
0560 #else
0561
0562 #define BOOST_CONTAINER_SET_EMPLACE_CODE(N) \
0563 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
0564 BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> emplace(BOOST_MOVE_UREF##N)\
0565 { return this->base_t::emplace_unique(BOOST_MOVE_FWD##N); }\
0566 \
0567 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
0568 BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
0569 { return this->base_t::emplace_hint_unique(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
0570
0571 BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SET_EMPLACE_CODE)
0572 #undef BOOST_CONTAINER_SET_EMPLACE_CODE
0573
0574 #endif
0575
0576 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0577
0578
0579
0580
0581
0582
0583
0584
0585 std::pair<iterator, bool> insert(const value_type &x);
0586
0587
0588
0589
0590
0591
0592
0593
0594
0595 std::pair<iterator, bool> insert(value_type &&x);
0596 #else
0597 private:
0598 typedef std::pair<iterator, bool> insert_return_pair;
0599 public:
0600 BOOST_MOVE_CONVERSION_AWARE_CATCH
0601 (insert, value_type, insert_return_pair, this->base_t::insert_unique_convertible)
0602 #endif
0603
0604 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0605
0606
0607
0608
0609
0610
0611
0612
0613
0614 iterator insert(const_iterator p, const value_type &x);
0615
0616
0617
0618
0619
0620
0621
0622 iterator insert(const_iterator p, value_type &&x);
0623 #else
0624 BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG
0625 (insert, value_type, iterator, this->base_t::insert_unique_hint_convertible, const_iterator, const_iterator)
0626 #endif
0627
0628
0629
0630
0631
0632
0633
0634 template <class InputIterator>
0635 BOOST_CONTAINER_FORCEINLINE void insert(InputIterator first, InputIterator last)
0636 { this->base_t::insert_unique_range(first, last); }
0637
0638 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
0639
0640
0641
0642
0643 BOOST_CONTAINER_FORCEINLINE void insert(std::initializer_list<value_type> il)
0644 { this->base_t::insert_unique_range(il.begin(), il.end()); }
0645 #endif
0646
0647
0648 BOOST_CONTAINER_FORCEINLINE insert_return_type insert(BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh)
0649 { return this->base_t::insert_unique_node(boost::move(nh)); }
0650
0651
0652 BOOST_CONTAINER_FORCEINLINE insert_return_type insert(const_iterator hint, BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh)
0653 { return this->base_t::insert_unique_node(hint, boost::move(nh)); }
0654
0655
0656 template<class C2>
0657 BOOST_CONTAINER_FORCEINLINE void merge(set<Key, C2, Allocator, Options>& source)
0658 {
0659 typedef dtl::tree
0660 <Key, void, C2, Allocator, Options> base2_t;
0661 this->base_t::merge_unique(static_cast<base2_t&>(source));
0662 }
0663
0664
0665 template<class C2>
0666 BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG set<Key, C2, Allocator, Options> BOOST_RV_REF_END source)
0667 { return this->merge(static_cast<set<Key, C2, Allocator, Options>&>(source)); }
0668
0669
0670 template<class C2>
0671 BOOST_CONTAINER_FORCEINLINE void merge(multiset<Key, C2, Allocator, Options>& source)
0672 {
0673 typedef dtl::tree
0674 <Key, void, C2, Allocator, Options> base2_t;
0675 this->base_t::merge_unique(static_cast<base2_t&>(source));
0676 }
0677
0678
0679 template<class C2>
0680 BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG multiset<Key, C2, Allocator, Options> BOOST_RV_REF_END source)
0681 { return this->merge(static_cast<multiset<Key, C2, Allocator, Options>&>(source)); }
0682
0683
0684
0685
0686
0687
0688 BOOST_CONTAINER_FORCEINLINE size_type erase(const key_type& x)
0689 { return this->base_t::erase_unique(x); }
0690
0691 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0692
0693
0694
0695
0696
0697
0698
0699
0700 iterator erase(const_iterator p);
0701
0702
0703
0704
0705
0706
0707 iterator erase(const_iterator first, const_iterator last);
0708
0709
0710 node_type extract(const_iterator p);
0711
0712
0713 node_type extract(const key_type& x);
0714
0715
0716
0717
0718
0719
0720 void swap(set& x)
0721 BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
0722 && boost::container::dtl::is_nothrow_swappable<Compare>::value );
0723
0724
0725
0726
0727
0728
0729 void clear();
0730
0731
0732
0733
0734
0735 key_compare key_comp() const;
0736
0737
0738
0739
0740
0741 value_compare value_comp() const;
0742
0743
0744
0745
0746
0747 iterator find(const key_type& x);
0748
0749
0750
0751
0752
0753 const_iterator find(const key_type& x) const;
0754
0755
0756
0757
0758
0759
0760
0761
0762 template<typename K>
0763 iterator find(const K& x);
0764
0765
0766
0767
0768
0769
0770
0771
0772 template<typename K>
0773 const_iterator find(const K& x) const;
0774
0775 #else
0776 using base_t::erase;
0777 #endif
0778
0779
0780
0781
0782 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0783 size_type count(const key_type& x) const
0784 { return static_cast<size_type>(this->base_t::find(x) != this->base_t::cend()); }
0785
0786
0787
0788
0789
0790
0791
0792 template<typename K>
0793 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0794 size_type count(const K& x) const
0795 { return static_cast<size_type>(this->find(x) != this->cend()); }
0796
0797 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0798
0799
0800
0801
0802
0803 bool contains(const key_type& x) const;
0804
0805
0806
0807
0808
0809
0810
0811
0812 template<typename K>
0813 bool contains(const K& x) const;
0814
0815
0816
0817
0818
0819 iterator lower_bound(const key_type& x);
0820
0821
0822
0823
0824
0825 const_iterator lower_bound(const key_type& x) const;
0826
0827
0828
0829
0830
0831
0832
0833
0834 template<typename K>
0835 iterator lower_bound(const K& x);
0836
0837
0838
0839
0840
0841
0842
0843
0844 template<typename K>
0845 const_iterator lower_bound(const K& x) const;
0846
0847
0848
0849
0850
0851 iterator upper_bound(const key_type& x);
0852
0853
0854
0855
0856
0857 const_iterator upper_bound(const key_type& x) const;
0858
0859
0860
0861
0862
0863
0864
0865
0866 template<typename K>
0867 iterator upper_bound(const K& x);
0868
0869
0870
0871
0872
0873
0874
0875
0876 template<typename K>
0877 const_iterator upper_bound(const K& x) const;
0878
0879 #endif
0880
0881
0882
0883
0884 BOOST_CONTAINER_FORCEINLINE std::pair<iterator,iterator> equal_range(const key_type& x)
0885 { return this->base_t::lower_bound_range(x); }
0886
0887
0888
0889
0890 BOOST_CONTAINER_FORCEINLINE std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const
0891 { return this->base_t::lower_bound_range(x); }
0892
0893
0894
0895
0896
0897
0898
0899 template<typename K>
0900 BOOST_CONTAINER_FORCEINLINE std::pair<iterator,iterator> equal_range(const K& x)
0901 { return this->base_t::lower_bound_range(x); }
0902
0903
0904
0905
0906
0907
0908
0909 template<typename K>
0910 BOOST_CONTAINER_FORCEINLINE std::pair<const_iterator,const_iterator> equal_range(const K& x) const
0911 { return this->base_t::lower_bound_range(x); }
0912
0913 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0914
0915
0916
0917
0918 void rebalance();
0919
0920
0921
0922
0923 friend bool operator==(const set& x, const set& y);
0924
0925
0926
0927
0928 friend bool operator!=(const set& x, const set& y);
0929
0930
0931
0932
0933 friend bool operator<(const set& x, const set& y);
0934
0935
0936
0937
0938 friend bool operator>(const set& x, const set& y);
0939
0940
0941
0942
0943 friend bool operator<=(const set& x, const set& y);
0944
0945
0946
0947
0948 friend bool operator>=(const set& x, const set& y);
0949
0950
0951
0952
0953 friend void swap(set& x, set& y)
0954 BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
0955 && boost::container::dtl::is_nothrow_swappable<Compare>::value );
0956
0957 #endif
0958 };
0959
0960 #ifndef BOOST_CONTAINER_NO_CXX17_CTAD
0961
0962 template <typename InputIterator>
0963 set(InputIterator, InputIterator) ->
0964 set< it_based_value_type_t<InputIterator> >;
0965
0966 template < typename InputIterator, typename AllocatorOrCompare>
0967 set(InputIterator, InputIterator, AllocatorOrCompare const&) ->
0968 set< it_based_value_type_t<InputIterator>
0969 , typename dtl::if_c<
0970 dtl::is_allocator<AllocatorOrCompare>::value
0971 , std::less<it_based_value_type_t<InputIterator>>
0972 , AllocatorOrCompare
0973 >::type
0974 , typename dtl::if_c<
0975 dtl::is_allocator<AllocatorOrCompare>::value
0976 , AllocatorOrCompare
0977 , new_allocator<it_based_value_type_t<InputIterator>>
0978 >::type
0979 >;
0980
0981 template < typename InputIterator, typename Compare, typename Allocator
0982 , typename = dtl::require_nonallocator_t<Compare>
0983 , typename = dtl::require_allocator_t<Allocator>>
0984 set(InputIterator, InputIterator, Compare const&, Allocator const&) ->
0985 set< it_based_value_type_t<InputIterator>
0986 , Compare
0987 , Allocator>;
0988
0989 template <typename InputIterator>
0990 set(ordered_unique_range_t, InputIterator, InputIterator) ->
0991 set< it_based_value_type_t<InputIterator>>;
0992
0993
0994 template < typename InputIterator, typename AllocatorOrCompare>
0995 set(ordered_unique_range_t, InputIterator, InputIterator, AllocatorOrCompare const&) ->
0996 set< it_based_value_type_t<InputIterator>
0997 , typename dtl::if_c<
0998 dtl::is_allocator<AllocatorOrCompare>::value
0999 , std::less<it_based_value_type_t<InputIterator>>
1000 , AllocatorOrCompare
1001 >::type
1002 , typename dtl::if_c<
1003 dtl::is_allocator<AllocatorOrCompare>::value
1004 , AllocatorOrCompare
1005 , new_allocator<it_based_value_type_t<InputIterator>>
1006 >::type
1007 >;
1008
1009 template < typename InputIterator, typename Compare, typename Allocator
1010 , typename = dtl::require_nonallocator_t<Compare>
1011 , typename = dtl::require_allocator_t<Allocator>>
1012 set(ordered_unique_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) ->
1013 set< it_based_value_type_t<InputIterator>
1014 , Compare
1015 , Allocator>;
1016
1017 #endif
1018
1019 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
1020
1021 }
1022
1023
1024
1025 template <class Key, class Compare, class Allocator, class Options>
1026 struct has_trivial_destructor_after_move<boost::container::set<Key, Compare, Allocator, Options> >
1027 {
1028 typedef ::boost::container::dtl::tree<Key, void, Compare, Allocator, Options> tree;
1029 static const bool value = ::boost::has_trivial_destructor_after_move<tree>::value;
1030 };
1031
1032 namespace container {
1033
1034 #endif
1035
1036 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050 template <class Key, class Compare = std::less<Key>, class Allocator = new_allocator<Key>, class Options = tree_assoc_defaults >
1051 #else
1052 template <class Key, class Compare, class Allocator, class Options>
1053 #endif
1054 class multiset
1055
1056 : public dtl::tree
1057 <Key, void, Compare, Allocator, Options>
1058
1059 {
1060 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
1061 private:
1062 BOOST_COPYABLE_AND_MOVABLE(multiset)
1063 typedef dtl::tree
1064 <Key, void, Compare, Allocator, Options> base_t;
1065 #endif
1066
1067 public:
1068
1069
1070
1071
1072
1073
1074 typedef Key key_type;
1075 typedef Key value_type;
1076 typedef Compare key_compare;
1077 typedef key_compare value_compare;
1078 typedef typename base_t::allocator_type allocator_type;
1079 typedef ::boost::container::allocator_traits<allocator_type> allocator_traits_type;
1080 typedef typename ::boost::container::allocator_traits<allocator_type>::pointer pointer;
1081 typedef typename ::boost::container::allocator_traits<allocator_type>::const_pointer const_pointer;
1082 typedef typename ::boost::container::allocator_traits<allocator_type>::reference reference;
1083 typedef typename ::boost::container::allocator_traits<allocator_type>::const_reference const_reference;
1084 typedef typename ::boost::container::allocator_traits<allocator_type>::size_type size_type;
1085 typedef typename ::boost::container::allocator_traits<allocator_type>::difference_type difference_type;
1086 typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type) stored_allocator_type;
1087 typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator) iterator;
1088 typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_iterator) const_iterator;
1089 typedef typename BOOST_CONTAINER_IMPDEF(base_t::reverse_iterator) reverse_iterator;
1090 typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator;
1091 typedef typename BOOST_CONTAINER_IMPDEF(base_t::node_type) node_type;
1092
1093
1094
1095
1096
1097
1098
1099
1100 BOOST_CONTAINER_FORCEINLINE multiset()
1101 BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<allocator_type>::value &&
1102 dtl::is_nothrow_default_constructible<Compare>::value)
1103 : base_t()
1104 {}
1105
1106
1107 BOOST_CONTAINER_FORCEINLINE explicit multiset(const allocator_type& a)
1108 : base_t(a)
1109 {}
1110
1111
1112 BOOST_CONTAINER_FORCEINLINE explicit multiset(const Compare& comp)
1113 : base_t(comp)
1114 {}
1115
1116
1117 BOOST_CONTAINER_FORCEINLINE multiset(const Compare& comp, const allocator_type& a)
1118 : base_t(comp, a)
1119 {}
1120
1121
1122 template <class InputIterator>
1123 BOOST_CONTAINER_FORCEINLINE multiset(InputIterator first, InputIterator last)
1124 : base_t(false, first, last)
1125 {}
1126
1127
1128 template <class InputIterator>
1129 BOOST_CONTAINER_FORCEINLINE multiset(InputIterator first, InputIterator last, const allocator_type& a)
1130 : base_t(false, first, last, key_compare(), a)
1131 {}
1132
1133
1134 template <class InputIterator>
1135 BOOST_CONTAINER_FORCEINLINE multiset(InputIterator first, InputIterator last, const Compare& comp)
1136 : base_t(false, first, last, comp)
1137 {}
1138
1139
1140 template <class InputIterator>
1141 BOOST_CONTAINER_FORCEINLINE multiset(InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
1142 : base_t(false, first, last, comp, a)
1143 {}
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154 template <class InputIterator>
1155 BOOST_CONTAINER_FORCEINLINE multiset( ordered_range_t, InputIterator first, InputIterator last )
1156 : base_t(ordered_range, first, last)
1157 {}
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168 template <class InputIterator>
1169 BOOST_CONTAINER_FORCEINLINE multiset( ordered_range_t, InputIterator first, InputIterator last, const Compare& comp)
1170 : base_t(ordered_range, first, last, comp)
1171 {}
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182 template <class InputIterator>
1183 BOOST_CONTAINER_FORCEINLINE multiset( ordered_range_t, InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
1184 : base_t(ordered_range, first, last, comp, a)
1185 {}
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196 template <class InputIterator>
1197 BOOST_CONTAINER_FORCEINLINE multiset(ordered_range_t, InputIterator first, InputIterator last, const allocator_type &a)
1198 : base_t(ordered_range, first, last, Compare(), a)
1199 {}
1200
1201 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
1202
1203 BOOST_CONTAINER_FORCEINLINE multiset(std::initializer_list<value_type> il)
1204 : base_t(false, il.begin(), il.end())
1205 {}
1206
1207
1208 BOOST_CONTAINER_FORCEINLINE multiset(std::initializer_list<value_type> il, const allocator_type& a)
1209 : base_t(false, il.begin(), il.end(), Compare(), a)
1210 {}
1211
1212
1213 BOOST_CONTAINER_FORCEINLINE multiset(std::initializer_list<value_type> il, const Compare& comp)
1214 : base_t(false, il.begin(), il.end(), comp)
1215 {}
1216
1217
1218 BOOST_CONTAINER_FORCEINLINE multiset(std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
1219 : base_t(false, il.begin(), il.end(), comp, a)
1220 {}
1221
1222
1223 BOOST_CONTAINER_FORCEINLINE multiset(ordered_range_t, std::initializer_list<value_type> il)
1224 : base_t(ordered_range, il.begin(), il.end())
1225 {}
1226
1227
1228 BOOST_CONTAINER_FORCEINLINE multiset(ordered_range_t, std::initializer_list<value_type> il, const Compare& comp)
1229 : base_t(ordered_range, il.begin(), il.end(), comp)
1230 {}
1231
1232
1233 BOOST_CONTAINER_FORCEINLINE multiset(ordered_range_t, std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
1234 : base_t(ordered_range, il.begin(), il.end(), comp, a)
1235 {}
1236 #endif
1237
1238
1239 BOOST_CONTAINER_FORCEINLINE multiset(const multiset& x)
1240 : base_t(static_cast<const base_t&>(x))
1241 {}
1242
1243
1244 BOOST_CONTAINER_FORCEINLINE multiset(BOOST_RV_REF(multiset) x)
1245 BOOST_NOEXCEPT_IF(boost::container::dtl::is_nothrow_move_constructible<Compare>::value)
1246 : base_t(BOOST_MOVE_BASE(base_t, x))
1247 {}
1248
1249
1250 BOOST_CONTAINER_FORCEINLINE multiset(const multiset& x, const allocator_type &a)
1251 : base_t(static_cast<const base_t&>(x), a)
1252 {}
1253
1254
1255 BOOST_CONTAINER_FORCEINLINE multiset(BOOST_RV_REF(multiset) x, const allocator_type &a)
1256 : base_t(BOOST_MOVE_BASE(base_t, x), a)
1257 {}
1258
1259
1260 BOOST_CONTAINER_FORCEINLINE multiset& operator=(BOOST_COPY_ASSIGN_REF(multiset) x)
1261 { return static_cast<multiset&>(this->base_t::operator=(static_cast<const base_t&>(x))); }
1262
1263
1264 BOOST_CONTAINER_FORCEINLINE multiset& operator=(BOOST_RV_REF(multiset) x)
1265 BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value ||
1266 allocator_traits_type::is_always_equal::value) &&
1267 boost::container::dtl::is_nothrow_move_assignable<Compare>::value)
1268 { return static_cast<multiset&>(this->base_t::operator=(BOOST_MOVE_BASE(base_t, x))); }
1269
1270 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
1271
1272 multiset& operator=(std::initializer_list<value_type> il)
1273 {
1274 this->clear();
1275 insert(il.begin(), il.end());
1276 return *this;
1277 }
1278 #endif
1279 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1280
1281
1282 allocator_type get_allocator() const;
1283
1284
1285 stored_allocator_type &get_stored_allocator();
1286
1287
1288 const stored_allocator_type &get_stored_allocator() const;
1289
1290
1291 iterator begin();
1292
1293
1294 const_iterator begin() const;
1295
1296
1297 const_iterator cbegin() const;
1298
1299
1300 iterator end() BOOST_NOEXCEPT_OR_NOTHROW;
1301
1302
1303 const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW;
1304
1305
1306 const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW;
1307
1308
1309 reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW;
1310
1311
1312 const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
1313
1314
1315 const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
1316
1317
1318 reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW;
1319
1320
1321 const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW;
1322
1323
1324 const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW;
1325
1326
1327 bool empty() const;
1328
1329
1330 size_type size() const;
1331
1332
1333 size_type max_size() const;
1334
1335 #endif
1336
1337 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1338
1339
1340
1341
1342
1343
1344 template <class... Args>
1345 BOOST_CONTAINER_FORCEINLINE iterator emplace(BOOST_FWD_REF(Args)... args)
1346 { return this->base_t::emplace_equal(boost::forward<Args>(args)...); }
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356 template <class... Args>
1357 BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args)
1358 { return this->base_t::emplace_hint_equal(p, boost::forward<Args>(args)...); }
1359
1360 #else
1361
1362 #define BOOST_CONTAINER_MULTISET_EMPLACE_CODE(N) \
1363 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
1364 BOOST_CONTAINER_FORCEINLINE iterator emplace(BOOST_MOVE_UREF##N)\
1365 { return this->base_t::emplace_equal(BOOST_MOVE_FWD##N); }\
1366 \
1367 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
1368 BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
1369 { return this->base_t::emplace_hint_equal(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
1370
1371 BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_MULTISET_EMPLACE_CODE)
1372 #undef BOOST_CONTAINER_MULTISET_EMPLACE_CODE
1373
1374 #endif
1375
1376 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1377
1378
1379
1380
1381 iterator insert(const value_type &x);
1382
1383
1384
1385
1386
1387
1388
1389
1390 iterator insert(value_type &&x);
1391 #else
1392 BOOST_MOVE_CONVERSION_AWARE_CATCH(insert, value_type, iterator, this->base_t::insert_equal_convertible)
1393 #endif
1394
1395 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1396
1397
1398
1399
1400
1401
1402
1403
1404 iterator insert(const_iterator p, const value_type &x);
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414 iterator insert(const_iterator p, value_type &&x);
1415 #else
1416 BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG
1417 (insert, value_type, iterator, this->base_t::insert_equal_hint_convertible, const_iterator, const_iterator)
1418 #endif
1419
1420
1421
1422
1423
1424
1425 template <class InputIterator>
1426 BOOST_CONTAINER_FORCEINLINE void insert(InputIterator first, InputIterator last)
1427 { this->base_t::insert_equal_range(first, last); }
1428
1429 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
1430
1431 BOOST_CONTAINER_FORCEINLINE void insert(std::initializer_list<value_type> il)
1432 { this->base_t::insert_equal_range(il.begin(), il.end()); }
1433 #endif
1434
1435
1436 BOOST_CONTAINER_FORCEINLINE iterator insert(BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh)
1437 { return this->base_t::insert_equal_node(boost::move(nh)); }
1438
1439
1440 BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator hint, BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh)
1441 { return this->base_t::insert_equal_node(hint, boost::move(nh)); }
1442
1443
1444 template<class C2>
1445 BOOST_CONTAINER_FORCEINLINE void merge(multiset<Key, C2, Allocator, Options>& source)
1446 {
1447 typedef dtl::tree
1448 <Key, void, C2, Allocator, Options> base2_t;
1449 this->base_t::merge_equal(static_cast<base2_t&>(source));
1450 }
1451
1452
1453 template<class C2>
1454 BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG multiset<Key, C2, Allocator, Options> BOOST_RV_REF_END source)
1455 { return this->merge(static_cast<multiset<Key, C2, Allocator, Options>&>(source)); }
1456
1457
1458 template<class C2>
1459 BOOST_CONTAINER_FORCEINLINE void merge(set<Key, C2, Allocator, Options>& source)
1460 {
1461 typedef dtl::tree
1462 <Key, void, C2, Allocator, Options> base2_t;
1463 this->base_t::merge_equal(static_cast<base2_t&>(source));
1464 }
1465
1466
1467 template<class C2>
1468 BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG set<Key, C2, Allocator, Options> BOOST_RV_REF_END source)
1469 { return this->merge(static_cast<set<Key, C2, Allocator, Options>&>(source)); }
1470
1471 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1472
1473
1474 iterator erase(const_iterator p);
1475
1476
1477 size_type erase(const key_type& x);
1478
1479
1480 iterator erase(const_iterator first, const_iterator last);
1481
1482
1483 node_type extract(const_iterator p);
1484
1485
1486 node_type extract(const key_type& x);
1487
1488
1489 void swap(multiset& x)
1490 BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
1491 && boost::container::dtl::is_nothrow_swappable<Compare>::value );
1492
1493
1494 void clear() BOOST_NOEXCEPT_OR_NOTHROW;
1495
1496
1497 key_compare key_comp() const;
1498
1499
1500 value_compare value_comp() const;
1501
1502
1503 iterator find(const key_type& x);
1504
1505
1506 const_iterator find(const key_type& x) const;
1507
1508
1509 template<typename K>
1510 iterator find(const K& x);
1511
1512
1513 template<typename K>
1514 const_iterator find(const K& x) const;
1515
1516
1517 size_type count(const key_type& x) const;
1518
1519
1520 template<typename K>
1521 size_type count(const K& x) const;
1522
1523
1524 bool contains(const key_type& x) const;
1525
1526
1527 template<typename K>
1528 bool contains(const K& x) const;
1529
1530
1531 iterator lower_bound(const key_type& x);
1532
1533
1534 const_iterator lower_bound(const key_type& x) const;
1535
1536
1537 template<typename K>
1538 iterator lower_bound(const K& x);
1539
1540
1541 template<typename K>
1542 const_iterator lower_bound(const K& x) const;
1543
1544
1545 iterator upper_bound(const key_type& x);
1546
1547
1548 const_iterator upper_bound(const key_type& x) const;
1549
1550
1551 template<typename K>
1552 iterator upper_bound(const K& x);
1553
1554
1555 template<typename K>
1556 const_iterator upper_bound(const K& x) const;
1557
1558
1559 std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
1560
1561
1562 std::pair<iterator,iterator> equal_range(const key_type& x);
1563
1564
1565 template<typename K>
1566 std::pair<const_iterator, const_iterator> equal_range(const K& x) const;
1567
1568
1569 template<typename K>
1570 std::pair<iterator,iterator> equal_range(const K& x);
1571
1572
1573 void rebalance();
1574
1575
1576
1577
1578 friend bool operator==(const multiset& x, const multiset& y);
1579
1580
1581
1582
1583 friend bool operator!=(const multiset& x, const multiset& y);
1584
1585
1586
1587
1588 friend bool operator<(const multiset& x, const multiset& y);
1589
1590
1591
1592
1593 friend bool operator>(const multiset& x, const multiset& y);
1594
1595
1596
1597
1598 friend bool operator<=(const multiset& x, const multiset& y);
1599
1600
1601
1602
1603 friend bool operator>=(const multiset& x, const multiset& y);
1604
1605
1606
1607
1608 friend void swap(multiset& x, multiset& y)
1609 BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
1610 && boost::container::dtl::is_nothrow_swappable<Compare>::value );
1611
1612 #endif
1613 };
1614
1615 #ifndef BOOST_CONTAINER_NO_CXX17_CTAD
1616
1617 template <typename InputIterator>
1618 multiset(InputIterator, InputIterator) ->
1619 multiset< it_based_value_type_t<InputIterator> >;
1620
1621
1622 template < typename InputIterator, typename AllocatorOrCompare>
1623 multiset(InputIterator, InputIterator, AllocatorOrCompare const&) ->
1624 multiset < it_based_value_type_t<InputIterator>
1625 , typename dtl::if_c<
1626 dtl::is_allocator<AllocatorOrCompare>::value
1627 , std::less<it_based_value_type_t<InputIterator>>
1628 , AllocatorOrCompare
1629 >::type
1630 , typename dtl::if_c<
1631 dtl::is_allocator<AllocatorOrCompare>::value
1632 , AllocatorOrCompare
1633 , new_allocator<it_based_value_type_t<InputIterator>>
1634 >::type
1635 >;
1636
1637 template < typename InputIterator, typename Compare, typename Allocator
1638 , typename = dtl::require_nonallocator_t<Compare>
1639 , typename = dtl::require_allocator_t<Allocator>>
1640 multiset(InputIterator, InputIterator, Compare const&, Allocator const&) ->
1641 multiset< it_based_value_type_t<InputIterator>
1642 , Compare
1643 , Allocator>;
1644
1645 template <typename InputIterator>
1646 multiset(ordered_range_t, InputIterator, InputIterator) ->
1647 multiset< it_based_value_type_t<InputIterator>>;
1648
1649 template < typename InputIterator, typename AllocatorOrCompare>
1650 multiset(ordered_range_t, InputIterator, InputIterator, AllocatorOrCompare const&) ->
1651 multiset < it_based_value_type_t<InputIterator>
1652 , typename dtl::if_c<
1653 dtl::is_allocator<AllocatorOrCompare>::value
1654 , std::less<it_based_value_type_t<InputIterator>>
1655 , AllocatorOrCompare
1656 >::type
1657 , typename dtl::if_c<
1658 dtl::is_allocator<AllocatorOrCompare>::value
1659 , AllocatorOrCompare
1660 , new_allocator<it_based_value_type_t<InputIterator>>
1661 >::type
1662 >;
1663
1664 template < typename InputIterator, typename Compare, typename Allocator
1665 , typename = dtl::require_nonallocator_t<Compare>
1666 , typename = dtl::require_allocator_t<Allocator>>
1667 multiset(ordered_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) ->
1668 multiset< it_based_value_type_t<InputIterator>
1669 , Compare
1670 , Allocator>;
1671
1672 #endif
1673
1674 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
1675
1676 }
1677
1678
1679
1680 template <class Key, class Compare, class Allocator, class Options>
1681 struct has_trivial_destructor_after_move<boost::container::multiset<Key, Compare, Allocator, Options> >
1682 {
1683 typedef ::boost::container::dtl::tree<Key, void, Compare, Allocator, Options> tree;
1684 static const bool value = ::boost::has_trivial_destructor_after_move<tree>::value;
1685 };
1686
1687 namespace container {
1688
1689 #endif
1690
1691 }}
1692
1693 #include <boost/container/detail/config_end.hpp>
1694
1695 #endif