File indexing completed on 2025-01-18 09:53:23
0001
0002
0003
0004
0005 #ifndef BOOST_UNORDERED_UNORDERED_FLAT_MAP_HPP_INCLUDED
0006 #define BOOST_UNORDERED_UNORDERED_FLAT_MAP_HPP_INCLUDED
0007
0008 #include <boost/config.hpp>
0009 #if defined(BOOST_HAS_PRAGMA_ONCE)
0010 #pragma once
0011 #endif
0012
0013 #include <boost/unordered/concurrent_flat_map_fwd.hpp>
0014 #include <boost/unordered/detail/foa/flat_map_types.hpp>
0015 #include <boost/unordered/detail/foa/table.hpp>
0016 #include <boost/unordered/detail/serialize_container.hpp>
0017 #include <boost/unordered/detail/type_traits.hpp>
0018 #include <boost/unordered/unordered_flat_map_fwd.hpp>
0019
0020 #include <boost/core/allocator_access.hpp>
0021 #include <boost/container_hash/hash.hpp>
0022 #include <boost/throw_exception.hpp>
0023
0024 #include <initializer_list>
0025 #include <iterator>
0026 #include <stdexcept>
0027 #include <type_traits>
0028 #include <utility>
0029
0030 namespace boost {
0031 namespace unordered {
0032
0033 #if defined(BOOST_MSVC)
0034 #pragma warning(push)
0035 #pragma warning(disable : 4714)
0036 #endif
0037
0038 template <class Key, class T, class Hash, class KeyEqual, class Allocator>
0039 class unordered_flat_map
0040 {
0041 template <class Key2, class T2, class Hash2, class Pred2,
0042 class Allocator2>
0043 friend class concurrent_flat_map;
0044
0045 using map_types = detail::foa::flat_map_types<Key, T>;
0046
0047 using table_type = detail::foa::table<map_types, Hash, KeyEqual,
0048 typename boost::allocator_rebind<Allocator,
0049 typename map_types::value_type>::type>;
0050
0051 table_type table_;
0052
0053 template <class K, class V, class H, class KE, class A>
0054 bool friend operator==(unordered_flat_map<K, V, H, KE, A> const& lhs,
0055 unordered_flat_map<K, V, H, KE, A> const& rhs);
0056
0057 template <class K, class V, class H, class KE, class A, class Pred>
0058 typename unordered_flat_map<K, V, H, KE, A>::size_type friend erase_if(
0059 unordered_flat_map<K, V, H, KE, A>& set, Pred pred);
0060
0061 public:
0062 using key_type = Key;
0063 using mapped_type = T;
0064 using value_type = typename map_types::value_type;
0065 using init_type = typename map_types::init_type;
0066 using size_type = std::size_t;
0067 using difference_type = std::ptrdiff_t;
0068 using hasher = typename boost::unordered::detail::type_identity<Hash>::type;
0069 using key_equal = typename boost::unordered::detail::type_identity<KeyEqual>::type;
0070 using allocator_type = typename boost::unordered::detail::type_identity<Allocator>::type;
0071 using reference = value_type&;
0072 using const_reference = value_type const&;
0073 using pointer = typename boost::allocator_pointer<allocator_type>::type;
0074 using const_pointer =
0075 typename boost::allocator_const_pointer<allocator_type>::type;
0076 using iterator = typename table_type::iterator;
0077 using const_iterator = typename table_type::const_iterator;
0078
0079 unordered_flat_map() : unordered_flat_map(0) {}
0080
0081 explicit unordered_flat_map(size_type n, hasher const& h = hasher(),
0082 key_equal const& pred = key_equal(),
0083 allocator_type const& a = allocator_type())
0084 : table_(n, h, pred, a)
0085 {
0086 }
0087
0088 unordered_flat_map(size_type n, allocator_type const& a)
0089 : unordered_flat_map(n, hasher(), key_equal(), a)
0090 {
0091 }
0092
0093 unordered_flat_map(size_type n, hasher const& h, allocator_type const& a)
0094 : unordered_flat_map(n, h, key_equal(), a)
0095 {
0096 }
0097
0098 template <class InputIterator>
0099 unordered_flat_map(
0100 InputIterator f, InputIterator l, allocator_type const& a)
0101 : unordered_flat_map(f, l, size_type(0), hasher(), key_equal(), a)
0102 {
0103 }
0104
0105 explicit unordered_flat_map(allocator_type const& a)
0106 : unordered_flat_map(0, a)
0107 {
0108 }
0109
0110 template <class Iterator>
0111 unordered_flat_map(Iterator first, Iterator last, size_type n = 0,
0112 hasher const& h = hasher(), key_equal const& pred = key_equal(),
0113 allocator_type const& a = allocator_type())
0114 : unordered_flat_map(n, h, pred, a)
0115 {
0116 this->insert(first, last);
0117 }
0118
0119 template <class Iterator>
0120 unordered_flat_map(
0121 Iterator first, Iterator last, size_type n, allocator_type const& a)
0122 : unordered_flat_map(first, last, n, hasher(), key_equal(), a)
0123 {
0124 }
0125
0126 template <class Iterator>
0127 unordered_flat_map(Iterator first, Iterator last, size_type n,
0128 hasher const& h, allocator_type const& a)
0129 : unordered_flat_map(first, last, n, h, key_equal(), a)
0130 {
0131 }
0132
0133 unordered_flat_map(unordered_flat_map const& other) : table_(other.table_)
0134 {
0135 }
0136
0137 unordered_flat_map(
0138 unordered_flat_map const& other, allocator_type const& a)
0139 : table_(other.table_, a)
0140 {
0141 }
0142
0143 unordered_flat_map(unordered_flat_map&& other)
0144 noexcept(std::is_nothrow_move_constructible<table_type>::value)
0145 : table_(std::move(other.table_))
0146 {
0147 }
0148
0149 unordered_flat_map(unordered_flat_map&& other, allocator_type const& al)
0150 : table_(std::move(other.table_), al)
0151 {
0152 }
0153
0154 unordered_flat_map(std::initializer_list<value_type> ilist,
0155 size_type n = 0, hasher const& h = hasher(),
0156 key_equal const& pred = key_equal(),
0157 allocator_type const& a = allocator_type())
0158 : unordered_flat_map(ilist.begin(), ilist.end(), n, h, pred, a)
0159 {
0160 }
0161
0162 unordered_flat_map(
0163 std::initializer_list<value_type> il, allocator_type const& a)
0164 : unordered_flat_map(il, size_type(0), hasher(), key_equal(), a)
0165 {
0166 }
0167
0168 unordered_flat_map(std::initializer_list<value_type> init, size_type n,
0169 allocator_type const& a)
0170 : unordered_flat_map(init, n, hasher(), key_equal(), a)
0171 {
0172 }
0173
0174 unordered_flat_map(std::initializer_list<value_type> init, size_type n,
0175 hasher const& h, allocator_type const& a)
0176 : unordered_flat_map(init, n, h, key_equal(), a)
0177 {
0178 }
0179
0180 unordered_flat_map(
0181 concurrent_flat_map<Key, T, Hash, KeyEqual, Allocator>&& other)
0182 : table_(std::move(other.table_))
0183 {
0184 }
0185
0186 ~unordered_flat_map() = default;
0187
0188 unordered_flat_map& operator=(unordered_flat_map const& other)
0189 {
0190 table_ = other.table_;
0191 return *this;
0192 }
0193
0194 unordered_flat_map& operator=(unordered_flat_map&& other) noexcept(
0195 noexcept(std::declval<table_type&>() = std::declval<table_type&&>()))
0196 {
0197 table_ = std::move(other.table_);
0198 return *this;
0199 }
0200
0201 allocator_type get_allocator() const noexcept
0202 {
0203 return table_.get_allocator();
0204 }
0205
0206
0207
0208
0209 iterator begin() noexcept { return table_.begin(); }
0210 const_iterator begin() const noexcept { return table_.begin(); }
0211 const_iterator cbegin() const noexcept { return table_.cbegin(); }
0212
0213 iterator end() noexcept { return table_.end(); }
0214 const_iterator end() const noexcept { return table_.end(); }
0215 const_iterator cend() const noexcept { return table_.cend(); }
0216
0217
0218
0219
0220 BOOST_ATTRIBUTE_NODISCARD bool empty() const noexcept
0221 {
0222 return table_.empty();
0223 }
0224
0225 size_type size() const noexcept { return table_.size(); }
0226
0227 size_type max_size() const noexcept { return table_.max_size(); }
0228
0229
0230
0231
0232 void clear() noexcept { table_.clear(); }
0233
0234 template <class Ty>
0235 BOOST_FORCEINLINE auto insert(Ty&& value)
0236 -> decltype(table_.insert(std::forward<Ty>(value)))
0237 {
0238 return table_.insert(std::forward<Ty>(value));
0239 }
0240
0241 BOOST_FORCEINLINE std::pair<iterator, bool> insert(init_type&& value)
0242 {
0243 return table_.insert(std::move(value));
0244 }
0245
0246 template <class Ty>
0247 BOOST_FORCEINLINE auto insert(const_iterator, Ty&& value)
0248 -> decltype(table_.insert(std::forward<Ty>(value)).first)
0249 {
0250 return table_.insert(std::forward<Ty>(value)).first;
0251 }
0252
0253 BOOST_FORCEINLINE iterator insert(const_iterator, init_type&& value)
0254 {
0255 return table_.insert(std::move(value)).first;
0256 }
0257
0258 template <class InputIterator>
0259 BOOST_FORCEINLINE void insert(InputIterator first, InputIterator last)
0260 {
0261 for (auto pos = first; pos != last; ++pos) {
0262 table_.emplace(*pos);
0263 }
0264 }
0265
0266 void insert(std::initializer_list<value_type> ilist)
0267 {
0268 this->insert(ilist.begin(), ilist.end());
0269 }
0270
0271 template <class M>
0272 std::pair<iterator, bool> insert_or_assign(key_type const& key, M&& obj)
0273 {
0274 auto ibp = table_.try_emplace(key, std::forward<M>(obj));
0275 if (ibp.second) {
0276 return ibp;
0277 }
0278 ibp.first->second = std::forward<M>(obj);
0279 return ibp;
0280 }
0281
0282 template <class M>
0283 std::pair<iterator, bool> insert_or_assign(key_type&& key, M&& obj)
0284 {
0285 auto ibp = table_.try_emplace(std::move(key), std::forward<M>(obj));
0286 if (ibp.second) {
0287 return ibp;
0288 }
0289 ibp.first->second = std::forward<M>(obj);
0290 return ibp;
0291 }
0292
0293 template <class K, class M>
0294 typename std::enable_if<
0295 boost::unordered::detail::are_transparent<K, hasher, key_equal>::value,
0296 std::pair<iterator, bool> >::type
0297 insert_or_assign(K&& k, M&& obj)
0298 {
0299 auto ibp = table_.try_emplace(std::forward<K>(k), std::forward<M>(obj));
0300 if (ibp.second) {
0301 return ibp;
0302 }
0303 ibp.first->second = std::forward<M>(obj);
0304 return ibp;
0305 }
0306
0307 template <class M>
0308 iterator insert_or_assign(const_iterator, key_type const& key, M&& obj)
0309 {
0310 return this->insert_or_assign(key, std::forward<M>(obj)).first;
0311 }
0312
0313 template <class M>
0314 iterator insert_or_assign(const_iterator, key_type&& key, M&& obj)
0315 {
0316 return this->insert_or_assign(std::move(key), std::forward<M>(obj))
0317 .first;
0318 }
0319
0320 template <class K, class M>
0321 typename std::enable_if<
0322 boost::unordered::detail::are_transparent<K, hasher, key_equal>::value,
0323 iterator>::type
0324 insert_or_assign(const_iterator, K&& k, M&& obj)
0325 {
0326 return this->insert_or_assign(std::forward<K>(k), std::forward<M>(obj))
0327 .first;
0328 }
0329
0330 template <class... Args>
0331 BOOST_FORCEINLINE std::pair<iterator, bool> emplace(Args&&... args)
0332 {
0333 return table_.emplace(std::forward<Args>(args)...);
0334 }
0335
0336 template <class... Args>
0337 BOOST_FORCEINLINE iterator emplace_hint(const_iterator, Args&&... args)
0338 {
0339 return table_.emplace(std::forward<Args>(args)...).first;
0340 }
0341
0342 template <class... Args>
0343 BOOST_FORCEINLINE std::pair<iterator, bool> try_emplace(
0344 key_type const& key, Args&&... args)
0345 {
0346 return table_.try_emplace(key, std::forward<Args>(args)...);
0347 }
0348
0349 template <class... Args>
0350 BOOST_FORCEINLINE std::pair<iterator, bool> try_emplace(
0351 key_type&& key, Args&&... args)
0352 {
0353 return table_.try_emplace(std::move(key), std::forward<Args>(args)...);
0354 }
0355
0356 template <class K, class... Args>
0357 BOOST_FORCEINLINE typename std::enable_if<
0358 boost::unordered::detail::transparent_non_iterable<K,
0359 unordered_flat_map>::value,
0360 std::pair<iterator, bool> >::type
0361 try_emplace(K&& key, Args&&... args)
0362 {
0363 return table_.try_emplace(
0364 std::forward<K>(key), std::forward<Args>(args)...);
0365 }
0366
0367 template <class... Args>
0368 BOOST_FORCEINLINE iterator try_emplace(
0369 const_iterator, key_type const& key, Args&&... args)
0370 {
0371 return table_.try_emplace(key, std::forward<Args>(args)...).first;
0372 }
0373
0374 template <class... Args>
0375 BOOST_FORCEINLINE iterator try_emplace(
0376 const_iterator, key_type&& key, Args&&... args)
0377 {
0378 return table_.try_emplace(std::move(key), std::forward<Args>(args)...)
0379 .first;
0380 }
0381
0382 template <class K, class... Args>
0383 BOOST_FORCEINLINE typename std::enable_if<
0384 boost::unordered::detail::transparent_non_iterable<K,
0385 unordered_flat_map>::value,
0386 iterator>::type
0387 try_emplace(const_iterator, K&& key, Args&&... args)
0388 {
0389 return table_
0390 .try_emplace(std::forward<K>(key), std::forward<Args>(args)...)
0391 .first;
0392 }
0393
0394 BOOST_FORCEINLINE typename table_type::erase_return_type erase(
0395 iterator pos)
0396 {
0397 return table_.erase(pos);
0398 }
0399
0400 BOOST_FORCEINLINE typename table_type::erase_return_type erase(
0401 const_iterator pos)
0402 {
0403 return table_.erase(pos);
0404 }
0405
0406 iterator erase(const_iterator first, const_iterator last)
0407 {
0408 while (first != last) {
0409 this->erase(first++);
0410 }
0411 return iterator{detail::foa::const_iterator_cast_tag{}, last};
0412 }
0413
0414 BOOST_FORCEINLINE size_type erase(key_type const& key)
0415 {
0416 return table_.erase(key);
0417 }
0418
0419 template <class K>
0420 BOOST_FORCEINLINE typename std::enable_if<
0421 detail::transparent_non_iterable<K, unordered_flat_map>::value,
0422 size_type>::type
0423 erase(K const& key)
0424 {
0425 return table_.erase(key);
0426 }
0427
0428 void swap(unordered_flat_map& rhs) noexcept(
0429 noexcept(std::declval<table_type&>().swap(std::declval<table_type&>())))
0430 {
0431 table_.swap(rhs.table_);
0432 }
0433
0434 template <class H2, class P2>
0435 void merge(
0436 unordered_flat_map<key_type, mapped_type, H2, P2, allocator_type>&
0437 source)
0438 {
0439 table_.merge(source.table_);
0440 }
0441
0442 template <class H2, class P2>
0443 void merge(
0444 unordered_flat_map<key_type, mapped_type, H2, P2, allocator_type>&&
0445 source)
0446 {
0447 table_.merge(std::move(source.table_));
0448 }
0449
0450
0451
0452
0453 mapped_type& at(key_type const& key)
0454 {
0455 auto pos = table_.find(key);
0456 if (pos != table_.end()) {
0457 return pos->second;
0458 }
0459
0460
0461
0462 boost::throw_exception(
0463 std::out_of_range("key was not found in unordered_flat_map"));
0464 }
0465
0466 mapped_type const& at(key_type const& key) const
0467 {
0468 auto pos = table_.find(key);
0469 if (pos != table_.end()) {
0470 return pos->second;
0471 }
0472 boost::throw_exception(
0473 std::out_of_range("key was not found in unordered_flat_map"));
0474 }
0475
0476 template <class K>
0477 typename std::enable_if<
0478 boost::unordered::detail::are_transparent<K, hasher, key_equal>::value,
0479 mapped_type&>::type
0480 at(K&& key)
0481 {
0482 auto pos = table_.find(std::forward<K>(key));
0483 if (pos != table_.end()) {
0484 return pos->second;
0485 }
0486 boost::throw_exception(
0487 std::out_of_range("key was not found in unordered_flat_map"));
0488 }
0489
0490 template <class K>
0491 typename std::enable_if<
0492 boost::unordered::detail::are_transparent<K, hasher, key_equal>::value,
0493 mapped_type const&>::type
0494 at(K&& key) const
0495 {
0496 auto pos = table_.find(std::forward<K>(key));
0497 if (pos != table_.end()) {
0498 return pos->second;
0499 }
0500 boost::throw_exception(
0501 std::out_of_range("key was not found in unordered_flat_map"));
0502 }
0503
0504 BOOST_FORCEINLINE mapped_type& operator[](key_type const& key)
0505 {
0506 return table_.try_emplace(key).first->second;
0507 }
0508
0509 BOOST_FORCEINLINE mapped_type& operator[](key_type&& key)
0510 {
0511 return table_.try_emplace(std::move(key)).first->second;
0512 }
0513
0514 template <class K>
0515 typename std::enable_if<
0516 boost::unordered::detail::are_transparent<K, hasher, key_equal>::value,
0517 mapped_type&>::type
0518 operator[](K&& key)
0519 {
0520 return table_.try_emplace(std::forward<K>(key)).first->second;
0521 }
0522
0523 BOOST_FORCEINLINE size_type count(key_type const& key) const
0524 {
0525 auto pos = table_.find(key);
0526 return pos != table_.end() ? 1 : 0;
0527 }
0528
0529 template <class K>
0530 BOOST_FORCEINLINE typename std::enable_if<
0531 detail::are_transparent<K, hasher, key_equal>::value, size_type>::type
0532 count(K const& key) const
0533 {
0534 auto pos = table_.find(key);
0535 return pos != table_.end() ? 1 : 0;
0536 }
0537
0538 BOOST_FORCEINLINE iterator find(key_type const& key)
0539 {
0540 return table_.find(key);
0541 }
0542
0543 BOOST_FORCEINLINE const_iterator find(key_type const& key) const
0544 {
0545 return table_.find(key);
0546 }
0547
0548 template <class K>
0549 BOOST_FORCEINLINE typename std::enable_if<
0550 boost::unordered::detail::are_transparent<K, hasher, key_equal>::value,
0551 iterator>::type
0552 find(K const& key)
0553 {
0554 return table_.find(key);
0555 }
0556
0557 template <class K>
0558 BOOST_FORCEINLINE typename std::enable_if<
0559 boost::unordered::detail::are_transparent<K, hasher, key_equal>::value,
0560 const_iterator>::type
0561 find(K const& key) const
0562 {
0563 return table_.find(key);
0564 }
0565
0566 BOOST_FORCEINLINE bool contains(key_type const& key) const
0567 {
0568 return this->find(key) != this->end();
0569 }
0570
0571 template <class K>
0572 BOOST_FORCEINLINE typename std::enable_if<
0573 boost::unordered::detail::are_transparent<K, hasher, key_equal>::value,
0574 bool>::type
0575 contains(K const& key) const
0576 {
0577 return this->find(key) != this->end();
0578 }
0579
0580 std::pair<iterator, iterator> equal_range(key_type const& key)
0581 {
0582 auto pos = table_.find(key);
0583 if (pos == table_.end()) {
0584 return {pos, pos};
0585 }
0586
0587 auto next = pos;
0588 ++next;
0589 return {pos, next};
0590 }
0591
0592 std::pair<const_iterator, const_iterator> equal_range(
0593 key_type const& key) const
0594 {
0595 auto pos = table_.find(key);
0596 if (pos == table_.end()) {
0597 return {pos, pos};
0598 }
0599
0600 auto next = pos;
0601 ++next;
0602 return {pos, next};
0603 }
0604
0605 template <class K>
0606 typename std::enable_if<
0607 detail::are_transparent<K, hasher, key_equal>::value,
0608 std::pair<iterator, iterator> >::type
0609 equal_range(K const& key)
0610 {
0611 auto pos = table_.find(key);
0612 if (pos == table_.end()) {
0613 return {pos, pos};
0614 }
0615
0616 auto next = pos;
0617 ++next;
0618 return {pos, next};
0619 }
0620
0621 template <class K>
0622 typename std::enable_if<
0623 detail::are_transparent<K, hasher, key_equal>::value,
0624 std::pair<const_iterator, const_iterator> >::type
0625 equal_range(K const& key) const
0626 {
0627 auto pos = table_.find(key);
0628 if (pos == table_.end()) {
0629 return {pos, pos};
0630 }
0631
0632 auto next = pos;
0633 ++next;
0634 return {pos, next};
0635 }
0636
0637
0638
0639
0640 size_type bucket_count() const noexcept { return table_.capacity(); }
0641
0642 float load_factor() const noexcept { return table_.load_factor(); }
0643
0644 float max_load_factor() const noexcept
0645 {
0646 return table_.max_load_factor();
0647 }
0648
0649 void max_load_factor(float) {}
0650
0651 size_type max_load() const noexcept { return table_.max_load(); }
0652
0653 void rehash(size_type n) { table_.rehash(n); }
0654
0655 void reserve(size_type n) { table_.reserve(n); }
0656
0657
0658
0659
0660 hasher hash_function() const { return table_.hash_function(); }
0661
0662 key_equal key_eq() const { return table_.key_eq(); }
0663 };
0664
0665 template <class Key, class T, class Hash, class KeyEqual, class Allocator>
0666 bool operator==(
0667 unordered_flat_map<Key, T, Hash, KeyEqual, Allocator> const& lhs,
0668 unordered_flat_map<Key, T, Hash, KeyEqual, Allocator> const& rhs)
0669 {
0670 return lhs.table_ == rhs.table_;
0671 }
0672
0673 template <class Key, class T, class Hash, class KeyEqual, class Allocator>
0674 bool operator!=(
0675 unordered_flat_map<Key, T, Hash, KeyEqual, Allocator> const& lhs,
0676 unordered_flat_map<Key, T, Hash, KeyEqual, Allocator> const& rhs)
0677 {
0678 return !(lhs == rhs);
0679 }
0680
0681 template <class Key, class T, class Hash, class KeyEqual, class Allocator>
0682 void swap(unordered_flat_map<Key, T, Hash, KeyEqual, Allocator>& lhs,
0683 unordered_flat_map<Key, T, Hash, KeyEqual, Allocator>& rhs)
0684 noexcept(noexcept(lhs.swap(rhs)))
0685 {
0686 lhs.swap(rhs);
0687 }
0688
0689 template <class Key, class T, class Hash, class KeyEqual, class Allocator,
0690 class Pred>
0691 typename unordered_flat_map<Key, T, Hash, KeyEqual, Allocator>::size_type
0692 erase_if(
0693 unordered_flat_map<Key, T, Hash, KeyEqual, Allocator>& map, Pred pred)
0694 {
0695 return erase_if(map.table_, pred);
0696 }
0697
0698 template <class Archive, class Key, class T, class Hash, class KeyEqual,
0699 class Allocator>
0700 void serialize(Archive& ar,
0701 unordered_flat_map<Key, T, Hash, KeyEqual, Allocator>& map,
0702 unsigned int version)
0703 {
0704 detail::serialize_container(ar, map, version);
0705 }
0706
0707 #if defined(BOOST_MSVC)
0708 #pragma warning(pop)
0709 #endif
0710
0711 #if BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES
0712
0713 template <class InputIterator,
0714 class Hash =
0715 boost::hash<boost::unordered::detail::iter_key_t<InputIterator> >,
0716 class Pred =
0717 std::equal_to<boost::unordered::detail::iter_key_t<InputIterator> >,
0718 class Allocator = std::allocator<
0719 boost::unordered::detail::iter_to_alloc_t<InputIterator> >,
0720 class = std::enable_if_t<detail::is_input_iterator_v<InputIterator> >,
0721 class = std::enable_if_t<detail::is_hash_v<Hash> >,
0722 class = std::enable_if_t<detail::is_pred_v<Pred> >,
0723 class = std::enable_if_t<detail::is_allocator_v<Allocator> > >
0724 unordered_flat_map(InputIterator, InputIterator,
0725 std::size_t = boost::unordered::detail::foa::default_bucket_count,
0726 Hash = Hash(), Pred = Pred(), Allocator = Allocator())
0727 -> unordered_flat_map<boost::unordered::detail::iter_key_t<InputIterator>,
0728 boost::unordered::detail::iter_val_t<InputIterator>, Hash, Pred,
0729 Allocator>;
0730
0731 template <class Key, class T,
0732 class Hash = boost::hash<std::remove_const_t<Key> >,
0733 class Pred = std::equal_to<std::remove_const_t<Key> >,
0734 class Allocator = std::allocator<std::pair<const Key, T> >,
0735 class = std::enable_if_t<detail::is_hash_v<Hash> >,
0736 class = std::enable_if_t<detail::is_pred_v<Pred> >,
0737 class = std::enable_if_t<detail::is_allocator_v<Allocator> > >
0738 unordered_flat_map(std::initializer_list<std::pair<Key, T> >,
0739 std::size_t = boost::unordered::detail::foa::default_bucket_count,
0740 Hash = Hash(), Pred = Pred(), Allocator = Allocator())
0741 -> unordered_flat_map<std::remove_const_t<Key>, T, Hash, Pred,
0742 Allocator>;
0743
0744 template <class InputIterator, class Allocator,
0745 class = std::enable_if_t<detail::is_input_iterator_v<InputIterator> >,
0746 class = std::enable_if_t<detail::is_allocator_v<Allocator> > >
0747 unordered_flat_map(InputIterator, InputIterator, std::size_t, Allocator)
0748 -> unordered_flat_map<boost::unordered::detail::iter_key_t<InputIterator>,
0749 boost::unordered::detail::iter_val_t<InputIterator>,
0750 boost::hash<boost::unordered::detail::iter_key_t<InputIterator> >,
0751 std::equal_to<boost::unordered::detail::iter_key_t<InputIterator> >,
0752 Allocator>;
0753
0754 template <class InputIterator, class Allocator,
0755 class = std::enable_if_t<detail::is_input_iterator_v<InputIterator> >,
0756 class = std::enable_if_t<detail::is_allocator_v<Allocator> > >
0757 unordered_flat_map(InputIterator, InputIterator, Allocator)
0758 -> unordered_flat_map<boost::unordered::detail::iter_key_t<InputIterator>,
0759 boost::unordered::detail::iter_val_t<InputIterator>,
0760 boost::hash<boost::unordered::detail::iter_key_t<InputIterator> >,
0761 std::equal_to<boost::unordered::detail::iter_key_t<InputIterator> >,
0762 Allocator>;
0763
0764 template <class InputIterator, class Hash, class Allocator,
0765 class = std::enable_if_t<detail::is_hash_v<Hash> >,
0766 class = std::enable_if_t<detail::is_input_iterator_v<InputIterator> >,
0767 class = std::enable_if_t<detail::is_allocator_v<Allocator> > >
0768 unordered_flat_map(
0769 InputIterator, InputIterator, std::size_t, Hash, Allocator)
0770 -> unordered_flat_map<boost::unordered::detail::iter_key_t<InputIterator>,
0771 boost::unordered::detail::iter_val_t<InputIterator>, Hash,
0772 std::equal_to<boost::unordered::detail::iter_key_t<InputIterator> >,
0773 Allocator>;
0774
0775 template <class Key, class T, class Allocator,
0776 class = std::enable_if_t<detail::is_allocator_v<Allocator> > >
0777 unordered_flat_map(std::initializer_list<std::pair<Key, T> >, std::size_t,
0778 Allocator) -> unordered_flat_map<std::remove_const_t<Key>, T,
0779 boost::hash<std::remove_const_t<Key> >,
0780 std::equal_to<std::remove_const_t<Key> >, Allocator>;
0781
0782 template <class Key, class T, class Allocator,
0783 class = std::enable_if_t<detail::is_allocator_v<Allocator> > >
0784 unordered_flat_map(std::initializer_list<std::pair<Key, T> >, Allocator)
0785 -> unordered_flat_map<std::remove_const_t<Key>, T,
0786 boost::hash<std::remove_const_t<Key> >,
0787 std::equal_to<std::remove_const_t<Key> >, Allocator>;
0788
0789 template <class Key, class T, class Hash, class Allocator,
0790 class = std::enable_if_t<detail::is_hash_v<Hash> >,
0791 class = std::enable_if_t<detail::is_allocator_v<Allocator> > >
0792 unordered_flat_map(std::initializer_list<std::pair<Key, T> >, std::size_t,
0793 Hash, Allocator) -> unordered_flat_map<std::remove_const_t<Key>, T,
0794 Hash, std::equal_to<std::remove_const_t<Key> >, Allocator>;
0795 #endif
0796
0797 }
0798 }
0799
0800 #endif