File indexing completed on 2025-01-18 09:42:09
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_MULTI_INDEX_DETAIL_SEQ_INDEX_OPS_HPP
0010 #define BOOST_MULTI_INDEX_DETAIL_SEQ_INDEX_OPS_HPP
0011
0012 #if defined(_MSC_VER)
0013 #pragma once
0014 #endif
0015
0016 #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
0017 #include <boost/core/no_exceptions_support.hpp>
0018 #include <boost/multi_index/detail/seq_index_node.hpp>
0019 #include <boost/limits.hpp>
0020 #include <boost/type_traits/aligned_storage.hpp>
0021 #include <boost/type_traits/alignment_of.hpp>
0022 #include <cstddef>
0023
0024 namespace boost{
0025
0026 namespace multi_index{
0027
0028 namespace detail{
0029
0030
0031
0032
0033
0034 template <typename SequencedIndex,typename Predicate>
0035 void sequenced_index_remove(SequencedIndex& x,Predicate pred)
0036 {
0037 typedef typename SequencedIndex::iterator iterator;
0038 iterator first=x.begin(),last=x.end();
0039 while(first!=last){
0040 if(pred(*first))x.erase(first++);
0041 else ++first;
0042 }
0043 }
0044
0045 template <typename SequencedIndex,class BinaryPredicate>
0046 void sequenced_index_unique(SequencedIndex& x,BinaryPredicate binary_pred)
0047 {
0048 typedef typename SequencedIndex::iterator iterator;
0049 iterator first=x.begin();
0050 iterator last=x.end();
0051 if(first!=last){
0052 for(iterator middle=first;++middle!=last;middle=first){
0053 if(binary_pred(*middle,*first))x.erase(middle);
0054 else first=middle;
0055 }
0056 }
0057 }
0058
0059 template <typename SequencedIndex,typename Compare>
0060 void sequenced_index_merge(SequencedIndex& x,SequencedIndex& y,Compare comp)
0061 {
0062 typedef typename SequencedIndex::iterator iterator;
0063 if(&x!=&y){
0064 iterator first0=x.begin(),last0=x.end();
0065 iterator first1=y.begin(),last1=y.end();
0066 while(first0!=last0&&first1!=last1){
0067 if(comp(*first1,*first0))x.splice(first0,y,first1++);
0068 else ++first0;
0069 }
0070 x.splice(last0,y,first1,last1);
0071 }
0072 }
0073
0074
0075
0076
0077
0078 template<typename Node,typename Compare>
0079 void sequenced_index_collate(
0080 BOOST_DEDUCED_TYPENAME Node::impl_type* x,
0081 BOOST_DEDUCED_TYPENAME Node::impl_type* y,
0082 Compare comp)
0083 {
0084 typedef typename Node::impl_type impl_type;
0085 typedef typename Node::impl_pointer impl_pointer;
0086
0087 impl_pointer first0=x->next();
0088 impl_pointer last0=x;
0089 impl_pointer first1=y->next();
0090 impl_pointer last1=y;
0091 while(first0!=last0&&first1!=last1){
0092 if(comp(
0093 Node::from_impl(first1)->value(),Node::from_impl(first0)->value())){
0094 impl_pointer tmp=first1->next();
0095 impl_type::relink(first0,first1);
0096 first1=tmp;
0097 }
0098 else first0=first0->next();
0099 }
0100 impl_type::relink(last0,first1,last1);
0101 }
0102
0103
0104
0105
0106
0107
0108 BOOST_STATIC_CONSTANT(
0109 std::size_t,
0110 sequenced_index_sort_max_fill=
0111 (std::size_t)std::numeric_limits<std::size_t>::digits+1);
0112
0113 #include <boost/multi_index/detail/ignore_wstrict_aliasing.hpp>
0114
0115 template<typename Node,typename Compare>
0116 void sequenced_index_sort(Node* header,Compare comp)
0117 {
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128 if(header->next()==header->impl()||
0129 header->next()->next()==header->impl())return;
0130
0131 typedef typename Node::impl_type impl_type;
0132 typedef typename Node::impl_pointer impl_pointer;
0133
0134 typedef typename aligned_storage<
0135 sizeof(impl_type),
0136 alignment_of<impl_type>::value
0137 >::type carry_spc_type;
0138 carry_spc_type carry_spc;
0139 impl_type& carry=
0140 *reinterpret_cast<impl_type*>(&carry_spc);
0141 typedef typename aligned_storage<
0142 sizeof(
0143 impl_type
0144 [sequenced_index_sort_max_fill]),
0145 alignment_of<
0146 impl_type
0147 [sequenced_index_sort_max_fill]
0148 >::value
0149 >::type counter_spc_type;
0150 counter_spc_type counter_spc;
0151 impl_type* counter=
0152 reinterpret_cast<impl_type*>(&counter_spc);
0153 std::size_t fill=0;
0154
0155 carry.prior()=carry.next()=static_cast<impl_pointer>(&carry);
0156 counter[0].prior()=counter[0].next()=static_cast<impl_pointer>(&counter[0]);
0157
0158 BOOST_TRY{
0159 while(header->next()!=header->impl()){
0160 impl_type::relink(carry.next(),header->next());
0161 std::size_t i=0;
0162 while(i<fill&&counter[i].next()!=static_cast<impl_pointer>(&counter[i])){
0163 sequenced_index_collate<Node>(&carry,&counter[i++],comp);
0164 }
0165 impl_type::swap(
0166 static_cast<impl_pointer>(&carry),
0167 static_cast<impl_pointer>(&counter[i]));
0168 if(i==fill){
0169 ++fill;
0170 counter[fill].prior()=counter[fill].next()=
0171 static_cast<impl_pointer>(&counter[fill]);
0172 }
0173 }
0174
0175 for(std::size_t i=1;i<fill;++i){
0176 sequenced_index_collate<Node>(&counter[i],&counter[i-1],comp);
0177 }
0178 impl_type::swap(
0179 header->impl(),static_cast<impl_pointer>(&counter[fill-1]));
0180 }
0181 BOOST_CATCH(...)
0182 {
0183 impl_type::relink(
0184 header->impl(),carry.next(),static_cast<impl_pointer>(&carry));
0185 for(std::size_t i=0;i<=fill;++i){
0186 impl_type::relink(
0187 header->impl(),counter[i].next(),
0188 static_cast<impl_pointer>(&counter[i]));
0189 }
0190 BOOST_RETHROW;
0191 }
0192 BOOST_CATCH_END
0193 }
0194
0195 #include <boost/multi_index/detail/restore_wstrict_aliasing.hpp>
0196
0197 }
0198
0199 }
0200
0201 }
0202
0203 #endif