Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/intrusive/detail/hashtable_node.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 ///////////////////////////////////////////////////////////////////////////// | |
2 // | |
3 // (C) Copyright Ion Gaztanaga 2007-2013 | |
4 // | |
5 // Distributed under the Boost Software License, Version 1.0. | |
6 // (See accompanying file LICENSE_1_0.txt or copy at | |
7 // http://www.boost.org/LICENSE_1_0.txt) | |
8 // | |
9 // See http://www.boost.org/libs/intrusive for documentation. | |
10 // | |
11 ///////////////////////////////////////////////////////////////////////////// | |
12 | |
13 #ifndef BOOST_INTRUSIVE_HASHTABLE_NODE_HPP | |
14 #define BOOST_INTRUSIVE_HASHTABLE_NODE_HPP | |
15 | |
16 #include <boost/intrusive/detail/config_begin.hpp> | |
17 #include <iterator> | |
18 #include <boost/intrusive/detail/assert.hpp> | |
19 #include <boost/intrusive/pointer_traits.hpp> | |
20 #include <boost/intrusive/circular_list_algorithms.hpp> | |
21 #include <boost/intrusive/detail/mpl.hpp> | |
22 #include <boost/intrusive/detail/utilities.hpp> | |
23 #include <boost/intrusive/slist.hpp> //remove-me | |
24 #include <boost/intrusive/pointer_traits.hpp> | |
25 #include <boost/intrusive/trivial_value_traits.hpp> | |
26 #include <cstddef> | |
27 #include <boost/type_traits/make_unsigned.hpp> | |
28 #include <boost/pointer_cast.hpp> | |
29 #include <boost/move/core.hpp> | |
30 | |
31 | |
32 namespace boost { | |
33 namespace intrusive { | |
34 namespace detail { | |
35 | |
36 template<int Dummy = 0> | |
37 struct prime_list_holder | |
38 { | |
39 static const std::size_t prime_list[]; | |
40 static const std::size_t prime_list_size; | |
41 }; | |
42 | |
43 template<int Dummy> | |
44 const std::size_t prime_list_holder<Dummy>::prime_list[] = { | |
45 3ul, 7ul, 11ul, 17ul, 29ul, | |
46 53ul, 97ul, 193ul, 389ul, 769ul, | |
47 1543ul, 3079ul, 6151ul, 12289ul, 24593ul, | |
48 49157ul, 98317ul, 196613ul, 393241ul, 786433ul, | |
49 1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul, | |
50 50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul, | |
51 1610612741ul, 3221225473ul, 4294967291ul }; | |
52 | |
53 template<int Dummy> | |
54 const std::size_t prime_list_holder<Dummy>::prime_list_size | |
55 = sizeof(prime_list)/sizeof(std::size_t); | |
56 | |
57 template <class Slist> | |
58 struct bucket_impl : public Slist | |
59 { | |
60 typedef Slist slist_type; | |
61 bucket_impl() | |
62 {} | |
63 | |
64 bucket_impl(const bucket_impl &) | |
65 {} | |
66 | |
67 ~bucket_impl() | |
68 { | |
69 //This bucket is still being used! | |
70 BOOST_INTRUSIVE_INVARIANT_ASSERT(Slist::empty()); | |
71 } | |
72 | |
73 bucket_impl &operator=(const bucket_impl&) | |
74 { | |
75 //This bucket is still in use! | |
76 BOOST_INTRUSIVE_INVARIANT_ASSERT(Slist::empty()); | |
77 //Slist::clear(); | |
78 return *this; | |
79 } | |
80 }; | |
81 | |
82 template<class Slist> | |
83 struct bucket_traits_impl | |
84 { | |
85 private: | |
86 BOOST_COPYABLE_AND_MOVABLE(bucket_traits_impl) | |
87 | |
88 public: | |
89 /// @cond | |
90 | |
91 typedef typename pointer_traits | |
92 <typename Slist::pointer>::template rebind_pointer | |
93 < bucket_impl<Slist> >::type bucket_ptr; | |
94 typedef Slist slist; | |
95 typedef typename Slist::size_type size_type; | |
96 /// @endcond | |
97 | |
98 bucket_traits_impl(bucket_ptr buckets, size_type len) | |
99 : buckets_(buckets), buckets_len_(len) | |
100 {} | |
101 | |
102 bucket_traits_impl(const bucket_traits_impl &x) | |
103 : buckets_(x.buckets_), buckets_len_(x.buckets_len_) | |
104 {} | |
105 | |
106 bucket_traits_impl(BOOST_RV_REF(bucket_traits_impl) x) | |
107 : buckets_(x.buckets_), buckets_len_(x.buckets_len_) | |
108 { x.buckets_ = bucket_ptr(); x.buckets_len_ = 0; } | |
109 | |
110 bucket_traits_impl& operator=(BOOST_RV_REF(bucket_traits_impl) x) | |
111 { | |
112 buckets_ = x.buckets_; buckets_len_ = x.buckets_len_; | |
113 x.buckets_ = bucket_ptr(); x.buckets_len_ = 0; return *this; | |
114 } | |
115 | |
116 bucket_traits_impl& operator=(BOOST_COPY_ASSIGN_REF(bucket_traits_impl) x) | |
117 { | |
118 buckets_ = x.buckets_; buckets_len_ = x.buckets_len_; return *this; | |
119 } | |
120 | |
121 const bucket_ptr &bucket_begin() const | |
122 { return buckets_; } | |
123 | |
124 size_type bucket_count() const | |
125 { return buckets_len_; } | |
126 | |
127 private: | |
128 bucket_ptr buckets_; | |
129 size_type buckets_len_; | |
130 }; | |
131 | |
132 template <class NodeTraits> | |
133 struct hash_reduced_slist_node_traits | |
134 { | |
135 template <class U> static detail::one test(...); | |
136 template <class U> static detail::two test(typename U::reduced_slist_node_traits* = 0); | |
137 static const bool value = sizeof(test<NodeTraits>(0)) == sizeof(detail::two); | |
138 }; | |
139 | |
140 template <class NodeTraits> | |
141 struct apply_reduced_slist_node_traits | |
142 { | |
143 typedef typename NodeTraits::reduced_slist_node_traits type; | |
144 }; | |
145 | |
146 template <class NodeTraits> | |
147 struct reduced_slist_node_traits | |
148 { | |
149 typedef typename detail::eval_if_c | |
150 < hash_reduced_slist_node_traits<NodeTraits>::value | |
151 , apply_reduced_slist_node_traits<NodeTraits> | |
152 , detail::identity<NodeTraits> | |
153 >::type type; | |
154 }; | |
155 | |
156 template<class NodeTraits> | |
157 struct get_slist_impl | |
158 { | |
159 typedef trivial_value_traits<NodeTraits, normal_link> trivial_traits; | |
160 | |
161 //Reducing symbol length | |
162 struct type : make_slist | |
163 < typename NodeTraits::node | |
164 , boost::intrusive::value_traits<trivial_traits> | |
165 , boost::intrusive::constant_time_size<false> | |
166 , boost::intrusive::size_type<typename boost::make_unsigned | |
167 <typename pointer_traits<typename NodeTraits::node_ptr>::difference_type>::type > | |
168 >::type | |
169 {}; | |
170 }; | |
171 | |
172 } //namespace detail { | |
173 | |
174 template<class BucketValueTraits, bool IsConst> | |
175 class hashtable_iterator | |
176 : public std::iterator | |
177 < std::forward_iterator_tag | |
178 , typename BucketValueTraits::real_value_traits::value_type | |
179 , typename pointer_traits<typename BucketValueTraits::real_value_traits::value_type*>::difference_type | |
180 , typename detail::add_const_if_c | |
181 <typename BucketValueTraits::real_value_traits::value_type, IsConst>::type * | |
182 , typename detail::add_const_if_c | |
183 <typename BucketValueTraits::real_value_traits::value_type, IsConst>::type & | |
184 > | |
185 { | |
186 typedef typename BucketValueTraits::real_value_traits real_value_traits; | |
187 typedef typename BucketValueTraits::real_bucket_traits real_bucket_traits; | |
188 typedef typename real_value_traits::node_traits node_traits; | |
189 typedef typename detail::get_slist_impl | |
190 <typename detail::reduced_slist_node_traits | |
191 <typename real_value_traits::node_traits>::type | |
192 >::type slist_impl; | |
193 typedef typename slist_impl::iterator siterator; | |
194 typedef typename slist_impl::const_iterator const_siterator; | |
195 typedef detail::bucket_impl<slist_impl> bucket_type; | |
196 | |
197 typedef typename pointer_traits | |
198 <typename real_value_traits::pointer>::template rebind_pointer | |
199 < const BucketValueTraits >::type const_bucketvaltraits_ptr; | |
200 typedef typename slist_impl::size_type size_type; | |
201 | |
202 | |
203 static typename node_traits::node_ptr downcast_bucket(typename bucket_type::node_ptr p) | |
204 { | |
205 return pointer_traits<typename node_traits::node_ptr>:: | |
206 pointer_to(static_cast<typename node_traits::node&>(*p)); | |
207 } | |
208 | |
209 public: | |
210 typedef typename real_value_traits::value_type value_type; | |
211 typedef typename detail::add_const_if_c<value_type, IsConst>::type *pointer; | |
212 typedef typename detail::add_const_if_c<value_type, IsConst>::type &reference; | |
213 | |
214 hashtable_iterator () | |
215 {} | |
216 | |
217 explicit hashtable_iterator(siterator ptr, const BucketValueTraits *cont) | |
218 : slist_it_ (ptr), traitsptr_ (cont ? pointer_traits<const_bucketvaltraits_ptr>::pointer_to(*cont) : const_bucketvaltraits_ptr() ) | |
219 {} | |
220 | |
221 hashtable_iterator(const hashtable_iterator<BucketValueTraits, false> &other) | |
222 : slist_it_(other.slist_it()), traitsptr_(other.get_bucket_value_traits()) | |
223 {} | |
224 | |
225 const siterator &slist_it() const | |
226 { return slist_it_; } | |
227 | |
228 hashtable_iterator<BucketValueTraits, false> unconst() const | |
229 { return hashtable_iterator<BucketValueTraits, false>(this->slist_it(), this->get_bucket_value_traits()); } | |
230 | |
231 public: | |
232 hashtable_iterator& operator++() | |
233 { this->increment(); return *this; } | |
234 | |
235 hashtable_iterator operator++(int) | |
236 { | |
237 hashtable_iterator result (*this); | |
238 this->increment(); | |
239 return result; | |
240 } | |
241 | |
242 friend bool operator== (const hashtable_iterator& i, const hashtable_iterator& i2) | |
243 { return i.slist_it_ == i2.slist_it_; } | |
244 | |
245 friend bool operator!= (const hashtable_iterator& i, const hashtable_iterator& i2) | |
246 { return !(i == i2); } | |
247 | |
248 reference operator*() const | |
249 { return *this->operator ->(); } | |
250 | |
251 pointer operator->() const | |
252 { | |
253 return boost::intrusive::detail::to_raw_pointer(this->priv_real_value_traits().to_value_ptr | |
254 (downcast_bucket(slist_it_.pointed_node()))); | |
255 } | |
256 | |
257 const const_bucketvaltraits_ptr &get_bucket_value_traits() const | |
258 { return traitsptr_; } | |
259 | |
260 const real_value_traits &priv_real_value_traits() const | |
261 { return traitsptr_->priv_real_value_traits(); } | |
262 | |
263 const real_bucket_traits &priv_real_bucket_traits() const | |
264 { return traitsptr_->priv_real_bucket_traits(); } | |
265 | |
266 private: | |
267 void increment() | |
268 { | |
269 const real_bucket_traits &rbuck_traits = this->priv_real_bucket_traits(); | |
270 bucket_type* const buckets = boost::intrusive::detail::to_raw_pointer(rbuck_traits.bucket_begin()); | |
271 const size_type buckets_len = rbuck_traits.bucket_count(); | |
272 | |
273 ++slist_it_; | |
274 const typename slist_impl::node_ptr n = slist_it_.pointed_node(); | |
275 const siterator first_bucket_bbegin = buckets->end(); | |
276 if(first_bucket_bbegin.pointed_node() <= n && n <= buckets[buckets_len-1].cend().pointed_node()){ | |
277 //If one-past the node is inside the bucket then look for the next non-empty bucket | |
278 //1. get the bucket_impl from the iterator | |
279 const bucket_type &b = static_cast<const bucket_type&> | |
280 (bucket_type::slist_type::container_from_end_iterator(slist_it_)); | |
281 | |
282 //2. Now just calculate the index b has in the bucket array | |
283 size_type n_bucket = static_cast<size_type>(&b - buckets); | |
284 | |
285 //3. Iterate until a non-empty bucket is found | |
286 do{ | |
287 if (++n_bucket >= buckets_len){ //bucket overflow, return end() iterator | |
288 slist_it_ = buckets->before_begin(); | |
289 return; | |
290 } | |
291 } | |
292 while (buckets[n_bucket].empty()); | |
293 slist_it_ = buckets[n_bucket].begin(); | |
294 } | |
295 else{ | |
296 //++slist_it_ yield to a valid object | |
297 } | |
298 } | |
299 | |
300 siterator slist_it_; | |
301 const_bucketvaltraits_ptr traitsptr_; | |
302 }; | |
303 | |
304 } //namespace intrusive { | |
305 } //namespace boost { | |
306 | |
307 #endif |