annotate DEPENDENCIES/generic/include/boost/multi_index/detail/rnd_index_node.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-2015 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_RND_INDEX_NODE_HPP
Chris@16 10 #define BOOST_MULTI_INDEX_DETAIL_RND_INDEX_NODE_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 <algorithm>
Chris@16 18 #include <boost/detail/allocator_utilities.hpp>
Chris@101 19 #include <boost/integer/common_factor_rt.hpp>
Chris@16 20 #include <cstddef>
Chris@16 21 #include <functional>
Chris@16 22
Chris@16 23 namespace boost{
Chris@16 24
Chris@16 25 namespace multi_index{
Chris@16 26
Chris@16 27 namespace detail{
Chris@16 28
Chris@16 29 template<typename Allocator>
Chris@16 30 struct random_access_index_node_impl
Chris@16 31 {
Chris@101 32 typedef typename
Chris@101 33 boost::detail::allocator::rebind_to<
Chris@101 34 Allocator,random_access_index_node_impl
Chris@101 35 >::type::pointer pointer;
Chris@101 36 typedef typename
Chris@101 37 boost::detail::allocator::rebind_to<
Chris@101 38 Allocator,random_access_index_node_impl
Chris@101 39 >::type::const_pointer const_pointer;
Chris@101 40 typedef typename
Chris@101 41 boost::detail::allocator::rebind_to<
Chris@101 42 Allocator,pointer
Chris@101 43 >::type::pointer ptr_pointer;
Chris@16 44
Chris@16 45 ptr_pointer& up(){return up_;}
Chris@16 46 ptr_pointer up()const{return up_;}
Chris@16 47
Chris@16 48 /* interoperability with rnd_node_iterator */
Chris@16 49
Chris@16 50 static void increment(pointer& x)
Chris@16 51 {
Chris@16 52 x=*(x->up()+1);
Chris@16 53 }
Chris@16 54
Chris@16 55 static void decrement(pointer& x)
Chris@16 56 {
Chris@16 57 x=*(x->up()-1);
Chris@16 58 }
Chris@16 59
Chris@16 60 static void advance(pointer& x,std::ptrdiff_t n)
Chris@16 61 {
Chris@16 62 x=*(x->up()+n);
Chris@16 63 }
Chris@16 64
Chris@16 65 static std::ptrdiff_t distance(pointer x,pointer y)
Chris@16 66 {
Chris@16 67 return y->up()-x->up();
Chris@16 68 }
Chris@16 69
Chris@16 70 /* algorithmic stuff */
Chris@16 71
Chris@16 72 static void relocate(ptr_pointer pos,ptr_pointer x)
Chris@16 73 {
Chris@16 74 pointer n=*x;
Chris@16 75 if(x<pos){
Chris@16 76 extract(x,pos);
Chris@16 77 *(pos-1)=n;
Chris@16 78 n->up()=pos-1;
Chris@16 79 }
Chris@16 80 else{
Chris@16 81 while(x!=pos){
Chris@16 82 *x=*(x-1);
Chris@16 83 (*x)->up()=x;
Chris@16 84 --x;
Chris@16 85 }
Chris@16 86 *pos=n;
Chris@16 87 n->up()=pos;
Chris@16 88 }
Chris@16 89 };
Chris@16 90
Chris@16 91 static void relocate(ptr_pointer pos,ptr_pointer first,ptr_pointer last)
Chris@16 92 {
Chris@16 93 ptr_pointer begin,middle,end;
Chris@16 94 if(pos<first){
Chris@16 95 begin=pos;
Chris@16 96 middle=first;
Chris@16 97 end=last;
Chris@16 98 }
Chris@16 99 else{
Chris@16 100 begin=first;
Chris@16 101 middle=last;
Chris@16 102 end=pos;
Chris@16 103 }
Chris@16 104
Chris@16 105 std::ptrdiff_t n=end-begin;
Chris@16 106 std::ptrdiff_t m=middle-begin;
Chris@16 107 std::ptrdiff_t n_m=n-m;
Chris@101 108 std::ptrdiff_t p=integer::gcd(n,m);
Chris@16 109
Chris@16 110 for(std::ptrdiff_t i=0;i<p;++i){
Chris@16 111 pointer tmp=begin[i];
Chris@16 112 for(std::ptrdiff_t j=i,k;;){
Chris@16 113 if(j<n_m)k=j+m;
Chris@16 114 else k=j-n_m;
Chris@16 115 if(k==i){
Chris@16 116 *(begin+j)=tmp;
Chris@16 117 (*(begin+j))->up()=begin+j;
Chris@16 118 break;
Chris@16 119 }
Chris@16 120 else{
Chris@16 121 *(begin+j)=*(begin+k);
Chris@16 122 (*(begin+j))->up()=begin+j;
Chris@16 123 }
Chris@16 124
Chris@16 125 if(k<n_m)j=k+m;
Chris@16 126 else j=k-n_m;
Chris@16 127 if(j==i){
Chris@16 128 *(begin+k)=tmp;
Chris@16 129 (*(begin+k))->up()=begin+k;
Chris@16 130 break;
Chris@16 131 }
Chris@16 132 else{
Chris@16 133 *(begin+k)=*(begin+j);
Chris@16 134 (*(begin+k))->up()=begin+k;
Chris@16 135 }
Chris@16 136 }
Chris@16 137 }
Chris@16 138 };
Chris@16 139
Chris@16 140 static void extract(ptr_pointer x,ptr_pointer pend)
Chris@16 141 {
Chris@16 142 --pend;
Chris@16 143 while(x!=pend){
Chris@16 144 *x=*(x+1);
Chris@16 145 (*x)->up()=x;
Chris@16 146 ++x;
Chris@16 147 }
Chris@16 148 }
Chris@16 149
Chris@16 150 static void transfer(
Chris@16 151 ptr_pointer pbegin0,ptr_pointer pend0,ptr_pointer pbegin1)
Chris@16 152 {
Chris@16 153 while(pbegin0!=pend0){
Chris@16 154 *pbegin1=*pbegin0++;
Chris@16 155 (*pbegin1)->up()=pbegin1;
Chris@16 156 ++pbegin1;
Chris@16 157 }
Chris@16 158 }
Chris@16 159
Chris@16 160 static void reverse(ptr_pointer pbegin,ptr_pointer pend)
Chris@16 161 {
Chris@16 162 std::ptrdiff_t d=(pend-pbegin)/2;
Chris@16 163 for(std::ptrdiff_t i=0;i<d;++i){
Chris@16 164 std::swap(*pbegin,*--pend);
Chris@16 165 (*pbegin)->up()=pbegin;
Chris@16 166 (*pend)->up()=pend;
Chris@16 167 ++pbegin;
Chris@16 168 }
Chris@16 169 }
Chris@16 170
Chris@16 171 private:
Chris@16 172 ptr_pointer up_;
Chris@16 173 };
Chris@16 174
Chris@16 175 template<typename Super>
Chris@16 176 struct random_access_index_node_trampoline:
Chris@101 177 random_access_index_node_impl<
Chris@101 178 typename boost::detail::allocator::rebind_to<
Chris@101 179 typename Super::allocator_type,
Chris@101 180 char
Chris@101 181 >::type
Chris@101 182 >
Chris@16 183 {
Chris@101 184 typedef random_access_index_node_impl<
Chris@101 185 typename boost::detail::allocator::rebind_to<
Chris@101 186 typename Super::allocator_type,
Chris@101 187 char
Chris@101 188 >::type
Chris@101 189 > impl_type;
Chris@16 190 };
Chris@16 191
Chris@16 192 template<typename Super>
Chris@16 193 struct random_access_index_node:
Chris@16 194 Super,random_access_index_node_trampoline<Super>
Chris@16 195 {
Chris@16 196 private:
Chris@16 197 typedef random_access_index_node_trampoline<Super> trampoline;
Chris@16 198
Chris@16 199 public:
Chris@16 200 typedef typename trampoline::impl_type impl_type;
Chris@16 201 typedef typename trampoline::pointer impl_pointer;
Chris@16 202 typedef typename trampoline::const_pointer const_impl_pointer;
Chris@16 203 typedef typename trampoline::ptr_pointer impl_ptr_pointer;
Chris@16 204
Chris@16 205 impl_ptr_pointer& up(){return trampoline::up();}
Chris@16 206 impl_ptr_pointer up()const{return trampoline::up();}
Chris@16 207
Chris@16 208 impl_pointer impl()
Chris@16 209 {
Chris@16 210 return static_cast<impl_pointer>(
Chris@16 211 static_cast<impl_type*>(static_cast<trampoline*>(this)));
Chris@16 212 }
Chris@16 213
Chris@16 214 const_impl_pointer impl()const
Chris@16 215 {
Chris@16 216 return static_cast<const_impl_pointer>(
Chris@16 217 static_cast<const impl_type*>(static_cast<const trampoline*>(this)));
Chris@16 218 }
Chris@16 219
Chris@16 220 static random_access_index_node* from_impl(impl_pointer x)
Chris@16 221 {
Chris@16 222 return static_cast<random_access_index_node*>(
Chris@16 223 static_cast<trampoline*>(&*x));
Chris@16 224 }
Chris@16 225
Chris@16 226 static const random_access_index_node* from_impl(const_impl_pointer x)
Chris@16 227 {
Chris@16 228 return static_cast<const random_access_index_node*>(
Chris@16 229 static_cast<const trampoline*>(&*x));
Chris@16 230 }
Chris@16 231
Chris@16 232 /* interoperability with rnd_node_iterator */
Chris@16 233
Chris@16 234 static void increment(random_access_index_node*& x)
Chris@16 235 {
Chris@16 236 impl_pointer xi=x->impl();
Chris@16 237 trampoline::increment(xi);
Chris@16 238 x=from_impl(xi);
Chris@16 239 }
Chris@16 240
Chris@16 241 static void decrement(random_access_index_node*& x)
Chris@16 242 {
Chris@16 243 impl_pointer xi=x->impl();
Chris@16 244 trampoline::decrement(xi);
Chris@16 245 x=from_impl(xi);
Chris@16 246 }
Chris@16 247
Chris@16 248 static void advance(random_access_index_node*& x,std::ptrdiff_t n)
Chris@16 249 {
Chris@16 250 impl_pointer xi=x->impl();
Chris@16 251 trampoline::advance(xi,n);
Chris@16 252 x=from_impl(xi);
Chris@16 253 }
Chris@16 254
Chris@16 255 static std::ptrdiff_t distance(
Chris@16 256 random_access_index_node* x,random_access_index_node* y)
Chris@16 257 {
Chris@16 258 return trampoline::distance(x->impl(),y->impl());
Chris@16 259 }
Chris@16 260 };
Chris@16 261
Chris@16 262 } /* namespace multi_index::detail */
Chris@16 263
Chris@16 264 } /* namespace multi_index */
Chris@16 265
Chris@16 266 } /* namespace boost */
Chris@16 267
Chris@16 268 #endif