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