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