Reduced compile-time dependencies, headers, and the use of Boost.Preprocessor, specially for hooks and iterators.

This commit is contained in:
Ion Gaztañaga
2014-12-08 15:48:08 +01:00
parent adda517544
commit a4f0c0c7b3
19 changed files with 428 additions and 398 deletions

View File

@ -3761,6 +3761,12 @@ to be inserted in intrusive containers are allocated using `std::vector` or `std
[section:release_notes Release Notes] [section:release_notes Release Notes]
[section:release_notes_boost_1_58_00 Boost 1.58 Release]
* Reduced compile-time dependencies, headers, and the use of Boost.Preprocessor, specially for hooks and iterators.
[endsect]
[section:release_notes_boost_1_57_00 Boost 1.57 Release] [section:release_notes_boost_1_57_00 Boost 1.57 Release]
* Experimental version of node checkers, contributed by Matei David. Many thanks! * Experimental version of node checkers, contributed by Matei David. Many thanks!

View File

@ -20,6 +20,7 @@
#include <cstddef> #include <cstddef>
#include <boost/intrusive/detail/config_begin.hpp> #include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/intrusive_fwd.hpp> #include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/intrusive/detail/bstree_algorithms_base.hpp>
#include <boost/intrusive/detail/assert.hpp> #include <boost/intrusive/detail/assert.hpp>
#include <boost/intrusive/detail/uncast.hpp> #include <boost/intrusive/detail/uncast.hpp>
#include <boost/intrusive/detail/math.hpp> #include <boost/intrusive/detail/math.hpp>
@ -167,7 +168,7 @@ struct bstree_node_checker
//! //!
//! <tt>static void set_right(node_ptr n, node_ptr right);</tt> //! <tt>static void set_right(node_ptr n, node_ptr right);</tt>
template<class NodeTraits> template<class NodeTraits>
class bstree_algorithms class bstree_algorithms : public bstree_algorithms_base<NodeTraits>
{ {
public: public:
typedef typename NodeTraits::node node; typedef typename NodeTraits::node node;
@ -178,7 +179,8 @@ class bstree_algorithms
typedef data_for_rebalance_t<node_ptr> data_for_rebalance; typedef data_for_rebalance_t<node_ptr> data_for_rebalance;
/// @cond /// @cond
typedef bstree_algorithms<NodeTraits> this_type;
typedef bstree_algorithms_base<NodeTraits> base_type;
private: private:
template<class Disposer> template<class Disposer>
struct dispose_subtree_disposer struct dispose_subtree_disposer
@ -247,6 +249,7 @@ class bstree_algorithms
static bool unique(const const_node_ptr & node) static bool unique(const const_node_ptr & node)
{ return !NodeTraits::get_parent(node); } { return !NodeTraits::get_parent(node); }
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
//! <b>Requires</b>: 'node' is a node of the tree or a header node. //! <b>Requires</b>: 'node' is a node of the tree or a header node.
//! //!
//! <b>Effects</b>: Returns the header of the tree. //! <b>Effects</b>: Returns the header of the tree.
@ -254,42 +257,8 @@ class bstree_algorithms
//! <b>Complexity</b>: Logarithmic. //! <b>Complexity</b>: Logarithmic.
//! //!
//! <b>Throws</b>: Nothing. //! <b>Throws</b>: Nothing.
static node_ptr get_header(const const_node_ptr & node) static node_ptr get_header(const const_node_ptr & node);
{ #endif
node_ptr n(detail::uncast(node));
node_ptr p(NodeTraits::get_parent(node));
//If p is null, then n is the header of an empty tree
if(p){
//Non-empty tree, check if n is neither root nor header
node_ptr pp(NodeTraits::get_parent(p));
//If granparent is not equal to n, then n is neither root nor header,
//the try the fast path
if(n != pp){
do{
n = p;
p = pp;
pp = NodeTraits::get_parent(pp);
}while(n != pp);
n = p;
}
//Check if n is root or header when size() > 0
else if(!is_header(n)){
n = p;
}
}
return n;
/*
node_ptr h = detail::uncast(node);
node_ptr p = NodeTraits::get_parent(node);
if(p){
while(!is_header(p))
p = NodeTraits::get_parent(p);
return p;
}
else{
return h;
}*/
}
//! <b>Requires</b>: node1 and node2 can't be header nodes //! <b>Requires</b>: node1 and node2 can't be header nodes
//! of two trees. //! of two trees.
@ -311,7 +280,7 @@ class bstree_algorithms
if(node1 == node2) if(node1 == node2)
return; return;
node_ptr header1(get_header(node1)), header2(get_header(node2)); node_ptr header1(base_type::get_header(node1)), header2(base_type::get_header(node2));
swap_nodes(node1, header1, node2, header2); swap_nodes(node1, header1, node2, header2);
} }
@ -481,7 +450,7 @@ class bstree_algorithms
{ {
if(node_to_be_replaced == new_node) if(node_to_be_replaced == new_node)
return; return;
replace_node(node_to_be_replaced, get_header(node_to_be_replaced), new_node); replace_node(node_to_be_replaced, base_type::get_header(node_to_be_replaced), new_node);
} }
//! <b>Requires</b>: node_to_be_replaced must be inserted in a tree //! <b>Requires</b>: node_to_be_replaced must be inserted in a tree
@ -541,6 +510,7 @@ class bstree_algorithms
} }
} }
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
//! <b>Requires</b>: 'node' is a node from the tree except the header. //! <b>Requires</b>: 'node' is a node from the tree except the header.
//! //!
//! <b>Effects</b>: Returns the next node of the tree. //! <b>Effects</b>: Returns the next node of the tree.
@ -548,22 +518,7 @@ class bstree_algorithms
//! <b>Complexity</b>: Average constant time. //! <b>Complexity</b>: Average constant time.
//! //!
//! <b>Throws</b>: Nothing. //! <b>Throws</b>: Nothing.
static node_ptr next_node(const node_ptr & node) static node_ptr next_node(const node_ptr & node);
{
node_ptr const n_right(NodeTraits::get_right(node));
if(n_right){
return minimum(n_right);
}
else {
node_ptr n(node);
node_ptr p(NodeTraits::get_parent(n));
while(n == NodeTraits::get_right(p)){
n = p;
p = NodeTraits::get_parent(p);
}
return NodeTraits::get_right(n) != p ? p : n;
}
}
//! <b>Requires</b>: 'node' is a node from the tree except the leftmost node. //! <b>Requires</b>: 'node' is a node from the tree except the leftmost node.
//! //!
@ -572,25 +527,7 @@ class bstree_algorithms
//! <b>Complexity</b>: Average constant time. //! <b>Complexity</b>: Average constant time.
//! //!
//! <b>Throws</b>: Nothing. //! <b>Throws</b>: Nothing.
static node_ptr prev_node(const node_ptr & node) static node_ptr prev_node(const node_ptr & node);
{
if(is_header(node)){
return NodeTraits::get_right(node);
//return maximum(NodeTraits::get_parent(node));
}
else if(NodeTraits::get_left(node)){
return maximum(NodeTraits::get_left(node));
}
else {
node_ptr p(node);
node_ptr x = NodeTraits::get_parent(p);
while(p == NodeTraits::get_left(x)){
p = x;
x = NodeTraits::get_parent(x);
}
return x;
}
}
//! <b>Requires</b>: 'node' is a node of a tree but not the header. //! <b>Requires</b>: 'node' is a node of a tree but not the header.
//! //!
@ -599,15 +536,7 @@ class bstree_algorithms
//! <b>Complexity</b>: Logarithmic to the size of the subtree. //! <b>Complexity</b>: Logarithmic to the size of the subtree.
//! //!
//! <b>Throws</b>: Nothing. //! <b>Throws</b>: Nothing.
static node_ptr minimum(node_ptr node) static node_ptr minimum(node_ptr node);
{
for(node_ptr p_left = NodeTraits::get_left(node)
;p_left
;p_left = NodeTraits::get_left(node)){
node = p_left;
}
return node;
}
//! <b>Requires</b>: 'node' is a node of a tree but not the header. //! <b>Requires</b>: 'node' is a node of a tree but not the header.
//! //!
@ -616,15 +545,8 @@ class bstree_algorithms
//! <b>Complexity</b>: Logarithmic to the size of the subtree. //! <b>Complexity</b>: Logarithmic to the size of the subtree.
//! //!
//! <b>Throws</b>: Nothing. //! <b>Throws</b>: Nothing.
static node_ptr maximum(node_ptr node) static node_ptr maximum(node_ptr node);
{ #endif
for(node_ptr p_right = NodeTraits::get_right(node)
;p_right
;p_right = NodeTraits::get_right(node)){
node = p_right;
}
return node;
}
//! <b>Requires</b>: 'node' must not be part of any tree. //! <b>Requires</b>: 'node' must not be part of any tree.
//! //!
@ -716,7 +638,7 @@ class bstree_algorithms
if (leftmost_right){ if (leftmost_right){
NodeTraits::set_parent(leftmost_right, leftmost_parent); NodeTraits::set_parent(leftmost_right, leftmost_parent);
NodeTraits::set_left(header, bstree_algorithms::minimum(leftmost_right)); NodeTraits::set_left(header, base_type::minimum(leftmost_right));
if (is_root) if (is_root)
NodeTraits::set_parent(header, leftmost_right); NodeTraits::set_parent(header, leftmost_right);
@ -747,7 +669,7 @@ class bstree_algorithms
node_ptr beg(begin_node(header)); node_ptr beg(begin_node(header));
node_ptr end(end_node(header)); node_ptr end(end_node(header));
std::size_t i = 0; std::size_t i = 0;
for(;beg != end; beg = next_node(beg)) ++i; for(;beg != end; beg = base_type::next_node(beg)) ++i;
return i; return i;
} }
@ -800,6 +722,7 @@ class bstree_algorithms
} }
} }
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
//! <b>Requires</b>: p is a node of a tree. //! <b>Requires</b>: p is a node of a tree.
//! //!
//! <b>Effects</b>: Returns true if p is the header of the tree. //! <b>Effects</b>: Returns true if p is the header of the tree.
@ -807,22 +730,8 @@ class bstree_algorithms
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
//! //!
//! <b>Throws</b>: Nothing. //! <b>Throws</b>: Nothing.
static bool is_header(const const_node_ptr & p) static bool is_header(const const_node_ptr & p);
{ #endif
node_ptr p_left (NodeTraits::get_left(p));
node_ptr p_right(NodeTraits::get_right(p));
if(!NodeTraits::get_parent(p) || //Header condition when empty tree
(p_left && p_right && //Header always has leftmost and rightmost
(p_left == p_right || //Header condition when only node
(NodeTraits::get_parent(p_left) != p ||
NodeTraits::get_parent(p_right) != p ))
//When tree size > 1 headers can't be leftmost's
//and rightmost's parent
)){
return true;
}
return false;
}
//! <b>Requires</b>: "header" must be the header node of a tree. //! <b>Requires</b>: "header" must be the header node of a tree.
//! KeyNodePtrCompare is a function object that induces a strict weak //! KeyNodePtrCompare is a function object that induces a strict weak
@ -940,7 +849,7 @@ class bstree_algorithms
std::size_t n = 0; std::size_t n = 0;
while(ret.first != ret.second){ while(ret.first != ret.second){
++n; ++n;
ret.first = next_node(ret.first); ret.first = base_type::next_node(ret.first);
} }
return n; return n;
} }
@ -985,7 +894,7 @@ class bstree_algorithms
node_ptr const lb(lower_bound(header, key, comp)); node_ptr const lb(lower_bound(header, key, comp));
std::pair<node_ptr, node_ptr> ret_ii(lb, lb); std::pair<node_ptr, node_ptr> ret_ii(lb, lb);
if(lb != header && !comp(key, lb)){ if(lb != header && !comp(key, lb)){
ret_ii.second = next_node(ret_ii.second); ret_ii.second = base_type::next_node(ret_ii.second);
} }
return ret_ii; return ret_ii;
} }
@ -1172,7 +1081,7 @@ class bstree_algorithms
if(hint == header || comp(key, hint)){ if(hint == header || comp(key, hint)){
node_ptr prev(hint); node_ptr prev(hint);
//Previous value should be less than the key //Previous value should be less than the key
if(hint == begin_node(header) || comp((prev = prev_node(hint)), key)){ if(hint == begin_node(header) || comp((prev = base_type::prev_node(hint)), key)){
commit_data.link_left = unique(header) || !NodeTraits::get_left(hint); commit_data.link_left = unique(header) || !NodeTraits::get_left(hint);
commit_data.node = commit_data.link_left ? hint : prev; commit_data.node = commit_data.link_left ? hint : prev;
if(pdepth){ if(pdepth){
@ -1422,7 +1331,7 @@ class bstree_algorithms
{ {
node_ptr x = NodeTraits::get_parent(node); node_ptr x = NodeTraits::get_parent(node);
if(x){ if(x){
while(!is_header(x)) while(!base_type::is_header(x))
x = NodeTraits::get_parent(x); x = NodeTraits::get_parent(x);
erase(x, node); erase(x, node);
} }
@ -1543,7 +1452,7 @@ class bstree_algorithms
} }
else{ //make y != z else{ //make y != z
// y = find z's successor // y = find z's successor
y = bstree_algorithms::minimum(z_right); y = base_type::minimum(z_right);
x = NodeTraits::get_right(y); // x might be null. x = NodeTraits::get_right(y); // x might be null.
} }
@ -1573,14 +1482,14 @@ class bstree_algorithms
x_parent = y; x_parent = y;
} }
NodeTraits::set_parent(y, z_parent); NodeTraits::set_parent(y, z_parent);
bstree_algorithms::set_child(header, y, z_parent, z_is_leftchild); this_type::set_child(header, y, z_parent, z_is_leftchild);
} }
else { // z has zero or one child, x is one child (it can be null) else { // z has zero or one child, x is one child (it can be null)
//Just link x to z's parent //Just link x to z's parent
x_parent = z_parent; x_parent = z_parent;
if(x) if(x)
NodeTraits::set_parent(x, z_parent); NodeTraits::set_parent(x, z_parent);
bstree_algorithms::set_child(header, x, z_parent, z_is_leftchild); this_type::set_child(header, x, z_parent, z_is_leftchild);
//Now update leftmost/rightmost in case z was one of them //Now update leftmost/rightmost in case z was one of them
if(NodeTraits::get_left(header) == z){ if(NodeTraits::get_left(header) == z){
@ -1588,14 +1497,14 @@ class bstree_algorithms
BOOST_ASSERT(!z_left); BOOST_ASSERT(!z_left);
NodeTraits::set_left(header, !z_right ? NodeTraits::set_left(header, !z_right ?
z_parent : // makes leftmost == header if z == root z_parent : // makes leftmost == header if z == root
bstree_algorithms::minimum(z_right)); base_type::minimum(z_right));
} }
if(NodeTraits::get_right(header) == z){ if(NodeTraits::get_right(header) == z){
//z_right must be null because z is the rightmost //z_right must be null because z is the rightmost
BOOST_ASSERT(!z_right); BOOST_ASSERT(!z_right);
NodeTraits::set_right(header, !z_left ? NodeTraits::set_right(header, !z_left ?
z_parent : // makes rightmost == header if z == root z_parent : // makes rightmost == header if z == root
bstree_algorithms::maximum(z_left)); base_type::maximum(z_left));
} }
} }
@ -1682,7 +1591,7 @@ class bstree_algorithms
{ {
node_ptr prev(pos); node_ptr prev(pos);
if(pos != NodeTraits::get_left(header)) if(pos != NodeTraits::get_left(header))
prev = prev_node(pos); prev = base_type::prev_node(pos);
bool link_left = unique(header) || !NodeTraits::get_left(pos); bool link_left = unique(header) || !NodeTraits::get_left(pos);
commit_data.link_left = link_left; commit_data.link_left = link_left;
commit_data.node = link_left ? pos : prev; commit_data.node = link_left ? pos : prev;
@ -1733,7 +1642,7 @@ class bstree_algorithms
if(hint == header || !comp(hint, new_node)){ if(hint == header || !comp(hint, new_node)){
node_ptr prev(hint); node_ptr prev(hint);
if(hint == NodeTraits::get_left(header) || if(hint == NodeTraits::get_left(header) ||
!comp(new_node, (prev = prev_node(hint)))){ !comp(new_node, (prev = base_type::prev_node(hint)))){
bool link_left = unique(header) || !NodeTraits::get_left(hint); bool link_left = unique(header) || !NodeTraits::get_left(hint);
commit_data.link_left = link_left; commit_data.link_left = link_left;
commit_data.node = link_left ? hint : prev; commit_data.node = link_left ? hint : prev;
@ -1945,7 +1854,7 @@ class bstree_algorithms
BOOST_INTRUSIVE_INVARIANT_ASSERT((!inited(node))); BOOST_INTRUSIVE_INVARIANT_ASSERT((!inited(node)));
node_ptr x = NodeTraits::get_parent(node); node_ptr x = NodeTraits::get_parent(node);
if(x){ if(x){
while(!is_header(x)){ while(!base_type::is_header(x)){
x = NodeTraits::get_parent(x); x = NodeTraits::get_parent(x);
} }
return x; return x;

View File

@ -211,60 +211,6 @@ class circular_list_algorithms
//! <b>Complexity</b>: Constant //! <b>Complexity</b>: Constant
//! //!
//! <b>Throws</b>: Nothing. //! <b>Throws</b>: Nothing.
/*
static void swap_nodes(const node_ptr &this_node, const node_ptr &other_node)
{
if (other_node == this_node)
return;
bool empty1 = unique(this_node);
bool empty2 = unique(other_node);
node_ptr next_this(NodeTraits::get_next(this_node));
node_ptr prev_this(NodeTraits::get_previous(this_node));
node_ptr next_other(NodeTraits::get_next(other_node));
node_ptr prev_other(NodeTraits::get_previous(other_node));
//Do the swap
NodeTraits::set_next(this_node, next_other);
NodeTraits::set_next(other_node, next_this);
NodeTraits::set_previous(this_node, prev_other);
NodeTraits::set_previous(other_node, prev_this);
if (empty2){
init(this_node);
}
else{
NodeTraits::set_next(prev_other, this_node);
NodeTraits::set_previous(next_other, this_node);
}
if (empty1){
init(other_node);
}
else{
NodeTraits::set_next(prev_this, other_node);
NodeTraits::set_previous(next_this, other_node);
}
}
*/
//Watanabe version
private:
static void swap_prev(const node_ptr &this_node, const node_ptr &other_node)
{
node_ptr temp(NodeTraits::get_previous(this_node));
NodeTraits::set_previous(this_node, NodeTraits::get_previous(other_node));
NodeTraits::set_previous(other_node, temp);
}
static void swap_next(const node_ptr &this_node, const node_ptr &other_node)
{
node_ptr temp(NodeTraits::get_next(this_node));
NodeTraits::set_next(this_node, NodeTraits::get_next(other_node));
NodeTraits::set_next(other_node, temp);
}
public:
static void swap_nodes(const node_ptr &this_node, const node_ptr &other_node) static void swap_nodes(const node_ptr &this_node, const node_ptr &other_node)
{ {
if (other_node == this_node) if (other_node == this_node)
@ -487,6 +433,21 @@ class circular_list_algorithms
info.num_2nd_partition = num2; info.num_2nd_partition = num2;
info.beg_2st_partition = new_f; info.beg_2st_partition = new_f;
} }
private:
static void swap_prev(const node_ptr &this_node, const node_ptr &other_node)
{
node_ptr temp(NodeTraits::get_previous(this_node));
NodeTraits::set_previous(this_node, NodeTraits::get_previous(other_node));
NodeTraits::set_previous(other_node, temp);
}
static void swap_next(const node_ptr &this_node, const node_ptr &other_node)
{
node_ptr temp(NodeTraits::get_next(this_node));
NodeTraits::set_next(this_node, NodeTraits::get_next(other_node));
NodeTraits::set_next(other_node, temp);
}
}; };
/// @cond /// @cond

View File

@ -0,0 +1,180 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2014-2014
//
// 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_BSTREE_ALGORITHMS_BASE_HPP
#define BOOST_INTRUSIVE_BSTREE_ALGORITHMS_BASE_HPP
#if defined(_MSC_VER)
# pragma once
#endif
#include <boost/intrusive/detail/uncast.hpp>
namespace boost {
namespace intrusive {
template<class NodeTraits>
class bstree_algorithms_base
{
public:
typedef typename NodeTraits::node node;
typedef NodeTraits node_traits;
typedef typename NodeTraits::node_ptr node_ptr;
typedef typename NodeTraits::const_node_ptr const_node_ptr;
//! <b>Requires</b>: 'node' is a node from the tree except the header.
//!
//! <b>Effects</b>: Returns the next node of the tree.
//!
//! <b>Complexity</b>: Average constant time.
//!
//! <b>Throws</b>: Nothing.
static node_ptr next_node(const node_ptr & node)
{
node_ptr const n_right(NodeTraits::get_right(node));
if(n_right){
return minimum(n_right);
}
else {
node_ptr n(node);
node_ptr p(NodeTraits::get_parent(n));
while(n == NodeTraits::get_right(p)){
n = p;
p = NodeTraits::get_parent(p);
}
return NodeTraits::get_right(n) != p ? p : n;
}
}
//! <b>Requires</b>: 'node' is a node from the tree except the leftmost node.
//!
//! <b>Effects</b>: Returns the previous node of the tree.
//!
//! <b>Complexity</b>: Average constant time.
//!
//! <b>Throws</b>: Nothing.
static node_ptr prev_node(const node_ptr & node)
{
if(is_header(node)){
return NodeTraits::get_right(node);
//return maximum(NodeTraits::get_parent(node));
}
else if(NodeTraits::get_left(node)){
return maximum(NodeTraits::get_left(node));
}
else {
node_ptr p(node);
node_ptr x = NodeTraits::get_parent(p);
while(p == NodeTraits::get_left(x)){
p = x;
x = NodeTraits::get_parent(x);
}
return x;
}
}
//! <b>Requires</b>: 'node' is a node of a tree but not the header.
//!
//! <b>Effects</b>: Returns the minimum node of the subtree starting at p.
//!
//! <b>Complexity</b>: Logarithmic to the size of the subtree.
//!
//! <b>Throws</b>: Nothing.
static node_ptr minimum(node_ptr node)
{
for(node_ptr p_left = NodeTraits::get_left(node)
;p_left
;p_left = NodeTraits::get_left(node)){
node = p_left;
}
return node;
}
//! <b>Requires</b>: 'node' is a node of a tree but not the header.
//!
//! <b>Effects</b>: Returns the maximum node of the subtree starting at p.
//!
//! <b>Complexity</b>: Logarithmic to the size of the subtree.
//!
//! <b>Throws</b>: Nothing.
static node_ptr maximum(node_ptr node)
{
for(node_ptr p_right = NodeTraits::get_right(node)
;p_right
;p_right = NodeTraits::get_right(node)){
node = p_right;
}
return node;
}
//! <b>Requires</b>: p is a node of a tree.
//!
//! <b>Effects</b>: Returns true if p is the header of the tree.
//!
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: Nothing.
static bool is_header(const const_node_ptr & p)
{
node_ptr p_left (NodeTraits::get_left(p));
node_ptr p_right(NodeTraits::get_right(p));
if(!NodeTraits::get_parent(p) || //Header condition when empty tree
(p_left && p_right && //Header always has leftmost and rightmost
(p_left == p_right || //Header condition when only node
(NodeTraits::get_parent(p_left) != p ||
NodeTraits::get_parent(p_right) != p ))
//When tree size > 1 headers can't be leftmost's
//and rightmost's parent
)){
return true;
}
return false;
}
//! <b>Requires</b>: 'node' is a node of the tree or a header node.
//!
//! <b>Effects</b>: Returns the header of the tree.
//!
//! <b>Complexity</b>: Logarithmic.
//!
//! <b>Throws</b>: Nothing.
static node_ptr get_header(const const_node_ptr & node)
{
node_ptr n(detail::uncast(node));
node_ptr p(NodeTraits::get_parent(node));
//If p is null, then n is the header of an empty tree
if(p){
//Non-empty tree, check if n is neither root nor header
node_ptr pp(NodeTraits::get_parent(p));
//If granparent is not equal to n, then n is neither root nor header,
//the try the fast path
if(n != pp){
do{
n = p;
p = pp;
pp = NodeTraits::get_parent(pp);
}while(n != pp);
n = p;
}
//Check if n is root or header when size() > 0
else if(!bstree_algorithms_base::is_header(n)){
n = p;
}
}
return n;
}
};
} //namespace intrusive
} //namespace boost
#endif //BOOST_INTRUSIVE_BSTREE_ALGORITHMS_BASE_HPP

View File

@ -1,92 +0,0 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Pablo Halpern 2009. 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)
//
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2011-2014. 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_ALLOCATOR_MEMORY_UTIL_HPP
#define BOOST_INTRUSIVE_ALLOCATOR_MEMORY_UTIL_HPP
#if defined(_MSC_VER)
# pragma once
#endif
#include <boost/intrusive/detail/workaround.hpp>
#include <boost/intrusive/detail/mpl.hpp>
#include <boost/intrusive/detail/preprocessor.hpp>
#include <boost/preprocessor/iteration/iterate.hpp>
namespace boost {
namespace intrusive {
namespace detail {
template <typename T>
inline T* addressof(T& obj)
{
return static_cast<T*>
(static_cast<void*>
(const_cast<char*>
(&reinterpret_cast<const char&>(obj))
)
);
}
template <typename T>
struct LowPriorityConversion
{
// Convertible from T with user-defined-conversion rank.
LowPriorityConversion(const T&) { }
};
}}} //namespace boost::intrusive::detail
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME pointer_to
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace intrusive { namespace detail {
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
#define BOOST_PP_ITERATION_PARAMS_1 (3, (1, 1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
#include BOOST_PP_ITERATE()
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME static_cast_from
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace intrusive { namespace detail {
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
#define BOOST_PP_ITERATION_PARAMS_1 (3, (1, 1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
#include BOOST_PP_ITERATE()
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME const_cast_from
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace intrusive { namespace detail {
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
#define BOOST_PP_ITERATION_PARAMS_1 (3, (1, 1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
#include BOOST_PP_ITERATE()
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME dynamic_cast_from
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace intrusive { namespace detail {
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
#define BOOST_PP_ITERATION_PARAMS_1 (3, (1, 1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
#include BOOST_PP_ITERATE()
namespace boost {
namespace intrusive {
namespace detail {
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(element_type)
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(difference_type)
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(reference)
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(value_traits_ptr)
} //namespace detail {
} //namespace intrusive {
} //namespace boost {
#endif // ! defined(BOOST_INTRUSIVE_ALLOCATOR_MEMORY_UTIL_HPP)

View File

@ -367,6 +367,59 @@ struct TRAITS_PREFIX##_bool_is_true\
};\ };\
// //
template<typename T, T> struct helper;
#define BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(TRAITS_NAME, FUNC_NAME) \
template <typename U, typename Signature> \
class TRAITS_NAME \
{ \
private: \
template<typename T> \
static yes_type check(helper<Signature, &T::FUNC_NAME>*); \
template<typename T> static no_type check(...); \
public: \
static const bool value = sizeof(check<U>(0)) == sizeof(yes_type); \
}; \
//
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED(TRAITS_NAME, FUNC_NAME) \
template <typename Type> \
struct TRAITS_NAME \
{ \
struct BaseMixin \
{ \
void FUNC_NAME(); \
}; \
struct Base : public Type, public BaseMixin { Base(); }; \
template <typename T, T t> class Helper{}; \
template <typename U> \
static no_type check(U*, Helper<void (BaseMixin::*)(), &U::FUNC_NAME>* = 0); \
static yes_type check(...); \
static const bool value = sizeof(yes_type) == sizeof(check((Base*)(0))); \
};\
//
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED_IGNORE_SIGNATURE(TRAITS_NAME, FUNC_NAME) \
BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED(TRAITS_NAME##_ignore_signature, FUNC_NAME) \
\
template <typename Type, class> \
struct TRAITS_NAME \
: public TRAITS_NAME##_ignore_signature<Type> \
{};\
//
template <typename T>
inline T* addressof(T& obj)
{
return static_cast<T*>
(static_cast<void*>
(const_cast<char*>
(&reinterpret_cast<const char&>(obj))
)
);
}
} //namespace detail } //namespace detail
} //namespace intrusive } //namespace intrusive
} //namespace boost } //namespace boost

View File

@ -90,16 +90,6 @@ class transform_iterator
friend bool operator!= (const transform_iterator& i, const transform_iterator& i2) friend bool operator!= (const transform_iterator& i, const transform_iterator& i2)
{ return !(i == i2); } { return !(i == i2); }
/*
friend bool operator> (const transform_iterator& i, const transform_iterator& i2)
{ return i2 < i; }
friend bool operator<= (const transform_iterator& i, const transform_iterator& i2)
{ return !(i > i2); }
friend bool operator>= (const transform_iterator& i, const transform_iterator& i2)
{ return !(i < i2); }
*/
friend typename Iterator::difference_type operator- (const transform_iterator& i, const transform_iterator& i2) friend typename Iterator::difference_type operator- (const transform_iterator& i, const transform_iterator& i2)
{ return i2.distance_to(i); } { return i2.distance_to(i); }

View File

@ -20,7 +20,7 @@
#include <boost/intrusive/detail/config_begin.hpp> #include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/detail/std_fwd.hpp> #include <boost/intrusive/detail/std_fwd.hpp>
#include <boost/intrusive/detail/iiterator.hpp> #include <boost/intrusive/detail/iiterator.hpp>
#include <boost/intrusive/bstree_algorithms.hpp> #include <boost/intrusive/detail/bstree_algorithms_base.hpp>
namespace boost { namespace boost {
namespace intrusive { namespace intrusive {
@ -46,8 +46,9 @@ class tree_iterator
typedef typename types_t::node node; typedef typename types_t::node node;
typedef typename types_t::node_ptr node_ptr; typedef typename types_t::node_ptr node_ptr;
typedef typename types_t::const_value_traits_ptr const_value_traits_ptr; typedef typename types_t::const_value_traits_ptr const_value_traits_ptr;
typedef bstree_algorithms_base<node_traits> node_algorithms;
static const bool stateful_value_traits = types_t::stateful_value_traits; static const bool stateful_value_traits = types_t::stateful_value_traits;
typedef bstree_algorithms<node_traits> node_algorithms;
void unspecified_bool_type_func() const {} void unspecified_bool_type_func() const {}
typedef void (tree_iterator::*unspecified_bool_type)() const; typedef void (tree_iterator::*unspecified_bool_type)() const;

View File

@ -353,7 +353,7 @@ class list_impl
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
const_reference front() const const_reference front() const
{ return *priv_value_traits().to_value_ptr(detail::uncast(node_traits::get_next(this->get_root_node()))); } { return *priv_value_traits().to_value_ptr(node_traits::get_next(this->get_root_node())); }
//! <b>Effects</b>: Returns a reference to the last element of the list. //! <b>Effects</b>: Returns a reference to the last element of the list.
//! //!
@ -1248,7 +1248,7 @@ class list_impl
static const_iterator s_iterator_to(const_reference value) static const_iterator s_iterator_to(const_reference value)
{ {
BOOST_STATIC_ASSERT((!stateful_value_traits)); BOOST_STATIC_ASSERT((!stateful_value_traits));
reference r =*pointer_traits<pointer>::const_cast_from(pointer_traits<const_pointer>::pointer_to(value)); reference r =*detail::uncast(pointer_traits<const_pointer>::pointer_to(value));
BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(value_traits::to_node_ptr(r))); BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(value_traits::to_node_ptr(r)));
return const_iterator(value_traits::to_node_ptr(r), const_value_traits_ptr()); return const_iterator(value_traits::to_node_ptr(r), const_value_traits_ptr());
} }
@ -1279,7 +1279,7 @@ class list_impl
//! <b>Note</b>: Iterators and references are not invalidated. //! <b>Note</b>: Iterators and references are not invalidated.
const_iterator iterator_to(const_reference value) const const_iterator iterator_to(const_reference value) const
{ {
reference r = *pointer_traits<pointer>::const_cast_from(pointer_traits<const_pointer>::pointer_to(value)); reference r = *detail::uncast(pointer_traits<const_pointer>::pointer_to(value));
BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(this->priv_value_traits().to_node_ptr(r))); BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(this->priv_value_traits().to_node_ptr(r)));
return const_iterator(this->priv_value_traits().to_node_ptr(r), this->priv_value_traits_ptr()); return const_iterator(this->priv_value_traits().to_node_ptr(r), this->priv_value_traits_ptr());
} }

View File

@ -308,7 +308,7 @@ struct pack_options
//! //!
//! \code //! \code
//! struct OPTION_NAME<class TYPE> //! struct OPTION_NAME<class TYPE>
//! { /*unspecified_content*/ }; //! { unspecified_content };
//! \endcode //! \endcode
//! //!
//! ...that after being combined with //! ...that after being combined with
@ -338,7 +338,7 @@ struct pack_options
//! //!
//! \code //! \code
//! struct OPTION_NAME<TYPE VALUE> //! struct OPTION_NAME<TYPE VALUE>
//! { /*unspecified_content*/ }; //! { unspecified_content };
//! \endcode //! \endcode
//! //!
//! ...that after being combined with //! ...that after being combined with

View File

@ -6,7 +6,7 @@
// //
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// //
// (C) Copyright Ion Gaztanaga 2011-2013. Distributed under the Boost // (C) Copyright Ion Gaztanaga 2011-2014. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// //
@ -24,7 +24,6 @@
#include <boost/intrusive/detail/config_begin.hpp> #include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/intrusive_fwd.hpp> #include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/intrusive/detail/workaround.hpp> #include <boost/intrusive/detail/workaround.hpp>
#include <boost/intrusive/detail/memory_util.hpp>
#include <boost/intrusive/pointer_rebind.hpp> #include <boost/intrusive/pointer_rebind.hpp>
#include <boost/intrusive/detail/pointer_element.hpp> #include <boost/intrusive/detail/pointer_element.hpp>
#include <boost/intrusive/detail/mpl.hpp> #include <boost/intrusive/detail/mpl.hpp>
@ -32,6 +31,27 @@
namespace boost { namespace boost {
namespace intrusive { namespace intrusive {
namespace detail {
#if !defined(BOOST_MSVC) || (BOOST_MSVC > 1310)
BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(has_member_function_callable_with_pointer_to, pointer_to);
BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(has_member_function_callable_with_dynamic_cast_from, dynamic_cast_from);
BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(has_member_function_callable_with_static_cast_from, static_cast_from);
BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(has_member_function_callable_with_const_cast_from, const_cast_from);
#else
BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED_IGNORE_SIGNATURE(has_member_function_callable_with_pointer_to, pointer_to);
BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED_IGNORE_SIGNATURE(has_member_function_callable_with_dynamic_cast_from, dynamic_cast_from);
BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED_IGNORE_SIGNATURE(has_member_function_callable_with_static_cast_from, static_cast_from);
BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED_IGNORE_SIGNATURE(has_member_function_callable_with_const_cast_from, const_cast_from);
#endif
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(element_type)
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(difference_type)
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(reference)
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(value_traits_ptr)
} //namespace detail {
//! pointer_traits is the implementation of C++11 std::pointer_traits class with some //! pointer_traits is the implementation of C++11 std::pointer_traits class with some
//! extensions like castings. //! extensions like castings.
@ -91,59 +111,83 @@ struct pointer_traits
//! <b>Remark</b>: If element_type is (possibly cv-qualified) void, r type is unspecified; otherwise, //! <b>Remark</b>: If element_type is (possibly cv-qualified) void, r type is unspecified; otherwise,
//! it is element_type &. //! it is element_type &.
//! //!
//! <b>Returns</b>: A dereferenceable pointer to r obtained by calling Ptr::pointer_to(r). //! <b>Returns</b>: A dereferenceable pointer to r obtained by calling Ptr::pointer_to(reference).
//! Non-standard extension: If such function does not exist, returns pointer(addressof(r)); //! Non-standard extension: If such function does not exist, returns pointer(addressof(r));
//!
//! <b>Note</b>: For non-conforming compilers only the existence of a member function called
//! <code>pointer_to</code> is checked.
static pointer pointer_to(reference r) static pointer pointer_to(reference r)
{ {
//Non-standard extension, it does not require Ptr::pointer_to. If not present //Non-standard extension, it does not require Ptr::pointer_to. If not present
//tries to converts &r to pointer. //tries to converts &r to pointer.
const bool value = boost::intrusive::detail:: const bool value = boost::intrusive::detail::
has_member_function_callable_with_pointer_to has_member_function_callable_with_pointer_to
<Ptr, reference>::value; <Ptr, Ptr (*)(reference)>::value;
boost::intrusive::detail::bool_<value> flag; boost::intrusive::detail::bool_<value> flag;
return pointer_traits::priv_pointer_to(flag, r); return pointer_traits::priv_pointer_to(flag, r);
} }
//! <b>Remark</b>: Non-standard extension. //! <b>Remark</b>: Non-standard extension.
//! //!
//! <b>Returns</b>: A dereferenceable pointer to r obtained by calling Ptr::static_cast_from(r). //! <b>Returns</b>: A dereferenceable pointer to r obtained by calling the static template function
//! Ptr::static_cast_from(UPpr/const UPpr &).
//! If such function does not exist, returns pointer_to(static_cast<element_type&>(*uptr)) //! If such function does not exist, returns pointer_to(static_cast<element_type&>(*uptr))
//!
//! <b>Note</b>: For non-conforming compilers only the existence of a member function called
//! <code>static_cast_from</code> is checked.
template<class UPtr> template<class UPtr>
static pointer static_cast_from(const UPtr &uptr) static pointer static_cast_from(const UPtr &uptr)
{ {
typedef const UPtr &RefArg;
const bool value = boost::intrusive::detail:: const bool value = boost::intrusive::detail::
has_member_function_callable_with_static_cast_from has_member_function_callable_with_static_cast_from
<Ptr, const UPtr>::value; <pointer, pointer(*)(RefArg)>::value
boost::intrusive::detail::bool_<value> flag; || boost::intrusive::detail::
return pointer_traits::priv_static_cast_from(flag, uptr); has_member_function_callable_with_static_cast_from
<pointer, pointer(*)(UPtr)>::value;
return pointer_traits::priv_static_cast_from(boost::intrusive::detail::bool_<value>(), uptr);
} }
//! <b>Remark</b>: Non-standard extension. //! <b>Remark</b>: Non-standard extension.
//! //!
//! <b>Returns</b>: A dereferenceable pointer to r obtained by calling Ptr::const_cast_from(r). //! <b>Returns</b>: A dereferenceable pointer to r obtained by calling the static template function
//! Ptr::const_cast_from<UPtr>(UPpr/const UPpr &).
//! If such function does not exist, returns pointer_to(const_cast<element_type&>(*uptr)) //! If such function does not exist, returns pointer_to(const_cast<element_type&>(*uptr))
//!
//! <b>Note</b>: For non-conforming compilers only the existence of a member function called
//! <code>const_cast_from</code> is checked.
template<class UPtr> template<class UPtr>
static pointer const_cast_from(const UPtr &uptr) static pointer const_cast_from(const UPtr &uptr)
{ {
typedef const UPtr &RefArg;
const bool value = boost::intrusive::detail:: const bool value = boost::intrusive::detail::
has_member_function_callable_with_const_cast_from has_member_function_callable_with_const_cast_from
<Ptr, const UPtr>::value; <pointer, pointer(*)(RefArg)>::value
boost::intrusive::detail::bool_<value> flag; || boost::intrusive::detail::
return pointer_traits::priv_const_cast_from(flag, uptr); has_member_function_callable_with_const_cast_from
<pointer, pointer(*)(UPtr)>::value;
return pointer_traits::priv_const_cast_from(boost::intrusive::detail::bool_<value>(), uptr);
} }
//! <b>Remark</b>: Non-standard extension. //! <b>Remark</b>: Non-standard extension.
//! //!
//! <b>Returns</b>: A dereferenceable pointer to r obtained by calling Ptr::dynamic_cast_from(r). //! <b>Returns</b>: A dereferenceable pointer to r obtained by calling the static template function
//! Ptr::dynamic_cast_from<UPtr>(UPpr/const UPpr &).
//! If such function does not exist, returns pointer_to(*dynamic_cast<element_type*>(&*uptr)) //! If such function does not exist, returns pointer_to(*dynamic_cast<element_type*>(&*uptr))
//!
//! <b>Note</b>: For non-conforming compilers only the existence of a member function called
//! <code>dynamic_cast_from</code> is checked.
template<class UPtr> template<class UPtr>
static pointer dynamic_cast_from(const UPtr &uptr) static pointer dynamic_cast_from(const UPtr &uptr)
{ {
typedef const UPtr &RefArg;
const bool value = boost::intrusive::detail:: const bool value = boost::intrusive::detail::
has_member_function_callable_with_dynamic_cast_from has_member_function_callable_with_dynamic_cast_from
<Ptr, const UPtr>::value; <pointer, pointer(*)(RefArg)>::value
boost::intrusive::detail::bool_<value> flag; || boost::intrusive::detail::
return pointer_traits::priv_dynamic_cast_from(flag, uptr); has_member_function_callable_with_dynamic_cast_from
<pointer, pointer(*)(UPtr)>::value;
return pointer_traits::priv_dynamic_cast_from(boost::intrusive::detail::bool_<value>(), uptr);
} }
///@cond ///@cond

View File

@ -152,7 +152,7 @@ struct alpha_holder
} }
h_alpha_t get_h_alpha_t() const h_alpha_t get_h_alpha_t() const
{ return h_alpha_t(/*alpha_, */inv_minus_logalpha_); } { return h_alpha_t(inv_minus_logalpha_); }
multiply_by_alpha_t get_multiply_by_alpha_t() const multiply_by_alpha_t get_multiply_by_alpha_t() const
{ return multiply_by_alpha_t(alpha_); } { return multiply_by_alpha_t(alpha_); }

View File

@ -1714,7 +1714,7 @@ class slist_impl
static const_iterator s_iterator_to(const_reference value) static const_iterator s_iterator_to(const_reference value)
{ {
BOOST_STATIC_ASSERT((!stateful_value_traits)); BOOST_STATIC_ASSERT((!stateful_value_traits));
reference r =*pointer_traits<pointer>::const_cast_from(pointer_traits<const_pointer>::pointer_to(value)); reference r =*detail::uncast(pointer_traits<const_pointer>::pointer_to(value));
return const_iterator(value_traits::to_node_ptr(r), const_value_traits_ptr()); return const_iterator(value_traits::to_node_ptr(r), const_value_traits_ptr());
} }
@ -1744,7 +1744,7 @@ class slist_impl
//! <b>Note</b>: Iterators and references are not invalidated. //! <b>Note</b>: Iterators and references are not invalidated.
const_iterator iterator_to(const_reference value) const const_iterator iterator_to(const_reference value) const
{ {
reference r =*pointer_traits<pointer>::const_cast_from(pointer_traits<const_pointer>::pointer_to(value)); reference r =*detail::uncast(pointer_traits<const_pointer>::pointer_to(value));
BOOST_INTRUSIVE_INVARIANT_ASSERT (linear || !node_algorithms::inited(this->priv_value_traits().to_node_ptr(r))); BOOST_INTRUSIVE_INVARIANT_ASSERT (linear || !node_algorithms::inited(this->priv_value_traits().to_node_ptr(r)));
return const_iterator(this->priv_value_traits().to_node_ptr(r), this->priv_value_traits_ptr()); return const_iterator(this->priv_value_traits().to_node_ptr(r), this->priv_value_traits_ptr());
} }

View File

@ -233,21 +233,21 @@ class splaytree_algorithms
if(NodeTraits::get_left(z)){ if(NodeTraits::get_left(z)){
splay_up(bstree_algo::prev_node(z), header); splay_up(bstree_algo::prev_node(z), header);
} }
/*
//possibility 2 //possibility 2
if(NodeTraits::get_left(z)){ //if(NodeTraits::get_left(z)){
node_ptr l = NodeTraits::get_left(z); // node_ptr l = NodeTraits::get_left(z);
splay_up(l, header); // splay_up(l, header);
}*/ //}
/*
if(NodeTraits::get_left(z)){ //if(NodeTraits::get_left(z)){
node_ptr l = bstree_algo::prev_node(z); // node_ptr l = bstree_algo::prev_node(z);
splay_up_impl(l, z); // splay_up_impl(l, z);
}*/ //}
/*
//possibility 4 //possibility 4
splay_up(z, header); //splay_up(z, header);
*/
bstree_algo::erase(header, z); bstree_algo::erase(header, z);
} }

View File

@ -247,6 +247,9 @@
<File <File
RelativePath="..\..\..\..\..\boost\intrusive\detail\avltree_node.hpp"> RelativePath="..\..\..\..\..\boost\intrusive\detail\avltree_node.hpp">
</File> </File>
<File
RelativePath="..\..\..\..\..\boost\intrusive\detail\bstree_algorithms_base.hpp">
</File>
<File <File
RelativePath="..\..\..\..\..\boost\intrusive\detail\common_slist_algorithms.hpp"> RelativePath="..\..\..\..\..\boost\intrusive\detail\common_slist_algorithms.hpp">
</File> </File>
@ -310,9 +313,6 @@
<File <File
RelativePath="..\..\..\..\..\boost\intrusive\detail\math.hpp"> RelativePath="..\..\..\..\..\boost\intrusive\detail\math.hpp">
</File> </File>
<File
RelativePath="..\..\..\..\..\boost\intrusive\detail\memory_util.hpp">
</File>
<File <File
RelativePath="..\..\..\..\..\boost\intrusive\detail\mpl.hpp"> RelativePath="..\..\..\..\..\boost\intrusive\detail\mpl.hpp">
</File> </File>

View File

@ -30,6 +30,7 @@
DisableLanguageExtensions="FALSE" DisableLanguageExtensions="FALSE"
TreatWChar_tAsBuiltInType="TRUE" TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE" ForceConformanceInForLoopScope="TRUE"
RuntimeTypeInfo="TRUE"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"
WarningLevel="4" WarningLevel="4"
Detect64BitPortabilityProblems="TRUE" Detect64BitPortabilityProblems="TRUE"

View File

@ -197,32 +197,6 @@ class pointer_holder
T* const _ptr; T* const _ptr;
}; };
/*
struct int_testvalue_comp
{
template<class Hooks, bool constant_time_size>
bool operator()
(const testvalue<Hooks, constant_time_size>& v1, const int &i) const
{ return v1.value_ < i; }
template<class Hooks, bool constant_time_size>
bool operator()
(const int &i, const testvalue<Hooks, constant_time_size>& v1) const
{ return i < v1.value_; }
};
struct int_testvalue_pcomp
{
template<class Hooks, bool constant_time_size>
bool operator()
(const testvalue<Hooks, constant_time_size>& v1, const int &i) const
{ return v1.value_ < i; }
template<class Hooks, bool constant_time_size>
bool operator()
(const int &i, const testvalue<Hooks, constant_time_size>& v1) const
{ return i < v1.value_; }
};
*/
} //namespace boost{ } //namespace boost{
} //namespace intrusive{ } //namespace intrusive{

View File

@ -16,7 +16,7 @@
#include <boost/intrusive/sg_set.hpp> #include <boost/intrusive/sg_set.hpp>
#include <boost/intrusive/treap_set.hpp> #include <boost/intrusive/treap_set.hpp>
#include <boost/intrusive/splay_set.hpp> #include <boost/intrusive/splay_set.hpp>
#include <boost/intrusive/detail/memory_util.hpp> #include <boost/intrusive/detail/mpl.hpp>
#include <boost/core/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
#include <boost/aligned_storage.hpp> #include <boost/aligned_storage.hpp>

View File

@ -10,6 +10,28 @@
#include <boost/intrusive/detail/mpl.hpp> #include <boost/intrusive/detail/mpl.hpp>
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
#include <boost/intrusive/pointer_traits.hpp> #include <boost/intrusive/pointer_traits.hpp>
#include <boost/core/lightweight_test.hpp>
struct CompleteSmartPtrStats
{
static unsigned static_cast_called;
static unsigned dynamic_cast_called;
static unsigned const_cast_called;
static unsigned pointer_to_called;
static void reset_stats()
{
static_cast_called = 0;
dynamic_cast_called = 0;
const_cast_called = 0;
pointer_to_called = 0;
}
};
unsigned CompleteSmartPtrStats::static_cast_called= 0;
unsigned CompleteSmartPtrStats::dynamic_cast_called = 0;
unsigned CompleteSmartPtrStats::const_cast_called = 0;
unsigned CompleteSmartPtrStats::pointer_to_called = 0;
template<class T> template<class T>
class CompleteSmartPtr class CompleteSmartPtr
@ -18,7 +40,6 @@ class CompleteSmartPtr
friend class CompleteSmartPtr; friend class CompleteSmartPtr;
public: public:
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template <class U> using rebind = CompleteSmartPtr<U>; template <class U> using rebind = CompleteSmartPtr<U>;
#else #else
@ -44,7 +65,7 @@ class CompleteSmartPtr
{ this->ptr_ = c.ptr_; } { this->ptr_ = c.ptr_; }
static CompleteSmartPtr pointer_to(T &r) static CompleteSmartPtr pointer_to(T &r)
{ return CompleteSmartPtr(r); } { ++CompleteSmartPtrStats::pointer_to_called; return CompleteSmartPtr(r); }
T * operator->() const T * operator->() const
{ return ptr_; } { return ptr_; }
@ -54,15 +75,15 @@ class CompleteSmartPtr
template<class U> template<class U>
static CompleteSmartPtr static_cast_from(const CompleteSmartPtr<U> &uptr) static CompleteSmartPtr static_cast_from(const CompleteSmartPtr<U> &uptr)
{ return CompleteSmartPtr(*static_cast<element_type*>(uptr.ptr_)); } { ++CompleteSmartPtrStats::static_cast_called; return CompleteSmartPtr(*static_cast<element_type*>(uptr.ptr_)); }
template<class U> template<class U>
static CompleteSmartPtr const_cast_from(const CompleteSmartPtr<U> &uptr) static CompleteSmartPtr const_cast_from(const CompleteSmartPtr<U> &uptr)
{ return CompleteSmartPtr(*const_cast<element_type*>(uptr.ptr_)); } { ++CompleteSmartPtrStats::const_cast_called; return CompleteSmartPtr(*const_cast<element_type*>(uptr.ptr_)); }
template<class U> template<class U>
static CompleteSmartPtr dynamic_cast_from(const CompleteSmartPtr<U> &uptr) static CompleteSmartPtr dynamic_cast_from(const CompleteSmartPtr<U> &uptr)
{ return CompleteSmartPtr(*dynamic_cast<element_type*>(uptr.ptr_)); } { ++CompleteSmartPtrStats::dynamic_cast_called; return CompleteSmartPtr(*dynamic_cast<element_type*>(uptr.ptr_)); }
friend bool operator ==(const CompleteSmartPtr &l, const CompleteSmartPtr &r) friend bool operator ==(const CompleteSmartPtr &l, const CompleteSmartPtr &r)
{ return l.ptr_ == r.ptr_; } { return l.ptr_ == r.ptr_; }
@ -128,18 +149,10 @@ int main()
BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same<boost::intrusive::pointer_traits BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same<boost::intrusive::pointer_traits
<int*>::rebind_pointer<double>::type <int*>::rebind_pointer<double>::type
, double*>::value )); , double*>::value ));
if(boost::intrusive::pointer_traits<int*>::pointer_to(dummy) != &dummy){ BOOST_TEST(boost::intrusive::pointer_traits<int*>::pointer_to(dummy) == &dummy);
return 1; BOOST_TEST(boost::intrusive::pointer_traits<D*>:: static_cast_from((B*)0) == 0);
} BOOST_TEST(boost::intrusive::pointer_traits<D*>:: const_cast_from((const D*)0) == 0);
if(boost::intrusive::pointer_traits<D*>::static_cast_from((B*)0)){ BOOST_TEST(boost::intrusive::pointer_traits<DD*>:: dynamic_cast_from((B*)0) == 0);
return 1;
}
if(boost::intrusive::pointer_traits<D*>::const_cast_from((const D*)0)){
return 1;
}
if(boost::intrusive::pointer_traits<DD*>::dynamic_cast_from((B*)0)){
return 1;
}
//Complete smart pointer //Complete smart pointer
BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same<boost::intrusive::pointer_traits BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same<boost::intrusive::pointer_traits
@ -151,22 +164,22 @@ int main()
BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same<boost::intrusive::pointer_traits BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same<boost::intrusive::pointer_traits
< CompleteSmartPtr<int> >::rebind_pointer<double>::type < CompleteSmartPtr<int> >::rebind_pointer<double>::type
, CompleteSmartPtr<double> >::value )); , CompleteSmartPtr<double> >::value ));
if(boost::intrusive::pointer_traits< CompleteSmartPtr<int> > //pointer_to
::pointer_to(dummy) != CompleteSmartPtr<int>(dummy)){ CompleteSmartPtrStats::reset_stats();
return 1; BOOST_TEST(boost::intrusive::pointer_traits< CompleteSmartPtr<int> >::pointer_to(dummy) == CompleteSmartPtr<int>(dummy));
} BOOST_TEST(CompleteSmartPtrStats::pointer_to_called == 1);
if(boost::intrusive::pointer_traits< CompleteSmartPtr<D> >:: //static_cast_from
static_cast_from(CompleteSmartPtr<B>()) != CompleteSmartPtr<D>()){ CompleteSmartPtrStats::reset_stats();
return 1; BOOST_TEST(boost::intrusive::pointer_traits< CompleteSmartPtr<D> >::static_cast_from(CompleteSmartPtr<B>()) == CompleteSmartPtr<D>());
} BOOST_TEST(CompleteSmartPtrStats::static_cast_called == 1);
if(boost::intrusive::pointer_traits< CompleteSmartPtr<D> >:: //const_cast_from
const_cast_from(CompleteSmartPtr<const D>()) != CompleteSmartPtr<D>()){ CompleteSmartPtrStats::reset_stats();
return 1; BOOST_TEST(boost::intrusive::pointer_traits< CompleteSmartPtr<D> >::const_cast_from(CompleteSmartPtr<const D>()) == CompleteSmartPtr<D>());
} BOOST_TEST(CompleteSmartPtrStats::const_cast_called == 1);
if(boost::intrusive::pointer_traits< CompleteSmartPtr<DD> >:: //dynamic_cast_from
dynamic_cast_from(CompleteSmartPtr<B>()) != CompleteSmartPtr<DD>()){ CompleteSmartPtrStats::reset_stats();
return 1; BOOST_TEST(boost::intrusive::pointer_traits< CompleteSmartPtr<DD> >::dynamic_cast_from(CompleteSmartPtr<B>()) == CompleteSmartPtr<DD>());
} BOOST_TEST(CompleteSmartPtrStats::dynamic_cast_called == 1);
//Simple smart pointer //Simple smart pointer
BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same<boost::intrusive::pointer_traits BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same<boost::intrusive::pointer_traits
@ -178,21 +191,11 @@ int main()
BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same<boost::intrusive::pointer_traits BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same<boost::intrusive::pointer_traits
< SimpleSmartPtr<int> >::rebind_pointer<double>::type < SimpleSmartPtr<int> >::rebind_pointer<double>::type
, SimpleSmartPtr<double> >::value )); , SimpleSmartPtr<double> >::value ));
if(boost::intrusive::pointer_traits< SimpleSmartPtr<int> >
::pointer_to(dummy) != SimpleSmartPtr<int>(&dummy)){ BOOST_TEST(boost::intrusive::pointer_traits< SimpleSmartPtr<int> >::pointer_to(dummy) == SimpleSmartPtr<int>(&dummy));
return 1; BOOST_TEST(boost::intrusive::pointer_traits< SimpleSmartPtr<D> > ::static_cast_from(SimpleSmartPtr<B>()) == SimpleSmartPtr<D>());
} BOOST_TEST(boost::intrusive::pointer_traits< SimpleSmartPtr<D> > ::const_cast_from(SimpleSmartPtr<const D>()) == SimpleSmartPtr<D>());
if(boost::intrusive::pointer_traits< SimpleSmartPtr<D> >:: BOOST_TEST(boost::intrusive::pointer_traits< SimpleSmartPtr<DD> >::dynamic_cast_from(SimpleSmartPtr<B>()) == SimpleSmartPtr<DD>());
static_cast_from(SimpleSmartPtr<B>()) != SimpleSmartPtr<D>()){
return 1; return boost::report_errors();
}
if(boost::intrusive::pointer_traits< SimpleSmartPtr<D> >::
const_cast_from(SimpleSmartPtr<const D>()) != SimpleSmartPtr<D>()){
return 1;
}
if(boost::intrusive::pointer_traits< SimpleSmartPtr<DD> >::
dynamic_cast_from(SimpleSmartPtr<B>()) != SimpleSmartPtr<DD>()){
return 1;
}
return 0;
} }