]>
Commit | Line | Data |
---|---|---|
92f5a8d4 | 1 | /* Copyright 2003-2019 Joaquin M Lopez Munoz. |
7c673cae FG |
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_SEQUENCED_INDEX_HPP | |
10 | #define BOOST_MULTI_INDEX_SEQUENCED_INDEX_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/bind.hpp> | |
18 | #include <boost/call_traits.hpp> | |
11fdf7f2 | 19 | #include <boost/core/addressof.hpp> |
7c673cae FG |
20 | #include <boost/detail/no_exceptions_support.hpp> |
21 | #include <boost/detail/workaround.hpp> | |
22 | #include <boost/foreach_fwd.hpp> | |
23 | #include <boost/iterator/reverse_iterator.hpp> | |
24 | #include <boost/move/core.hpp> | |
92f5a8d4 | 25 | #include <boost/move/utility_core.hpp> |
7c673cae FG |
26 | #include <boost/mpl/bool.hpp> |
27 | #include <boost/mpl/not.hpp> | |
28 | #include <boost/mpl/push_front.hpp> | |
29 | #include <boost/multi_index/detail/access_specifier.hpp> | |
92f5a8d4 | 30 | #include <boost/multi_index/detail/allocator_traits.hpp> |
7c673cae FG |
31 | #include <boost/multi_index/detail/bidir_node_iterator.hpp> |
32 | #include <boost/multi_index/detail/do_not_copy_elements_tag.hpp> | |
33 | #include <boost/multi_index/detail/index_node_base.hpp> | |
34 | #include <boost/multi_index/detail/safe_mode.hpp> | |
35 | #include <boost/multi_index/detail/scope_guard.hpp> | |
36 | #include <boost/multi_index/detail/seq_index_node.hpp> | |
37 | #include <boost/multi_index/detail/seq_index_ops.hpp> | |
38 | #include <boost/multi_index/detail/vartempl_support.hpp> | |
39 | #include <boost/multi_index/sequenced_index_fwd.hpp> | |
40 | #include <boost/tuple/tuple.hpp> | |
41 | #include <boost/type_traits/is_integral.hpp> | |
7c673cae FG |
42 | #include <functional> |
43 | #include <utility> | |
44 | ||
45 | #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) | |
46 | #include<initializer_list> | |
47 | #endif | |
48 | ||
49 | #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) | |
50 | #include <boost/bind.hpp> | |
51 | #endif | |
52 | ||
53 | #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) | |
54 | #define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(x) \ | |
55 | detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ | |
56 | detail::make_obj_guard(x,&sequenced_index::check_invariant_); \ | |
57 | BOOST_JOIN(check_invariant_,__LINE__).touch(); | |
58 | #define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT \ | |
59 | BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(*this) | |
60 | #else | |
61 | #define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(x) | |
62 | #define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT | |
63 | #endif | |
64 | ||
65 | namespace boost{ | |
66 | ||
67 | namespace multi_index{ | |
68 | ||
69 | namespace detail{ | |
70 | ||
71 | /* sequenced_index adds a layer of sequenced indexing to a given Super */ | |
72 | ||
73 | template<typename SuperMeta,typename TagList> | |
74 | class sequenced_index: | |
75 | BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type | |
76 | ||
77 | #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) | |
78 | ,public safe_mode::safe_container< | |
79 | sequenced_index<SuperMeta,TagList> > | |
80 | #endif | |
81 | ||
82 | { | |
83 | #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ | |
84 | BOOST_WORKAROUND(__MWERKS__,<=0x3003) | |
85 | /* The "ISO C++ Template Parser" option in CW8.3 has a problem with the | |
86 | * lifetime of const references bound to temporaries --precisely what | |
87 | * scopeguards are. | |
88 | */ | |
89 | ||
90 | #pragma parse_mfunc_templ off | |
91 | #endif | |
92 | ||
92f5a8d4 | 93 | typedef typename SuperMeta::type super; |
7c673cae FG |
94 | |
95 | protected: | |
96 | typedef sequenced_index_node< | |
92f5a8d4 | 97 | typename super::node_type> node_type; |
7c673cae FG |
98 | |
99 | private: | |
92f5a8d4 | 100 | typedef typename node_type::impl_type node_impl_type; |
7c673cae FG |
101 | |
102 | public: | |
103 | /* types */ | |
104 | ||
92f5a8d4 TL |
105 | typedef typename node_type::value_type value_type; |
106 | typedef tuples::null_type ctor_args; | |
107 | typedef typename super::final_allocator_type allocator_type; | |
108 | typedef value_type& reference; | |
109 | typedef const value_type& const_reference; | |
7c673cae FG |
110 | |
111 | #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) | |
112 | typedef safe_mode::safe_iterator< | |
113 | bidir_node_iterator<node_type>, | |
92f5a8d4 | 114 | sequenced_index> iterator; |
7c673cae | 115 | #else |
92f5a8d4 | 116 | typedef bidir_node_iterator<node_type> iterator; |
7c673cae FG |
117 | #endif |
118 | ||
92f5a8d4 | 119 | typedef iterator const_iterator; |
7c673cae | 120 | |
92f5a8d4 TL |
121 | private: |
122 | typedef allocator_traits<allocator_type> alloc_traits; | |
123 | ||
124 | public: | |
125 | typedef typename alloc_traits::pointer pointer; | |
126 | typedef typename alloc_traits::const_pointer const_pointer; | |
127 | typedef typename alloc_traits::size_type size_type; | |
128 | typedef typename alloc_traits::difference_type difference_type; | |
7c673cae | 129 | typedef typename |
92f5a8d4 | 130 | boost::reverse_iterator<iterator> reverse_iterator; |
7c673cae | 131 | typedef typename |
92f5a8d4 TL |
132 | boost::reverse_iterator<const_iterator> const_reverse_iterator; |
133 | typedef TagList tag_list; | |
7c673cae FG |
134 | |
135 | protected: | |
136 | typedef typename super::final_node_type final_node_type; | |
137 | typedef tuples::cons< | |
138 | ctor_args, | |
139 | typename super::ctor_args_list> ctor_args_list; | |
140 | typedef typename mpl::push_front< | |
141 | typename super::index_type_list, | |
142 | sequenced_index>::type index_type_list; | |
143 | typedef typename mpl::push_front< | |
144 | typename super::iterator_type_list, | |
145 | iterator>::type iterator_type_list; | |
146 | typedef typename mpl::push_front< | |
147 | typename super::const_iterator_type_list, | |
148 | const_iterator>::type const_iterator_type_list; | |
149 | typedef typename super::copy_map_type copy_map_type; | |
150 | ||
151 | #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) | |
152 | typedef typename super::index_saver_type index_saver_type; | |
153 | typedef typename super::index_loader_type index_loader_type; | |
154 | #endif | |
155 | ||
156 | private: | |
157 | #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) | |
158 | typedef safe_mode::safe_container< | |
159 | sequenced_index> safe_super; | |
160 | #endif | |
161 | ||
162 | typedef typename call_traits<value_type>::param_type value_param_type; | |
163 | ||
164 | /* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL | |
165 | * expansion. | |
166 | */ | |
167 | ||
168 | typedef std::pair<iterator,bool> emplace_return_type; | |
169 | ||
170 | public: | |
171 | ||
172 | /* construct/copy/destroy | |
173 | * Default and copy ctors are in the protected section as indices are | |
174 | * not supposed to be created on their own. No range ctor either. | |
175 | */ | |
176 | ||
177 | sequenced_index<SuperMeta,TagList>& operator=( | |
178 | const sequenced_index<SuperMeta,TagList>& x) | |
179 | { | |
180 | this->final()=x.final(); | |
181 | return *this; | |
182 | } | |
183 | ||
184 | #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) | |
185 | sequenced_index<SuperMeta,TagList>& operator=( | |
186 | std::initializer_list<value_type> list) | |
187 | { | |
188 | this->final()=list; | |
189 | return *this; | |
190 | } | |
191 | #endif | |
192 | ||
193 | template <class InputIterator> | |
194 | void assign(InputIterator first,InputIterator last) | |
195 | { | |
196 | assign_iter(first,last,mpl::not_<is_integral<InputIterator> >()); | |
197 | } | |
198 | ||
199 | #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) | |
200 | void assign(std::initializer_list<value_type> list) | |
201 | { | |
202 | assign(list.begin(),list.end()); | |
203 | } | |
204 | #endif | |
205 | ||
206 | void assign(size_type n,value_param_type value) | |
207 | { | |
208 | BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; | |
209 | clear(); | |
210 | for(size_type i=0;i<n;++i)push_back(value); | |
211 | } | |
212 | ||
213 | allocator_type get_allocator()const BOOST_NOEXCEPT | |
214 | { | |
215 | return this->final().get_allocator(); | |
216 | } | |
217 | ||
218 | /* iterators */ | |
219 | ||
220 | iterator begin()BOOST_NOEXCEPT | |
221 | {return make_iterator(node_type::from_impl(header()->next()));} | |
222 | const_iterator begin()const BOOST_NOEXCEPT | |
223 | {return make_iterator(node_type::from_impl(header()->next()));} | |
224 | iterator | |
225 | end()BOOST_NOEXCEPT{return make_iterator(header());} | |
226 | const_iterator | |
227 | end()const BOOST_NOEXCEPT{return make_iterator(header());} | |
228 | reverse_iterator | |
229 | rbegin()BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());} | |
230 | const_reverse_iterator | |
231 | rbegin()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());} | |
232 | reverse_iterator | |
233 | rend()BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());} | |
234 | const_reverse_iterator | |
235 | rend()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());} | |
236 | const_iterator | |
237 | cbegin()const BOOST_NOEXCEPT{return begin();} | |
238 | const_iterator | |
239 | cend()const BOOST_NOEXCEPT{return end();} | |
240 | const_reverse_iterator | |
241 | crbegin()const BOOST_NOEXCEPT{return rbegin();} | |
242 | const_reverse_iterator | |
243 | crend()const BOOST_NOEXCEPT{return rend();} | |
244 | ||
245 | iterator iterator_to(const value_type& x) | |
246 | { | |
11fdf7f2 | 247 | return make_iterator(node_from_value<node_type>(boost::addressof(x))); |
7c673cae FG |
248 | } |
249 | ||
250 | const_iterator iterator_to(const value_type& x)const | |
251 | { | |
11fdf7f2 | 252 | return make_iterator(node_from_value<node_type>(boost::addressof(x))); |
7c673cae FG |
253 | } |
254 | ||
255 | /* capacity */ | |
256 | ||
257 | bool empty()const BOOST_NOEXCEPT{return this->final_empty_();} | |
258 | size_type size()const BOOST_NOEXCEPT{return this->final_size_();} | |
259 | size_type max_size()const BOOST_NOEXCEPT{return this->final_max_size_();} | |
260 | ||
261 | void resize(size_type n) | |
262 | { | |
263 | BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; | |
264 | if(n>size()){ | |
265 | for(size_type m=n-size();m--;) | |
266 | this->final_emplace_(BOOST_MULTI_INDEX_NULL_PARAM_PACK); | |
267 | } | |
268 | else if(n<size()){for(size_type m=size()-n;m--;)pop_back();} | |
269 | } | |
270 | ||
271 | void resize(size_type n,value_param_type x) | |
272 | { | |
273 | BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; | |
92f5a8d4 | 274 | if(n>size())insert(end(),static_cast<size_type>(n-size()),x); |
7c673cae FG |
275 | else if(n<size())for(size_type m=size()-n;m--;)pop_back(); |
276 | } | |
277 | ||
278 | /* access: no non-const versions provided as sequenced_index | |
279 | * handles const elements. | |
280 | */ | |
281 | ||
282 | const_reference front()const{return *begin();} | |
283 | const_reference back()const{return *--end();} | |
284 | ||
285 | /* modifiers */ | |
286 | ||
287 | BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( | |
288 | emplace_return_type,emplace_front,emplace_front_impl) | |
289 | ||
290 | std::pair<iterator,bool> push_front(const value_type& x) | |
291 | {return insert(begin(),x);} | |
292 | std::pair<iterator,bool> push_front(BOOST_RV_REF(value_type) x) | |
293 | {return insert(begin(),boost::move(x));} | |
294 | void pop_front(){erase(begin());} | |
295 | ||
296 | BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( | |
297 | emplace_return_type,emplace_back,emplace_back_impl) | |
298 | ||
299 | std::pair<iterator,bool> push_back(const value_type& x) | |
300 | {return insert(end(),x);} | |
301 | std::pair<iterator,bool> push_back(BOOST_RV_REF(value_type) x) | |
302 | {return insert(end(),boost::move(x));} | |
303 | void pop_back(){erase(--end());} | |
304 | ||
305 | BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( | |
306 | emplace_return_type,emplace,emplace_impl,iterator,position) | |
307 | ||
308 | std::pair<iterator,bool> insert(iterator position,const value_type& x) | |
309 | { | |
310 | BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); | |
311 | BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); | |
312 | BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; | |
313 | std::pair<final_node_type*,bool> p=this->final_insert_(x); | |
314 | if(p.second&&position.get_node()!=header()){ | |
315 | relink(position.get_node(),p.first); | |
316 | } | |
317 | return std::pair<iterator,bool>(make_iterator(p.first),p.second); | |
318 | } | |
319 | ||
320 | std::pair<iterator,bool> insert(iterator position,BOOST_RV_REF(value_type) x) | |
321 | { | |
322 | BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); | |
323 | BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); | |
324 | BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; | |
325 | std::pair<final_node_type*,bool> p=this->final_insert_rv_(x); | |
326 | if(p.second&&position.get_node()!=header()){ | |
327 | relink(position.get_node(),p.first); | |
328 | } | |
329 | return std::pair<iterator,bool>(make_iterator(p.first),p.second); | |
330 | } | |
331 | ||
332 | void insert(iterator position,size_type n,value_param_type x) | |
333 | { | |
334 | BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); | |
335 | BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); | |
336 | BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; | |
337 | for(size_type i=0;i<n;++i)insert(position,x); | |
338 | } | |
339 | ||
340 | template<typename InputIterator> | |
341 | void insert(iterator position,InputIterator first,InputIterator last) | |
342 | { | |
343 | insert_iter(position,first,last,mpl::not_<is_integral<InputIterator> >()); | |
344 | } | |
345 | ||
346 | #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) | |
347 | void insert(iterator position,std::initializer_list<value_type> list) | |
348 | { | |
349 | insert(position,list.begin(),list.end()); | |
350 | } | |
351 | #endif | |
352 | ||
353 | iterator erase(iterator position) | |
354 | { | |
355 | BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); | |
356 | BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); | |
357 | BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); | |
358 | BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; | |
359 | this->final_erase_(static_cast<final_node_type*>(position++.get_node())); | |
360 | return position; | |
361 | } | |
362 | ||
363 | iterator erase(iterator first,iterator last) | |
364 | { | |
365 | BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); | |
366 | BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); | |
367 | BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this); | |
368 | BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this); | |
369 | BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); | |
370 | BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; | |
371 | while(first!=last){ | |
372 | first=erase(first); | |
373 | } | |
374 | return first; | |
375 | } | |
376 | ||
377 | bool replace(iterator position,const value_type& x) | |
378 | { | |
379 | BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); | |
380 | BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); | |
381 | BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); | |
382 | BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; | |
383 | return this->final_replace_( | |
384 | x,static_cast<final_node_type*>(position.get_node())); | |
385 | } | |
386 | ||
387 | bool replace(iterator position,BOOST_RV_REF(value_type) x) | |
388 | { | |
389 | BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); | |
390 | BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); | |
391 | BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); | |
392 | BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; | |
393 | return this->final_replace_rv_( | |
394 | x,static_cast<final_node_type*>(position.get_node())); | |
395 | } | |
396 | ||
397 | template<typename Modifier> | |
398 | bool modify(iterator position,Modifier mod) | |
399 | { | |
400 | BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); | |
401 | BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); | |
402 | BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); | |
403 | BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; | |
404 | ||
405 | #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) | |
406 | /* MSVC++ 6.0 optimizer on safe mode code chokes if this | |
407 | * this is not added. Left it for all compilers as it does no | |
408 | * harm. | |
409 | */ | |
410 | ||
411 | position.detach(); | |
412 | #endif | |
413 | ||
414 | return this->final_modify_( | |
415 | mod,static_cast<final_node_type*>(position.get_node())); | |
416 | } | |
417 | ||
418 | template<typename Modifier,typename Rollback> | |
419 | bool modify(iterator position,Modifier mod,Rollback back_) | |
420 | { | |
421 | BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); | |
422 | BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); | |
423 | BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); | |
424 | BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; | |
425 | ||
426 | #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) | |
427 | /* MSVC++ 6.0 optimizer on safe mode code chokes if this | |
428 | * this is not added. Left it for all compilers as it does no | |
429 | * harm. | |
430 | */ | |
431 | ||
432 | position.detach(); | |
433 | #endif | |
434 | ||
435 | return this->final_modify_( | |
436 | mod,back_,static_cast<final_node_type*>(position.get_node())); | |
437 | } | |
438 | ||
439 | void swap(sequenced_index<SuperMeta,TagList>& x) | |
440 | { | |
441 | BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; | |
442 | BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(x); | |
443 | this->final_swap_(x.final()); | |
444 | } | |
445 | ||
446 | void clear()BOOST_NOEXCEPT | |
447 | { | |
448 | BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; | |
449 | this->final_clear_(); | |
450 | } | |
451 | ||
452 | /* list operations */ | |
453 | ||
454 | void splice(iterator position,sequenced_index<SuperMeta,TagList>& x) | |
455 | { | |
456 | BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); | |
457 | BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); | |
458 | BOOST_MULTI_INDEX_CHECK_DIFFERENT_CONTAINER(*this,x); | |
459 | BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; | |
460 | iterator first=x.begin(),last=x.end(); | |
461 | while(first!=last){ | |
462 | if(insert(position,*first).second)first=x.erase(first); | |
463 | else ++first; | |
464 | } | |
465 | } | |
466 | ||
467 | void splice(iterator position,sequenced_index<SuperMeta,TagList>& x,iterator i) | |
468 | { | |
469 | BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); | |
470 | BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); | |
471 | BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(i); | |
472 | BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i); | |
473 | BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,x); | |
474 | BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; | |
475 | if(&x==this){ | |
476 | if(position!=i)relink(position.get_node(),i.get_node()); | |
477 | } | |
478 | else{ | |
479 | if(insert(position,*i).second){ | |
480 | ||
481 | #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) | |
482 | /* MSVC++ 6.0 optimizer has a hard time with safe mode, and the following | |
483 | * workaround is needed. Left it for all compilers as it does no | |
484 | * harm. | |
485 | */ | |
486 | i.detach(); | |
487 | x.erase(x.make_iterator(i.get_node())); | |
488 | #else | |
489 | x.erase(i); | |
490 | #endif | |
491 | ||
492 | } | |
493 | } | |
494 | } | |
495 | ||
496 | void splice( | |
497 | iterator position,sequenced_index<SuperMeta,TagList>& x, | |
498 | iterator first,iterator last) | |
499 | { | |
500 | BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); | |
501 | BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); | |
502 | BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); | |
503 | BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); | |
504 | BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,x); | |
505 | BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,x); | |
506 | BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); | |
507 | BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; | |
508 | if(&x==this){ | |
509 | BOOST_MULTI_INDEX_CHECK_OUTSIDE_RANGE(position,first,last); | |
510 | if(position!=last)relink( | |
511 | position.get_node(),first.get_node(),last.get_node()); | |
512 | } | |
513 | else{ | |
514 | while(first!=last){ | |
515 | if(insert(position,*first).second)first=x.erase(first); | |
516 | else ++first; | |
517 | } | |
518 | } | |
519 | } | |
520 | ||
521 | void remove(value_param_type value) | |
522 | { | |
523 | sequenced_index_remove( | |
524 | *this, | |
525 | ::boost::bind(std::equal_to<value_type>(),::boost::arg<1>(),value)); | |
526 | } | |
527 | ||
528 | template<typename Predicate> | |
529 | void remove_if(Predicate pred) | |
530 | { | |
531 | sequenced_index_remove(*this,pred); | |
532 | } | |
533 | ||
534 | void unique() | |
535 | { | |
536 | sequenced_index_unique(*this,std::equal_to<value_type>()); | |
537 | } | |
538 | ||
539 | template <class BinaryPredicate> | |
540 | void unique(BinaryPredicate binary_pred) | |
541 | { | |
542 | sequenced_index_unique(*this,binary_pred); | |
543 | } | |
544 | ||
545 | void merge(sequenced_index<SuperMeta,TagList>& x) | |
546 | { | |
547 | sequenced_index_merge(*this,x,std::less<value_type>()); | |
548 | } | |
549 | ||
550 | template <typename Compare> | |
551 | void merge(sequenced_index<SuperMeta,TagList>& x,Compare comp) | |
552 | { | |
553 | sequenced_index_merge(*this,x,comp); | |
554 | } | |
555 | ||
556 | void sort() | |
557 | { | |
558 | BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; | |
559 | sequenced_index_sort(header(),std::less<value_type>()); | |
560 | } | |
561 | ||
562 | template <typename Compare> | |
563 | void sort(Compare comp) | |
564 | { | |
565 | BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; | |
566 | sequenced_index_sort(header(),comp); | |
567 | } | |
568 | ||
569 | void reverse()BOOST_NOEXCEPT | |
570 | { | |
571 | BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; | |
572 | node_impl_type::reverse(header()->impl()); | |
573 | } | |
574 | ||
575 | /* rearrange operations */ | |
576 | ||
577 | void relocate(iterator position,iterator i) | |
578 | { | |
579 | BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); | |
580 | BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); | |
581 | BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(i); | |
582 | BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i); | |
583 | BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,*this); | |
584 | BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; | |
585 | if(position!=i)relink(position.get_node(),i.get_node()); | |
586 | } | |
587 | ||
588 | void relocate(iterator position,iterator first,iterator last) | |
589 | { | |
590 | BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); | |
591 | BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); | |
592 | BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); | |
593 | BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); | |
594 | BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this); | |
595 | BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this); | |
596 | BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); | |
597 | BOOST_MULTI_INDEX_CHECK_OUTSIDE_RANGE(position,first,last); | |
598 | BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; | |
599 | if(position!=last)relink( | |
600 | position.get_node(),first.get_node(),last.get_node()); | |
601 | } | |
602 | ||
603 | template<typename InputIterator> | |
604 | void rearrange(InputIterator first) | |
605 | { | |
606 | BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; | |
607 | node_type* pos=header(); | |
608 | for(size_type s=size();s--;){ | |
609 | const value_type& v=*first++; | |
610 | relink(pos,node_from_value<node_type>(&v)); | |
611 | } | |
612 | } | |
613 | ||
614 | BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: | |
615 | sequenced_index(const ctor_args_list& args_list,const allocator_type& al): | |
616 | super(args_list.get_tail(),al) | |
617 | { | |
618 | empty_initialize(); | |
619 | } | |
620 | ||
621 | sequenced_index(const sequenced_index<SuperMeta,TagList>& x): | |
622 | super(x) | |
623 | ||
624 | #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) | |
625 | ,safe_super() | |
626 | #endif | |
627 | ||
628 | { | |
629 | /* the actual copying takes place in subsequent call to copy_() */ | |
630 | } | |
631 | ||
632 | sequenced_index( | |
633 | const sequenced_index<SuperMeta,TagList>& x,do_not_copy_elements_tag): | |
634 | super(x,do_not_copy_elements_tag()) | |
635 | ||
636 | #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) | |
637 | ,safe_super() | |
638 | #endif | |
639 | ||
640 | { | |
641 | empty_initialize(); | |
642 | } | |
643 | ||
644 | ~sequenced_index() | |
645 | { | |
646 | /* the container is guaranteed to be empty by now */ | |
647 | } | |
648 | ||
649 | #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) | |
650 | iterator make_iterator(node_type* node){return iterator(node,this);} | |
651 | const_iterator make_iterator(node_type* node)const | |
652 | {return const_iterator(node,const_cast<sequenced_index*>(this));} | |
653 | #else | |
654 | iterator make_iterator(node_type* node){return iterator(node);} | |
655 | const_iterator make_iterator(node_type* node)const | |
656 | {return const_iterator(node);} | |
657 | #endif | |
658 | ||
659 | void copy_( | |
660 | const sequenced_index<SuperMeta,TagList>& x,const copy_map_type& map) | |
661 | { | |
662 | node_type* org=x.header(); | |
663 | node_type* cpy=header(); | |
664 | do{ | |
665 | node_type* next_org=node_type::from_impl(org->next()); | |
666 | node_type* next_cpy=map.find(static_cast<final_node_type*>(next_org)); | |
667 | cpy->next()=next_cpy->impl(); | |
668 | next_cpy->prior()=cpy->impl(); | |
669 | org=next_org; | |
670 | cpy=next_cpy; | |
671 | }while(org!=x.header()); | |
672 | ||
673 | super::copy_(x,map); | |
674 | } | |
675 | ||
676 | template<typename Variant> | |
677 | final_node_type* insert_( | |
678 | value_param_type v,final_node_type*& x,Variant variant) | |
679 | { | |
680 | final_node_type* res=super::insert_(v,x,variant); | |
681 | if(res==x)link(static_cast<node_type*>(x)); | |
682 | return res; | |
683 | } | |
684 | ||
685 | template<typename Variant> | |
686 | final_node_type* insert_( | |
687 | value_param_type v,node_type* position,final_node_type*& x,Variant variant) | |
688 | { | |
689 | final_node_type* res=super::insert_(v,position,x,variant); | |
690 | if(res==x)link(static_cast<node_type*>(x)); | |
691 | return res; | |
692 | } | |
693 | ||
694 | void erase_(node_type* x) | |
695 | { | |
696 | unlink(x); | |
697 | super::erase_(x); | |
698 | ||
699 | #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) | |
700 | detach_iterators(x); | |
701 | #endif | |
702 | } | |
703 | ||
704 | void delete_all_nodes_() | |
705 | { | |
706 | for(node_type* x=node_type::from_impl(header()->next());x!=header();){ | |
707 | node_type* y=node_type::from_impl(x->next()); | |
708 | this->final_delete_node_(static_cast<final_node_type*>(x)); | |
709 | x=y; | |
710 | } | |
711 | } | |
712 | ||
713 | void clear_() | |
714 | { | |
715 | super::clear_(); | |
716 | empty_initialize(); | |
717 | ||
718 | #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) | |
719 | safe_super::detach_dereferenceable_iterators(); | |
720 | #endif | |
721 | } | |
722 | ||
723 | void swap_(sequenced_index<SuperMeta,TagList>& x) | |
724 | { | |
725 | #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) | |
726 | safe_super::swap(x); | |
727 | #endif | |
728 | ||
729 | super::swap_(x); | |
730 | } | |
731 | ||
732 | void swap_elements_(sequenced_index<SuperMeta,TagList>& x) | |
733 | { | |
734 | #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) | |
735 | safe_super::swap(x); | |
736 | #endif | |
737 | ||
738 | super::swap_elements_(x); | |
739 | } | |
740 | ||
741 | template<typename Variant> | |
742 | bool replace_(value_param_type v,node_type* x,Variant variant) | |
743 | { | |
744 | return super::replace_(v,x,variant); | |
745 | } | |
746 | ||
747 | bool modify_(node_type* x) | |
748 | { | |
749 | BOOST_TRY{ | |
750 | if(!super::modify_(x)){ | |
751 | unlink(x); | |
752 | ||
753 | #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) | |
754 | detach_iterators(x); | |
755 | #endif | |
756 | ||
757 | return false; | |
758 | } | |
759 | else return true; | |
760 | } | |
761 | BOOST_CATCH(...){ | |
762 | unlink(x); | |
763 | ||
764 | #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) | |
765 | detach_iterators(x); | |
766 | #endif | |
767 | ||
768 | BOOST_RETHROW; | |
769 | } | |
770 | BOOST_CATCH_END | |
771 | } | |
772 | ||
773 | bool modify_rollback_(node_type* x) | |
774 | { | |
775 | return super::modify_rollback_(x); | |
776 | } | |
777 | ||
b32b8144 FG |
778 | bool check_rollback_(node_type* x)const |
779 | { | |
780 | return super::check_rollback_(x); | |
781 | } | |
782 | ||
7c673cae FG |
783 | #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) |
784 | /* serialization */ | |
785 | ||
786 | template<typename Archive> | |
787 | void save_( | |
788 | Archive& ar,const unsigned int version,const index_saver_type& sm)const | |
789 | { | |
790 | sm.save(begin(),end(),ar,version); | |
791 | super::save_(ar,version,sm); | |
792 | } | |
793 | ||
794 | template<typename Archive> | |
795 | void load_( | |
796 | Archive& ar,const unsigned int version,const index_loader_type& lm) | |
797 | { | |
798 | lm.load( | |
799 | ::boost::bind( | |
800 | &sequenced_index::rearranger,this,::boost::arg<1>(),::boost::arg<2>()), | |
801 | ar,version); | |
802 | super::load_(ar,version,lm); | |
803 | } | |
804 | #endif | |
805 | ||
806 | #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) | |
807 | /* invariant stuff */ | |
808 | ||
809 | bool invariant_()const | |
810 | { | |
811 | if(size()==0||begin()==end()){ | |
812 | if(size()!=0||begin()!=end()|| | |
813 | header()->next()!=header()->impl()|| | |
814 | header()->prior()!=header()->impl())return false; | |
815 | } | |
816 | else{ | |
817 | size_type s=0; | |
818 | for(const_iterator it=begin(),it_end=end();it!=it_end;++it,++s){ | |
819 | if(it.get_node()->next()->prior()!=it.get_node()->impl())return false; | |
820 | if(it.get_node()->prior()->next()!=it.get_node()->impl())return false; | |
821 | } | |
822 | if(s!=size())return false; | |
823 | } | |
824 | ||
825 | return super::invariant_(); | |
826 | } | |
827 | ||
828 | /* This forwarding function eases things for the boost::mem_fn construct | |
829 | * in BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT. Actually, | |
830 | * final_check_invariant is already an inherited member function of index. | |
831 | */ | |
832 | void check_invariant_()const{this->final_check_invariant_();} | |
833 | #endif | |
834 | ||
835 | private: | |
836 | node_type* header()const{return this->final_header();} | |
837 | ||
838 | void empty_initialize() | |
839 | { | |
840 | header()->prior()=header()->next()=header()->impl(); | |
841 | } | |
842 | ||
843 | void link(node_type* x) | |
844 | { | |
845 | node_impl_type::link(x->impl(),header()->impl()); | |
92f5a8d4 | 846 | } |
7c673cae FG |
847 | |
848 | static void unlink(node_type* x) | |
849 | { | |
850 | node_impl_type::unlink(x->impl()); | |
851 | } | |
852 | ||
853 | static void relink(node_type* position,node_type* x) | |
854 | { | |
855 | node_impl_type::relink(position->impl(),x->impl()); | |
856 | } | |
857 | ||
858 | static void relink(node_type* position,node_type* first,node_type* last) | |
859 | { | |
860 | node_impl_type::relink( | |
861 | position->impl(),first->impl(),last->impl()); | |
862 | } | |
863 | ||
864 | #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) | |
865 | void rearranger(node_type* position,node_type *x) | |
866 | { | |
867 | if(!position)position=header(); | |
868 | node_type::increment(position); | |
869 | if(position!=x)relink(position,x); | |
870 | } | |
871 | #endif | |
872 | ||
873 | #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) | |
874 | void detach_iterators(node_type* x) | |
875 | { | |
876 | iterator it=make_iterator(x); | |
877 | safe_mode::detach_equivalent_iterators(it); | |
878 | } | |
879 | #endif | |
880 | ||
881 | template <class InputIterator> | |
882 | void assign_iter(InputIterator first,InputIterator last,mpl::true_) | |
883 | { | |
884 | BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; | |
885 | clear(); | |
886 | for(;first!=last;++first)this->final_insert_ref_(*first); | |
887 | } | |
888 | ||
889 | void assign_iter(size_type n,value_param_type value,mpl::false_) | |
890 | { | |
891 | BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; | |
892 | clear(); | |
893 | for(size_type i=0;i<n;++i)push_back(value); | |
894 | } | |
895 | ||
896 | template<typename InputIterator> | |
897 | void insert_iter( | |
898 | iterator position,InputIterator first,InputIterator last,mpl::true_) | |
899 | { | |
900 | BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; | |
901 | for(;first!=last;++first){ | |
902 | std::pair<final_node_type*,bool> p= | |
903 | this->final_insert_ref_(*first); | |
904 | if(p.second&&position.get_node()!=header()){ | |
905 | relink(position.get_node(),p.first); | |
906 | } | |
907 | } | |
908 | } | |
909 | ||
910 | void insert_iter( | |
911 | iterator position,size_type n,value_param_type x,mpl::false_) | |
912 | { | |
913 | BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); | |
914 | BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); | |
915 | BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; | |
916 | for(size_type i=0;i<n;++i)insert(position,x); | |
917 | } | |
918 | ||
919 | template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK> | |
920 | std::pair<iterator,bool> emplace_front_impl( | |
921 | BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) | |
922 | { | |
923 | return emplace_impl(begin(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); | |
924 | } | |
925 | ||
926 | template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK> | |
927 | std::pair<iterator,bool> emplace_back_impl( | |
928 | BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) | |
929 | { | |
930 | return emplace_impl(end(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); | |
931 | } | |
932 | ||
933 | template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK> | |
934 | std::pair<iterator,bool> emplace_impl( | |
935 | iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) | |
936 | { | |
937 | BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); | |
938 | BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); | |
939 | BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; | |
940 | std::pair<final_node_type*,bool> p= | |
941 | this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); | |
942 | if(p.second&&position.get_node()!=header()){ | |
943 | relink(position.get_node(),p.first); | |
944 | } | |
945 | return std::pair<iterator,bool>(make_iterator(p.first),p.second); | |
946 | } | |
947 | ||
948 | #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ | |
949 | BOOST_WORKAROUND(__MWERKS__,<=0x3003) | |
950 | #pragma parse_mfunc_templ reset | |
951 | #endif | |
952 | }; | |
953 | ||
954 | /* comparison */ | |
955 | ||
956 | template< | |
957 | typename SuperMeta1,typename TagList1, | |
958 | typename SuperMeta2,typename TagList2 | |
959 | > | |
960 | bool operator==( | |
961 | const sequenced_index<SuperMeta1,TagList1>& x, | |
962 | const sequenced_index<SuperMeta2,TagList2>& y) | |
963 | { | |
964 | return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin()); | |
965 | } | |
966 | ||
967 | template< | |
968 | typename SuperMeta1,typename TagList1, | |
969 | typename SuperMeta2,typename TagList2 | |
970 | > | |
971 | bool operator<( | |
972 | const sequenced_index<SuperMeta1,TagList1>& x, | |
973 | const sequenced_index<SuperMeta2,TagList2>& y) | |
974 | { | |
975 | return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end()); | |
976 | } | |
977 | ||
978 | template< | |
979 | typename SuperMeta1,typename TagList1, | |
980 | typename SuperMeta2,typename TagList2 | |
981 | > | |
982 | bool operator!=( | |
983 | const sequenced_index<SuperMeta1,TagList1>& x, | |
984 | const sequenced_index<SuperMeta2,TagList2>& y) | |
985 | { | |
986 | return !(x==y); | |
987 | } | |
988 | ||
989 | template< | |
990 | typename SuperMeta1,typename TagList1, | |
991 | typename SuperMeta2,typename TagList2 | |
992 | > | |
993 | bool operator>( | |
994 | const sequenced_index<SuperMeta1,TagList1>& x, | |
995 | const sequenced_index<SuperMeta2,TagList2>& y) | |
996 | { | |
997 | return y<x; | |
998 | } | |
999 | ||
1000 | template< | |
1001 | typename SuperMeta1,typename TagList1, | |
1002 | typename SuperMeta2,typename TagList2 | |
1003 | > | |
1004 | bool operator>=( | |
1005 | const sequenced_index<SuperMeta1,TagList1>& x, | |
1006 | const sequenced_index<SuperMeta2,TagList2>& y) | |
1007 | { | |
1008 | return !(x<y); | |
1009 | } | |
1010 | ||
1011 | template< | |
1012 | typename SuperMeta1,typename TagList1, | |
1013 | typename SuperMeta2,typename TagList2 | |
1014 | > | |
1015 | bool operator<=( | |
1016 | const sequenced_index<SuperMeta1,TagList1>& x, | |
1017 | const sequenced_index<SuperMeta2,TagList2>& y) | |
1018 | { | |
1019 | return !(x>y); | |
1020 | } | |
1021 | ||
1022 | /* specialized algorithms */ | |
1023 | ||
1024 | template<typename SuperMeta,typename TagList> | |
1025 | void swap( | |
1026 | sequenced_index<SuperMeta,TagList>& x, | |
1027 | sequenced_index<SuperMeta,TagList>& y) | |
1028 | { | |
1029 | x.swap(y); | |
1030 | } | |
1031 | ||
1032 | } /* namespace multi_index::detail */ | |
1033 | ||
1034 | /* sequenced index specifier */ | |
1035 | ||
1036 | template <typename TagList> | |
1037 | struct sequenced | |
1038 | { | |
1039 | BOOST_STATIC_ASSERT(detail::is_tag<TagList>::value); | |
1040 | ||
1041 | template<typename Super> | |
1042 | struct node_class | |
1043 | { | |
1044 | typedef detail::sequenced_index_node<Super> type; | |
1045 | }; | |
1046 | ||
1047 | template<typename SuperMeta> | |
1048 | struct index_class | |
1049 | { | |
1050 | typedef detail::sequenced_index<SuperMeta,typename TagList::type> type; | |
1051 | }; | |
1052 | }; | |
1053 | ||
1054 | } /* namespace multi_index */ | |
1055 | ||
1056 | } /* namespace boost */ | |
1057 | ||
1058 | /* Boost.Foreach compatibility */ | |
1059 | ||
1060 | template<typename SuperMeta,typename TagList> | |
1061 | inline boost::mpl::true_* boost_foreach_is_noncopyable( | |
1062 | boost::multi_index::detail::sequenced_index<SuperMeta,TagList>*&, | |
1063 | boost_foreach_argument_dependent_lookup_hack) | |
1064 | { | |
1065 | return 0; | |
1066 | } | |
1067 | ||
1068 | #undef BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT | |
1069 | #undef BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF | |
1070 | ||
1071 | #endif |