Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/intrusive/hashtable.hpp @ 101:c530137014c0
Update Boost headers (1.58.0)
author | Chris Cannam |
---|---|
date | Mon, 07 Sep 2015 11:12:49 +0100 |
parents | 2665513ce2d3 |
children |
comparison
equal
deleted
inserted
replaced
100:793467b5e61c | 101:c530137014c0 |
---|---|
11 ///////////////////////////////////////////////////////////////////////////// | 11 ///////////////////////////////////////////////////////////////////////////// |
12 #ifndef BOOST_INTRUSIVE_HASHTABLE_HPP | 12 #ifndef BOOST_INTRUSIVE_HASHTABLE_HPP |
13 #define BOOST_INTRUSIVE_HASHTABLE_HPP | 13 #define BOOST_INTRUSIVE_HASHTABLE_HPP |
14 | 14 |
15 #include <boost/intrusive/detail/config_begin.hpp> | 15 #include <boost/intrusive/detail/config_begin.hpp> |
16 //std C++ | 16 #include <boost/intrusive/intrusive_fwd.hpp> |
17 #include <functional> //std::equal_to | 17 |
18 #include <utility> //std::pair | |
19 #include <algorithm> //std::swap, std::lower_bound, std::upper_bound | |
20 #include <cstddef> //std::size_t | |
21 //boost | |
22 #include <boost/intrusive/detail/assert.hpp> | |
23 #include <boost/static_assert.hpp> | |
24 #include <boost/functional/hash.hpp> | |
25 #include <boost/pointer_cast.hpp> | |
26 //General intrusive utilities | 18 //General intrusive utilities |
27 #include <boost/intrusive/intrusive_fwd.hpp> | |
28 #include <boost/intrusive/detail/hashtable_node.hpp> | 19 #include <boost/intrusive/detail/hashtable_node.hpp> |
29 #include <boost/intrusive/detail/transform_iterator.hpp> | 20 #include <boost/intrusive/detail/transform_iterator.hpp> |
30 #include <boost/intrusive/link_mode.hpp> | 21 #include <boost/intrusive/link_mode.hpp> |
31 #include <boost/intrusive/detail/ebo_functor_holder.hpp> | 22 #include <boost/intrusive/detail/ebo_functor_holder.hpp> |
32 #include <boost/intrusive/detail/clear_on_destructor_base.hpp> | 23 #include <boost/intrusive/detail/is_stateful_value_traits.hpp> |
33 #include <boost/intrusive/detail/utilities.hpp> | 24 #include <boost/intrusive/detail/node_to_value.hpp> |
25 #include <boost/intrusive/detail/exception_disposer.hpp> | |
26 #include <boost/intrusive/detail/node_cloner_disposer.hpp> | |
27 #include <boost/intrusive/detail/simple_disposers.hpp> | |
28 #include <boost/intrusive/detail/size_holder.hpp> | |
29 | |
34 //Implementation utilities | 30 //Implementation utilities |
35 #include <boost/intrusive/unordered_set_hook.hpp> | 31 #include <boost/intrusive/unordered_set_hook.hpp> |
36 #include <boost/intrusive/slist.hpp> | 32 #include <boost/intrusive/slist.hpp> |
37 #include <boost/intrusive/pointer_traits.hpp> | 33 #include <boost/intrusive/pointer_traits.hpp> |
38 #include <boost/intrusive/detail/mpl.hpp> | 34 #include <boost/intrusive/detail/mpl.hpp> |
39 #include <boost/move/move.hpp> | 35 |
36 //boost | |
37 #include <boost/functional/hash.hpp> | |
38 #include <boost/intrusive/detail/assert.hpp> | |
39 #include <boost/static_assert.hpp> | |
40 #include <boost/move/utility_core.hpp> | |
41 #include <boost/move/adl_move_swap.hpp> | |
42 | |
43 //std C++ | |
44 #include <boost/intrusive/detail/minimal_less_equal_header.hpp> //std::equal_to | |
45 #include <boost/intrusive/detail/minimal_pair_header.hpp> //std::pair | |
46 #include <algorithm> //std::lower_bound, std::upper_bound | |
47 #include <cstddef> //std::size_t | |
48 | |
49 #if defined(BOOST_HAS_PRAGMA_ONCE) | |
50 # pragma once | |
51 #endif | |
40 | 52 |
41 namespace boost { | 53 namespace boost { |
42 namespace intrusive { | 54 namespace intrusive { |
43 | 55 |
44 /// @cond | 56 /// @cond |
57 | |
58 template<int Dummy = 0> | |
59 struct prime_list_holder | |
60 { | |
61 static const std::size_t prime_list[]; | |
62 static const std::size_t prime_list_size; | |
63 }; | |
64 | |
65 //We only support LLP64(Win64) or LP64(most Unix) data models | |
66 #ifdef _WIN64 //In 64 bit windows sizeof(size_t) == sizeof(unsigned long long) | |
67 #define BOOST_INTRUSIVE_PRIME_C(NUMBER) NUMBER##ULL | |
68 #define BOOST_INTRUSIVE_64_BIT_SIZE_T 1 | |
69 #else //In 32 bit windows and 32/64 bit unixes sizeof(size_t) == sizeof(unsigned long) | |
70 #define BOOST_INTRUSIVE_PRIME_C(NUMBER) NUMBER##UL | |
71 #define BOOST_INTRUSIVE_64_BIT_SIZE_T (((((ULONG_MAX>>16)>>16)>>16)>>15) != 0) | |
72 #endif | |
73 | |
74 template<int Dummy> | |
75 const std::size_t prime_list_holder<Dummy>::prime_list[] = { | |
76 BOOST_INTRUSIVE_PRIME_C(3), BOOST_INTRUSIVE_PRIME_C(7), | |
77 BOOST_INTRUSIVE_PRIME_C(11), BOOST_INTRUSIVE_PRIME_C(17), | |
78 BOOST_INTRUSIVE_PRIME_C(29), BOOST_INTRUSIVE_PRIME_C(53), | |
79 BOOST_INTRUSIVE_PRIME_C(97), BOOST_INTRUSIVE_PRIME_C(193), | |
80 BOOST_INTRUSIVE_PRIME_C(389), BOOST_INTRUSIVE_PRIME_C(769), | |
81 BOOST_INTRUSIVE_PRIME_C(1543), BOOST_INTRUSIVE_PRIME_C(3079), | |
82 BOOST_INTRUSIVE_PRIME_C(6151), BOOST_INTRUSIVE_PRIME_C(12289), | |
83 BOOST_INTRUSIVE_PRIME_C(24593), BOOST_INTRUSIVE_PRIME_C(49157), | |
84 BOOST_INTRUSIVE_PRIME_C(98317), BOOST_INTRUSIVE_PRIME_C(196613), | |
85 BOOST_INTRUSIVE_PRIME_C(393241), BOOST_INTRUSIVE_PRIME_C(786433), | |
86 BOOST_INTRUSIVE_PRIME_C(1572869), BOOST_INTRUSIVE_PRIME_C(3145739), | |
87 BOOST_INTRUSIVE_PRIME_C(6291469), BOOST_INTRUSIVE_PRIME_C(12582917), | |
88 BOOST_INTRUSIVE_PRIME_C(25165843), BOOST_INTRUSIVE_PRIME_C(50331653), | |
89 BOOST_INTRUSIVE_PRIME_C(100663319), BOOST_INTRUSIVE_PRIME_C(201326611), | |
90 BOOST_INTRUSIVE_PRIME_C(402653189), BOOST_INTRUSIVE_PRIME_C(805306457), | |
91 BOOST_INTRUSIVE_PRIME_C(1610612741), BOOST_INTRUSIVE_PRIME_C(3221225473), | |
92 #if BOOST_INTRUSIVE_64_BIT_SIZE_T | |
93 //Taken from Boost.MultiIndex code, thanks to Joaquin M Lopez Munoz. | |
94 BOOST_INTRUSIVE_PRIME_C(6442450939), BOOST_INTRUSIVE_PRIME_C(12884901893), | |
95 BOOST_INTRUSIVE_PRIME_C(25769803751), BOOST_INTRUSIVE_PRIME_C(51539607551), | |
96 BOOST_INTRUSIVE_PRIME_C(103079215111), BOOST_INTRUSIVE_PRIME_C(206158430209), | |
97 BOOST_INTRUSIVE_PRIME_C(412316860441), BOOST_INTRUSIVE_PRIME_C(824633720831), | |
98 BOOST_INTRUSIVE_PRIME_C(1649267441651), BOOST_INTRUSIVE_PRIME_C(3298534883309), | |
99 BOOST_INTRUSIVE_PRIME_C(6597069766657), BOOST_INTRUSIVE_PRIME_C(13194139533299), | |
100 BOOST_INTRUSIVE_PRIME_C(26388279066623), BOOST_INTRUSIVE_PRIME_C(52776558133303), | |
101 BOOST_INTRUSIVE_PRIME_C(105553116266489), BOOST_INTRUSIVE_PRIME_C(211106232532969), | |
102 BOOST_INTRUSIVE_PRIME_C(422212465066001), BOOST_INTRUSIVE_PRIME_C(844424930131963), | |
103 BOOST_INTRUSIVE_PRIME_C(1688849860263953), BOOST_INTRUSIVE_PRIME_C(3377699720527861), | |
104 BOOST_INTRUSIVE_PRIME_C(6755399441055731), BOOST_INTRUSIVE_PRIME_C(13510798882111483), | |
105 BOOST_INTRUSIVE_PRIME_C(27021597764222939), BOOST_INTRUSIVE_PRIME_C(54043195528445957), | |
106 BOOST_INTRUSIVE_PRIME_C(108086391056891903), BOOST_INTRUSIVE_PRIME_C(216172782113783843), | |
107 BOOST_INTRUSIVE_PRIME_C(432345564227567621), BOOST_INTRUSIVE_PRIME_C(864691128455135207), | |
108 BOOST_INTRUSIVE_PRIME_C(1729382256910270481), BOOST_INTRUSIVE_PRIME_C(3458764513820540933), | |
109 BOOST_INTRUSIVE_PRIME_C(6917529027641081903), BOOST_INTRUSIVE_PRIME_C(13835058055282163729), | |
110 BOOST_INTRUSIVE_PRIME_C(18446744073709551557) | |
111 #else | |
112 BOOST_INTRUSIVE_PRIME_C(4294967291) | |
113 #endif | |
114 }; | |
115 | |
116 #undef BOOST_INTRUSIVE_PRIME_C | |
117 #undef BOOST_INTRUSIVE_64_BIT_SIZE_T | |
118 | |
119 template<int Dummy> | |
120 const std::size_t prime_list_holder<Dummy>::prime_list_size | |
121 = sizeof(prime_list)/sizeof(std::size_t); | |
45 | 122 |
46 struct hash_bool_flags | 123 struct hash_bool_flags |
47 { | 124 { |
48 static const std::size_t unique_keys_pos = 1u; | 125 static const std::size_t unique_keys_pos = 1u; |
49 static const std::size_t constant_time_size_pos = 2u; | 126 static const std::size_t constant_time_size_pos = 2u; |
56 namespace detail { | 133 namespace detail { |
57 | 134 |
58 template<class SupposedValueTraits> | 135 template<class SupposedValueTraits> |
59 struct get_slist_impl_from_supposed_value_traits | 136 struct get_slist_impl_from_supposed_value_traits |
60 { | 137 { |
61 typedef typename detail::get_real_value_traits | 138 typedef SupposedValueTraits value_traits; |
62 <SupposedValueTraits>::type real_value_traits; | |
63 typedef typename detail::get_node_traits | 139 typedef typename detail::get_node_traits |
64 <real_value_traits>::type node_traits; | 140 <value_traits>::type node_traits; |
65 typedef typename get_slist_impl | 141 typedef typename get_slist_impl |
66 <typename reduced_slist_node_traits | 142 <typename reduced_slist_node_traits |
67 <node_traits>::type | 143 <node_traits>::type |
68 >::type type; | 144 >::type type; |
69 }; | 145 }; |
254 { | 330 { |
255 if(first_in_group){ | 331 if(first_in_group){ |
256 if(group_algorithms::unique(first_in_group)) | 332 if(group_algorithms::unique(first_in_group)) |
257 group_algorithms::link_after(first_in_group, n); | 333 group_algorithms::link_after(first_in_group, n); |
258 else{ | 334 else{ |
259 group_algorithms::link_after(group_algorithms::node_traits::get_next(first_in_group), n); | 335 group_algorithms::link_after(node_traits::get_next(first_in_group), n); |
260 } | 336 } |
261 } | 337 } |
262 else{ | 338 else{ |
263 group_algorithms::init_header(n); | 339 group_algorithms::init_header(n); |
264 } | 340 } |
273 slist_node_ptr prev; | 349 slist_node_ptr prev; |
274 node_ptr elem(detail::dcast_bucket_ptr<node>(i)); | 350 node_ptr elem(detail::dcast_bucket_ptr<node>(i)); |
275 | 351 |
276 //It's the last in group if the next_node is a bucket | 352 //It's the last in group if the next_node is a bucket |
277 slist_node_ptr nxt(node_traits::get_next(elem)); | 353 slist_node_ptr nxt(node_traits::get_next(elem)); |
278 bool last_in_group = (first_end_ptr <= nxt && nxt <= last_end_ptr)/* || | 354 bool last_in_group = (first_end_ptr <= nxt && nxt <= last_end_ptr) || |
279 (group_traits::get_next(nxt) != elem)*/; | 355 (group_traits::get_next(detail::dcast_bucket_ptr<node>(nxt)) != elem); |
280 //It's the first in group if group_previous's next_node is not | 356 //It's the first in group if group_previous's next_node is not |
281 //itself, as group list does not link bucket | 357 //itself, as group list does not link bucket |
282 node_ptr prev_in_group(group_traits::get_next(elem)); | 358 node_ptr prev_in_group(group_traits::get_next(elem)); |
283 bool first_in_group = node_traits::get_next(prev_in_group) != elem; | 359 bool first_in_group = node_traits::get_next(prev_in_group) != elem; |
284 | 360 |
389 //!a hash container. | 465 //!a hash container. |
390 template<class ValueTraitsOrHookOption> | 466 template<class ValueTraitsOrHookOption> |
391 struct unordered_bucket | 467 struct unordered_bucket |
392 : public detail::unordered_bucket_impl | 468 : public detail::unordered_bucket_impl |
393 <typename ValueTraitsOrHookOption:: | 469 <typename ValueTraitsOrHookOption:: |
394 template pack<none>::proto_value_traits | 470 template pack<empty>::proto_value_traits |
395 > | 471 > |
396 {}; | 472 {}; |
397 | 473 |
398 //!This metafunction will obtain the type of a bucket pointer | 474 //!This metafunction will obtain the type of a bucket pointer |
399 //!from the value_traits or hook option to be used with | 475 //!from the value_traits or hook option to be used with |
400 //!a hash container. | 476 //!a hash container. |
401 template<class ValueTraitsOrHookOption> | 477 template<class ValueTraitsOrHookOption> |
402 struct unordered_bucket_ptr | 478 struct unordered_bucket_ptr |
403 : public detail::unordered_bucket_ptr_impl | 479 : public detail::unordered_bucket_ptr_impl |
404 <typename ValueTraitsOrHookOption:: | 480 <typename ValueTraitsOrHookOption:: |
405 template pack<none>::proto_value_traits | 481 template pack<empty>::proto_value_traits |
406 > | 482 > |
407 {}; | 483 {}; |
408 | 484 |
409 //!This metafunction will obtain the type of the default bucket traits | 485 //!This metafunction will obtain the type of the default bucket traits |
410 //!(when the user does not specify the bucket_traits<> option) from the | 486 //!(when the user does not specify the bucket_traits<> option) from the |
411 //!value_traits or hook option to be used with | 487 //!value_traits or hook option to be used with |
412 //!a hash container. | 488 //!a hash container. |
413 template<class ValueTraitsOrHookOption> | 489 template<class ValueTraitsOrHookOption> |
414 struct unordered_default_bucket_traits | 490 struct unordered_default_bucket_traits |
415 { | 491 { |
416 typedef typename ValueTraitsOrHookOption:: | 492 typedef typename ValueTraitsOrHookOption:: |
417 template pack<none>::proto_value_traits supposed_value_traits; | 493 template pack<empty>::proto_value_traits supposed_value_traits; |
418 typedef typename detail:: | 494 typedef typename detail:: |
419 get_slist_impl_from_supposed_value_traits | 495 get_slist_impl_from_supposed_value_traits |
420 <supposed_value_traits>::type slist_impl; | 496 <supposed_value_traits>::type slist_impl; |
421 typedef detail::bucket_traits_impl | 497 typedef detail::bucket_traits_impl |
422 <slist_impl> implementation_defined; | 498 <slist_impl> implementation_defined; |
423 typedef implementation_defined type; | 499 typedef implementation_defined type; |
424 }; | 500 }; |
425 | 501 |
426 struct default_bucket_traits; | 502 struct default_bucket_traits; |
427 | 503 |
504 //hashtable default hook traits | |
505 struct default_hashtable_hook_applier | |
506 { template <class T> struct apply{ typedef typename T::default_hashtable_hook type; }; }; | |
507 | |
508 template<> | |
509 struct is_default_hook_tag<default_hashtable_hook_applier> | |
510 { static const bool value = true; }; | |
511 | |
428 struct hashtable_defaults | 512 struct hashtable_defaults |
429 { | 513 { |
430 typedef detail::default_hashtable_hook proto_value_traits; | 514 typedef default_hashtable_hook_applier proto_value_traits; |
431 typedef std::size_t size_type; | 515 typedef std::size_t size_type; |
432 typedef void equal; | 516 typedef void equal; |
433 typedef void hash; | 517 typedef void hash; |
434 typedef default_bucket_traits bucket_traits; | 518 typedef default_bucket_traits bucket_traits; |
435 static const bool constant_time_size = true; | 519 static const bool constant_time_size = true; |
437 static const bool cache_begin = false; | 521 static const bool cache_begin = false; |
438 static const bool compare_hash = false; | 522 static const bool compare_hash = false; |
439 static const bool incremental = false; | 523 static const bool incremental = false; |
440 }; | 524 }; |
441 | 525 |
442 template<class RealValueTraits, bool IsConst> | 526 template<class ValueTraits, bool IsConst> |
443 struct downcast_node_to_value_t | 527 struct downcast_node_to_value_t |
444 : public detail::node_to_value<RealValueTraits, IsConst> | 528 : public detail::node_to_value<ValueTraits, IsConst> |
445 { | 529 { |
446 typedef detail::node_to_value<RealValueTraits, IsConst> base_t; | 530 typedef detail::node_to_value<ValueTraits, IsConst> base_t; |
447 typedef typename base_t::result_type result_type; | 531 typedef typename base_t::result_type result_type; |
448 typedef RealValueTraits real_value_traits; | 532 typedef ValueTraits value_traits; |
449 typedef typename detail::get_slist_impl | 533 typedef typename detail::get_slist_impl |
450 <typename detail::reduced_slist_node_traits | 534 <typename detail::reduced_slist_node_traits |
451 <typename real_value_traits::node_traits>::type | 535 <typename value_traits::node_traits>::type |
452 >::type slist_impl; | 536 >::type slist_impl; |
453 typedef typename detail::add_const_if_c | 537 typedef typename detail::add_const_if_c |
454 <typename slist_impl::node, IsConst>::type & first_argument_type; | 538 <typename slist_impl::node, IsConst>::type & first_argument_type; |
455 typedef typename detail::add_const_if_c | 539 typedef typename detail::add_const_if_c |
456 < typename RealValueTraits::node_traits::node | 540 < typename ValueTraits::node_traits::node |
457 , IsConst>::type & intermediate_argument_type; | 541 , IsConst>::type & intermediate_argument_type; |
458 typedef typename pointer_traits | 542 typedef typename pointer_traits |
459 <typename RealValueTraits::pointer>:: | 543 <typename ValueTraits::pointer>:: |
460 template rebind_pointer | 544 template rebind_pointer |
461 <const RealValueTraits>::type const_real_value_traits_ptr; | 545 <const ValueTraits>::type const_value_traits_ptr; |
462 | 546 |
463 downcast_node_to_value_t(const const_real_value_traits_ptr &ptr) | 547 downcast_node_to_value_t(const const_value_traits_ptr &ptr) |
464 : base_t(ptr) | 548 : base_t(ptr) |
465 {} | 549 {} |
466 | 550 |
467 result_type operator()(first_argument_type arg) const | 551 result_type operator()(first_argument_type arg) const |
468 { return this->base_t::operator()(static_cast<intermediate_argument_type>(arg)); } | 552 { return this->base_t::operator()(static_cast<intermediate_argument_type>(arg)); } |
469 }; | 553 }; |
470 | 554 |
471 template<class F, class SlistNodePtr, class NodePtr> | 555 template<class F, class SlistNodePtr, class NodePtr> |
472 struct node_cast_adaptor | 556 struct node_cast_adaptor |
473 : private detail::ebo_functor_holder<F> | 557 //Use public inheritance to avoid MSVC bugs with closures |
558 : public detail::ebo_functor_holder<F> | |
474 { | 559 { |
475 typedef detail::ebo_functor_holder<F> base_t; | 560 typedef detail::ebo_functor_holder<F> base_t; |
476 | 561 |
477 typedef typename pointer_traits<SlistNodePtr>::element_type slist_node; | 562 typedef typename pointer_traits<SlistNodePtr>::element_type slist_node; |
478 typedef typename pointer_traits<NodePtr>::element_type node; | 563 typedef typename pointer_traits<NodePtr>::element_type node; |
495 ( hash_bool_flags::cache_begin_pos | 580 ( hash_bool_flags::cache_begin_pos |
496 | hash_bool_flags::constant_time_size_pos | 581 | hash_bool_flags::constant_time_size_pos |
497 | hash_bool_flags::incremental_pos | 582 | hash_bool_flags::incremental_pos |
498 ); | 583 ); |
499 | 584 |
585 //bucket_plus_vtraits stores ValueTraits + BucketTraits | |
586 //this data is needed by iterators to obtain the | |
587 //value from the iterator and detect the bucket | |
500 template<class ValueTraits, class BucketTraits> | 588 template<class ValueTraits, class BucketTraits> |
501 struct bucket_plus_vtraits : public ValueTraits | 589 struct bucket_plus_vtraits : public ValueTraits |
502 { | 590 { |
503 typedef BucketTraits bucket_traits; | 591 typedef BucketTraits bucket_traits; |
504 typedef ValueTraits value_traits; | 592 typedef ValueTraits value_traits; |
505 | 593 |
506 static const bool external_value_traits = | 594 static const bool safemode_or_autounlink = is_safe_autounlink<value_traits::link_mode>::value; |
507 detail::external_value_traits_bool_is_true<ValueTraits>::value; | 595 |
508 | |
509 static const bool external_bucket_traits = | |
510 detail::external_bucket_traits_bool_is_true<bucket_traits>::value; | |
511 | |
512 typedef typename detail::get_real_value_traits<ValueTraits>::type real_value_traits; | |
513 | |
514 static const bool safemode_or_autounlink = is_safe_autounlink<real_value_traits::link_mode>::value; | |
515 | |
516 typedef typename detail::eval_if_c | |
517 < external_bucket_traits | |
518 , detail::eval_bucket_traits<bucket_traits> | |
519 , detail::identity<bucket_traits> | |
520 >::type real_bucket_traits; | |
521 typedef typename | 596 typedef typename |
522 detail::get_slist_impl_from_supposed_value_traits | 597 detail::get_slist_impl_from_supposed_value_traits |
523 <real_value_traits>::type slist_impl; | 598 <value_traits>::type slist_impl; |
599 typedef typename value_traits::node_traits node_traits; | |
600 typedef unordered_group_adapter<node_traits> group_traits; | |
601 typedef typename slist_impl::iterator siterator; | |
602 typedef typename slist_impl::size_type size_type; | |
603 typedef detail::bucket_impl<slist_impl> bucket_type; | |
604 typedef detail::group_functions<node_traits> group_functions_t; | |
605 typedef typename slist_impl::node_algorithms node_algorithms; | |
606 typedef typename slist_impl::node_ptr slist_node_ptr; | |
607 typedef typename node_traits::node_ptr node_ptr; | |
608 typedef typename node_traits::node node; | |
609 typedef typename value_traits::value_type value_type; | |
610 typedef circular_slist_algorithms<group_traits> group_algorithms; | |
611 typedef typename pointer_traits | |
612 <typename value_traits::pointer>:: | |
613 template rebind_pointer | |
614 <const value_traits>::type const_value_traits_ptr; | |
615 typedef typename pointer_traits | |
616 <typename value_traits::pointer>:: | |
617 template rebind_pointer | |
618 <const bucket_plus_vtraits>::type const_bucket_value_traits_ptr; | |
619 typedef typename detail::unordered_bucket_ptr_impl | |
620 <value_traits>::type bucket_ptr; | |
621 typedef detail::bool_<detail::optimize_multikey_is_true | |
622 <node_traits>::value> optimize_multikey_t; | |
524 | 623 |
525 template<class BucketTraitsType> | 624 template<class BucketTraitsType> |
526 bucket_plus_vtraits(const ValueTraits &val_traits, BOOST_FWD_REF(BucketTraitsType) b_traits) | 625 bucket_plus_vtraits(const ValueTraits &val_traits, BOOST_FWD_REF(BucketTraitsType) b_traits) |
527 : ValueTraits(val_traits), bucket_traits_(::boost::forward<BucketTraitsType>(b_traits)) | 626 : ValueTraits(val_traits), bucket_traits_(::boost::forward<BucketTraitsType>(b_traits)) |
528 {} | 627 {} |
529 | 628 |
530 bucket_plus_vtraits & operator =(const bucket_plus_vtraits &x) | 629 bucket_plus_vtraits & operator =(const bucket_plus_vtraits &x) |
531 { | 630 { bucket_traits_ = x.bucket_traits_; return *this; } |
532 bucket_traits_ = x.bucket_traits_; | 631 |
533 return *this; | 632 const_value_traits_ptr priv_value_traits_ptr() const |
534 } | 633 { return pointer_traits<const_value_traits_ptr>::pointer_to(this->priv_value_traits()); } |
535 | |
536 //real_value_traits | |
537 // | |
538 const real_value_traits &priv_real_value_traits(detail::false_) const | |
539 { return *this; } | |
540 | |
541 const real_value_traits &priv_real_value_traits(detail::true_) const | |
542 { return this->get_value_traits(*this); } | |
543 | |
544 real_value_traits &priv_real_value_traits(detail::false_) | |
545 { return *this; } | |
546 | |
547 real_value_traits &priv_real_value_traits(detail::true_) | |
548 { return this->get_value_traits(*this); } | |
549 | |
550 const real_value_traits &priv_real_value_traits() const | |
551 { return this->priv_real_value_traits(detail::bool_<external_value_traits>()); } | |
552 | |
553 real_value_traits &priv_real_value_traits() | |
554 { return this->priv_real_value_traits(detail::bool_<external_value_traits>()); } | |
555 | |
556 typedef typename pointer_traits<typename real_value_traits::pointer>:: | |
557 template rebind_pointer<const real_value_traits>::type const_real_value_traits_ptr; | |
558 | |
559 const_real_value_traits_ptr real_value_traits_ptr() const | |
560 { return pointer_traits<const_real_value_traits_ptr>::pointer_to(this->priv_real_value_traits()); } | |
561 | |
562 //real_bucket_traits | |
563 // | |
564 const real_bucket_traits &priv_real_bucket_traits(detail::false_) const | |
565 { return this->bucket_traits_; } | |
566 | |
567 const real_bucket_traits &priv_real_bucket_traits(detail::true_) const | |
568 { return this->bucket_traits_.get_bucket_traits(*this); } | |
569 | |
570 real_bucket_traits &priv_real_bucket_traits(detail::false_) | |
571 { return bucket_traits_; } | |
572 | |
573 real_bucket_traits &priv_real_bucket_traits(detail::true_) | |
574 { return this->get_bucket_traits(*this); } | |
575 | |
576 const real_bucket_traits &priv_real_bucket_traits() const | |
577 { return this->priv_real_bucket_traits(detail::bool_<external_bucket_traits>()); } | |
578 | |
579 real_bucket_traits &priv_real_bucket_traits() | |
580 { return this->priv_real_bucket_traits(detail::bool_<external_bucket_traits>()); } | |
581 | 634 |
582 //bucket_value_traits | 635 //bucket_value_traits |
583 // | 636 // |
584 const bucket_plus_vtraits &get_bucket_value_traits() const | 637 const bucket_plus_vtraits &get_bucket_value_traits() const |
585 { return *this; } | 638 { return *this; } |
586 | 639 |
587 bucket_plus_vtraits &get_bucket_value_traits() | 640 bucket_plus_vtraits &get_bucket_value_traits() |
588 { return *this; } | 641 { return *this; } |
589 | 642 |
590 typedef typename pointer_traits<typename real_value_traits::pointer>:: | |
591 template rebind_pointer<const bucket_plus_vtraits>::type const_bucket_value_traits_ptr; | |
592 | |
593 const_bucket_value_traits_ptr bucket_value_traits_ptr() const | 643 const_bucket_value_traits_ptr bucket_value_traits_ptr() const |
594 { return pointer_traits<const_bucket_value_traits_ptr>::pointer_to(this->get_bucket_value_traits()); } | 644 { return pointer_traits<const_bucket_value_traits_ptr>::pointer_to(this->get_bucket_value_traits()); } |
595 | 645 |
596 //value traits | 646 //value traits |
597 // | 647 // |
607 { return this->bucket_traits_; } | 657 { return this->bucket_traits_; } |
608 | 658 |
609 bucket_traits &priv_bucket_traits() | 659 bucket_traits &priv_bucket_traits() |
610 { return this->bucket_traits_; } | 660 { return this->bucket_traits_; } |
611 | 661 |
612 //operations | 662 //bucket operations |
613 typedef typename detail::unordered_bucket_ptr_impl<real_value_traits>::type bucket_ptr; | |
614 | |
615 bucket_ptr priv_bucket_pointer() const | 663 bucket_ptr priv_bucket_pointer() const |
616 { return this->priv_real_bucket_traits().bucket_begin(); } | 664 { return this->priv_bucket_traits().bucket_begin(); } |
617 | 665 |
618 typename slist_impl::size_type priv_bucket_count() const | 666 typename slist_impl::size_type priv_bucket_count() const |
619 { return this->priv_real_bucket_traits().bucket_count(); } | 667 { return this->priv_bucket_traits().bucket_count(); } |
620 | 668 |
621 bucket_ptr priv_invalid_bucket() const | 669 bucket_ptr priv_invalid_bucket() const |
622 { | 670 { |
623 const real_bucket_traits &rbt = this->priv_real_bucket_traits(); | 671 const bucket_traits &rbt = this->priv_bucket_traits(); |
624 return rbt.bucket_begin() + rbt.bucket_count(); | 672 return rbt.bucket_begin() + rbt.bucket_count(); |
625 } | 673 } |
626 | |
627 typedef typename real_value_traits::node_traits node_traits; | |
628 typedef unordered_group_adapter<node_traits> group_traits; | |
629 typedef typename slist_impl::iterator siterator; | |
630 typedef typename slist_impl::size_type size_type; | |
631 typedef detail::bucket_impl<slist_impl> bucket_type; | |
632 typedef detail::group_functions<node_traits> group_functions_t; | |
633 typedef typename slist_impl::node_algorithms node_algorithms; | |
634 typedef typename slist_impl::node_ptr slist_node_ptr; | |
635 typedef typename node_traits::node_ptr node_ptr; | |
636 typedef typename node_traits::node node; | |
637 typedef typename real_value_traits::value_type value_type; | |
638 typedef circular_slist_algorithms<group_traits> group_algorithms; | |
639 | |
640 | |
641 /* | |
642 siterator priv_invalid_local_it() const | 674 siterator priv_invalid_local_it() const |
643 { return this->priv_invalid_bucket()->end(); } | 675 { return this->priv_bucket_traits().bucket_begin()->before_begin(); } |
644 */ | 676 |
645 siterator priv_invalid_local_it() const | |
646 { | |
647 return this->priv_real_bucket_traits().bucket_begin()->before_begin(); | |
648 } | |
649 | |
650 /// | |
651 static siterator priv_get_last(bucket_type &b, detail::true_) //optimize multikey | 677 static siterator priv_get_last(bucket_type &b, detail::true_) //optimize multikey |
652 { | 678 { |
653 //First find the last node of p's group. | 679 //First find the last node of p's group. |
654 //This requires checking the first node of the next group or | 680 //This requires checking the first node of the next group or |
655 //the bucket node. | 681 //the bucket node. |
729 } | 755 } |
730 | 756 |
731 static std::size_t priv_stored_hash(slist_node_ptr n, detail::true_) //store_hash | 757 static std::size_t priv_stored_hash(slist_node_ptr n, detail::true_) //store_hash |
732 { return node_traits::get_hash(detail::dcast_bucket_ptr<node>(n)); } | 758 { return node_traits::get_hash(detail::dcast_bucket_ptr<node>(n)); } |
733 | 759 |
734 static std::size_t priv_stored_hash(slist_node_ptr, detail::false_) //NO store_hash | 760 static std::size_t priv_stored_hash(slist_node_ptr, detail::false_) //NO store_hash (This should never be called) |
735 { | 761 { BOOST_INTRUSIVE_INVARIANT_ASSERT(0); return 0; } |
736 //This code should never be reached! | |
737 BOOST_INTRUSIVE_INVARIANT_ASSERT(0); | |
738 return 0; | |
739 } | |
740 | 762 |
741 node &priv_value_to_node(value_type &v) | 763 node &priv_value_to_node(value_type &v) |
742 { return *this->priv_real_value_traits().to_node_ptr(v); } | 764 { return *this->priv_value_traits().to_node_ptr(v); } |
743 | 765 |
744 const node &priv_value_to_node(const value_type &v) const | 766 const node &priv_value_to_node(const value_type &v) const |
745 { return *this->priv_real_value_traits().to_node_ptr(v); } | 767 { return *this->priv_value_traits().to_node_ptr(v); } |
746 | 768 |
747 value_type &priv_value_from_slist_node(slist_node_ptr n) | 769 value_type &priv_value_from_slist_node(slist_node_ptr n) |
748 { return *this->priv_real_value_traits().to_value_ptr(detail::dcast_bucket_ptr<node>(n)); } | 770 { return *this->priv_value_traits().to_value_ptr(detail::dcast_bucket_ptr<node>(n)); } |
749 | 771 |
750 const value_type &priv_value_from_slist_node(slist_node_ptr n) const | 772 const value_type &priv_value_from_slist_node(slist_node_ptr n) const |
751 { return *this->priv_real_value_traits().to_value_ptr(detail::dcast_bucket_ptr<node>(n)); } | 773 { return *this->priv_value_traits().to_value_ptr(detail::dcast_bucket_ptr<node>(n)); } |
774 | |
775 void priv_clear_buckets(const bucket_ptr buckets_ptr, const size_type bucket_cnt) | |
776 { | |
777 bucket_ptr buckets_it = buckets_ptr; | |
778 for(size_type bucket_i = 0; bucket_i != bucket_cnt; ++buckets_it, ++bucket_i){ | |
779 if(safemode_or_autounlink){ | |
780 bucket_plus_vtraits::priv_clear_group_nodes(*buckets_it, optimize_multikey_t()); | |
781 buckets_it->clear_and_dispose(detail::init_disposer<node_algorithms>()); | |
782 } | |
783 else{ | |
784 buckets_it->clear(); | |
785 } | |
786 } | |
787 } | |
752 | 788 |
753 bucket_traits bucket_traits_; | 789 bucket_traits bucket_traits_; |
754 }; | 790 }; |
755 | 791 |
792 template<class Hash, class T> | |
793 struct get_hash | |
794 { | |
795 typedef Hash type; | |
796 }; | |
797 | |
798 template<class T> | |
799 struct get_hash<void, T> | |
800 { | |
801 typedef ::boost::hash<T> type; | |
802 }; | |
803 | |
804 //bucket_hash_t | |
805 //Stores bucket_plus_vtraits plust the hash function | |
756 template<class VoidOrKeyHash, class ValueTraits, class BucketTraits> | 806 template<class VoidOrKeyHash, class ValueTraits, class BucketTraits> |
757 struct bucket_hash_t | 807 struct bucket_hash_t |
808 //Use public inheritance to avoid MSVC bugs with closures | |
758 : public detail::ebo_functor_holder | 809 : public detail::ebo_functor_holder |
759 <typename get_hash< VoidOrKeyHash | 810 <typename get_hash< VoidOrKeyHash |
760 , typename bucket_plus_vtraits<ValueTraits,BucketTraits>::real_value_traits::value_type | 811 , typename bucket_plus_vtraits<ValueTraits,BucketTraits>::value_traits::value_type |
761 >::type | 812 >::type |
762 > | 813 > |
763 , bucket_plus_vtraits<ValueTraits, BucketTraits> | |
764 { | 814 { |
765 typedef typename bucket_plus_vtraits<ValueTraits,BucketTraits>::real_value_traits real_value_traits; | 815 typedef typename bucket_plus_vtraits<ValueTraits,BucketTraits>::value_traits value_traits; |
766 typedef typename real_value_traits::value_type value_type; | 816 typedef typename value_traits::value_type value_type; |
767 typedef typename real_value_traits::node_traits node_traits; | 817 typedef typename value_traits::node_traits node_traits; |
768 typedef typename get_hash< VoidOrKeyHash, value_type>::type hasher; | 818 typedef typename get_hash< VoidOrKeyHash, value_type>::type hasher; |
769 typedef BucketTraits bucket_traits; | 819 typedef BucketTraits bucket_traits; |
770 typedef bucket_plus_vtraits<ValueTraits, BucketTraits> bucket_plus_vtraits_t; | 820 typedef bucket_plus_vtraits<ValueTraits, BucketTraits> bucket_plus_vtraits_t; |
771 | 821 |
772 template<class BucketTraitsType> | 822 template<class BucketTraitsType> |
773 bucket_hash_t(const ValueTraits &val_traits, BOOST_FWD_REF(BucketTraitsType) b_traits, const hasher & h) | 823 bucket_hash_t(const ValueTraits &val_traits, BOOST_FWD_REF(BucketTraitsType) b_traits, const hasher & h) |
774 : detail::ebo_functor_holder<hasher>(h), bucket_plus_vtraits_t(val_traits, ::boost::forward<BucketTraitsType>(b_traits)) | 824 : detail::ebo_functor_holder<hasher>(h), internal(val_traits, ::boost::forward<BucketTraitsType>(b_traits)) |
775 {} | 825 {} |
776 | 826 |
777 const hasher &priv_hasher() const | 827 const hasher &priv_hasher() const |
778 { return this->detail::ebo_functor_holder<hasher>::get(); } | 828 { return this->detail::ebo_functor_holder<hasher>::get(); } |
779 | 829 |
780 hasher &priv_hasher() | 830 hasher &priv_hasher() |
781 { return this->detail::ebo_functor_holder<hasher>::get(); } | 831 { return this->detail::ebo_functor_holder<hasher>::get(); } |
782 | 832 |
783 std::size_t priv_stored_or_compute_hash(const value_type &v, detail::true_) const //For store_hash == true | 833 std::size_t priv_stored_or_compute_hash(const value_type &v, detail::true_) const //For store_hash == true |
784 { return node_traits::get_hash(this->priv_real_value_traits().to_node_ptr(v)); } | 834 { return node_traits::get_hash(this->internal.priv_value_traits().to_node_ptr(v)); } |
785 | 835 |
786 std::size_t priv_stored_or_compute_hash(const value_type &v, detail::false_) const //For store_hash == false | 836 std::size_t priv_stored_or_compute_hash(const value_type &v, detail::false_) const //For store_hash == false |
787 { return this->priv_hasher()(v); } | 837 { return this->priv_hasher()(v); } |
838 | |
839 bucket_plus_vtraits_t internal; //4 | |
788 }; | 840 }; |
789 | 841 |
842 | |
843 template<class EqualTo, class T> | |
844 struct get_equal_to | |
845 { | |
846 typedef EqualTo type; | |
847 }; | |
848 | |
849 template<class T> | |
850 struct get_equal_to<void, T> | |
851 { | |
852 typedef ::std::equal_to<T> type; | |
853 }; | |
854 | |
855 | |
856 //bucket_hash_equal_t | |
857 //Stores bucket_hash_t and the equality function when the first | |
858 //non-empty bucket shall not be cached. | |
790 template<class VoidOrKeyHash, class VoidOrKeyEqual, class ValueTraits, class BucketTraits, bool> | 859 template<class VoidOrKeyHash, class VoidOrKeyEqual, class ValueTraits, class BucketTraits, bool> |
791 struct bucket_hash_equal_t | 860 struct bucket_hash_equal_t |
861 //Use public inheritance to avoid MSVC bugs with closures | |
792 : public detail::ebo_functor_holder //equal | 862 : public detail::ebo_functor_holder //equal |
793 <typename get_equal_to< VoidOrKeyEqual | 863 <typename get_equal_to< VoidOrKeyEqual |
794 , typename bucket_plus_vtraits<ValueTraits,BucketTraits>::real_value_traits::value_type | 864 , typename bucket_plus_vtraits<ValueTraits,BucketTraits>::value_traits::value_type |
795 >::type | 865 >::type |
796 > | 866 > |
797 , bucket_hash_t<VoidOrKeyHash, ValueTraits, BucketTraits> | |
798 { | 867 { |
799 typedef bucket_hash_t<VoidOrKeyHash, ValueTraits, BucketTraits> bucket_hash_type; | 868 typedef bucket_hash_t<VoidOrKeyHash, ValueTraits, BucketTraits> bucket_hash_type; |
800 typedef typename bucket_plus_vtraits<ValueTraits,BucketTraits>::real_value_traits real_value_traits; | 869 typedef bucket_plus_vtraits<ValueTraits,BucketTraits> bucket_plus_vtraits_t; |
870 typedef typename bucket_plus_vtraits_t::value_traits value_traits; | |
801 typedef typename get_equal_to< VoidOrKeyEqual | 871 typedef typename get_equal_to< VoidOrKeyEqual |
802 , typename real_value_traits::value_type | 872 , typename value_traits::value_type |
803 >::type value_equal; | 873 >::type value_equal; |
804 typedef typename bucket_hash_type::hasher hasher; | 874 typedef typename bucket_hash_type::hasher hasher; |
805 typedef BucketTraits bucket_traits; | 875 typedef BucketTraits bucket_traits; |
806 typedef bucket_hash_t<VoidOrKeyHash, ValueTraits, BucketTraits> buckethash_t; | 876 typedef typename bucket_plus_vtraits_t::slist_impl slist_impl; |
807 typedef typename bucket_hash_type::real_bucket_traits real_bucket_traits; | 877 typedef typename slist_impl::size_type size_type; |
808 typedef typename bucket_hash_type::slist_impl slist_impl; | 878 typedef typename slist_impl::iterator siterator; |
809 typedef typename slist_impl::size_type size_type; | 879 typedef detail::bucket_impl<slist_impl> bucket_type; |
810 typedef typename slist_impl::iterator siterator; | 880 typedef typename detail::unordered_bucket_ptr_impl<value_traits>::type bucket_ptr; |
811 typedef detail::bucket_impl<slist_impl> bucket_type; | |
812 typedef typename detail::unordered_bucket_ptr_impl<real_value_traits>::type bucket_ptr; | |
813 | 881 |
814 template<class BucketTraitsType> | 882 template<class BucketTraitsType> |
815 bucket_hash_equal_t(const ValueTraits &val_traits, BOOST_FWD_REF(BucketTraitsType) b_traits, const hasher & h, const value_equal &e) | 883 bucket_hash_equal_t(const ValueTraits &val_traits, BOOST_FWD_REF(BucketTraitsType) b_traits, const hasher & h, const value_equal &e) |
816 : detail::ebo_functor_holder<value_equal>(e) | 884 : detail::ebo_functor_holder<value_equal>(e) |
817 , buckethash_t(val_traits, ::boost::forward<BucketTraitsType>(b_traits), h) | 885 , internal(val_traits, ::boost::forward<BucketTraitsType>(b_traits), h) |
818 {} | 886 {} |
819 | 887 |
820 bucket_ptr priv_get_cache() | 888 bucket_ptr priv_get_cache() |
821 { return this->priv_bucket_pointer(); } | 889 { return this->internal.internal.priv_bucket_pointer(); } |
822 | 890 |
823 void priv_set_cache(const bucket_ptr &) | 891 void priv_set_cache(const bucket_ptr &) |
824 {} | 892 {} |
825 | 893 |
826 size_type priv_get_cache_bucket_num() | 894 size_type priv_get_cache_bucket_num() |
833 {} | 901 {} |
834 | 902 |
835 siterator priv_begin() const | 903 siterator priv_begin() const |
836 { | 904 { |
837 size_type n = 0; | 905 size_type n = 0; |
838 size_type bucket_cnt = this->priv_bucket_count(); | 906 size_type bucket_cnt = this->internal.internal.priv_bucket_count(); |
839 for (n = 0; n < bucket_cnt; ++n){ | 907 for (n = 0; n < bucket_cnt; ++n){ |
840 bucket_type &b = this->priv_bucket_pointer()[n]; | 908 bucket_type &b = this->internal.internal.priv_bucket_pointer()[n]; |
841 if(!b.empty()){ | 909 if(!b.empty()){ |
842 return b.begin(); | 910 return b.begin(); |
843 } | 911 } |
844 } | 912 } |
845 return this->priv_invalid_local_it(); | 913 return this->internal.internal.priv_invalid_local_it(); |
846 } | 914 } |
847 | 915 |
848 void priv_insertion_update_cache(size_type) | 916 void priv_insertion_update_cache(size_type) |
849 {} | 917 {} |
850 | 918 |
857 const value_equal &priv_equal() const | 925 const value_equal &priv_equal() const |
858 { return this->detail::ebo_functor_holder<value_equal>::get(); } | 926 { return this->detail::ebo_functor_holder<value_equal>::get(); } |
859 | 927 |
860 value_equal &priv_equal() | 928 value_equal &priv_equal() |
861 { return this->detail::ebo_functor_holder<value_equal>::get(); } | 929 { return this->detail::ebo_functor_holder<value_equal>::get(); } |
930 | |
931 bucket_hash_t<VoidOrKeyHash, ValueTraits, BucketTraits> internal; //3 | |
862 }; | 932 }; |
863 | 933 |
934 //bucket_hash_equal_t | |
935 //Stores bucket_hash_t and the equality function when the first | |
936 //non-empty bucket shall be cached. | |
864 template<class VoidOrKeyHash, class VoidOrKeyEqual, class ValueTraits, class BucketTraits> //cache_begin == true version | 937 template<class VoidOrKeyHash, class VoidOrKeyEqual, class ValueTraits, class BucketTraits> //cache_begin == true version |
865 struct bucket_hash_equal_t<VoidOrKeyHash, VoidOrKeyEqual, ValueTraits, BucketTraits, true> | 938 struct bucket_hash_equal_t<VoidOrKeyHash, VoidOrKeyEqual, ValueTraits, BucketTraits, true> |
939 //Use public inheritance to avoid MSVC bugs with closures | |
866 : public detail::ebo_functor_holder //equal | 940 : public detail::ebo_functor_holder //equal |
867 <typename get_equal_to< VoidOrKeyEqual | 941 <typename get_equal_to< VoidOrKeyEqual |
868 , typename bucket_plus_vtraits<ValueTraits,BucketTraits>::real_value_traits::value_type | 942 , typename bucket_plus_vtraits<ValueTraits,BucketTraits>::value_traits::value_type |
869 >::type | 943 >::type |
870 > | 944 > |
871 , public bucket_hash_t<VoidOrKeyHash, ValueTraits, BucketTraits> | |
872 { | 945 { |
873 typedef bucket_hash_t<VoidOrKeyHash, ValueTraits, BucketTraits> bucket_hash_type; | 946 typedef bucket_plus_vtraits<ValueTraits, BucketTraits> bucket_plus_vtraits_t; |
874 typedef typename get_equal_to< VoidOrKeyEqual | 947 typedef bucket_hash_t<VoidOrKeyHash, ValueTraits, BucketTraits> bucket_hash_type; |
875 , typename bucket_plus_vtraits<ValueTraits,BucketTraits>::real_value_traits::value_type | 948 typedef typename bucket_plus_vtraits |
876 >::type value_equal; | 949 <ValueTraits,BucketTraits>::value_traits value_traits; |
877 typedef typename bucket_hash_type::hasher hasher; | 950 typedef typename get_equal_to |
878 typedef BucketTraits bucket_traits; | 951 < VoidOrKeyEqual |
879 typedef typename bucket_hash_type::slist_impl::size_type size_type; | 952 , typename value_traits::value_type>::type value_equal; |
880 typedef typename bucket_hash_type::slist_impl::iterator siterator; | 953 typedef typename bucket_hash_type::hasher hasher; |
954 typedef BucketTraits bucket_traits; | |
955 typedef typename bucket_plus_vtraits_t::slist_impl::size_type size_type; | |
956 typedef typename bucket_plus_vtraits_t::slist_impl::iterator siterator; | |
881 | 957 |
882 template<class BucketTraitsType> | 958 template<class BucketTraitsType> |
883 bucket_hash_equal_t(const ValueTraits &val_traits, BOOST_FWD_REF(BucketTraitsType) b_traits, const hasher & h, const value_equal &e) | 959 bucket_hash_equal_t(const ValueTraits &val_traits, BOOST_FWD_REF(BucketTraitsType) b_traits, const hasher & h, const value_equal &e) |
884 : detail::ebo_functor_holder<value_equal>(e) | 960 : detail::ebo_functor_holder<value_equal>(e) |
885 , bucket_hash_type(val_traits, ::boost::forward<BucketTraitsType>(b_traits), h) | 961 , internal(val_traits, ::boost::forward<BucketTraitsType>(b_traits), h) |
886 {} | 962 {} |
887 | 963 |
888 typedef typename detail::unordered_bucket_ptr_impl | 964 typedef typename detail::unordered_bucket_ptr_impl |
889 <typename bucket_hash_type::real_value_traits>::type bucket_ptr; | 965 <typename bucket_hash_type::value_traits>::type bucket_ptr; |
890 | 966 |
891 bucket_ptr &priv_get_cache() | 967 bucket_ptr &priv_get_cache() |
892 { return cached_begin_; } | 968 { return cached_begin_; } |
893 | 969 |
894 const bucket_ptr &priv_get_cache() const | 970 const bucket_ptr &priv_get_cache() const |
896 | 972 |
897 void priv_set_cache(const bucket_ptr &p) | 973 void priv_set_cache(const bucket_ptr &p) |
898 { cached_begin_ = p; } | 974 { cached_begin_ = p; } |
899 | 975 |
900 std::size_t priv_get_cache_bucket_num() | 976 std::size_t priv_get_cache_bucket_num() |
901 { return this->cached_begin_ - this->priv_bucket_pointer(); } | 977 { return this->cached_begin_ - this->internal.internal.priv_bucket_pointer(); } |
902 | 978 |
903 void priv_initialize_cache() | 979 void priv_initialize_cache() |
904 { this->cached_begin_ = this->priv_invalid_bucket(); } | 980 { this->cached_begin_ = this->internal.internal.priv_invalid_bucket(); } |
905 | 981 |
906 void priv_swap_cache(bucket_hash_equal_t &other) | 982 void priv_swap_cache(bucket_hash_equal_t &other) |
907 { | 983 { |
908 std::swap(this->cached_begin_, other.cached_begin_); | 984 ::boost::adl_move_swap(this->cached_begin_, other.cached_begin_); |
909 } | 985 } |
910 | 986 |
911 siterator priv_begin() const | 987 siterator priv_begin() const |
912 { | 988 { |
913 if(this->cached_begin_ == this->priv_invalid_bucket()){ | 989 if(this->cached_begin_ == this->internal.internal.priv_invalid_bucket()){ |
914 return this->priv_invalid_local_it(); | 990 return this->internal.internal.priv_invalid_local_it(); |
915 } | 991 } |
916 else{ | 992 else{ |
917 return this->cached_begin_->begin(); | 993 return this->cached_begin_->begin(); |
918 } | 994 } |
919 } | 995 } |
920 | 996 |
921 void priv_insertion_update_cache(size_type insertion_bucket) | 997 void priv_insertion_update_cache(size_type insertion_bucket) |
922 { | 998 { |
923 bucket_ptr p = this->priv_bucket_pointer() + insertion_bucket; | 999 bucket_ptr p = this->internal.internal.priv_bucket_pointer() + insertion_bucket; |
924 if(p < this->cached_begin_){ | 1000 if(p < this->cached_begin_){ |
925 this->cached_begin_ = p; | 1001 this->cached_begin_ = p; |
926 } | 1002 } |
927 } | 1003 } |
928 | 1004 |
935 void priv_erasure_update_cache_range(size_type first_bucket_num, size_type last_bucket_num) | 1011 void priv_erasure_update_cache_range(size_type first_bucket_num, size_type last_bucket_num) |
936 { | 1012 { |
937 //If the last bucket is the end, the cache must be updated | 1013 //If the last bucket is the end, the cache must be updated |
938 //to the last position if all | 1014 //to the last position if all |
939 if(this->priv_get_cache_bucket_num() == first_bucket_num && | 1015 if(this->priv_get_cache_bucket_num() == first_bucket_num && |
940 this->priv_bucket_pointer()[first_bucket_num].empty() ){ | 1016 this->internal.internal.priv_bucket_pointer()[first_bucket_num].empty() ){ |
941 this->priv_set_cache(this->priv_bucket_pointer() + last_bucket_num); | 1017 this->priv_set_cache(this->internal.internal.priv_bucket_pointer() + last_bucket_num); |
942 this->priv_erasure_update_cache(); | 1018 this->priv_erasure_update_cache(); |
943 } | 1019 } |
944 } | 1020 } |
945 | 1021 |
946 void priv_erasure_update_cache() | 1022 void priv_erasure_update_cache() |
947 { | 1023 { |
948 if(this->cached_begin_ != this->priv_invalid_bucket()){ | 1024 if(this->cached_begin_ != this->internal.internal.priv_invalid_bucket()){ |
949 size_type current_n = this->priv_get_cache() - this->priv_bucket_pointer(); | 1025 size_type current_n = this->priv_get_cache() - this->internal.internal.priv_bucket_pointer(); |
950 for( const size_type num_buckets = this->priv_bucket_count() | 1026 for( const size_type num_buckets = this->internal.internal.priv_bucket_count() |
951 ; current_n < num_buckets | 1027 ; current_n < num_buckets |
952 ; ++current_n, ++this->priv_get_cache()){ | 1028 ; ++current_n, ++this->priv_get_cache()){ |
953 if(!this->priv_get_cache()->empty()){ | 1029 if(!this->priv_get_cache()->empty()){ |
954 return; | 1030 return; |
955 } | 1031 } |
956 } | 1032 } |
957 this->priv_initialize_cache(); | 1033 this->priv_initialize_cache(); |
958 } | 1034 } |
959 } | 1035 } |
960 | 1036 |
961 private: | |
962 bucket_ptr cached_begin_; | 1037 bucket_ptr cached_begin_; |
1038 bucket_hash_t<VoidOrKeyHash, ValueTraits, BucketTraits> internal; //2 | |
963 }; | 1039 }; |
964 | 1040 |
1041 //hashdata_internal | |
1042 //Stores bucket_hash_equal_t and split_traits | |
965 template<class SizeType, std::size_t BoolFlags, class VoidOrKeyHash, class VoidOrKeyEqual, class ValueTraits, class BucketTraits> | 1043 template<class SizeType, std::size_t BoolFlags, class VoidOrKeyHash, class VoidOrKeyEqual, class ValueTraits, class BucketTraits> |
966 struct hashdata_internal | 1044 struct hashdata_internal |
967 : public detail::size_holder< 0 != (BoolFlags & hash_bool_flags::incremental_pos), SizeType, int> //split_traits | 1045 : public detail::size_holder< 0 != (BoolFlags & hash_bool_flags::incremental_pos), SizeType, int> //split_traits |
968 , public bucket_hash_equal_t | |
969 < VoidOrKeyHash, VoidOrKeyEqual, ValueTraits, BucketTraits | |
970 , 0 != (BoolFlags & hash_bool_flags::cache_begin_pos) | |
971 > | |
972 { | 1046 { |
973 typedef bucket_hash_equal_t | 1047 typedef bucket_hash_equal_t |
974 < VoidOrKeyHash, VoidOrKeyEqual, ValueTraits, BucketTraits | 1048 < VoidOrKeyHash, VoidOrKeyEqual |
1049 , ValueTraits, BucketTraits | |
975 , 0 != (BoolFlags & hash_bool_flags::cache_begin_pos) | 1050 , 0 != (BoolFlags & hash_bool_flags::cache_begin_pos) |
976 > bucket_hash_equal_type; | 1051 > internal_type; |
977 | 1052 typedef typename internal_type::value_equal value_equal; |
978 typedef typename bucket_hash_equal_type::value_equal value_equal; | 1053 typedef typename internal_type::hasher hasher; |
979 typedef typename bucket_hash_equal_type::hasher hasher; | 1054 typedef bucket_plus_vtraits<ValueTraits,BucketTraits> bucket_plus_vtraits_t; |
980 typedef bucket_plus_vtraits<ValueTraits,BucketTraits> bucket_plus_vtraits_t; | 1055 typedef typename bucket_plus_vtraits_t::size_type size_type; |
981 typedef typename bucket_plus_vtraits_t::size_type size_type; | 1056 typedef typename bucket_plus_vtraits_t::bucket_ptr bucket_ptr; |
982 typedef typename bucket_plus_vtraits_t::bucket_ptr bucket_ptr; | 1057 typedef detail::size_holder |
983 static const bool optimize_multikey | 1058 <0 != (BoolFlags & hash_bool_flags::incremental_pos) |
984 = detail::optimize_multikey_is_true<typename bucket_plus_vtraits_t::real_value_traits::node_traits>::value; | 1059 , SizeType, int> split_traits; |
985 | 1060 typedef typename bucket_plus_vtraits_t:: |
986 typedef detail::bool_<optimize_multikey> optimize_multikey_t; | 1061 value_traits::node_traits node_traits; |
1062 typedef detail::bool_<detail::optimize_multikey_is_true | |
1063 <node_traits>::value> optimize_multikey_t; | |
987 | 1064 |
988 template<class BucketTraitsType> | 1065 template<class BucketTraitsType> |
989 hashdata_internal(const ValueTraits &val_traits, BOOST_FWD_REF(BucketTraitsType) b_traits, const hasher & h, const value_equal &e) | 1066 hashdata_internal( const ValueTraits &val_traits, BOOST_FWD_REF(BucketTraitsType) b_traits |
990 : bucket_hash_equal_type(val_traits, ::boost::forward<BucketTraitsType>(b_traits), h, e) | 1067 , const hasher & h, const value_equal &e) |
1068 : internal(val_traits, ::boost::forward<BucketTraitsType>(b_traits), h, e) | |
991 {} | 1069 {} |
992 | |
993 typedef detail::size_holder | |
994 <0 != (BoolFlags & hash_bool_flags::incremental_pos), SizeType, int> split_traits; | |
995 | 1070 |
996 split_traits &priv_split_traits() | 1071 split_traits &priv_split_traits() |
997 { return *this; } | 1072 { return *this; } |
998 | 1073 |
999 const split_traits &priv_split_traits() const | 1074 const split_traits &priv_split_traits() const |
1000 { return *this; } | 1075 { return *this; } |
1076 | |
1077 ~hashdata_internal() | |
1078 { this->priv_clear_buckets(); } | |
1079 | |
1080 void priv_clear_buckets() | |
1081 { | |
1082 this->internal.internal.internal.priv_clear_buckets | |
1083 ( this->internal.priv_get_cache() | |
1084 , this->internal.internal.internal.priv_bucket_count() | |
1085 - (this->internal.priv_get_cache() | |
1086 - this->internal.internal.internal.priv_bucket_pointer())); | |
1087 } | |
1088 | |
1089 void priv_clear_buckets_and_cache() | |
1090 { | |
1091 this->priv_clear_buckets(); | |
1092 this->internal.priv_initialize_cache(); | |
1093 } | |
1094 | |
1095 void priv_initialize_buckets_and_cache() | |
1096 { | |
1097 this->internal.internal.internal.priv_clear_buckets | |
1098 ( this->internal.internal.internal.priv_bucket_pointer() | |
1099 , this->internal.internal.internal.priv_bucket_count()); | |
1100 this->internal.priv_initialize_cache(); | |
1101 } | |
1102 | |
1103 internal_type internal; //2 | |
1001 }; | 1104 }; |
1002 | 1105 |
1106 //hashtable_data_t | |
1107 //Stores hashdata_internal and size_traits | |
1003 template<class SizeType, std::size_t BoolFlags, class VoidOrKeyHash, class VoidOrKeyEqual, class ValueTraits, class BucketTraits> | 1108 template<class SizeType, std::size_t BoolFlags, class VoidOrKeyHash, class VoidOrKeyEqual, class ValueTraits, class BucketTraits> |
1004 struct hashtable_data_t | 1109 struct hashtable_data_t |
1005 : public detail::size_holder< 0 != (BoolFlags & hash_bool_flags::constant_time_size_pos), SizeType> //size_traits | 1110 : public detail::size_holder |
1006 , public hashdata_internal | 1111 < 0 != (BoolFlags & hash_bool_flags::constant_time_size_pos), SizeType> //size_traits |
1007 < SizeType, BoolFlags & (hash_bool_flags::incremental_pos | hash_bool_flags::cache_begin_pos) | |
1008 , VoidOrKeyHash, VoidOrKeyEqual, ValueTraits, BucketTraits> | |
1009 { | 1112 { |
1010 static const std::size_t bool_flags = BoolFlags; | |
1011 typedef detail::size_holder | 1113 typedef detail::size_holder |
1012 < 0 != (BoolFlags & hash_bool_flags::constant_time_size_pos) | 1114 < 0 != (BoolFlags & hash_bool_flags::constant_time_size_pos) |
1013 , SizeType> size_traits; | 1115 , SizeType> size_traits; |
1014 | |
1015 typedef hashdata_internal | 1116 typedef hashdata_internal |
1016 < SizeType, BoolFlags & (hash_bool_flags::incremental_pos | hash_bool_flags::cache_begin_pos) | 1117 < SizeType |
1017 , VoidOrKeyHash, VoidOrKeyEqual, ValueTraits, BucketTraits> internal_type; | 1118 , BoolFlags & (hash_bool_flags::incremental_pos | hash_bool_flags::cache_begin_pos) |
1018 | 1119 , VoidOrKeyHash, VoidOrKeyEqual |
1019 typedef ValueTraits value_traits; | 1120 , ValueTraits, BucketTraits> internal_type; |
1020 typedef typename internal_type::value_equal value_equal; | 1121 typedef ValueTraits value_traits; |
1021 typedef typename internal_type::hasher hasher; | 1122 typedef typename internal_type::value_equal value_equal; |
1022 typedef BucketTraits bucket_traits; | 1123 typedef typename internal_type::hasher hasher; |
1124 typedef BucketTraits bucket_traits; | |
1023 typedef bucket_plus_vtraits | 1125 typedef bucket_plus_vtraits |
1024 <ValueTraits,BucketTraits> bucket_plus_vtraits_t; | 1126 <ValueTraits,BucketTraits> bucket_plus_vtraits_t; |
1025 | |
1026 static const bool external_value_traits = | |
1027 detail::external_value_traits_bool_is_true<ValueTraits>::value; | |
1028 static const bool external_bucket_traits = bucket_plus_vtraits_t::external_bucket_traits; | |
1029 | |
1030 typedef typename bucket_plus_vtraits_t::real_value_traits real_value_traits; | |
1031 typedef typename bucket_plus_vtraits_t::real_bucket_traits real_bucket_traits; | |
1032 | |
1033 size_traits &priv_size_traits() | |
1034 { return *this; } | |
1035 | |
1036 const size_traits &priv_size_traits() const | |
1037 { return *this; } | |
1038 | 1127 |
1039 template<class BucketTraitsType> | 1128 template<class BucketTraitsType> |
1040 hashtable_data_t( BOOST_FWD_REF(BucketTraitsType) b_traits, const hasher & h | 1129 hashtable_data_t( BOOST_FWD_REF(BucketTraitsType) b_traits, const hasher & h |
1041 , const value_equal &e, const value_traits &val_traits) | 1130 , const value_equal &e, const value_traits &val_traits) |
1042 : size_traits() | 1131 : internal(val_traits, ::boost::forward<BucketTraitsType>(b_traits), h, e) |
1043 , internal_type(val_traits, ::boost::forward<BucketTraitsType>(b_traits), h, e) | |
1044 {} | 1132 {} |
1133 | |
1134 internal_type internal; //1 | |
1045 }; | 1135 }; |
1046 | 1136 |
1047 /// @endcond | 1137 /// @endcond |
1048 | 1138 |
1049 //! The class template hashtable is an intrusive hash table container, that | 1139 //! The class template hashtable is an intrusive hash table container, that |
1086 template<class T, class ...Options> | 1176 template<class T, class ...Options> |
1087 #else | 1177 #else |
1088 template<class ValueTraits, class VoidOrKeyHash, class VoidOrKeyEqual, class SizeType, class BucketTraits, std::size_t BoolFlags> | 1178 template<class ValueTraits, class VoidOrKeyHash, class VoidOrKeyEqual, class SizeType, class BucketTraits, std::size_t BoolFlags> |
1089 #endif | 1179 #endif |
1090 class hashtable_impl | 1180 class hashtable_impl |
1091 : public hashtable_data_t | 1181 : private hashtable_data_t |
1092 < SizeType | 1182 < SizeType |
1093 , BoolFlags & hashtable_data_bool_flags_mask | 1183 , BoolFlags & hashtable_data_bool_flags_mask |
1094 , VoidOrKeyHash, VoidOrKeyEqual, ValueTraits, BucketTraits> | 1184 , VoidOrKeyHash, VoidOrKeyEqual, ValueTraits, BucketTraits> |
1095 , private detail::clear_on_destructor_base | |
1096 < hashtable_impl<ValueTraits, VoidOrKeyHash, VoidOrKeyEqual, SizeType, BucketTraits, BoolFlags> | |
1097 , true //To always clear the bucket array | |
1098 //is_safe_autounlink<detail::get_real_value_traits<ValueTraits>::type::link_mode>::value | |
1099 > | |
1100 { | 1185 { |
1101 template<class C, bool> friend class detail::clear_on_destructor_base; | |
1102 public: | |
1103 typedef ValueTraits value_traits; | |
1104 | |
1105 typedef hashtable_data_t | 1186 typedef hashtable_data_t |
1106 < SizeType | 1187 < SizeType |
1107 , BoolFlags & hashtable_data_bool_flags_mask | 1188 , BoolFlags & hashtable_data_bool_flags_mask |
1108 , VoidOrKeyHash, VoidOrKeyEqual, ValueTraits, BucketTraits> data_type; | 1189 , VoidOrKeyHash, VoidOrKeyEqual, ValueTraits, BucketTraits> data_type; |
1190 | |
1191 public: | |
1192 typedef ValueTraits value_traits; | |
1109 | 1193 |
1110 /// @cond | 1194 /// @cond |
1111 static const bool external_value_traits = data_type::external_value_traits; | |
1112 static const bool external_bucket_traits = data_type::external_bucket_traits; | |
1113 | |
1114 typedef BucketTraits bucket_traits; | 1195 typedef BucketTraits bucket_traits; |
1115 typedef typename data_type::real_bucket_traits real_bucket_traits; | |
1116 typedef typename data_type::real_value_traits real_value_traits; | |
1117 | |
1118 | 1196 |
1119 typedef typename detail::get_slist_impl | 1197 typedef typename detail::get_slist_impl |
1120 <typename detail::reduced_slist_node_traits | 1198 <typename detail::reduced_slist_node_traits |
1121 <typename real_value_traits::node_traits>::type | 1199 <typename value_traits::node_traits>::type |
1122 >::type slist_impl; | 1200 >::type slist_impl; |
1123 typedef bucket_plus_vtraits<ValueTraits, BucketTraits> bucket_plus_vtraits_t; | 1201 typedef bucket_plus_vtraits<ValueTraits, BucketTraits> bucket_plus_vtraits_t; |
1124 typedef typename bucket_plus_vtraits_t::const_real_value_traits_ptr const_real_value_traits_ptr; | 1202 typedef typename bucket_plus_vtraits_t::const_value_traits_ptr const_value_traits_ptr; |
1125 | 1203 |
1126 | 1204 |
1127 /// @endcond | 1205 /// @endcond |
1128 | 1206 |
1129 typedef typename real_value_traits::pointer pointer; | 1207 typedef typename value_traits::pointer pointer; |
1130 typedef typename real_value_traits::const_pointer const_pointer; | 1208 typedef typename value_traits::const_pointer const_pointer; |
1131 typedef typename real_value_traits::value_type value_type; | 1209 typedef typename value_traits::value_type value_type; |
1132 typedef typename pointer_traits<pointer>::reference reference; | 1210 typedef typename pointer_traits<pointer>::reference reference; |
1133 typedef typename pointer_traits<const_pointer>::reference const_reference; | 1211 typedef typename pointer_traits<const_pointer>::reference const_reference; |
1134 typedef typename pointer_traits<pointer>::difference_type difference_type; | 1212 typedef typename pointer_traits<pointer>::difference_type difference_type; |
1135 typedef SizeType size_type; | 1213 typedef SizeType size_type; |
1136 typedef value_type key_type; | 1214 typedef value_type key_type; |
1137 typedef typename data_type::value_equal key_equal; | 1215 typedef typename data_type::value_equal key_equal; |
1216 typedef typename data_type::value_equal value_equal; | |
1138 typedef typename data_type::hasher hasher; | 1217 typedef typename data_type::hasher hasher; |
1139 typedef detail::bucket_impl<slist_impl> bucket_type; | 1218 typedef detail::bucket_impl<slist_impl> bucket_type; |
1140 typedef typename pointer_traits | 1219 typedef typename pointer_traits |
1141 <pointer>::template rebind_pointer | 1220 <pointer>::template rebind_pointer |
1142 < bucket_type >::type bucket_ptr; | 1221 < bucket_type >::type bucket_ptr; |
1222 typedef typename pointer_traits | |
1223 <pointer>::template rebind_pointer | |
1224 < const bucket_type >::type const_bucket_ptr; | |
1225 typedef typename pointer_traits | |
1226 <bucket_ptr>::reference bucket_reference; | |
1227 typedef typename pointer_traits | |
1228 <bucket_ptr>::reference const_bucket_reference; | |
1143 typedef typename slist_impl::iterator siterator; | 1229 typedef typename slist_impl::iterator siterator; |
1144 typedef typename slist_impl::const_iterator const_siterator; | 1230 typedef typename slist_impl::const_iterator const_siterator; |
1145 typedef hashtable_iterator<bucket_plus_vtraits_t, false> iterator; | 1231 typedef hashtable_iterator<bucket_plus_vtraits_t, false> iterator; |
1146 typedef hashtable_iterator<bucket_plus_vtraits_t, true> const_iterator; | 1232 typedef hashtable_iterator<bucket_plus_vtraits_t, true> const_iterator; |
1147 typedef typename real_value_traits::node_traits node_traits; | 1233 typedef typename value_traits::node_traits node_traits; |
1148 typedef typename node_traits::node node; | 1234 typedef typename node_traits::node node; |
1149 typedef typename pointer_traits | 1235 typedef typename pointer_traits |
1150 <pointer>::template rebind_pointer | 1236 <pointer>::template rebind_pointer |
1151 < node >::type node_ptr; | 1237 < node >::type node_ptr; |
1152 typedef typename pointer_traits | 1238 typedef typename pointer_traits |
1153 <pointer>::template rebind_pointer | 1239 <pointer>::template rebind_pointer |
1154 < const node >::type const_node_ptr; | 1240 < const node >::type const_node_ptr; |
1241 typedef typename pointer_traits | |
1242 <node_ptr>::reference node_reference; | |
1243 typedef typename pointer_traits | |
1244 <const_node_ptr>::reference const_node_reference; | |
1155 typedef typename slist_impl::node_algorithms node_algorithms; | 1245 typedef typename slist_impl::node_algorithms node_algorithms; |
1156 | 1246 |
1157 static const bool stateful_value_traits = detail::is_stateful_value_traits<real_value_traits>::value; | 1247 static const bool stateful_value_traits = detail::is_stateful_value_traits<value_traits>::value; |
1158 static const bool store_hash = detail::store_hash_is_true<node_traits>::value; | 1248 static const bool store_hash = detail::store_hash_is_true<node_traits>::value; |
1159 | 1249 |
1160 static const bool unique_keys = 0 != (BoolFlags & hash_bool_flags::unique_keys_pos); | 1250 static const bool unique_keys = 0 != (BoolFlags & hash_bool_flags::unique_keys_pos); |
1161 static const bool constant_time_size = 0 != (BoolFlags & hash_bool_flags::constant_time_size_pos); | 1251 static const bool constant_time_size = 0 != (BoolFlags & hash_bool_flags::constant_time_size_pos); |
1162 static const bool cache_begin = 0 != (BoolFlags & hash_bool_flags::cache_begin_pos); | 1252 static const bool cache_begin = 0 != (BoolFlags & hash_bool_flags::cache_begin_pos); |
1193 | 1283 |
1194 private: | 1284 private: |
1195 //noncopyable, movable | 1285 //noncopyable, movable |
1196 BOOST_MOVABLE_BUT_NOT_COPYABLE(hashtable_impl) | 1286 BOOST_MOVABLE_BUT_NOT_COPYABLE(hashtable_impl) |
1197 | 1287 |
1198 static const bool safemode_or_autounlink = is_safe_autounlink<real_value_traits::link_mode>::value; | 1288 static const bool safemode_or_autounlink = is_safe_autounlink<value_traits::link_mode>::value; |
1199 | 1289 |
1200 //Constant-time size is incompatible with auto-unlink hooks! | 1290 //Constant-time size is incompatible with auto-unlink hooks! |
1201 BOOST_STATIC_ASSERT(!(constant_time_size && ((int)real_value_traits::link_mode == (int)auto_unlink))); | 1291 BOOST_STATIC_ASSERT(!(constant_time_size && ((int)value_traits::link_mode == (int)auto_unlink))); |
1202 //Cache begin is incompatible with auto-unlink hooks! | 1292 //Cache begin is incompatible with auto-unlink hooks! |
1203 BOOST_STATIC_ASSERT(!(cache_begin && ((int)real_value_traits::link_mode == (int)auto_unlink))); | 1293 BOOST_STATIC_ASSERT(!(cache_begin && ((int)value_traits::link_mode == (int)auto_unlink))); |
1204 | 1294 |
1205 template<class Disposer> | 1295 template<class Disposer> |
1206 node_cast_adaptor< detail::node_disposer<Disposer, real_value_traits, CircularSListAlgorithms> | 1296 node_cast_adaptor< detail::node_disposer<Disposer, value_traits, CircularSListAlgorithms> |
1207 , slist_node_ptr, node_ptr > | 1297 , slist_node_ptr, node_ptr > |
1208 make_node_disposer(const Disposer &disposer) const | 1298 make_node_disposer(const Disposer &disposer) const |
1209 { | 1299 { |
1210 return node_cast_adaptor | 1300 return node_cast_adaptor |
1211 < detail::node_disposer<Disposer, real_value_traits, CircularSListAlgorithms> | 1301 < detail::node_disposer<Disposer, value_traits, CircularSListAlgorithms> |
1212 , slist_node_ptr, node_ptr > | 1302 , slist_node_ptr, node_ptr > |
1213 (disposer, &this->priv_real_value_traits()); | 1303 (disposer, &this->priv_value_traits()); |
1214 } | 1304 } |
1215 | 1305 |
1216 /// @endcond | 1306 /// @endcond |
1217 | 1307 |
1218 public: | 1308 public: |
1219 typedef detail::insert_commit_data_impl insert_commit_data; | 1309 typedef detail::insert_commit_data_impl insert_commit_data; |
1220 | 1310 |
1221 typedef detail::transform_iterator | 1311 typedef detail::transform_iterator |
1222 < typename slist_impl::iterator | 1312 < typename slist_impl::iterator |
1223 , downcast_node_to_value_t | 1313 , downcast_node_to_value_t |
1224 < real_value_traits | 1314 < value_traits |
1225 , false> > local_iterator; | 1315 , false> > local_iterator; |
1226 | 1316 |
1227 typedef detail::transform_iterator | 1317 typedef detail::transform_iterator |
1228 < typename slist_impl::iterator | 1318 < typename slist_impl::iterator |
1229 , downcast_node_to_value_t | 1319 , downcast_node_to_value_t |
1230 < real_value_traits | 1320 < value_traits |
1231 , true> > const_local_iterator; | 1321 , true> > const_local_iterator; |
1232 | 1322 |
1233 public: | 1323 public: |
1234 | 1324 |
1235 //! <b>Requires</b>: buckets must not be being used by any other resource. | 1325 //! <b>Requires</b>: buckets must not be being used by any other resource. |
1249 , const hasher & hash_func = hasher() | 1339 , const hasher & hash_func = hasher() |
1250 , const key_equal &equal_func = key_equal() | 1340 , const key_equal &equal_func = key_equal() |
1251 , const value_traits &v_traits = value_traits()) | 1341 , const value_traits &v_traits = value_traits()) |
1252 : data_type(b_traits, hash_func, equal_func, v_traits) | 1342 : data_type(b_traits, hash_func, equal_func, v_traits) |
1253 { | 1343 { |
1254 this->priv_initialize_buckets(); | 1344 this->data_type::internal.priv_initialize_buckets_and_cache(); |
1255 this->priv_size_traits().set_size(size_type(0)); | 1345 this->priv_size_traits().set_size(size_type(0)); |
1256 size_type bucket_sz = this->priv_bucket_count(); | 1346 size_type bucket_sz = this->priv_bucket_count(); |
1257 BOOST_INTRUSIVE_INVARIANT_ASSERT(bucket_sz != 0); | 1347 BOOST_INTRUSIVE_INVARIANT_ASSERT(bucket_sz != 0); |
1258 //Check power of two bucket array if the option is activated | 1348 //Check power of two bucket array if the option is activated |
1259 BOOST_INTRUSIVE_INVARIANT_ASSERT | 1349 BOOST_INTRUSIVE_INVARIANT_ASSERT |
1294 //! | 1384 //! |
1295 //! <b>Complexity</b>: Linear to the number of elements in the unordered_set, if | 1385 //! <b>Complexity</b>: Linear to the number of elements in the unordered_set, if |
1296 //! it's a safe-mode or auto-unlink value. Otherwise constant. | 1386 //! it's a safe-mode or auto-unlink value. Otherwise constant. |
1297 //! | 1387 //! |
1298 //! <b>Throws</b>: Nothing. | 1388 //! <b>Throws</b>: Nothing. |
1299 ~hashtable_impl() | 1389 ~hashtable_impl(); |
1300 {} | |
1301 #endif | 1390 #endif |
1302 | 1391 |
1303 //! <b>Effects</b>: Returns an iterator pointing to the beginning of the unordered_set. | 1392 //! <b>Effects</b>: Returns an iterator pointing to the beginning of the unordered_set. |
1304 //! | 1393 //! |
1305 //! <b>Complexity</b>: Amortized constant time. | 1394 //! <b>Complexity</b>: Amortized constant time. |
1427 //! | 1516 //! |
1428 //! <b>Throws</b>: If the swap() call for the comparison or hash functors | 1517 //! <b>Throws</b>: If the swap() call for the comparison or hash functors |
1429 //! found using ADL throw. Basic guarantee. | 1518 //! found using ADL throw. Basic guarantee. |
1430 void swap(hashtable_impl& other) | 1519 void swap(hashtable_impl& other) |
1431 { | 1520 { |
1432 using std::swap; | |
1433 //These can throw | 1521 //These can throw |
1434 swap(this->priv_equal(), other.priv_equal()); | 1522 ::boost::adl_move_swap(this->priv_equal(), other.priv_equal()); |
1435 swap(this->priv_hasher(), other.priv_hasher()); | 1523 ::boost::adl_move_swap(this->priv_hasher(), other.priv_hasher()); |
1436 //These can't throw | 1524 //These can't throw |
1437 swap(this->priv_bucket_traits(), other.priv_bucket_traits()); | 1525 ::boost::adl_move_swap(this->priv_bucket_traits(), other.priv_bucket_traits()); |
1438 swap(this->priv_value_traits(), other.priv_value_traits()); | 1526 ::boost::adl_move_swap(this->priv_value_traits(), other.priv_value_traits()); |
1439 this->priv_swap_cache(other); | 1527 this->priv_swap_cache(other); |
1440 if(constant_time_size){ | 1528 if(constant_time_size){ |
1441 size_type backup = this->priv_size_traits().get_size(); | 1529 size_type backup = this->priv_size_traits().get_size(); |
1442 this->priv_size_traits().set_size(other.priv_size_traits().get_size()); | 1530 this->priv_size_traits().set_size(other.priv_size_traits().get_size()); |
1443 other.priv_size_traits().set_size(backup); | 1531 other.priv_size_traits().set_size(backup); |
1485 if(!incremental && (src_bucket_count >= dst_bucket_count)){ | 1573 if(!incremental && (src_bucket_count >= dst_bucket_count)){ |
1486 //First clone the first ones | 1574 //First clone the first ones |
1487 const bucket_ptr src_buckets = src.priv_bucket_pointer(); | 1575 const bucket_ptr src_buckets = src.priv_bucket_pointer(); |
1488 const bucket_ptr dst_buckets = this->priv_bucket_pointer(); | 1576 const bucket_ptr dst_buckets = this->priv_bucket_pointer(); |
1489 size_type constructed; | 1577 size_type constructed; |
1490 | 1578 |
1491 typedef node_cast_adaptor< detail::node_disposer<Disposer, real_value_traits, CircularSListAlgorithms> | 1579 typedef node_cast_adaptor< detail::node_disposer<Disposer, value_traits, CircularSListAlgorithms> |
1492 , slist_node_ptr, node_ptr > NodeDisposer; | 1580 , slist_node_ptr, node_ptr > NodeDisposer; |
1493 typedef node_cast_adaptor< detail::node_cloner <Cloner, real_value_traits, CircularSListAlgorithms> | 1581 typedef node_cast_adaptor< detail::node_cloner <Cloner, value_traits, CircularSListAlgorithms> |
1494 , slist_node_ptr, node_ptr > NodeCloner; | 1582 , slist_node_ptr, node_ptr > NodeCloner; |
1495 NodeDisposer node_disp(disposer, &this->priv_real_value_traits()); | 1583 NodeDisposer node_disp(disposer, &this->priv_value_traits()); |
1496 | 1584 |
1497 detail::exception_array_disposer<bucket_type, NodeDisposer, size_type> | 1585 detail::exception_array_disposer<bucket_type, NodeDisposer, size_type> |
1498 rollback(dst_buckets[0], node_disp, constructed); | 1586 rollback(dst_buckets[0], node_disp, constructed); |
1499 for( constructed = 0 | 1587 for( constructed = 0 |
1500 ; constructed < dst_bucket_count | 1588 ; constructed < dst_bucket_count |
1501 ; ++constructed){ | 1589 ; ++constructed){ |
1502 dst_buckets[constructed].clone_from | 1590 dst_buckets[constructed].clone_from |
1503 ( src_buckets[constructed] | 1591 ( src_buckets[constructed] |
1504 , NodeCloner(cloner, &this->priv_real_value_traits()), node_disp); | 1592 , NodeCloner(cloner, &this->priv_value_traits()), node_disp); |
1505 } | 1593 } |
1506 if(src_bucket_count != dst_bucket_count){ | 1594 if(src_bucket_count != dst_bucket_count){ |
1507 //Now insert the remaining ones using the modulo trick | 1595 //Now insert the remaining ones using the modulo trick |
1508 for(//"constructed" comes from the previous loop | 1596 for(//"constructed" comes from the previous loop |
1509 ; constructed < src_bucket_count | 1597 ; constructed < src_bucket_count |
1512 dst_buckets[detail::hash_to_bucket_split<power_2_buckets, incremental>(constructed, dst_bucket_count, dst_bucket_count)]; | 1600 dst_buckets[detail::hash_to_bucket_split<power_2_buckets, incremental>(constructed, dst_bucket_count, dst_bucket_count)]; |
1513 bucket_type &src_b = src_buckets[constructed]; | 1601 bucket_type &src_b = src_buckets[constructed]; |
1514 for( siterator b(src_b.begin()), e(src_b.end()) | 1602 for( siterator b(src_b.begin()), e(src_b.end()) |
1515 ; b != e | 1603 ; b != e |
1516 ; ++b){ | 1604 ; ++b){ |
1517 dst_b.push_front(*(NodeCloner(cloner, &this->priv_real_value_traits())(*b.pointed_node()))); | 1605 dst_b.push_front(*(NodeCloner(cloner, &this->priv_value_traits())(*b.pointed_node()))); |
1518 } | 1606 } |
1519 } | 1607 } |
1520 } | 1608 } |
1521 this->priv_hasher() = src.priv_hasher(); | 1609 this->priv_hasher() = src.priv_hasher(); |
1522 this->priv_equal() = src.priv_equal(); | 1610 this->priv_equal() = src.priv_equal(); |
1527 this->priv_erasure_update_cache(); | 1615 this->priv_erasure_update_cache(); |
1528 } | 1616 } |
1529 else if(store_hash){ | 1617 else if(store_hash){ |
1530 //Unlike previous cloning algorithm, this can throw | 1618 //Unlike previous cloning algorithm, this can throw |
1531 //if cloner, hasher or comparison functor throw | 1619 //if cloner, hasher or comparison functor throw |
1532 const_iterator b(src.begin()), e(src.end()); | 1620 const_iterator b(src.cbegin()), e(src.cend()); |
1533 detail::exception_disposer<hashtable_impl, Disposer> | 1621 detail::exception_disposer<hashtable_impl, Disposer> |
1534 rollback(*this, disposer); | 1622 rollback(*this, disposer); |
1535 for(; b != e; ++b){ | 1623 for(; b != e; ++b){ |
1536 std::size_t hash_value = this->priv_stored_or_compute_hash(*b, store_hash_t());; | 1624 std::size_t hash_value = this->priv_stored_or_compute_hash(*b, store_hash_t());; |
1537 this->priv_insert_equal_with_hash(*cloner(*b), hash_value); | 1625 this->priv_insert_equal_with_hash(*cloner(*b), hash_value); |
1539 rollback.release(); | 1627 rollback.release(); |
1540 } | 1628 } |
1541 else{ | 1629 else{ |
1542 //Unlike previous cloning algorithm, this can throw | 1630 //Unlike previous cloning algorithm, this can throw |
1543 //if cloner, hasher or comparison functor throw | 1631 //if cloner, hasher or comparison functor throw |
1544 const_iterator b(src.begin()), e(src.end()); | 1632 const_iterator b(src.cbegin()), e(src.cend()); |
1545 detail::exception_disposer<hashtable_impl, Disposer> | 1633 detail::exception_disposer<hashtable_impl, Disposer> |
1546 rollback(*this, disposer); | 1634 rollback(*this, disposer); |
1547 for(; b != e; ++b){ | 1635 for(; b != e; ++b){ |
1548 this->insert_equal(*cloner(*b)); | 1636 this->insert_equal(*cloner(*b)); |
1549 } | 1637 } |
1577 //! <b>Requires</b>: Dereferencing iterator must yield an lvalue | 1665 //! <b>Requires</b>: Dereferencing iterator must yield an lvalue |
1578 //! of type value_type. | 1666 //! of type value_type. |
1579 //! | 1667 //! |
1580 //! <b>Effects</b>: Equivalent to this->insert_equal(t) for each element in [b, e). | 1668 //! <b>Effects</b>: Equivalent to this->insert_equal(t) for each element in [b, e). |
1581 //! | 1669 //! |
1582 //! <b>Complexity</b>: Average case O(N), where N is std::distance(b, e). | 1670 //! <b>Complexity</b>: Average case O(N), where N is distance(b, e). |
1583 //! Worst case O(N*this->size()). | 1671 //! Worst case O(N*this->size()). |
1584 //! | 1672 //! |
1585 //! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee. | 1673 //! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee. |
1586 //! | 1674 //! |
1587 //! <b>Note</b>: Does not affect the validity of iterators and references. | 1675 //! <b>Note</b>: Does not affect the validity of iterators and references. |
1623 //! <b>Requires</b>: Dereferencing iterator must yield an lvalue | 1711 //! <b>Requires</b>: Dereferencing iterator must yield an lvalue |
1624 //! of type value_type. | 1712 //! of type value_type. |
1625 //! | 1713 //! |
1626 //! <b>Effects</b>: Equivalent to this->insert_unique(t) for each element in [b, e). | 1714 //! <b>Effects</b>: Equivalent to this->insert_unique(t) for each element in [b, e). |
1627 //! | 1715 //! |
1628 //! <b>Complexity</b>: Average case O(N), where N is std::distance(b, e). | 1716 //! <b>Complexity</b>: Average case O(N), where N is distance(b, e). |
1629 //! Worst case O(N*this->size()). | 1717 //! Worst case O(N*this->size()). |
1630 //! | 1718 //! |
1631 //! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee. | 1719 //! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee. |
1632 //! | 1720 //! |
1633 //! <b>Note</b>: Does not affect the validity of iterators and references. | 1721 //! <b>Note</b>: Does not affect the validity of iterators and references. |
1736 void erase(const_iterator i) | 1824 void erase(const_iterator i) |
1737 { this->erase_and_dispose(i, detail::null_disposer()); } | 1825 { this->erase_and_dispose(i, detail::null_disposer()); } |
1738 | 1826 |
1739 //! <b>Effects</b>: Erases the range pointed to by b end e. | 1827 //! <b>Effects</b>: Erases the range pointed to by b end e. |
1740 //! | 1828 //! |
1741 //! <b>Complexity</b>: Average case O(std::distance(b, e)), | 1829 //! <b>Complexity</b>: Average case O(distance(b, e)), |
1742 //! worst case O(this->size()). | 1830 //! worst case O(this->size()). |
1743 //! | 1831 //! |
1744 //! <b>Throws</b>: Nothing. | 1832 //! <b>Throws</b>: Nothing. |
1745 //! | 1833 //! |
1746 //! <b>Note</b>: Invalidates the iterators (but not the references) | 1834 //! <b>Note</b>: Invalidates the iterators (but not the references) |
1813 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw. | 1901 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw. |
1814 //! | 1902 //! |
1815 //! <b>Effects</b>: Erases the range pointed to by b end e. | 1903 //! <b>Effects</b>: Erases the range pointed to by b end e. |
1816 //! Disposer::operator()(pointer) is called for the removed elements. | 1904 //! Disposer::operator()(pointer) is called for the removed elements. |
1817 //! | 1905 //! |
1818 //! <b>Complexity</b>: Average case O(std::distance(b, e)), | 1906 //! <b>Complexity</b>: Average case O(distance(b, e)), |
1819 //! worst case O(this->size()). | 1907 //! worst case O(this->size()). |
1820 //! | 1908 //! |
1821 //! <b>Throws</b>: Nothing. | 1909 //! <b>Throws</b>: Nothing. |
1822 //! | 1910 //! |
1823 //! <b>Note</b>: Invalidates the iterators | 1911 //! <b>Note</b>: Invalidates the iterators |
1936 //! | 2024 //! |
1937 //! <b>Note</b>: Invalidates the iterators (but not the references) | 2025 //! <b>Note</b>: Invalidates the iterators (but not the references) |
1938 //! to the erased elements. No destructors are called. | 2026 //! to the erased elements. No destructors are called. |
1939 void clear() | 2027 void clear() |
1940 { | 2028 { |
1941 this->priv_clear_buckets(); | 2029 this->data_type::internal.priv_clear_buckets_and_cache(); |
1942 this->priv_size_traits().set_size(size_type(0)); | 2030 this->priv_size_traits().set_size(size_type(0)); |
1943 } | 2031 } |
1944 | 2032 |
1945 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw. | 2033 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw. |
1946 //! | 2034 //! |
2151 { | 2239 { |
2152 size_type bucket_n1, bucket_n2, cnt; | 2240 size_type bucket_n1, bucket_n2, cnt; |
2153 std::pair<siterator, siterator> ret = | 2241 std::pair<siterator, siterator> ret = |
2154 this->priv_equal_range(key, hash_func, equal_func, bucket_n1, bucket_n2, cnt); | 2242 this->priv_equal_range(key, hash_func, equal_func, bucket_n1, bucket_n2, cnt); |
2155 return std::pair<const_iterator, const_iterator> | 2243 return std::pair<const_iterator, const_iterator> |
2156 (const_iterator(ret.first, &this->get_bucket_value_traits()), const_iterator(ret.second, &this->get_bucket_value_traits())); | 2244 ( const_iterator(ret.first, &this->get_bucket_value_traits()) |
2245 , const_iterator(ret.second, &this->get_bucket_value_traits())); | |
2157 } | 2246 } |
2158 | 2247 |
2159 //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of | 2248 //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of |
2160 //! appropriate type. Otherwise the behavior is undefined. | 2249 //! appropriate type. Otherwise the behavior is undefined. |
2161 //! | 2250 //! |
2165 //! <b>Complexity</b>: Constant. | 2254 //! <b>Complexity</b>: Constant. |
2166 //! | 2255 //! |
2167 //! <b>Throws</b>: If the internal hash function throws. | 2256 //! <b>Throws</b>: If the internal hash function throws. |
2168 iterator iterator_to(reference value) | 2257 iterator iterator_to(reference value) |
2169 { | 2258 { |
2170 return iterator(bucket_type::s_iterator_to(this->priv_value_to_node(value)), &this->get_bucket_value_traits()); | 2259 return iterator(bucket_type::s_iterator_to |
2260 (this->priv_value_to_node(value)), &this->get_bucket_value_traits()); | |
2171 } | 2261 } |
2172 | 2262 |
2173 //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of | 2263 //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of |
2174 //! appropriate type. Otherwise the behavior is undefined. | 2264 //! appropriate type. Otherwise the behavior is undefined. |
2175 //! | 2265 //! |
2179 //! <b>Complexity</b>: Constant. | 2269 //! <b>Complexity</b>: Constant. |
2180 //! | 2270 //! |
2181 //! <b>Throws</b>: If the internal hash function throws. | 2271 //! <b>Throws</b>: If the internal hash function throws. |
2182 const_iterator iterator_to(const_reference value) const | 2272 const_iterator iterator_to(const_reference value) const |
2183 { | 2273 { |
2184 siterator sit = bucket_type::s_iterator_to(const_cast<node &>(this->priv_value_to_node(value))); | 2274 node_reference r = *pointer_traits<node_ptr>::const_cast_from |
2275 (pointer_traits<const_node_ptr>::pointer_to(this->priv_value_to_node(value))); | |
2276 siterator sit = bucket_type::s_iterator_to(r); | |
2185 return const_iterator(sit, &this->get_bucket_value_traits()); | 2277 return const_iterator(sit, &this->get_bucket_value_traits()); |
2186 } | 2278 } |
2187 | 2279 |
2188 //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of | 2280 //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of |
2189 //! appropriate type. Otherwise the behavior is undefined. | 2281 //! appropriate type. Otherwise the behavior is undefined. |
2198 //! <b>Note</b>: This static function is available only if the <i>value traits</i> | 2290 //! <b>Note</b>: This static function is available only if the <i>value traits</i> |
2199 //! is stateless. | 2291 //! is stateless. |
2200 static local_iterator s_local_iterator_to(reference value) | 2292 static local_iterator s_local_iterator_to(reference value) |
2201 { | 2293 { |
2202 BOOST_STATIC_ASSERT((!stateful_value_traits)); | 2294 BOOST_STATIC_ASSERT((!stateful_value_traits)); |
2203 siterator sit = bucket_type::s_iterator_to(((hashtable_impl*)0)->priv_value_to_node(value)); | 2295 siterator sit = bucket_type::s_iterator_to(*value_traits::to_node_ptr(value)); |
2204 return local_iterator(sit, const_real_value_traits_ptr()); | 2296 return local_iterator(sit, const_value_traits_ptr()); |
2205 } | 2297 } |
2206 | 2298 |
2207 //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of | 2299 //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of |
2208 //! appropriate type. Otherwise the behavior is undefined. | 2300 //! appropriate type. Otherwise the behavior is undefined. |
2209 //! | 2301 //! |
2217 //! <b>Note</b>: This static function is available only if the <i>value traits</i> | 2309 //! <b>Note</b>: This static function is available only if the <i>value traits</i> |
2218 //! is stateless. | 2310 //! is stateless. |
2219 static const_local_iterator s_local_iterator_to(const_reference value) | 2311 static const_local_iterator s_local_iterator_to(const_reference value) |
2220 { | 2312 { |
2221 BOOST_STATIC_ASSERT((!stateful_value_traits)); | 2313 BOOST_STATIC_ASSERT((!stateful_value_traits)); |
2222 siterator sit = bucket_type::s_iterator_to(((hashtable_impl*)0)->priv_value_to_node(const_cast<value_type&>(value))); | 2314 node_reference r = *pointer_traits<node_ptr>::const_cast_from |
2223 return const_local_iterator(sit, const_real_value_traits_ptr()); | 2315 (value_traits::to_node_ptr(value)); |
2316 siterator sit = bucket_type::s_iterator_to(r); | |
2317 return const_local_iterator(sit, const_value_traits_ptr()); | |
2224 } | 2318 } |
2225 | 2319 |
2226 //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of | 2320 //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of |
2227 //! appropriate type. Otherwise the behavior is undefined. | 2321 //! appropriate type. Otherwise the behavior is undefined. |
2228 //! | 2322 //! |
2233 //! | 2327 //! |
2234 //! <b>Throws</b>: Nothing. | 2328 //! <b>Throws</b>: Nothing. |
2235 local_iterator local_iterator_to(reference value) | 2329 local_iterator local_iterator_to(reference value) |
2236 { | 2330 { |
2237 siterator sit = bucket_type::s_iterator_to(this->priv_value_to_node(value)); | 2331 siterator sit = bucket_type::s_iterator_to(this->priv_value_to_node(value)); |
2238 return local_iterator(sit, this->real_value_traits_ptr()); | 2332 return local_iterator(sit, this->priv_value_traits_ptr()); |
2239 } | 2333 } |
2240 | 2334 |
2241 //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of | 2335 //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of |
2242 //! appropriate type. Otherwise the behavior is undefined. | 2336 //! appropriate type. Otherwise the behavior is undefined. |
2243 //! | 2337 //! |
2247 //! <b>Complexity</b>: Constant. | 2341 //! <b>Complexity</b>: Constant. |
2248 //! | 2342 //! |
2249 //! <b>Throws</b>: Nothing. | 2343 //! <b>Throws</b>: Nothing. |
2250 const_local_iterator local_iterator_to(const_reference value) const | 2344 const_local_iterator local_iterator_to(const_reference value) const |
2251 { | 2345 { |
2252 siterator sit = bucket_type::s_iterator_to | 2346 node_reference r = *pointer_traits<node_ptr>::const_cast_from |
2253 (const_cast<node &>(this->priv_value_to_node(value))); | 2347 (pointer_traits<const_node_ptr>::pointer_to(this->priv_value_to_node(value))); |
2254 return const_local_iterator(sit, this->real_value_traits_ptr()); | 2348 siterator sit = bucket_type::s_iterator_to(r); |
2349 return const_local_iterator(sit, this->priv_value_traits_ptr()); | |
2255 } | 2350 } |
2256 | 2351 |
2257 //! <b>Effects</b>: Returns the number of buckets passed in the constructor | 2352 //! <b>Effects</b>: Returns the number of buckets passed in the constructor |
2258 //! or the last rehash function. | 2353 //! or the last rehash function. |
2259 //! | 2354 //! |
2319 //! <b>Throws</b>: Nothing. | 2414 //! <b>Throws</b>: Nothing. |
2320 //! | 2415 //! |
2321 //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range | 2416 //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range |
2322 //! containing all of the elements in the nth bucket. | 2417 //! containing all of the elements in the nth bucket. |
2323 local_iterator begin(size_type n) | 2418 local_iterator begin(size_type n) |
2324 { return local_iterator(this->priv_bucket_pointer()[n].begin(), this->real_value_traits_ptr()); } | 2419 { return local_iterator(this->priv_bucket_pointer()[n].begin(), this->priv_value_traits_ptr()); } |
2325 | 2420 |
2326 //! <b>Requires</b>: n is in the range [0, this->bucket_count()). | 2421 //! <b>Requires</b>: n is in the range [0, this->bucket_count()). |
2327 //! | 2422 //! |
2328 //! <b>Effects</b>: Returns a const_local_iterator pointing to the beginning | 2423 //! <b>Effects</b>: Returns a const_local_iterator pointing to the beginning |
2329 //! of the sequence stored in the bucket n. | 2424 //! of the sequence stored in the bucket n. |
2348 //! | 2443 //! |
2349 //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range | 2444 //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range |
2350 //! containing all of the elements in the nth bucket. | 2445 //! containing all of the elements in the nth bucket. |
2351 const_local_iterator cbegin(size_type n) const | 2446 const_local_iterator cbegin(size_type n) const |
2352 { | 2447 { |
2353 siterator sit = const_cast<bucket_type&>(this->priv_bucket_pointer()[n]).begin(); | 2448 bucket_reference br = pointer_traits<bucket_ptr>::const_cast_from(this->priv_bucket_pointer())[n]; |
2354 return const_local_iterator(sit, this->real_value_traits_ptr()); | 2449 return const_local_iterator(br.begin(), this->priv_value_traits_ptr()); |
2355 } | 2450 } |
2356 | 2451 |
2357 //! <b>Requires</b>: n is in the range [0, this->bucket_count()). | 2452 //! <b>Requires</b>: n is in the range [0, this->bucket_count()). |
2358 //! | 2453 //! |
2359 //! <b>Effects</b>: Returns a local_iterator pointing to the end | 2454 //! <b>Effects</b>: Returns a local_iterator pointing to the end |
2364 //! <b>Throws</b>: Nothing. | 2459 //! <b>Throws</b>: Nothing. |
2365 //! | 2460 //! |
2366 //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range | 2461 //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range |
2367 //! containing all of the elements in the nth bucket. | 2462 //! containing all of the elements in the nth bucket. |
2368 local_iterator end(size_type n) | 2463 local_iterator end(size_type n) |
2369 { return local_iterator(this->priv_bucket_pointer()[n].end(), this->real_value_traits_ptr()); } | 2464 { return local_iterator(this->priv_bucket_pointer()[n].end(), this->priv_value_traits_ptr()); } |
2370 | 2465 |
2371 //! <b>Requires</b>: n is in the range [0, this->bucket_count()). | 2466 //! <b>Requires</b>: n is in the range [0, this->bucket_count()). |
2372 //! | 2467 //! |
2373 //! <b>Effects</b>: Returns a const_local_iterator pointing to the end | 2468 //! <b>Effects</b>: Returns a const_local_iterator pointing to the end |
2374 //! of the sequence stored in the bucket n. | 2469 //! of the sequence stored in the bucket n. |
2393 //! | 2488 //! |
2394 //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range | 2489 //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range |
2395 //! containing all of the elements in the nth bucket. | 2490 //! containing all of the elements in the nth bucket. |
2396 const_local_iterator cend(size_type n) const | 2491 const_local_iterator cend(size_type n) const |
2397 { | 2492 { |
2398 return const_local_iterator ( const_cast<bucket_type&>(this->priv_bucket_pointer()[n]).end() | 2493 bucket_reference br = pointer_traits<bucket_ptr>::const_cast_from(this->priv_bucket_pointer())[n]; |
2399 , this->real_value_traits_ptr()); | 2494 return const_local_iterator ( br.end(), this->priv_value_traits_ptr()); |
2400 } | 2495 } |
2401 | 2496 |
2402 //! <b>Requires</b>: new_bucket_traits can hold a pointer to a new bucket array | 2497 //! <b>Requires</b>: new_bucket_traits can hold a pointer to a new bucket array |
2403 //! or the same as the old bucket array with a different length. new_size is the length of the | 2498 //! or the same as the old bucket array with a different length. new_size is the length of the |
2404 //! the array pointed by new_buckets. If new_bucket_traits.bucket_begin() == this->bucket_pointer() | 2499 //! the array pointed by new_buckets. If new_bucket_traits.bucket_begin() == this->bucket_pointer() |
2501 } | 2596 } |
2502 } | 2597 } |
2503 | 2598 |
2504 this->priv_size_traits().set_size(size_backup); | 2599 this->priv_size_traits().set_size(size_backup); |
2505 this->priv_split_traits().set_size(new_bucket_count); | 2600 this->priv_split_traits().set_size(new_bucket_count); |
2506 this->priv_real_bucket_traits() = new_bucket_traits; | 2601 this->priv_bucket_traits() = new_bucket_traits; |
2507 this->priv_initialize_cache(); | 2602 this->priv_initialize_cache(); |
2508 this->priv_insertion_update_cache(new_first_bucket_num); | 2603 this->priv_insertion_update_cache(new_first_bucket_num); |
2509 rollback1.release(); | 2604 rollback1.release(); |
2510 rollback2.release(); | 2605 rollback2.release(); |
2511 } | 2606 } |
2614 return false; | 2709 return false; |
2615 } | 2710 } |
2616 | 2711 |
2617 const size_type ini_n = this->priv_get_cache_bucket_num(); | 2712 const size_type ini_n = this->priv_get_cache_bucket_num(); |
2618 const bucket_ptr old_buckets = this->priv_bucket_pointer(); | 2713 const bucket_ptr old_buckets = this->priv_bucket_pointer(); |
2619 this->priv_real_bucket_traits() = new_bucket_traits; | 2714 this->priv_bucket_traits() = new_bucket_traits; |
2620 if(new_bucket_traits.bucket_begin() != old_buckets){ | 2715 if(new_bucket_traits.bucket_begin() != old_buckets){ |
2621 for(size_type n = ini_n; n < split_idx; ++n){ | 2716 for(size_type n = ini_n; n < split_idx; ++n){ |
2622 bucket_type &new_bucket = new_bucket_traits.bucket_begin()[n]; | 2717 bucket_type &new_bucket = new_bucket_traits.bucket_begin()[n]; |
2623 bucket_type &old_bucket = old_buckets[n]; | 2718 bucket_type &old_bucket = old_buckets[n]; |
2624 new_bucket.splice_after(new_bucket.cbefore_begin(), old_bucket); | 2719 new_bucket.splice_after(new_bucket.cbefore_begin(), old_bucket); |
2653 //! <b>Complexity</b>: Amortized constant time. | 2748 //! <b>Complexity</b>: Amortized constant time. |
2654 //! | 2749 //! |
2655 //! <b>Throws</b>: Nothing. | 2750 //! <b>Throws</b>: Nothing. |
2656 static size_type suggested_upper_bucket_count(size_type n) | 2751 static size_type suggested_upper_bucket_count(size_type n) |
2657 { | 2752 { |
2658 const std::size_t *primes = &detail::prime_list_holder<0>::prime_list[0]; | 2753 const std::size_t *primes = &prime_list_holder<0>::prime_list[0]; |
2659 const std::size_t *primes_end = primes + detail::prime_list_holder<0>::prime_list_size; | 2754 const std::size_t *primes_end = primes + prime_list_holder<0>::prime_list_size; |
2660 std::size_t const* bound = std::lower_bound(primes, primes_end, n); | 2755 std::size_t const* bound = std::lower_bound(primes, primes_end, n); |
2661 if(bound == primes_end) | 2756 bound -= (bound == primes_end); |
2662 --bound; | |
2663 return size_type(*bound); | 2757 return size_type(*bound); |
2664 } | 2758 } |
2665 | 2759 |
2666 //! <b>Effects</b>: Returns the nearest new bucket count optimized for | 2760 //! <b>Effects</b>: Returns the nearest new bucket count optimized for |
2667 //! the container that is smaller or equal than n. This suggestion can be | 2761 //! the container that is smaller or equal than n. This suggestion can be |
2672 //! <b>Complexity</b>: Amortized constant time. | 2766 //! <b>Complexity</b>: Amortized constant time. |
2673 //! | 2767 //! |
2674 //! <b>Throws</b>: Nothing. | 2768 //! <b>Throws</b>: Nothing. |
2675 static size_type suggested_lower_bucket_count(size_type n) | 2769 static size_type suggested_lower_bucket_count(size_type n) |
2676 { | 2770 { |
2677 const std::size_t *primes = &detail::prime_list_holder<0>::prime_list[0]; | 2771 const std::size_t *primes = &prime_list_holder<0>::prime_list[0]; |
2678 const std::size_t *primes_end = primes + detail::prime_list_holder<0>::prime_list_size; | 2772 const std::size_t *primes_end = primes + prime_list_holder<0>::prime_list_size; |
2679 size_type const* bound = std::upper_bound(primes, primes_end, n); | 2773 size_type const* bound = std::upper_bound(primes, primes_end, n); |
2680 if(bound != primes) | 2774 bound -= (bound != primes); |
2681 --bound; | |
2682 return size_type(*bound); | 2775 return size_type(*bound); |
2683 } | 2776 } |
2684 | |
2685 /// @cond | 2777 /// @cond |
2778 void check() const {} | |
2686 private: | 2779 private: |
2687 | 2780 size_traits &priv_size_traits() |
2688 void priv_clear_buckets(bucket_ptr buckets_ptr, size_type bucket_cnt) | 2781 { return static_cast<size_traits&>(static_cast<data_type&>(*this)); } |
2689 { | 2782 |
2690 for(; bucket_cnt--; ++buckets_ptr){ | 2783 const size_traits &priv_size_traits() const |
2691 if(safemode_or_autounlink){ | 2784 { return static_cast<const size_traits&>(static_cast<const data_type&>(*this)); } |
2692 bucket_plus_vtraits_t::priv_clear_group_nodes(*buckets_ptr, optimize_multikey_t()); | 2785 |
2693 buckets_ptr->clear_and_dispose(detail::init_disposer<node_algorithms>()); | 2786 bucket_ptr priv_bucket_pointer() const |
2694 } | 2787 { return this->data_type::internal.internal.internal.internal.priv_bucket_pointer(); } |
2695 else{ | 2788 |
2696 buckets_ptr->clear(); | 2789 SizeType priv_bucket_count() const |
2697 } | 2790 { return this->data_type::internal.internal.internal.internal.priv_bucket_count(); } |
2698 } | 2791 |
2699 this->priv_initialize_cache(); | 2792 const bucket_plus_vtraits<ValueTraits, BucketTraits> &get_bucket_value_traits() const |
2700 } | 2793 { return this->data_type::internal.internal.internal.internal.get_bucket_value_traits(); } |
2701 | 2794 |
2702 void priv_initialize_buckets() | 2795 bucket_plus_vtraits<ValueTraits, BucketTraits> &get_bucket_value_traits() |
2703 { this->priv_clear_buckets(this->priv_bucket_pointer(), this->priv_bucket_count()); } | 2796 { return this->data_type::internal.internal.internal.internal.get_bucket_value_traits(); } |
2704 | 2797 |
2705 void priv_clear_buckets() | 2798 bucket_traits &priv_bucket_traits() |
2706 { | 2799 { return this->data_type::internal.internal.internal.internal.priv_bucket_traits(); } |
2707 this->priv_clear_buckets | 2800 |
2708 ( this->priv_get_cache() | 2801 const bucket_traits &priv_bucket_traits() const |
2709 , this->priv_bucket_count() - (this->priv_get_cache() - this->priv_bucket_pointer())); | 2802 { return this->data_type::internal.internal.internal.internal.priv_bucket_traits(); } |
2710 } | 2803 |
2804 value_traits &priv_value_traits() | |
2805 { return this->data_type::internal.internal.internal.internal.priv_value_traits(); } | |
2806 | |
2807 const value_traits &priv_value_traits() const | |
2808 { return this->data_type::internal.internal.internal.internal.priv_value_traits(); } | |
2809 | |
2810 const_value_traits_ptr priv_value_traits_ptr() const | |
2811 { return this->data_type::internal.internal.internal.internal.priv_value_traits_ptr(); } | |
2812 | |
2813 siterator priv_invalid_local_it() const | |
2814 { return this->data_type::internal.internal.internal.internal.priv_invalid_local_it(); } | |
2815 | |
2816 split_traits &priv_split_traits() | |
2817 { return this->data_type::internal.priv_split_traits(); } | |
2818 | |
2819 const split_traits &priv_split_traits() const | |
2820 { return this->data_type::internal.priv_split_traits(); } | |
2821 | |
2822 bucket_ptr priv_get_cache() | |
2823 { return this->data_type::internal.internal.priv_get_cache(); } | |
2824 | |
2825 void priv_initialize_cache() | |
2826 { return this->data_type::internal.internal.priv_initialize_cache(); } | |
2827 | |
2828 siterator priv_begin() const | |
2829 { return this->data_type::internal.internal.priv_begin(); } | |
2830 | |
2831 const value_equal &priv_equal() const | |
2832 { return this->data_type::internal.internal.priv_equal(); } | |
2833 | |
2834 value_equal &priv_equal() | |
2835 { return this->data_type::internal.internal.priv_equal(); } | |
2836 | |
2837 const hasher &priv_hasher() const | |
2838 { return this->data_type::internal.internal.internal.priv_hasher(); } | |
2839 | |
2840 hasher &priv_hasher() | |
2841 { return this->data_type::internal.internal.internal.priv_hasher(); } | |
2842 | |
2843 void priv_swap_cache(hashtable_impl &h) | |
2844 { this->data_type::internal.internal.priv_swap_cache(h.data_type::internal.internal); } | |
2845 | |
2846 node &priv_value_to_node(value_type &v) | |
2847 { return this->data_type::internal.internal.internal.internal.priv_value_to_node(v); } | |
2848 | |
2849 const node &priv_value_to_node(const value_type &v) const | |
2850 { return this->data_type::internal.internal.internal.internal.priv_value_to_node(v); } | |
2851 | |
2852 SizeType priv_get_cache_bucket_num() | |
2853 { return this->data_type::internal.internal.priv_get_cache_bucket_num(); } | |
2854 | |
2855 void priv_insertion_update_cache(SizeType n) | |
2856 { return this->data_type::internal.internal.priv_insertion_update_cache(n); } | |
2857 | |
2858 template<bool Boolean> | |
2859 std::size_t priv_stored_or_compute_hash(const value_type &v, detail::bool_<Boolean> b) const | |
2860 { return this->data_type::internal.internal.internal.priv_stored_or_compute_hash(v, b); } | |
2861 | |
2862 value_type &priv_value_from_slist_node(slist_node_ptr n) | |
2863 { return this->data_type::internal.internal.internal.internal.priv_value_from_slist_node(n); } | |
2864 | |
2865 const value_type &priv_value_from_slist_node(slist_node_ptr n) const | |
2866 { return this->data_type::internal.internal.internal.internal.priv_value_from_slist_node(n); } | |
2867 | |
2868 void priv_erasure_update_cache_range(SizeType first_bucket_num, SizeType last_bucket_num) | |
2869 { return this->data_type::internal.internal.priv_erasure_update_cache_range(first_bucket_num, last_bucket_num); } | |
2870 | |
2871 void priv_erasure_update_cache() | |
2872 { return this->data_type::internal.internal.priv_erasure_update_cache(); } | |
2873 | |
2874 static std::size_t priv_stored_hash(slist_node_ptr n, detail::true_ true_value) | |
2875 { return bucket_plus_vtraits<ValueTraits, BucketTraits>::priv_stored_hash(n, true_value); } | |
2876 | |
2877 static std::size_t priv_stored_hash(slist_node_ptr n, detail::false_ false_value) | |
2878 { return bucket_plus_vtraits<ValueTraits, BucketTraits>::priv_stored_hash(n, false_value); } | |
2711 | 2879 |
2712 std::size_t priv_hash_to_bucket(std::size_t hash_value) const | 2880 std::size_t priv_hash_to_bucket(std::size_t hash_value) const |
2713 { | 2881 { |
2714 return detail::hash_to_bucket_split<power_2_buckets, incremental> | 2882 return detail::hash_to_bucket_split<power_2_buckets, incremental> |
2715 (hash_value, this->priv_real_bucket_traits().bucket_count(), this->priv_split_traits().get_size()); | 2883 (hash_value, this->priv_bucket_traits().bucket_count(), this->priv_split_traits().get_size()); |
2716 } | 2884 } |
2717 | 2885 |
2718 template<class Disposer> | 2886 template<class Disposer> |
2719 void priv_erase_range_impl | 2887 void priv_erase_range_impl |
2720 (size_type bucket_num, siterator before_first_it, siterator end_sit, Disposer disposer, size_type &num_erased) | 2888 (size_type bucket_num, siterator before_first_it, siterator end_sit, Disposer disposer, size_type &num_erased) |
2788 return this->priv_hash_to_bucket | 2956 return this->priv_hash_to_bucket |
2789 (this->priv_stored_hash(it.pointed_node(), store_hash_t())); | 2957 (this->priv_stored_hash(it.pointed_node(), store_hash_t())); |
2790 } | 2958 } |
2791 | 2959 |
2792 std::size_t priv_get_bucket_num_hash_dispatch(siterator it, detail::false_) //NO store_hash | 2960 std::size_t priv_get_bucket_num_hash_dispatch(siterator it, detail::false_) //NO store_hash |
2793 { return this->priv_get_bucket_num_no_hash_store(it, optimize_multikey_t()); } | 2961 { return this->data_type::internal.internal.internal.internal.priv_get_bucket_num_no_hash_store(it, optimize_multikey_t()); } |
2794 | 2962 |
2795 static siterator priv_get_previous(bucket_type &b, siterator i) | 2963 static siterator priv_get_previous(bucket_type &b, siterator i) |
2796 { return bucket_plus_vtraits_t::priv_get_previous(b, i, optimize_multikey_t()); } | 2964 { return bucket_plus_vtraits_t::priv_get_previous(b, i, optimize_multikey_t()); } |
2797 | 2965 |
2798 static siterator priv_get_last(bucket_type &b) | 2966 static siterator priv_get_last(bucket_type &b) |
2946 siterator it = to_return.first; | 3114 siterator it = to_return.first; |
2947 if(optimize_multikey){ | 3115 if(optimize_multikey){ |
2948 to_return.second = bucket_type::s_iterator_to | 3116 to_return.second = bucket_type::s_iterator_to |
2949 (*node_traits::get_next(group_functions_t::get_last_in_group | 3117 (*node_traits::get_next(group_functions_t::get_last_in_group |
2950 (detail::dcast_bucket_ptr<node>(it.pointed_node()), optimize_multikey_t()))); | 3118 (detail::dcast_bucket_ptr<node>(it.pointed_node()), optimize_multikey_t()))); |
2951 cnt = std::distance(it, to_return.second); | 3119 |
3120 cnt = 0; | |
3121 for(; it != to_return.second; ++it){ ++cnt; } | |
2952 if(to_return.second != b.end()){ | 3122 if(to_return.second != b.end()){ |
2953 bucket_number_second = bucket_number_first; | 3123 bucket_number_second = bucket_number_first; |
2954 return to_return; | 3124 return to_return; |
2955 } | 3125 } |
2956 } | 3126 } |
3003 , class PackedOptions | 3173 , class PackedOptions |
3004 > | 3174 > |
3005 #else | 3175 #else |
3006 template <class T, bool UniqueKeys, class ...Options> | 3176 template <class T, bool UniqueKeys, class ...Options> |
3007 #endif | 3177 #endif |
3008 struct make_real_bucket_traits | 3178 struct make_bucket_traits |
3009 { | 3179 { |
3010 //Real value traits must be calculated from options | 3180 //Real value traits must be calculated from options |
3011 typedef typename detail::get_value_traits | 3181 typedef typename detail::get_value_traits |
3012 <T, typename PackedOptions::proto_value_traits>::type value_traits; | 3182 <T, typename PackedOptions::proto_value_traits>::type value_traits; |
3013 /* | 3183 |
3014 static const bool resizable_bucket_traits = | |
3015 detail::resizable_bool_is_true<bucket_traits_traits>::value;*/ | |
3016 typedef typename detail::get_real_value_traits<value_traits>::type real_value_traits; | |
3017 typedef typename PackedOptions::bucket_traits specified_bucket_traits; | 3184 typedef typename PackedOptions::bucket_traits specified_bucket_traits; |
3018 | 3185 |
3019 //Real bucket traits must be calculated from options and calculated value_traits | 3186 //Real bucket traits must be calculated from options and calculated value_traits |
3020 typedef typename detail::get_slist_impl | 3187 typedef typename detail::get_slist_impl |
3021 <typename detail::reduced_slist_node_traits | 3188 <typename detail::reduced_slist_node_traits |
3022 <typename real_value_traits::node_traits>::type | 3189 <typename value_traits::node_traits>::type |
3023 >::type slist_impl; | 3190 >::type slist_impl; |
3024 | 3191 |
3025 typedef typename | 3192 typedef typename |
3026 detail::if_c< detail::is_same | 3193 detail::if_c< detail::is_same |
3027 < specified_bucket_traits | 3194 < specified_bucket_traits |
3058 >::type packed_options; | 3225 >::type packed_options; |
3059 | 3226 |
3060 typedef typename detail::get_value_traits | 3227 typedef typename detail::get_value_traits |
3061 <T, typename packed_options::proto_value_traits>::type value_traits; | 3228 <T, typename packed_options::proto_value_traits>::type value_traits; |
3062 | 3229 |
3063 typedef typename make_real_bucket_traits | 3230 typedef typename make_bucket_traits |
3064 <T, false, packed_options>::type real_bucket_traits; | 3231 <T, false, packed_options>::type bucket_traits; |
3065 | 3232 |
3066 typedef hashtable_impl | 3233 typedef hashtable_impl |
3067 < value_traits | 3234 < value_traits |
3068 , typename packed_options::hash | 3235 , typename packed_options::hash |
3069 , typename packed_options::equal | 3236 , typename packed_options::equal |
3070 , typename packed_options::size_type | 3237 , typename packed_options::size_type |
3071 , real_bucket_traits | 3238 , bucket_traits |
3072 , (std::size_t(false)*hash_bool_flags::unique_keys_pos) | 3239 , (std::size_t(false)*hash_bool_flags::unique_keys_pos) |
3073 | (std::size_t(packed_options::constant_time_size)*hash_bool_flags::constant_time_size_pos) | 3240 | (std::size_t(packed_options::constant_time_size)*hash_bool_flags::constant_time_size_pos) |
3074 | (std::size_t(packed_options::power_2_buckets)*hash_bool_flags::power_2_buckets_pos) | 3241 | (std::size_t(packed_options::power_2_buckets)*hash_bool_flags::power_2_buckets_pos) |
3075 | (std::size_t(packed_options::cache_begin)*hash_bool_flags::cache_begin_pos) | 3242 | (std::size_t(packed_options::cache_begin)*hash_bool_flags::cache_begin_pos) |
3076 | (std::size_t(packed_options::compare_hash)*hash_bool_flags::compare_hash_pos) | 3243 | (std::size_t(packed_options::compare_hash)*hash_bool_flags::compare_hash_pos) |
3106 >::type Base; | 3273 >::type Base; |
3107 BOOST_MOVABLE_BUT_NOT_COPYABLE(hashtable) | 3274 BOOST_MOVABLE_BUT_NOT_COPYABLE(hashtable) |
3108 | 3275 |
3109 public: | 3276 public: |
3110 typedef typename Base::value_traits value_traits; | 3277 typedef typename Base::value_traits value_traits; |
3111 typedef typename Base::real_value_traits real_value_traits; | |
3112 typedef typename Base::iterator iterator; | 3278 typedef typename Base::iterator iterator; |
3113 typedef typename Base::const_iterator const_iterator; | 3279 typedef typename Base::const_iterator const_iterator; |
3114 typedef typename Base::bucket_ptr bucket_ptr; | 3280 typedef typename Base::bucket_ptr bucket_ptr; |
3115 typedef typename Base::size_type size_type; | 3281 typedef typename Base::size_type size_type; |
3116 typedef typename Base::hasher hasher; | 3282 typedef typename Base::hasher hasher; |
3117 typedef typename Base::bucket_traits bucket_traits; | 3283 typedef typename Base::bucket_traits bucket_traits; |
3118 typedef typename Base::key_equal key_equal; | 3284 typedef typename Base::key_equal key_equal; |
3119 | 3285 |
3120 //Assert if passed value traits are compatible with the type | 3286 //Assert if passed value traits are compatible with the type |
3121 BOOST_STATIC_ASSERT((detail::is_same<typename real_value_traits::value_type, T>::value)); | 3287 BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value)); |
3122 | 3288 |
3123 explicit hashtable ( const bucket_traits &b_traits | 3289 explicit hashtable ( const bucket_traits &b_traits |
3124 , const hasher & hash_func = hasher() | 3290 , const hasher & hash_func = hasher() |
3125 , const key_equal &equal_func = key_equal() | 3291 , const key_equal &equal_func = key_equal() |
3126 , const value_traits &v_traits = value_traits()) | 3292 , const value_traits &v_traits = value_traits()) |
3127 : Base(b_traits, hash_func, equal_func, v_traits) | 3293 : Base(b_traits, hash_func, equal_func, v_traits) |
3128 {} | 3294 {} |
3129 | 3295 |
3130 hashtable(BOOST_RV_REF(hashtable) x) | 3296 hashtable(BOOST_RV_REF(hashtable) x) |
3131 : Base(::boost::move(static_cast<Base&>(x))) | 3297 : Base(BOOST_MOVE_BASE(Base, x)) |
3132 {} | 3298 {} |
3133 | 3299 |
3134 hashtable& operator=(BOOST_RV_REF(hashtable) x) | 3300 hashtable& operator=(BOOST_RV_REF(hashtable) x) |
3135 { return static_cast<hashtable&>(this->Base::operator=(::boost::move(static_cast<Base&>(x)))); } | 3301 { return static_cast<hashtable&>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); } |
3136 }; | 3302 }; |
3137 | 3303 |
3138 #endif | 3304 #endif |
3139 | 3305 |
3140 } //namespace intrusive | 3306 } //namespace intrusive |