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