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