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_NODE_HPP
0010 #define BOOST_MULTI_INDEX_DETAIL_SEQ_INDEX_NODE_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 <algorithm>
0018 #include <boost/multi_index/detail/allocator_traits.hpp>
0019 #include <boost/multi_index/detail/raw_ptr.hpp>
0020
0021 namespace boost{
0022
0023 namespace multi_index{
0024
0025 namespace detail{
0026
0027
0028
0029 template<typename Allocator>
0030 struct sequenced_index_node_impl
0031 {
0032 typedef typename rebind_alloc_for<
0033 Allocator,sequenced_index_node_impl
0034 >::type node_allocator;
0035 typedef allocator_traits<node_allocator> alloc_traits;
0036 typedef typename alloc_traits::pointer pointer;
0037 typedef typename alloc_traits::const_pointer const_pointer;
0038 typedef typename alloc_traits::difference_type difference_type;
0039
0040 pointer& prior(){return prior_;}
0041 pointer prior()const{return prior_;}
0042 pointer& next(){return next_;}
0043 pointer next()const{return next_;}
0044
0045
0046
0047 static void increment(pointer& x){x=x->next();}
0048 static void decrement(pointer& x){x=x->prior();}
0049
0050
0051
0052 static void link(pointer x,pointer header)
0053 {
0054 x->prior()=header->prior();
0055 x->next()=header;
0056 x->prior()->next()=x->next()->prior()=x;
0057 }
0058
0059 static void unlink(pointer x)
0060 {
0061 x->prior()->next()=x->next();
0062 x->next()->prior()=x->prior();
0063 }
0064
0065 static void relink(pointer position,pointer x)
0066 {
0067 unlink(x);
0068 x->prior()=position->prior();
0069 x->next()=position;
0070 x->prior()->next()=x->next()->prior()=x;
0071 }
0072
0073 static void relink(pointer position,pointer x,pointer y)
0074 {
0075
0076
0077 if(x!=y){
0078 pointer z=y->prior();
0079 x->prior()->next()=y;
0080 y->prior()=x->prior();
0081 x->prior()=position->prior();
0082 z->next()=position;
0083 x->prior()->next()=x;
0084 z->next()->prior()=z;
0085 }
0086 }
0087
0088 static void reverse(pointer header)
0089 {
0090 pointer x=header;
0091 do{
0092 pointer y=x->next();
0093 std::swap(x->prior(),x->next());
0094 x=y;
0095 }while(x!=header);
0096 }
0097
0098 static void swap(pointer x,pointer y)
0099 {
0100
0101
0102
0103
0104
0105 if(x->next()!=x){
0106 if(y->next()!=y){
0107 std::swap(x->next(),y->next());
0108 std::swap(x->prior(),y->prior());
0109 x->next()->prior()=x->prior()->next()=x;
0110 y->next()->prior()=y->prior()->next()=y;
0111 }
0112 else{
0113 y->next()=x->next();
0114 y->prior()=x->prior();
0115 x->next()=x->prior()=x;
0116 y->next()->prior()=y->prior()->next()=y;
0117 }
0118 }
0119 else if(y->next()!=y){
0120 x->next()=y->next();
0121 x->prior()=y->prior();
0122 y->next()=y->prior()=y;
0123 x->next()->prior()=x->prior()->next()=x;
0124 }
0125 }
0126
0127 private:
0128 pointer prior_;
0129 pointer next_;
0130 };
0131
0132 template<typename Super>
0133 struct sequenced_index_node_trampoline:
0134 sequenced_index_node_impl<
0135 typename rebind_alloc_for<
0136 typename Super::allocator_type,
0137 char
0138 >::type
0139 >
0140 {
0141 typedef sequenced_index_node_impl<
0142 typename rebind_alloc_for<
0143 typename Super::allocator_type,
0144 char
0145 >::type
0146 > impl_type;
0147 };
0148
0149 template<typename Super>
0150 struct sequenced_index_node:Super,sequenced_index_node_trampoline<Super>
0151 {
0152 private:
0153 typedef sequenced_index_node_trampoline<Super> trampoline;
0154
0155 public:
0156 typedef typename trampoline::impl_type impl_type;
0157 typedef typename trampoline::pointer impl_pointer;
0158 typedef typename trampoline::const_pointer const_impl_pointer;
0159 typedef typename trampoline::difference_type difference_type;
0160
0161 impl_pointer& prior(){return trampoline::prior();}
0162 impl_pointer prior()const{return trampoline::prior();}
0163 impl_pointer& next(){return trampoline::next();}
0164 impl_pointer next()const{return trampoline::next();}
0165
0166 impl_pointer impl()
0167 {
0168 return static_cast<impl_pointer>(
0169 static_cast<impl_type*>(static_cast<trampoline*>(this)));
0170 }
0171
0172 const_impl_pointer impl()const
0173 {
0174 return static_cast<const_impl_pointer>(
0175 static_cast<const impl_type*>(static_cast<const trampoline*>(this)));
0176 }
0177
0178 static sequenced_index_node* from_impl(impl_pointer x)
0179 {
0180 return
0181 static_cast<sequenced_index_node*>(
0182 static_cast<trampoline*>(
0183 raw_ptr<impl_type*>(x)));
0184 }
0185
0186 static const sequenced_index_node* from_impl(const_impl_pointer x)
0187 {
0188 return
0189 static_cast<const sequenced_index_node*>(
0190 static_cast<const trampoline*>(
0191 raw_ptr<const impl_type*>(x)));
0192 }
0193
0194
0195
0196 static void increment(sequenced_index_node*& x)
0197 {
0198 impl_pointer xi=x->impl();
0199 trampoline::increment(xi);
0200 x=from_impl(xi);
0201 }
0202
0203 static void decrement(sequenced_index_node*& x)
0204 {
0205 impl_pointer xi=x->impl();
0206 trampoline::decrement(xi);
0207 x=from_impl(xi);
0208 }
0209 };
0210
0211 }
0212
0213 }
0214
0215 }
0216
0217 #endif