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