annotate DEPENDENCIES/generic/include/boost/multi_index/detail/seq_index_ops.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents c530137014c0
children
rev   line source
Chris@101 1 /* Copyright 2003-2013 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_SEQ_INDEX_OPS_HPP
Chris@16 10 #define BOOST_MULTI_INDEX_DETAIL_SEQ_INDEX_OPS_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/no_exceptions_support.hpp>
Chris@16 18 #include <boost/multi_index/detail/seq_index_node.hpp>
Chris@16 19 #include <boost/limits.hpp>
Chris@16 20 #include <boost/type_traits/aligned_storage.hpp>
Chris@16 21 #include <boost/type_traits/alignment_of.hpp>
Chris@16 22 #include <cstddef>
Chris@16 23
Chris@16 24 namespace boost{
Chris@16 25
Chris@16 26 namespace multi_index{
Chris@16 27
Chris@16 28 namespace detail{
Chris@16 29
Chris@16 30 /* Common code for sequenced_index memfuns having templatized and
Chris@16 31 * non-templatized versions.
Chris@16 32 */
Chris@16 33
Chris@16 34 template <typename SequencedIndex,typename Predicate>
Chris@16 35 void sequenced_index_remove(SequencedIndex& x,Predicate pred)
Chris@16 36 {
Chris@16 37 typedef typename SequencedIndex::iterator iterator;
Chris@16 38 iterator first=x.begin(),last=x.end();
Chris@16 39 while(first!=last){
Chris@16 40 if(pred(*first))x.erase(first++);
Chris@16 41 else ++first;
Chris@16 42 }
Chris@16 43 }
Chris@16 44
Chris@16 45 template <typename SequencedIndex,class BinaryPredicate>
Chris@16 46 void sequenced_index_unique(SequencedIndex& x,BinaryPredicate binary_pred)
Chris@16 47 {
Chris@16 48 typedef typename SequencedIndex::iterator iterator;
Chris@16 49 iterator first=x.begin();
Chris@16 50 iterator last=x.end();
Chris@16 51 if(first!=last){
Chris@16 52 for(iterator middle=first;++middle!=last;middle=first){
Chris@16 53 if(binary_pred(*middle,*first))x.erase(middle);
Chris@16 54 else first=middle;
Chris@16 55 }
Chris@16 56 }
Chris@16 57 }
Chris@16 58
Chris@16 59 template <typename SequencedIndex,typename Compare>
Chris@16 60 void sequenced_index_merge(SequencedIndex& x,SequencedIndex& y,Compare comp)
Chris@16 61 {
Chris@16 62 typedef typename SequencedIndex::iterator iterator;
Chris@16 63 if(&x!=&y){
Chris@16 64 iterator first0=x.begin(),last0=x.end();
Chris@16 65 iterator first1=y.begin(),last1=y.end();
Chris@16 66 while(first0!=last0&&first1!=last1){
Chris@16 67 if(comp(*first1,*first0))x.splice(first0,y,first1++);
Chris@16 68 else ++first0;
Chris@16 69 }
Chris@16 70 x.splice(last0,y,first1,last1);
Chris@16 71 }
Chris@16 72 }
Chris@16 73
Chris@16 74 /* sorting */
Chris@16 75
Chris@16 76 /* auxiliary stuff */
Chris@16 77
Chris@16 78 template<typename Node,typename Compare>
Chris@16 79 void sequenced_index_collate(
Chris@16 80 BOOST_DEDUCED_TYPENAME Node::impl_type* x,
Chris@16 81 BOOST_DEDUCED_TYPENAME Node::impl_type* y,
Chris@101 82 Compare comp)
Chris@16 83 {
Chris@16 84 typedef typename Node::impl_type impl_type;
Chris@16 85 typedef typename Node::impl_pointer impl_pointer;
Chris@16 86
Chris@16 87 impl_pointer first0=x->next();
Chris@16 88 impl_pointer last0=x;
Chris@16 89 impl_pointer first1=y->next();
Chris@16 90 impl_pointer last1=y;
Chris@16 91 while(first0!=last0&&first1!=last1){
Chris@16 92 if(comp(
Chris@16 93 Node::from_impl(first1)->value(),Node::from_impl(first0)->value())){
Chris@16 94 impl_pointer tmp=first1->next();
Chris@16 95 impl_type::relink(first0,first1);
Chris@16 96 first1=tmp;
Chris@16 97 }
Chris@16 98 else first0=first0->next();
Chris@16 99 }
Chris@16 100 impl_type::relink(last0,first1,last1);
Chris@16 101 }
Chris@16 102
Chris@16 103 /* Some versions of CGG require a bogus typename in counter_spc
Chris@16 104 * inside sequenced_index_sort if the following is defined
Chris@16 105 * also inside sequenced_index_sort.
Chris@16 106 */
Chris@16 107
Chris@16 108 BOOST_STATIC_CONSTANT(
Chris@16 109 std::size_t,
Chris@16 110 sequenced_index_sort_max_fill=
Chris@16 111 (std::size_t)std::numeric_limits<std::size_t>::digits+1);
Chris@16 112
Chris@16 113 template<typename Node,typename Compare>
Chris@16 114 void sequenced_index_sort(Node* header,Compare comp)
Chris@16 115 {
Chris@16 116 /* Musser's mergesort, see http://www.cs.rpi.edu/~musser/gp/List/lists1.html.
Chris@16 117 * The implementation is a little convoluted: in the original code
Chris@16 118 * counter elements and carry are std::lists: here we do not want
Chris@16 119 * to use multi_index instead, so we do things at a lower level, managing
Chris@16 120 * directly the internal node representation.
Chris@16 121 * Incidentally, the implementations I've seen of this algorithm (SGI,
Chris@16 122 * Dinkumware, STLPort) are not exception-safe: this is. Moreover, we do not
Chris@16 123 * use any dynamic storage.
Chris@16 124 */
Chris@16 125
Chris@16 126 if(header->next()==header->impl()||
Chris@16 127 header->next()->next()==header->impl())return;
Chris@16 128
Chris@16 129 typedef typename Node::impl_type impl_type;
Chris@16 130 typedef typename Node::impl_pointer impl_pointer;
Chris@16 131
Chris@16 132 typedef typename aligned_storage<
Chris@16 133 sizeof(impl_type),
Chris@16 134 alignment_of<impl_type>::value
Chris@16 135 >::type carry_spc_type;
Chris@16 136 carry_spc_type carry_spc;
Chris@16 137 impl_type& carry=
Chris@16 138 *static_cast<impl_type*>(static_cast<void*>(&carry_spc));
Chris@16 139 typedef typename aligned_storage<
Chris@16 140 sizeof(
Chris@16 141 impl_type
Chris@16 142 [sequenced_index_sort_max_fill]),
Chris@16 143 alignment_of<
Chris@16 144 impl_type
Chris@16 145 [sequenced_index_sort_max_fill]
Chris@16 146 >::value
Chris@16 147 >::type counter_spc_type;
Chris@16 148 counter_spc_type counter_spc;
Chris@16 149 impl_type* counter=
Chris@16 150 static_cast<impl_type*>(static_cast<void*>(&counter_spc));
Chris@16 151 std::size_t fill=0;
Chris@16 152
Chris@16 153 carry.prior()=carry.next()=static_cast<impl_pointer>(&carry);
Chris@16 154 counter[0].prior()=counter[0].next()=static_cast<impl_pointer>(&counter[0]);
Chris@16 155
Chris@16 156 BOOST_TRY{
Chris@16 157 while(header->next()!=header->impl()){
Chris@16 158 impl_type::relink(carry.next(),header->next());
Chris@16 159 std::size_t i=0;
Chris@16 160 while(i<fill&&counter[i].next()!=static_cast<impl_pointer>(&counter[i])){
Chris@16 161 sequenced_index_collate<Node>(&carry,&counter[i++],comp);
Chris@16 162 }
Chris@16 163 impl_type::swap(
Chris@16 164 static_cast<impl_pointer>(&carry),
Chris@16 165 static_cast<impl_pointer>(&counter[i]));
Chris@16 166 if(i==fill){
Chris@16 167 ++fill;
Chris@16 168 counter[fill].prior()=counter[fill].next()=
Chris@16 169 static_cast<impl_pointer>(&counter[fill]);
Chris@16 170 }
Chris@16 171 }
Chris@16 172
Chris@16 173 for(std::size_t i=1;i<fill;++i){
Chris@16 174 sequenced_index_collate<Node>(&counter[i],&counter[i-1],comp);
Chris@16 175 }
Chris@16 176 impl_type::swap(
Chris@16 177 header->impl(),static_cast<impl_pointer>(&counter[fill-1]));
Chris@16 178 }
Chris@16 179 BOOST_CATCH(...)
Chris@16 180 {
Chris@16 181 impl_type::relink(
Chris@16 182 header->impl(),carry.next(),static_cast<impl_pointer>(&carry));
Chris@16 183 for(std::size_t i=0;i<=fill;++i){
Chris@16 184 impl_type::relink(
Chris@16 185 header->impl(),counter[i].next(),
Chris@16 186 static_cast<impl_pointer>(&counter[i]));
Chris@16 187 }
Chris@16 188 BOOST_RETHROW;
Chris@16 189 }
Chris@16 190 BOOST_CATCH_END
Chris@16 191 }
Chris@16 192
Chris@16 193 } /* namespace multi_index::detail */
Chris@16 194
Chris@16 195 } /* namespace multi_index */
Chris@16 196
Chris@16 197 } /* namespace boost */
Chris@16 198
Chris@16 199 #endif