hash_index_node.hpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /* Copyright 2003-2008 Joaquin M Lopez Munoz.
  2. * Distributed under the Boost Software License, Version 1.0.
  3. * (See accompanying file LICENSE_1_0.txt or copy at
  4. * http://www.boost.org/LICENSE_1_0.txt)
  5. *
  6. * See http://www.boost.org/libs/multi_index for library home page.
  7. */
  8. #ifndef BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_NODE_HPP
  9. #define BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_NODE_HPP
  10. #if defined(_MSC_VER)&&(_MSC_VER>=1200)
  11. #pragma once
  12. #endif
  13. #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
  14. #include <boost/detail/allocator_utilities.hpp>
  15. #include <boost/multi_index/detail/prevent_eti.hpp>
  16. #include <functional>
  17. namespace boost{
  18. namespace multi_index{
  19. namespace detail{
  20. /* singly-linked node for use by hashed_index */
  21. template<typename Allocator>
  22. struct hashed_index_node_impl
  23. {
  24. typedef typename prevent_eti<
  25. Allocator,
  26. typename boost::detail::allocator::rebind_to<
  27. Allocator,hashed_index_node_impl
  28. >::type
  29. >::type::pointer pointer;
  30. typedef typename prevent_eti<
  31. Allocator,
  32. typename boost::detail::allocator::rebind_to<
  33. Allocator,hashed_index_node_impl
  34. >::type
  35. >::type::const_pointer const_pointer;
  36. pointer& next(){return next_;}
  37. pointer next()const{return next_;}
  38. /* algorithmic stuff */
  39. static void increment(pointer& x,pointer bbegin,pointer bend)
  40. {
  41. std::less_equal<pointer> leq;
  42. x=x->next();
  43. if(leq(bbegin,x)&&leq(x,bend)){ /* bucket node */
  44. do{
  45. ++x;
  46. }while(x->next()==x);
  47. x=x->next();
  48. }
  49. }
  50. static void link(pointer x,pointer pos)
  51. {
  52. x->next()=pos->next();
  53. pos->next()=x;
  54. };
  55. static void unlink(pointer x)
  56. {
  57. pointer y=x->next();
  58. while(y->next()!=x){y=y->next();}
  59. y->next()=x->next();
  60. }
  61. static pointer prev(pointer x)
  62. {
  63. pointer y=x->next();
  64. while(y->next()!=x){y=y->next();}
  65. return y;
  66. }
  67. static void unlink_next(pointer x)
  68. {
  69. x->next()=x->next()->next();
  70. }
  71. private:
  72. pointer next_;
  73. };
  74. template<typename Super>
  75. struct hashed_index_node_trampoline:
  76. prevent_eti<
  77. Super,
  78. hashed_index_node_impl<
  79. typename boost::detail::allocator::rebind_to<
  80. typename Super::allocator_type,
  81. char
  82. >::type
  83. >
  84. >::type
  85. {
  86. typedef typename prevent_eti<
  87. Super,
  88. hashed_index_node_impl<
  89. typename boost::detail::allocator::rebind_to<
  90. typename Super::allocator_type,
  91. char
  92. >::type
  93. >
  94. >::type impl_type;
  95. };
  96. template<typename Super>
  97. struct hashed_index_node:Super,hashed_index_node_trampoline<Super>
  98. {
  99. private:
  100. typedef hashed_index_node_trampoline<Super> trampoline;
  101. public:
  102. typedef typename trampoline::impl_type impl_type;
  103. typedef typename trampoline::pointer impl_pointer;
  104. typedef typename trampoline::const_pointer const_impl_pointer;
  105. impl_pointer impl()
  106. {
  107. return static_cast<impl_pointer>(
  108. static_cast<impl_type*>(static_cast<trampoline*>(this)));
  109. }
  110. const_impl_pointer impl()const
  111. {
  112. return static_cast<const_impl_pointer>(
  113. static_cast<const impl_type*>(static_cast<const trampoline*>(this)));
  114. }
  115. static hashed_index_node* from_impl(impl_pointer x)
  116. {
  117. return static_cast<hashed_index_node*>(
  118. static_cast<trampoline*>(&*x));
  119. }
  120. static const hashed_index_node* from_impl(const_impl_pointer x)
  121. {
  122. return static_cast<const hashed_index_node*>(
  123. static_cast<const trampoline*>(&*x));
  124. }
  125. static void increment(
  126. hashed_index_node*& x,impl_pointer bbegin,impl_pointer bend)
  127. {
  128. impl_pointer xi=x->impl();
  129. trampoline::increment(xi,bbegin,bend);
  130. x=from_impl(xi);
  131. }
  132. };
  133. } /* namespace multi_index::detail */
  134. } /* namespace multi_index */
  135. } /* namespace boost */
  136. #endif