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