Chris@101: /* Copyright 2003-2014 Joaquin M Lopez Munoz. Chris@16: * Distributed under the Boost Software License, Version 1.0. Chris@16: * (See accompanying file LICENSE_1_0.txt or copy at Chris@16: * http://www.boost.org/LICENSE_1_0.txt) Chris@16: * Chris@16: * See http://www.boost.org/libs/multi_index for library home page. Chris@16: */ Chris@16: Chris@16: #ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_BASE_HPP Chris@16: #define BOOST_MULTI_INDEX_DETAIL_INDEX_BASE_HPP Chris@16: Chris@101: #if defined(_MSC_VER) Chris@16: #pragma once Chris@16: #endif Chris@16: Chris@16: #include /* keep it first to prevent nasty warns in MSVC */ Chris@16: #include Chris@101: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) Chris@16: #include Chris@16: #include Chris@16: #endif Chris@16: Chris@16: namespace boost{ Chris@16: Chris@16: namespace multi_index{ Chris@16: Chris@16: namespace detail{ Chris@16: Chris@16: /* The role of this class is threefold: Chris@16: * - tops the linear hierarchy of indices. Chris@16: * - terminates some cascading backbone function calls (insert_, etc.), Chris@16: * - grants access to the backbone functions of the final Chris@16: * multi_index_container class (for access restriction reasons, these Chris@16: * cannot be called directly from the index classes.) Chris@16: */ Chris@16: Chris@16: struct lvalue_tag{}; Chris@16: struct rvalue_tag{}; Chris@16: struct emplaced_tag{}; Chris@16: Chris@16: template Chris@16: class index_base Chris@16: { Chris@16: protected: Chris@16: typedef index_node_base node_type; Chris@16: typedef typename multi_index_node_type< Chris@16: Value,IndexSpecifierList,Allocator>::type final_node_type; Chris@16: typedef multi_index_container< Chris@16: Value,IndexSpecifierList,Allocator> final_type; Chris@16: typedef tuples::null_type ctor_args_list; Chris@16: typedef typename Chris@101: boost::detail::allocator::rebind_to< Chris@101: Allocator, Chris@101: typename Allocator::value_type Chris@101: >::type final_allocator_type; Chris@16: typedef mpl::vector0<> index_type_list; Chris@16: typedef mpl::vector0<> iterator_type_list; Chris@16: typedef mpl::vector0<> const_iterator_type_list; Chris@16: typedef copy_map< Chris@16: final_node_type, Chris@16: final_allocator_type> copy_map_type; Chris@16: Chris@16: #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) Chris@16: typedef index_saver< Chris@16: node_type, Chris@16: final_allocator_type> index_saver_type; Chris@16: typedef index_loader< Chris@16: node_type, Chris@16: final_node_type, Chris@16: final_allocator_type> index_loader_type; Chris@16: #endif Chris@16: Chris@16: private: Chris@16: typedef Value value_type; Chris@16: Chris@16: protected: Chris@16: explicit index_base(const ctor_args_list&,const Allocator&){} Chris@16: Chris@16: index_base( Chris@16: const index_base&, Chris@16: do_not_copy_elements_tag) Chris@16: {} Chris@16: Chris@16: void copy_( Chris@16: const index_base&,const copy_map_type&) Chris@16: {} Chris@16: Chris@101: final_node_type* insert_(const value_type& v,final_node_type*& x,lvalue_tag) Chris@16: { Chris@101: x=final().allocate_node(); Chris@101: BOOST_TRY{ Chris@101: boost::detail::allocator::construct(&x->value(),v); Chris@101: } Chris@101: BOOST_CATCH(...){ Chris@101: final().deallocate_node(x); Chris@101: BOOST_RETHROW; Chris@101: } Chris@101: BOOST_CATCH_END Chris@16: return x; Chris@16: } Chris@16: Chris@101: final_node_type* insert_(const value_type& v,final_node_type*& x,rvalue_tag) Chris@16: { Chris@101: x=final().allocate_node(); Chris@101: BOOST_TRY{ Chris@101: /* This shoud have used a modified, T&&-compatible version of Chris@101: * boost::detail::allocator::construct, but Chris@101: * is too old and venerable to Chris@101: * mess with; besides, it is a general internal utility and the imperfect Chris@101: * perfect forwarding emulation of Boost.Move might break other libs. Chris@101: */ Chris@16: Chris@101: new (&x->value()) value_type(boost::move(const_cast(v))); Chris@101: } Chris@101: BOOST_CATCH(...){ Chris@101: final().deallocate_node(x); Chris@101: BOOST_RETHROW; Chris@101: } Chris@101: BOOST_CATCH_END Chris@16: return x; Chris@16: } Chris@16: Chris@101: final_node_type* insert_(const value_type&,final_node_type*& x,emplaced_tag) Chris@16: { Chris@16: return x; Chris@16: } Chris@16: Chris@101: final_node_type* insert_( Chris@101: const value_type& v,node_type*,final_node_type*& x,lvalue_tag) Chris@16: { Chris@101: return insert_(v,x,lvalue_tag()); Chris@16: } Chris@16: Chris@101: final_node_type* insert_( Chris@101: const value_type& v,node_type*,final_node_type*& x,rvalue_tag) Chris@16: { Chris@101: return insert_(v,x,rvalue_tag()); Chris@16: } Chris@16: Chris@101: final_node_type* insert_( Chris@101: const value_type&,node_type*,final_node_type*& x,emplaced_tag) Chris@16: { Chris@16: return x; Chris@16: } Chris@16: Chris@16: void erase_(node_type* x) Chris@16: { Chris@16: boost::detail::allocator::destroy(&x->value()); Chris@16: } Chris@16: Chris@16: void delete_node_(node_type* x) Chris@16: { Chris@16: boost::detail::allocator::destroy(&x->value()); Chris@16: } Chris@16: Chris@16: void clear_(){} Chris@16: Chris@16: void swap_(index_base&){} Chris@16: Chris@16: void swap_elements_(index_base&){} Chris@16: Chris@16: bool replace_(const value_type& v,node_type* x,lvalue_tag) Chris@16: { Chris@16: x->value()=v; Chris@16: return true; Chris@16: } Chris@16: Chris@16: bool replace_(const value_type& v,node_type* x,rvalue_tag) Chris@16: { Chris@16: x->value()=boost::move(const_cast(v)); Chris@16: return true; Chris@16: } Chris@16: Chris@16: bool modify_(node_type*){return true;} Chris@16: Chris@16: bool modify_rollback_(node_type*){return true;} Chris@16: Chris@16: #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) Chris@16: /* serialization */ Chris@16: Chris@16: template Chris@16: void save_(Archive&,const unsigned int,const index_saver_type&)const{} Chris@16: Chris@16: template Chris@16: void load_(Archive&,const unsigned int,const index_loader_type&){} Chris@16: #endif Chris@16: Chris@16: #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) Chris@16: /* invariant stuff */ Chris@16: Chris@16: bool invariant_()const{return true;} Chris@16: #endif Chris@16: Chris@16: /* access to backbone memfuns of Final class */ Chris@16: Chris@16: final_type& final(){return *static_cast(this);} Chris@16: const final_type& final()const{return *static_cast(this);} Chris@16: Chris@16: final_node_type* final_header()const{return final().header();} Chris@16: Chris@16: bool final_empty_()const{return final().empty_();} Chris@16: std::size_t final_size_()const{return final().size_();} Chris@16: std::size_t final_max_size_()const{return final().max_size_();} Chris@16: Chris@16: std::pair final_insert_(const value_type& x) Chris@16: {return final().insert_(x);} Chris@16: std::pair final_insert_rv_(const value_type& x) Chris@16: {return final().insert_rv_(x);} Chris@16: template Chris@101: std::pair final_insert_ref_(const T& t) Chris@101: {return final().insert_ref_(t);} Chris@101: template Chris@16: std::pair final_insert_ref_(T& t) Chris@16: {return final().insert_ref_(t);} Chris@16: Chris@16: template Chris@16: std::pair final_emplace_( Chris@16: BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) Chris@16: { Chris@16: return final().emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); Chris@16: } Chris@16: Chris@16: std::pair final_insert_( Chris@16: const value_type& x,final_node_type* position) Chris@16: {return final().insert_(x,position);} Chris@16: std::pair final_insert_rv_( Chris@16: const value_type& x,final_node_type* position) Chris@16: {return final().insert_rv_(x,position);} Chris@16: template Chris@16: std::pair final_insert_ref_( Chris@101: const T& t,final_node_type* position) Chris@101: {return final().insert_ref_(t,position);} Chris@101: template Chris@101: std::pair final_insert_ref_( Chris@16: T& t,final_node_type* position) Chris@16: {return final().insert_ref_(t,position);} Chris@16: Chris@16: template Chris@16: std::pair final_emplace_hint_( Chris@16: final_node_type* position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) Chris@16: { Chris@16: return final().emplace_hint_( Chris@16: position,BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); Chris@16: } Chris@16: Chris@16: void final_erase_(final_node_type* x){final().erase_(x);} Chris@16: Chris@16: void final_delete_node_(final_node_type* x){final().delete_node_(x);} Chris@16: void final_delete_all_nodes_(){final().delete_all_nodes_();} Chris@16: void final_clear_(){final().clear_();} Chris@16: Chris@16: void final_swap_(final_type& x){final().swap_(x);} Chris@16: Chris@16: bool final_replace_( Chris@16: const value_type& k,final_node_type* x) Chris@16: {return final().replace_(k,x);} Chris@16: bool final_replace_rv_( Chris@16: const value_type& k,final_node_type* x) Chris@16: {return final().replace_rv_(k,x);} Chris@16: Chris@16: template Chris@16: bool final_modify_(Modifier& mod,final_node_type* x) Chris@16: {return final().modify_(mod,x);} Chris@16: Chris@16: template Chris@16: bool final_modify_(Modifier& mod,Rollback& back,final_node_type* x) Chris@16: {return final().modify_(mod,back,x);} Chris@16: Chris@16: #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) Chris@16: void final_check_invariant_()const{final().check_invariant_();} Chris@16: #endif Chris@16: }; Chris@16: Chris@16: } /* namespace multi_index::detail */ Chris@16: Chris@16: } /* namespace multi_index */ Chris@16: Chris@16: } /* namespace boost */ Chris@16: Chris@16: #endif