1 /* Copyright 2003-2015 Joaquin M Lopez Munoz.
2 * Distributed under the Boost Software License, Version 1.0.
3 * (See accompanying file LICENSE_1_0.txt or copy at
4 * http://www.boost.org/LICENSE_1_0.txt)
6 * See http://www.boost.org/libs/multi_index for library home page.
9 #ifndef BOOST_MULTI_INDEX_DETAIL_RNK_INDEX_OPS_HPP
10 #define BOOST_MULTI_INDEX_DETAIL_RNK_INDEX_OPS_HPP
16 #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
17 #include <boost/mpl/and.hpp>
18 #include <boost/multi_index/detail/promotes_arg.hpp>
24 namespace multi_index{
28 /* Common code for ranked_index memfuns having templatized and
29 * non-templatized versions.
32 template<typename Pointer>
33 inline std::size_t ranked_node_size(Pointer x)
35 return x!=Pointer(0)?x->size:0;
38 template<typename Pointer>
39 inline Pointer ranked_index_nth(std::size_t n,Pointer end_)
41 Pointer top=end_->parent();
42 if(top==Pointer(0)||n>=top->size)return end_;
45 std::size_t s=ranked_node_size(top->left());
47 if(n<s)top=top->left();
55 template<typename Pointer>
56 inline std::size_t ranked_index_rank(Pointer x,Pointer end_)
58 Pointer top=end_->parent();
59 if(top==Pointer(0))return 0;
60 if(x==end_)return top->size;
62 std::size_t s=ranked_node_size(x->left());
64 Pointer z=x->parent();
66 s+=ranked_node_size(z->left())+1;
74 typename Node,typename KeyFromValue,
75 typename CompatibleKey,typename CompatibleCompare
77 inline std::size_t ranked_index_find_rank(
78 Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
79 const CompatibleCompare& comp)
81 typedef typename KeyFromValue::result_type key_type;
83 return ranked_index_find_rank(
86 promotes_1st_arg<CompatibleCompare,CompatibleKey,key_type>,
87 promotes_2nd_arg<CompatibleCompare,key_type,CompatibleKey> >());
91 typename Node,typename KeyFromValue,
92 typename CompatibleCompare
94 inline std::size_t ranked_index_find_rank(
95 Node* top,Node* y,const KeyFromValue& key,
96 const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x,
97 const CompatibleCompare& comp,mpl::true_)
99 return ranked_index_find_rank(top,y,key,x,comp,mpl::false_());
103 typename Node,typename KeyFromValue,
104 typename CompatibleKey,typename CompatibleCompare
106 inline std::size_t ranked_index_find_rank(
107 Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
108 const CompatibleCompare& comp,mpl::false_)
112 std::size_t s=top->size,
117 if(!comp(key(top->value()),x)){
119 s-=ranked_node_size(y->right())+1;
120 top=Node::from_impl(top->left());
122 else top=Node::from_impl(top->right());
125 return (y==y0||comp(x,key(y->value())))?s0:s;
129 typename Node,typename KeyFromValue,
130 typename CompatibleKey,typename CompatibleCompare
132 inline std::size_t ranked_index_lower_bound_rank(
133 Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
134 const CompatibleCompare& comp)
136 typedef typename KeyFromValue::result_type key_type;
138 return ranked_index_lower_bound_rank(
140 promotes_2nd_arg<CompatibleCompare,key_type,CompatibleKey>());
144 typename Node,typename KeyFromValue,
145 typename CompatibleCompare
147 inline std::size_t ranked_index_lower_bound_rank(
148 Node* top,Node* y,const KeyFromValue& key,
149 const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x,
150 const CompatibleCompare& comp,mpl::true_)
152 return ranked_index_lower_bound_rank(top,y,key,x,comp,mpl::false_());
156 typename Node,typename KeyFromValue,
157 typename CompatibleKey,typename CompatibleCompare
159 inline std::size_t ranked_index_lower_bound_rank(
160 Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
161 const CompatibleCompare& comp,mpl::false_)
165 std::size_t s=top->size;
168 if(!comp(key(top->value()),x)){
170 s-=ranked_node_size(y->right())+1;
171 top=Node::from_impl(top->left());
173 else top=Node::from_impl(top->right());
180 typename Node,typename KeyFromValue,
181 typename CompatibleKey,typename CompatibleCompare
183 inline std::size_t ranked_index_upper_bound_rank(
184 Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
185 const CompatibleCompare& comp)
187 typedef typename KeyFromValue::result_type key_type;
189 return ranked_index_upper_bound_rank(
191 promotes_1st_arg<CompatibleCompare,CompatibleKey,key_type>());
195 typename Node,typename KeyFromValue,
196 typename CompatibleCompare
198 inline std::size_t ranked_index_upper_bound_rank(
199 Node* top,Node* y,const KeyFromValue& key,
200 const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x,
201 const CompatibleCompare& comp,mpl::true_)
203 return ranked_index_upper_bound_rank(top,y,key,x,comp,mpl::false_());
207 typename Node,typename KeyFromValue,
208 typename CompatibleKey,typename CompatibleCompare
210 inline std::size_t ranked_index_upper_bound_rank(
211 Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
212 const CompatibleCompare& comp,mpl::false_)
216 std::size_t s=top->size;
219 if(comp(x,key(top->value()))){
221 s-=ranked_node_size(y->right())+1;
222 top=Node::from_impl(top->left());
224 else top=Node::from_impl(top->right());
231 typename Node,typename KeyFromValue,
232 typename CompatibleKey,typename CompatibleCompare
234 inline std::pair<std::size_t,std::size_t> ranked_index_equal_range_rank(
235 Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
236 const CompatibleCompare& comp)
238 typedef typename KeyFromValue::result_type key_type;
240 return ranked_index_equal_range_rank(
243 promotes_1st_arg<CompatibleCompare,CompatibleKey,key_type>,
244 promotes_2nd_arg<CompatibleCompare,key_type,CompatibleKey> >());
248 typename Node,typename KeyFromValue,
249 typename CompatibleCompare
251 inline std::pair<std::size_t,std::size_t> ranked_index_equal_range_rank(
252 Node* top,Node* y,const KeyFromValue& key,
253 const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x,
254 const CompatibleCompare& comp,mpl::true_)
256 return ranked_index_equal_range_rank(top,y,key,x,comp,mpl::false_());
260 typename Node,typename KeyFromValue,
261 typename CompatibleKey,typename CompatibleCompare
263 inline std::pair<std::size_t,std::size_t> ranked_index_equal_range_rank(
264 Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
265 const CompatibleCompare& comp,mpl::false_)
267 if(!top)return std::pair<std::size_t,std::size_t>(0,0);
269 std::size_t s=top->size;
272 if(comp(key(top->value()),x)){
273 top=Node::from_impl(top->right());
275 else if(comp(x,key(top->value()))){
277 s-=ranked_node_size(y->right())+1;
278 top=Node::from_impl(top->left());
281 return std::pair<std::size_t,std::size_t>(
283 ranked_index_lower_bound_rank(
284 Node::from_impl(top->left()),top,key,x,comp,mpl::false_()),
285 s-ranked_node_size(top->right())+
286 ranked_index_upper_bound_rank(
287 Node::from_impl(top->right()),y,key,x,comp,mpl::false_()));
291 return std::pair<std::size_t,std::size_t>(s,s);
294 } /* namespace multi_index::detail */
296 } /* namespace multi_index */
298 } /* namespace boost */