📄 ordered_index.hpp
字号:
/* Copyright 2003-2004 Joaqu韓 M L髉ez Mu駉z. * 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. * * The internal implementation of red-black trees is based on that of SGI STL * stl_tree.h file: * * Copyright (c) 1996,1997 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Silicon Graphics makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * * Copyright (c) 1994 * Hewlett-Packard Company * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Hewlett-Packard Company makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * */#ifndef BOOST_MULTI_INDEX_ORDERED_INDEX_HPP#define BOOST_MULTI_INDEX_ORDERED_INDEX_HPP#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */#include <algorithm>#include <boost/call_traits.hpp>#include <boost/detail/no_exceptions_support.hpp>#include <boost/detail/workaround.hpp>#include <boost/iterator/reverse_iterator.hpp>#include <boost/mpl/push_front.hpp>#include <boost/multi_index/detail/access_specifier.hpp>#include <boost/multi_index/detail/index_iterator.hpp>#include <boost/multi_index/detail/modify_key_adaptor.hpp>#include <boost/multi_index/detail/ord_index_node.hpp>#include <boost/multi_index/detail/ord_index_ops.hpp>#include <boost/multi_index/detail/prevent_eti.hpp>#include <boost/multi_index/detail/safe_mode.hpp>#include <boost/multi_index/detail/scope_guard.hpp>#include <boost/multi_index/detail/unbounded.hpp>#include <boost/multi_index/detail/value_compare.hpp>#include <boost/multi_index/ordered_index_fwd.hpp>#include <boost/ref.hpp>#include <boost/tuple/tuple.hpp>#include <utility>#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT \ detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ detail::make_obj_guard(*this,&ordered_index::check_invariant_); \ BOOST_JOIN(check_invariant_,__LINE__).touch();#else#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT#endifnamespace boost{namespace multi_index{namespace detail{/* ordered_index adds a layer of indexing to a given Super *//* Most of the implementation of unique and non-unique indices is * shared. We tell from one another on instantiation time by using * these tags. */struct ordered_unique_tag{};struct ordered_non_unique_tag{};template< typename KeyFromValue,typename Compare, typename Super,typename TagList,typename Category>#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)#if BOOST_WORKAROUND(BOOST_MSVC,<1300)class ordered_index: BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS Super, public index_proxy<ordered_index_node<typename Super::node_type> >#elseclass ordered_index: BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS Super, public safe_container< ordered_index<KeyFromValue,Compare,Super,TagList,Category> >#endif#elseclass ordered_index: BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS Super#endif{ #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ BOOST_WORKAROUND(__MWERKS__,<=0x3003)/* The "ISO C++ Template Parser" option in CW8.3 has a problem with the * lifetime of const references bound to temporaries --precisely what * scopeguards are. */#pragma parse_mfunc_templ off#endifprotected: typedef ordered_index_node< typename Super::node_type> node_type;public: /* types */ typedef typename KeyFromValue::result_type key_type; typedef typename node_type::value_type value_type; typedef KeyFromValue key_from_value; typedef Compare key_compare; typedef value_comparison< value_type,KeyFromValue,Compare> value_compare; typedef tuple<key_from_value,key_compare> ctor_args; typedef typename Super::final_allocator_type allocator_type; typedef typename allocator_type::reference reference; typedef typename allocator_type::const_reference const_reference;#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)#if BOOST_WORKAROUND(BOOST_MSVC,<1300) typedef index_iterator<node_type> iterator; typedef index_iterator<node_type> const_iterator;#else typedef index_iterator<node_type,ordered_index> iterator; typedef index_iterator<node_type,ordered_index> const_iterator;#endif#else typedef index_iterator<node_type> iterator; typedef index_iterator<node_type> const_iterator;#endif typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; typedef typename allocator_type::pointer pointer; typedef typename allocator_type::const_pointer const_pointer; typedef typename boost::reverse_iterator<iterator> reverse_iterator; typedef typename boost::reverse_iterator<const_iterator> const_reverse_iterator; typedef typename TagList::type tag_list;protected: typedef typename Super::final_node_type final_node_type; typedef tuples::cons< ctor_args, typename Super::ctor_args_list> ctor_args_list; typedef typename mpl::push_front< typename Super::index_type_list, ordered_index>::type index_type_list; typedef typename mpl::push_front< typename Super::iterator_type_list, iterator>::type iterator_type_list; typedef typename mpl::push_front< typename Super::const_iterator_type_list, const_iterator>::type const_iterator_type_list; typedef typename Super::copy_map_type copy_map_type;private:#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)#if BOOST_WORKAROUND(BOOST_MSVC,<1300) typedef index_proxy< ordered_index_node< typename Super::node_type> > safe_super;#else typedef safe_container<ordered_index> safe_super;#endif#endif typedef typename call_traits< value_type>::param_type value_param_type; typedef typename call_traits< key_type>::param_type key_param_type;public: /* construct/copy/destroy * Default and copy ctors are in the protected section as indices are * not supposed to be created on their own. No range ctor either. */ ordered_index<KeyFromValue,Compare,Super,TagList,Category>& operator=( const ordered_index<KeyFromValue,Compare,Super,TagList,Category>& x) { BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; this->final()=x.final(); return *this; } allocator_type get_allocator()const { return this->final().get_allocator(); } /* iterators */ iterator begin(){return make_iterator(leftmost());} const_iterator begin()const{return make_iterator(leftmost());} iterator end(){return make_iterator(header());} const_iterator end()const{return make_iterator(header());} reverse_iterator rbegin(){return make_reverse_iterator(end());} const_reverse_iterator rbegin()const{return make_reverse_iterator(end());} reverse_iterator rend(){return make_reverse_iterator(begin());} const_reverse_iterator rend()const{return make_reverse_iterator(begin());} /* capacity */ bool empty()const{return this->final_empty_();} size_type size()const{return this->final_size_();} size_type max_size()const{return this->final_max_size_();} /* modifiers */ std::pair<iterator,bool> insert(value_param_type x) { BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; std::pair<final_node_type*,bool> p=this->final_insert_(x); return std::pair<iterator,bool>(make_iterator(p.first),p.second); } iterator insert(iterator position,value_param_type x) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; std::pair<final_node_type*,bool> p=this->final_insert_( x,static_cast<final_node_type*>(position.get_node())); return make_iterator(p.first); } template<typename InputIterator> void insert(InputIterator first,InputIterator last) { BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; iterator hint=end(); for(;first!=last;++first)hint=insert(hint,*first); } void erase(iterator position) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) /* MSVC++ 6.0 optimizer on safe mode code chokes if this * this is not added. Left it for all compilers as it does no * harm. */ position.detach();#endif this->final_erase_(static_cast<final_node_type*>(position.get_node())); } size_type erase(key_param_type x) { BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; std::pair<iterator,iterator> p=equal_range(x); size_type s=0; while(p.first!=p.second){ erase(p.first++); ++s; } return s; } void erase(iterator first,iterator last) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this); BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this); BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; while(first!=last){ erase(first++); } } bool replace(iterator position,value_param_type x) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; return this->final_replace_( x,static_cast<final_node_type*>(position.get_node())); } template<typename Modifier> bool modify(iterator position,Modifier mod) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) /* MSVC++ 6.0 optimizer on safe mode code chokes if this * this is not added. Left it for all compilers as it does no * harm. */ position.detach();#endif return this->final_modify_( mod,static_cast<final_node_type*>(position.get_node())); } template<typename Modifier> bool modify_key(iterator position,Modifier mod) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; return modify( position,modify_key_adaptor<Modifier,value_type,KeyFromValue>(mod,key)); } void swap(ordered_index<KeyFromValue,Compare,Super,TagList,Category>& x) { BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; this->final_swap_(x.final()); } void clear() { BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; erase(begin(),end()); } /* observers */ key_from_value key_extractor()const{return key;} key_compare key_comp()const{return comp;} value_compare value_comp()const{return value_compare(key,comp);} /* set operations */ /* no need to provide non-const versions as * ordered_index::iterator==ordered_index::const_iterator */ template<typename CompatibleKey> const_iterator find(const CompatibleKey& x)const { return make_iterator(ordered_index_find(header(),key,x,comp)); } template<typename CompatibleKey,typename CompatibleCompare> const_iterator find( const CompatibleKey& x,const CompatibleCompare& comp)const { return make_iterator(ordered_index_find(header(),key,x,comp)); } template<typename CompatibleKey> size_type count(const CompatibleKey& x)const {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -