itestvalue.hpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Olaf Krzikalla 2004-2006.
  4. // (C) Copyright Ion Gaztanaga 2006-2013.
  5. //
  6. // Distributed under the Boost Software License, Version 1.0.
  7. // (See accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. // See http://www.boost.org/libs/intrusive for documentation.
  11. //
  12. /////////////////////////////////////////////////////////////////////////////
  13. #ifndef BOOST_INTRUSIVE_DETAIL_ITESTVALUE_HPP
  14. #define BOOST_INTRUSIVE_DETAIL_ITESTVALUE_HPP
  15. #include <iostream>
  16. #include <boost/intrusive/options.hpp>
  17. #include <boost/functional/hash.hpp>
  18. #include <boost/intrusive/pointer_traits.hpp>
  19. #include "nonhook_node.hpp"
  20. #include "int_holder.hpp"
  21. #include <boost/intrusive/detail/get_value_traits.hpp>
  22. #include <boost/container/vector.hpp>
  23. namespace boost{
  24. namespace intrusive{
  25. struct testvalue_filler
  26. {
  27. void *dummy_[3];
  28. };
  29. template<class Hooks>
  30. struct testvalue
  31. : testvalue_filler
  32. , Hooks::base_hook_type
  33. , Hooks::auto_base_hook_type
  34. {
  35. typename Hooks::member_hook_type node_;
  36. typename Hooks::auto_member_hook_type auto_node_;
  37. typename Hooks::nonhook_node_member_type nhn_member_;
  38. int_holder value_;
  39. testvalue()
  40. {}
  41. explicit testvalue(int i)
  42. : value_(i)
  43. {}
  44. testvalue (const testvalue& src)
  45. : value_(src.value_)
  46. {}
  47. // testvalue is used in boost::container::vector and thus prev and next
  48. // have to be handled appropriately when copied:
  49. testvalue & operator= (const testvalue& src)
  50. {
  51. Hooks::base_hook_type::operator=(static_cast<const typename Hooks::base_hook_type&>(src));
  52. Hooks::auto_base_hook_type::operator=(static_cast<const typename Hooks::auto_base_hook_type&>(src));
  53. this->node_ = src.node_;
  54. this->auto_node_ = src.auto_node_;
  55. this->nhn_member_ = src.nhn_member_;
  56. value_ = src.value_;
  57. return *this;
  58. }
  59. void swap_nodes(testvalue &other)
  60. {
  61. Hooks::base_hook_type::swap_nodes(static_cast<typename Hooks::base_hook_type&>(other));
  62. Hooks::auto_base_hook_type::swap_nodes(static_cast<typename Hooks::auto_base_hook_type&>(other));
  63. node_.swap_nodes(other.node_);
  64. auto_node_.swap_nodes(other.auto_node_);
  65. nhn_member_.swap_nodes(other.nhn_member_);
  66. }
  67. bool is_linked() const
  68. {
  69. return Hooks::base_hook_type::is_linked() ||
  70. Hooks::auto_base_hook_type::is_linked() ||
  71. node_.is_linked() ||
  72. auto_node_.is_linked() ||
  73. nhn_member_.is_linked();
  74. }
  75. const int_holder &get_int_holder() const
  76. { return value_; }
  77. int int_value() const
  78. { return value_.int_value(); }
  79. ~testvalue()
  80. {}
  81. bool operator< (const testvalue &other) const
  82. { return value_ < other.value_; }
  83. bool operator> (const testvalue &other) const
  84. { return value_ > other.value_; }
  85. bool operator==(const testvalue &other) const
  86. { return value_ == other.value_; }
  87. bool operator!=(const testvalue &other) const
  88. { return value_ != other.value_; }
  89. friend bool operator< (int other1, const testvalue &other2)
  90. { return other1 < other2.value_.int_; }
  91. friend bool operator> (int other1, const testvalue &other2)
  92. { return other1 > other2.value_.int_; }
  93. friend bool operator< (const testvalue &other1, int other2)
  94. { return other1.value_.int_ < other2; }
  95. friend bool operator> (const testvalue &other1, int other2)
  96. { return other1.value_.int_ > other2; }
  97. friend bool operator== (int other1, const testvalue &other2)
  98. { return other1 == other2.value_.int_; }
  99. friend bool operator== (const testvalue &other1, int other2)
  100. { return other1.value_.int_ == other2; }
  101. friend bool operator!= (int other1, const testvalue &other2)
  102. { return other1 != other2.value_.int_; }
  103. friend bool operator!= (const testvalue &other1, int other2)
  104. { return other1.value_.int_ != other2; }
  105. friend std::size_t hash_value(const testvalue&t)
  106. {
  107. boost::hash<int> hasher;
  108. return hasher((&t)->int_value());
  109. }
  110. };
  111. template<class T>
  112. std::size_t priority_hash(const T &t)
  113. { return boost::hash<int>()((&t)->int_value()); }
  114. std::size_t priority_hash(int i)
  115. { return boost::hash<int>()(i); }
  116. template <class T, class U>
  117. bool priority_order(const T& t1, const U& t2)
  118. {
  119. std::size_t hash1 = (priority_hash)(t1);
  120. boost::hash_combine(hash1, -hash1);
  121. std::size_t hash2 = (priority_hash)(t2);
  122. boost::hash_combine(hash2, -hash2);
  123. return hash1 < hash2;
  124. }
  125. template < typename Node_Algorithms, class Hooks>
  126. void swap_nodes(testvalue<Hooks>& lhs, testvalue<Hooks>& rhs)
  127. {
  128. lhs.swap_nodes(rhs);
  129. }
  130. template<class Hooks>
  131. std::ostream& operator<<
  132. (std::ostream& s, const testvalue<Hooks>& t)
  133. { return s << t.value_.int_value(); }
  134. struct even_odd
  135. {
  136. template < typename key_type_1, typename key_type_2 >
  137. bool operator()
  138. (const key_type_1& v1
  139. ,const key_type_2& v2) const
  140. {
  141. if (((&v1)->int_value() & 1) == ((&v2)->int_value() & 1))
  142. return (&v1)->int_value() < (&v2)->int_value();
  143. else
  144. return (&v2)->int_value() & 1;
  145. }
  146. };
  147. struct is_even
  148. {
  149. template <typename key_type>
  150. bool operator()
  151. (const key_type& v1) const
  152. { return ((&v1)->int_value() & 1) == 0; }
  153. };
  154. struct is_odd
  155. {
  156. template <typename key_type>
  157. bool operator()
  158. (const key_type& v1) const
  159. { return ((&v1)->int_value() & 1) != 0; }
  160. };
  161. template <typename>
  162. struct ValueContainer;
  163. template < class Hooks>
  164. struct ValueContainer< testvalue<Hooks> >
  165. {
  166. typedef boost::container::vector< testvalue<Hooks> > type;
  167. };
  168. template < typename Pointer >
  169. class heap_node_holder
  170. {
  171. typedef typename pointer_traits<Pointer>::element_type element_type;
  172. typedef Pointer pointer;
  173. typedef typename pointer_rebind<pointer, const element_type>::type const_pointer;
  174. public:
  175. heap_node_holder()
  176. : m_ptr(pointer_traits<Pointer>::pointer_to(*new element_type))
  177. {}
  178. ~heap_node_holder()
  179. { delete &*m_ptr; }
  180. const_pointer get_node() const
  181. { return m_ptr; }
  182. pointer get_node()
  183. { return m_ptr; }
  184. private:
  185. pointer m_ptr;
  186. };
  187. template<class Hooks>
  188. struct testvalue_traits
  189. : public Hooks
  190. {
  191. typedef testvalue< Hooks > value_type;
  192. //base
  193. typedef typename detail::get_base_value_traits
  194. < value_type
  195. , typename Hooks::base_hook_type
  196. >::type base_value_traits;
  197. //auto-base
  198. typedef typename detail::get_base_value_traits
  199. < value_type
  200. , typename Hooks::auto_base_hook_type
  201. >::type auto_base_value_traits;
  202. //member
  203. typedef typename detail::get_member_value_traits
  204. < member_hook
  205. < value_type
  206. , typename Hooks::member_hook_type
  207. , &value_type::node_
  208. >
  209. >::type member_value_traits;
  210. //auto-member
  211. typedef typename detail::get_member_value_traits
  212. < member_hook
  213. < value_type
  214. , typename Hooks::auto_member_hook_type
  215. , &value_type::auto_node_
  216. >
  217. >::type auto_member_value_traits;
  218. //nonmember
  219. typedef nonhook_node_member_value_traits
  220. < value_type
  221. , typename Hooks::nonhook_node_member_type
  222. , &value_type::nhn_member_
  223. , safe_link
  224. > nonhook_value_traits;
  225. };
  226. } //namespace intrusive{
  227. } //namespace boost{
  228. bool priority_order(int t1, int t2)
  229. {
  230. std::size_t hash1 = boost::hash<int>()(t1);
  231. boost::hash_combine(hash1, &t1);
  232. std::size_t hash2 = boost::hash<int>()(t2);
  233. boost::hash_combine(hash2, &t2);
  234. return hash1 < hash2;
  235. }
  236. #endif