]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | { | |
b32b8144 FG |
62 | private: |
63 | struct sfinae_type; | |
64 | ||
65 | public: | |
7c673cae FG |
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 | ||
92f5a8d4 | 81 | BOOST_INTRUSIVE_FORCEINLINE base_t base() const |
7c673cae FG |
82 | { return static_cast<const base_t&>(*this); } |
83 | ||
84 | 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> | |
b32b8144 | 90 | BOOST_INTRUSIVE_FORCEINLINE bool operator()(const T1 &t1, typename enable_if_c< is_same_or_nodeptr_convertible<T1>::value, sfinae_type* >::type = 0) const |
7c673cae FG |
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> | |
96 | BOOST_INTRUSIVE_FORCEINLINE bool operator() | |
b32b8144 | 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 |
7c673cae FG |
98 | { return base()(*traits_->to_value_ptr(t1), *traits_->to_value_ptr(t2)); } |
99 | ||
100 | //pred(pnode, key) | |
101 | template<class T1, class T2> | |
102 | BOOST_INTRUSIVE_FORCEINLINE bool operator() | |
b32b8144 | 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 |
7c673cae FG |
104 | { return base()(*traits_->to_value_ptr(t1), t2); } |
105 | ||
106 | //pred(key, pnode) | |
107 | template<class T1, class T2> | |
108 | BOOST_INTRUSIVE_FORCEINLINE bool operator() | |
b32b8144 | 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 |
7c673cae FG |
110 | { return base()(t1, *traits_->to_value_ptr(t2)); } |
111 | ||
112 | //pred(key, key) | |
113 | template<class T1, class T2> | |
114 | BOOST_INTRUSIVE_FORCEINLINE bool operator() | |
b32b8144 | 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 |
7c673cae FG |
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 |