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