123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402 |
- /* Copyright 2003-2022 Joaquin M Lopez Munoz.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE_1_0.txt or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- *
- * See http://www.boost.org/libs/multi_index for library home page.
- */
- #ifndef BOOST_MULTI_INDEX_RANKED_INDEX_HPP
- #define BOOST_MULTI_INDEX_RANKED_INDEX_HPP
- #if defined(_MSC_VER)
- #pragma once
- #endif
- #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
- #include <boost/multi_index/detail/ord_index_impl.hpp>
- #include <boost/multi_index/detail/rnk_index_ops.hpp>
- #include <boost/multi_index/ranked_index_fwd.hpp>
- namespace boost{
- namespace multi_index{
- namespace detail{
- /* ranked_index augments a given ordered index to provide rank operations */
- template<typename OrderedIndexNodeImpl>
- struct ranked_node:OrderedIndexNodeImpl
- {
- typedef typename OrderedIndexNodeImpl::size_type size_type;
- size_type size;
- };
- template<typename OrderedIndexImpl>
- class ranked_index:public OrderedIndexImpl
- {
- typedef OrderedIndexImpl super;
- protected:
- typedef typename super::index_node_type index_node_type;
- typedef typename super::node_impl_pointer node_impl_pointer;
- public:
- typedef typename super::ctor_args_list ctor_args_list;
- typedef typename super::allocator_type allocator_type;
- typedef typename super::iterator iterator;
- typedef typename super::size_type size_type;
- /* set operations */
- template<typename CompatibleKey>
- size_type count(const CompatibleKey& x)const
- {
- return count(x,this->comp_);
- }
- template<typename CompatibleKey,typename CompatibleCompare>
- size_type count(const CompatibleKey& x,const CompatibleCompare& comp)const
- {
- std::pair<size_type,size_type> p=this->equal_range_rank(x,comp);
- return p.second-p.first;
- }
- /* rank operations */
- iterator nth(size_type n)const
- {
- return this->make_iterator(index_node_type::from_impl(
- ranked_index_nth(n,this->header()->impl())));
- }
- size_type rank(iterator position)const
- {
- BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
- BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
- return ranked_index_rank(
- position.get_node()->impl(),this->header()->impl());
- }
- template<typename CompatibleKey>
- size_type find_rank(const CompatibleKey& x)const
- {
- return ranked_index_find_rank(
- this->root(),this->header(),this->key,x,this->comp_);
- }
- template<typename CompatibleKey,typename CompatibleCompare>
- size_type find_rank(
- const CompatibleKey& x,const CompatibleCompare& comp)const
- {
- return ranked_index_find_rank(
- this->root(),this->header(),this->key,x,comp);
- }
- template<typename CompatibleKey>
- size_type lower_bound_rank(const CompatibleKey& x)const
- {
- return ranked_index_lower_bound_rank(
- this->root(),this->header(),this->key,x,this->comp_);
- }
- template<typename CompatibleKey,typename CompatibleCompare>
- size_type lower_bound_rank(
- const CompatibleKey& x,const CompatibleCompare& comp)const
- {
- return ranked_index_lower_bound_rank(
- this->root(),this->header(),this->key,x,comp);
- }
- template<typename CompatibleKey>
- size_type upper_bound_rank(const CompatibleKey& x)const
- {
- return ranked_index_upper_bound_rank(
- this->root(),this->header(),this->key,x,this->comp_);
- }
- template<typename CompatibleKey,typename CompatibleCompare>
- size_type upper_bound_rank(
- const CompatibleKey& x,const CompatibleCompare& comp)const
- {
- return ranked_index_upper_bound_rank(
- this->root(),this->header(),this->key,x,comp);
- }
- template<typename CompatibleKey>
- std::pair<size_type,size_type> equal_range_rank(
- const CompatibleKey& x)const
- {
- return ranked_index_equal_range_rank(
- this->root(),this->header(),this->key,x,this->comp_);
- }
- template<typename CompatibleKey,typename CompatibleCompare>
- std::pair<size_type,size_type> equal_range_rank(
- const CompatibleKey& x,const CompatibleCompare& comp)const
- {
- return ranked_index_equal_range_rank(
- this->root(),this->header(),this->key,x,comp);
- }
- template<typename LowerBounder,typename UpperBounder>
- std::pair<size_type,size_type>
- range_rank(LowerBounder lower,UpperBounder upper)const
- {
- typedef typename mpl::if_<
- is_same<LowerBounder,unbounded_type>,
- BOOST_DEDUCED_TYPENAME mpl::if_<
- is_same<UpperBounder,unbounded_type>,
- both_unbounded_tag,
- lower_unbounded_tag
- >::type,
- BOOST_DEDUCED_TYPENAME mpl::if_<
- is_same<UpperBounder,unbounded_type>,
- upper_unbounded_tag,
- none_unbounded_tag
- >::type
- >::type dispatch;
- return range_rank(lower,upper,dispatch());
- }
- protected:
- ranked_index(const ranked_index& x):super(x){};
- ranked_index(const ranked_index& x,do_not_copy_elements_tag):
- super(x,do_not_copy_elements_tag()){};
- ranked_index(
- const ctor_args_list& args_list,const allocator_type& al):
- super(args_list,al){}
- private:
- template<typename LowerBounder,typename UpperBounder>
- std::pair<size_type,size_type>
- range_rank(LowerBounder lower,UpperBounder upper,none_unbounded_tag)const
- {
- index_node_type* y=this->header();
- index_node_type* z=this->root();
- if(!z)return std::pair<size_type,size_type>(0,0);
- size_type s=z->impl()->size;
- do{
- if(!lower(this->key(z->value()))){
- z=index_node_type::from_impl(z->right());
- }
- else if(!upper(this->key(z->value()))){
- y=z;
- s-=ranked_node_size(y->right())+1;
- z=index_node_type::from_impl(z->left());
- }
- else{
- return std::pair<size_type,size_type>(
- s-z->impl()->size+
- lower_range_rank(index_node_type::from_impl(z->left()),z,lower),
- s-ranked_node_size(z->right())+
- upper_range_rank(index_node_type::from_impl(z->right()),y,upper));
- }
- }while(z);
- return std::pair<size_type,size_type>(s,s);
- }
- template<typename LowerBounder,typename UpperBounder>
- std::pair<size_type,size_type>
- range_rank(LowerBounder,UpperBounder upper,lower_unbounded_tag)const
- {
- return std::pair<size_type,size_type>(
- 0,
- upper_range_rank(this->root(),this->header(),upper));
- }
- template<typename LowerBounder,typename UpperBounder>
- std::pair<size_type,size_type>
- range_rank(LowerBounder lower,UpperBounder,upper_unbounded_tag)const
- {
- return std::pair<size_type,size_type>(
- lower_range_rank(this->root(),this->header(),lower),
- this->size());
- }
- template<typename LowerBounder,typename UpperBounder>
- std::pair<size_type,size_type>
- range_rank(LowerBounder,UpperBounder,both_unbounded_tag)const
- {
- return std::pair<size_type,size_type>(0,this->size());
- }
- template<typename LowerBounder>
- size_type
- lower_range_rank(
- index_node_type* top,index_node_type* y,LowerBounder lower)const
- {
- if(!top)return 0;
- size_type s=top->impl()->size;
- do{
- if(lower(this->key(top->value()))){
- y=top;
- s-=ranked_node_size(y->right())+1;
- top=index_node_type::from_impl(top->left());
- }
- else top=index_node_type::from_impl(top->right());
- }while(top);
- return s;
- }
- template<typename UpperBounder>
- size_type
- upper_range_rank(
- index_node_type* top,index_node_type* y,UpperBounder upper)const
- {
- if(!top)return 0;
- size_type s=top->impl()->size;
- do{
- if(!upper(this->key(top->value()))){
- y=top;
- s-=ranked_node_size(y->right())+1;
- top=index_node_type::from_impl(top->left());
- }
- else top=index_node_type::from_impl(top->right());
- }while(top);
- return s;
- }
- };
- /* augmenting policy for ordered_index */
- struct rank_policy
- {
- template<typename OrderedIndexNodeImpl>
- struct augmented_node
- {
- typedef ranked_node<OrderedIndexNodeImpl> type;
- };
- template<typename OrderedIndexImpl>
- struct augmented_interface
- {
- typedef ranked_index<OrderedIndexImpl> type;
- };
- /* algorithmic stuff */
- template<typename Pointer>
- static void add(Pointer x,Pointer root)
- {
- x->size=1;
- while(x!=root){
- x=x->parent();
- ++(x->size);
- }
- }
- template<typename Pointer>
- static void remove(Pointer x,Pointer root)
- {
- while(x!=root){
- x=x->parent();
- --(x->size);
- }
- }
- template<typename Pointer>
- static void copy(Pointer x,Pointer y)
- {
- y->size=x->size;
- }
- template<typename Pointer>
- static void rotate_left(Pointer x,Pointer y) /* in: x==y->left() */
- {
- y->size=x->size;
- x->size=ranked_node_size(x->left())+ranked_node_size(x->right())+1;
- }
- template<typename Pointer>
- static void rotate_right(Pointer x,Pointer y) /* in: x==y->right() */
- {
- rotate_left(x,y);
- }
- #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
- /* invariant stuff */
- template<typename Pointer>
- static bool invariant(Pointer x)
- {
- return x->size==ranked_node_size(x->left())+ranked_node_size(x->right())+1;
- }
- #endif
- };
- } /* namespace multi_index::detail */
- /* ranked_index specifiers */
- template<typename Arg1,typename Arg2,typename Arg3>
- struct ranked_unique
- {
- typedef typename detail::ordered_index_args<
- Arg1,Arg2,Arg3> index_args;
- typedef typename index_args::tag_list_type::type tag_list_type;
- typedef typename index_args::key_from_value_type key_from_value_type;
- typedef typename index_args::compare_type compare_type;
- template<typename Super>
- struct node_class
- {
- typedef detail::ordered_index_node<detail::rank_policy,Super> type;
- };
- template<typename SuperMeta>
- struct index_class
- {
- typedef detail::ordered_index<
- key_from_value_type,compare_type,
- SuperMeta,tag_list_type,detail::ordered_unique_tag,
- detail::rank_policy> type;
- };
- };
- template<typename Arg1,typename Arg2,typename Arg3>
- struct ranked_non_unique
- {
- typedef detail::ordered_index_args<
- Arg1,Arg2,Arg3> index_args;
- typedef typename index_args::tag_list_type::type tag_list_type;
- typedef typename index_args::key_from_value_type key_from_value_type;
- typedef typename index_args::compare_type compare_type;
- template<typename Super>
- struct node_class
- {
- typedef detail::ordered_index_node<detail::rank_policy,Super> type;
- };
- template<typename SuperMeta>
- struct index_class
- {
- typedef detail::ordered_index<
- key_from_value_type,compare_type,
- SuperMeta,tag_list_type,detail::ordered_non_unique_tag,
- detail::rank_policy> type;
- };
- };
- } /* namespace multi_index */
- } /* namespace boost */
- #endif
|