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