scary_iterators_test.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2013-2013
  4. //
  5. // Distributed under the Boost Software License, Version 1.0.
  6. // (See accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //
  9. // See http://www.boost.org/libs/intrusive for documentation.
  10. //
  11. /////////////////////////////////////////////////////////////////////////////
  12. #include <boost/intrusive/list.hpp>
  13. #include <boost/intrusive/slist.hpp>
  14. #include <boost/intrusive/set.hpp>
  15. #include <boost/intrusive/unordered_set.hpp>
  16. #include <boost/intrusive/avl_set.hpp>
  17. #include <boost/intrusive/sg_set.hpp>
  18. #include <boost/intrusive/bs_set.hpp>
  19. #include <boost/intrusive/splay_set.hpp>
  20. #include <boost/intrusive/treap_set.hpp>
  21. #include <boost/intrusive/detail/mpl.hpp>
  22. #include <boost/static_assert.hpp>
  23. #include "smart_ptr.hpp"
  24. #include <functional> //std::greater/std::less
  25. using namespace boost::intrusive;
  26. struct my_tag;
  27. template<class VoidPtr = void*, link_mode_type mode = normal_link>
  28. class MyClass
  29. : public make_list_base_hook
  30. < void_pointer<VoidPtr>, link_mode<mode> >::type
  31. , public make_slist_base_hook
  32. < void_pointer<VoidPtr>, link_mode<mode> >::type
  33. , public make_set_base_hook
  34. < void_pointer<VoidPtr>, link_mode<mode> >::type
  35. , public make_unordered_set_base_hook
  36. < void_pointer<VoidPtr>, link_mode<mode> >::type
  37. , public make_avl_set_base_hook
  38. < void_pointer<VoidPtr>, link_mode<mode> >::type
  39. , public make_bs_set_base_hook
  40. < void_pointer<VoidPtr>, link_mode<mode> >::type
  41. {
  42. int int_;
  43. public:
  44. MyClass(int i)
  45. : int_(i)
  46. {}
  47. friend bool operator<(const MyClass &l, const MyClass &r)
  48. { return l.int_ < r.int_; }
  49. friend bool operator==(const MyClass &l, const MyClass &r)
  50. { return l.int_ == r.int_; }
  51. friend std::size_t hash_value(const MyClass &v)
  52. { return boost::hash_value(v.int_); }
  53. friend bool priority_order(const MyClass &l, const MyClass &r)
  54. { return l.int_ < r.int_; }
  55. };
  56. template<class T>
  57. struct inverse_priority
  58. {
  59. bool operator()(const T &l, const T &r)
  60. { return l.int_ > r.int_; }
  61. };
  62. template<class T>
  63. struct inverse_hash
  64. {
  65. bool operator()(const T &l)
  66. { return hash_value(l); }
  67. };
  68. template<class T>
  69. struct alternative_equal
  70. {
  71. bool operator()(const T &l, const T &r)
  72. { return l.int_ == r.int_; }
  73. };
  74. int main()
  75. {
  76. ////////////
  77. // list
  78. ////////////
  79. BOOST_STATIC_ASSERT((!detail::is_same< list<MyClass<> >::iterator
  80. , list<MyClass<> >::const_iterator
  81. >::value));
  82. //constant_time_size does not change iterator
  83. BOOST_STATIC_ASSERT((detail::is_same< list<MyClass<>, constant_time_size<true> >::iterator
  84. , list<MyClass<>, constant_time_size<false> >::iterator
  85. >::value));
  86. //void_pointer does change iterator
  87. BOOST_STATIC_ASSERT((!detail::is_same< list<MyClass<> >::iterator
  88. , list<MyClass<smart_ptr<void> > >::iterator
  89. >::value));
  90. //size_type does not change iterator
  91. BOOST_STATIC_ASSERT((detail::is_same< list<MyClass<>, size_type<unsigned int > >::iterator
  92. , list<MyClass<>, size_type<unsigned char> >::iterator
  93. >::value));
  94. ////////////
  95. // slist
  96. ////////////
  97. BOOST_STATIC_ASSERT((!detail::is_same< slist<MyClass<> >::iterator
  98. , slist<MyClass<> >::const_iterator
  99. >::value));
  100. //constant_time_size does not change iterator
  101. BOOST_STATIC_ASSERT((detail::is_same< slist<MyClass<>, constant_time_size<true> >::iterator
  102. , slist<MyClass<>, constant_time_size<false> >::iterator
  103. >::value));
  104. //void_pointer does change iterator
  105. BOOST_STATIC_ASSERT((!detail::is_same< slist<MyClass<> >::iterator
  106. , slist<MyClass<smart_ptr<void> > >::iterator
  107. >::value));
  108. //size_type does not change iterator
  109. BOOST_STATIC_ASSERT((detail::is_same< slist<MyClass<>, size_type<unsigned int > >::iterator
  110. , slist<MyClass<>, size_type<unsigned char> >::iterator
  111. >::value));
  112. //cache_last does not change iterator
  113. BOOST_STATIC_ASSERT((detail::is_same< slist<MyClass<>, cache_last<false> >::iterator
  114. , slist<MyClass<>, cache_last<true> >::iterator
  115. >::value));
  116. //linear does not change iterator
  117. BOOST_STATIC_ASSERT((detail::is_same< slist<MyClass<>, linear<false> >::iterator
  118. , slist<MyClass<>, linear<true> >::iterator
  119. >::value));
  120. ////////////
  121. // set
  122. ////////////
  123. BOOST_STATIC_ASSERT((!detail::is_same< set<MyClass<> >::iterator
  124. , set<MyClass<> >::const_iterator
  125. >::value));
  126. //constant_time_size does not change iterator
  127. BOOST_STATIC_ASSERT((detail::is_same< set<MyClass<>, constant_time_size<true> >::iterator
  128. , set<MyClass<>, constant_time_size<false> >::iterator
  129. >::value));
  130. //void_pointer does change iterator
  131. BOOST_STATIC_ASSERT((!detail::is_same< set<MyClass<> >::iterator
  132. , set<MyClass<smart_ptr<void> > >::iterator
  133. >::value));
  134. //size_type does not change iterator
  135. BOOST_STATIC_ASSERT((detail::is_same< set<MyClass<>, size_type<unsigned int > >::iterator
  136. , set<MyClass<>, size_type<unsigned char> >::iterator
  137. >::value));
  138. //compare does not change iterator
  139. BOOST_STATIC_ASSERT((detail::is_same< set<MyClass<>, compare< std::greater<MyClass<> > > >::iterator
  140. , set<MyClass<>, compare< std::less<MyClass<> > > >::iterator
  141. >::value));
  142. ////////////
  143. // avl_set
  144. ////////////
  145. BOOST_STATIC_ASSERT((!detail::is_same< avl_set<MyClass<> >::iterator
  146. , avl_set<MyClass<> >::const_iterator
  147. >::value));
  148. //constant_time_size does not change iterator
  149. BOOST_STATIC_ASSERT((detail::is_same< avl_set<MyClass<>, constant_time_size<true> >::iterator
  150. , avl_set<MyClass<>, constant_time_size<false> >::iterator
  151. >::value));
  152. //void_pointer does change iterator
  153. BOOST_STATIC_ASSERT((!detail::is_same< avl_set<MyClass<> >::iterator
  154. , avl_set<MyClass<smart_ptr<void> > >::iterator
  155. >::value));
  156. //size_type does not change iterator
  157. BOOST_STATIC_ASSERT((detail::is_same< avl_set<MyClass<>, size_type<unsigned int > >::iterator
  158. , avl_set<MyClass<>, size_type<unsigned char> >::iterator
  159. >::value));
  160. //compare does not change iterator
  161. BOOST_STATIC_ASSERT((detail::is_same< avl_set<MyClass<>, compare< std::greater<MyClass<> > > >::iterator
  162. , avl_set<MyClass<>, compare< std::less<MyClass<> > > >::iterator
  163. >::value));
  164. ////////////
  165. // sg_set
  166. ////////////
  167. BOOST_STATIC_ASSERT((!detail::is_same< sg_set<MyClass<> >::iterator
  168. , sg_set<MyClass<> >::const_iterator
  169. >::value));
  170. //void_pointer does change iterator
  171. BOOST_STATIC_ASSERT((!detail::is_same< sg_set<MyClass<> >::iterator
  172. , sg_set<MyClass<smart_ptr<void> > >::iterator
  173. >::value));
  174. //size_type does not change iterator
  175. BOOST_STATIC_ASSERT((detail::is_same< sg_set<MyClass<>, size_type<unsigned int > >::iterator
  176. , sg_set<MyClass<>, size_type<unsigned char> >::iterator
  177. >::value));
  178. //compare does not change iterator
  179. BOOST_STATIC_ASSERT((detail::is_same< sg_set<MyClass<>, compare< std::greater<MyClass<> > > >::iterator
  180. , sg_set<MyClass<>, compare< std::less<MyClass<> > > >::iterator
  181. >::value));
  182. //floating_point does not change iterator
  183. BOOST_STATIC_ASSERT((detail::is_same< sg_set<MyClass<>, floating_point<false> >::iterator
  184. , sg_set<MyClass<>, floating_point<true> >::iterator
  185. >::value));
  186. ////////////
  187. // bs_set
  188. ////////////
  189. BOOST_STATIC_ASSERT((!detail::is_same< bs_set<MyClass<> >::iterator
  190. , bs_set<MyClass<> >::const_iterator
  191. >::value));
  192. //constant_time_size does not change iterator
  193. BOOST_STATIC_ASSERT((detail::is_same< bs_set<MyClass<>, constant_time_size<true> >::iterator
  194. , bs_set<MyClass<>, constant_time_size<false> >::iterator
  195. >::value));
  196. //void_pointer does change iterator
  197. BOOST_STATIC_ASSERT((!detail::is_same< bs_set<MyClass<> >::iterator
  198. , bs_set<MyClass<smart_ptr<void> > >::iterator
  199. >::value));
  200. //size_type does not change iterator
  201. BOOST_STATIC_ASSERT((detail::is_same< bs_set<MyClass<>, size_type<unsigned int > >::iterator
  202. , bs_set<MyClass<>, size_type<unsigned char> >::iterator
  203. >::value));
  204. //compare does not change iterator
  205. BOOST_STATIC_ASSERT((detail::is_same< bs_set<MyClass<>, compare< std::greater<MyClass<> > > >::iterator
  206. , bs_set<MyClass<>, compare< std::less<MyClass<> > > >::iterator
  207. >::value));
  208. ////////////
  209. // splay_set
  210. ////////////
  211. BOOST_STATIC_ASSERT((!detail::is_same< splay_set<MyClass<> >::iterator
  212. , splay_set<MyClass<> >::const_iterator
  213. >::value));
  214. //constant_time_size does not change iterator
  215. BOOST_STATIC_ASSERT((detail::is_same< splay_set<MyClass<>, constant_time_size<true> >::iterator
  216. , splay_set<MyClass<>, constant_time_size<false> >::iterator
  217. >::value));
  218. //void_pointer does change iterator
  219. BOOST_STATIC_ASSERT((!detail::is_same< splay_set<MyClass<> >::iterator
  220. , splay_set<MyClass<smart_ptr<void> > >::iterator
  221. >::value));
  222. //size_type does not change iterator
  223. BOOST_STATIC_ASSERT((detail::is_same< splay_set<MyClass<>, size_type<unsigned int > >::iterator
  224. , splay_set<MyClass<>, size_type<unsigned char> >::iterator
  225. >::value));
  226. //compare does not change iterator
  227. BOOST_STATIC_ASSERT((detail::is_same< splay_set<MyClass<>, compare< std::greater<MyClass<> > > >::iterator
  228. , splay_set<MyClass<>, compare< std::less<MyClass<> > > >::iterator
  229. >::value));
  230. ////////////
  231. // treap_set
  232. ////////////
  233. BOOST_STATIC_ASSERT((!detail::is_same< treap_set<MyClass<> >::iterator
  234. , treap_set<MyClass<> >::const_iterator
  235. >::value));
  236. //constant_time_size does not change iterator
  237. BOOST_STATIC_ASSERT((detail::is_same< treap_set<MyClass<>, constant_time_size<true> >::iterator
  238. , treap_set<MyClass<>, constant_time_size<false> >::iterator
  239. >::value));
  240. //void_pointer does change iterator
  241. BOOST_STATIC_ASSERT((!detail::is_same< treap_set<MyClass<> >::iterator
  242. , treap_set<MyClass<smart_ptr<void> > >::iterator
  243. >::value));
  244. //size_type does not change iterator
  245. BOOST_STATIC_ASSERT((detail::is_same< treap_set<MyClass<>, size_type<unsigned int > >::iterator
  246. , treap_set<MyClass<>, size_type<unsigned char> >::iterator
  247. >::value));
  248. //compare does not change iterator
  249. BOOST_STATIC_ASSERT((detail::is_same< treap_set<MyClass<>, compare< std::greater<MyClass<> > > >::iterator
  250. , treap_set<MyClass<>, compare< std::less<MyClass<> > > >::iterator
  251. >::value));
  252. //priority does not change iterator
  253. BOOST_STATIC_ASSERT((detail::is_same< treap_set<MyClass<> >::iterator
  254. , treap_set<MyClass<>, priority< inverse_priority<MyClass<> > > >::iterator
  255. >::value));
  256. //////////////
  257. // common tree
  258. //////////////
  259. BOOST_STATIC_ASSERT((detail::is_same< bs_set<MyClass<> >::iterator
  260. , sg_set<MyClass<> >::iterator
  261. >::value));
  262. BOOST_STATIC_ASSERT((detail::is_same< bs_set<MyClass<> >::iterator
  263. , treap_set<MyClass<> >::iterator
  264. >::value));
  265. BOOST_STATIC_ASSERT((detail::is_same< bs_set<MyClass<> >::iterator
  266. , splay_set<MyClass<> >::iterator
  267. >::value));
  268. ////////////
  269. // unordered_set
  270. ////////////
  271. BOOST_STATIC_ASSERT((!detail::is_same< unordered_set<MyClass<> >::iterator
  272. , unordered_set<MyClass<> >::const_iterator
  273. >::value));
  274. //constant_time_size does not change iterator
  275. BOOST_STATIC_ASSERT((detail::is_same< unordered_set<MyClass<>, constant_time_size<true> >::iterator
  276. , unordered_set<MyClass<>, constant_time_size<false> >::iterator
  277. >::value));
  278. //void_pointer does change iterator
  279. BOOST_STATIC_ASSERT((!detail::is_same< unordered_set<MyClass<> >::iterator
  280. , unordered_set<MyClass<smart_ptr<void> > >::iterator
  281. >::value));
  282. //size_type does not change iterator
  283. BOOST_STATIC_ASSERT((detail::is_same< unordered_set<MyClass<>, size_type<unsigned int > >::iterator
  284. , unordered_set<MyClass<>, size_type<unsigned char> >::iterator
  285. >::value));
  286. //hash does not change iterator
  287. BOOST_STATIC_ASSERT((detail::is_same< unordered_set<MyClass<> >::iterator
  288. , unordered_set<MyClass<>, hash< inverse_hash<MyClass<> > > >::iterator
  289. >::value));
  290. //equal does not change iterator
  291. BOOST_STATIC_ASSERT((detail::is_same< unordered_set<MyClass<> >::iterator
  292. , unordered_set<MyClass<>, equal< alternative_equal<MyClass<> > > >::iterator
  293. >::value));
  294. //power_2_buckets does not change iterator
  295. BOOST_STATIC_ASSERT((detail::is_same< unordered_set<MyClass<> >::iterator
  296. , unordered_set<MyClass<>, power_2_buckets<true> >::iterator
  297. >::value));
  298. //cache_begin does not change iterator
  299. BOOST_STATIC_ASSERT((detail::is_same< unordered_set<MyClass<> >::iterator
  300. , unordered_set<MyClass<>, cache_begin<true> >::iterator
  301. >::value));
  302. return 0;
  303. }