index_base.hpp 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. /* Copyright 2003-2021 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)
  5. *
  6. * See http://www.boost.org/libs/multi_index for library home page.
  7. */
  8. #ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_BASE_HPP
  9. #define BOOST_MULTI_INDEX_DETAIL_INDEX_BASE_HPP
  10. #if defined(_MSC_VER)
  11. #pragma once
  12. #endif
  13. #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
  14. #include <boost/core/addressof.hpp>
  15. #include <boost/core/no_exceptions_support.hpp>
  16. #include <boost/detail/workaround.hpp>
  17. #include <boost/move/utility_core.hpp>
  18. #include <boost/mpl/vector.hpp>
  19. #include <boost/multi_index/detail/allocator_traits.hpp>
  20. #include <boost/multi_index/detail/copy_map.hpp>
  21. #include <boost/multi_index/detail/do_not_copy_elements_tag.hpp>
  22. #include <boost/multi_index/detail/index_access_sequence.hpp>
  23. #include <boost/multi_index/detail/node_handle.hpp>
  24. #include <boost/multi_index/detail/node_type.hpp>
  25. #include <boost/multi_index/detail/vartempl_support.hpp>
  26. #include <boost/multi_index_container_fwd.hpp>
  27. #include <boost/tuple/tuple.hpp>
  28. #include <utility>
  29. #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
  30. #include <boost/multi_index/detail/index_loader.hpp>
  31. #include <boost/multi_index/detail/index_saver.hpp>
  32. #endif
  33. namespace boost{
  34. namespace multi_index{
  35. namespace detail{
  36. /* The role of this class is threefold:
  37. * - tops the linear hierarchy of indices.
  38. * - terminates some cascading backbone function calls (insert_, etc.),
  39. * - grants access to the backbone functions of the final
  40. * multi_index_container class (for access restriction reasons, these
  41. * cannot be called directly from the index classes.)
  42. */
  43. struct lvalue_tag{};
  44. struct rvalue_tag{};
  45. struct emplaced_tag{};
  46. template<typename Value,typename IndexSpecifierList,typename Allocator>
  47. class index_base
  48. {
  49. protected:
  50. typedef index_node_base<Value,Allocator> index_node_type;
  51. typedef typename multi_index_node_type<
  52. Value,IndexSpecifierList,Allocator>::type final_node_type;
  53. typedef multi_index_container<
  54. Value,IndexSpecifierList,Allocator> final_type;
  55. typedef tuples::null_type ctor_args_list;
  56. typedef typename rebind_alloc_for<
  57. Allocator,typename Allocator::value_type
  58. >::type final_allocator_type;
  59. typedef node_handle<
  60. final_node_type,final_allocator_type> final_node_handle_type;
  61. typedef mpl::vector0<> index_type_list;
  62. typedef mpl::vector0<> iterator_type_list;
  63. typedef mpl::vector0<> const_iterator_type_list;
  64. typedef copy_map<
  65. final_node_type,
  66. final_allocator_type> copy_map_type;
  67. #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
  68. typedef index_saver<
  69. index_node_type,
  70. final_allocator_type> index_saver_type;
  71. typedef index_loader<
  72. index_node_type,
  73. final_node_type,
  74. final_allocator_type> index_loader_type;
  75. #endif
  76. private:
  77. typedef Value value_type;
  78. typedef allocator_traits<Allocator> alloc_traits;
  79. typedef typename alloc_traits::size_type size_type;
  80. protected:
  81. explicit index_base(const ctor_args_list&,const Allocator&){}
  82. index_base(
  83. const index_base<Value,IndexSpecifierList,Allocator>&,
  84. do_not_copy_elements_tag)
  85. {}
  86. void copy_(
  87. const index_base<Value,IndexSpecifierList,Allocator>&,const copy_map_type&)
  88. {}
  89. final_node_type* insert_(const value_type& v,final_node_type*& x,lvalue_tag)
  90. {
  91. x=final().allocate_node();
  92. BOOST_TRY{
  93. final().construct_value(x,v);
  94. }
  95. BOOST_CATCH(...){
  96. final().deallocate_node(x);
  97. BOOST_RETHROW;
  98. }
  99. BOOST_CATCH_END
  100. return x;
  101. }
  102. final_node_type* insert_(const value_type& v,final_node_type*& x,rvalue_tag)
  103. {
  104. x=final().allocate_node();
  105. BOOST_TRY{
  106. final().construct_value(x,boost::move(const_cast<value_type&>(v)));
  107. }
  108. BOOST_CATCH(...){
  109. final().deallocate_node(x);
  110. BOOST_RETHROW;
  111. }
  112. BOOST_CATCH_END
  113. return x;
  114. }
  115. final_node_type* insert_(const value_type&,final_node_type*& x,emplaced_tag)
  116. {
  117. return x;
  118. }
  119. template<typename MultiIndexContainer>
  120. final_node_type* insert_(
  121. const value_type&,final_node_type*& x,MultiIndexContainer* p)
  122. {
  123. p->final_extract_for_transfer_(
  124. x,index_access_sequence<final_type>(&final()));
  125. return x;
  126. }
  127. final_node_type* insert_(
  128. const value_type& v,index_node_type*,final_node_type*& x,lvalue_tag)
  129. {
  130. return insert_(v,x,lvalue_tag());
  131. }
  132. final_node_type* insert_(
  133. const value_type& v,index_node_type*,final_node_type*& x,rvalue_tag)
  134. {
  135. return insert_(v,x,rvalue_tag());
  136. }
  137. final_node_type* insert_(
  138. const value_type&,index_node_type*,final_node_type*& x,emplaced_tag)
  139. {
  140. return x;
  141. }
  142. template<typename Dst>
  143. void extract_(index_node_type*,Dst){}
  144. void clear_(){}
  145. template<typename BoolConstant>
  146. void swap_(
  147. index_base<Value,IndexSpecifierList,Allocator>&,
  148. BoolConstant /* swap_allocators */)
  149. {}
  150. void swap_elements_(index_base<Value,IndexSpecifierList,Allocator>&){}
  151. bool replace_(const value_type& v,index_node_type* x,lvalue_tag)
  152. {
  153. x->value()=v;
  154. return true;
  155. }
  156. bool replace_(const value_type& v,index_node_type* x,rvalue_tag)
  157. {
  158. x->value()=boost::move(const_cast<value_type&>(v));
  159. return true;
  160. }
  161. bool modify_(index_node_type*){return true;}
  162. bool modify_rollback_(index_node_type*){return true;}
  163. bool check_rollback_(index_node_type*)const{return true;}
  164. #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
  165. /* serialization */
  166. template<typename Archive>
  167. void save_(Archive&,const unsigned int,const index_saver_type&)const{}
  168. template<typename Archive>
  169. void load_(Archive&,const unsigned int,const index_loader_type&){}
  170. #endif
  171. #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
  172. /* invariant stuff */
  173. bool invariant_()const{return true;}
  174. #endif
  175. /* access to backbone memfuns of Final class */
  176. final_type& final(){return *static_cast<final_type*>(this);}
  177. const final_type& final()const{return *static_cast<const final_type*>(this);}
  178. template<typename Index>
  179. static typename Index::final_type& final(Index& x) /* cross-index access */
  180. {return static_cast<typename Index::final_type&>(x);}
  181. final_node_type* final_header()const{return final().header();}
  182. bool final_empty_()const{return final().empty_();}
  183. size_type final_size_()const{return final().size_();}
  184. size_type final_max_size_()const{return final().max_size_();}
  185. std::pair<final_node_type*,bool> final_insert_(const value_type& x)
  186. {return final().insert_(x);}
  187. std::pair<final_node_type*,bool> final_insert_rv_(const value_type& x)
  188. {return final().insert_rv_(x);}
  189. template<typename T>
  190. std::pair<final_node_type*,bool> final_insert_ref_(const T& t)
  191. {return final().insert_ref_(t);}
  192. template<typename T>
  193. std::pair<final_node_type*,bool> final_insert_ref_(T& t)
  194. {return final().insert_ref_(t);}
  195. std::pair<final_node_type*,bool> final_insert_nh_(final_node_handle_type& nh)
  196. {return final().insert_nh_(nh);}
  197. template<typename Index>
  198. std::pair<final_node_type*,bool> final_transfer_(Index& x,final_node_type* n)
  199. {return final().transfer_(x,n);}
  200. template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
  201. std::pair<final_node_type*,bool> final_emplace_(
  202. BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
  203. {
  204. return final().emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
  205. }
  206. std::pair<final_node_type*,bool> final_insert_(
  207. const value_type& x,final_node_type* position)
  208. {return final().insert_(x,position);}
  209. std::pair<final_node_type*,bool> final_insert_rv_(
  210. const value_type& x,final_node_type* position)
  211. {return final().insert_rv_(x,position);}
  212. template<typename T>
  213. std::pair<final_node_type*,bool> final_insert_ref_(
  214. const T& t,final_node_type* position)
  215. {return final().insert_ref_(t,position);}
  216. template<typename T>
  217. std::pair<final_node_type*,bool> final_insert_ref_(
  218. T& t,final_node_type* position)
  219. {return final().insert_ref_(t,position);}
  220. std::pair<final_node_type*,bool> final_insert_nh_(
  221. final_node_handle_type& nh,final_node_type* position)
  222. {return final().insert_nh_(nh,position);}
  223. template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
  224. std::pair<final_node_type*,bool> final_emplace_hint_(
  225. final_node_type* position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
  226. {
  227. return final().emplace_hint_(
  228. position,BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
  229. }
  230. final_node_handle_type final_extract_(final_node_type* x)
  231. {
  232. return final().extract_(x);
  233. }
  234. template<typename Dst>
  235. void final_extract_for_transfer_(final_node_type* x,Dst dst)
  236. {
  237. final().extract_for_transfer_(x,dst);
  238. }
  239. void final_erase_(final_node_type* x){final().erase_(x);}
  240. void final_delete_node_(final_node_type* x){final().delete_node_(x);}
  241. void final_delete_all_nodes_(){final().delete_all_nodes_();}
  242. void final_clear_(){final().clear_();}
  243. template<typename Index>
  244. void final_transfer_range_(
  245. Index& x,
  246. BOOST_DEDUCED_TYPENAME Index::iterator first,
  247. BOOST_DEDUCED_TYPENAME Index::iterator last)
  248. {final().transfer_range_(x,first,last);}
  249. void final_swap_(final_type& x){final().swap_(x);}
  250. bool final_replace_(
  251. const value_type& k,final_node_type* x)
  252. {return final().replace_(k,x);}
  253. bool final_replace_rv_(
  254. const value_type& k,final_node_type* x)
  255. {return final().replace_rv_(k,x);}
  256. template<typename Modifier>
  257. bool final_modify_(Modifier& mod,final_node_type* x)
  258. {return final().modify_(mod,x);}
  259. template<typename Modifier,typename Rollback>
  260. bool final_modify_(Modifier& mod,Rollback& back,final_node_type* x)
  261. {return final().modify_(mod,back,x);}
  262. #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
  263. void final_check_invariant_()const{final().check_invariant_();}
  264. #endif
  265. };
  266. } /* namespace multi_index::detail */
  267. } /* namespace multi_index */
  268. } /* namespace boost */
  269. #endif