key_nodeptr_comp.hpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2014-2014
  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_KEY_NODEPTR_COMP_HPP
  13. #define BOOST_INTRUSIVE_DETAIL_KEY_NODEPTR_COMP_HPP
  14. #ifndef BOOST_CONFIG_HPP
  15. # include <boost/config.hpp>
  16. #endif
  17. #if defined(BOOST_HAS_PRAGMA_ONCE)
  18. # pragma once
  19. #endif
  20. #include <boost/intrusive/detail/mpl.hpp>
  21. #include <boost/intrusive/detail/ebo_functor_holder.hpp>
  22. #include <boost/intrusive/detail/tree_value_compare.hpp>
  23. namespace boost {
  24. namespace intrusive {
  25. namespace detail {
  26. template < class KeyTypeKeyCompare
  27. , class ValueTraits
  28. , class KeyOfValue
  29. >
  30. struct key_nodeptr_comp_types
  31. {
  32. typedef ValueTraits value_traits;
  33. typedef typename value_traits::value_type value_type;
  34. typedef typename value_traits::node_ptr node_ptr;
  35. typedef typename value_traits::const_node_ptr const_node_ptr;
  36. typedef typename detail::if_c
  37. < detail::is_same<KeyOfValue, void>::value
  38. , detail::identity<value_type>
  39. , KeyOfValue
  40. >::type key_of_value;
  41. typedef tree_value_compare
  42. <typename ValueTraits::pointer, KeyTypeKeyCompare, key_of_value> base_t;
  43. };
  44. //This function object transforms a key comparison type to
  45. //a function that can compare nodes or nodes with nodes or keys.
  46. template < class KeyTypeKeyCompare
  47. , class ValueTraits
  48. , class KeyOfValue = void
  49. >
  50. struct key_nodeptr_comp
  51. //Use public inheritance to avoid MSVC bugs with closures
  52. : public key_nodeptr_comp_types<KeyTypeKeyCompare, ValueTraits, KeyOfValue>::base_t
  53. {
  54. private:
  55. struct sfinae_type;
  56. public:
  57. typedef key_nodeptr_comp_types<KeyTypeKeyCompare, ValueTraits, KeyOfValue> types_t;
  58. typedef typename types_t::value_traits value_traits;
  59. typedef typename types_t::value_type value_type;
  60. typedef typename types_t::node_ptr node_ptr;
  61. typedef typename types_t::const_node_ptr const_node_ptr;
  62. typedef typename types_t::base_t base_t;
  63. typedef typename types_t::key_of_value key_of_value;
  64. template <class P1>
  65. struct is_same_or_nodeptr_convertible
  66. {
  67. static const bool same_type = is_same<P1,const_node_ptr>::value || is_same<P1,node_ptr>::value;
  68. static const bool value = same_type || is_convertible<P1, const_node_ptr>::value;
  69. };
  70. inline base_t base() const
  71. { return static_cast<const base_t&>(*this); }
  72. inline key_nodeptr_comp(KeyTypeKeyCompare kcomp, const ValueTraits *traits)
  73. : base_t(kcomp), traits_(traits)
  74. {}
  75. //pred(pnode)
  76. template<class T1>
  77. inline bool operator()(const T1 &t1, typename enable_if_c< is_same_or_nodeptr_convertible<T1>::value, sfinae_type* >::type = 0) const
  78. { return base().get()(key_of_value()(*traits_->to_value_ptr(t1))); }
  79. //operator() 2 arg
  80. //pred(pnode, pnode)
  81. template<class T1, class T2>
  82. inline bool operator()
  83. (const T1 &t1, const T2 &t2, typename enable_if_c< is_same_or_nodeptr_convertible<T1>::value && is_same_or_nodeptr_convertible<T2>::value, sfinae_type* >::type = 0) const
  84. { return base()(*traits_->to_value_ptr(t1), *traits_->to_value_ptr(t2)); }
  85. //pred(pnode, key)
  86. template<class T1, class T2>
  87. inline bool operator()
  88. (const T1 &t1, const T2 &t2, typename enable_if_c< is_same_or_nodeptr_convertible<T1>::value && !is_same_or_nodeptr_convertible<T2>::value, sfinae_type* >::type = 0) const
  89. { return base()(*traits_->to_value_ptr(t1), t2); }
  90. //pred(key, pnode)
  91. template<class T1, class T2>
  92. inline bool operator()
  93. (const T1 &t1, const T2 &t2, typename enable_if_c< !is_same_or_nodeptr_convertible<T1>::value && is_same_or_nodeptr_convertible<T2>::value, sfinae_type* >::type = 0) const
  94. { return base()(t1, *traits_->to_value_ptr(t2)); }
  95. //pred(key, key)
  96. template<class T1, class T2>
  97. inline bool operator()
  98. (const T1 &t1, const T2 &t2, typename enable_if_c< !is_same_or_nodeptr_convertible<T1>::value && !is_same_or_nodeptr_convertible<T2>::value, sfinae_type* >::type = 0) const
  99. { return base()(t1, t2); }
  100. const ValueTraits *const traits_;
  101. };
  102. } //namespace detail{
  103. } //namespace intrusive{
  104. } //namespace boost{
  105. #endif //BOOST_INTRUSIVE_DETAIL_KEY_NODEPTR_COMP_HPP