File indexing completed on 2025-01-18 09:42:07
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_MATCHER_HPP
0010 #define BOOST_MULTI_INDEX_DETAIL_INDEX_MATCHER_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/core/noncopyable.hpp>
0019 #include <boost/multi_index/detail/auto_space.hpp>
0020 #include <boost/multi_index/detail/raw_ptr.hpp>
0021 #include <cstddef>
0022 #include <functional>
0023
0024 namespace boost{
0025
0026 namespace multi_index{
0027
0028 namespace detail{
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059 namespace index_matcher{
0060
0061
0062
0063
0064
0065
0066
0067
0068 struct entry
0069 {
0070 entry(void* node_,std::size_t pos_=0):node(node_),pos(pos_){}
0071
0072
0073
0074 void* node;
0075 std::size_t pos;
0076 entry* previous;
0077 bool ordered;
0078
0079 struct less_by_node
0080 {
0081 bool operator()(
0082 const entry& x,const entry& y)const
0083 {
0084 return std::less<void*>()(x.node,y.node);
0085 }
0086 };
0087
0088
0089
0090 std::size_t pile_top;
0091 entry* pile_top_entry;
0092
0093 struct less_by_pile_top
0094 {
0095 bool operator()(
0096 const entry& x,const entry& y)const
0097 {
0098 return x.pile_top<y.pile_top;
0099 }
0100 };
0101 };
0102
0103
0104
0105 template<typename Allocator>
0106 class algorithm_base:private noncopyable
0107 {
0108 protected:
0109 algorithm_base(const Allocator& al,std::size_t size):
0110 spc(al,size),size_(size),n_(0),sorted(false)
0111 {
0112 }
0113
0114 void add(void* node)
0115 {
0116 entries()[n_]=entry(node,n_);
0117 ++n_;
0118 }
0119
0120 void begin_algorithm()const
0121 {
0122 if(!sorted){
0123 std::sort(entries(),entries()+size_,entry::less_by_node());
0124 sorted=true;
0125 }
0126 num_piles=0;
0127 }
0128
0129 void add_node_to_algorithm(void* node)const
0130 {
0131 entry* ent=
0132 std::lower_bound(
0133 entries(),entries()+size_,
0134 entry(node),entry::less_by_node());
0135 ent->ordered=false;
0136 std::size_t n=ent->pos;
0137
0138 entry dummy(0);
0139 dummy.pile_top=n;
0140
0141 entry* pile_ent=
0142 std::lower_bound(
0143 entries(),entries()+num_piles,
0144 dummy,entry::less_by_pile_top());
0145
0146 pile_ent->pile_top=n;
0147 pile_ent->pile_top_entry=ent;
0148
0149
0150 if(pile_ent>&entries()[0]){
0151 ent->previous=(pile_ent-1)->pile_top_entry;
0152 }
0153
0154 if(pile_ent==&entries()[num_piles]){
0155 ++num_piles;
0156 }
0157 }
0158
0159 void finish_algorithm()const
0160 {
0161 if(num_piles>0){
0162
0163
0164
0165
0166
0167 entry* ent=entries()[num_piles-1].pile_top_entry;
0168 for(std::size_t n=num_piles;n--;){
0169 ent->ordered=true;
0170 ent=ent->previous;
0171 }
0172 }
0173 }
0174
0175 bool is_ordered(void * node)const
0176 {
0177 return std::lower_bound(
0178 entries(),entries()+size_,
0179 entry(node),entry::less_by_node())->ordered;
0180 }
0181
0182 private:
0183 entry* entries()const{return raw_ptr<entry*>(spc.data());}
0184
0185 auto_space<entry,Allocator> spc;
0186 std::size_t size_;
0187 std::size_t n_;
0188 mutable bool sorted;
0189 mutable std::size_t num_piles;
0190 };
0191
0192
0193
0194
0195
0196
0197
0198 template<typename Node,typename Allocator>
0199 class algorithm:private algorithm_base<Allocator>
0200 {
0201 typedef algorithm_base<Allocator> super;
0202
0203 public:
0204 algorithm(const Allocator& al,std::size_t size):super(al,size){}
0205
0206 void add(Node* node)
0207 {
0208 super::add(node);
0209 }
0210
0211 template<typename IndexIterator>
0212 void execute(IndexIterator first,IndexIterator last)const
0213 {
0214 super::begin_algorithm();
0215
0216 for(IndexIterator it=first;it!=last;++it){
0217 add_node_to_algorithm(get_node(it));
0218 }
0219
0220 super::finish_algorithm();
0221 }
0222
0223 bool is_ordered(Node* node)const
0224 {
0225 return super::is_ordered(node);
0226 }
0227
0228 private:
0229 void add_node_to_algorithm(Node* node)const
0230 {
0231 super::add_node_to_algorithm(node);
0232 }
0233
0234 template<typename IndexIterator>
0235 static Node* get_node(IndexIterator it)
0236 {
0237 return static_cast<Node*>(it.get_node());
0238 }
0239 };
0240
0241 }
0242
0243 }
0244
0245 }
0246
0247 }
0248
0249 #endif