File indexing completed on 2025-01-18 09:30:17
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_CONTAINER_FLAT_MAP_HPP
0011 #define BOOST_CONTAINER_FLAT_MAP_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 #include <boost/container/allocator_traits.hpp>
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/flat_tree.hpp>
0030 #include <boost/container/detail/type_traits.hpp>
0031 #include <boost/container/detail/mpl.hpp>
0032 #include <boost/container/detail/algorithm.hpp> //equal()
0033 #include <boost/container/detail/container_or_allocator_rebind.hpp>
0034
0035 #include <boost/move/utility_core.hpp>
0036 #include <boost/move/traits.hpp>
0037
0038 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0039 #include <boost/move/detail/fwd_macros.hpp>
0040 #endif
0041 #include <boost/move/detail/move_helpers.hpp>
0042 #include <boost/move/detail/force_ptr.hpp>
0043
0044 #include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
0045 #include <boost/intrusive/detail/minimal_less_equal_header.hpp>//less, equal
0046
0047 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
0048 #include <initializer_list>
0049 #endif
0050
0051 namespace boost {
0052 namespace container {
0053
0054 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0055
0056 template <class Key, class T, class Compare, class AllocatorOrContainer>
0057 class flat_multimap;
0058
0059 namespace dtl{
0060
0061 template<class D, class S>
0062 BOOST_CONTAINER_FORCEINLINE static D &force(S &s)
0063 { return *move_detail::force_ptr<D*>(&s); }
0064
0065 template<class D, class S>
0066 BOOST_CONTAINER_FORCEINLINE static const D &force(const S &s)
0067 { return *move_detail::force_ptr<const D*>(&s); }
0068
0069 template<class D, class S>
0070 BOOST_CONTAINER_FORCEINLINE static D force_copy(const S &s)
0071 {
0072 const D *const vp = move_detail::force_ptr<const D *>(&s);
0073 D ret_val(*vp);
0074 return ret_val;
0075 }
0076
0077 }
0078
0079 #endif
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
0111 template <class Key, class T, class Compare = std::less<Key>, class AllocatorOrContainer = new_allocator< std::pair< Key, T> > >
0112 #else
0113 template <class Key, class T, class Compare, class AllocatorOrContainer>
0114 #endif
0115 class flat_map
0116 {
0117 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0118 private:
0119 BOOST_COPYABLE_AND_MOVABLE(flat_map)
0120
0121 typedef dtl::flat_tree<
0122 std::pair<Key, T>,
0123 dtl::select1st<Key>,
0124 Compare,
0125 AllocatorOrContainer> tree_t;
0126
0127
0128 typedef dtl::flat_tree<
0129 dtl::pair<Key, T>,
0130 dtl::select1st<Key>,
0131 Compare,
0132 typename dtl::container_or_allocator_rebind<AllocatorOrContainer, dtl::pair<Key, T> >::type
0133 > impl_tree_t;
0134 impl_tree_t m_flat_tree;
0135
0136 typedef typename impl_tree_t::value_type impl_value_type;
0137 typedef typename impl_tree_t::const_iterator impl_const_iterator;
0138 typedef typename impl_tree_t::iterator impl_iterator;
0139 typedef typename impl_tree_t::allocator_type impl_allocator_type;
0140 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
0141 typedef std::initializer_list<impl_value_type> impl_initializer_list;
0142 #endif
0143
0144 typedef dtl::flat_tree_value_compare
0145 < Compare
0146 , dtl::select1st<Key>
0147 , std::pair<Key, T> > value_compare_t;
0148 typedef typename tree_t::iterator iterator_t;
0149 typedef typename tree_t::const_iterator const_iterator_t;
0150 typedef typename tree_t::reverse_iterator reverse_iterator_t;
0151 typedef typename tree_t::const_reverse_iterator const_reverse_iterator_t;
0152
0153 public:
0154 typedef typename impl_tree_t::stored_allocator_type impl_stored_allocator_type;
0155 typedef typename impl_tree_t::sequence_type impl_sequence_type;
0156
0157 BOOST_CONTAINER_FORCEINLINE impl_tree_t &tree()
0158 { return m_flat_tree; }
0159
0160 BOOST_CONTAINER_FORCEINLINE const impl_tree_t &tree() const
0161 { return m_flat_tree; }
0162
0163 private:
0164 typedef typename tree_t::get_stored_allocator_const_return_t get_stored_allocator_const_return_t;
0165 typedef typename tree_t::get_stored_allocator_noconst_return_t get_stored_allocator_noconst_return_t;
0166 typedef typename impl_tree_t::get_stored_allocator_const_return_t impl_get_stored_allocator_const_return_t;
0167 typedef typename impl_tree_t::get_stored_allocator_noconst_return_t impl_get_stored_allocator_noconst_return_t;
0168
0169 #endif
0170
0171 public:
0172
0173
0174
0175
0176
0177
0178 typedef Key key_type;
0179 typedef T mapped_type;
0180 typedef Compare key_compare;
0181 typedef std::pair<Key, T> value_type;
0182 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::sequence_type) sequence_type;
0183 typedef typename sequence_type::allocator_type allocator_type;
0184 typedef ::boost::container::allocator_traits<allocator_type> allocator_traits_type;
0185 typedef typename sequence_type::pointer pointer;
0186 typedef typename sequence_type::const_pointer const_pointer;
0187 typedef typename sequence_type::reference reference;
0188 typedef typename sequence_type::const_reference const_reference;
0189 typedef typename sequence_type::size_type size_type;
0190 typedef typename sequence_type::difference_type difference_type;
0191 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::stored_allocator_type) stored_allocator_type;
0192 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::value_compare) value_compare;
0193
0194 typedef typename sequence_type::iterator iterator;
0195 typedef typename sequence_type::const_iterator const_iterator;
0196 typedef typename sequence_type::reverse_iterator reverse_iterator;
0197 typedef typename sequence_type::const_reverse_iterator const_reverse_iterator;
0198 typedef BOOST_CONTAINER_IMPDEF(impl_value_type) movable_value_type;
0199
0200
0201 BOOST_STATIC_ASSERT((dtl::is_same<std::pair<Key, T>, value_type>::value));
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212 BOOST_CONTAINER_FORCEINLINE flat_map() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<AllocatorOrContainer>::value &&
0213 dtl::is_nothrow_default_constructible<Compare>::value)
0214 : m_flat_tree()
0215 {}
0216
0217
0218
0219
0220 BOOST_CONTAINER_FORCEINLINE explicit flat_map(const allocator_type& a)
0221 : m_flat_tree(dtl::force<const impl_allocator_type>(a))
0222 {}
0223
0224
0225
0226
0227
0228 BOOST_CONTAINER_FORCEINLINE explicit flat_map(const Compare& comp)
0229 : m_flat_tree(comp)
0230 {}
0231
0232
0233
0234
0235
0236 BOOST_CONTAINER_FORCEINLINE flat_map(const Compare& comp, const allocator_type& a)
0237 : m_flat_tree(comp, dtl::force<const impl_allocator_type>(a))
0238 {}
0239
0240
0241
0242
0243
0244
0245 template <class InputIterator>
0246 BOOST_CONTAINER_FORCEINLINE flat_map(InputIterator first, InputIterator last)
0247 : m_flat_tree(true, first, last)
0248 {}
0249
0250
0251
0252
0253
0254
0255 template <class InputIterator>
0256 BOOST_CONTAINER_FORCEINLINE flat_map(InputIterator first, InputIterator last, const allocator_type& a)
0257 : m_flat_tree(true, first, last, dtl::force<const impl_allocator_type>(a))
0258 {}
0259
0260
0261
0262
0263
0264
0265 template <class InputIterator>
0266 BOOST_CONTAINER_FORCEINLINE flat_map(InputIterator first, InputIterator last, const Compare& comp)
0267 : m_flat_tree(true, first, last, comp)
0268 {}
0269
0270
0271
0272
0273
0274
0275 template <class InputIterator>
0276 BOOST_CONTAINER_FORCEINLINE flat_map(InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
0277 : m_flat_tree(true, first, last, comp, dtl::force<const impl_allocator_type>(a))
0278 {}
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289 template <class InputIterator>
0290 BOOST_CONTAINER_FORCEINLINE
0291 flat_map(ordered_unique_range_t, InputIterator first, InputIterator last)
0292 : m_flat_tree(ordered_range, first, last)
0293 {}
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304 template <class InputIterator>
0305 BOOST_CONTAINER_FORCEINLINE
0306 flat_map(ordered_unique_range_t, InputIterator first, InputIterator last, const Compare& comp)
0307 : m_flat_tree(ordered_range, first, last, comp)
0308 {}
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319 template <class InputIterator>
0320 BOOST_CONTAINER_FORCEINLINE
0321 flat_map(ordered_unique_range_t, InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
0322 : m_flat_tree(ordered_range, first, last, comp, dtl::force<const impl_allocator_type>(a))
0323 {}
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334 template <class InputIterator>
0335 BOOST_CONTAINER_FORCEINLINE
0336 flat_map(ordered_unique_range_t, InputIterator first, InputIterator last, const allocator_type& a)
0337 : m_flat_tree(ordered_range, first, last, Compare(), a)
0338 {}
0339
0340 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
0341
0342
0343
0344
0345
0346 BOOST_CONTAINER_FORCEINLINE flat_map(std::initializer_list<value_type> il)
0347 : m_flat_tree( true
0348 , dtl::force<impl_initializer_list>(il).begin()
0349 , dtl::force<impl_initializer_list>(il).end())
0350 {}
0351
0352
0353
0354
0355
0356
0357 BOOST_CONTAINER_FORCEINLINE flat_map(std::initializer_list<value_type> il, const allocator_type& a)
0358 : m_flat_tree( true
0359 , dtl::force<impl_initializer_list>(il).begin()
0360 , dtl::force<impl_initializer_list>(il).end()
0361 , dtl::force<const impl_allocator_type>(a))
0362 {}
0363
0364
0365
0366
0367
0368
0369 BOOST_CONTAINER_FORCEINLINE flat_map(std::initializer_list<value_type> il, const Compare& comp)
0370 : m_flat_tree(true
0371 , dtl::force<impl_initializer_list>(il).begin()
0372 , dtl::force<impl_initializer_list>(il).end()
0373 , comp)
0374 {}
0375
0376
0377
0378
0379
0380
0381 BOOST_CONTAINER_FORCEINLINE flat_map(std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
0382 : m_flat_tree(true
0383 , dtl::force<impl_initializer_list>(il).begin()
0384 , dtl::force<impl_initializer_list>(il).end()
0385 , comp
0386 , dtl::force<const impl_allocator_type>(a))
0387 {}
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399 BOOST_CONTAINER_FORCEINLINE flat_map(ordered_unique_range_t, std::initializer_list<value_type> il)
0400 : m_flat_tree(ordered_unique_range
0401 , dtl::force<impl_initializer_list>(il).begin()
0402 , dtl::force<impl_initializer_list>(il).end())
0403 {}
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415 BOOST_CONTAINER_FORCEINLINE flat_map(ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp)
0416 : m_flat_tree(ordered_unique_range
0417 , dtl::force<impl_initializer_list>(il).begin()
0418 , dtl::force<impl_initializer_list>(il).end()
0419 , comp)
0420 {}
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432 BOOST_CONTAINER_FORCEINLINE flat_map(ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
0433 : m_flat_tree( ordered_unique_range
0434 , dtl::force<impl_initializer_list>(il).begin()
0435 , dtl::force<impl_initializer_list>(il).end()
0436 , comp
0437 , dtl::force<const impl_allocator_type>(a))
0438 {}
0439 #endif
0440
0441
0442
0443
0444 BOOST_CONTAINER_FORCEINLINE flat_map(const flat_map& x)
0445 : m_flat_tree(x.m_flat_tree)
0446 {}
0447
0448
0449
0450
0451
0452
0453
0454 BOOST_CONTAINER_FORCEINLINE flat_map(BOOST_RV_REF(flat_map) x)
0455 BOOST_NOEXCEPT_IF(boost::container::dtl::is_nothrow_move_constructible<Compare>::value)
0456 : m_flat_tree(boost::move(x.m_flat_tree))
0457 {}
0458
0459
0460
0461
0462 BOOST_CONTAINER_FORCEINLINE flat_map(const flat_map& x, const allocator_type &a)
0463 : m_flat_tree(x.m_flat_tree, dtl::force<const impl_allocator_type>(a))
0464 {}
0465
0466
0467
0468
0469
0470 BOOST_CONTAINER_FORCEINLINE flat_map(BOOST_RV_REF(flat_map) x, const allocator_type &a)
0471 : m_flat_tree(boost::move(x.m_flat_tree), dtl::force<const impl_allocator_type>(a))
0472 {}
0473
0474
0475
0476
0477 BOOST_CONTAINER_FORCEINLINE flat_map& operator=(BOOST_COPY_ASSIGN_REF(flat_map) x)
0478 { m_flat_tree = x.m_flat_tree; return *this; }
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489 BOOST_CONTAINER_FORCEINLINE flat_map& operator=(BOOST_RV_REF(flat_map) x)
0490 BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value ||
0491 allocator_traits_type::is_always_equal::value) &&
0492 boost::container::dtl::is_nothrow_move_assignable<Compare>::value)
0493 { m_flat_tree = boost::move(x.m_flat_tree); return *this; }
0494
0495 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
0496
0497 flat_map& operator=(std::initializer_list<value_type> il)
0498 {
0499 this->clear();
0500 this->insert(il.begin(), il.end());
0501 return *this;
0502 }
0503 #endif
0504
0505
0506
0507
0508
0509 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0510 allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
0511 { return dtl::force_copy<allocator_type>(m_flat_tree.get_allocator()); }
0512
0513
0514
0515
0516
0517
0518
0519
0520 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0521 get_stored_allocator_noconst_return_t get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
0522 {
0523 impl_get_stored_allocator_noconst_return_t r = m_flat_tree.get_stored_allocator();
0524 return dtl::force<stored_allocator_type>(r);
0525 }
0526
0527
0528
0529
0530
0531
0532
0533
0534 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0535 get_stored_allocator_const_return_t get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
0536 {
0537 impl_get_stored_allocator_const_return_t r = m_flat_tree.get_stored_allocator();
0538 return dtl::force<const stored_allocator_type>(r);
0539 }
0540
0541
0542
0543
0544
0545
0546
0547
0548
0549
0550
0551
0552 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0553 iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
0554 { return dtl::force_copy<iterator>(m_flat_tree.begin()); }
0555
0556
0557
0558
0559
0560
0561 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0562 const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
0563 { return dtl::force_copy<const_iterator>(m_flat_tree.begin()); }
0564
0565
0566
0567
0568
0569
0570 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0571 iterator end() BOOST_NOEXCEPT_OR_NOTHROW
0572 { return dtl::force_copy<iterator>(m_flat_tree.end()); }
0573
0574
0575
0576
0577
0578
0579 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0580 const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
0581 { return dtl::force_copy<const_iterator>(m_flat_tree.end()); }
0582
0583
0584
0585
0586
0587
0588
0589 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0590 reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW
0591 { return dtl::force_copy<reverse_iterator>(m_flat_tree.rbegin()); }
0592
0593
0594
0595
0596
0597
0598
0599 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0600 const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
0601 { return dtl::force_copy<const_reverse_iterator>(m_flat_tree.rbegin()); }
0602
0603
0604
0605
0606
0607
0608
0609 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0610 reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW
0611 { return dtl::force_copy<reverse_iterator>(m_flat_tree.rend()); }
0612
0613
0614
0615
0616
0617
0618
0619 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0620 const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW
0621 { return dtl::force_copy<const_reverse_iterator>(m_flat_tree.rend()); }
0622
0623
0624
0625
0626
0627
0628 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0629 const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
0630 { return dtl::force_copy<const_iterator>(m_flat_tree.cbegin()); }
0631
0632
0633
0634
0635
0636
0637 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0638 const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
0639 { return dtl::force_copy<const_iterator>(m_flat_tree.cend()); }
0640
0641
0642
0643
0644
0645
0646
0647 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0648 const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW
0649 { return dtl::force_copy<const_reverse_iterator>(m_flat_tree.crbegin()); }
0650
0651
0652
0653
0654
0655
0656
0657 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0658 const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW
0659 { return dtl::force_copy<const_reverse_iterator>(m_flat_tree.crend()); }
0660
0661
0662
0663
0664
0665
0666
0667
0668
0669
0670
0671
0672 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0673 bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
0674 { return m_flat_tree.empty(); }
0675
0676
0677
0678
0679
0680
0681 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0682 size_type size() const BOOST_NOEXCEPT_OR_NOTHROW
0683 { return m_flat_tree.size(); }
0684
0685
0686
0687
0688
0689
0690 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0691 size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
0692 { return m_flat_tree.max_size(); }
0693
0694
0695
0696
0697
0698
0699
0700 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0701 size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW
0702 { return m_flat_tree.capacity(); }
0703
0704
0705
0706
0707
0708
0709
0710
0711
0712
0713
0714 BOOST_CONTAINER_FORCEINLINE void reserve(size_type cnt)
0715 { m_flat_tree.reserve(cnt); }
0716
0717
0718
0719
0720
0721
0722
0723 BOOST_CONTAINER_FORCEINLINE void shrink_to_fit()
0724 { m_flat_tree.shrink_to_fit(); }
0725
0726
0727
0728
0729
0730
0731
0732 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0733
0734
0735
0736
0737
0738
0739 mapped_type &operator[](const key_type& k);
0740
0741
0742
0743
0744
0745
0746
0747 mapped_type &operator[](key_type &&k);
0748 #elif defined(BOOST_MOVE_HELPERS_RETURN_SFINAE_BROKEN)
0749
0750 BOOST_CONTAINER_FORCEINLINE mapped_type& operator[](const key_type &k) { return this->priv_subscript(k); }
0751 BOOST_CONTAINER_FORCEINLINE mapped_type& operator[](BOOST_RV_REF(key_type) k) { return this->priv_subscript(::boost::move(k)); }
0752 #else
0753 BOOST_MOVE_CONVERSION_AWARE_CATCH( operator[] , key_type, mapped_type&, this->priv_subscript)
0754 #endif
0755
0756
0757
0758
0759
0760
0761
0762
0763
0764
0765
0766
0767
0768 template <class M>
0769 BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> insert_or_assign(const key_type& k, BOOST_FWD_REF(M) obj)
0770 {
0771 return dtl::force_copy< std::pair<iterator, bool> >
0772 (this->m_flat_tree.insert_or_assign
0773 ( impl_const_iterator(), k, ::boost::forward<M>(obj))
0774 );
0775 }
0776
0777
0778
0779
0780
0781
0782
0783
0784
0785
0786
0787
0788
0789 template <class M>
0790 BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> insert_or_assign(BOOST_RV_REF(key_type) k, BOOST_FWD_REF(M) obj)
0791 {
0792 return dtl::force_copy< std::pair<iterator, bool> >
0793 (this->m_flat_tree.insert_or_assign
0794 ( impl_const_iterator(), ::boost::move(k), ::boost::forward<M>(obj))
0795 );
0796 }
0797
0798
0799
0800
0801
0802
0803
0804
0805
0806
0807
0808
0809
0810
0811
0812 template <class M>
0813 BOOST_CONTAINER_FORCEINLINE iterator insert_or_assign(const_iterator hint, const key_type& k, BOOST_FWD_REF(M) obj)
0814 {
0815 return dtl::force_copy<iterator>
0816 (this->m_flat_tree.insert_or_assign
0817 ( dtl::force_copy<impl_const_iterator>(hint)
0818 , k, ::boost::forward<M>(obj)).first
0819 );
0820 }
0821
0822
0823
0824
0825
0826
0827
0828
0829
0830
0831
0832
0833
0834
0835
0836 template <class M>
0837 BOOST_CONTAINER_FORCEINLINE iterator insert_or_assign(const_iterator hint, BOOST_RV_REF(key_type) k, BOOST_FWD_REF(M) obj)
0838 {
0839 return dtl::force_copy<iterator>
0840 (this->m_flat_tree.insert_or_assign
0841 ( dtl::force_copy<impl_const_iterator>(hint)
0842 , ::boost::move(k), ::boost::forward<M>(obj)).first
0843 );
0844 }
0845
0846
0847 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0848 iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
0849 { return dtl::force_copy<iterator>(m_flat_tree.nth(n)); }
0850
0851
0852 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0853 const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
0854 { return dtl::force_copy<iterator>(m_flat_tree.nth(n)); }
0855
0856
0857 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0858 size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
0859 { return m_flat_tree.index_of(dtl::force_copy<impl_iterator>(p)); }
0860
0861
0862 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0863 size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW
0864 { return m_flat_tree.index_of(dtl::force_copy<impl_const_iterator>(p)); }
0865
0866
0867
0868
0869
0870
0871 BOOST_CONTAINER_ATTRIBUTE_NODISCARD T& at(const key_type& k)
0872 {
0873 iterator i = this->find(k);
0874 if(i == this->end()){
0875 throw_out_of_range("flat_map::at key not found");
0876 }
0877 return i->second;
0878 }
0879
0880
0881
0882
0883
0884
0885 BOOST_CONTAINER_ATTRIBUTE_NODISCARD const T& at(const key_type& k) const
0886 {
0887 const_iterator i = this->find(k);
0888 if(i == this->end()){
0889 throw_out_of_range("flat_map::at key not found");
0890 }
0891 return i->second;
0892 }
0893
0894
0895
0896
0897
0898
0899
0900 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0901
0902
0903
0904
0905
0906
0907
0908
0909
0910
0911
0912
0913
0914 template <class... Args>
0915 BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> emplace(BOOST_FWD_REF(Args)... args)
0916 { return dtl::force_copy< std::pair<iterator, bool> >(m_flat_tree.emplace_unique(boost::forward<Args>(args)...)); }
0917
0918
0919
0920
0921
0922
0923
0924
0925
0926
0927
0928
0929
0930 template <class... Args>
0931 BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(Args)... args)
0932 {
0933 return dtl::force_copy<iterator>
0934 (m_flat_tree.emplace_hint_unique( dtl::force_copy<impl_const_iterator>(hint)
0935 , boost::forward<Args>(args)...));
0936 }
0937
0938
0939
0940
0941
0942
0943
0944
0945
0946
0947
0948
0949 template <class... Args>
0950 BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> try_emplace(const key_type& k, BOOST_FWD_REF(Args)... args)
0951 {
0952 return dtl::force_copy< std::pair<iterator, bool> >(
0953 m_flat_tree.try_emplace(impl_const_iterator(), k, boost::forward<Args>(args)...));
0954 }
0955
0956
0957
0958
0959
0960
0961
0962
0963
0964
0965
0966
0967 template <class... Args>
0968 BOOST_CONTAINER_FORCEINLINE iterator try_emplace(const_iterator hint, const key_type &k, BOOST_FWD_REF(Args)... args)
0969 {
0970 return dtl::force_copy<iterator>(m_flat_tree.try_emplace
0971 (dtl::force_copy<impl_const_iterator>(hint), k, boost::forward<Args>(args)...).first);
0972 }
0973
0974
0975
0976
0977
0978
0979
0980
0981
0982
0983
0984
0985 template <class... Args>
0986 BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> try_emplace(BOOST_RV_REF(key_type) k, BOOST_FWD_REF(Args)... args)
0987 {
0988 return dtl::force_copy< std::pair<iterator, bool> >
0989 (m_flat_tree.try_emplace(impl_const_iterator(), boost::move(k), boost::forward<Args>(args)...));
0990 }
0991
0992
0993
0994
0995
0996
0997
0998
0999
1000
1001
1002
1003 template <class... Args>
1004 BOOST_CONTAINER_FORCEINLINE iterator try_emplace(const_iterator hint, BOOST_RV_REF(key_type) k, BOOST_FWD_REF(Args)... args)
1005 {
1006 return dtl::force_copy<iterator>
1007 (m_flat_tree.try_emplace(dtl::force_copy
1008 <impl_const_iterator>(hint), boost::move(k), boost::forward<Args>(args)...).first);
1009 }
1010
1011 #else
1012
1013 #define BOOST_CONTAINER_FLAT_MAP_EMPLACE_CODE(N) \
1014 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
1015 BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> emplace(BOOST_MOVE_UREF##N)\
1016 {\
1017 return dtl::force_copy< std::pair<iterator, bool> >\
1018 (m_flat_tree.emplace_unique(BOOST_MOVE_FWD##N));\
1019 }\
1020 \
1021 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
1022 BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
1023 {\
1024 return dtl::force_copy<iterator>(m_flat_tree.emplace_hint_unique\
1025 (dtl::force_copy<impl_const_iterator>(hint) BOOST_MOVE_I##N BOOST_MOVE_FWD##N));\
1026 }\
1027 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
1028 BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> try_emplace(const key_type& k BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
1029 {\
1030 return dtl::force_copy< std::pair<iterator, bool> >\
1031 (m_flat_tree.try_emplace(impl_const_iterator(), k BOOST_MOVE_I##N BOOST_MOVE_FWD##N));\
1032 }\
1033 \
1034 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
1035 BOOST_CONTAINER_FORCEINLINE iterator try_emplace(const_iterator hint, const key_type &k BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
1036 { return dtl::force_copy<iterator>(m_flat_tree.try_emplace\
1037 (dtl::force_copy<impl_const_iterator>(hint), k BOOST_MOVE_I##N BOOST_MOVE_FWD##N).first); }\
1038 \
1039 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
1040 BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> try_emplace(BOOST_RV_REF(key_type) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
1041 {\
1042 return dtl::force_copy< std::pair<iterator, bool> >\
1043 (m_flat_tree.try_emplace(impl_const_iterator(), boost::move(k) BOOST_MOVE_I##N BOOST_MOVE_FWD##N));\
1044 }\
1045 \
1046 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
1047 BOOST_CONTAINER_FORCEINLINE iterator try_emplace(const_iterator hint, BOOST_RV_REF(key_type) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
1048 { return dtl::force_copy<iterator>(m_flat_tree.try_emplace\
1049 (dtl::force_copy<impl_const_iterator>(hint), boost::move(k) BOOST_MOVE_I##N BOOST_MOVE_FWD##N).first); }\
1050
1051 BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_MAP_EMPLACE_CODE)
1052 #undef BOOST_CONTAINER_FLAT_MAP_EMPLACE_CODE
1053
1054 #endif
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067 BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> insert(const value_type& x)
1068 { return dtl::force_copy<std::pair<iterator,bool> >(
1069 m_flat_tree.insert_unique(dtl::force<const impl_value_type>(x))); }
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082 BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> insert(BOOST_RV_REF(value_type) x)
1083 {
1084 return dtl::force_copy<std::pair<iterator,bool> >(
1085 m_flat_tree.insert_unique(boost::move(dtl::force<impl_value_type>(x))));
1086 }
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099 template <class Pair>
1100 BOOST_CONTAINER_FORCEINLINE BOOST_CONTAINER_DOC1ST
1101 ( std::pair<iterator BOOST_MOVE_I bool>
1102 , typename dtl::enable_if_c<dtl::is_convertible<Pair BOOST_MOVE_I impl_value_type>::value
1103 BOOST_MOVE_I std::pair<iterator BOOST_MOVE_I bool> >::type)
1104 insert(BOOST_FWD_REF(Pair) x)
1105 {
1106 return dtl::force_copy<std::pair<iterator,bool> >
1107 (m_flat_tree.emplace_unique(boost::forward<Pair>(x)));
1108 }
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121 BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, const value_type& x)
1122 {
1123 return dtl::force_copy<iterator>(
1124 m_flat_tree.insert_unique( dtl::force_copy<impl_const_iterator>(p)
1125 , dtl::force<const impl_value_type>(x)));
1126 }
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137 BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, BOOST_RV_REF(value_type) x)
1138 {
1139 return dtl::force_copy<iterator>
1140 (m_flat_tree.insert_unique( dtl::force_copy<impl_const_iterator>(p)
1141 , boost::move(dtl::force<impl_value_type>(x))));
1142 }
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153 template <class Pair>
1154 BOOST_CONTAINER_FORCEINLINE BOOST_CONTAINER_DOC1ST
1155 ( iterator
1156 , typename dtl::enable_if_c<dtl::is_convertible<Pair BOOST_MOVE_I impl_value_type>::value
1157 BOOST_MOVE_I iterator>::type)
1158 insert(const_iterator p, BOOST_FWD_REF(Pair) x)
1159 {
1160 return dtl::force_copy<iterator>(
1161 m_flat_tree.emplace_hint_unique(dtl::force_copy<impl_const_iterator>(p), boost::forward<Pair>(x)));
1162 }
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172 template <class InputIterator>
1173 BOOST_CONTAINER_FORCEINLINE void insert(InputIterator first, InputIterator last)
1174 { m_flat_tree.insert_unique(first, last); }
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190 template <class InputIterator>
1191 BOOST_CONTAINER_FORCEINLINE void insert(ordered_unique_range_t, InputIterator first, InputIterator last)
1192 { m_flat_tree.insert_unique(ordered_unique_range, first, last); }
1193
1194 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
1195
1196
1197
1198
1199
1200
1201 BOOST_CONTAINER_FORCEINLINE void insert(std::initializer_list<value_type> il)
1202 {
1203 m_flat_tree.insert_unique( dtl::force<impl_initializer_list>(il).begin()
1204 , dtl::force<impl_initializer_list>(il).end());
1205 }
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219 BOOST_CONTAINER_FORCEINLINE void insert(ordered_unique_range_t, std::initializer_list<value_type> il)
1220 {
1221 m_flat_tree.insert_unique(ordered_unique_range
1222 , dtl::force<impl_initializer_list>(il).begin()
1223 , dtl::force<impl_initializer_list>(il).end());
1224 }
1225 #endif
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236 template<class C2>
1237 BOOST_CONTAINER_FORCEINLINE void merge(flat_map<Key, T, C2, AllocatorOrContainer>& source)
1238 { m_flat_tree.merge_unique(source.tree()); }
1239
1240
1241 template<class C2>
1242 BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_map<Key, T, C2, AllocatorOrContainer> BOOST_RV_REF_END source)
1243 { return this->merge(static_cast<flat_map<Key, T, C2, AllocatorOrContainer>&>(source)); }
1244
1245
1246 template<class C2>
1247 BOOST_CONTAINER_FORCEINLINE void merge(flat_multimap<Key, T, C2, AllocatorOrContainer>& source)
1248 { m_flat_tree.merge_unique(source.tree()); }
1249
1250
1251 template<class C2>
1252 BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_multimap<Key, T, C2, AllocatorOrContainer> BOOST_RV_REF_END source)
1253 { return this->merge(static_cast<flat_multimap<Key, T, C2, AllocatorOrContainer>&>(source)); }
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265 BOOST_CONTAINER_FORCEINLINE iterator erase(const_iterator p)
1266 {
1267 return dtl::force_copy<iterator>
1268 (m_flat_tree.erase(dtl::force_copy<impl_const_iterator>(p)));
1269 }
1270
1271
1272
1273
1274
1275
1276
1277 BOOST_CONTAINER_FORCEINLINE size_type erase(const key_type& x)
1278 { return m_flat_tree.erase_unique(x); }
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288 BOOST_CONTAINER_FORCEINLINE iterator erase(const_iterator first, const_iterator last)
1289 {
1290 return dtl::force_copy<iterator>(
1291 m_flat_tree.erase( dtl::force_copy<impl_const_iterator>(first)
1292 , dtl::force_copy<impl_const_iterator>(last)));
1293 }
1294
1295
1296
1297
1298
1299
1300 BOOST_CONTAINER_FORCEINLINE void swap(flat_map& x)
1301 BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
1302 && boost::container::dtl::is_nothrow_swappable<Compare>::value )
1303 { m_flat_tree.swap(x.m_flat_tree); }
1304
1305
1306
1307
1308
1309
1310 BOOST_CONTAINER_FORCEINLINE void clear() BOOST_NOEXCEPT_OR_NOTHROW
1311 { m_flat_tree.clear(); }
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1324 key_compare key_comp() const
1325 { return dtl::force_copy<key_compare>(m_flat_tree.key_comp()); }
1326
1327
1328
1329
1330
1331 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1332 value_compare value_comp() const
1333 { return value_compare(dtl::force_copy<key_compare>(m_flat_tree.key_comp())); }
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1346 iterator find(const key_type& x)
1347 { return dtl::force_copy<iterator>(m_flat_tree.find(x)); }
1348
1349
1350
1351
1352
1353 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1354 const_iterator find(const key_type& x) const
1355 { return dtl::force_copy<const_iterator>(m_flat_tree.find(x)); }
1356
1357
1358
1359
1360
1361
1362
1363
1364 template<class K>
1365 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1366 iterator find(const K& x)
1367 { return dtl::force_copy<iterator>(m_flat_tree.find(x)); }
1368
1369
1370
1371
1372
1373
1374
1375
1376 template<class K>
1377 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1378 const_iterator find(const K& x) const
1379 { return dtl::force_copy<const_iterator>(m_flat_tree.find(x)); }
1380
1381
1382
1383
1384 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1385 size_type count(const key_type& x) const
1386 { return static_cast<size_type>(m_flat_tree.find(x) != m_flat_tree.end()); }
1387
1388
1389
1390
1391
1392
1393
1394 template<class K>
1395 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1396 size_type count(const K& x) const
1397
1398
1399 { return m_flat_tree.count(x); }
1400
1401
1402
1403
1404
1405 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1406 bool contains(const key_type& x) const
1407 { return m_flat_tree.find(x) != m_flat_tree.end(); }
1408
1409
1410
1411
1412
1413
1414
1415
1416 template<typename K>
1417 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1418 bool contains(const K& x) const
1419 { return m_flat_tree.find(x) != m_flat_tree.end(); }
1420
1421
1422
1423
1424
1425 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1426 iterator lower_bound(const key_type& x)
1427 { return dtl::force_copy<iterator>(m_flat_tree.lower_bound(x)); }
1428
1429
1430
1431
1432
1433 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1434 const_iterator lower_bound(const key_type& x) const
1435 { return dtl::force_copy<const_iterator>(m_flat_tree.lower_bound(x)); }
1436
1437
1438
1439
1440
1441
1442
1443
1444 template<class K>
1445 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1446 iterator lower_bound(const K& x)
1447 { return dtl::force_copy<iterator>(m_flat_tree.lower_bound(x)); }
1448
1449
1450
1451
1452
1453
1454
1455
1456 template<class K>
1457 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1458 const_iterator lower_bound(const K& x) const
1459 { return dtl::force_copy<const_iterator>(m_flat_tree.lower_bound(x)); }
1460
1461
1462
1463
1464
1465 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1466 iterator upper_bound(const key_type& x)
1467 { return dtl::force_copy<iterator>(m_flat_tree.upper_bound(x)); }
1468
1469
1470
1471
1472
1473 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1474 const_iterator upper_bound(const key_type& x) const
1475 { return dtl::force_copy<const_iterator>(m_flat_tree.upper_bound(x)); }
1476
1477
1478
1479
1480
1481
1482
1483
1484 template<class K>
1485 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1486 iterator upper_bound(const K& x)
1487 { return dtl::force_copy<iterator>(m_flat_tree.upper_bound(x)); }
1488
1489
1490
1491
1492
1493
1494
1495
1496 template<class K>
1497 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1498 const_iterator upper_bound(const K& x) const
1499 { return dtl::force_copy<const_iterator>(m_flat_tree.upper_bound(x)); }
1500
1501
1502
1503
1504 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1505 std::pair<iterator,iterator> equal_range(const key_type& x)
1506 { return dtl::force_copy<std::pair<iterator,iterator> >(m_flat_tree.lower_bound_range(x)); }
1507
1508
1509
1510
1511 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1512 std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const
1513 { return dtl::force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.lower_bound_range(x)); }
1514
1515
1516
1517
1518
1519
1520
1521 template<class K>
1522 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1523 std::pair<iterator,iterator> equal_range(const K& x)
1524
1525
1526 { return dtl::force_copy<std::pair<iterator,iterator> >(m_flat_tree.equal_range(x)); }
1527
1528
1529
1530
1531
1532
1533
1534 template<class K>
1535 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1536 std::pair<const_iterator, const_iterator> equal_range(const K& x) const
1537
1538
1539 { return dtl::force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x)); }
1540
1541
1542
1543
1544
1545
1546
1547
1548 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE sequence_type extract_sequence()
1549 {
1550 return boost::move(dtl::force<sequence_type>(m_flat_tree.get_sequence_ref()));
1551 }
1552
1553
1554
1555
1556
1557
1558
1559 BOOST_CONTAINER_FORCEINLINE void adopt_sequence(BOOST_RV_REF(sequence_type) seq)
1560 { this->m_flat_tree.adopt_sequence_unique(boost::move(dtl::force<impl_sequence_type>(seq))); }
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571 BOOST_CONTAINER_FORCEINLINE void adopt_sequence(ordered_unique_range_t, BOOST_RV_REF(sequence_type) seq)
1572 { this->m_flat_tree.adopt_sequence_unique(ordered_unique_range_t(), boost::move(dtl::force<impl_sequence_type>(seq))); }
1573
1574
1575
1576
1577
1578
1579 BOOST_CONTAINER_FORCEINLINE const sequence_type & sequence() const BOOST_NOEXCEPT
1580 { return dtl::force<sequence_type>(m_flat_tree.get_sequence_cref()); }
1581
1582
1583
1584
1585 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1586 friend bool operator==(const flat_map& x, const flat_map& y)
1587 { return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); }
1588
1589
1590
1591
1592 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1593 friend bool operator!=(const flat_map& x, const flat_map& y)
1594 { return !(x == y); }
1595
1596
1597
1598
1599 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1600 friend bool operator<(const flat_map& x, const flat_map& y)
1601 { return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
1602
1603
1604
1605
1606 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1607 friend bool operator>(const flat_map& x, const flat_map& y)
1608 { return y < x; }
1609
1610
1611
1612
1613 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1614 friend bool operator<=(const flat_map& x, const flat_map& y)
1615 { return !(y < x); }
1616
1617
1618
1619
1620 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1621 friend bool operator>=(const flat_map& x, const flat_map& y)
1622 { return !(x < y); }
1623
1624
1625
1626
1627 BOOST_CONTAINER_FORCEINLINE friend void swap(flat_map& x, flat_map& y)
1628 BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT(x.swap(y)))
1629 { x.swap(y); }
1630
1631 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
1632 private:
1633 mapped_type &priv_subscript(const key_type& k)
1634 {
1635 iterator i = this->lower_bound(k);
1636
1637 if (i == end() || key_comp()(k, (*i).first)){
1638 dtl::value_init<mapped_type> m;
1639 impl_value_type v(k, ::boost::move(m.m_t));
1640 i = this->insert(i, ::boost::move(v));
1641 }
1642 return (*i).second;
1643 }
1644 mapped_type &priv_subscript(BOOST_RV_REF(key_type) mk)
1645 {
1646 key_type &k = mk;
1647 iterator i = this->lower_bound(k);
1648
1649 if (i == end() || key_comp()(k, (*i).first)){
1650 dtl::value_init<mapped_type> m;
1651 impl_value_type v(::boost::move(k), ::boost::move(m.m_t));
1652 i = this->insert(i, ::boost::move(v));
1653 }
1654 return (*i).second;
1655 }
1656 #endif
1657 };
1658
1659 #ifndef BOOST_CONTAINER_NO_CXX17_CTAD
1660
1661 template <typename InputIterator>
1662 flat_map(InputIterator, InputIterator) ->
1663 flat_map< it_based_non_const_first_type_t<InputIterator>
1664 , it_based_second_type_t<InputIterator>>;
1665
1666 template < typename InputIterator, typename AllocatorOrCompare>
1667 flat_map(InputIterator, InputIterator, AllocatorOrCompare const&) ->
1668 flat_map< it_based_non_const_first_type_t<InputIterator>
1669 , it_based_second_type_t<InputIterator>
1670 , typename dtl::if_c<
1671 dtl::is_allocator<AllocatorOrCompare>::value
1672 , std::less<it_based_non_const_first_type_t<InputIterator>>
1673 , AllocatorOrCompare
1674 >::type
1675 , typename dtl::if_c<
1676 dtl::is_allocator<AllocatorOrCompare>::value
1677 , AllocatorOrCompare
1678 , new_allocator<std::pair<it_based_non_const_first_type_t<InputIterator>, it_based_second_type_t<InputIterator>>>
1679 >::type
1680 >;
1681
1682 template < typename InputIterator, typename Compare, typename Allocator
1683 , typename = dtl::require_nonallocator_t<Compare>
1684 , typename = dtl::require_allocator_t<Allocator>>
1685 flat_map(InputIterator, InputIterator, Compare const&, Allocator const&) ->
1686 flat_map< it_based_non_const_first_type_t<InputIterator>
1687 , it_based_second_type_t<InputIterator>
1688 , Compare
1689 , Allocator>;
1690
1691 template <typename InputIterator>
1692 flat_map(ordered_unique_range_t, InputIterator, InputIterator) ->
1693 flat_map< it_based_non_const_first_type_t<InputIterator>
1694 , it_based_second_type_t<InputIterator>>;
1695
1696 template < typename InputIterator, typename AllocatorOrCompare>
1697 flat_map(ordered_unique_range_t, InputIterator, InputIterator, AllocatorOrCompare const&) ->
1698 flat_map< it_based_non_const_first_type_t<InputIterator>
1699 , it_based_second_type_t<InputIterator>
1700 , typename dtl::if_c<
1701 dtl::is_allocator<AllocatorOrCompare>::value
1702 , std::less<it_based_non_const_first_type_t<InputIterator>>
1703 , AllocatorOrCompare
1704 >::type
1705 , typename dtl::if_c<
1706 dtl::is_allocator<AllocatorOrCompare>::value
1707 , AllocatorOrCompare
1708 , new_allocator<std::pair<it_based_non_const_first_type_t<InputIterator>, it_based_second_type_t<InputIterator>>>
1709 >::type
1710 >;
1711
1712 template < typename InputIterator, typename Compare, typename Allocator
1713 , typename = dtl::require_nonallocator_t<Compare>
1714 , typename = dtl::require_allocator_t<Allocator>>
1715 flat_map(ordered_unique_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) ->
1716 flat_map< it_based_non_const_first_type_t<InputIterator>
1717 , it_based_second_type_t<InputIterator>
1718 , Compare
1719 , Allocator>;
1720
1721 #endif
1722
1723 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
1724
1725 }
1726
1727
1728
1729 template <class Key, class T, class Compare, class AllocatorOrContainer>
1730 struct has_trivial_destructor_after_move<boost::container::flat_map<Key, T, Compare, AllocatorOrContainer> >
1731 {
1732 typedef ::boost::container::dtl::pair<Key, T> value_t;
1733 typedef typename ::boost::container::dtl::container_or_allocator_rebind<AllocatorOrContainer, value_t>::type alloc_or_cont_t;
1734 typedef ::boost::container::dtl::flat_tree<value_t,::boost::container::dtl::select1st<Key>, Compare, alloc_or_cont_t> tree;
1735 static const bool value = ::boost::has_trivial_destructor_after_move<tree>::value;
1736 };
1737
1738 namespace container {
1739
1740 #endif
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
1771 template <class Key, class T, class Compare = std::less<Key>, class AllocatorOrContainer = new_allocator< std::pair< Key, T> > >
1772 #else
1773 template <class Key, class T, class Compare, class AllocatorOrContainer>
1774 #endif
1775 class flat_multimap
1776 {
1777 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
1778 private:
1779 BOOST_COPYABLE_AND_MOVABLE(flat_multimap)
1780 typedef dtl::flat_tree<
1781 std::pair<Key, T>,
1782 dtl::select1st<Key>,
1783 Compare,
1784 AllocatorOrContainer> tree_t;
1785
1786 typedef dtl::flat_tree<
1787 dtl::pair<Key, T>,
1788 dtl::select1st<Key>,
1789 Compare,
1790 typename dtl::container_or_allocator_rebind<AllocatorOrContainer, dtl::pair<Key, T> >::type
1791 > impl_tree_t;
1792 impl_tree_t m_flat_tree;
1793
1794 typedef typename impl_tree_t::value_type impl_value_type;
1795 typedef typename impl_tree_t::const_iterator impl_const_iterator;
1796 typedef typename impl_tree_t::iterator impl_iterator;
1797 typedef typename impl_tree_t::allocator_type impl_allocator_type;
1798 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
1799 typedef std::initializer_list<impl_value_type> impl_initializer_list;
1800 #endif
1801
1802 typedef dtl::flat_tree_value_compare
1803 < Compare
1804 , dtl::select1st<Key>
1805 , std::pair<Key, T> > value_compare_t;
1806 typedef typename tree_t::iterator iterator_t;
1807 typedef typename tree_t::const_iterator const_iterator_t;
1808 typedef typename tree_t::reverse_iterator reverse_iterator_t;
1809 typedef typename tree_t::const_reverse_iterator const_reverse_iterator_t;
1810
1811 public:
1812 typedef typename impl_tree_t::stored_allocator_type impl_stored_allocator_type;
1813 typedef typename impl_tree_t::sequence_type impl_sequence_type;
1814
1815 BOOST_CONTAINER_FORCEINLINE impl_tree_t &tree()
1816 { return m_flat_tree; }
1817
1818 BOOST_CONTAINER_FORCEINLINE const impl_tree_t &tree() const
1819 { return m_flat_tree; }
1820
1821 private:
1822 #endif
1823
1824 public:
1825
1826
1827
1828
1829
1830
1831 typedef Key key_type;
1832 typedef T mapped_type;
1833 typedef Compare key_compare;
1834 typedef std::pair<Key, T> value_type;
1835 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::sequence_type) sequence_type;
1836 typedef typename sequence_type::allocator_type allocator_type;
1837 typedef ::boost::container::allocator_traits<allocator_type> allocator_traits_type;
1838 typedef typename sequence_type::pointer pointer;
1839 typedef typename sequence_type::const_pointer const_pointer;
1840 typedef typename sequence_type::reference reference;
1841 typedef typename sequence_type::const_reference const_reference;
1842 typedef typename sequence_type::size_type size_type;
1843 typedef typename sequence_type::difference_type difference_type;
1844 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::stored_allocator_type) stored_allocator_type;
1845 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::value_compare) value_compare;
1846
1847 typedef typename sequence_type::iterator iterator;
1848 typedef typename sequence_type::const_iterator const_iterator;
1849 typedef typename sequence_type::reverse_iterator reverse_iterator;
1850 typedef typename sequence_type::const_reverse_iterator const_reverse_iterator;
1851 typedef BOOST_CONTAINER_IMPDEF(impl_value_type) movable_value_type;
1852
1853
1854 BOOST_STATIC_ASSERT((dtl::is_same<std::pair<Key, T>, value_type>::value));
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865 BOOST_CONTAINER_FORCEINLINE flat_multimap()
1866 BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<AllocatorOrContainer>::value &&
1867 dtl::is_nothrow_default_constructible<Compare>::value)
1868 : m_flat_tree()
1869 {}
1870
1871
1872
1873
1874 BOOST_CONTAINER_FORCEINLINE explicit flat_multimap(const allocator_type& a)
1875 : m_flat_tree(dtl::force<const impl_allocator_type>(a))
1876 {}
1877
1878
1879
1880
1881
1882 BOOST_CONTAINER_FORCEINLINE explicit flat_multimap(const Compare& comp)
1883 : m_flat_tree(comp)
1884 {}
1885
1886
1887
1888
1889
1890 BOOST_CONTAINER_FORCEINLINE
1891 flat_multimap(const Compare& comp, const allocator_type& a)
1892 : m_flat_tree(comp, dtl::force<const impl_allocator_type>(a))
1893 {}
1894
1895
1896
1897
1898
1899
1900 template <class InputIterator>
1901 BOOST_CONTAINER_FORCEINLINE
1902 flat_multimap(InputIterator first, InputIterator last)
1903 : m_flat_tree(false, first, last)
1904 {}
1905
1906
1907
1908
1909
1910
1911 template <class InputIterator>
1912 BOOST_CONTAINER_FORCEINLINE
1913 flat_multimap(InputIterator first, InputIterator last, const allocator_type& a)
1914 : m_flat_tree(false, first, last, dtl::force<const impl_allocator_type>(a))
1915 {}
1916
1917
1918
1919
1920
1921
1922 template <class InputIterator>
1923 BOOST_CONTAINER_FORCEINLINE
1924 flat_multimap(InputIterator first, InputIterator last, const Compare& comp)
1925 : m_flat_tree(false, first, last, comp)
1926 {}
1927
1928
1929
1930
1931
1932
1933 template <class InputIterator>
1934 BOOST_CONTAINER_FORCEINLINE
1935 flat_multimap(InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
1936 : m_flat_tree(false, first, last, comp, dtl::force<const impl_allocator_type>(a))
1937 {}
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948 template <class InputIterator>
1949 BOOST_CONTAINER_FORCEINLINE
1950 flat_multimap(ordered_range_t, InputIterator first, InputIterator last)
1951 : m_flat_tree(ordered_range, first, last)
1952 {}
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963 template <class InputIterator>
1964 BOOST_CONTAINER_FORCEINLINE
1965 flat_multimap(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp)
1966 : m_flat_tree(ordered_range, first, last, comp)
1967 {}
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978 template <class InputIterator>
1979 BOOST_CONTAINER_FORCEINLINE
1980 flat_multimap(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
1981 : m_flat_tree(ordered_range, first, last, comp, a)
1982 {}
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993 template <class InputIterator>
1994 BOOST_CONTAINER_FORCEINLINE
1995 flat_multimap(ordered_range_t, InputIterator first, InputIterator last, const allocator_type &a)
1996 : m_flat_tree(ordered_range, first, last, Compare(), a)
1997 {}
1998
1999 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
2000
2001
2002
2003
2004
2005 BOOST_CONTAINER_FORCEINLINE
2006 flat_multimap(std::initializer_list<value_type> il)
2007 : m_flat_tree( false
2008 , dtl::force<impl_initializer_list>(il).begin()
2009 , dtl::force<impl_initializer_list>(il).end())
2010 {}
2011
2012
2013
2014
2015
2016
2017 BOOST_CONTAINER_FORCEINLINE
2018 flat_multimap(std::initializer_list<value_type> il, const allocator_type& a)
2019 : m_flat_tree(false
2020 , dtl::force<impl_initializer_list>(il).begin()
2021 , dtl::force<impl_initializer_list>(il).end()
2022 , dtl::force<const impl_allocator_type>(a))
2023 {}
2024
2025
2026
2027
2028
2029
2030 BOOST_CONTAINER_FORCEINLINE
2031 flat_multimap(std::initializer_list<value_type> il, const Compare& comp)
2032 : m_flat_tree(false
2033 , dtl::force<impl_initializer_list>(il).begin()
2034 , dtl::force<impl_initializer_list>(il).end(), comp)
2035 {}
2036
2037
2038
2039
2040
2041
2042 BOOST_CONTAINER_FORCEINLINE
2043 flat_multimap(std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
2044 : m_flat_tree( false
2045 , dtl::force<impl_initializer_list>(il).begin()
2046 , dtl::force<impl_initializer_list>(il).end()
2047 , comp, dtl::force<const impl_allocator_type>(a))
2048 {}
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059 BOOST_CONTAINER_FORCEINLINE
2060 flat_multimap(ordered_range_t, std::initializer_list<value_type> il)
2061 : m_flat_tree( ordered_range
2062 , dtl::force<impl_initializer_list>(il).begin()
2063 , dtl::force<impl_initializer_list>(il).end())
2064 {}
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075 BOOST_CONTAINER_FORCEINLINE
2076 flat_multimap(ordered_range_t, std::initializer_list<value_type> il, const Compare& comp)
2077 : m_flat_tree( ordered_range
2078 , dtl::force<impl_initializer_list>(il).begin()
2079 , dtl::force<impl_initializer_list>(il).end(), comp)
2080 {}
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091 BOOST_CONTAINER_FORCEINLINE
2092 flat_multimap(ordered_range_t, std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
2093 : m_flat_tree( ordered_range
2094 , dtl::force<impl_initializer_list>(il).begin()
2095 , dtl::force<impl_initializer_list>(il).end()
2096 , comp, dtl::force<const impl_allocator_type>(a))
2097 {}
2098 #endif
2099
2100
2101
2102
2103 BOOST_CONTAINER_FORCEINLINE
2104 flat_multimap(const flat_multimap& x)
2105 : m_flat_tree(x.m_flat_tree)
2106 {}
2107
2108
2109
2110
2111
2112
2113 BOOST_CONTAINER_FORCEINLINE
2114 flat_multimap(BOOST_RV_REF(flat_multimap) x)
2115 BOOST_NOEXCEPT_IF(boost::container::dtl::is_nothrow_move_constructible<Compare>::value)
2116 : m_flat_tree(boost::move(x.m_flat_tree))
2117 {}
2118
2119
2120
2121
2122 BOOST_CONTAINER_FORCEINLINE
2123 flat_multimap(const flat_multimap& x, const allocator_type &a)
2124 : m_flat_tree(x.m_flat_tree, dtl::force<const impl_allocator_type>(a))
2125 {}
2126
2127
2128
2129
2130
2131 BOOST_CONTAINER_FORCEINLINE
2132 flat_multimap(BOOST_RV_REF(flat_multimap) x, const allocator_type &a)
2133 : m_flat_tree(boost::move(x.m_flat_tree), dtl::force<const impl_allocator_type>(a))
2134 {}
2135
2136
2137
2138
2139 BOOST_CONTAINER_FORCEINLINE
2140 flat_multimap& operator=(BOOST_COPY_ASSIGN_REF(flat_multimap) x)
2141 { m_flat_tree = x.m_flat_tree; return *this; }
2142
2143
2144
2145
2146 BOOST_CONTAINER_FORCEINLINE
2147 flat_multimap& operator=(BOOST_RV_REF(flat_multimap) x)
2148 BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value ||
2149 allocator_traits_type::is_always_equal::value) &&
2150 boost::container::dtl::is_nothrow_move_assignable<Compare>::value)
2151 { m_flat_tree = boost::move(x.m_flat_tree); return *this; }
2152
2153 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
2154
2155
2156
2157 BOOST_CONTAINER_FORCEINLINE
2158 flat_multimap& operator=(std::initializer_list<value_type> il)
2159 {
2160 this->clear();
2161 this->insert(il.begin(), il.end());
2162 return *this;
2163 }
2164 #endif
2165
2166
2167
2168
2169
2170 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2171 allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
2172 { return dtl::force_copy<allocator_type>(m_flat_tree.get_allocator()); }
2173
2174
2175
2176
2177
2178
2179
2180
2181 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2182 stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
2183 { return dtl::force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
2184
2185
2186
2187
2188
2189
2190
2191
2192 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2193 const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
2194 { return dtl::force<const stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2208 iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
2209 { return dtl::force_copy<iterator>(m_flat_tree.begin()); }
2210
2211
2212
2213
2214
2215
2216 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2217 const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
2218 { return dtl::force_copy<const_iterator>(m_flat_tree.begin()); }
2219
2220
2221
2222
2223
2224
2225 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2226 iterator end() BOOST_NOEXCEPT_OR_NOTHROW
2227 { return dtl::force_copy<iterator>(m_flat_tree.end()); }
2228
2229
2230
2231
2232
2233
2234 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2235 const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
2236 { return dtl::force_copy<const_iterator>(m_flat_tree.end()); }
2237
2238
2239
2240
2241
2242
2243
2244 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2245 reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW
2246 { return dtl::force_copy<reverse_iterator>(m_flat_tree.rbegin()); }
2247
2248
2249
2250
2251
2252
2253
2254 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2255 const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
2256 { return dtl::force_copy<const_reverse_iterator>(m_flat_tree.rbegin()); }
2257
2258
2259
2260
2261
2262
2263
2264 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2265 reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW
2266 { return dtl::force_copy<reverse_iterator>(m_flat_tree.rend()); }
2267
2268
2269
2270
2271
2272
2273
2274 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2275 const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW
2276 { return dtl::force_copy<const_reverse_iterator>(m_flat_tree.rend()); }
2277
2278
2279
2280
2281
2282
2283 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2284 const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
2285 { return dtl::force_copy<const_iterator>(m_flat_tree.cbegin()); }
2286
2287
2288
2289
2290
2291
2292 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2293 const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
2294 { return dtl::force_copy<const_iterator>(m_flat_tree.cend()); }
2295
2296
2297
2298
2299
2300
2301
2302 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2303 const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW
2304 { return dtl::force_copy<const_reverse_iterator>(m_flat_tree.crbegin()); }
2305
2306
2307
2308
2309
2310
2311
2312 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2313 const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW
2314 { return dtl::force_copy<const_reverse_iterator>(m_flat_tree.crend()); }
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2328 bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
2329 { return m_flat_tree.empty(); }
2330
2331
2332
2333
2334
2335
2336 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2337 size_type size() const BOOST_NOEXCEPT_OR_NOTHROW
2338 { return m_flat_tree.size(); }
2339
2340
2341
2342
2343
2344
2345 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2346 size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
2347 { return m_flat_tree.max_size(); }
2348
2349
2350
2351
2352
2353
2354
2355 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2356 size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW
2357 { return m_flat_tree.capacity(); }
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369 BOOST_CONTAINER_FORCEINLINE
2370 void reserve(size_type cnt)
2371 { m_flat_tree.reserve(cnt); }
2372
2373
2374
2375
2376
2377
2378
2379 BOOST_CONTAINER_FORCEINLINE
2380 void shrink_to_fit()
2381 { m_flat_tree.shrink_to_fit(); }
2382
2383
2384 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2385 iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
2386 { return dtl::force_copy<iterator>(m_flat_tree.nth(n)); }
2387
2388
2389 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2390 const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
2391 { return dtl::force_copy<iterator>(m_flat_tree.nth(n)); }
2392
2393
2394 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2395 size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
2396 { return m_flat_tree.index_of(dtl::force_copy<impl_iterator>(p)); }
2397
2398
2399 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2400 size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW
2401 { return m_flat_tree.index_of(dtl::force_copy<impl_const_iterator>(p)); }
2402
2403 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413 template <class... Args>
2414 BOOST_CONTAINER_FORCEINLINE
2415 iterator emplace(BOOST_FWD_REF(Args)... args)
2416 { return dtl::force_copy<iterator>(m_flat_tree.emplace_equal(boost::forward<Args>(args)...)); }
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430 template <class... Args>
2431 BOOST_CONTAINER_FORCEINLINE
2432 iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(Args)... args)
2433 {
2434 return dtl::force_copy<iterator>(m_flat_tree.emplace_hint_equal
2435 (dtl::force_copy<impl_const_iterator>(hint), boost::forward<Args>(args)...));
2436 }
2437
2438 #else
2439
2440 #define BOOST_CONTAINER_FLAT_MULTIMAP_EMPLACE_CODE(N) \
2441 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
2442 BOOST_CONTAINER_FORCEINLINE iterator emplace(BOOST_MOVE_UREF##N)\
2443 { return dtl::force_copy<iterator>(m_flat_tree.emplace_equal(BOOST_MOVE_FWD##N)); }\
2444 \
2445 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
2446 BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
2447 {\
2448 return dtl::force_copy<iterator>(m_flat_tree.emplace_hint_equal\
2449 (dtl::force_copy<impl_const_iterator>(hint) BOOST_MOVE_I##N BOOST_MOVE_FWD##N));\
2450 }\
2451
2452 BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_MULTIMAP_EMPLACE_CODE)
2453 #undef BOOST_CONTAINER_FLAT_MULTIMAP_EMPLACE_CODE
2454
2455 #endif
2456
2457
2458
2459
2460
2461
2462
2463
2464 BOOST_CONTAINER_FORCEINLINE iterator insert(const value_type& x)
2465 {
2466 return dtl::force_copy<iterator>(
2467 m_flat_tree.insert_equal(dtl::force<const impl_value_type>(x)));
2468 }
2469
2470
2471
2472
2473
2474
2475
2476
2477 template<class Pair>
2478 BOOST_CONTAINER_FORCEINLINE BOOST_CONTAINER_DOC1ST
2479 ( iterator
2480 , typename dtl::enable_if_c<dtl::is_convertible<Pair BOOST_MOVE_I impl_value_type>::value
2481 BOOST_MOVE_I iterator >::type)
2482 insert(BOOST_FWD_REF(Pair) x)
2483 { return dtl::force_copy<iterator>(m_flat_tree.emplace_equal(boost::forward<Pair>(x))); }
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496 BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, const value_type& x)
2497 {
2498 return dtl::force_copy<iterator>
2499 (m_flat_tree.insert_equal( dtl::force_copy<impl_const_iterator>(p)
2500 , dtl::force<const impl_value_type>(x)));
2501 }
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514 template<class Pair>
2515 BOOST_CONTAINER_FORCEINLINE BOOST_CONTAINER_DOC1ST
2516 ( iterator
2517 , typename dtl::enable_if_c<dtl::is_convertible<Pair BOOST_MOVE_I impl_value_type>::value
2518 BOOST_MOVE_I iterator>::type)
2519 insert(const_iterator p, BOOST_FWD_REF(Pair) x)
2520 {
2521 return dtl::force_copy<iterator>(
2522 m_flat_tree.emplace_hint_equal(dtl::force_copy<impl_const_iterator>(p), boost::forward<Pair>(x)));
2523 }
2524
2525
2526
2527
2528
2529
2530
2531
2532 template <class InputIterator>
2533 BOOST_CONTAINER_FORCEINLINE void insert(InputIterator first, InputIterator last)
2534 { m_flat_tree.insert_equal(first, last); }
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549 template <class InputIterator>
2550 BOOST_CONTAINER_FORCEINLINE void insert(ordered_range_t, InputIterator first, InputIterator last)
2551 { m_flat_tree.insert_equal(ordered_range, first, last); }
2552
2553 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
2554
2555
2556
2557
2558
2559 BOOST_CONTAINER_FORCEINLINE void insert(std::initializer_list<value_type> il)
2560 {
2561 m_flat_tree.insert_equal( dtl::force<impl_initializer_list>(il).begin()
2562 , dtl::force<impl_initializer_list>(il).end());
2563 }
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576 BOOST_CONTAINER_FORCEINLINE void insert(ordered_range_t, std::initializer_list<value_type> il)
2577 {
2578 m_flat_tree.insert_equal( ordered_range
2579 , dtl::force<impl_initializer_list>(il).begin()
2580 , dtl::force<impl_initializer_list>(il).end());
2581 }
2582 #endif
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592 template<class C2>
2593 BOOST_CONTAINER_FORCEINLINE void merge(flat_multimap<Key, T, C2, AllocatorOrContainer>& source)
2594 { m_flat_tree.merge_equal(source.tree()); }
2595
2596
2597 template<class C2>
2598 BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_multimap<Key, T, C2, AllocatorOrContainer> BOOST_RV_REF_END source)
2599 { return this->merge(static_cast<flat_multimap<Key, T, C2, AllocatorOrContainer>&>(source)); }
2600
2601
2602 template<class C2>
2603 BOOST_CONTAINER_FORCEINLINE void merge(flat_map<Key, T, C2, AllocatorOrContainer>& source)
2604 { m_flat_tree.merge_equal(source.tree()); }
2605
2606
2607 template<class C2>
2608 BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_map<Key, T, C2, AllocatorOrContainer> BOOST_RV_REF_END source)
2609 { return this->merge(static_cast<flat_map<Key, T, C2, AllocatorOrContainer>&>(source)); }
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621 BOOST_CONTAINER_FORCEINLINE iterator erase(const_iterator p)
2622 {
2623 return dtl::force_copy<iterator>(
2624 m_flat_tree.erase(dtl::force_copy<impl_const_iterator>(p)));
2625 }
2626
2627
2628
2629
2630
2631
2632
2633 BOOST_CONTAINER_FORCEINLINE size_type erase(const key_type& x)
2634 { return m_flat_tree.erase(x); }
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644 BOOST_CONTAINER_FORCEINLINE iterator erase(const_iterator first, const_iterator last)
2645 {
2646 return dtl::force_copy<iterator>
2647 (m_flat_tree.erase( dtl::force_copy<impl_const_iterator>(first)
2648 , dtl::force_copy<impl_const_iterator>(last)));
2649 }
2650
2651
2652
2653
2654
2655
2656 BOOST_CONTAINER_FORCEINLINE void swap(flat_multimap& x)
2657 BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
2658 && boost::container::dtl::is_nothrow_swappable<Compare>::value )
2659 { m_flat_tree.swap(x.m_flat_tree); }
2660
2661
2662
2663
2664
2665
2666 BOOST_CONTAINER_FORCEINLINE void clear() BOOST_NOEXCEPT_OR_NOTHROW
2667 { m_flat_tree.clear(); }
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2680 key_compare key_comp() const
2681 { return dtl::force_copy<key_compare>(m_flat_tree.key_comp()); }
2682
2683
2684
2685
2686
2687 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2688 value_compare value_comp() const
2689 { return value_compare(dtl::force_copy<key_compare>(m_flat_tree.key_comp())); }
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2702 iterator find(const key_type& x)
2703 { return dtl::force_copy<iterator>(m_flat_tree.find(x)); }
2704
2705
2706
2707
2708
2709 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2710 const_iterator find(const key_type& x) const
2711 { return dtl::force_copy<const_iterator>(m_flat_tree.find(x)); }
2712
2713
2714
2715
2716
2717
2718
2719
2720 template<class K>
2721 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2722 iterator find(const K& x)
2723 { return dtl::force_copy<iterator>(m_flat_tree.find(x)); }
2724
2725
2726
2727
2728
2729
2730
2731
2732 template<class K>
2733 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2734 const_iterator find(const K& x) const
2735 { return dtl::force_copy<const_iterator>(m_flat_tree.find(x)); }
2736
2737
2738
2739
2740 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2741 size_type count(const key_type& x) const
2742 { return m_flat_tree.count(x); }
2743
2744
2745
2746
2747
2748
2749
2750 template<class K>
2751 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2752 size_type count(const K& x) const
2753 { return m_flat_tree.count(x); }
2754
2755
2756
2757
2758
2759 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2760 bool contains(const key_type& x) const
2761 { return m_flat_tree.find(x) != m_flat_tree.end(); }
2762
2763
2764
2765
2766
2767
2768
2769
2770 template<typename K>
2771 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2772 bool contains(const K& x) const
2773 { return m_flat_tree.find(x) != m_flat_tree.end(); }
2774
2775
2776
2777
2778
2779 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2780 iterator lower_bound(const key_type& x)
2781 { return dtl::force_copy<iterator>(m_flat_tree.lower_bound(x)); }
2782
2783
2784
2785
2786
2787 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2788 const_iterator lower_bound(const key_type& x) const
2789 { return dtl::force_copy<const_iterator>(m_flat_tree.lower_bound(x)); }
2790
2791
2792
2793
2794
2795
2796
2797
2798 template<class K>
2799 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2800 iterator lower_bound(const K& x)
2801 { return dtl::force_copy<iterator>(m_flat_tree.lower_bound(x)); }
2802
2803
2804
2805
2806
2807
2808
2809
2810 template<class K>
2811 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2812 const_iterator lower_bound(const K& x) const
2813 { return dtl::force_copy<const_iterator>(m_flat_tree.lower_bound(x)); }
2814
2815
2816
2817
2818
2819 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2820 iterator upper_bound(const key_type& x)
2821 {return dtl::force_copy<iterator>(m_flat_tree.upper_bound(x)); }
2822
2823
2824
2825
2826
2827 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2828 const_iterator upper_bound(const key_type& x) const
2829 { return dtl::force_copy<const_iterator>(m_flat_tree.upper_bound(x)); }
2830
2831
2832
2833
2834
2835
2836
2837
2838 template<class K>
2839 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2840 iterator upper_bound(const K& x)
2841 {return dtl::force_copy<iterator>(m_flat_tree.upper_bound(x)); }
2842
2843
2844
2845
2846
2847
2848
2849
2850 template<class K>
2851 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2852 const_iterator upper_bound(const K& x) const
2853 { return dtl::force_copy<const_iterator>(m_flat_tree.upper_bound(x)); }
2854
2855
2856
2857
2858 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2859 std::pair<iterator,iterator> equal_range(const key_type& x)
2860 { return dtl::force_copy<std::pair<iterator,iterator> >(m_flat_tree.equal_range(x)); }
2861
2862
2863
2864
2865 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2866 std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const
2867 { return dtl::force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x)); }
2868
2869
2870
2871
2872
2873
2874
2875 template<class K>
2876 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2877 std::pair<iterator,iterator> equal_range(const K& x)
2878 { return dtl::force_copy<std::pair<iterator,iterator> >(m_flat_tree.equal_range(x)); }
2879
2880
2881
2882
2883
2884
2885
2886 template<class K>
2887 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2888 std::pair<const_iterator, const_iterator> equal_range(const K& x) const
2889 { return dtl::force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x)); }
2890
2891
2892
2893
2894
2895
2896
2897
2898 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2899 sequence_type extract_sequence()
2900 { return boost::move(dtl::force<sequence_type>(m_flat_tree.get_sequence_ref())); }
2901
2902
2903
2904
2905
2906
2907
2908 BOOST_CONTAINER_FORCEINLINE void adopt_sequence(BOOST_RV_REF(sequence_type) seq)
2909 { this->m_flat_tree.adopt_sequence_equal(boost::move(dtl::force<impl_sequence_type>(seq))); }
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919 BOOST_CONTAINER_FORCEINLINE void adopt_sequence(ordered_range_t, BOOST_RV_REF(sequence_type) seq)
2920 { this->m_flat_tree.adopt_sequence_equal(ordered_range_t(), boost::move(dtl::force<impl_sequence_type>(seq))); }
2921
2922
2923
2924
2925
2926
2927 BOOST_CONTAINER_FORCEINLINE const sequence_type & sequence() const BOOST_NOEXCEPT
2928 { return dtl::force<sequence_type>(m_flat_tree.get_sequence_cref()); }
2929
2930
2931
2932
2933 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2934 friend bool operator==(const flat_multimap& x, const flat_multimap& y)
2935 { return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); }
2936
2937
2938
2939
2940 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2941 friend bool operator!=(const flat_multimap& x, const flat_multimap& y)
2942 { return !(x == y); }
2943
2944
2945
2946
2947 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2948 friend bool operator<(const flat_multimap& x, const flat_multimap& y)
2949 { return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
2950
2951
2952
2953
2954 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2955 friend bool operator>(const flat_multimap& x, const flat_multimap& y)
2956 { return y < x; }
2957
2958
2959
2960
2961 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2962 friend bool operator<=(const flat_multimap& x, const flat_multimap& y)
2963 { return !(y < x); }
2964
2965
2966
2967
2968 BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2969 friend bool operator>=(const flat_multimap& x, const flat_multimap& y)
2970 { return !(x < y); }
2971
2972
2973
2974
2975 BOOST_CONTAINER_FORCEINLINE friend void swap(flat_multimap& x, flat_multimap& y)
2976 BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT(x.swap(y)))
2977 { x.swap(y); }
2978 };
2979
2980 #ifndef BOOST_CONTAINER_NO_CXX17_CTAD
2981
2982 template <typename InputIterator>
2983 flat_multimap(InputIterator, InputIterator) ->
2984 flat_multimap< it_based_non_const_first_type_t<InputIterator>
2985 , it_based_second_type_t<InputIterator>>;
2986
2987 template < typename InputIterator, typename AllocatorOrCompare>
2988 flat_multimap(InputIterator, InputIterator, AllocatorOrCompare const&) ->
2989 flat_multimap< it_based_non_const_first_type_t<InputIterator>
2990 , it_based_second_type_t<InputIterator>
2991 , typename dtl::if_c<
2992 dtl::is_allocator<AllocatorOrCompare>::value
2993 , std::less<it_based_non_const_first_type_t<InputIterator>>
2994 , AllocatorOrCompare
2995 >::type
2996 , typename dtl::if_c<
2997 dtl::is_allocator<AllocatorOrCompare>::value
2998 , AllocatorOrCompare
2999 , new_allocator<std::pair<it_based_non_const_first_type_t<InputIterator>, it_based_second_type_t<InputIterator>>>
3000 >::type
3001 >;
3002
3003 template < typename InputIterator, typename Compare, typename Allocator
3004 , typename = dtl::require_nonallocator_t<Compare>
3005 , typename = dtl::require_allocator_t<Allocator>>
3006 flat_multimap(InputIterator, InputIterator, Compare const&, Allocator const&) ->
3007 flat_multimap< it_based_non_const_first_type_t<InputIterator>
3008 , it_based_second_type_t<InputIterator>
3009 , Compare
3010 , Allocator>;
3011
3012 template <typename InputIterator>
3013 flat_multimap(ordered_range_t, InputIterator, InputIterator) ->
3014 flat_multimap< it_based_non_const_first_type_t<InputIterator>
3015 , it_based_second_type_t<InputIterator>>;
3016
3017 template < typename InputIterator, typename AllocatorOrCompare>
3018 flat_multimap(ordered_range_t, InputIterator, InputIterator, AllocatorOrCompare const&) ->
3019 flat_multimap< it_based_non_const_first_type_t<InputIterator>
3020 , it_based_second_type_t<InputIterator>
3021 , typename dtl::if_c<
3022 dtl::is_allocator<AllocatorOrCompare>::value
3023 , std::less<it_based_non_const_first_type_t<InputIterator>>
3024 , AllocatorOrCompare
3025 >::type
3026 , typename dtl::if_c<
3027 dtl::is_allocator<AllocatorOrCompare>::value
3028 , AllocatorOrCompare
3029 , new_allocator<std::pair<it_based_non_const_first_type_t<InputIterator>, it_based_second_type_t<InputIterator>>>
3030 >::type
3031 >;
3032
3033 template < typename InputIterator, typename Compare, typename Allocator
3034 , typename = dtl::require_nonallocator_t<Compare>
3035 , typename = dtl::require_allocator_t<Allocator>>
3036 flat_multimap(ordered_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) ->
3037 flat_multimap< it_based_non_const_first_type_t<InputIterator>
3038 , it_based_second_type_t<InputIterator>
3039 , Compare
3040 , Allocator>;
3041
3042 #endif
3043
3044 }}
3045
3046 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
3047
3048 namespace boost {
3049
3050
3051
3052 template <class Key, class T, class Compare, class AllocatorOrContainer>
3053 struct has_trivial_destructor_after_move< boost::container::flat_multimap<Key, T, Compare, AllocatorOrContainer> >
3054 {
3055 typedef ::boost::container::dtl::pair<Key, T> value_t;
3056 typedef typename ::boost::container::dtl::container_or_allocator_rebind<AllocatorOrContainer, value_t>::type alloc_or_cont_t;
3057 typedef ::boost::container::dtl::flat_tree<value_t,::boost::container::dtl::select1st<Key>, Compare, alloc_or_cont_t> tree;
3058 static const bool value = ::boost::has_trivial_destructor_after_move<tree>::value;
3059 };
3060
3061 }
3062
3063 #endif
3064
3065 #include <boost/container/detail/config_end.hpp>
3066
3067 #endif