1 | ////////////////////////////////////////////////////////////////////////////// |
2 | // |
3 | // (C) Copyright Ion Gaztanaga 2015-2015. Distributed under the Boost |
4 | // Software License, Version 1.0. (See accompanying file |
5 | // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
6 | // |
7 | // See http://www.boost.org/libs/container for documentation. |
8 | // |
9 | ////////////////////////////////////////////////////////////////////////////// |
10 | #ifndef BOOST_INTRUSIVE_DETAIL_TREE_VALUE_COMPARE_HPP |
11 | #define BOOST_INTRUSIVE_DETAIL_TREE_VALUE_COMPARE_HPP |
12 | |
13 | #ifndef BOOST_CONFIG_HPP |
14 | # include <boost/config.hpp> |
15 | #endif |
16 | |
17 | #if defined(BOOST_HAS_PRAGMA_ONCE) |
18 | # pragma once |
19 | #endif |
20 | |
21 | #include <boost/intrusive/detail/workaround.hpp> |
22 | #include <boost/intrusive/detail/mpl.hpp> |
23 | #include <boost/intrusive/detail/ebo_functor_holder.hpp> |
24 | #include <boost/intrusive/pointer_traits.hpp> |
25 | |
26 | namespace boost{ |
27 | namespace intrusive{ |
28 | |
29 | //Needed to support smart references to value types |
30 | template <class From, class ValuePtr> |
31 | struct disable_if_smartref_to |
32 | : detail::disable_if_c |
33 | < detail::is_same |
34 | <From, typename pointer_traits |
35 | <ValuePtr> |
36 | ::reference>::value |
37 | || detail::is_same |
38 | <From, typename pointer_traits |
39 | < typename pointer_rebind |
40 | < ValuePtr |
41 | , const typename boost::movelib::pointer_element<ValuePtr>::type>::type> |
42 | ::reference>::value |
43 | > |
44 | {}; |
45 | |
46 | //This function object takes a KeyCompare function object |
47 | //and compares values that contains keys using KeyOfValue |
48 | template< class ValuePtr, class KeyCompare, class KeyOfValue |
49 | , bool = boost::intrusive::detail::is_same |
50 | <typename boost::movelib::pointer_element<ValuePtr>::type, typename KeyOfValue::type>::value > |
51 | struct tree_value_compare |
52 | : public boost::intrusive::detail::ebo_functor_holder<KeyCompare> |
53 | { |
54 | typedef typename |
55 | boost::movelib::pointer_element<ValuePtr>::type value_type; |
56 | typedef KeyCompare key_compare; |
57 | typedef KeyOfValue key_of_value; |
58 | typedef typename KeyOfValue::type key_type; |
59 | |
60 | typedef boost::intrusive::detail::ebo_functor_holder<KeyCompare> base_t; |
61 | |
62 | BOOST_INTRUSIVE_FORCEINLINE tree_value_compare() |
63 | : base_t() |
64 | {} |
65 | |
66 | BOOST_INTRUSIVE_FORCEINLINE explicit tree_value_compare(const key_compare &kcomp) |
67 | : base_t(kcomp) |
68 | {} |
69 | |
70 | BOOST_INTRUSIVE_FORCEINLINE tree_value_compare (const tree_value_compare &x) |
71 | : base_t(x.base_t::get()) |
72 | {} |
73 | |
74 | BOOST_INTRUSIVE_FORCEINLINE tree_value_compare &operator=(const tree_value_compare &x) |
75 | { this->base_t::get() = x.base_t::get(); return *this; } |
76 | |
77 | BOOST_INTRUSIVE_FORCEINLINE tree_value_compare &operator=(const key_compare &x) |
78 | { this->base_t::get() = x; return *this; } |
79 | |
80 | BOOST_INTRUSIVE_FORCEINLINE const key_compare &key_comp() const |
81 | { return static_cast<const key_compare &>(*this); } |
82 | |
83 | BOOST_INTRUSIVE_FORCEINLINE bool operator()(const key_type &key1, const key_type &key2) const |
84 | { return this->key_comp()(key1, key2); } |
85 | |
86 | BOOST_INTRUSIVE_FORCEINLINE bool operator()(const value_type &value1, const value_type &value2) const |
87 | { return this->key_comp()(KeyOfValue()(value1), KeyOfValue()(value2)); } |
88 | |
89 | BOOST_INTRUSIVE_FORCEINLINE bool operator()(const key_type &key1, const value_type &value2) const |
90 | { return this->key_comp()(key1, KeyOfValue()(value2)); } |
91 | |
92 | BOOST_INTRUSIVE_FORCEINLINE bool operator()(const value_type &value1, const key_type &key2) const |
93 | { return this->key_comp()(KeyOfValue()(value1), key2); } |
94 | |
95 | template<class U> |
96 | BOOST_INTRUSIVE_FORCEINLINE bool operator()( const key_type &key1, const U &nonkey2 |
97 | , typename disable_if_smartref_to<U, ValuePtr>::type* = 0) const |
98 | { return this->key_comp()(key1, nonkey2); } |
99 | |
100 | template<class U> |
101 | BOOST_INTRUSIVE_FORCEINLINE bool operator()( const U &nonkey1, const key_type &key2 |
102 | , typename disable_if_smartref_to<U, ValuePtr>::type* = 0) const |
103 | { return this->key_comp()(nonkey1, key2); } |
104 | |
105 | template<class U> |
106 | BOOST_INTRUSIVE_FORCEINLINE bool operator()( const value_type &value1, const U &nonvalue2 |
107 | , typename disable_if_smartref_to<U, ValuePtr>::type* = 0) const |
108 | { return this->key_comp()(KeyOfValue()(value1), nonvalue2); } |
109 | |
110 | template<class U> |
111 | BOOST_INTRUSIVE_FORCEINLINE bool operator()( const U &nonvalue1, const value_type &value2 |
112 | , typename disable_if_smartref_to<U, ValuePtr>::type* = 0) const |
113 | { return this->key_comp()(nonvalue1, KeyOfValue()(value2)); } |
114 | }; |
115 | |
116 | template<class ValuePtr, class KeyCompare, class KeyOfValue> |
117 | struct tree_value_compare<ValuePtr, KeyCompare, KeyOfValue, true> |
118 | : public boost::intrusive::detail::ebo_functor_holder<KeyCompare> |
119 | { |
120 | typedef typename |
121 | boost::movelib::pointer_element<ValuePtr>::type value_type; |
122 | typedef KeyCompare key_compare; |
123 | typedef KeyOfValue key_of_value; |
124 | typedef typename KeyOfValue::type key_type; |
125 | |
126 | typedef boost::intrusive::detail::ebo_functor_holder<KeyCompare> base_t; |
127 | |
128 | |
129 | BOOST_INTRUSIVE_FORCEINLINE tree_value_compare() |
130 | : base_t() |
131 | {} |
132 | |
133 | BOOST_INTRUSIVE_FORCEINLINE explicit tree_value_compare(const key_compare &kcomp) |
134 | : base_t(kcomp) |
135 | {} |
136 | |
137 | BOOST_INTRUSIVE_FORCEINLINE tree_value_compare (const tree_value_compare &x) |
138 | : base_t(x.base_t::get()) |
139 | {} |
140 | |
141 | BOOST_INTRUSIVE_FORCEINLINE tree_value_compare &operator=(const tree_value_compare &x) |
142 | { this->base_t::get() = x.base_t::get(); return *this; } |
143 | |
144 | BOOST_INTRUSIVE_FORCEINLINE tree_value_compare &operator=(const key_compare &x) |
145 | { this->base_t::get() = x; return *this; } |
146 | |
147 | BOOST_INTRUSIVE_FORCEINLINE const key_compare &key_comp() const |
148 | { return static_cast<const key_compare &>(*this); } |
149 | |
150 | BOOST_INTRUSIVE_FORCEINLINE bool operator()(const key_type &key1, const key_type &key2) const |
151 | { return this->key_comp()(key1, key2); } |
152 | |
153 | template<class U> |
154 | BOOST_INTRUSIVE_FORCEINLINE bool operator()( const key_type &key1, const U &nonkey2 |
155 | , typename disable_if_smartref_to<U, ValuePtr>::type* = 0) const |
156 | { return this->key_comp()(key1, nonkey2); } |
157 | |
158 | template<class U> |
159 | BOOST_INTRUSIVE_FORCEINLINE bool operator()(const U &nonkey1, const key_type &key2 |
160 | , typename disable_if_smartref_to<U, ValuePtr>::type* = 0) const |
161 | { return this->key_comp()(nonkey1, key2); } |
162 | }; |
163 | |
164 | } //namespace intrusive{ |
165 | } //namespace boost{ |
166 | |
167 | #endif //#ifdef BOOST_INTRUSIVE_DETAIL_TREE_VALUE_COMPARE_HPP |
168 | |