]>
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 | { | |
62 | typedef key_nodeptr_comp_types<KeyTypeKeyCompare, ValueTraits, KeyOfValue> types_t; | |
63 | typedef typename types_t::value_traits value_traits; | |
64 | typedef typename types_t::value_type value_type; | |
65 | typedef typename types_t::node_ptr node_ptr; | |
66 | typedef typename types_t::const_node_ptr const_node_ptr; | |
67 | typedef typename types_t::base_t base_t; | |
68 | typedef typename types_t::key_of_value key_of_value; | |
69 | ||
70 | template <class P1> | |
71 | struct is_same_or_nodeptr_convertible | |
72 | { | |
73 | static const bool same_type = is_same<P1,const_node_ptr>::value || is_same<P1,node_ptr>::value; | |
74 | static const bool value = same_type || is_convertible<P1, const_node_ptr>::value; | |
75 | }; | |
76 | ||
77 | base_t base() const | |
78 | { return static_cast<const base_t&>(*this); } | |
79 | ||
80 | BOOST_INTRUSIVE_FORCEINLINE key_nodeptr_comp(KeyTypeKeyCompare kcomp, const ValueTraits *traits) | |
81 | : base_t(kcomp), traits_(traits) | |
82 | {} | |
83 | ||
84 | //pred(pnode) | |
85 | template<class T1> | |
86 | BOOST_INTRUSIVE_FORCEINLINE bool operator()(const T1 &t1, typename enable_if_c< is_same_or_nodeptr_convertible<T1>::value >::type* =0) const | |
87 | { return base().get()(key_of_value()(*traits_->to_value_ptr(t1))); } | |
88 | ||
89 | //operator() 2 arg | |
90 | //pred(pnode, pnode) | |
91 | template<class T1, class T2> | |
92 | BOOST_INTRUSIVE_FORCEINLINE 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 >::type* =0) const | |
94 | { return base()(*traits_->to_value_ptr(t1), *traits_->to_value_ptr(t2)); } | |
95 | ||
96 | //pred(pnode, key) | |
97 | template<class T1, class T2> | |
98 | BOOST_INTRUSIVE_FORCEINLINE bool operator() | |
99 | (const T1 &t1, const T2 &t2, typename enable_if_c< is_same_or_nodeptr_convertible<T1>::value && !is_same_or_nodeptr_convertible<T2>::value >::type* =0) const | |
100 | { return base()(*traits_->to_value_ptr(t1), t2); } | |
101 | ||
102 | //pred(key, pnode) | |
103 | template<class T1, class T2> | |
104 | BOOST_INTRUSIVE_FORCEINLINE bool operator() | |
105 | (const T1 &t1, const T2 &t2, typename enable_if_c< !is_same_or_nodeptr_convertible<T1>::value && is_same_or_nodeptr_convertible<T2>::value >::type* =0) const | |
106 | { return base()(t1, *traits_->to_value_ptr(t2)); } | |
107 | ||
108 | //pred(key, key) | |
109 | template<class T1, class T2> | |
110 | BOOST_INTRUSIVE_FORCEINLINE bool operator() | |
111 | (const T1 &t1, const T2 &t2, typename enable_if_c< !is_same_or_nodeptr_convertible<T1>::value && !is_same_or_nodeptr_convertible<T2>::value >::type* =0) const | |
112 | { return base()(t1, t2); } | |
113 | ||
114 | const ValueTraits *const traits_; | |
115 | }; | |
116 | ||
117 | } //namespace detail{ | |
118 | } //namespace intrusive{ | |
119 | } //namespace boost{ | |
120 | ||
121 | #endif //BOOST_INTRUSIVE_DETAIL_KEY_NODEPTR_COMP_HPP |