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