diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DEPENDENCIES/generic/include/boost/intrusive/detail/hashtable_node.hpp	Tue Aug 05 11:11:38 2014 +0100
@@ -0,0 +1,307 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga  2007-2013
+//
+// Distributed under the Boost Software License, Version 1.0.
+//    (See accompanying file LICENSE_1_0.txt or copy at
+//          http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_HASHTABLE_NODE_HPP
+#define BOOST_INTRUSIVE_HASHTABLE_NODE_HPP
+
+#include <boost/intrusive/detail/config_begin.hpp>
+#include <iterator>
+#include <boost/intrusive/detail/assert.hpp>
+#include <boost/intrusive/pointer_traits.hpp>
+#include <boost/intrusive/circular_list_algorithms.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
+#include <boost/intrusive/detail/utilities.hpp>
+#include <boost/intrusive/slist.hpp> //remove-me
+#include <boost/intrusive/pointer_traits.hpp>
+#include <boost/intrusive/trivial_value_traits.hpp>
+#include <cstddef>
+#include <boost/type_traits/make_unsigned.hpp>
+#include <boost/pointer_cast.hpp>
+#include <boost/move/core.hpp>
+
+
+namespace boost {
+namespace intrusive {
+namespace detail {
+
+template<int Dummy = 0>
+struct prime_list_holder
+{
+   static const std::size_t prime_list[];
+   static const std::size_t prime_list_size;
+};
+
+template<int Dummy>
+const std::size_t prime_list_holder<Dummy>::prime_list[] = {
+   3ul, 7ul, 11ul, 17ul, 29ul,
+   53ul, 97ul, 193ul, 389ul, 769ul,
+   1543ul, 3079ul, 6151ul, 12289ul, 24593ul,
+   49157ul, 98317ul, 196613ul, 393241ul, 786433ul,
+   1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul,
+   50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,
+   1610612741ul, 3221225473ul, 4294967291ul };
+
+template<int Dummy>
+const std::size_t prime_list_holder<Dummy>::prime_list_size
+   = sizeof(prime_list)/sizeof(std::size_t);
+
+template <class Slist>
+struct bucket_impl : public Slist
+{
+   typedef Slist slist_type;
+   bucket_impl()
+   {}
+
+   bucket_impl(const bucket_impl &)
+   {}
+
+   ~bucket_impl()
+   {
+      //This bucket is still being used!
+      BOOST_INTRUSIVE_INVARIANT_ASSERT(Slist::empty());
+   }
+
+   bucket_impl &operator=(const bucket_impl&)
+   {
+      //This bucket is still in use!
+      BOOST_INTRUSIVE_INVARIANT_ASSERT(Slist::empty());
+      //Slist::clear();
+      return *this;
+   }
+};
+
+template<class Slist>
+struct bucket_traits_impl
+{
+   private:
+   BOOST_COPYABLE_AND_MOVABLE(bucket_traits_impl)
+
+   public:
+   /// @cond
+
+   typedef typename pointer_traits
+      <typename Slist::pointer>::template rebind_pointer
+         < bucket_impl<Slist> >::type                                bucket_ptr;
+   typedef Slist slist;
+   typedef typename Slist::size_type size_type;
+   /// @endcond
+
+   bucket_traits_impl(bucket_ptr buckets, size_type len)
+      :  buckets_(buckets), buckets_len_(len)
+   {}
+
+   bucket_traits_impl(const bucket_traits_impl &x)
+      : buckets_(x.buckets_), buckets_len_(x.buckets_len_)
+   {}
+
+   bucket_traits_impl(BOOST_RV_REF(bucket_traits_impl) x)
+      : buckets_(x.buckets_), buckets_len_(x.buckets_len_)
+   {  x.buckets_ = bucket_ptr();   x.buckets_len_ = 0;  }
+
+   bucket_traits_impl& operator=(BOOST_RV_REF(bucket_traits_impl) x)
+   {
+      buckets_ = x.buckets_; buckets_len_ = x.buckets_len_;
+      x.buckets_ = bucket_ptr();   x.buckets_len_ = 0; return *this;
+   }
+
+   bucket_traits_impl& operator=(BOOST_COPY_ASSIGN_REF(bucket_traits_impl) x)
+   {
+      buckets_ = x.buckets_;  buckets_len_ = x.buckets_len_; return *this;
+   }
+
+   const bucket_ptr &bucket_begin() const
+   {  return buckets_;  }
+
+   size_type  bucket_count() const
+   {  return buckets_len_;  }
+
+   private:
+   bucket_ptr  buckets_;
+   size_type   buckets_len_;
+};
+
+template <class NodeTraits>
+struct hash_reduced_slist_node_traits
+{
+   template <class U> static detail::one test(...);
+   template <class U> static detail::two test(typename U::reduced_slist_node_traits* = 0);
+   static const bool value = sizeof(test<NodeTraits>(0)) == sizeof(detail::two);
+};
+
+template <class NodeTraits>
+struct apply_reduced_slist_node_traits
+{
+   typedef typename NodeTraits::reduced_slist_node_traits type;
+};
+
+template <class NodeTraits>
+struct reduced_slist_node_traits
+{
+   typedef typename detail::eval_if_c
+      < hash_reduced_slist_node_traits<NodeTraits>::value
+      , apply_reduced_slist_node_traits<NodeTraits>
+      , detail::identity<NodeTraits>
+      >::type type;
+};
+
+template<class NodeTraits>
+struct get_slist_impl
+{
+   typedef trivial_value_traits<NodeTraits, normal_link> trivial_traits;
+
+   //Reducing symbol length
+   struct type : make_slist
+      < typename NodeTraits::node
+      , boost::intrusive::value_traits<trivial_traits>
+      , boost::intrusive::constant_time_size<false>
+	  , boost::intrusive::size_type<typename boost::make_unsigned
+         <typename pointer_traits<typename NodeTraits::node_ptr>::difference_type>::type >
+      >::type
+   {};
+};
+
+}  //namespace detail {
+
+template<class BucketValueTraits, bool IsConst>
+class hashtable_iterator
+   :  public std::iterator
+         < std::forward_iterator_tag
+         , typename BucketValueTraits::real_value_traits::value_type
+         , typename pointer_traits<typename BucketValueTraits::real_value_traits::value_type*>::difference_type
+         , typename detail::add_const_if_c
+                     <typename BucketValueTraits::real_value_traits::value_type, IsConst>::type *
+         , typename detail::add_const_if_c
+                     <typename BucketValueTraits::real_value_traits::value_type, IsConst>::type &
+         >
+{
+   typedef typename BucketValueTraits::real_value_traits          real_value_traits;
+   typedef typename BucketValueTraits::real_bucket_traits         real_bucket_traits;
+   typedef typename real_value_traits::node_traits                node_traits;
+   typedef typename detail::get_slist_impl
+      <typename detail::reduced_slist_node_traits
+         <typename real_value_traits::node_traits>::type
+      >::type                                                     slist_impl;
+   typedef typename slist_impl::iterator                          siterator;
+   typedef typename slist_impl::const_iterator                    const_siterator;
+   typedef detail::bucket_impl<slist_impl>                        bucket_type;
+
+   typedef typename pointer_traits
+      <typename real_value_traits::pointer>::template rebind_pointer
+         < const BucketValueTraits >::type                        const_bucketvaltraits_ptr;
+   typedef typename slist_impl::size_type                         size_type;
+
+
+   static typename node_traits::node_ptr downcast_bucket(typename bucket_type::node_ptr p)
+   {
+      return pointer_traits<typename node_traits::node_ptr>::
+         pointer_to(static_cast<typename node_traits::node&>(*p));
+   }
+
+   public:
+   typedef typename real_value_traits::value_type    value_type;
+   typedef typename detail::add_const_if_c<value_type, IsConst>::type *pointer;
+   typedef typename detail::add_const_if_c<value_type, IsConst>::type &reference;
+
+   hashtable_iterator ()
+   {}
+
+   explicit hashtable_iterator(siterator ptr, const BucketValueTraits *cont)
+      :  slist_it_ (ptr),   traitsptr_ (cont ? pointer_traits<const_bucketvaltraits_ptr>::pointer_to(*cont) : const_bucketvaltraits_ptr() )
+   {}
+
+   hashtable_iterator(const hashtable_iterator<BucketValueTraits, false> &other)
+      :  slist_it_(other.slist_it()), traitsptr_(other.get_bucket_value_traits())
+   {}
+
+   const siterator &slist_it() const
+   { return slist_it_; }
+
+   hashtable_iterator<BucketValueTraits, false> unconst() const
+   {  return hashtable_iterator<BucketValueTraits, false>(this->slist_it(), this->get_bucket_value_traits());   }
+
+   public:
+   hashtable_iterator& operator++()
+   {  this->increment();   return *this;   }
+
+   hashtable_iterator operator++(int)
+   {
+      hashtable_iterator result (*this);
+      this->increment();
+      return result;
+   }
+
+   friend bool operator== (const hashtable_iterator& i, const hashtable_iterator& i2)
+   { return i.slist_it_ == i2.slist_it_; }
+
+   friend bool operator!= (const hashtable_iterator& i, const hashtable_iterator& i2)
+   { return !(i == i2); }
+
+   reference operator*() const
+   { return *this->operator ->(); }
+
+   pointer operator->() const
+   {
+      return boost::intrusive::detail::to_raw_pointer(this->priv_real_value_traits().to_value_ptr
+         (downcast_bucket(slist_it_.pointed_node())));
+   }
+
+   const const_bucketvaltraits_ptr &get_bucket_value_traits() const
+   {  return traitsptr_;  }
+
+   const real_value_traits &priv_real_value_traits() const
+   {  return traitsptr_->priv_real_value_traits();  }
+
+   const real_bucket_traits &priv_real_bucket_traits() const
+   {  return traitsptr_->priv_real_bucket_traits();  }
+
+   private:
+   void increment()
+   {
+      const real_bucket_traits &rbuck_traits = this->priv_real_bucket_traits();
+      bucket_type* const buckets = boost::intrusive::detail::to_raw_pointer(rbuck_traits.bucket_begin());
+      const size_type buckets_len = rbuck_traits.bucket_count();
+
+      ++slist_it_;
+      const typename slist_impl::node_ptr n = slist_it_.pointed_node();
+      const siterator first_bucket_bbegin = buckets->end();
+      if(first_bucket_bbegin.pointed_node() <= n && n <= buckets[buckets_len-1].cend().pointed_node()){
+         //If one-past the node is inside the bucket then look for the next non-empty bucket
+         //1. get the bucket_impl from the iterator
+         const bucket_type &b = static_cast<const bucket_type&>
+            (bucket_type::slist_type::container_from_end_iterator(slist_it_));
+
+         //2. Now just calculate the index b has in the bucket array
+         size_type n_bucket = static_cast<size_type>(&b - buckets);
+
+         //3. Iterate until a non-empty bucket is found
+         do{
+            if (++n_bucket >= buckets_len){  //bucket overflow, return end() iterator
+               slist_it_ = buckets->before_begin();
+               return;
+            }
+         }
+         while (buckets[n_bucket].empty());
+         slist_it_ = buckets[n_bucket].begin();
+      }
+      else{
+         //++slist_it_ yield to a valid object
+      }
+   }
+
+   siterator                  slist_it_;
+   const_bucketvaltraits_ptr  traitsptr_;
+};
+
+}  //namespace intrusive {
+}  //namespace boost {
+
+#endif