utilities.hpp 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072
  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2006-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. #ifndef BOOST_INTRUSIVE_DETAIL_UTILITIES_HPP
  13. #define BOOST_INTRUSIVE_DETAIL_UTILITIES_HPP
  14. #include <boost/intrusive/detail/config_begin.hpp>
  15. #include <boost/intrusive/pointer_traits.hpp>
  16. #include <boost/intrusive/detail/parent_from_member.hpp>
  17. #include <boost/intrusive/detail/ebo_functor_holder.hpp>
  18. #include <boost/intrusive/link_mode.hpp>
  19. #include <boost/intrusive/detail/mpl.hpp>
  20. #include <boost/intrusive/detail/assert.hpp>
  21. #include <boost/intrusive/detail/is_stateful_value_traits.hpp>
  22. #include <boost/intrusive/pointer_traits.hpp>
  23. #include <boost/cstdint.hpp>
  24. #include <cstddef>
  25. #include <climits>
  26. #include <iterator>
  27. #include <boost/cstdint.hpp>
  28. #include <boost/static_assert.hpp>
  29. #include <boost/detail/no_exceptions_support.hpp>
  30. #include <functional>
  31. #include <boost/functional/hash.hpp>
  32. namespace boost {
  33. namespace intrusive {
  34. enum algo_types
  35. {
  36. CircularListAlgorithms,
  37. CircularSListAlgorithms,
  38. LinearSListAlgorithms,
  39. BsTreeAlgorithms,
  40. RbTreeAlgorithms,
  41. AvlTreeAlgorithms,
  42. SgTreeAlgorithms,
  43. SplayTreeAlgorithms,
  44. TreapAlgorithms
  45. };
  46. template<algo_types AlgoType, class NodeTraits>
  47. struct get_algo;
  48. template <link_mode_type link_mode>
  49. struct is_safe_autounlink
  50. {
  51. static const bool value =
  52. (int)link_mode == (int)auto_unlink ||
  53. (int)link_mode == (int)safe_link;
  54. };
  55. namespace detail {
  56. template <class T>
  57. struct internal_member_value_traits
  58. {
  59. template <class U> static detail::one test(...);
  60. template <class U> static detail::two test(typename U::member_value_traits* = 0);
  61. static const bool value = sizeof(test<T>(0)) == sizeof(detail::two);
  62. };
  63. #define BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(TRAITS_PREFIX, TYPEDEF_TO_FIND) \
  64. template <class T>\
  65. struct TRAITS_PREFIX##_bool\
  66. {\
  67. template<bool Add>\
  68. struct two_or_three {one _[2 + Add];};\
  69. template <class U> static one test(...);\
  70. template <class U> static two_or_three<U::TYPEDEF_TO_FIND> test (int);\
  71. static const std::size_t value = sizeof(test<T>(0));\
  72. };\
  73. \
  74. template <class T>\
  75. struct TRAITS_PREFIX##_bool_is_true\
  76. {\
  77. static const bool value = TRAITS_PREFIX##_bool<T>::value > sizeof(one)*2;\
  78. };\
  79. //
  80. BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(internal_base_hook, hooktags::is_base_hook)
  81. BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(internal_any_hook, is_any_hook)
  82. BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(external_value_traits, external_value_traits)
  83. BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(external_bucket_traits, external_bucket_traits)
  84. BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(resizable, resizable)
  85. template <class T>
  86. inline T* to_raw_pointer(T* p)
  87. { return p; }
  88. template <class Pointer>
  89. inline typename boost::intrusive::pointer_traits<Pointer>::element_type*
  90. to_raw_pointer(const Pointer &p)
  91. { return boost::intrusive::detail::to_raw_pointer(p.operator->()); }
  92. //This functor compares a stored value
  93. //and the one passed as an argument
  94. template<class ConstReference>
  95. class equal_to_value
  96. {
  97. ConstReference t_;
  98. public:
  99. equal_to_value(ConstReference t)
  100. : t_(t)
  101. {}
  102. bool operator()(ConstReference t)const
  103. { return t_ == t; }
  104. };
  105. class null_disposer
  106. {
  107. public:
  108. template <class Pointer>
  109. void operator()(Pointer)
  110. {}
  111. };
  112. template<class NodeAlgorithms>
  113. class init_disposer
  114. {
  115. typedef typename NodeAlgorithms::node_ptr node_ptr;
  116. public:
  117. void operator()(const node_ptr & p)
  118. { NodeAlgorithms::init(p); }
  119. };
  120. template<bool ConstantSize, class SizeType, class Tag = void>
  121. struct size_holder
  122. {
  123. static const bool constant_time_size = ConstantSize;
  124. typedef SizeType size_type;
  125. SizeType get_size() const
  126. { return size_; }
  127. void set_size(SizeType size)
  128. { size_ = size; }
  129. void decrement()
  130. { --size_; }
  131. void increment()
  132. { ++size_; }
  133. void increase(SizeType n)
  134. { size_ += n; }
  135. void decrease(SizeType n)
  136. { size_ -= n; }
  137. SizeType size_;
  138. };
  139. template<class SizeType>
  140. struct size_holder<false, SizeType>
  141. {
  142. static const bool constant_time_size = false;
  143. typedef SizeType size_type;
  144. size_type get_size() const
  145. { return 0; }
  146. void set_size(size_type)
  147. {}
  148. void decrement()
  149. {}
  150. void increment()
  151. {}
  152. void increase(SizeType)
  153. {}
  154. void decrease(SizeType)
  155. {}
  156. };
  157. template<class KeyValueCompare, class RealValueTraits>
  158. struct key_nodeptr_comp
  159. : private detail::ebo_functor_holder<KeyValueCompare>
  160. {
  161. typedef RealValueTraits real_value_traits;
  162. typedef typename real_value_traits::value_type value_type;
  163. typedef typename real_value_traits::node_ptr node_ptr;
  164. typedef typename real_value_traits::const_node_ptr const_node_ptr;
  165. typedef detail::ebo_functor_holder<KeyValueCompare> base_t;
  166. key_nodeptr_comp(KeyValueCompare kcomp, const RealValueTraits *traits)
  167. : base_t(kcomp), traits_(traits)
  168. {}
  169. template<class T>
  170. struct is_node_ptr
  171. {
  172. static const bool value = is_same<T, const_node_ptr>::value || is_same<T, node_ptr>::value;
  173. };
  174. template<class T>
  175. const value_type & key_forward
  176. (const T &node, typename enable_if_c<is_node_ptr<T>::value>::type * = 0) const
  177. { return *traits_->to_value_ptr(node); }
  178. template<class T>
  179. const T & key_forward(const T &key, typename enable_if_c<!is_node_ptr<T>::value>::type* = 0) const
  180. { return key; }
  181. template<class KeyType, class KeyType2>
  182. bool operator()(const KeyType &key1, const KeyType2 &key2) const
  183. { return base_t::get()(this->key_forward(key1), this->key_forward(key2)); }
  184. const RealValueTraits *traits_;
  185. };
  186. template<class F, class RealValueTraits, algo_types AlgoType>
  187. struct node_cloner
  188. : private detail::ebo_functor_holder<F>
  189. {
  190. typedef RealValueTraits real_value_traits;
  191. typedef typename real_value_traits::node_traits node_traits;
  192. typedef typename node_traits::node_ptr node_ptr;
  193. typedef detail::ebo_functor_holder<F> base_t;
  194. typedef typename get_algo< AlgoType
  195. , node_traits>::type node_algorithms;
  196. static const bool safemode_or_autounlink =
  197. is_safe_autounlink<real_value_traits::link_mode>::value;
  198. typedef typename real_value_traits::value_type value_type;
  199. typedef typename real_value_traits::pointer pointer;
  200. typedef typename node_traits::node node;
  201. typedef typename real_value_traits::const_node_ptr const_node_ptr;
  202. node_cloner(F f, const RealValueTraits *traits)
  203. : base_t(f), traits_(traits)
  204. {}
  205. node_ptr operator()(const node_ptr & p)
  206. { return this->operator()(*p); }
  207. node_ptr operator()(const node &to_clone)
  208. {
  209. const value_type &v =
  210. *traits_->to_value_ptr
  211. (pointer_traits<const_node_ptr>::pointer_to(to_clone));
  212. node_ptr n = traits_->to_node_ptr(*base_t::get()(v));
  213. //Cloned node must be in default mode if the linking mode requires it
  214. if(safemode_or_autounlink)
  215. BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(n));
  216. return n;
  217. }
  218. const RealValueTraits *traits_;
  219. };
  220. template<class F, class RealValueTraits, algo_types AlgoType>
  221. struct node_disposer
  222. : private detail::ebo_functor_holder<F>
  223. {
  224. typedef RealValueTraits real_value_traits;
  225. typedef typename real_value_traits::node_traits node_traits;
  226. typedef typename node_traits::node_ptr node_ptr;
  227. typedef detail::ebo_functor_holder<F> base_t;
  228. typedef typename get_algo< AlgoType
  229. , node_traits>::type node_algorithms;
  230. static const bool safemode_or_autounlink =
  231. is_safe_autounlink<real_value_traits::link_mode>::value;
  232. node_disposer(F f, const RealValueTraits *cont)
  233. : base_t(f), traits_(cont)
  234. {}
  235. void operator()(const node_ptr & p)
  236. {
  237. if(safemode_or_autounlink)
  238. node_algorithms::init(p);
  239. base_t::get()(traits_->to_value_ptr(p));
  240. }
  241. const RealValueTraits *traits_;
  242. };
  243. template<class VoidPointer>
  244. struct dummy_constptr
  245. {
  246. typedef typename boost::intrusive::pointer_traits<VoidPointer>::
  247. template rebind_pointer<const void>::type ConstVoidPtr;
  248. explicit dummy_constptr(ConstVoidPtr)
  249. {}
  250. dummy_constptr()
  251. {}
  252. ConstVoidPtr get_ptr() const
  253. { return ConstVoidPtr(); }
  254. };
  255. template<class VoidPointer>
  256. struct constptr
  257. {
  258. typedef typename boost::intrusive::pointer_traits<VoidPointer>::
  259. template rebind_pointer<const void>::type ConstVoidPtr;
  260. constptr()
  261. {}
  262. explicit constptr(const ConstVoidPtr &ptr)
  263. : const_void_ptr_(ptr)
  264. {}
  265. const void *get_ptr() const
  266. { return boost::intrusive::detail::to_raw_pointer(const_void_ptr_); }
  267. ConstVoidPtr const_void_ptr_;
  268. };
  269. template <class VoidPointer, bool store_ptr>
  270. struct select_constptr
  271. {
  272. typedef typename detail::if_c
  273. < store_ptr
  274. , constptr<VoidPointer>
  275. , dummy_constptr<VoidPointer>
  276. >::type type;
  277. };
  278. template<class T, bool Add>
  279. struct add_const_if_c
  280. {
  281. typedef typename detail::if_c
  282. < Add
  283. , typename detail::add_const<T>::type
  284. , T
  285. >::type type;
  286. };
  287. template <link_mode_type LinkMode>
  288. struct link_dispatch
  289. {};
  290. template<class Hook>
  291. void destructor_impl(Hook &hook, detail::link_dispatch<safe_link>)
  292. { //If this assertion raises, you might have destroyed an object
  293. //while it was still inserted in a container that is alive.
  294. //If so, remove the object from the container before destroying it.
  295. (void)hook; BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT(!hook.is_linked());
  296. }
  297. template<class Hook>
  298. void destructor_impl(Hook &hook, detail::link_dispatch<auto_unlink>)
  299. { hook.unlink(); }
  300. template<class Hook>
  301. void destructor_impl(Hook &, detail::link_dispatch<normal_link>)
  302. {}
  303. //This function uses binary search to discover the
  304. //highest set bit of the integer
  305. inline std::size_t floor_log2 (std::size_t x)
  306. {
  307. const std::size_t Bits = sizeof(std::size_t)*CHAR_BIT;
  308. const bool Size_t_Bits_Power_2= !(Bits & (Bits-1));
  309. BOOST_STATIC_ASSERT(Size_t_Bits_Power_2);
  310. std::size_t n = x;
  311. std::size_t log2 = 0;
  312. for(std::size_t shift = Bits >> 1; shift; shift >>= 1){
  313. std::size_t tmp = n >> shift;
  314. if (tmp)
  315. log2 += shift, n = tmp;
  316. }
  317. return log2;
  318. }
  319. //Thanks to Laurent de Soras in
  320. //http://www.flipcode.com/archives/Fast_log_Function.shtml
  321. inline float fast_log2 (float val)
  322. {
  323. union caster_t
  324. {
  325. boost::uint32_t x;
  326. float val;
  327. } caster;
  328. caster.val = val;
  329. boost::uint32_t x = caster.x;
  330. const int log_2 = int((x >> 23) & 255) - 128;
  331. x &= ~(boost::uint32_t(255u) << 23u);
  332. x += boost::uint32_t(127) << 23u;
  333. caster.x = x;
  334. val = caster.val;
  335. //1+log2(m), m ranging from 1 to 2
  336. //3rd degree polynomial keeping first derivate continuity.
  337. //For less precision the line can be commented out
  338. val = ((-1.0f/3.f) * val + 2.f) * val - (2.0f/3.f);
  339. return (val + log_2);
  340. }
  341. inline std::size_t ceil_log2 (std::size_t x)
  342. {
  343. return ((x & (x-1))!= 0) + floor_log2(x);
  344. }
  345. template<class SizeType, std::size_t N>
  346. struct numbits_eq
  347. {
  348. static const bool value = sizeof(SizeType)*CHAR_BIT == N;
  349. };
  350. template<class SizeType, class Enabler = void >
  351. struct sqrt2_pow_max;
  352. template <class SizeType>
  353. struct sqrt2_pow_max<SizeType, typename enable_if< numbits_eq<SizeType, 32> >::type>
  354. {
  355. static const boost::uint32_t value = 0xb504f334;
  356. static const std::size_t pow = 31;
  357. };
  358. #ifndef BOOST_NO_INT64_T
  359. template <class SizeType>
  360. struct sqrt2_pow_max<SizeType, typename enable_if< numbits_eq<SizeType, 64> >::type>
  361. {
  362. static const boost::uint64_t value = 0xb504f333f9de6484ull;
  363. static const std::size_t pow = 63;
  364. };
  365. #endif //BOOST_NO_INT64_T
  366. // Returns floor(pow(sqrt(2), x * 2 + 1)).
  367. // Defined for X from 0 up to the number of bits in size_t minus 1.
  368. inline std::size_t sqrt2_pow_2xplus1 (std::size_t x)
  369. {
  370. const std::size_t value = (std::size_t)sqrt2_pow_max<std::size_t>::value;
  371. const std::size_t pow = (std::size_t)sqrt2_pow_max<std::size_t>::pow;
  372. return (value >> (pow - x)) + 1;
  373. }
  374. template<class Container, class Disposer>
  375. class exception_disposer
  376. {
  377. Container *cont_;
  378. Disposer &disp_;
  379. exception_disposer(const exception_disposer&);
  380. exception_disposer &operator=(const exception_disposer&);
  381. public:
  382. exception_disposer(Container &cont, Disposer &disp)
  383. : cont_(&cont), disp_(disp)
  384. {}
  385. void release()
  386. { cont_ = 0; }
  387. ~exception_disposer()
  388. {
  389. if(cont_){
  390. cont_->clear_and_dispose(disp_);
  391. }
  392. }
  393. };
  394. template<class Container, class Disposer, class SizeType>
  395. class exception_array_disposer
  396. {
  397. Container *cont_;
  398. Disposer &disp_;
  399. SizeType &constructed_;
  400. exception_array_disposer(const exception_array_disposer&);
  401. exception_array_disposer &operator=(const exception_array_disposer&);
  402. public:
  403. exception_array_disposer
  404. (Container &cont, Disposer &disp, SizeType &constructed)
  405. : cont_(&cont), disp_(disp), constructed_(constructed)
  406. {}
  407. void release()
  408. { cont_ = 0; }
  409. ~exception_array_disposer()
  410. {
  411. SizeType n = constructed_;
  412. if(cont_){
  413. while(n--){
  414. cont_[n].clear_and_dispose(disp_);
  415. }
  416. }
  417. }
  418. };
  419. template<class RealValueTraits, bool IsConst>
  420. struct node_to_value
  421. : public detail::select_constptr
  422. < typename pointer_traits
  423. <typename RealValueTraits::pointer>::template rebind_pointer<void>::type
  424. , is_stateful_value_traits<RealValueTraits>::value
  425. >::type
  426. {
  427. static const bool stateful_value_traits = is_stateful_value_traits<RealValueTraits>::value;
  428. typedef typename detail::select_constptr
  429. < typename pointer_traits
  430. <typename RealValueTraits::pointer>::
  431. template rebind_pointer<void>::type
  432. , stateful_value_traits >::type Base;
  433. typedef RealValueTraits real_value_traits;
  434. typedef typename real_value_traits::value_type value_type;
  435. typedef typename real_value_traits::node_traits::node node;
  436. typedef typename detail::add_const_if_c
  437. <value_type, IsConst>::type vtype;
  438. typedef typename detail::add_const_if_c
  439. <node, IsConst>::type ntype;
  440. typedef typename pointer_traits
  441. <typename RealValueTraits::pointer>::
  442. template rebind_pointer<ntype>::type npointer;
  443. typedef typename pointer_traits<npointer>::
  444. template rebind_pointer<const RealValueTraits>::type const_real_value_traits_ptr;
  445. node_to_value(const const_real_value_traits_ptr &ptr)
  446. : Base(ptr)
  447. {}
  448. typedef vtype & result_type;
  449. typedef ntype & first_argument_type;
  450. const_real_value_traits_ptr get_real_value_traits() const
  451. {
  452. if(stateful_value_traits)
  453. return pointer_traits<const_real_value_traits_ptr>::static_cast_from(Base::get_ptr());
  454. else
  455. return const_real_value_traits_ptr();
  456. }
  457. result_type operator()(first_argument_type arg) const
  458. {
  459. return *(this->get_real_value_traits()->to_value_ptr
  460. (pointer_traits<npointer>::pointer_to(arg)));
  461. }
  462. };
  463. //This is not standard, but should work with all compilers
  464. union max_align
  465. {
  466. char char_;
  467. short short_;
  468. int int_;
  469. long long_;
  470. #ifdef BOOST_HAS_LONG_LONG
  471. long long long_long_;
  472. #endif
  473. float float_;
  474. double double_;
  475. long double long_double_;
  476. void * void_ptr_;
  477. };
  478. template<class T, std::size_t N>
  479. class array_initializer
  480. {
  481. public:
  482. template<class CommonInitializer>
  483. array_initializer(const CommonInitializer &init)
  484. {
  485. char *init_buf = (char*)rawbuf;
  486. std::size_t i = 0;
  487. BOOST_TRY{
  488. for(; i != N; ++i){
  489. new(init_buf)T(init);
  490. init_buf += sizeof(T);
  491. }
  492. }
  493. BOOST_CATCH(...){
  494. while(i--){
  495. init_buf -= sizeof(T);
  496. ((T*)init_buf)->~T();
  497. }
  498. BOOST_RETHROW;
  499. }
  500. BOOST_CATCH_END
  501. }
  502. operator T* ()
  503. { return (T*)(rawbuf); }
  504. operator const T*() const
  505. { return (const T*)(rawbuf); }
  506. ~array_initializer()
  507. {
  508. char *init_buf = (char*)rawbuf + N*sizeof(T);
  509. for(std::size_t i = 0; i != N; ++i){
  510. init_buf -= sizeof(T);
  511. ((T*)init_buf)->~T();
  512. }
  513. }
  514. private:
  515. detail::max_align rawbuf[(N*sizeof(T)-1)/sizeof(detail::max_align)+1];
  516. };
  517. template<class It>
  518. class reverse_iterator
  519. : public std::iterator<
  520. typename std::iterator_traits<It>::iterator_category,
  521. typename std::iterator_traits<It>::value_type,
  522. typename std::iterator_traits<It>::difference_type,
  523. typename std::iterator_traits<It>::pointer,
  524. typename std::iterator_traits<It>::reference>
  525. {
  526. public:
  527. typedef typename std::iterator_traits<It>::pointer pointer;
  528. typedef typename std::iterator_traits<It>::reference reference;
  529. typedef typename std::iterator_traits<It>::difference_type difference_type;
  530. typedef It iterator_type;
  531. reverse_iterator(){}
  532. explicit reverse_iterator(It r)
  533. : m_current(r)
  534. {}
  535. template<class OtherIt>
  536. reverse_iterator(const reverse_iterator<OtherIt>& r)
  537. : m_current(r.base())
  538. {}
  539. It base() const
  540. { return m_current; }
  541. reference operator*() const
  542. { It temp(m_current); --temp; return *temp; }
  543. pointer operator->() const
  544. { It temp(m_current); --temp; return temp.operator->(); }
  545. reference operator[](difference_type off) const
  546. { return this->m_current[-off]; }
  547. reverse_iterator& operator++()
  548. { --m_current; return *this; }
  549. reverse_iterator operator++(int)
  550. {
  551. reverse_iterator temp = *this;
  552. --m_current;
  553. return temp;
  554. }
  555. reverse_iterator& operator--()
  556. {
  557. ++m_current;
  558. return *this;
  559. }
  560. reverse_iterator operator--(int)
  561. {
  562. reverse_iterator temp(*this);
  563. ++m_current;
  564. return temp;
  565. }
  566. friend bool operator==(const reverse_iterator& l, const reverse_iterator& r)
  567. { return l.m_current == r.m_current; }
  568. friend bool operator!=(const reverse_iterator& l, const reverse_iterator& r)
  569. { return l.m_current != r.m_current; }
  570. friend bool operator<(const reverse_iterator& l, const reverse_iterator& r)
  571. { return l.m_current < r.m_current; }
  572. friend bool operator<=(const reverse_iterator& l, const reverse_iterator& r)
  573. { return l.m_current <= r.m_current; }
  574. friend bool operator>(const reverse_iterator& l, const reverse_iterator& r)
  575. { return l.m_current > r.m_current; }
  576. friend bool operator>=(const reverse_iterator& l, const reverse_iterator& r)
  577. { return l.m_current >= r.m_current; }
  578. reverse_iterator& operator+=(difference_type off)
  579. { m_current -= off; return *this; }
  580. friend reverse_iterator operator+(const reverse_iterator & l, difference_type off)
  581. {
  582. reverse_iterator tmp(l.m_current);
  583. tmp.m_current -= off;
  584. return tmp;
  585. }
  586. reverse_iterator& operator-=(difference_type off)
  587. { m_current += off; return *this; }
  588. friend reverse_iterator operator-(const reverse_iterator & l, difference_type off)
  589. {
  590. reverse_iterator tmp(l.m_current);
  591. tmp.m_current += off;
  592. return tmp;
  593. }
  594. friend difference_type operator-(const reverse_iterator& l, const reverse_iterator& r)
  595. { return r.m_current - l.m_current; }
  596. private:
  597. It m_current; // the wrapped iterator
  598. };
  599. template<class ConstNodePtr>
  600. struct uncast_types
  601. {
  602. typedef typename pointer_traits<ConstNodePtr>::element_type element_type;
  603. typedef typename remove_const<element_type>::type non_const_type;
  604. typedef typename pointer_traits<ConstNodePtr>::
  605. template rebind_pointer<non_const_type>::type non_const_pointer;
  606. typedef pointer_traits<non_const_pointer> non_const_traits;
  607. };
  608. template<class ConstNodePtr>
  609. static typename uncast_types<ConstNodePtr>::non_const_pointer
  610. uncast(const ConstNodePtr & ptr)
  611. {
  612. return uncast_types<ConstNodePtr>::non_const_traits::const_cast_from(ptr);
  613. }
  614. } //namespace detail
  615. template<class Node, class Tag, unsigned int>
  616. struct node_holder
  617. : public Node
  618. {};
  619. template<class T, class NodePtr, class Tag, unsigned int Type>
  620. struct bhtraits_base
  621. {
  622. public:
  623. typedef NodePtr node_ptr;
  624. typedef typename pointer_traits<node_ptr>::element_type node;
  625. typedef node_holder<node, Tag, Type> node_holder_type;
  626. typedef T value_type;
  627. typedef typename pointer_traits<node_ptr>::
  628. template rebind_pointer<const node>::type const_node_ptr;
  629. typedef typename pointer_traits<node_ptr>::
  630. template rebind_pointer<T>::type pointer;
  631. typedef typename pointer_traits<node_ptr>::
  632. template rebind_pointer<const T>::type const_pointer;
  633. //typedef typename pointer_traits<pointer>::reference reference;
  634. //typedef typename pointer_traits<const_pointer>::reference const_reference;
  635. typedef T & reference;
  636. typedef const T & const_reference;
  637. typedef node_holder_type & node_holder_reference;
  638. typedef const node_holder_type & const_node_holder_reference;
  639. typedef node& node_reference;
  640. typedef const node & const_node_reference;
  641. static pointer to_value_ptr(const node_ptr & n)
  642. {
  643. return pointer_traits<pointer>::pointer_to
  644. (static_cast<reference>(static_cast<node_holder_reference>(*n)));
  645. }
  646. static const_pointer to_value_ptr(const const_node_ptr & n)
  647. {
  648. return pointer_traits<const_pointer>::pointer_to
  649. (static_cast<const_reference>(static_cast<const_node_holder_reference>(*n)));
  650. }
  651. static node_ptr to_node_ptr(reference value)
  652. {
  653. return pointer_traits<node_ptr>::pointer_to
  654. (static_cast<node_reference>(static_cast<node_holder_reference>(value)));
  655. }
  656. static const_node_ptr to_node_ptr(const_reference value)
  657. {
  658. return pointer_traits<const_node_ptr>::pointer_to
  659. (static_cast<const_node_reference>(static_cast<const_node_holder_reference>(value)));
  660. }
  661. };
  662. template<class T, class NodeTraits, link_mode_type LinkMode, class Tag, unsigned int Type>
  663. struct bhtraits
  664. : public bhtraits_base<T, typename NodeTraits::node_ptr, Tag, Type>
  665. {
  666. static const link_mode_type link_mode = LinkMode;
  667. typedef NodeTraits node_traits;
  668. };
  669. /*
  670. template<class T, class NodePtr, typename pointer_traits<NodePtr>::element_type T::* P>
  671. struct mhtraits_base
  672. {
  673. public:
  674. typedef typename pointer_traits<NodePtr>::element_type node;
  675. typedef T value_type;
  676. typedef NodePtr node_ptr;
  677. typedef typename pointer_traits<node_ptr>::
  678. template rebind_pointer<const node>::type const_node_ptr;
  679. typedef typename pointer_traits<node_ptr>::
  680. template rebind_pointer<T>::type pointer;
  681. typedef typename pointer_traits<node_ptr>::
  682. template rebind_pointer<const T>::type const_pointer;
  683. typedef T & reference;
  684. typedef const T & const_reference;
  685. typedef node& node_reference;
  686. typedef const node & const_node_reference;
  687. static node_ptr to_node_ptr(reference value)
  688. {
  689. return pointer_traits<node_ptr>::pointer_to
  690. (static_cast<node_reference>(value.*P));
  691. }
  692. static const_node_ptr to_node_ptr(const_reference value)
  693. {
  694. return pointer_traits<const_node_ptr>::pointer_to
  695. (static_cast<const_node_reference>(value.*P));
  696. }
  697. static pointer to_value_ptr(const node_ptr & n)
  698. {
  699. return pointer_traits<pointer>::pointer_to
  700. (*detail::parent_from_member<T, node>
  701. (boost::intrusive::detail::to_raw_pointer(n), P));
  702. }
  703. static const_pointer to_value_ptr(const const_node_ptr & n)
  704. {
  705. return pointer_traits<const_pointer>::pointer_to
  706. (*detail::parent_from_member<T, node>
  707. (boost::intrusive::detail::to_raw_pointer(n), P));
  708. }
  709. };
  710. template<class T, class NodeTraits, typename NodeTraits::node T::* P, link_mode_type LinkMode>
  711. struct mhtraits
  712. : public mhtraits_base<T, typename NodeTraits::node_ptr, P>
  713. {
  714. static const link_mode_type link_mode = LinkMode;
  715. typedef NodeTraits node_traits;
  716. };
  717. */
  718. template<class T, class Hook, Hook T::* P>
  719. struct mhtraits
  720. {
  721. public:
  722. typedef Hook hook_type;
  723. typedef typename hook_type::hooktags::node_traits node_traits;
  724. typedef typename node_traits::node node;
  725. typedef T value_type;
  726. typedef typename node_traits::node_ptr node_ptr;
  727. typedef typename node_traits::const_node_ptr const_node_ptr;
  728. typedef typename pointer_traits<node_ptr>::
  729. template rebind_pointer<T>::type pointer;
  730. typedef typename pointer_traits<node_ptr>::
  731. template rebind_pointer<const T>::type const_pointer;
  732. typedef T & reference;
  733. typedef const T & const_reference;
  734. typedef node& node_reference;
  735. typedef const node & const_node_reference;
  736. typedef hook_type& hook_reference;
  737. typedef const hook_type & const_hook_reference;
  738. static const link_mode_type link_mode = Hook::hooktags::link_mode;
  739. static node_ptr to_node_ptr(reference value)
  740. {
  741. return pointer_traits<node_ptr>::pointer_to
  742. (static_cast<node_reference>(static_cast<hook_reference>(value.*P)));
  743. }
  744. static const_node_ptr to_node_ptr(const_reference value)
  745. {
  746. return pointer_traits<const_node_ptr>::pointer_to
  747. (static_cast<const_node_reference>(static_cast<const_hook_reference>(value.*P)));
  748. }
  749. static pointer to_value_ptr(const node_ptr & n)
  750. {
  751. return pointer_traits<pointer>::pointer_to
  752. (*detail::parent_from_member<T, Hook>
  753. (static_cast<Hook*>(boost::intrusive::detail::to_raw_pointer(n)), P));
  754. }
  755. static const_pointer to_value_ptr(const const_node_ptr & n)
  756. {
  757. return pointer_traits<const_pointer>::pointer_to
  758. (*detail::parent_from_member<T, Hook>
  759. (static_cast<const Hook*>(boost::intrusive::detail::to_raw_pointer(n)), P));
  760. }
  761. };
  762. template<class Functor>
  763. struct fhtraits
  764. {
  765. public:
  766. typedef typename Functor::hook_type hook_type;
  767. typedef typename Functor::hook_ptr hook_ptr;
  768. typedef typename Functor::const_hook_ptr const_hook_ptr;
  769. typedef typename hook_type::hooktags::node_traits node_traits;
  770. typedef typename node_traits::node node;
  771. typedef typename Functor::value_type value_type;
  772. typedef typename node_traits::node_ptr node_ptr;
  773. typedef typename node_traits::const_node_ptr const_node_ptr;
  774. typedef typename pointer_traits<node_ptr>::
  775. template rebind_pointer<value_type>::type pointer;
  776. typedef typename pointer_traits<node_ptr>::
  777. template rebind_pointer<const value_type>::type const_pointer;
  778. typedef value_type & reference;
  779. typedef const value_type & const_reference;
  780. static const link_mode_type link_mode = hook_type::hooktags::link_mode;
  781. static node_ptr to_node_ptr(reference value)
  782. { return static_cast<node*>(boost::intrusive::detail::to_raw_pointer(Functor::to_hook_ptr(value))); }
  783. static const_node_ptr to_node_ptr(const_reference value)
  784. { return static_cast<const node*>(boost::intrusive::detail::to_raw_pointer(Functor::to_hook_ptr(value))); }
  785. static pointer to_value_ptr(const node_ptr & n)
  786. { return Functor::to_value_ptr(to_hook_ptr(n)); }
  787. static const_pointer to_value_ptr(const const_node_ptr & n)
  788. { return Functor::to_value_ptr(to_hook_ptr(n)); }
  789. private:
  790. static hook_ptr to_hook_ptr(const node_ptr & n)
  791. { return hook_ptr(&*static_cast<hook_type*>(&*n)); }
  792. static const_hook_ptr to_hook_ptr(const const_node_ptr & n)
  793. { return const_hook_ptr(&*static_cast<const hook_type*>(&*n)); }
  794. };
  795. template<class RealValueTraits, bool IsConst, class Category>
  796. struct iiterator
  797. {
  798. typedef RealValueTraits real_value_traits;
  799. typedef typename real_value_traits::node_traits node_traits;
  800. typedef typename node_traits::node node;
  801. typedef typename node_traits::node_ptr node_ptr;
  802. typedef ::boost::intrusive::pointer_traits<node_ptr> nodepointer_traits_t;
  803. typedef typename nodepointer_traits_t::template
  804. rebind_pointer<void>::type void_pointer;
  805. typedef typename RealValueTraits::value_type value_type;
  806. typedef typename RealValueTraits::pointer nonconst_pointer;
  807. typedef typename RealValueTraits::const_pointer yesconst_pointer;
  808. typedef typename ::boost::intrusive::pointer_traits
  809. <nonconst_pointer>::reference nonconst_reference;
  810. typedef typename ::boost::intrusive::pointer_traits
  811. <yesconst_pointer>::reference yesconst_reference;
  812. typedef typename nodepointer_traits_t::difference_type difference_type;
  813. typedef typename detail::if_c
  814. <IsConst, yesconst_pointer, nonconst_pointer>::type pointer;
  815. typedef typename detail::if_c
  816. <IsConst, yesconst_reference, nonconst_reference>::type reference;
  817. typedef std::iterator
  818. < Category
  819. , value_type
  820. , difference_type
  821. , pointer
  822. , reference
  823. > iterator_base;
  824. static const bool stateful_value_traits =
  825. detail::is_stateful_value_traits<real_value_traits>::value;
  826. };
  827. template<class NodePtr, bool StatefulValueTraits = true>
  828. struct iiterator_members
  829. {
  830. typedef ::boost::intrusive::pointer_traits<NodePtr> pointer_traits_t;
  831. typedef typename pointer_traits_t::template
  832. rebind_pointer<const void>::type const_void_pointer;
  833. iiterator_members()
  834. {}
  835. iiterator_members(const NodePtr &n_ptr, const const_void_pointer &data)
  836. : nodeptr_(n_ptr), ptr_(data)
  837. {}
  838. const_void_pointer get_ptr() const
  839. { return ptr_; }
  840. NodePtr nodeptr_;
  841. const_void_pointer ptr_;
  842. };
  843. template<class NodePtr>
  844. struct iiterator_members<NodePtr, false>
  845. {
  846. typedef ::boost::intrusive::pointer_traits<NodePtr> pointer_traits_t;
  847. typedef typename pointer_traits_t::template
  848. rebind_pointer<const void>::type const_void_pointer;
  849. iiterator_members()
  850. {}
  851. iiterator_members(const NodePtr &n_ptr, const const_void_pointer &)
  852. : nodeptr_(n_ptr)
  853. {}
  854. const_void_pointer get_ptr() const
  855. { return const_void_pointer(); }
  856. NodePtr nodeptr_;
  857. };
  858. template<class Less, class T>
  859. struct get_less
  860. {
  861. typedef Less type;
  862. };
  863. template<class T>
  864. struct get_less<void, T>
  865. {
  866. typedef ::std::less<T> type;
  867. };
  868. template<class EqualTo, class T>
  869. struct get_equal_to
  870. {
  871. typedef EqualTo type;
  872. };
  873. template<class T>
  874. struct get_equal_to<void, T>
  875. {
  876. typedef ::std::equal_to<T> type;
  877. };
  878. template<class Hash, class T>
  879. struct get_hash
  880. {
  881. typedef Hash type;
  882. };
  883. template<class T>
  884. struct get_hash<void, T>
  885. {
  886. typedef ::boost::hash<T> type;
  887. };
  888. struct empty{};
  889. } //namespace intrusive
  890. } //namespace boost
  891. #include <boost/intrusive/detail/config_end.hpp>
  892. #endif //BOOST_INTRUSIVE_DETAIL_UTILITIES_HPP