diff --git a/include/boost/intrusive/circular_slist_algorithms.hpp b/include/boost/intrusive/circular_slist_algorithms.hpp
index cbb1d20..20dcafa 100644
--- a/include/boost/intrusive/circular_slist_algorithms.hpp
+++ b/include/boost/intrusive/circular_slist_algorithms.hpp
@@ -48,6 +48,7 @@ class circular_slist_algorithms
public:
typedef typename NodeTraits::node_ptr node_ptr;
typedef typename NodeTraits::const_node_ptr const_node_ptr;
+ typedef NodeTraits node_traits;
//! Requires: this_node must be in a circular list or be an empty circular list.
//!
diff --git a/include/boost/intrusive/derivation_value_traits.hpp b/include/boost/intrusive/derivation_value_traits.hpp
index 5ff3bae..2036890 100644
--- a/include/boost/intrusive/derivation_value_traits.hpp
+++ b/include/boost/intrusive/derivation_value_traits.hpp
@@ -13,7 +13,7 @@
#ifndef BOOST_INTRUSIVE_DERIVATION_VALUE_TRAITS_HPP
#define BOOST_INTRUSIVE_DERIVATION_VALUE_TRAITS_HPP
-#include
+#include
#include
namespace boost {
@@ -22,7 +22,7 @@ namespace intrusive {
//!This value traits template is used to create value traits
//!from user defined node traits where value_traits::value_type will
//!derive from node_traits::node
-template
+template
struct derivation_value_traits
{
public:
@@ -35,8 +35,7 @@ struct derivation_value_traits
typedef typename boost::pointer_to_other::type const_pointer;
typedef typename std::iterator_traits::reference reference;
typedef typename std::iterator_traits::reference const_reference;
-
- enum { linking_policy = Policy };
+ static const link_mode_type link_mode = LinkMode;
static node_ptr to_node_ptr(reference value)
{ return node_ptr(&value); }
diff --git a/include/boost/intrusive/detail/config_begin.hpp b/include/boost/intrusive/detail/config_begin.hpp
index b4b20c6..f30069d 100644
--- a/include/boost/intrusive/detail/config_begin.hpp
+++ b/include/boost/intrusive/detail/config_begin.hpp
@@ -10,12 +10,10 @@
//
/////////////////////////////////////////////////////////////////////////////
-#ifndef BOOST_INTRUSIVE_SELECT_COMPILER_INCLUDED
-#ifndef BOOST_COMPILER_CONFIG
+#ifndef BOOST_INTRUSIVE_CONFIG_INCLUDED
+#define BOOST_INTRUSIVE_CONFIG_INCLUDED
#include
#endif
-#define BOOST_INTRUSIVE_SELECT_COMPILER_INCLUDED
-#endif
#ifdef BOOST_MSVC
diff --git a/include/boost/intrusive/detail/ebo_functor_holder.hpp b/include/boost/intrusive/detail/ebo_functor_holder.hpp
index d58516f..69c50cd 100644
--- a/include/boost/intrusive/detail/ebo_functor_holder.hpp
+++ b/include/boost/intrusive/detail/ebo_functor_holder.hpp
@@ -35,7 +35,7 @@ class ebo_functor_holder_impl
template
class ebo_functor_holder_impl
- : private T
+ : public T
{
public:
ebo_functor_holder_impl(){}
diff --git a/include/boost/intrusive/detail/generic_hook.hpp b/include/boost/intrusive/detail/generic_hook.hpp
new file mode 100644
index 0000000..e01c5e9
--- /dev/null
+++ b/include/boost/intrusive/detail/generic_hook.hpp
@@ -0,0 +1,185 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007
+//
+// 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_GENERIC_HOOK_HPP
+#define BOOST_INTRUSIVE_GENERIC_HOOK_HPP
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace boost {
+namespace intrusive {
+namespace detail {
+
+/// @cond
+
+enum
+{ NoBaseHook
+, ListBaseHook
+, SlistBaseHook
+, SetBaseHook
+, UsetBaseHook
+};
+
+struct no_default_definer{};
+
+template
+struct default_definer;
+
+template
+struct default_definer
+{ typedef Hook default_list_hook; };
+
+template
+struct default_definer
+{ typedef Hook default_slist_hook; };
+
+template
+struct default_definer
+{ typedef Hook default_set_hook; };
+
+template
+struct default_definer
+{ typedef Hook default_uset_hook; };
+
+template
+struct make_default_definer
+{
+ typedef typename detail::if_c
+ < BaseHookType != 0
+ , default_definer
+ , no_default_definer>::type type;
+};
+
+template
+ < class GetNodeAlgorithms
+ , class Tag
+ , link_mode_type LinkMode
+ , int HookType
+ >
+struct make_node_holder
+{
+ typedef typename detail::if_c
+ ::value
+ , detail::node_holder
+ < typename GetNodeAlgorithms::type::node_traits::node
+ , Tag
+ , LinkMode
+ , HookType>
+ , typename GetNodeAlgorithms::type::node_traits::node
+ >::type type;
+};
+
+/// @endcond
+
+template
+ < class GetNodeAlgorithms
+ , class Tag
+ , link_mode_type LinkMode
+ , int HookType
+ >
+class generic_hook
+ /// @cond
+
+ //If the hook is a base hook, derive generic hook from detail::node_holder
+ //so that a unique base class is created to convert from the node
+ //to the type. This mechanism will be used by base_hook_traits.
+ //
+ //If the hook is a member hook, generic hook will directly derive
+ //from the hook.
+ : public make_default_definer
+ < generic_hook
+ , detail::is_same::value*HookType
+ >::type
+ , public make_node_holder::type
+ /// @endcond
+{
+ public:
+ /// @cond
+ struct boost_intrusive_tags
+ {
+ static const int hook_type = HookType;
+ static const link_mode_type link_mode = LinkMode;
+ typedef Tag tag;
+ typedef typename GetNodeAlgorithms::type node_algorithms;
+ typedef typename node_algorithms::node_traits node_traits;
+ typedef typename node_traits::node node;
+ typedef typename node_traits::node_ptr node_ptr;
+ typedef typename node_traits::const_node_ptr const_node_ptr;
+ static const bool is_base_hook = !detail::is_same::value;
+ enum { safemode_or_autounlink =
+ (int)link_mode == (int)auto_unlink ||
+ (int)link_mode == (int)safe_link };
+ };
+ /// @endcond
+
+ generic_hook()
+ {
+ if(boost_intrusive_tags::safemode_or_autounlink){
+ boost_intrusive_tags::node_algorithms::init
+ (static_cast(this));
+ }
+ }
+
+ generic_hook(const generic_hook& )
+ {
+ if(boost_intrusive_tags::safemode_or_autounlink){
+ boost_intrusive_tags::node_algorithms::init
+ (static_cast(this));
+ }
+ }
+
+ generic_hook& operator=(const generic_hook& )
+ { return *this; }
+
+ ~generic_hook()
+ {
+ destructor_impl
+ (*this, detail::link_dispatch());
+ }
+
+ void swap_nodes(generic_hook &other)
+ {
+ boost_intrusive_tags::node_algorithms::swap_nodes
+ ( static_cast(this)
+ , static_cast(&other));
+ }
+
+ bool is_linked() const
+ {
+ //is_linked() can be only used in safe-mode or auto-unlink
+ BOOST_STATIC_ASSERT(( boost_intrusive_tags::safemode_or_autounlink ));
+ return !boost_intrusive_tags::node_algorithms::unique
+ (static_cast(this));
+ }
+
+ void unlink()
+ {
+ BOOST_STATIC_ASSERT(( (int)boost_intrusive_tags::link_mode == (int)auto_unlink ));
+ boost_intrusive_tags::node_algorithms::unlink
+ (static_cast(this));
+ boost_intrusive_tags::node_algorithms::init
+ (static_cast(this));
+ }
+};
+
+} //namespace detail
+} //namespace intrusive
+} //namespace boost
+
+#include
+
+#endif //BOOST_INTRUSIVE_GENERIC_HOOK_HPP
diff --git a/include/boost/intrusive/detail/hashtable_node.hpp b/include/boost/intrusive/detail/hashtable_node.hpp
index 7e875cf..d10ad2c 100644
--- a/include/boost/intrusive/detail/hashtable_node.hpp
+++ b/include/boost/intrusive/detail/hashtable_node.hpp
@@ -18,14 +18,9 @@
#include
#include
#include
-#ifdef BOOST_INTRUSIVE_USE_ITERATOR_FACADE
-#include
-#endif
-#ifdef BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE
-#include
-#include
-#endif
#include
+#include
+#include //remove-me
#include
namespace boost {
@@ -52,27 +47,34 @@ template
const std::size_t prime_list_holder::prime_list_size
= sizeof(prime_list)/sizeof(std::size_t);
-template
-struct bucket_type_impl
- : public SlistImpl
+template
+struct bucket_impl : public Slist
{
- bucket_type_impl()
+ bucket_impl()
{}
- bucket_type_impl(const bucket_type_impl &)
+ bucket_impl(const bucket_impl &)
{}
- bucket_type_impl &operator=(const bucket_type_impl&)
- { SlistImpl::clear(); }
-
- static typename std::iterator_traits
- ::difference_type
- get_bucket_num
- ( typename SlistImpl::const_iterator it
- , const bucket_type_impl &first_bucket
- , const bucket_type_impl &last_bucket)
+ ~bucket_impl()
{
- typename SlistImpl::const_iterator
+ //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();
+ }
+
+ static typename Slist::difference_type get_bucket_num
+ ( typename Slist::const_iterator it
+ , const bucket_impl &first_bucket
+ , const bucket_impl &last_bucket)
+ {
+ typename Slist::const_iterator
first(first_bucket.cend()), last(last_bucket.cend());
//The end node is embedded in the singly linked list:
@@ -81,252 +83,130 @@ struct bucket_type_impl
it.pointed_node() <= last.pointed_node())){
++it;
}
- //Now get the bucket_type_impl from the iterator
- const bucket_type_impl &b = static_cast
- (SlistImpl::container_from_end_iterator(it));
+ //Now get the bucket_impl from the iterator
+ const bucket_impl &b = static_cast
+ (Slist::container_from_end_iterator(it));
//Now just calculate the index b has in the bucket array
return &b - &first_bucket;
}
-
- static SlistImpl &bucket_to_slist(bucket_type_impl &b)
- { return static_cast(b); }
-
- static const SlistImpl &bucket_to_slist(const bucket_type_impl &b)
- { return static_cast(b); }
};
-template
-struct bucket_info_impl
+template
+struct bucket_traits_impl
{
+ /// @cond
typedef typename boost::pointer_to_other
- < typename SlistImpl::pointer
- , bucket_type_impl >::type bucket_ptr;
- typedef typename SlistImpl::size_type size_type;
+ < typename Slist::pointer, bucket_impl >::type bucket_ptr;
+ typedef typename Slist::size_type size_type;
+ /// @endcond
+
+ bucket_traits_impl(bucket_ptr buckets, size_type len)
+ : buckets_(buckets), buckets_len_(len)
+ {}
+
+ bucket_ptr bucket_begin() const
+ { return buckets_; }
+
+ size_type bucket_count() const
+ { return buckets_len_; }
+
+ private:
bucket_ptr buckets_;
size_type buckets_len_;
};
-#ifdef BOOST_INTRUSIVE_USE_ITERATOR_FACADE
-
-template
+template
class hashtable_iterator
- : public boost::iterator_facade
- < hashtable_iterator
- , Value
- , boost::forward_traversal_tag
- , Value&
- , typename std::iterator_traits::difference_type
+ : public std::iterator
+ < std::forward_iterator_tag
+ , typename detail::add_const_if_c
+ ::type
>
{
- typedef typename SlistImpl::iterator local_iterator;
- typedef typename SlistImpl::const_iterator const_local_iterator;
- typedef typename SlistImpl::value_traits::node_ptr node_ptr;
- typedef typename SlistImpl::value_traits::const_node_ptr const_node_ptr;
-
- typedef bucket_type_impl bucket_type;
+ typedef typename Container::real_value_traits real_value_traits;
+ typedef typename Container::siterator siterator;
+ typedef typename Container::const_siterator const_siterator;
+ typedef typename Container::bucket_type bucket_type;
typedef typename boost::pointer_to_other
- < typename SlistImpl::pointer, bucket_type>::type bucket_ptr;
- typedef typename boost::pointer_to_other
- < typename SlistImpl::pointer, const bucket_type>::type const_bucket_ptr;
- typedef detail::bucket_info_impl bucket_info_t;
- typedef typename boost::pointer_to_other
- ::type bucket_info_ptr;
- typedef typename boost::pointer_to_other
- ::type const_bucket_info_ptr;
- typedef typename SlistImpl::size_type size_type;
- struct enabler {};
+ < typename Container::pointer, const Container>::type const_cont_ptr;
+ typedef typename Container::size_type size_type;
public:
- hashtable_iterator ()
- {}
-
- explicit hashtable_iterator(local_iterator ptr, const_bucket_info_ptr bucket_info)
- : local_it_ (ptr), bucket_info_ (bucket_info)
- {}
-
-
- #ifdef BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE
- template
- hashtable_iterator(hashtable_iterator const& other
- ,typename boost::enable_if<
- boost::is_convertible
- , enabler
- >::type = enabler()
- )
- : local_it_(other.local_it_), bucket_info_(other.bucket_info_)
- {}
- #else
- template
- hashtable_iterator(hashtable_iterator const& other,
- typename enable_if<
- is_convertible
- >::type* = 0)
- : local_it_(other.local_it_), bucket_info_(other.bucket_info_)
- {}
- #endif
-
- const local_iterator &local() const
- { return local_it_; }
-
- const_node_ptr pointed_node() const
- { return local_it_.pointed_node(); }
-
- const const_bucket_info_ptr &bucket_info() const
- { return bucket_info_; }
-
- private:
- friend class boost::iterator_core_access;
- template friend class hashtable_iterator;
-
- template
- bool equal(hashtable_iterator const& other) const
- { return other.local() == local_it_; }
-
- void increment()
- {
- size_type buckets_len = bucket_info_->buckets_len_;
- const_bucket_ptr buckets = bucket_info_->buckets_;
- const_local_iterator first = bucket_type::bucket_to_slist(buckets[0]).cend();
- const_local_iterator last = bucket_type::bucket_to_slist(buckets[buckets_len]).cend();
-
- ++local_it_;
- if(first.pointed_node() <= local_it_.pointed_node() &&
- local_it_.pointed_node() <= last.pointed_node()){
- size_type n_bucket = (size_type)
- bucket_type::get_bucket_num(local_it_, buckets[0], buckets[buckets_len]);
- do{
- if (++n_bucket == buckets_len){
- local_it_ = bucket_info_->buckets_->end();
- break;
- }
- local_it_ = bucket_type::bucket_to_slist(bucket_info_->buckets_[n_bucket]).begin();
- }
- while (local_it_ == bucket_type::bucket_to_slist(bucket_info_->buckets_[n_bucket]).end());
- }
- }
-
- Value& dereference() const
- { return *local_it_; }
-
- local_iterator local_it_;
- const_bucket_info_ptr bucket_info_;
-};
-
-#else
-
-template
-class hashtable_iterator
- : public std::iterator
-{
- typedef typename SlistImpl::iterator local_iterator;
- typedef typename SlistImpl::const_iterator const_local_iterator;
- typedef typename SlistImpl::value_traits::node_ptr node_ptr;
- typedef typename SlistImpl::value_traits::const_node_ptr const_node_ptr;
-
- typedef bucket_type_impl bucket_type;
- typedef typename boost::pointer_to_other
- < typename SlistImpl::pointer, bucket_type>::type bucket_ptr;
- typedef typename boost::pointer_to_other
- < typename SlistImpl::pointer, const bucket_type>::type const_bucket_ptr;
- typedef detail::bucket_info_impl bucket_info_t;
- typedef typename boost::pointer_to_other
- ::type bucket_info_ptr;
- typedef typename boost::pointer_to_other
- ::type const_bucket_info_ptr;
- typedef typename SlistImpl::size_type size_type;
- struct enabler {};
-
- public:
- typedef T & reference;
- typedef T * pointer;
+ typedef typename detail::add_const_if_c
+ ::type value_type;
hashtable_iterator ()
{}
- explicit hashtable_iterator(local_iterator ptr, const_bucket_info_ptr bucket_info)
- : local_it_ (ptr), bucket_info_ (bucket_info)
+ explicit hashtable_iterator(siterator ptr, const Container *cont)
+ : slist_it_ (ptr), cont_ (cont)
{}
-
- #ifdef BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE
- template
- hashtable_iterator(hashtable_iterator const& other
- ,typename boost::enable_if<
- boost::is_convertible
- , enabler
- >::type = enabler()
- )
- : local_it_(other.local_it_), bucket_info_(other.bucket_info_)
+ hashtable_iterator(const hashtable_iterator &other)
+ : slist_it_(other.slist_it()), cont_(other.get_container())
{}
- #else
- template
- hashtable_iterator(hashtable_iterator const& other,
- typename enable_if >::type* = 0)
- : local_it_(other.local_it_), bucket_info_(other.bucket_info_)
- {}
- #endif
- const local_iterator &local() const
- { return local_it_; }
-
- const_node_ptr pointed_node() const
- { return local_it_.pointed_node(); }
-
- const const_bucket_info_ptr &bucket_info() const
- { return bucket_info_; }
+ const siterator &slist_it() const
+ { return slist_it_; }
public:
hashtable_iterator& operator++()
- { increment(); return *this; }
+ { this->increment(); return *this; }
hashtable_iterator operator++(int)
{
hashtable_iterator result (*this);
- increment();
+ this->increment();
return result;
}
friend bool operator== (const hashtable_iterator& i, const hashtable_iterator& i2)
- { return i.pointed_node() == i2.pointed_node(); }
+ { return i.slist_it_ == i2.slist_it_; }
friend bool operator!= (const hashtable_iterator& i, const hashtable_iterator& i2)
{ return !(i == i2); }
- T& operator*() const
- { return *local_it_; }
+ value_type& operator*() const
+ { return *this->operator ->(); }
- pointer operator->() const
- { return &(*local_it_); }
+ value_type* operator->() const
+ { return detail::get_pointer(this->get_real_value_traits()->to_value_ptr(slist_it_.pointed_node())); }
+
+ const Container *get_container() const
+ { return detail::get_pointer(cont_); }
+
+ const real_value_traits *get_real_value_traits() const
+ { return &this->get_container()->get_real_value_traits(); }
private:
void increment()
{
- size_type buckets_len = bucket_info_->buckets_len_;
- const_bucket_ptr buckets = bucket_info_->buckets_;
- const_local_iterator first = bucket_type::bucket_to_slist(buckets[0]).cend();
- const_local_iterator last = bucket_type::bucket_to_slist(buckets[buckets_len]).cend();
+ const Container *cont = detail::get_pointer(cont_);
+ bucket_type* buckets = detail::get_pointer(cont->bucket_pointer());
+ size_type buckets_len = cont->bucket_count();
+ const_siterator first(buckets[0].cend());
+ const_siterator last (buckets[buckets_len].cend());
- ++local_it_;
- if(first.pointed_node() <= local_it_.pointed_node() &&
- local_it_.pointed_node() <= last.pointed_node()){
+ ++slist_it_;
+ if(first.pointed_node() <= slist_it_.pointed_node() &&
+ slist_it_.pointed_node()<= last.pointed_node() ){
size_type n_bucket = (size_type)
- bucket_type::get_bucket_num(local_it_, buckets[0], buckets[buckets_len]);
+ bucket_type::get_bucket_num(slist_it_, buckets[0], buckets[buckets_len]);
do{
if (++n_bucket == buckets_len){
- local_it_ = bucket_info_->buckets_->end();
+ slist_it_ = buckets->end();
break;
}
- local_it_ = bucket_type::bucket_to_slist(bucket_info_->buckets_[n_bucket]).begin();
+ slist_it_ = buckets[n_bucket].begin();
}
- while (local_it_ == bucket_type::bucket_to_slist(bucket_info_->buckets_[n_bucket]).end());
+ while (slist_it_ == buckets[n_bucket].end());
}
}
- local_iterator local_it_;
- const_bucket_info_ptr bucket_info_;
+ siterator slist_it_;
+ const_cont_ptr cont_;
};
-#endif
} //namespace detail {
} //namespace intrusive {
diff --git a/include/boost/intrusive/detail/list_node.hpp b/include/boost/intrusive/detail/list_node.hpp
index 03c8927..ec48a6d 100644
--- a/include/boost/intrusive/detail/list_node.hpp
+++ b/include/boost/intrusive/detail/list_node.hpp
@@ -19,35 +19,31 @@
#include
#include
#include
-#ifdef BOOST_INTRUSIVE_USE_ITERATOR_FACADE
-#include
-#endif
-#ifdef BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE
-#include
-#include
-#endif
namespace boost {
namespace intrusive {
-namespace detail {
// list_node_traits can be used with circular_list_algorithms and supplies
// a list_node holding the pointers needed for a double-linked list
// it is used by list_derived_node and list_member_node
+
+template
+struct list_node
+{
+ typedef typename boost::pointer_to_other
+ ::type node_ptr;
+ node_ptr prev_, next_;
+};
+
template
struct list_node_traits
{
- struct node;
+ typedef list_node node;
typedef typename boost::pointer_to_other
::type node_ptr;
typedef typename boost::pointer_to_other
::type const_node_ptr;
- struct node
- {
- node_ptr prev_, next_;
- };
-
static node_ptr get_previous(const_node_ptr n)
{ return n->prev_; }
@@ -61,178 +57,126 @@ struct list_node_traits
{ n->next_ = next; }
};
-#ifdef BOOST_INTRUSIVE_USE_ITERATOR_FACADE
-
-// list_iterator provides some basic functions for a
-// node oriented forward iterator:
-template
-class list_iterator
- : public boost::iterator_facade
- < list_iterator
- , T
- , boost::bidirectional_traversal_tag
- , T&
- , typename std::iterator_traits::difference_type
- >
-{
- typedef typename ValueTraits::node_traits node_traits;
- typedef typename node_traits::node node;
- typedef typename node_traits::node_ptr node_ptr;
- typedef typename node_traits::const_node_ptr const_node_ptr;
- struct enabler{};
-
- public:
- typedef typename pointer_to_other::type pointer;
- typedef typename std::iterator_traits::difference_type difference_type;
-
- list_iterator ()
- : node_ (0)
- {}
-
- explicit list_iterator(node_ptr node)
- : node_ (node)
- {}
-
- #ifdef BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE
- template
- list_iterator(list_iterator const& other
- ,typename boost::enable_if<
- boost::is_convertible
- , enabler
- >::type = enabler()
- )
- : node_(other.pointed_node())
- {}
- #else
- template
- list_iterator(list_iterator const& other,
- typename enable_if<
- is_convertible
- >::type* = 0)
- : node_(other.pointed_node())
- {}
- #endif
-
- const node_ptr &pointed_node() const
- { return node_; }
-
- private:
- friend class boost::iterator_core_access;
- template friend class list_iterator;
-
- template
- bool equal(list_iterator const& other) const
- { return other.pointed_node() == node_; }
-
- void increment()
- { node_ = node_traits::get_next(node_); }
-
- void decrement()
- { node_ = node_traits::get_previous(node_); }
-
- T& dereference() const
- { return *ValueTraits::to_value_ptr(node_); }
-
- node_ptr node_;
-};
-
-#else //BOOST_INTRUSIVE_USE_ITERATOR_FACADE
-
// list_iterator provides some basic functions for a
// node oriented bidirectional iterator:
-template
+template
class list_iterator
- : public std::iterator
+ : public std::iterator
+ < std::bidirectional_iterator_tag
+ , typename detail::add_const_if_c
+ ::type
+ >
{
- struct enabler{};
protected:
- typedef typename ValueTraits::node_traits node_traits;
- typedef typename node_traits::node node;
- typedef typename node_traits::node_ptr node_ptr;
-
+ typedef typename Container::real_value_traits real_value_traits;
+ typedef typename real_value_traits::node_traits node_traits;
+ typedef typename node_traits::node node;
+ typedef typename node_traits::node_ptr node_ptr;
+ typedef typename boost::pointer_to_other
+ ::type void_pointer;
+ static const bool store_container_ptr =
+ detail::store_cont_ptr_on_it::value;
+
public:
- typedef T & reference;
- typedef T * pointer;
+ typedef typename detail::add_const_if_c
+
+ ::type value_type;
+ typedef value_type & reference;
+ typedef value_type * pointer;
list_iterator()
- : node_ (0)
+ : members_ (0, 0)
{}
- explicit list_iterator(node_ptr node)
- : node_ (node)
+ explicit list_iterator(node_ptr node, const Container *cont_ptr)
+ : members_ (node, cont_ptr)
{}
- #ifdef BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE
- template
- list_iterator(list_iterator const& other
- ,typename boost::enable_if<
- boost::is_convertible
- , enabler
- >::type = enabler()
- )
- : node_(other.pointed_node())
+
+ list_iterator(list_iterator const& other)
+ : members_(other.pointed_node(), other.get_container())
{}
- #else
- template
- list_iterator(list_iterator const& other,
- typename enable_if<
- is_convertible
- >::type* = 0)
- : node_(other.pointed_node())
- {}
- #endif
const node_ptr &pointed_node() const
- { return node_; }
+ { return members_.nodeptr_; }
list_iterator &operator=(const node_ptr &node)
- { node_ = node; return static_cast(*this); }
+ { members_.nodeptr_ = node; return static_cast(*this); }
public:
list_iterator& operator++()
{
- node_ = node_traits::get_next(node_);
+ members_.nodeptr_ = node_traits::get_next(members_.nodeptr_);
return static_cast (*this);
}
list_iterator operator++(int)
{
- list_iterator result (node_);
- node_ = node_traits::get_next(node_);
+ list_iterator result (*this);
+ members_.nodeptr_ = node_traits::get_next(members_.nodeptr_);
return result;
}
list_iterator& operator--()
{
- node_ = node_traits::get_previous(node_);
+ members_.nodeptr_ = node_traits::get_previous(members_.nodeptr_);
return static_cast (*this);
}
list_iterator operator--(int)
{
- list_iterator result (node_);
- node_ = node_traits::get_previous(node_);
+ list_iterator result (*this);
+ members_.nodeptr_ = node_traits::get_previous(members_.nodeptr_);
return result;
}
bool operator== (const list_iterator& i) const
- { return node_ == i.pointed_node(); }
+ { return members_.nodeptr_ == i.pointed_node(); }
bool operator!= (const list_iterator& i) const
- { return !operator== (i); }
+ { return !operator== (i); }
- T& operator*() const
- { return *ValueTraits::to_value_ptr(node_); }
+ value_type& operator*() const
+ { return *operator->(); }
pointer operator->() const
- { return detail::get_pointer(ValueTraits::to_value_ptr(node_)); }
+ { return detail::get_pointer(this->get_real_value_traits()->to_value_ptr(members_.nodeptr_)); }
+
+ const Container *get_container() const
+ {
+ if(store_container_ptr){
+ const Container* c = static_cast(members_.get_ptr());
+ BOOST_INTRUSIVE_INVARIANT_ASSERT(c != 0);
+ return c;
+ }
+ else{
+ return 0;
+ }
+ }
+
+ const real_value_traits *get_real_value_traits() const
+ {
+ if(store_container_ptr)
+ return &this->get_container()->get_real_value_traits();
+ else
+ return 0;
+ }
private:
- node_ptr node_;
+ struct members
+ : public detail::select_constptr
+ ::type
+ {
+ typedef typename detail::select_constptr
+ ::type Base;
+
+ members(const node_ptr &n_ptr, const void *cont)
+ : Base(cont), nodeptr_(n_ptr)
+ {}
+
+ node_ptr nodeptr_;
+ } members_;
};
-#endif
-
-} //namespace detail
} //namespace intrusive
} //namespace boost
diff --git a/include/boost/intrusive/detail/mpl.hpp b/include/boost/intrusive/detail/mpl.hpp
index 821c640..f4fd3f6 100644
--- a/include/boost/intrusive/detail/mpl.hpp
+++ b/include/boost/intrusive/detail/mpl.hpp
@@ -17,6 +17,9 @@ namespace boost {
namespace intrusive {
namespace detail {
+typedef char one;
+struct two {one _[2];};
+
template< bool C_ >
struct bool_
{
@@ -55,7 +58,61 @@ class is_convertible
static false_t dispatch(...);
static T trigger();
public:
- enum { value = sizeof(dispatch(trigger())) == sizeof(true_t) };
+ static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t);
+};
+
+template<
+ bool C
+ , typename T1
+ , typename T2
+ >
+struct if_c
+{
+ typedef T1 type;
+};
+
+template<
+ typename T1
+ , typename T2
+ >
+struct if_c
+{
+ typedef T2 type;
+};
+
+template<
+ typename C
+ , typename T1
+ , typename T2
+ >
+struct if_
+{
+ typedef typename if_c<0 != C::value, T1, T2>::type type;
+};
+
+template<
+ bool C
+ , typename F1
+ , typename F2
+ >
+struct eval_if_c
+ : if_c::type
+{};
+
+template<
+ typename C
+ , typename T1
+ , typename T2
+ >
+struct eval_if
+ : if_::type
+{};
+
+// identity is an extension: it is not part of the standard.
+template
+struct identity
+{
+ typedef T type;
};
#if defined(BOOST_MSVC) || defined(__BORLANDC_)
@@ -130,18 +187,20 @@ yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1));
template
struct is_unary_or_binary_function_impl
{
- static T* t;
- enum{ value = sizeof(is_function_ptr_tester(t)) == sizeof(yes_type) };
+ static T* t;
+ static const bool value = sizeof(is_function_ptr_tester(t)) == sizeof(yes_type);
};
template
struct is_unary_or_binary_function_impl
-{ enum {value = false }; };
+{
+ static const bool value = false;
+};
template
struct is_unary_or_binary_function
{
- enum{ value = is_unary_or_binary_function_impl::value };
+ static const bool value = is_unary_or_binary_function_impl::value;
};
//boost::alignment_of yields to 10K lines of preprocessed code, so we
@@ -159,15 +218,68 @@ struct alignment_of_hack
template
struct alignment_logic
{
- enum{ value = A < S ? A : S };
+ static const std::size_t value = A < S ? A : S;
};
template< typename T >
struct alignment_of
{
- enum{ value = alignment_logic
+ static const std::size_t value = alignment_logic
< sizeof(alignment_of_hack) - sizeof(T)
- , sizeof(T)>::value };
+ , sizeof(T)
+ >::value;
+};
+
+template
+struct is_same
+{
+ typedef char yes_type;
+ struct no_type
+ {
+ char padding[8];
+ };
+
+ template
+ static yes_type is_same_tester(V*, V*);
+ static no_type is_same_tester(...);
+
+ static T *t;
+ static U *u;
+
+ static const bool value = sizeof(yes_type) == sizeof(is_same_tester(t,u));
+};
+
+template
+struct add_const
+{ typedef const T type; };
+
+template
+struct remove_reference
+{
+ typedef T type;
+};
+
+template
+struct remove_reference
+{
+ typedef T type;
+};
+
+template
+class is_empty_class
+{
+ template
+ struct empty_helper_t1 : public T
+ {
+ empty_helper_t1();
+ int i[256];
+ };
+
+ struct empty_helper_t2
+ { int i[256]; };
+
+ public:
+ static const bool value = sizeof(empty_helper_t1) == sizeof(empty_helper_t2);
};
} //namespace detail
diff --git a/include/boost/intrusive/detail/no_exceptions_support.hpp b/include/boost/intrusive/detail/no_exceptions_support.hpp
new file mode 100644
index 0000000..4344684
--- /dev/null
+++ b/include/boost/intrusive/detail/no_exceptions_support.hpp
@@ -0,0 +1,28 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007
+//
+// 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_NO_EXCEPTION_SUPPORT_HPP
+
+#if !(defined BOOST_INTRUSIVE_DISABLE_EXCEPTION_HANDLING)
+# include
+# define BOOST_INTRUSIVE_TRY BOOST_TRY
+# define BOOST_INTRUSIVE_CATCH(x) BOOST_CATCH(x)
+# define BOOST_INTRUSIVE_RETHROW BOOST_RETHROW
+# define BOOST_INTRUSIVE_CATCH_END BOOST_CATCH_END
+#else
+# define BOOST_INTRUSIVE_TRY { if (true)
+# define BOOST_INTRUSIVE_CATCH(x) else if (false)
+# define BOOST_INTRUSIVE_RETHROW
+# define BOOST_INTRUSIVE_CATCH_END }
+#endif
+
+#endif //#ifndef BOOST_INTRUSIVE_NO_EXCEPTION_SUPPORT_HPP
diff --git a/include/boost/intrusive/detail/parent_from_member.hpp b/include/boost/intrusive/detail/parent_from_member.hpp
index c0225ae..4a5d48a 100644
--- a/include/boost/intrusive/detail/parent_from_member.hpp
+++ b/include/boost/intrusive/detail/parent_from_member.hpp
@@ -13,6 +13,7 @@
#define BOOST_INTRUSIVE_PARENT_FROM_MEMBER_HPP
#include
+#include
#include
namespace boost {
@@ -22,14 +23,18 @@ namespace detail {
template
inline std::size_t offset_from_pointer_to_member(const Member Parent::* ptr_to_member)
{
+ //BOOST_STATIC_ASSERT(( sizeof(std::ptrdiff_t) == sizeof(ptr_to_member) ));
//The implementation of a pointer to member is compiler dependent.
- #if (defined(_MSC_VER) || defined(__GNUC__) || \
- defined(BOOST_INTEL) || defined(__HP_aCC))
- //This works with gcc, msvc, ac++
+ #if defined(BOOST_MSVC) || (defined (BOOST_WINDOWS) && defined(BOOST_INTEL))
+ //This works with gcc, msvc, ac++, ibmcpp
return *(const std::ptrdiff_t*)(void*)&ptr_to_member;
+ #elif defined(__GNUC__) || defined(__HP_aCC) || defined(BOOST_INTEL) || defined (__IBMCPP__)
+ const Parent * const parent = 0;
+ const char *const member = reinterpret_cast(&(parent->*ptr_to_member));
+ return std::size_t(member - reinterpret_cast(parent));
#else
//This is the traditional C-front approach: __MWERKS__, __DMC__, __SUNPRO_CC
- return *(const std::ptrdiff_t*)(void*)&ptr_to_member - 1;
+ return (*(const std::ptrdiff_t*)(void*)&ptr_to_member) - 1;
#endif
}
diff --git a/include/boost/intrusive/detail/rbtree_node.hpp b/include/boost/intrusive/detail/rbtree_node.hpp
index 12eab42..55a9110 100644
--- a/include/boost/intrusive/detail/rbtree_node.hpp
+++ b/include/boost/intrusive/detail/rbtree_node.hpp
@@ -18,19 +18,11 @@
#include
#include
#include
-#ifdef BOOST_INTRUSIVE_USE_ITERATOR_FACADE
-#include
-#endif
-#ifdef BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE
-#include
-#include
-#endif
#include
#include
namespace boost {
namespace intrusive {
-namespace detail {
/////////////////////////////////////////////////////////////////////////////
// //
@@ -164,14 +156,14 @@ struct rbtree_node_traits_dispatch
: public compact_rbtree_node_traits_impl
{};
-//Inherit from the dispatcher depending on the embedding capabilities
+//Inherit from the detail::link_dispatch depending on the embedding capabilities
template
struct rbtree_node_traits
: public rbtree_node_traits_dispatch
-
- >::value
+ < VoidPointer
+ , has_pointer_plus_bit
+ < VoidPointer
+ , detail::alignment_of >::value
>::value
>
{};
@@ -182,179 +174,124 @@ struct rbtree_node_traits
// //
/////////////////////////////////////////////////////////////////////////////
-#ifdef BOOST_INTRUSIVE_USE_ITERATOR_FACADE
-
-template
-class rbtree_iterator
- : public boost::iterator_facade
- < rbtree_iterator
- , T
- , boost::bidirectional_traversal_tag
- , T&
- , typename std::iterator_traits::difference_type
- >
-{
- typedef typename ValueTraits::node_traits node_traits;
- typedef typename node_traits::node node;
- typedef typename node_traits::node_ptr node_ptr;
- typedef typename node_traits::const_node_ptr const_node_ptr;
- typedef rbtree_algorithms node_algorithms;
- struct enabler{};
-
- public:
- typedef typename pointer_to_other::type pointer;
- typedef typename std::iterator_traits::difference_type difference_type;
-
- rbtree_iterator ()
- : node_ (0)
- {}
-
- explicit rbtree_iterator(node_ptr node)
- : node_ (node)
- {}
-
- #ifdef BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE
- template
- rbtree_iterator(rbtree_iterator const& other
- ,typename boost::enable_if<
- boost::is_convertible
- , enabler
- >::type = enabler()
- )
- : node_(other.pointed_node())
- {}
- #else
- template
- rbtree_iterator(rbtree_iterator const& other,
- typename enable_if<
- is_convertible
- >::type* = 0)
- : node_(other.pointed_node())
- {}
- #endif
-
- const node_ptr &pointed_node() const
- { return node_; }
-
- private:
- friend class boost::iterator_core_access;
- template friend class rbtree_iterator;
-
- template
- bool equal(rbtree_iterator const& other) const
- { return other.pointed_node() == node_; }
-
- void increment()
- { node_ = node_algorithms::next_node(node_); }
-
- void decrement()
- { node_ = node_algorithms::prev_node(node_); }
-
- T& dereference() const
- { return *ValueTraits::to_value_ptr(node_); }
-
- node_ptr node_;
-};
-
-#else
-
// rbtree_iterator provides some basic functions for a
// node oriented bidirectional iterator:
-template
+template
class rbtree_iterator
- : public std::iterator
+ : public std::iterator
+ < std::bidirectional_iterator_tag
+ , typename detail::add_const_if_c
+ ::type
+ >
{
- struct enabler{};
protected:
- typedef typename ValueTraits::node_traits node_traits;
- typedef typename node_traits::node node;
- typedef typename node_traits::node_ptr node_ptr;
- typedef rbtree_algorithms node_algorithms;
-
+ typedef typename Container::real_value_traits real_value_traits;
+ typedef typename real_value_traits::node_traits node_traits;
+ typedef typename node_traits::node node;
+ typedef typename node_traits::node_ptr node_ptr;
+ typedef rbtree_algorithms node_algorithms;
+ typedef typename boost::pointer_to_other
+ ::type void_pointer;
+ static const bool store_container_ptr =
+ detail::store_cont_ptr_on_it::value;
+
public:
- typedef T & reference;
- typedef T * pointer;
+ public:
+ typedef typename detail::add_const_if_c
+
+ ::type value_type;
+ typedef value_type & reference;
+ typedef value_type * pointer;
rbtree_iterator()
- : node_ (0)
+ : members_ (0, 0)
{}
- explicit rbtree_iterator(node_ptr node)
- : node_ (node)
+ explicit rbtree_iterator(node_ptr node, const Container *cont_ptr)
+ : members_ (node, cont_ptr)
{}
- #ifdef BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE
- template
- rbtree_iterator(rbtree_iterator const& other
- ,typename boost::enable_if<
- boost::is_convertible
- , enabler
- >::type = enabler()
- )
- : node_(other.pointed_node())
+ rbtree_iterator(rbtree_iterator const& other)
+ : members_(other.pointed_node(), other.get_container())
{}
- #else
- template
- rbtree_iterator(rbtree_iterator const& other,
- typename enable_if<
- is_convertible
- >::type* = 0)
- : node_(other.pointed_node())
- {}
- #endif
const node_ptr &pointed_node() const
- { return node_; }
+ { return members_.nodeptr_; }
rbtree_iterator &operator=(const node_ptr &node)
- { node_ = node; return static_cast(*this); }
+ { members_.nodeptr_ = node; return static_cast(*this); }
public:
rbtree_iterator& operator++()
{
- node_ = node_algorithms::next_node(node_);
+ members_.nodeptr_ = node_algorithms::next_node(members_.nodeptr_);
return static_cast (*this);
}
rbtree_iterator operator++(int)
{
- rbtree_iterator result (node_);
- node_ = node_algorithms::next_node(node_);
+ rbtree_iterator result (*this);
+ members_.nodeptr_ = node_algorithms::next_node(members_.nodeptr_);
return result;
}
rbtree_iterator& operator--()
{
- node_ = node_algorithms::prev_node(node_);
+ members_.nodeptr_ = node_algorithms::prev_node(members_.nodeptr_);
return static_cast (*this);
}
rbtree_iterator operator--(int)
{
- rbtree_iterator result (node_);
- node_ = node_algorithms::prev_node(node_);
+ rbtree_iterator result (*this);
+ members_.nodeptr_ = node_algorithms::prev_node(members_.nodeptr_);
return result;
}
bool operator== (const rbtree_iterator& i) const
- { return node_ == i.pointed_node(); }
+ { return members_.nodeptr_ == i.pointed_node(); }
bool operator!= (const rbtree_iterator& i) const
{ return !operator== (i); }
- T& operator*() const
- { return *ValueTraits::to_value_ptr(node_); }
+ value_type& operator*() const
+ { return *operator->(); }
pointer operator->() const
- { return detail::get_pointer(ValueTraits::to_value_ptr(node_)); }
+ { return detail::get_pointer(this->get_real_value_traits()->to_value_ptr(members_.nodeptr_)); }
+
+ const Container *get_container() const
+ {
+ if(store_container_ptr)
+ return static_cast(members_.get_ptr());
+ else
+ return 0;
+ }
+
+ const real_value_traits *get_real_value_traits() const
+ {
+ if(store_container_ptr)
+ return &this->get_container()->get_real_value_traits();
+ else
+ return 0;
+ }
private:
- node_ptr node_;
+ struct members
+ : public detail::select_constptr
+ ::type
+ {
+ typedef typename detail::select_constptr
+ ::type Base;
+
+ members(const node_ptr &n_ptr, const void *cont)
+ : Base(cont), nodeptr_(n_ptr)
+ {}
+
+ node_ptr nodeptr_;
+ } members_;
};
-#endif
-
-} //namespace detail
} //namespace intrusive
} //namespace boost
diff --git a/include/boost/intrusive/detail/slist_node.hpp b/include/boost/intrusive/detail/slist_node.hpp
index a22c117..a5d8883 100644
--- a/include/boost/intrusive/detail/slist_node.hpp
+++ b/include/boost/intrusive/detail/slist_node.hpp
@@ -19,17 +19,17 @@
#include
#include
#include
-#ifdef BOOST_INTRUSIVE_USE_ITERATOR_FACADE
-#include
-#endif
-#ifdef BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE
-#include
-#include
-#endif
namespace boost {
namespace intrusive {
-namespace detail {
+
+template
+struct slist_node
+{
+ typedef typename boost::pointer_to_other
+ ::type node_ptr;
+ node_ptr next_;
+};
// slist_node_traits can be used with circular_slist_algorithms and supplies
// a slist_node holding the pointers needed for a singly-linked list
@@ -37,18 +37,12 @@ namespace detail {
template
struct slist_node_traits
{
- struct node;
-
+ typedef slist_node node;
typedef typename boost::pointer_to_other
::type node_ptr;
typedef typename boost::pointer_to_other
::type const_node_ptr;
- struct node
- {
- node_ptr next_;
- };
-
static node_ptr get_next(const_node_ptr n)
{ return n->next_; }
@@ -56,163 +50,109 @@ struct slist_node_traits
{ n->next_ = next; }
};
-#ifdef BOOST_INTRUSIVE_USE_ITERATOR_FACADE
-
-// slist_iterator provides some basic functions for a
-// node oriented forward iterator:
-template
-class slist_iterator
- : public boost::iterator_facade
- < slist_iterator
- , T
- , boost::forward_traversal_tag
- , T&
- , typename std::iterator_traits::difference_type
- >
-{
- typedef typename ValueTraits::node_traits node_traits;
- typedef typename node_traits::node node;
- typedef typename node_traits::node_ptr node_ptr;
- typedef typename node_traits::const_node_ptr const_node_ptr;
- struct enabler{};
-
- public:
- typedef typename pointer_to_other::type pointer;
- typedef typename std::iterator_traits::difference_type difference_type;
-
- slist_iterator ()
- : node_ (0)
- {}
-
- explicit slist_iterator(node_ptr node)
- : node_ (node)
- {}
-
- #ifdef BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE
- template
- slist_iterator(slist_iterator const& other
- ,typename boost::enable_if<
- boost::is_convertible
- , enabler
- >::type = enabler()
- )
- : node_(other.pointed_node())
- {}
- #else
- template
- slist_iterator(slist_iterator const& other,
- typename enable_if<
- is_convertible
- >::type* = 0)
- : node_(other.pointed_node())
- {}
- #endif
-
- const node_ptr &pointed_node() const
- { return node_; }
-
- private:
- friend class boost::iterator_core_access;
- template friend class slist_iterator;
-
- template
- bool equal(slist_iterator const& other) const
- { return other.pointed_node() == node_; }
-
- void increment()
- { node_ = node_traits::get_next(node_); }
-
- T& dereference() const
- { return *ValueTraits::to_value_ptr(node_); }
-
- node_ptr node_;
-};
-
-#else
-
// slist_iterator provides some basic functions for a
// node oriented bidirectional iterator:
-template