File indexing completed on 2025-01-18 09:42:06
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_MULTI_INDEX_DETAIL_BUCKET_ARRAY_HPP
0010 #define BOOST_MULTI_INDEX_DETAIL_BUCKET_ARRAY_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/allocator_traits.hpp>
0020 #include <boost/multi_index/detail/auto_space.hpp>
0021 #include <boost/multi_index/detail/hash_index_node.hpp>
0022 #include <boost/preprocessor/repetition/repeat.hpp>
0023 #include <boost/preprocessor/seq/elem.hpp>
0024 #include <boost/preprocessor/seq/enum.hpp>
0025 #include <boost/preprocessor/seq/size.hpp>
0026 #include <cstddef>
0027 #include <limits.h>
0028
0029 #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
0030 #include <boost/core/serialization.hpp>
0031 #include <boost/multi_index/detail/bad_archive_exception.hpp>
0032 #include <boost/throw_exception.hpp>
0033 #endif
0034
0035 namespace boost{
0036
0037 namespace multi_index{
0038
0039 namespace detail{
0040
0041
0042
0043 #define BOOST_MULTI_INDEX_BA_SIZES_32BIT \
0044 (53ul)(97ul)(193ul)(389ul)(769ul) \
0045 (1543ul)(3079ul)(6151ul)(12289ul)(24593ul) \
0046 (49157ul)(98317ul)(196613ul)(393241ul)(786433ul) \
0047 (1572869ul)(3145739ul)(6291469ul)(12582917ul)(25165843ul) \
0048 (50331653ul)(100663319ul)(201326611ul)(402653189ul)(805306457ul) \
0049 (1610612741ul)(3221225473ul)
0050
0051 #if ((((ULONG_MAX>>16)>>16)>>16)>>15)==0
0052 #define BOOST_MULTI_INDEX_BA_SIZES \
0053 BOOST_MULTI_INDEX_BA_SIZES_32BIT \
0054 (4294967291ul)
0055 #else
0056
0057
0058
0059
0060
0061
0062
0063 #define BOOST_MULTI_INDEX_BA_SIZES \
0064 BOOST_MULTI_INDEX_BA_SIZES_32BIT \
0065 (6442450939ul)(12884901893ul)(25769803751ul)(51539607551ul) \
0066 (103079215111ul)(206158430209ul)(412316860441ul)(824633720831ul) \
0067 (1649267441651ul)(3298534883309ul)(6597069766657ul)(13194139533299ul) \
0068 (26388279066623ul)(52776558133303ul)(105553116266489ul)(211106232532969ul) \
0069 (422212465066001ul)(844424930131963ul)(1688849860263953ul) \
0070 (3377699720527861ul)(6755399441055731ul)(13510798882111483ul) \
0071 (27021597764222939ul)(54043195528445957ul)(108086391056891903ul) \
0072 (216172782113783843ul)(432345564227567621ul)(864691128455135207ul) \
0073 (1729382256910270481ul)(3458764513820540933ul)(6917529027641081903ul) \
0074 (13835058055282163729ul)(18446744073709551557ul)
0075 #endif
0076
0077 template<bool _=true>
0078 class bucket_array_base:private noncopyable
0079 {
0080 protected:
0081 static const std::size_t sizes[
0082 BOOST_PP_SEQ_SIZE(BOOST_MULTI_INDEX_BA_SIZES)];
0083
0084 static std::size_t size_index(std::size_t n)
0085 {
0086 const std::size_t *bound=std::lower_bound(sizes,sizes+sizes_length,n);
0087 if(bound==sizes+sizes_length)--bound;
0088 return bound-sizes;
0089 }
0090
0091 #define BOOST_MULTI_INDEX_BA_POSITION_CASE(z,n,_) \
0092 case n:return hash%BOOST_PP_SEQ_ELEM(n,BOOST_MULTI_INDEX_BA_SIZES);
0093
0094 static std::size_t position(std::size_t hash,std::size_t size_index_)
0095 {
0096
0097
0098
0099
0100
0101 switch(size_index_){
0102 default:
0103 BOOST_PP_REPEAT(
0104 BOOST_PP_SEQ_SIZE(BOOST_MULTI_INDEX_BA_SIZES),
0105 BOOST_MULTI_INDEX_BA_POSITION_CASE,~)
0106 }
0107 }
0108
0109 private:
0110 static const std::size_t sizes_length;
0111 };
0112
0113 template<bool _>
0114 const std::size_t bucket_array_base<_>::sizes[]={
0115 BOOST_PP_SEQ_ENUM(BOOST_MULTI_INDEX_BA_SIZES)
0116 };
0117
0118 template<bool _>
0119 const std::size_t bucket_array_base<_>::sizes_length=
0120 sizeof(bucket_array_base<_>::sizes)/
0121 sizeof(bucket_array_base<_>::sizes[0]);
0122
0123 #undef BOOST_MULTI_INDEX_BA_POSITION_CASE
0124 #undef BOOST_MULTI_INDEX_BA_SIZES
0125 #undef BOOST_MULTI_INDEX_BA_SIZES_32BIT
0126
0127 template<typename Allocator>
0128 class bucket_array:bucket_array_base<>
0129 {
0130 typedef bucket_array_base<> super;
0131 typedef hashed_index_base_node_impl<
0132 typename rebind_alloc_for<
0133 Allocator,
0134 char
0135 >::type
0136 > base_node_impl_type;
0137
0138 public:
0139 typedef typename base_node_impl_type::base_pointer base_pointer;
0140 typedef typename base_node_impl_type::pointer pointer;
0141
0142 bucket_array(const Allocator& al,pointer end_,std::size_t size_):
0143 size_index_(super::size_index(size_)),
0144 spc(al,static_cast<auto_space_size_type>(super::sizes[size_index_]+1))
0145 {
0146 clear(end_);
0147 }
0148
0149 std::size_t size()const
0150 {
0151 return super::sizes[size_index_];
0152 }
0153
0154 std::size_t position(std::size_t hash)const
0155 {
0156 return super::position(hash,size_index_);
0157 }
0158
0159 base_pointer begin()const{return buckets();}
0160 base_pointer end()const{return buckets()+size();}
0161 base_pointer at(std::size_t n)const{return buckets()+n;}
0162
0163 void clear(pointer end_)
0164 {
0165 for(base_pointer x=begin(),y=end();x!=y;++x)x->prior()=pointer(0);
0166 end()->prior()=end_->prior()=end_;
0167 end_->next()=end();
0168 }
0169
0170 void swap(bucket_array& x)
0171 {
0172 std::swap(size_index_,x.size_index_);
0173 spc.swap(x.spc);
0174 }
0175
0176 template<typename BoolConstant>
0177 void swap(bucket_array& x,BoolConstant swap_allocators)
0178 {
0179 std::swap(size_index_,x.size_index_);
0180 spc.swap(x.spc,swap_allocators);
0181 }
0182
0183 private:
0184 typedef auto_space<base_node_impl_type,Allocator> auto_space_type;
0185 typedef typename auto_space_type::size_type auto_space_size_type;
0186
0187 std::size_t size_index_;
0188 auto_space_type spc;
0189
0190 base_pointer buckets()const
0191 {
0192 return spc.data();
0193 }
0194
0195 #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
0196 friend class boost::serialization::access;
0197
0198
0199
0200
0201
0202
0203 template<class Archive>
0204 void serialize(Archive&,const unsigned int)
0205 {
0206 }
0207 #endif
0208 };
0209
0210 template<typename Allocator>
0211 void swap(bucket_array<Allocator>& x,bucket_array<Allocator>& y)
0212 {
0213 x.swap(y);
0214 }
0215
0216 }
0217
0218 }
0219
0220 #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
0221
0222
0223
0224
0225
0226
0227 #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
0228 namespace serialization{
0229 #else
0230 namespace multi_index{
0231 namespace detail{
0232 #endif
0233
0234 template<class Archive,typename Allocator>
0235 inline void load_construct_data(
0236 Archive&,boost::multi_index::detail::bucket_array<Allocator>*,
0237 const unsigned int)
0238 {
0239 throw_exception(boost::multi_index::detail::bad_archive_exception());
0240 }
0241
0242 #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
0243 }
0244 #else
0245 }
0246 }
0247 #endif
0248
0249 #endif
0250
0251 }
0252
0253 #endif