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