Fixes for 1.41

[SVN r56817]
This commit is contained in:
Ion Gaztañaga
2009-10-14 11:59:32 +00:00
parent b36ec05d0a
commit 8c6f93eae0
59 changed files with 1956 additions and 471 deletions

View File

@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2008
// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2008
// (C) Copyright Ion Gaztanaga 2007-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -489,6 +489,60 @@ class avl_set_impl
void insert(Iterator b, Iterator e)
{ tree_.insert_unique(b, e); }
//! <b>Requires</b>: value must be an lvalue, "pos" must be
//! a valid iterator (or end) and must be the succesor of value
//! once inserted according to the predicate. "value" must not be equal to any
//! inserted key according to the predicate.
//!
//! <b>Effects</b>: Inserts x into the tree before "pos".
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: This function does not check preconditions so if "pos" is not
//! the successor of "value" or "value" is not unique tree ordering and uniqueness
//! invariants will be broken respectively.
//! This is a low-level function to be used only for performance reasons
//! by advanced users.
iterator insert_before(const_iterator pos, reference value)
{ return tree_.insert_before(pos, value); }
//! <b>Requires</b>: value must be an lvalue, and it must be greater than
//! any inserted key according to the predicate.
//!
//! <b>Effects</b>: Inserts x into the tree in the last position.
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: This function does not check preconditions so if value is
//! less than or equal to the greatest inserted key tree ordering invariant will be broken.
//! This function is slightly more efficient than using "insert_before".
//! This is a low-level function to be used only for performance reasons
//! by advanced users.
void push_back(reference value)
{ tree_.push_back(value); }
//! <b>Requires</b>: value must be an lvalue, and it must be less
//! than any inserted key according to the predicate.
//!
//! <b>Effects</b>: Inserts x into the tree in the first position.
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: This function does not check preconditions so if value is
//! greater than or equal to the the mimum inserted key tree ordering or uniqueness
//! invariants will be broken.
//! This function is slightly more efficient than using "insert_before".
//! This is a low-level function to be used only for performance reasons
//! by advanced users.
void push_front(reference value)
{ tree_.push_front(value); }
//! <b>Effects</b>: Erases the element pointed to by pos.
//!
//! <b>Complexity</b>: Average complexity is constant time.
@@ -1532,6 +1586,60 @@ class avl_multiset_impl
void insert(Iterator b, Iterator e)
{ tree_.insert_equal(b, e); }
//! <b>Requires</b>: value must be an lvalue, "pos" must be
//! a valid iterator (or end) and must be the succesor of value
//! once inserted according to the predicate. "value" must not be equal to any
//! inserted key according to the predicate.
//!
//! <b>Effects</b>: Inserts x into the tree before "pos".
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: This function does not check preconditions so if "pos" is not
//! the successor of "value" or "value" is not unique tree ordering and uniqueness
//! invariants will be broken respectively.
//! This is a low-level function to be used only for performance reasons
//! by advanced users.
iterator insert_before(const_iterator pos, reference value)
{ return tree_.insert_before(pos, value); }
//! <b>Requires</b>: value must be an lvalue, and it must be greater than
//! any inserted key according to the predicate.
//!
//! <b>Effects</b>: Inserts x into the tree in the last position.
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: This function does not check preconditions so if value is
//! less than or equal to the greatest inserted key tree ordering invariant will be broken.
//! This function is slightly more efficient than using "insert_before".
//! This is a low-level function to be used only for performance reasons
//! by advanced users.
void push_back(reference value)
{ tree_.push_back(value); }
//! <b>Requires</b>: value must be an lvalue, and it must be less
//! than any inserted key according to the predicate.
//!
//! <b>Effects</b>: Inserts x into the tree in the first position.
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: This function does not check preconditions so if value is
//! greater than or equal to the the mimum inserted key tree ordering or uniqueness
//! invariants will be broken.
//! This function is slightly more efficient than using "insert_before".
//! This is a low-level function to be used only for performance reasons
//! by advanced users.
void push_front(reference value)
{ tree_.push_front(value); }
//! <b>Effects</b>: Erases the element pointed to by pos.
//!
//! <b>Complexity</b>: Average complexity is constant time.

View File

@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2008
// (C) Copyright Ion Gaztanaga 2007-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -96,6 +96,7 @@ class avl_set_base_hook
::type
{
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
public:
//! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state.
//!
@@ -221,6 +222,7 @@ class avl_set_member_hook
::type
{
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
public:
//! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state.
//!

View File

@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2008
// (C) Copyright Ion Gaztanaga 2007-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -704,6 +704,76 @@ class avltree_impl
return iterator(to_insert, this);
}
//! <b>Requires</b>: value must be an lvalue, "pos" must be
//! a valid iterator (or end) and must be the succesor of value
//! once inserted according to the predicate
//!
//! <b>Effects</b>: Inserts x into the tree before "pos".
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: This function does not check preconditions so if "pos" is not
//! the successor of "value" tree ordering invariant will be broken.
//! This is a low-level function to be used only for performance reasons
//! by advanced users.
iterator insert_before(const_iterator pos, reference value)
{
node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
this->priv_size_traits().increment();
return iterator(node_algorithms::insert_before
(node_ptr(&priv_header()), pos.pointed_node(), to_insert), this);
}
//! <b>Requires</b>: value must be an lvalue, and it must be no less
//! than the greatest inserted key
//!
//! <b>Effects</b>: Inserts x into the tree in the last position.
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: This function does not check preconditions so if value is
//! less than the greatest inserted key tree ordering invariant will be broken.
//! This function is slightly more efficient than using "insert_before".
//! This is a low-level function to be used only for performance reasons
//! by advanced users.
void push_back(reference value)
{
node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
this->priv_size_traits().increment();
node_algorithms::push_back(node_ptr(&priv_header()), to_insert);
}
//! <b>Requires</b>: value must be an lvalue, and it must be no greater
//! than the minimum inserted key
//!
//! <b>Effects</b>: Inserts x into the tree in the first position.
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: This function does not check preconditions so if value is
//! greater than the minimum inserted key tree ordering invariant will be broken.
//! This function is slightly more efficient than using "insert_before".
//! This is a low-level function to be used only for performance reasons
//! by advanced users.
void push_front(reference value)
{
node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
this->priv_size_traits().increment();
node_algorithms::push_front(node_ptr(&priv_header()), to_insert);
}
//! <b>Effects</b>: Erases the element pointed to by pos.
//!
//! <b>Complexity</b>: Average complexity for erase element is constant time.

View File

@@ -530,6 +530,66 @@ class avltree_algorithms
return new_node;
}
//! <b>Requires</b>: "header" must be the header node of a tree.
//! "pos" must be a valid iterator or header (end) node.
//! "pos" must be an iterator pointing to the successor to "new_node"
//! once inserted according to the order of already inserted nodes. This function does not
//! check "pos" and this precondition must be guaranteed by the caller.
//!
//! <b>Effects</b>: Inserts new_node into the tree before "pos".
//!
//! <b>Complexity</b>: Constant-time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: If "pos" is not the successor of the newly inserted "new_node"
//! tree invariants might be broken.
static node_ptr insert_before
(node_ptr header, node_ptr pos, node_ptr new_node)
{
tree_algorithms::insert_before(header, pos, new_node);
rebalance_after_insertion(header, new_node);
return new_node;
}
//! <b>Requires</b>: "header" must be the header node of a tree.
//! "new_node" must be, according to the used ordering no less than the
//! greatest inserted key.
//!
//! <b>Effects</b>: Inserts new_node into the tree before "pos".
//!
//! <b>Complexity</b>: Constant-time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: If "new_node" is less than the greatest inserted key
//! tree invariants are broken. This function is slightly faster than
//! using "insert_before".
static void push_back(node_ptr header, node_ptr new_node)
{
tree_algorithms::push_back(header, new_node);
rebalance_after_insertion(header, new_node);
}
//! <b>Requires</b>: "header" must be the header node of a tree.
//! "new_node" must be, according to the used ordering, no greater than the
//! lowest inserted key.
//!
//! <b>Effects</b>: Inserts new_node into the tree before "pos".
//!
//! <b>Complexity</b>: Constant-time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: If "new_node" is greater than the lowest inserted key
//! tree invariants are broken. This function is slightly faster than
//! using "insert_before".
static void push_front(node_ptr header, node_ptr new_node)
{
tree_algorithms::push_front(header, new_node);
rebalance_after_insertion(header, new_node);
}
//! <b>Requires</b>: "header" must be the header node of a tree.
//! KeyNodePtrCompare is a function object that induces a strict weak
//! ordering compatible with the strict weak ordering used to create the

View File

@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2008
// (C) Copyright Ion Gaztanaga 2007-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -96,6 +96,7 @@ class bs_set_base_hook
{
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
public:
//! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state.
//!
@@ -220,6 +221,7 @@ class bs_set_member_hook
::type
{
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
public:
//! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state.
//!

View File

@@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
// (C) Copyright Ion Gaztanaga 2006-2008
// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -110,7 +110,7 @@ class circular_list_algorithms
//! <b>Effects</b>: Returns the number of nodes in a circular list. If the circular list
//! is empty, returns 1.
//!
//! <b>Complexity</b>: Constant
//! <b>Complexity</b>: Linear
//!
//! <b>Throws</b>: Nothing.
static std::size_t count(const_node_ptr this_node)

View File

@@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
// (C) Copyright Ion Gaztanaga 2006-2008
// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -199,7 +199,7 @@ class circular_slist_algorithms
//! <b>Effects</b>: Returns the number of nodes in a circular list. If the circular list
//! is empty, returns 1.
//!
//! <b>Complexity</b>: Constant
//! <b>Complexity</b>: Linear
//!
//! <b>Throws</b>: Nothing.
static std::size_t count(const_node_ptr this_node)

View File

@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2008
// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2008
// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2008
// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,6 +1,6 @@
//////} // ///////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2008-2008. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2008-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)
//

View File

@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2008
// (C) Copyright Ion Gaztanaga 2007-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -74,15 +74,22 @@ class common_slist_algorithms
NodeTraits::set_next(prev_node, this_node);
}
static void transfer_after(node_ptr p, node_ptr b, node_ptr e)
static void incorporate_after(node_ptr bp, node_ptr b, node_ptr be)
{
if (p != b && p != e && b != e) {
node_ptr next_b = NodeTraits::get_next(b);
node_ptr next_e = NodeTraits::get_next(e);
node_ptr next_p = NodeTraits::get_next(p);
NodeTraits::set_next(b, next_e);
NodeTraits::set_next(e, next_p);
NodeTraits::set_next(p, next_b);
node_ptr p(NodeTraits::get_next(bp));
NodeTraits::set_next(bp, b);
NodeTraits::set_next(be, p);
}
static void transfer_after(node_ptr bp, node_ptr bb, node_ptr be)
{
if (bp != bb && bp != be && bb != be) {
node_ptr next_b = NodeTraits::get_next(bb);
node_ptr next_e = NodeTraits::get_next(be);
node_ptr next_p = NodeTraits::get_next(bp);
NodeTraits::set_next(bb, next_e);
NodeTraits::set_next(be, next_p);
NodeTraits::set_next(bp, next_b);
}
}
};

View File

@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2008
// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2008
// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Joaquin M Lopez Munoz 2006-2008
// (C) Copyright Joaquin M Lopez Munoz 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -13,6 +13,7 @@
#ifndef BOOST_INTRUSIVE_DETAIL_EBO_HOLDER_HPP
#define BOOST_INTRUSIVE_DETAIL_EBO_HOLDER_HPP
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/detail/mpl.hpp>
namespace boost {
@@ -89,4 +90,6 @@ class ebo_functor_holder
} //namespace intrusive {
} //namespace boost {
#include <boost/intrusive/detail/config_end.hpp>
#endif //#ifndef BOOST_INTRUSIVE_DETAIL_EBO_HOLDER_HPP

View File

@@ -0,0 +1,87 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2009-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)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
// This code was modified from the code posted by Alexandre Courpron in his
// article "Interface Detection" in The Code Project:
///////////////////////////////////////////////////////////////////////////////
// Copyright 2007 Alexandre Courpron
//
// Permission to use, copy, modify, redistribute and sell this software,
// provided that this copyright notice appears on all copies of the software.
///////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DETAIL_FUNCTION_DETECTOR_HPP
#define BOOST_INTRUSIVE_DETAIL_FUNCTION_DETECTOR_HPP
#include <boost/intrusive/detail/config_begin.hpp>
namespace boost {
namespace intrusive {
namespace function_detector {
typedef char NotFoundType;
struct StaticFunctionType { NotFoundType x [2]; };
struct NonStaticFunctionType { NotFoundType x [3]; };
enum
{ NotFound = 0,
StaticFunction = sizeof( StaticFunctionType ) - sizeof( NotFoundType ),
NonStaticFunction = sizeof( NonStaticFunctionType ) - sizeof( NotFoundType )
};
} //namespace boost {
} //namespace intrusive {
} //namespace function_detector {
#define BOOST_INTRUSIVE_CREATE_FUNCTION_DETECTOR(Identifier, InstantiationKey) \
namespace boost { \
namespace intrusive { \
namespace function_detector { \
template < class T, \
class NonStaticType, \
class NonStaticConstType, \
class StaticType > \
class DetectMember_##InstantiationKey_##Identifier { \
template < NonStaticType > \
struct TestNonStaticNonConst ; \
\
template < NonStaticConstType > \
struct TestNonStaticConst ; \
\
template < StaticType > \
struct TestStatic ; \
\
template <class U > \
static NonStaticFunctionType Test( TestNonStaticNonConst<&U::Identifier>*, int ); \
\
template <class U > \
static NonStaticFunctionType Test( TestNonStaticConst<&U::Identifier>*, int ); \
\
template <class U> \
static StaticFunctionType Test( TestStatic<&U::Identifier>*, int ); \
\
template <class U> \
static NotFoundType Test( ... ); \
public : \
static const int check = NotFound + (sizeof(Test<T>(0, 0)) - sizeof(NotFoundType));\
};\
}}} //namespace boost::intrusive::function_detector {
#define BOOST_INTRUSIVE_DETECT_FUNCTION(Class, InstantiationKey, ReturnType, Identifier, Params) \
::boost::intrusive::function_detector::DetectMember_##InstantiationKey_##Identifier< Class,\
ReturnType (Class::*)Params,\
ReturnType (Class::*)Params const,\
ReturnType (*)Params \
>::check
#include <boost/intrusive/detail/config_end.hpp>
#endif //@ifndef BOOST_INTRUSIVE_DETAIL_FUNCTION_DETECTOR_HPP

View File

@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2008
// (C) Copyright Ion Gaztanaga 2007-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2008
// (C) Copyright Ion Gaztanaga 2007-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -100,8 +100,12 @@ template<class Container, bool IsConst>
class hashtable_iterator
: public std::iterator
< std::forward_iterator_tag
, typename Container::value_type
, typename std::iterator_traits<typename Container::value_type*>::difference_type
, typename detail::add_const_if_c
<typename Container::value_type, IsConst>::type
<typename Container::value_type, IsConst>::type *
, typename detail::add_const_if_c
<typename Container::value_type, IsConst>::type &
>
{
typedef typename Container::real_value_traits real_value_traits;
@@ -116,8 +120,11 @@ class hashtable_iterator
{ return typename Container::node_ptr(&static_cast<typename Container::node&>(*p)); }
public:
typedef typename Container::value_type value_type;
typedef typename detail::add_const_if_c
<typename Container::value_type, IsConst>::type value_type;
<typename Container::value_type, IsConst>::type *pointer;
typedef typename detail::add_const_if_c
<typename Container::value_type, IsConst>::type &reference;
hashtable_iterator ()
{}
@@ -133,6 +140,9 @@ class hashtable_iterator
const siterator &slist_it() const
{ return slist_it_; }
hashtable_iterator<Container, false> unconst() const
{ return hashtable_iterator<Container, false>(this->slist_it(), this->get_container()); }
public:
hashtable_iterator& operator++()
{ this->increment(); return *this; }
@@ -150,10 +160,10 @@ class hashtable_iterator
friend bool operator!= (const hashtable_iterator& i, const hashtable_iterator& i2)
{ return !(i == i2); }
value_type& operator*() const
reference operator*() const
{ return *this->operator ->(); }
value_type* operator->() const
pointer operator->() const
{ return detail::get_pointer(this->get_real_value_traits()->to_value_ptr(downcast_bucket(slist_it_.pointed_node()))); }
const Container *get_container() const

View File

@@ -0,0 +1,56 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2009-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)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DETAIL_IS_STATEFUL_VALUE_TRAITS_HPP
#define BOOST_INTRUSIVE_DETAIL_IS_STATEFUL_VALUE_TRAITS_HPP
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/detail/function_detector.hpp>
BOOST_INTRUSIVE_CREATE_FUNCTION_DETECTOR(to_node_ptr, boost_intrusive)
BOOST_INTRUSIVE_CREATE_FUNCTION_DETECTOR(to_value_ptr, boost_intrusive)
namespace boost {
namespace intrusive {
namespace detail {
template<class ValueTraits>
struct is_stateful_value_traits
{
typedef typename ValueTraits::node_ptr node_ptr;
typedef typename ValueTraits::pointer pointer;
typedef typename ValueTraits::value_type value_type;
typedef typename ValueTraits::const_node_ptr const_node_ptr;
typedef typename ValueTraits::const_pointer const_pointer;
typedef ValueTraits value_traits;
static const bool value =
(boost::intrusive::function_detector::NonStaticFunction ==
(BOOST_INTRUSIVE_DETECT_FUNCTION(ValueTraits, boost_intrusive, node_ptr, to_node_ptr, (value_type&) )))
||
(boost::intrusive::function_detector::NonStaticFunction ==
(BOOST_INTRUSIVE_DETECT_FUNCTION(ValueTraits, boost_intrusive, pointer, to_value_ptr, (node_ptr) )))
||
(boost::intrusive::function_detector::NonStaticFunction ==
(BOOST_INTRUSIVE_DETECT_FUNCTION(ValueTraits, boost_intrusive, const_node_ptr, to_node_ptr, (const value_type&) )))
||
(boost::intrusive::function_detector::NonStaticFunction ==
(BOOST_INTRUSIVE_DETECT_FUNCTION(ValueTraits, boost_intrusive, const_pointer, to_value_ptr, (const_node_ptr) )))
;
};
}}}
#include <boost/intrusive/detail/config_end.hpp>
#endif //@ifndef BOOST_INTRUSIVE_DETAIL_IS_STATEFUL_VALUE_TRAITS_HPP

View File

@@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
// (C) Copyright Ion Gaztanaga 2006-2008
// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -63,8 +63,12 @@ template<class Container, bool IsConst>
class list_iterator
: public std::iterator
< std::bidirectional_iterator_tag
, typename Container::value_type
, typename std::iterator_traits<typename Container::value_type*>::difference_type
, typename detail::add_const_if_c
<typename Container::value_type, IsConst>::type
<typename Container::value_type, IsConst>::type *
, typename detail::add_const_if_c
<typename Container::value_type, IsConst>::type &
>
{
protected:
@@ -78,11 +82,11 @@ class list_iterator
detail::store_cont_ptr_on_it<Container>::value;
public:
typedef typename Container::value_type value_type;
typedef typename detail::add_const_if_c
<typename Container::value_type, IsConst>
::type value_type;
typedef value_type & reference;
typedef value_type * pointer;
<typename Container::value_type, IsConst>::type *pointer;
typedef typename detail::add_const_if_c
<typename Container::value_type, IsConst>::type &reference;
list_iterator()
: members_ (node_ptr(0), 0)
@@ -135,7 +139,7 @@ class list_iterator
bool operator!= (const list_iterator& i) const
{ return !operator== (i); }
value_type& operator*() const
reference operator*() const
{ return *operator->(); }
pointer operator->() const

View File

@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2008
// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -13,6 +13,7 @@
#ifndef BOOST_INTRUSIVE_DETAIL_MPL_HPP
#define BOOST_INTRUSIVE_DETAIL_MPL_HPP
#include <boost/intrusive/detail/config_begin.hpp>
#include <cstddef>
namespace boost {
@@ -364,4 +365,6 @@ struct ls_zeros<1>
} //namespace intrusive
} //namespace boost
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_DETAIL_MPL_HPP

View File

@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2008
// (C) Copyright Ion Gaztanaga 2007-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
// (C) Copyright Ion Gaztanaga 2006-2008.
// (C) Copyright Ion Gaztanaga 2006-2009.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
// (C) Copyright Ion Gaztanaga 2006-2008
// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -55,8 +55,12 @@ template<class Container, bool IsConst>
class slist_iterator
: public std::iterator
< std::forward_iterator_tag
, typename Container::value_type
, typename std::iterator_traits<typename Container::value_type*>::difference_type
, typename detail::add_const_if_c
<typename Container::value_type, IsConst>::type
<typename Container::value_type, IsConst>::type *
, typename detail::add_const_if_c
<typename Container::value_type, IsConst>::type &
>
{
protected:
@@ -70,11 +74,11 @@ class slist_iterator
detail::store_cont_ptr_on_it<Container>::value;
public:
typedef typename Container::value_type value_type;
typedef typename detail::add_const_if_c
<typename Container::value_type, IsConst>
::type value_type;
typedef value_type & reference;
typedef value_type * pointer;
<typename Container::value_type, IsConst>::type *pointer;
typedef typename detail::add_const_if_c
<typename Container::value_type, IsConst>::type &reference;
slist_iterator()
: members_ (node_ptr(0), 0)
@@ -114,7 +118,7 @@ class slist_iterator
bool operator!= (const slist_iterator& i) const
{ return !operator== (i); }
value_type& operator*() const
reference operator*() const
{ return *operator->(); }
pointer operator->() const

View File

@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2008
// (C) Copyright Ion Gaztanaga 2007-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at

View File

@@ -160,7 +160,7 @@ class tree_algorithms
//!
//! <b>Throws</b>: Nothing.
static bool unique(const_node_ptr node)
{ return NodeTraits::get_parent(node) == 0; }
{ return !NodeTraits::get_parent(node); }
static node_ptr get_header(const_node_ptr node)
{
@@ -460,7 +460,8 @@ class tree_algorithms
static node_ptr prev_node(node_ptr p)
{
if(is_header(p)){
return maximum(NodeTraits::get_parent(p));
return NodeTraits::get_right(p);
//return maximum(NodeTraits::get_parent(p));
}
else if(NodeTraits::get_left(p)){
return maximum(NodeTraits::get_left(p));
@@ -721,21 +722,19 @@ class tree_algorithms
static bool is_header(const_node_ptr p)
{
bool is_header = false;
if(NodeTraits::get_parent(p) == p){
is_header = true;
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;
}
else if(NodeTraits::get_parent(NodeTraits::get_parent(p)) == p){
if(NodeTraits::get_left(p) != 0){
if(NodeTraits::get_parent(NodeTraits::get_left(p)) != p){
is_header = true;
}
if(NodeTraits::get_parent(p) == NodeTraits::get_left(p)){
is_header = true;
}
}
}
return is_header;
return false;
}
//! <b>Requires</b>: "header" must be the header node of a tree.
@@ -894,10 +893,32 @@ class tree_algorithms
//! erased between the "insert_check" and "insert_commit" calls.
static void insert_unique_commit
(node_ptr header, node_ptr new_value, const insert_commit_data &commit_data)
{ return insert_commit(header, new_value, commit_data); }
static void insert_commit
(node_ptr header, node_ptr new_node, const insert_commit_data &commit_data)
{
//Check if commit_data has not been initialized by a insert_unique_check call.
BOOST_INTRUSIVE_INVARIANT_ASSERT(commit_data.node != 0);
link(header, new_value, commit_data.node, commit_data.link_left);
node_ptr parent_node(commit_data.node);
if(parent_node == header){
NodeTraits::set_parent(header, new_node);
NodeTraits::set_right(header, new_node);
NodeTraits::set_left(header, new_node);
}
else if(commit_data.link_left){
NodeTraits::set_left(parent_node, new_node);
if(parent_node == NodeTraits::get_left(header))
NodeTraits::set_left(header, new_node);
}
else{
NodeTraits::set_right(parent_node, new_node);
if(parent_node == NodeTraits::get_right(header))
NodeTraits::set_right(header, new_node);
}
NodeTraits::set_parent(new_node, parent_node);
NodeTraits::set_right(new_node, node_ptr(0));
NodeTraits::set_left(new_node, node_ptr(0));
}
//! <b>Requires</b>: "header" must be the header node of a tree.
@@ -979,9 +1000,9 @@ class tree_algorithms
{
//hint must be bigger than the key
if(hint == header || comp(key, hint)){
node_ptr prev = hint;
//The previous value should be less than the key
if(prev == NodeTraits::get_left(header) || comp((prev = prev_node(hint)), key)){
node_ptr prev(hint);
//Previous value should be less than the key
if(hint == begin_node(header)|| comp((prev = prev_node(hint)), key)){
commit_data.link_left = unique(header) || !NodeTraits::get_left(hint);
commit_data.node = commit_data.link_left ? hint : prev;
if(pdepth){
@@ -989,15 +1010,10 @@ class tree_algorithms
}
return std::pair<node_ptr, bool>(node_ptr(), true);
}
else{
}
//Hint was wrong, use hintless insertion
return insert_unique_check(header, key, comp, commit_data, pdepth);
}
}
//The hint was wrong, use hintless insert
else{
return insert_unique_check(header, key, comp, commit_data, pdepth);
}
}
template<class NodePtrCompare>
static void insert_equal_check
@@ -1040,7 +1056,7 @@ class tree_algorithms
{
insert_commit_data commit_data;
insert_equal_check(h, hint, new_node, comp, commit_data, pdepth);
link(h, new_node, commit_data.node, commit_data.link_left);
insert_commit(h, new_node, commit_data);
return new_node;
}
@@ -1050,7 +1066,7 @@ class tree_algorithms
{
insert_commit_data commit_data;
insert_equal_upper_bound_check(h, new_node, comp, commit_data, pdepth);
link(h, new_node, commit_data.node, commit_data.link_left);
insert_commit(h, new_node, commit_data);
return new_node;
}
@@ -1060,10 +1076,72 @@ class tree_algorithms
{
insert_commit_data commit_data;
insert_equal_lower_bound_check(h, new_node, comp, commit_data, pdepth);
link(h, new_node, commit_data.node, commit_data.link_left);
insert_commit(h, new_node, commit_data);
return new_node;
}
static node_ptr insert_before
(node_ptr header, node_ptr pos, node_ptr new_node, std::size_t *pdepth = 0)
{
insert_commit_data commit_data;
insert_before_check(header, pos, commit_data, pdepth);
insert_commit(header, new_node, commit_data);
return new_node;
}
static void insert_before_check
( node_ptr header, node_ptr pos
, insert_commit_data &commit_data, std::size_t *pdepth = 0)
{
node_ptr prev(pos);
if(pos != NodeTraits::get_left(header))
prev = prev_node(pos);
bool link_left = unique(header) || !NodeTraits::get_left(pos);
commit_data.link_left = link_left;
commit_data.node = link_left ? pos : prev;
if(pdepth){
*pdepth = commit_data.node == header ? 0 : depth(commit_data.node) + 1;
}
}
static void push_back
(node_ptr header, node_ptr new_node, std::size_t *pdepth = 0)
{
insert_commit_data commit_data;
push_back_check(header, commit_data, pdepth);
insert_commit(header, new_node, commit_data);
}
static void push_back_check
(node_ptr header, insert_commit_data &commit_data, std::size_t *pdepth = 0)
{
node_ptr prev(NodeTraits::get_right(header));
if(pdepth){
*pdepth = prev == header ? 0 : depth(prev) + 1;
}
commit_data.link_left = false;
commit_data.node = prev;
}
static void push_front
(node_ptr header, node_ptr new_node, std::size_t *pdepth = 0)
{
insert_commit_data commit_data;
push_front_check(header, commit_data, pdepth);
insert_commit(header, new_node, commit_data);
}
static void push_front_check
(node_ptr header, insert_commit_data &commit_data, std::size_t *pdepth = 0)
{
node_ptr pos(NodeTraits::get_left(header));
if(pdepth){
*pdepth = pos == header ? 0 : depth(pos) + 1;
}
commit_data.link_left = true;
commit_data.node = pos;
}
//! <b>Requires</b>: p can't be a header node.
//!
//! <b>Effects</b>: Calculates the depth of a node: the depth of a
@@ -1303,32 +1381,10 @@ class tree_algorithms
replace_own_impl(p, x, header, p_old_parent, p_was_left);
}
static void link(node_ptr header, node_ptr z, node_ptr par, bool left)
{
if(par == header){
NodeTraits::set_parent(header, z);
NodeTraits::set_right(header, z);
NodeTraits::set_left(header, z);
}
else if(left){
NodeTraits::set_left(par, z);
if(par == NodeTraits::get_left(header))
NodeTraits::set_left(header, z);
}
else{
NodeTraits::set_right(par, z);
if(par == NodeTraits::get_right(header))
NodeTraits::set_right(header, z);
}
NodeTraits::set_parent(z, par);
NodeTraits::set_right(z, node_ptr(0));
NodeTraits::set_left(z, node_ptr(0));
}
static void erase(node_ptr header, node_ptr z)
{
data_for_rebalance ignored;
erase(header, z, nop_erase_fixup(), ignored);
erase_impl(header, z, ignored);
}
struct data_for_rebalance
@@ -1609,12 +1665,12 @@ class tree_algorithms
NodeTraits::set_parent(x, x_parent);
tree_algorithms::replace_own (z, x, header);
if(NodeTraits::get_left(header) == z){
NodeTraits::set_left(header, NodeTraits::get_right(z) == 0 ? // z->get_left() must be null also
NodeTraits::set_left(header, !NodeTraits::get_right(z) ? // z->get_left() must be null also
NodeTraits::get_parent(z) : // makes leftmost == header if z == root
tree_algorithms::minimum (x));
}
if(NodeTraits::get_right(header) == z){
NodeTraits::set_right(header, NodeTraits::get_left(z) == 0 ? // z->get_right() must be null also
NodeTraits::set_right(header, !NodeTraits::get_left(z) ? // z->get_right() must be null also
NodeTraits::get_parent(z) : // makes rightmost == header if z == root
tree_algorithms::maximum(x));
}

View File

@@ -72,8 +72,12 @@ template<class Container, bool IsConst>
class tree_iterator
: public std::iterator
< std::bidirectional_iterator_tag
, typename Container::value_type
, typename std::iterator_traits<typename Container::value_type*>::difference_type
, typename detail::add_const_if_c
<typename Container::value_type, IsConst>::type
<typename Container::value_type, IsConst>::type *
, typename detail::add_const_if_c
<typename Container::value_type, IsConst>::type &
>
{
protected:
@@ -88,12 +92,11 @@ class tree_iterator
detail::store_cont_ptr_on_it<Container>::value;
public:
public:
typedef typename Container::value_type value_type;
typedef typename detail::add_const_if_c
<typename Container::value_type, IsConst>
::type value_type;
typedef value_type & reference;
typedef value_type * pointer;
<typename Container::value_type, IsConst>::type *pointer;
typedef typename detail::add_const_if_c
<typename Container::value_type, IsConst>::type &reference;
tree_iterator()
: members_ (0, 0)
@@ -146,27 +149,17 @@ class tree_iterator
bool operator!= (const tree_iterator& i) const
{ return !operator== (i); }
value_type& operator*() const
reference operator*() const
{ return *operator->(); }
pointer operator->() const
{ 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<const Container*>(members_.get_ptr());
else
return 0;
}
{ return static_cast<const Container*>(members_.get_ptr()); }
const real_value_traits *get_real_value_traits() const
{
if(store_container_ptr)
return &this->get_container()->get_real_value_traits();
else
return 0;
}
{ return &this->get_container()->get_real_value_traits(); }
tree_iterator end_iterator_from_it() const
{

View File

@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2008
// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -20,6 +20,7 @@
#include <boost/intrusive/link_mode.hpp>
#include <boost/intrusive/detail/mpl.hpp>
#include <boost/intrusive/detail/assert.hpp>
#include <boost/intrusive/detail/is_stateful_value_traits.hpp>
#include <boost/cstdint.hpp>
#include <cstddef>
#include <climits>
@@ -45,8 +46,7 @@ struct internal_base_hook_bool
template<bool Add>
struct two_or_three {one _[2 + Add];};
template <class U> static one test(...);
template <class U> static two_or_three<U::boost_intrusive_tags::is_base_hook>
test (int);
template <class U> static two_or_three<U::boost_intrusive_tags::is_base_hook> test (int);
static const std::size_t value = sizeof(test<T>(0));
};
@@ -62,8 +62,7 @@ struct internal_any_hook_bool
template<bool Add>
struct two_or_three {one _[2 + Add];};
template <class U> static one test(...);
template <class U> static two_or_three<U::is_any_hook>
test (int);
template <class U> static two_or_three<U::is_any_hook> test (int);
static const std::size_t value = sizeof(test<T>(0));
};
@@ -80,8 +79,7 @@ struct external_value_traits_bool
template<bool Add>
struct two_or_three {one _[2 + Add];};
template <class U> static one test(...);
template <class U> static two_or_three<U::external_value_traits>
test (int);
template <class U> static two_or_three<U::external_value_traits> test (int);
static const std::size_t value = sizeof(test<T>(0));
};
@@ -91,8 +89,7 @@ struct external_bucket_traits_bool
template<bool Add>
struct two_or_three {one _[2 + Add];};
template <class U> static one test(...);
template <class U> static two_or_three<U::external_bucket_traits>
test (int);
template <class U> static two_or_three<U::external_bucket_traits> test (int);
static const std::size_t value = sizeof(test<T>(0));
};
@@ -337,16 +334,6 @@ struct select_constptr
>::type type;
};
template <class Container>
struct store_cont_ptr_on_it
{
typedef typename Container::value_traits value_traits;
static const bool value =
!detail::is_empty_class<value_traits>::value
|| detail::external_value_traits_is_true<value_traits>::value
;
};
template<class T, bool Add>
struct add_const_if_c
{
@@ -357,58 +344,6 @@ struct add_const_if_c
>::type type;
};
template<class Container, bool IsConst>
struct node_to_value
: public detail::select_constptr
< typename boost::pointer_to_other
<typename Container::pointer, void>::type
, detail::store_cont_ptr_on_it<Container>::value
>::type
{
static const bool store_container_ptr =
detail::store_cont_ptr_on_it<Container>::value;
typedef typename Container::real_value_traits real_value_traits;
typedef typename real_value_traits::value_type value_type;
typedef typename detail::select_constptr
< typename boost::pointer_to_other
<typename Container::pointer, void>::type
, store_container_ptr >::type Base;
typedef typename real_value_traits::node_traits::node node;
typedef typename detail::add_const_if_c
<value_type, IsConst>::type vtype;
typedef typename detail::add_const_if_c
<node, IsConst>::type ntype;
typedef typename boost::pointer_to_other
<typename Container::pointer, ntype>::type npointer;
node_to_value(const Container *cont)
: Base(cont)
{}
typedef vtype & result_type;
typedef ntype & first_argument_type;
const Container *get_container() const
{
if(store_container_ptr)
return static_cast<const Container*>(Base::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;
}
result_type operator()(first_argument_type arg) const
{ return *(this->get_real_value_traits()->to_value_ptr(npointer(&arg))); }
};
template <link_mode_type LinkMode>
struct link_dispatch
{};
@@ -625,6 +560,79 @@ class exception_array_disposer
}
};
template<class ValueTraits, bool ExternalValueTraits>
struct store_cont_ptr_on_it_impl
{
static const bool value = is_stateful_value_traits<ValueTraits>::value;
};
template<class ValueTraits>
struct store_cont_ptr_on_it_impl<ValueTraits, true>
{
static const bool value = false;
};
template <class Container>
struct store_cont_ptr_on_it
{
typedef typename Container::value_traits value_traits;
static const bool value = store_cont_ptr_on_it_impl
<value_traits, external_value_traits_is_true<value_traits>::value>::value;
};
template<class Container, bool IsConst>
struct node_to_value
: public detail::select_constptr
< typename boost::pointer_to_other
<typename Container::pointer, void>::type
, detail::store_cont_ptr_on_it<Container>::value
>::type
{
static const bool store_container_ptr =
detail::store_cont_ptr_on_it<Container>::value;
typedef typename Container::real_value_traits real_value_traits;
typedef typename real_value_traits::value_type value_type;
typedef typename detail::select_constptr
< typename boost::pointer_to_other
<typename Container::pointer, void>::type
, store_container_ptr >::type Base;
typedef typename real_value_traits::node_traits::node node;
typedef typename detail::add_const_if_c
<value_type, IsConst>::type vtype;
typedef typename detail::add_const_if_c
<node, IsConst>::type ntype;
typedef typename boost::pointer_to_other
<typename Container::pointer, ntype>::type npointer;
node_to_value(const Container *cont)
: Base(cont)
{}
typedef vtype & result_type;
typedef ntype & first_argument_type;
const Container *get_container() const
{
if(store_container_ptr)
return static_cast<const Container*>(Base::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;
}
result_type operator()(first_argument_type arg) const
{ return *(this->get_real_value_traits()->to_value_ptr(npointer(&arg))); }
};
} //namespace detail
} //namespace intrusive
} //namespace boost

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-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)
//

View File

@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2008
// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -186,8 +186,7 @@ struct store_hash_bool
template<bool Add>
struct two_or_three {one _[2 + Add];};
template <class U> static one test(...);
template <class U> static two_or_three<U::store_hash>
test (int);
template <class U> static two_or_three<U::store_hash> test (int);
static const std::size_t value = sizeof(test<T>(0));
};
@@ -203,8 +202,7 @@ struct optimize_multikey_bool
template<bool Add>
struct two_or_three {one _[2 + Add];};
template <class U> static one test(...);
template <class U> static two_or_three<U::optimize_multikey>
test (int);
template <class U> static two_or_three<U::optimize_multikey> test (int);
static const std::size_t value = sizeof(test<T>(0));
};
@@ -603,7 +601,7 @@ class hashtable_impl
typedef typename real_value_traits::pointer pointer;
typedef typename real_value_traits::const_pointer const_pointer;
typedef typename std::iterator_traits<pointer>::value_type value_type;
typedef typename real_value_traits::value_type value_type;
typedef typename std::iterator_traits<pointer>::reference reference;
typedef typename std::iterator_traits<const_pointer>::reference const_reference;
typedef typename std::iterator_traits<pointer>::difference_type difference_type;
@@ -626,7 +624,7 @@ class hashtable_impl
<node_ptr, const node>::type const_node_ptr;
typedef typename slist_impl::node_algorithms node_algorithms;
static const bool stateful_value_traits = detail::store_cont_ptr_on_it<hashtable_impl>::value;
static const bool stateful_value_traits = detail::is_stateful_value_traits<real_value_traits>::value;
static const bool store_hash = detail::store_hash_is_true<node_traits>::value;
static const bool unique_keys = 0 != (Config::bool_flags & detail::hash_bool_flags::unique_keys_pos);
@@ -1231,8 +1229,8 @@ class hashtable_impl
//!
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased element. No destructors are called.
void erase(const_iterator i)
{ this->erase_and_dispose(i, detail::null_disposer()); }
iterator erase(const_iterator i)
{ return this->erase_and_dispose(i, detail::null_disposer()); }
//! <b>Effects</b>: Erases the range pointed to by b end e.
//!
@@ -1243,8 +1241,8 @@ class hashtable_impl
//!
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
void erase(const_iterator b, const_iterator e)
{ this->erase_and_dispose(b, e, detail::null_disposer()); }
iterator erase(const_iterator b, const_iterator e)
{ return this->erase_and_dispose(b, e, detail::null_disposer()); }
//! <b>Effects</b>: Erases all the elements with the given value.
//!
@@ -1297,19 +1295,20 @@ class hashtable_impl
//! <b>Note</b>: Invalidates the iterators
//! to the erased elements.
template<class Disposer>
void erase_and_dispose(const_iterator i, Disposer disposer)
iterator erase_and_dispose(const_iterator i, Disposer disposer
/// @cond
, typename detail::enable_if_c<!detail::is_convertible<Disposer, const_iterator>::value >::type * = 0
/// @endcond
)
{
iterator ret(i.unconst());
++ret;
priv_erase(i, disposer, optimize_multikey_t());
this->priv_size_traits().decrement();
priv_erasure_update_cache();
return ret;
}
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class Disposer>
iterator erase_and_dispose(iterator i, Disposer disposer)
{ return this->erase_and_dispose(const_iterator(i), disposer); }
#endif
//! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//!
//! <b>Effects</b>: Erases the range pointed to by b end e.
@@ -1323,10 +1322,9 @@ class hashtable_impl
//! <b>Note</b>: Invalidates the iterators
//! to the erased elements.
template<class Disposer>
void erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer)
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer)
{
if(b == e) return;
if(b != e){
//Get the bucket number and local iterator for both iterators
siterator first_local_it(b.slist_it());
size_type first_bucket_num = this->priv_get_bucket_num(first_local_it);
@@ -1349,6 +1347,8 @@ class hashtable_impl
priv_erase_range(before_first_local_it, first_bucket_num, last_local_it, last_bucket_num, disposer);
priv_erasure_update_cache(first_bucket_num, last_bucket_num);
}
return e.unconst();
}
//! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//!

View File

@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2008
// (C) Copyright Ion Gaztanaga 2007-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
// (C) Copyright Ion Gaztanaga 2006-2008
// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -156,7 +156,7 @@ class linear_slist_algorithms
//! <b>Effects</b>: Returns the number of nodes in a linear list. If the linear list
//! is empty, returns 1.
//!
//! <b>Complexity</b>: Constant
//! <b>Complexity</b>: Linear
//!
//! <b>Throws</b>: Nothing.
static std::size_t count(const_node_ptr this_node)

View File

@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2008
// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
// (C) Copyright Ion Gaztanaga 2006-2008
// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -106,7 +106,8 @@ class list_impl
typedef circular_list_algorithms<node_traits> node_algorithms;
static const bool constant_time_size = Config::constant_time_size;
static const bool stateful_value_traits = detail::store_cont_ptr_on_it<list_impl>::value;
static const bool stateful_value_traits = detail::is_stateful_value_traits<real_value_traits>::value;
BOOST_STATIC_ASSERT(( stateful_value_traits == false ));
/// @cond

View File

@@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
// (C) Copyright Ion Gaztanaga 2006-2008
// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -93,6 +93,7 @@ class list_base_hook
::type
{
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
public:
//! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state.
//!
@@ -214,6 +215,7 @@ class list_member_hook
::type
{
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
public:
//! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state.
//!

View File

@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2008
// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2008
// (C) Copyright Ion Gaztanaga 2007-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2008
// (C) Copyright Ion Gaztanaga 2007-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -50,7 +50,7 @@ template<class Pointer, std::size_t NumBits>
struct pointer_plus_bits;
//!This is the specialization to embed extra bits of information
//!in a raw pointer. The extra bits are stored in the lower bit of the pointer.
//!in a raw pointer. The extra bits are stored in the lower bits of the pointer.
template<class T, std::size_t NumBits>
struct pointer_plus_bits<T*, NumBits>
{

View File

@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2008
// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -29,6 +29,7 @@
#include <boost/intrusive/detail/mpl.hpp>
#include <boost/intrusive/detail/pointer_to_other.hpp>
#include <boost/intrusive/detail/clear_on_destructor_base.hpp>
#include <boost/intrusive/detail/function_detector.hpp>
#include <boost/intrusive/options.hpp>
#include <boost/intrusive/rbtree_algorithms.hpp>
#include <boost/intrusive/link_mode.hpp>
@@ -116,8 +117,7 @@ class rbtree_impl
typedef rbtree_algorithms<node_traits> node_algorithms;
static const bool constant_time_size = Config::constant_time_size;
static const bool stateful_value_traits = detail::store_cont_ptr_on_it<rbtree_impl>::value;
static const bool stateful_value_traits = detail::is_stateful_value_traits<real_value_traits>::value;
/// @cond
private:
typedef detail::size_holder<constant_time_size, size_type> size_traits;
@@ -704,6 +704,76 @@ class rbtree_impl
return iterator(to_insert, this);
}
//! <b>Requires</b>: value must be an lvalue, "pos" must be
//! a valid iterator (or end) and must be the succesor of value
//! once inserted according to the predicate
//!
//! <b>Effects</b>: Inserts x into the tree before "pos".
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: This function does not check preconditions so if "pos" is not
//! the successor of "value" tree ordering invariant will be broken.
//! This is a low-level function to be used only for performance reasons
//! by advanced users.
iterator insert_before(const_iterator pos, reference value)
{
node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
this->priv_size_traits().increment();
return iterator(node_algorithms::insert_before
(node_ptr(&priv_header()), pos.pointed_node(), to_insert), this);
}
//! <b>Requires</b>: value must be an lvalue, and it must be no less
//! than the greatest inserted key
//!
//! <b>Effects</b>: Inserts x into the tree in the last position.
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: This function does not check preconditions so if value is
//! less than the greatest inserted key tree ordering invariant will be broken.
//! This function is slightly more efficient than using "insert_before".
//! This is a low-level function to be used only for performance reasons
//! by advanced users.
void push_back(reference value)
{
node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
this->priv_size_traits().increment();
node_algorithms::push_back(node_ptr(&priv_header()), to_insert);
}
//! <b>Requires</b>: value must be an lvalue, and it must be no greater
//! than the minimum inserted key
//!
//! <b>Effects</b>: Inserts x into the tree in the first position.
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: This function does not check preconditions so if value is
//! greater than the minimum inserted key tree ordering invariant will be broken.
//! This function is slightly more efficient than using "insert_before".
//! This is a low-level function to be used only for performance reasons
//! by advanced users.
void push_front(reference value)
{
node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
this->priv_size_traits().increment();
node_algorithms::push_front(node_ptr(&priv_header()), to_insert);
}
//! <b>Effects</b>: Erases the element pointed to by pos.
//!
//! <b>Complexity</b>: Average complexity for erase element is constant time.

View File

@@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
// (C) Copyright Ion Gaztanaga 2006-2008.
// (C) Copyright Ion Gaztanaga 2006-2009.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -585,6 +585,66 @@ class rbtree_algorithms
return new_node;
}
//! <b>Requires</b>: "header" must be the header node of a tree.
//! "pos" must be a valid iterator or header (end) node.
//! "pos" must be an iterator pointing to the successor to "new_node"
//! once inserted according to the order of already inserted nodes. This function does not
//! check "pos" and this precondition must be guaranteed by the caller.
//!
//! <b>Effects</b>: Inserts new_node into the tree before "pos".
//!
//! <b>Complexity</b>: Constant-time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: If "pos" is not the successor of the newly inserted "new_node"
//! tree invariants might be broken.
static node_ptr insert_before
(node_ptr header, node_ptr pos, node_ptr new_node)
{
tree_algorithms::insert_before(header, pos, new_node);
rebalance_after_insertion(header, new_node);
return new_node;
}
//! <b>Requires</b>: "header" must be the header node of a tree.
//! "new_node" must be, according to the used ordering no less than the
//! greatest inserted key.
//!
//! <b>Effects</b>: Inserts new_node into the tree before "pos".
//!
//! <b>Complexity</b>: Constant-time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: If "new_node" is less than the greatest inserted key
//! tree invariants are broken. This function is slightly faster than
//! using "insert_before".
static void push_back(node_ptr header, node_ptr new_node)
{
tree_algorithms::push_back(header, new_node);
rebalance_after_insertion(header, new_node);
}
//! <b>Requires</b>: "header" must be the header node of a tree.
//! "new_node" must be, according to the used ordering, no greater than the
//! lowest inserted key.
//!
//! <b>Effects</b>: Inserts new_node into the tree before "pos".
//!
//! <b>Complexity</b>: Constant-time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: If "new_node" is greater than the lowest inserted key
//! tree invariants are broken. This function is slightly faster than
//! using "insert_before".
static void push_front(node_ptr header, node_ptr new_node)
{
tree_algorithms::push_front(header, new_node);
rebalance_after_insertion(header, new_node);
}
//! <b>Requires</b>: "header" must be the header node of a tree.
//! KeyNodePtrCompare is a function object that induces a strict weak
//! ordering compatible with the strict weak ordering used to create the

View File

@@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
// (C) Copyright Ion Gaztanaga 2006-2008
// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -490,6 +490,60 @@ class set_impl
void insert(Iterator b, Iterator e)
{ tree_.insert_unique(b, e); }
//! <b>Requires</b>: value must be an lvalue, "pos" must be
//! a valid iterator (or end) and must be the succesor of value
//! once inserted according to the predicate. "value" must not be equal to any
//! inserted key according to the predicate.
//!
//! <b>Effects</b>: Inserts x into the tree before "pos".
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: This function does not check preconditions so if "pos" is not
//! the successor of "value" or "value" is not unique tree ordering and uniqueness
//! invariants will be broken respectively.
//! This is a low-level function to be used only for performance reasons
//! by advanced users.
iterator insert_before(const_iterator pos, reference value)
{ return tree_.insert_before(pos, value); }
//! <b>Requires</b>: value must be an lvalue, and it must be greater than
//! any inserted key according to the predicate.
//!
//! <b>Effects</b>: Inserts x into the tree in the last position.
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: This function does not check preconditions so if value is
//! less than or equal to the greatest inserted key tree ordering invariant will be broken.
//! This function is slightly more efficient than using "insert_before".
//! This is a low-level function to be used only for performance reasons
//! by advanced users.
void push_back(reference value)
{ tree_.push_back(value); }
//! <b>Requires</b>: value must be an lvalue, and it must be less
//! than any inserted key according to the predicate.
//!
//! <b>Effects</b>: Inserts x into the tree in the first position.
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: This function does not check preconditions so if value is
//! greater than or equal to the the mimum inserted key tree ordering or uniqueness
//! invariants will be broken.
//! This function is slightly more efficient than using "insert_before".
//! This is a low-level function to be used only for performance reasons
//! by advanced users.
void push_front(reference value)
{ tree_.push_front(value); }
//! <b>Effects</b>: Erases the element pointed to by pos.
//!
//! <b>Complexity</b>: Average complexity is constant time.
@@ -1533,6 +1587,57 @@ class multiset_impl
void insert(Iterator b, Iterator e)
{ tree_.insert_equal(b, e); }
//! <b>Requires</b>: value must be an lvalue, "pos" must be
//! a valid iterator (or end) and must be the succesor of value
//! once inserted according to the predicate
//!
//! <b>Effects</b>: Inserts x into the tree before "pos".
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: This function does not check preconditions so if "pos" is not
//! the successor of "value" tree ordering invariant will be broken.
//! This is a low-level function to be used only for performance reasons
//! by advanced users.
iterator insert_before(const_iterator pos, reference value)
{ return tree_.insert_before(pos, value); }
//! <b>Requires</b>: value must be an lvalue, and it must be no less
//! than the greatest inserted key
//!
//! <b>Effects</b>: Inserts x into the tree in the last position.
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: This function does not check preconditions so if value is
//! less than the greatest inserted key tree ordering invariant will be broken.
//! This function is slightly more efficient than using "insert_before".
//! This is a low-level function to be used only for performance reasons
//! by advanced users.
void push_back(reference value)
{ tree_.push_back(value); }
//! <b>Requires</b>: value must be an lvalue, and it must be no greater
//! than the minimum inserted key
//!
//! <b>Effects</b>: Inserts x into the tree in the first position.
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: This function does not check preconditions so if value is
//! greater than the minimum inserted key tree ordering invariant will be broken.
//! This function is slightly more efficient than using "insert_before".
//! This is a low-level function to be used only for performance reasons
//! by advanced users.
void push_front(reference value)
{ tree_.push_front(value); }
//! <b>Effects</b>: Erases the element pointed to by pos.
//!
//! <b>Complexity</b>: Average complexity is constant time.

View File

@@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
// (C) Copyright Ion Gaztanaga 2006-2008
// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -98,6 +98,7 @@ class set_base_hook
>::type
{
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
public:
//! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state.
//!
@@ -224,6 +225,7 @@ class set_member_hook
>::type
{
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
public:
//! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state.
//!

View File

@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2008
// (C) Copyright Ion Gaztanaga 2007-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -381,7 +381,7 @@ class sg_set_impl
//! <b>Requires</b>: key_value_comp must be a comparison function that induces
//! the same strict weak ordering as value_compare. The difference is that
//! key_value_comp compares an ascapegoatitrary key with the contained values.
//! key_value_comp compares an arbitrary key with the contained values.
//!
//! <b>Effects</b>: Checks if a value can be inserted in the sg_set, using
//! a user provided key instead of the value itself.
@@ -416,7 +416,7 @@ class sg_set_impl
//! <b>Requires</b>: key_value_comp must be a comparison function that induces
//! the same strict weak ordering as value_compare. The difference is that
//! key_value_comp compares an ascapegoatitrary key with the contained values.
//! key_value_comp compares an arbitrary key with the contained values.
//!
//! <b>Effects</b>: Checks if a value can be inserted in the sg_set, using
//! a user provided key instead of the value itself, using "hint"
@@ -489,6 +489,60 @@ class sg_set_impl
void insert(Iterator b, Iterator e)
{ tree_.insert_unique(b, e); }
//! <b>Requires</b>: value must be an lvalue, "pos" must be
//! a valid iterator (or end) and must be the succesor of value
//! once inserted according to the predicate. "value" must not be equal to any
//! inserted key according to the predicate.
//!
//! <b>Effects</b>: Inserts x into the tree before "pos".
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: This function does not check preconditions so if "pos" is not
//! the successor of "value" or "value" is not unique tree ordering and uniqueness
//! invariants will be broken respectively.
//! This is a low-level function to be used only for performance reasons
//! by advanced users.
iterator insert_before(const_iterator pos, reference value)
{ return tree_.insert_before(pos, value); }
//! <b>Requires</b>: value must be an lvalue, and it must be greater than
//! any inserted key according to the predicate.
//!
//! <b>Effects</b>: Inserts x into the tree in the last position.
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: This function does not check preconditions so if value is
//! less than or equal to the greatest inserted key tree ordering invariant will be broken.
//! This function is slightly more efficient than using "insert_before".
//! This is a low-level function to be used only for performance reasons
//! by advanced users.
void push_back(reference value)
{ tree_.push_back(value); }
//! <b>Requires</b>: value must be an lvalue, and it must be less
//! than any inserted key according to the predicate.
//!
//! <b>Effects</b>: Inserts x into the tree in the first position.
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: This function does not check preconditions so if value is
//! greater than or equal to the the mimum inserted key tree ordering or uniqueness
//! invariants will be broken.
//! This function is slightly more efficient than using "insert_before".
//! This is a low-level function to be used only for performance reasons
//! by advanced users.
void push_front(reference value)
{ tree_.push_front(value); }
//! <b>Effects</b>: Erases the element pointed to by pos.
//!
//! <b>Complexity</b>: Average complexity is constant time.
@@ -1572,6 +1626,57 @@ class sg_multiset_impl
void insert(Iterator b, Iterator e)
{ tree_.insert_equal(b, e); }
//! <b>Requires</b>: value must be an lvalue, "pos" must be
//! a valid iterator (or end) and must be the succesor of value
//! once inserted according to the predicate
//!
//! <b>Effects</b>: Inserts x into the tree before "pos".
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: This function does not check preconditions so if "pos" is not
//! the successor of "value" tree ordering invariant will be broken.
//! This is a low-level function to be used only for performance reasons
//! by advanced users.
iterator insert_before(const_iterator pos, reference value)
{ return tree_.insert_before(pos, value); }
//! <b>Requires</b>: value must be an lvalue, and it must be no less
//! than the greatest inserted key
//!
//! <b>Effects</b>: Inserts x into the tree in the last position.
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: This function does not check preconditions so if value is
//! less than the greatest inserted key tree ordering invariant will be broken.
//! This function is slightly more efficient than using "insert_before".
//! This is a low-level function to be used only for performance reasons
//! by advanced users.
void push_back(reference value)
{ tree_.push_back(value); }
//! <b>Requires</b>: value must be an lvalue, and it must be no greater
//! than the minimum inserted key
//!
//! <b>Effects</b>: Inserts x into the tree in the first position.
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: This function does not check preconditions so if value is
//! greater than the minimum inserted key tree ordering invariant will be broken.
//! This function is slightly more efficient than using "insert_before".
//! This is a low-level function to be used only for performance reasons
//! by advanced users.
void push_front(reference value)
{ tree_.push_front(value); }
//! <b>Effects</b>: Erases the element pointed to by pos.
//!
//! <b>Complexity</b>: Average complexity is constant time.

View File

@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2008
// (C) Copyright Ion Gaztanaga 2007-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -244,7 +244,7 @@ class sgtree_impl
static const bool floating_point = Config::floating_point;
static const bool constant_time_size = true;
static const bool stateful_value_traits = detail::store_cont_ptr_on_it<sgtree_impl>::value;
static const bool stateful_value_traits = detail::is_stateful_value_traits<real_value_traits>::value;
/// @cond
private:
@@ -871,6 +871,88 @@ class sgtree_impl
return iterator(to_insert, this);
}
//! <b>Requires</b>: value must be an lvalue, "pos" must be
//! a valid iterator (or end) and must be the succesor of value
//! once inserted according to the predicate
//!
//! <b>Effects</b>: Inserts x into the tree before "pos".
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: This function does not check preconditions so if "pos" is not
//! the successor of "value" tree ordering invariant will be broken.
//! This is a low-level function to be used only for performance reasons
//! by advanced users.
iterator insert_before(const_iterator pos, reference value)
{
node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
this->priv_size_traits().increment();
std::size_t max_tree_size = (std::size_t)data_.max_tree_size_;
node_ptr p = node_algorithms::insert_before
( node_ptr(&priv_header()), pos.pointed_node(), to_insert
, (size_type)this->size(), this->get_h_alpha_func(), max_tree_size);
data_.max_tree_size_ = (size_type)max_tree_size;
return iterator(p, this);
}
//! <b>Requires</b>: value must be an lvalue, and it must be no less
//! than the greatest inserted key
//!
//! <b>Effects</b>: Inserts x into the tree in the last position.
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: This function does not check preconditions so if value is
//! less than the greatest inserted key tree ordering invariant will be broken.
//! This function is slightly more efficient than using "insert_before".
//! This is a low-level function to be used only for performance reasons
//! by advanced users.
void push_back(reference value)
{
node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
this->priv_size_traits().increment();
std::size_t max_tree_size = (std::size_t)data_.max_tree_size_;
node_algorithms::push_back
( node_ptr(&priv_header()), to_insert
, (size_type)this->size(), this->get_h_alpha_func(), max_tree_size);
data_.max_tree_size_ = (size_type)max_tree_size;
}
//! <b>Requires</b>: value must be an lvalue, and it must be no greater
//! than the minimum inserted key
//!
//! <b>Effects</b>: Inserts x into the tree in the first position.
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: This function does not check preconditions so if value is
//! greater than the minimum inserted key tree ordering invariant will be broken.
//! This function is slightly more efficient than using "insert_before".
//! This is a low-level function to be used only for performance reasons
//! by advanced users.
void push_front(reference value)
{
node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
this->priv_size_traits().increment();
std::size_t max_tree_size = (std::size_t)data_.max_tree_size_;
node_algorithms::push_front
( node_ptr(&priv_header()), to_insert
, (size_type)this->size(), this->get_h_alpha_func(), max_tree_size);
data_.max_tree_size_ = (size_type)max_tree_size;
}
//! <b>Effects</b>: Erases the element pointed to by pos.
//!
//! <b>Complexity</b>: Average complexity for erase element is constant time.
@@ -1071,7 +1153,6 @@ class sgtree_impl
{
node_algorithms::clear_and_dispose(node_ptr(&priv_header())
, detail::node_disposer<Disposer, sgtree_impl>(disposer, this));
node_algorithms::init_header(&priv_header());
this->priv_size_traits().set_size(0);
}

View File

@@ -539,6 +539,76 @@ class sgtree_algorithms
return ret;
}
//! <b>Requires</b>: "header" must be the header node of a tree.
//! "pos" must be a valid iterator or header (end) node.
//! "pos" must be an iterator pointing to the successor to "new_node"
//! once inserted according to the order of already inserted nodes. This function does not
//! check "pos" and this precondition must be guaranteed by the caller.
//!
//! <b>Effects</b>: Inserts new_node into the tree before "pos".
//!
//! <b>Complexity</b>: Constant-time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: If "pos" is not the successor of the newly inserted "new_node"
//! tree invariants might be broken.
template<class H_Alpha>
static node_ptr insert_before
(node_ptr header, node_ptr pos, node_ptr new_node
,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size)
{
std::size_t depth;
tree_algorithms::insert_before(header, pos, new_node, &depth);
rebalance_after_insertion(new_node, depth, tree_size+1, h_alpha, max_tree_size);
return new_node;
}
//! <b>Requires</b>: "header" must be the header node of a tree.
//! "new_node" must be, according to the used ordering no less than the
//! greatest inserted key.
//!
//! <b>Effects</b>: Inserts new_node into the tree before "pos".
//!
//! <b>Complexity</b>: Constant-time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: If "new_node" is less than the greatest inserted key
//! tree invariants are broken. This function is slightly faster than
//! using "insert_before".
template<class H_Alpha>
static void push_back(node_ptr header, node_ptr new_node
,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size)
{
std::size_t depth;
tree_algorithms::push_back(header, new_node, &depth);
rebalance_after_insertion(new_node, depth, tree_size+1, h_alpha, max_tree_size);
}
//! <b>Requires</b>: "header" must be the header node of a tree.
//! "new_node" must be, according to the used ordering, no greater than the
//! lowest inserted key.
//!
//! <b>Effects</b>: Inserts new_node into the tree before "pos".
//!
//! <b>Complexity</b>: Constant-time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: If "new_node" is greater than the lowest inserted key
//! tree invariants are broken. This function is slightly faster than
//! using "insert_before".
template<class H_Alpha>
static void push_front(node_ptr header, node_ptr new_node
,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size)
{
std::size_t depth;
tree_algorithms::push_front(header, new_node, &depth);
rebalance_after_insertion(new_node, depth, tree_size+1, h_alpha, max_tree_size);
}
//! <b>Requires</b>: "header" must be the header node of a tree.
//! KeyNodePtrCompare is a function object that induces a strict weak
//! ordering compatible with the strict weak ordering used to create the

View File

@@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
// (C) Copyright Ion Gaztanaga 2006-2008
// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -140,7 +140,7 @@ class slist_impl
>::type node_algorithms;
static const bool constant_time_size = Config::constant_time_size;
static const bool stateful_value_traits = detail::store_cont_ptr_on_it<slist_impl>::value;
static const bool stateful_value_traits = detail::is_stateful_value_traits<real_value_traits>::value;
static const bool linear = Config::linear;
static const bool cache_last = Config::cache_last;
@@ -539,6 +539,36 @@ class slist_impl
const_iterator cbefore_begin() const
{ return this->before_begin(); }
//! <b>Effects</b>: Returns an iterator to the last element contained in the list.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: This function is present only if cached_last<> option is true.
iterator last()
{ return iterator (this->get_last_node(), this); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: This function is present only if cached_last<> option is true.
const_iterator last() const
{ return const_iterator (this->get_last_node(), this); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: This function is present only if cached_last<> option is true.
const_iterator clast() const
{ return const_iterator(this->get_last_node(), this); }
//! <b>Precondition</b>: end_iterator must be a valid end iterator
//! of slist.
//!
@@ -1058,20 +1088,31 @@ class slist_impl
//! <b>Effects</b>: Transfers all the elements of list x to this list, after the
//! the element pointed by prev. No destructors or copy constructors are called.
//!
//! <b>Returns</b>: The last element inserted of x or prev if x is empty.
//! This iterator can be used as new "prev" iterator for a new splice_after call.
//! that will splice new values after the previously spliced values.
//! <b>Returns</b>: Nothing.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear to the elements contained in x.
//! Constant-time if cache_last<> option is true.
//! <b>Complexity</b>: In general, linear to the elements contained in x.
//! Constant-time if cache_last<> option is true and also constant-time if
//! linear<> option is true "this" is empty and "last" is not used.
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
iterator splice_after(const_iterator prev, slist_impl &x)
//!
//! <b>Additional note</b>: If the optional parameter "last" is provided, it will be
//! assigned to the last spliced element or prev if x is empty.
//! This iterator can be used as new "prev" iterator for a new splice_after call.
//! that will splice new values after the previously spliced values.
void splice_after(const_iterator prev, slist_impl &x, const_iterator *last = 0)
{
if (!x.empty()){
if(x.empty()){
if(last) *last = prev;
}
else if(linear && this->empty()){
this->swap(x);
if(last) *last = this->previous(this->cend());
}
else{
const_iterator last_x(x.previous(x.end())); //<- constant time if cache_last is active
node_ptr prev_n(prev.pointed_node());
node_ptr last_x_n(last_x.pointed_node());
@@ -1084,10 +1125,7 @@ class slist_impl
node_algorithms::transfer_after( prev_n, x.before_begin().pointed_node(), last_x_n);
this->priv_size_traits().set_size(this->priv_size_traits().get_size() + x.priv_size_traits().get_size());
x.priv_size_traits().set_size(size_type(0));
return last_x.unconst();
}
else{
return prev.unconst();
if(last) *last = last_x;
}
}
@@ -1166,10 +1204,7 @@ class slist_impl
//! <b>Effects</b>: Transfers all the elements of list x to this list, before the
//! the element pointed by it. No destructors or copy constructors are called.
//!
//! <b>Returns</b>: The last element inserted of x or the previous element
//! of it if x is empty.
//! This iterator can be used as new "prev" iterator for a new splice call.
//! that will splice new values after the previously spliced values.
//! <b>Returns</b>: Nothing.
//!
//! <b>Throws</b>: Nothing.
//!
@@ -1180,8 +1215,13 @@ class slist_impl
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
iterator splice(const_iterator it, slist_impl &x)
{ return this->splice_after(this->previous(it), x); }
//!
//! <b>Additional note</b>: If the optional parameter "last" is provided, it will be
//! assigned to the last spliced element or prev if x is empty.
//! This iterator can be used as new "prev" iterator for a new splice_after call.
//! that will splice new values after the previously spliced values.
void splice(const_iterator it, slist_impl &x, iterator *last = 0)
{ this->splice_after(this->previous(it), x, last); }
//! <b>Requires</b>: it p must be a valid iterator of *this.
//! elem must point to an element contained in list
@@ -1265,13 +1305,11 @@ class slist_impl
int i = 0;
while(i < fill && !counter[i].empty()) {
carry.swap(counter[i]);
last_inserted = carry.merge(counter[i++], p);
carry.merge(counter[i++], p, &last_inserted);
}
BOOST_INTRUSIVE_INVARIANT_ASSERT(counter[i].empty());
const_iterator last_element(carry.previous(last_inserted, carry.end()));
node_ptr p = node_algorithms::get_previous_node
(last_inserted.pointed_node(), carry.cend().pointed_node());
const_iterator last_element(p, this);
if(constant_time_size){
counter[i].splice_after( counter[i].cbefore_begin(), carry
, carry.cbefore_begin(), last_element
@@ -1286,12 +1324,9 @@ class slist_impl
}
for (int i = 1; i < fill; ++i)
last_inserted = counter[i].merge(counter[i-1], p);
BOOST_INTRUSIVE_INVARIANT_ASSERT(this->empty());
node_ptr p = node_algorithms::get_previous_node
(last_inserted.pointed_node(), counter[--fill].end().pointed_node());
const_iterator last_element(p, this);
counter[i].merge(counter[i-1], p, &last_inserted);
--fill;
const_iterator last_element(counter[fill].previous(last_inserted, counter[fill].end()));
if(constant_time_size){
this->splice_after( cbefore_begin(), counter[fill], counter[fill].cbefore_begin()
, last_element, counter[fill].size());
@@ -1330,7 +1365,7 @@ class slist_impl
//! in order into *this. The merge is stable; that is, if an element from *this is
//! equivalent to one from x, then the element from *this will precede the one from x.
//!
//! <b>Returns</b>: An iterator to the last transferred value, end() is x is empty.
//! <b>Returns</b>: Nothing.
//!
//! <b>Throws</b>: If the predicate throws. Basic guarantee.
//!
@@ -1338,11 +1373,15 @@ class slist_impl
//! size() + x.size() - 1 comparisons.
//!
//! <b>Note</b>: Iterators and references are not invalidated.
//!
//! <b>Additional note</b>: If optional "last" argument is passed, it is assigned
//! to an iterator to the last transferred value or end() is x is empty.
template<class Predicate>
iterator merge(slist_impl& x, Predicate p)
void merge(slist_impl& x, Predicate p, const_iterator *last = 0)
{
const_iterator e(this->cend()), ex(x.cend()), bb(this->cbefore_begin()),
bb_next, last_inserted(e);
bb_next;
if(last) *last = e.unconst();
while(!x.empty()){
const_iterator ibx_next(x.cbefore_begin()), ibx(ibx_next++);
while (++(bb_next = bb) != e && !p(*ibx_next, *bb_next)){
@@ -1350,7 +1389,7 @@ class slist_impl
}
if(bb_next == e){
//Now transfer the rest to the end of the container
last_inserted = this->splice_after(bb, x);
this->splice_after(bb, x, last);
break;
}
else{
@@ -1359,10 +1398,9 @@ class slist_impl
ibx = ibx_next; ++n;
} while(++(ibx_next = ibx) != ex && p(*ibx_next, *bb_next));
this->splice_after(bb, x, x.before_begin(), ibx, n);
last_inserted = ibx;
if(last) *last = ibx;
}
}
return last_inserted.unconst();
}
//! <b>Effects</b>: This function removes all of x's elements and inserts them
@@ -1618,14 +1656,7 @@ class slist_impl
//! <b>Complexity</b>: Linear to the number of elements before i.
//! Constant if cache_last<> is true and i == end().
iterator previous(iterator i)
{
if(cache_last && (i.pointed_node() == this->get_end_node())){
return iterator(this->get_last_node(), this);
}
return iterator
(node_algorithms::get_previous_node
(this->before_begin().pointed_node(), i.pointed_node()), this);
}
{ return this->previous(this->cbefore_begin(), i); }
//! <b>Returns</b>: The const_iterator to the element before i in the list.
//! Returns the end-const_iterator, if either i is the begin-const_iterator or
@@ -1636,13 +1667,86 @@ class slist_impl
//! <b>Complexity</b>: Linear to the number of elements before i.
//! Constant if cache_last<> is true and i == end().
const_iterator previous(const_iterator i) const
{ return this->previous(this->cbefore_begin(), i); }
//! <b>Returns</b>: The iterator to the element before i in the list,
//! starting the search on element after prev_from.
//! Returns the end-iterator, if either i is the begin-iterator or the
//! list is empty.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear to the number of elements before i.
//! Constant if cache_last<> is true and i == end().
iterator previous(const_iterator prev_from, iterator i)
{ return this->previous(prev_from, const_iterator(i)).unconst(); }
//! <b>Returns</b>: The const_iterator to the element before i in the list,
//! starting the search on element after prev_from.
//! Returns the end-const_iterator, if either i is the begin-const_iterator or
//! the list is empty.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear to the number of elements before i.
//! Constant if cache_last<> is true and i == end().
const_iterator previous(const_iterator prev_from, const_iterator i) const
{
if(cache_last && (i.pointed_node() == this->get_end_node())){
return const_iterator(uncast(this->get_last_node()), this);
}
return const_iterator
(node_algorithms::get_previous_node
(this->before_begin().pointed_node(), i.pointed_node()), this);
(prev_from.pointed_node(), i.pointed_node()), this);
}
//! <b>Requires</b>: prev_pos must be a dereferenceable iterator in *this or be
//! before_begin(), and before_first and before_last belong to x and
//! ++before_first != x.end() && before_last != x.end().
//!
//! <b>Effects</b>: Transfers the range (before_first, before_last] to this
//! list, after the element pointed by prev_pos.
//! No destructors or copy constructors are called.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear to the number of elements transferred
//! if constant_time_size is true. Constant-time otherwise.
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
void incorporate_after(const_iterator prev_from, node_ptr first, node_ptr before_last)
{
if(constant_time_size)
this->incorporate_after(prev_from, first, before_last, std::distance(first, before_last)+1);
else
this->priv_incorporate_after
(prev_from.pointed_node(), first, before_last);
}
//! <b>Requires</b>: prev_pos must be a dereferenceable iterator in *this or be
//! before_begin(), and before_first and before_last belong to x and
//! ++before_first != x.end() && before_last != x.end() and
//! n == std::distance(first, before_last) + 1.
//!
//! <b>Effects</b>: Transfers the range (before_first, before_last] from list x to this
//! list, after the element pointed by p. No destructors or copy constructors are called.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
void incorporate_after(const_iterator prev_pos, node_ptr first, node_ptr before_last, difference_type n)
{
if(n){
BOOST_INTRUSIVE_INVARIANT_ASSERT(std::distance(iterator(first, this), iterator(before_last, this))+1 == n);
this->priv_incorporate_after(prev_pos.pointed_node(), first, before_last);
if(constant_time_size){
this->priv_size_traits().set_size(this->priv_size_traits().get_size() + n);
}
}
}
private:
@@ -1662,6 +1766,16 @@ class slist_impl
}
}
void priv_incorporate_after(node_ptr prev_pos_n, node_ptr first_n, node_ptr before_last_n)
{
if(cache_last){
if(node_traits::get_next(prev_pos_n) == this->get_end_node()){
this->set_last_node(before_last_n);
}
}
node_algorithms::incorporate_after(prev_pos_n, first_n, before_last_n);
}
void priv_reverse(detail::bool_<false>)
{ node_algorithms::reverse(this->get_root_node()); }

View File

@@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
// (C) Copyright Ion Gaztanaga 2006-2008
// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -96,6 +96,7 @@ class slist_base_hook
>::type
{
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
public:
//! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state.
//!
@@ -218,6 +219,7 @@ class slist_member_hook
>::type
{
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
public:
//! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state.
//!

View File

@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2008
// (C) Copyright Ion Gaztanaga 2007-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
// (C) Copyright Ion Gaztanaga 2006-2008
// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -93,6 +93,7 @@ class splay_set_base_hook
>::type
{
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
public:
//! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state.
//!
@@ -216,6 +217,7 @@ class splay_set_member_hook
>::type
{
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
public:
//! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state.
//!

View File

@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2008
// (C) Copyright Ion Gaztanaga 2007-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -115,7 +115,7 @@ class splaytree_impl
typedef splaytree_algorithms<node_traits> node_algorithms;
static const bool constant_time_size = Config::constant_time_size;
static const bool stateful_value_traits = detail::store_cont_ptr_on_it<splaytree_impl>::value;
static const bool stateful_value_traits = detail::is_stateful_value_traits<real_value_traits>::value;
/// @cond
private:
@@ -895,7 +895,6 @@ class splaytree_impl
{
node_algorithms::clear_and_dispose(node_ptr(&priv_header())
, detail::node_disposer<Disposer, splaytree_impl>(disposer, this));
node_algorithms::init_header(&priv_header());
this->priv_size_traits().set_size(0);
}

View File

@@ -543,6 +543,79 @@ class splaytree_algorithms
return tree_algorithms::insert_equal(header, hint, new_node, comp);
}
//! <b>Requires</b>: "header" must be the header node of a tree.
//! "pos" must be a valid iterator or header (end) node.
//! "pos" must be an iterator pointing to the successor to "new_node"
//! once inserted according to the order of already inserted nodes. This function does not
//! check "pos" and this precondition must be guaranteed by the caller.
//!
//! <b>Effects</b>: Inserts new_node into the tree before "pos".
//!
//! <b>Complexity</b>: Constant-time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: If "pos" is not the successor of the newly inserted "new_node"
//! tree invariants might be broken.
static node_ptr insert_before
(node_ptr header, node_ptr pos, node_ptr new_node)
{
tree_algorithms::insert_before(header, pos, new_node);
splay_up(new_node, header);
return new_node;
}
//! <b>Requires</b>: "header" must be the header node of a tree.
//! "new_node" must be, according to the used ordering no less than the
//! greatest inserted key.
//!
//! <b>Effects</b>: Inserts new_node into the tree before "pos".
//!
//! <b>Complexity</b>: Constant-time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: If "new_node" is less than the greatest inserted key
//! tree invariants are broken. This function is slightly faster than
//! using "insert_before".
static void push_back(node_ptr header, node_ptr new_node)
{
tree_algorithms::push_back(header, new_node);
splay_up(new_node, header);
}
//! <b>Requires</b>: "header" must be the header node of a tree.
//! "new_node" must be, according to the used ordering, no greater than the
//! lowest inserted key.
//!
//! <b>Effects</b>: Inserts new_node into the tree before "pos".
//!
//! <b>Complexity</b>: Constant-time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: If "new_node" is greater than the lowest inserted key
//! tree invariants are broken. This function is slightly faster than
//! using "insert_before".
static void push_front(node_ptr header, node_ptr new_node)
{
tree_algorithms::push_front(header, new_node);
splay_up(new_node, header);
}
//! <b>Requires</b>: "header" must be the header node of a tree.
//! NodePtrCompare is a function object that induces a strict weak
//! ordering compatible with the strict weak ordering used to create the
//! the tree. NodePtrCompare compares two node_ptrs.
//!
//! <b>Effects</b>: Inserts new_node into the tree before the upper bound
//! according to "comp".
//!
//! <b>Complexity</b>: Average complexity for insert element is at
//! most logarithmic.
//!
//! <b>Throws</b>: If "comp" throws.
template<class NodePtrCompare>
static node_ptr insert_equal_upper_bound
(node_ptr header, node_ptr new_node, NodePtrCompare comp)
@@ -551,6 +624,18 @@ class splaytree_algorithms
return tree_algorithms::insert_equal_upper_bound(header, new_node, comp);
}
//! <b>Requires</b>: "header" must be the header node of a tree.
//! NodePtrCompare is a function object that induces a strict weak
//! ordering compatible with the strict weak ordering used to create the
//! the tree. NodePtrCompare compares two node_ptrs.
//!
//! <b>Effects</b>: Inserts new_node into the tree before the lower bound
//! according to "comp".
//!
//! <b>Complexity</b>: Average complexity for insert element is at
//! most logarithmic.
//!
//! <b>Throws</b>: If "comp" throws.
template<class NodePtrCompare>
static node_ptr insert_equal_lower_bound
(node_ptr header, node_ptr new_node, NodePtrCompare comp)
@@ -605,9 +690,8 @@ class splaytree_algorithms
// if( data_->parent == t )
// data_->parent = find_leftmost();
//posibility 1
if(splay && NodeTraits::get_left(z) != 0 ){
node_ptr l = prev_node(z);
splay_up(l, header);
if(splay && NodeTraits::get_left(z)){
splay_up(prev_node(z), header);
}
/*
//possibility 2
@@ -644,8 +728,8 @@ class splaytree_algorithms
if( n == t ) return;
for( ;; ){
node_ptr p = NodeTraits::get_parent(n);
node_ptr g = NodeTraits::get_parent(p);
node_ptr p(NodeTraits::get_parent(n));
node_ptr g(NodeTraits::get_parent(p));
if( p == t ) break;
@@ -688,9 +772,8 @@ class splaytree_algorithms
if(!NodeTraits::get_left(t) && !NodeTraits::get_right(t))
return t;
//Backup leftmost/rightmost
node_ptr leftmost = NodeTraits::get_left(header);
node_ptr rightmost = NodeTraits::get_right(header);
node_ptr leftmost (NodeTraits::get_left(header));
node_ptr rightmost(NodeTraits::get_right(header));
{
detail::splaydown_rollback<NodeTraits> rollback(&t, header, leftmost, rightmost);
node_ptr null = header;

View File

@@ -119,7 +119,7 @@ class treap_impl
typedef treap_algorithms<node_traits> node_algorithms;
static const bool constant_time_size = Config::constant_time_size;
static const bool stateful_value_traits = detail::store_cont_ptr_on_it<treap_impl>::value;
static const bool stateful_value_traits = detail::is_stateful_value_traits<real_value_traits>::value;
/// @cond
private:
@@ -217,7 +217,7 @@ class treap_impl
typedef typename node_algorithms::insert_commit_data insert_commit_data;
//! <b>Effects</b>: Constructs an empty tree.
//! <b>Effects</b>: Constructs an empty treap.
//!
//! <b>Complexity</b>: Constant.
//!
@@ -236,7 +236,7 @@ class treap_impl
//! <b>Requires</b>: Dereferencing iterator must yield an lvalue of type value_type.
//! cmp must be a comparison function that induces a strict weak ordering.
//!
//! <b>Effects</b>: Constructs an empty tree and inserts elements from
//! <b>Effects</b>: Constructs an empty treap and inserts elements from
//! [b, e).
//!
//! <b>Complexity</b>: Linear in N if [b, e) is already sorted using
@@ -272,7 +272,7 @@ class treap_impl
~treap_impl()
{}
//! <b>Effects</b>: Returns an iterator pointing to the beginning of the tree.
//! <b>Effects</b>: Returns an iterator pointing to the beginning of the treap.
//!
//! <b>Complexity</b>: Constant.
//!
@@ -280,7 +280,7 @@ class treap_impl
iterator begin()
{ return iterator (node_traits::get_left(node_ptr(&priv_header())), this); }
//! <b>Effects</b>: Returns a const_iterator pointing to the beginning of the tree.
//! <b>Effects</b>: Returns a const_iterator pointing to the beginning of the treap.
//!
//! <b>Complexity</b>: Constant.
//!
@@ -288,7 +288,7 @@ class treap_impl
const_iterator begin() const
{ return this->cbegin(); }
//! <b>Effects</b>: Returns a const_iterator pointing to the beginning of the tree.
//! <b>Effects</b>: Returns a const_iterator pointing to the beginning of the treap.
//!
//! <b>Complexity</b>: Constant.
//!
@@ -296,7 +296,7 @@ class treap_impl
const_iterator cbegin() const
{ return const_iterator (node_traits::get_left(const_node_ptr(&priv_header())), this); }
//! <b>Effects</b>: Returns an iterator pointing to the end of the tree.
//! <b>Effects</b>: Returns an iterator pointing to the end of the treap.
//!
//! <b>Complexity</b>: Constant.
//!
@@ -304,7 +304,7 @@ class treap_impl
iterator end()
{ return iterator (node_ptr(&priv_header()), this); }
//! <b>Effects</b>: Returns a const_iterator pointing to the end of the tree.
//! <b>Effects</b>: Returns a const_iterator pointing to the end of the treap.
//!
//! <b>Complexity</b>: Constant.
//!
@@ -312,7 +312,7 @@ class treap_impl
const_iterator end() const
{ return this->cend(); }
//! <b>Effects</b>: Returns a const_iterator pointing to the end of the tree.
//! <b>Effects</b>: Returns a const_iterator pointing to the end of the treap.
//!
//! <b>Complexity</b>: Constant.
//!
@@ -321,7 +321,7 @@ class treap_impl
{ return const_iterator (uncast(const_node_ptr(&priv_header())), this); }
//! <b>Effects</b>: Returns an iterator pointing to the highest priority object of the tree.
//! <b>Effects</b>: Returns an iterator pointing to the highest priority object of the treap.
//!
//! <b>Complexity</b>: Constant.
//!
@@ -329,7 +329,7 @@ class treap_impl
iterator top()
{ return this->empty() ? this->end() : iterator (node_traits::get_parent(node_ptr(&priv_header())), this); }
//! <b>Effects</b>: Returns a const_iterator pointing to the highest priority object of the tree..
//! <b>Effects</b>: Returns a const_iterator pointing to the highest priority object of the treap..
//!
//! <b>Complexity</b>: Constant.
//!
@@ -337,7 +337,7 @@ class treap_impl
const_iterator top() const
{ return this->ctop(); }
//! <b>Effects</b>: Returns a const_iterator pointing to the highest priority object of the tree..
//! <b>Effects</b>: Returns a const_iterator pointing to the highest priority object of the treap..
//!
//! <b>Complexity</b>: Constant.
//!
@@ -346,7 +346,7 @@ class treap_impl
{ return this->empty() ? this->cend() : const_iterator (node_traits::get_parent(const_node_ptr(&priv_header())), this); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning of the
//! reversed tree.
//! reversed treap.
//!
//! <b>Complexity</b>: Constant.
//!
@@ -355,7 +355,7 @@ class treap_impl
{ return reverse_iterator(this->end()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
//! of the reversed tree.
//! of the reversed treap.
//!
//! <b>Complexity</b>: Constant.
//!
@@ -364,7 +364,7 @@ class treap_impl
{ return const_reverse_iterator(this->end()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
//! of the reversed tree.
//! of the reversed treap.
//!
//! <b>Complexity</b>: Constant.
//!
@@ -373,7 +373,7 @@ class treap_impl
{ return const_reverse_iterator(this->end()); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the end
//! of the reversed tree.
//! of the reversed treap.
//!
//! <b>Complexity</b>: Constant.
//!
@@ -382,7 +382,7 @@ class treap_impl
{ return reverse_iterator(this->begin()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
//! of the reversed tree.
//! of the reversed treap.
//!
//! <b>Complexity</b>: Constant.
//!
@@ -391,7 +391,7 @@ class treap_impl
{ return const_reverse_iterator(this->begin()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
//! of the reversed tree.
//! of the reversed treap.
//!
//! <b>Complexity</b>: Constant.
//!
@@ -400,7 +400,7 @@ class treap_impl
{ return const_reverse_iterator(this->begin()); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the highest priority object of the
//! reversed tree.
//! reversed treap.
//!
//! <b>Complexity</b>: Constant.
//!
@@ -409,7 +409,7 @@ class treap_impl
{ return reverse_iterator(this->top()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the highest priority objec
//! of the reversed tree.
//! of the reversed treap.
//!
//! <b>Complexity</b>: Constant.
//!
@@ -418,7 +418,7 @@ class treap_impl
{ return const_reverse_iterator(this->top()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the highest priority object
//! of the reversed tree.
//! of the reversed treap.
//!
//! <b>Complexity</b>: Constant.
//!
@@ -451,7 +451,7 @@ class treap_impl
//! <b>Precondition</b>: it must be a valid iterator
//! of treap.
//!
//! <b>Effects</b>: Returns a const reference to the tree associated to the iterator
//! <b>Effects</b>: Returns a const reference to the treap associated to the iterator
//!
//! <b>Throws</b>: Nothing.
//!
@@ -462,7 +462,7 @@ class treap_impl
//! <b>Precondition</b>: it must be a valid end const_iterator
//! of treap.
//!
//! <b>Effects</b>: Returns a const reference to the tree associated to the end iterator
//! <b>Effects</b>: Returns a const reference to the treap associated to the end iterator
//!
//! <b>Throws</b>: Nothing.
//!
@@ -470,7 +470,7 @@ class treap_impl
static const treap_impl &container_from_iterator(const_iterator it)
{ return priv_container_from_iterator(it); }
//! <b>Effects</b>: Returns the value_compare object used by the tree.
//! <b>Effects</b>: Returns the value_compare object used by the treap.
//!
//! <b>Complexity</b>: Constant.
//!
@@ -478,7 +478,7 @@ class treap_impl
value_compare value_comp() const
{ return this->priv_comp(); }
//! <b>Effects</b>: Returns the priority_compare object used by the tree.
//! <b>Effects</b>: Returns the priority_compare object used by the treap.
//!
//! <b>Complexity</b>: Constant.
//!
@@ -494,7 +494,7 @@ class treap_impl
bool empty() const
{ return node_algorithms::unique(const_node_ptr(&priv_header())); }
//! <b>Effects</b>: Returns the number of elements stored in the tree.
//! <b>Effects</b>: Returns the number of elements stored in the treap.
//!
//! <b>Complexity</b>: Linear to elements contained in *this
//! if constant-time size option is disabled. Constant time otherwise.
@@ -531,12 +531,12 @@ class treap_impl
//! <b>Requires</b>: value must be an lvalue
//!
//! <b>Effects</b>: Inserts value into the tree before the upper bound.
//! <b>Effects</b>: Inserts value into the treap before the upper bound.
//!
//! <b>Complexity</b>: Average complexity for insert element is at
//! most logarithmic.
//!
//! <b>Throws</b>: If the internal value_compare or priority_compare funcstions throw. Strong guarantee.
//! <b>Throws</b>: If the internal value_compare or priority_compare functions throw. Strong guarantee.
//!
//! <b>Note</b>: Does not affect the validity of iterators and references.
//! No copy-constructors are called.
@@ -557,14 +557,14 @@ class treap_impl
//! <b>Requires</b>: value must be an lvalue, and "hint" must be
//! a valid iterator.
//!
//! <b>Effects</b>: Inserts x into the tree, using "hint" as a hint to
//! <b>Effects</b>: Inserts x into the treap, using "hint" as a hint to
//! where it will be inserted. If "hint" is the upper_bound
//! the insertion takes constant time (two comparisons in the worst case)
//!
//! <b>Complexity</b>: Logarithmic in general, but it is amortized
//! constant time if t is inserted immediately before hint.
//!
//! <b>Throws</b>: If the internal value_compare or priority_compare funcstions throw. Strong guarantee.
//! <b>Throws</b>: If the internal value_compare or priority_compare functions throw. Strong guarantee.
//!
//! <b>Note</b>: Does not affect the validity of iterators and references.
//! No copy-constructors are called.
@@ -585,14 +585,14 @@ class treap_impl
//! <b>Requires</b>: Dereferencing iterator must yield an lvalue
//! of type value_type.
//!
//! <b>Effects</b>: Inserts a each element of a range into the tree
//! <b>Effects</b>: Inserts a each element of a range into the treap
//! before the upper bound of the key of each element.
//!
//! <b>Complexity</b>: Insert range is in general O(N * log(N)), where N is the
//! size of the range. However, it is linear in N if the range is already sorted
//! by value_comp().
//!
//! <b>Throws</b>: If the internal value_compare or priority_compare funcstions throw.
//! <b>Throws</b>: If the internal value_compare or priority_compare functions throw.
//! Strong guarantee.
//!
//! <b>Note</b>: Does not affect the validity of iterators and references.
@@ -607,13 +607,13 @@ class treap_impl
//! <b>Requires</b>: value must be an lvalue
//!
//! <b>Effects</b>: Inserts value into the tree if the value
//! <b>Effects</b>: Inserts value into the treap if the value
//! is not already present.
//!
//! <b>Complexity</b>: Average complexity for insert element is at
//! most logarithmic.
//!
//! <b>Throws</b>: If the internal value_compare or priority_compare funcstions throw.
//! <b>Throws</b>: If the internal value_compare or priority_compare functions throw.
//! Strong guarantee.
//!
//! <b>Note</b>: Does not affect the validity of iterators and references.
@@ -630,14 +630,14 @@ class treap_impl
//! <b>Requires</b>: value must be an lvalue, and "hint" must be
//! a valid iterator
//!
//! <b>Effects</b>: Tries to insert x into the tree, using "hint" as a hint
//! <b>Effects</b>: Tries to insert x into the treap, using "hint" as a hint
//! to where it will be inserted.
//!
//! <b>Complexity</b>: Logarithmic in general, but it is amortized
//! constant time (two comparisons in the worst case)
//! if t is inserted immediately before hint.
//!
//! <b>Throws</b>: If the internal value_compare or priority_compare funcstions throw.
//! <b>Throws</b>: If the internal value_compare or priority_compare functions throw.
//! Strong guarantee.
//!
//! <b>Note</b>: Does not affect the validity of iterators and references.
@@ -654,13 +654,13 @@ class treap_impl
//! <b>Requires</b>: Dereferencing iterator must yield an lvalue
//! of type value_type.
//!
//! <b>Effects</b>: Tries to insert each element of a range into the tree.
//! <b>Effects</b>: Tries to insert each element of a range into the treap.
//!
//! <b>Complexity</b>: Insert range is in general O(N * log(N)), where N is the
//! size of the range. However, it is linear in N if the range is already sorted
//! by value_comp().
//!
//! <b>Throws</b>: If the internal value_compare or priority_compare funcstions throw.
//! <b>Throws</b>: If the internal value_compare or priority_compare functions throw.
//! Strong guarantee.
//!
//! <b>Note</b>: Does not affect the validity of iterators and references.
@@ -680,8 +680,10 @@ class treap_impl
}
//! <b>Requires</b>: key_value_comp must be a comparison function that induces
//! the same strict weak ordering as value_compare. The difference is that
//! key_value_comp compares an arbitrary key with the contained values.
//! the same strict weak ordering as value_compare.
//! key_value_pcomp must be a comparison function that induces
//! the same strict weak ordering as priority_compare. The difference is that
//! key_value_pcomp and key_value_comp compare an arbitrary key with the contained values.
//!
//! <b>Effects</b>: Checks if a value can be inserted in the container, using
//! a user provided key instead of the value itself.
@@ -694,7 +696,8 @@ class treap_impl
//!
//! <b>Complexity</b>: Average complexity is at most logarithmic.
//!
//! <b>Throws</b>: If the key_value_comp ordering function throws. Strong guarantee.
//! <b>Throws</b>: If the key_value_comp or key_value_pcomp
//! ordering functions throw. Strong guarantee.
//!
//! <b>Notes</b>: This function is used to improve performance when constructing
//! a value_type is expensive: if there is an equivalent value
@@ -725,8 +728,10 @@ class treap_impl
}
//! <b>Requires</b>: key_value_comp must be a comparison function that induces
//! the same strict weak ordering as value_compare. The difference is that
//! key_value_comp compares an arbitrary key with the contained values.
//! the same strict weak ordering as value_compare.
//! key_value_pcomp must be a comparison function that induces
//! the same strict weak ordering as priority_compare. The difference is that
//! key_value_pcomp and key_value_comp compare an arbitrary key with the contained values.
//!
//! <b>Effects</b>: Checks if a value can be inserted in the container, using
//! a user provided key instead of the value itself, using "hint"
@@ -741,7 +746,8 @@ class treap_impl
//! <b>Complexity</b>: Logarithmic in general, but it's amortized
//! constant time if t is inserted immediately before hint.
//!
//! <b>Throws</b>: If the key_value_comp ordering function throws. Strong guarantee.
//! <b>Throws</b>: If the key_value_comp or key_value_pcomp
//! ordering functions throw. Strong guarantee.
//!
//! <b>Notes</b>: This function is used to improve performance when constructing
//! a value_type is expensive: if there is an equivalent value
@@ -800,6 +806,82 @@ class treap_impl
return iterator(to_insert, this);
}
//! <b>Requires</b>: value must be an lvalue, "pos" must be
//! a valid iterator (or end) and must be the succesor of value
//! once inserted according to the predicate
//!
//! <b>Effects</b>: Inserts x into the treap before "pos".
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: If the internal priority_compare function throws. Strong guarantee.
//!
//! <b>Note</b>: This function does not check preconditions so if "pos" is not
//! the successor of "value" treap ordering invariant will be broken.
//! This is a low-level function to be used only for performance reasons
//! by advanced users.
iterator insert_before(const_iterator pos, reference value)
{
node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
this->priv_size_traits().increment();
detail::key_nodeptr_comp<priority_compare, treap_impl>
pcomp(priv_pcomp(), this);
return iterator(node_algorithms::insert_before
(node_ptr(&priv_header()), pos.pointed_node(), to_insert, pcomp), this);
}
//! <b>Requires</b>: value must be an lvalue, and it must be no less
//! than the greatest inserted key
//!
//! <b>Effects</b>: Inserts x into the treap in the last position.
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: If the internal priority_compare function throws. Strong guarantee.
//!
//! <b>Note</b>: This function does not check preconditions so if value is
//! less than the greatest inserted key treap ordering invariant will be broken.
//! This function is slightly more efficient than using "insert_before".
//! This is a low-level function to be used only for performance reasons
//! by advanced users.
void push_back(reference value)
{
node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
this->priv_size_traits().increment();
detail::key_nodeptr_comp<priority_compare, treap_impl>
pcomp(priv_pcomp(), this);
node_algorithms::push_back(node_ptr(&priv_header()), to_insert, pcomp);
}
//! <b>Requires</b>: value must be an lvalue, and it must be no greater
//! than the minimum inserted key
//!
//! <b>Effects</b>: Inserts x into the treap in the first position.
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: If the internal priority_compare function throws. Strong guarantee.
//!
//! <b>Note</b>: This function does not check preconditions so if value is
//! greater than the minimum inserted key treap ordering invariant will be broken.
//! This function is slightly more efficient than using "insert_before".
//! This is a low-level function to be used only for performance reasons
//! by advanced users.
void push_front(reference value)
{
node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
this->priv_size_traits().increment();
detail::key_nodeptr_comp<priority_compare, treap_impl>
pcomp(priv_pcomp(), this);
node_algorithms::push_front(node_ptr(&priv_header()), to_insert, pcomp);
}
//! <b>Effects</b>: Erases the element pointed to by pos.
//!
//! <b>Complexity</b>: Average complexity for erase element is constant time.
@@ -856,7 +938,8 @@ class treap_impl
//!
//! <b>Complexity</b>: O(log(size() + N).
//!
//! <b>Throws</b>: if the internal priority_compare function throws. Strong guarantee.
//! <b>Throws</b>: if the internal priority_compare function throws.
//! Equivalent guarantee to <i>while(beg != end) erase(beg++);</i>
//!
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
@@ -1260,16 +1343,16 @@ class treap_impl
}
}
//! <b>Effects</b>: Unlinks the leftmost node from the tree.
//! <b>Effects</b>: Unlinks the leftmost node from the treap.
//!
//! <b>Complexity</b>: Average complexity is constant time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Notes</b>: This function breaks the tree and the tree can
//! <b>Notes</b>: This function breaks the treap and the treap can
//! only be used for more unlink_leftmost_without_rebalance calls.
//! This function is normally used to achieve a step by step
//! controlled destruction of the tree.
//! controlled destruction of the treap.
pointer unlink_leftmost_without_rebalance()
{
node_ptr to_be_disposed(node_algorithms::unlink_leftmost_without_rebalance
@@ -1283,10 +1366,10 @@ class treap_impl
}
//! <b>Requires</b>: replace_this must be a valid iterator of *this
//! and with_this must not be inserted in any tree.
//! and with_this must not be inserted in any treap.
//!
//! <b>Effects</b>: Replaces replace_this in its position in the
//! tree with with_this. The tree does not need to be rebalanced.
//! treap with with_this. The treap does not need to be rebalanced.
//!
//! <b>Complexity</b>: Constant.
//!
@@ -1363,7 +1446,7 @@ class treap_impl
const_iterator iterator_to(const_reference value) const
{ return const_iterator (value_traits::to_node_ptr(const_cast<reference> (value)), this); }
//! <b>Requires</b>: value shall not be in a tree.
//! <b>Requires</b>: value shall not be in a treap.
//!
//! <b>Effects</b>: init_node puts the hook of a value in a well-known default
//! state.

View File

@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2008.
// (C) Copyright Ion Gaztanaga 2006-2009.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -10,8 +10,8 @@
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_TRIE_ALGORITHMS_HPP
#define BOOST_INTRUSIVE_TRIE_ALGORITHMS_HPP
#ifndef BOOST_INTRUSIVE_TREAP_ALGORITHMS_HPP
#define BOOST_INTRUSIVE_TREAP_ALGORITHMS_HPP
#include <boost/intrusive/detail/config_begin.hpp>
@@ -270,15 +270,15 @@ class treap_algorithms
//!
//! <b>Complexity</b>: Average complexity is constant time.
//!
//! <b>Throws</b>: Nothing.
template<class NodePriorityCompare>
static void unlink(node_ptr node, NodePriorityCompare prio)
//! <b>Throws</b>: If "pcomp" throws, strong guarantee
template<class NodePtrPriorityCompare>
static void unlink(node_ptr node, NodePtrPriorityCompare pcomp)
{
node_ptr x = NodeTraits::get_parent(node);
if(x){
while(!is_header(x))
x = NodeTraits::get_parent(x);
erase(x, node, prio);
erase(x, node, pcomp);
}
}
@@ -383,9 +383,9 @@ class treap_algorithms
//!
//! <b>Complexity</b>: Amortized constant time.
//!
//! <b>Throws</b>: Nothing.
template<class NodePriorityCompare>
static node_ptr erase(node_ptr header, node_ptr z, NodePriorityCompare pcomp)
//! <b>Throws</b>: If "pcomp" throws, strong guarantee.
template<class NodePtrPriorityCompare>
static node_ptr erase(node_ptr header, node_ptr z, NodePtrPriorityCompare pcomp)
{
rebalance_for_erasure(header, z, pcomp);
tree_algorithms::erase(header, z);
@@ -503,23 +503,24 @@ class treap_algorithms
//! NodePtrCompare is a function object that induces a strict weak
//! ordering compatible with the strict weak ordering used to create the
//! the tree. NodePtrCompare compares two node_ptrs.
//! NodePtrPriorityCompare is a priority function object that induces a strict weak
//! ordering compatible with the one used to create the
//! the tree. NodePtrPriorityCompare compares two node_ptrs.
//!
//! <b>Effects</b>: Inserts new_node into the tree before the upper bound
//! according to "comp".
//! according to "comp" and rotates the tree according to "pcomp".
//!
//! <b>Complexity</b>: Average complexity for insert element is at
//! most logarithmic.
//!
//! <b>Throws</b>: If "comp" throws.
template<class NodePtrCompare, class PriorityNodeCompare>
//! <b>Throws</b>: If "comp" throw or "pcomp" throw.
template<class NodePtrCompare, class NodePtrPriorityCompare>
static node_ptr insert_equal_upper_bound
(node_ptr h, node_ptr new_node, NodePtrCompare comp, PriorityNodeCompare pcomp)
(node_ptr h, node_ptr new_node, NodePtrCompare comp, NodePtrPriorityCompare pcomp)
{
insert_commit_data commit_data;
tree_algorithms::insert_equal_upper_bound_check(h, new_node, comp, commit_data);
rebalance_after_insertion_check(h, commit_data.node, new_node, pcomp, commit_data.rotations);
tree_algorithms::insert_unique_commit(h, new_node, commit_data);
rebalance_after_insertion_commit(h, new_node, commit_data.rotations);
rebalance_check_and_commit(h, new_node, pcomp, commit_data);
return new_node;
}
@@ -527,23 +528,24 @@ class treap_algorithms
//! NodePtrCompare is a function object that induces a strict weak
//! ordering compatible with the strict weak ordering used to create the
//! the tree. NodePtrCompare compares two node_ptrs.
//! NodePtrPriorityCompare is a priority function object that induces a strict weak
//! ordering compatible with the one used to create the
//! the tree. NodePtrPriorityCompare compares two node_ptrs.
//!
//! <b>Effects</b>: Inserts new_node into the tree before the lower bound
//! according to "comp".
//! <b>Effects</b>: Inserts new_node into the tree before the upper bound
//! according to "comp" and rotates the tree according to "pcomp".
//!
//! <b>Complexity</b>: Average complexity for insert element is at
//! most logarithmic.
//!
//! <b>Throws</b>: If "comp" throws.
template<class NodePtrCompare, class NodePriorityCompare>
template<class NodePtrCompare, class NodePtrPriorityCompare>
static node_ptr insert_equal_lower_bound
(node_ptr h, node_ptr new_node, NodePtrCompare comp, NodePriorityCompare pcomp)
(node_ptr h, node_ptr new_node, NodePtrCompare comp, NodePtrPriorityCompare pcomp)
{
insert_commit_data commit_data;
tree_algorithms::insert_equal_lower_bound_check(h, new_node, comp, commit_data);
rebalance_after_insertion_check(h, commit_data.node, new_node, pcomp, commit_data.rotations);
tree_algorithms::insert_unique_commit(h, new_node, commit_data);
rebalance_after_insertion_commit(h, new_node, commit_data.rotations);
rebalance_check_and_commit(h, new_node, pcomp, commit_data);
return new_node;
}
@@ -552,27 +554,107 @@ class treap_algorithms
//! ordering compatible with the strict weak ordering used to create the
//! the tree. NodePtrCompare compares two node_ptrs. "hint" is node from
//! the "header"'s tree.
//! NodePtrPriorityCompare is a priority function object that induces a strict weak
//! ordering compatible with the one used to create the
//! the tree. NodePtrPriorityCompare compares two node_ptrs.
//!
//! <b>Effects</b>: Inserts new_node into the tree, using "hint" as a hint to
//! where it will be inserted. If "hint" is the upper_bound
//! the insertion takes constant time (two comparisons in the worst case).
//! Rotates the tree according to "pcomp".
//!
//! <b>Complexity</b>: Logarithmic in general, but it is amortized
//! constant time if new_node is inserted immediately before "hint".
//!
//! <b>Throws</b>: If "comp" throws.
template<class NodePtrCompare, class NodePriorityCompare>
//! <b>Throws</b>: If "comp" throw or "pcomp" throw.
template<class NodePtrCompare, class NodePtrPriorityCompare>
static node_ptr insert_equal
(node_ptr h, node_ptr hint, node_ptr new_node, NodePtrCompare comp, NodePriorityCompare pcomp)
(node_ptr h, node_ptr hint, node_ptr new_node, NodePtrCompare comp, NodePtrPriorityCompare pcomp)
{
insert_commit_data commit_data;
tree_algorithms::insert_equal_check(h, hint, new_node, comp, commit_data);
rebalance_after_insertion_check(h, commit_data.node, new_node, pcomp, commit_data.rotations);
tree_algorithms::insert_unique_commit(h, new_node, commit_data);
rebalance_after_insertion_commit(h, new_node, commit_data.rotations);
rebalance_check_and_commit(h, new_node, pcomp, commit_data);
return new_node;
}
//! <b>Requires</b>: "header" must be the header node of a tree.
//! "pos" must be a valid node of the tree (including header end) node.
//! "pos" must be a node pointing to the successor to "new_node"
//! once inserted according to the order of already inserted nodes. This function does not
//! check "pos" and this precondition must be guaranteed by the caller.
//! NodePtrPriorityCompare is a priority function object that induces a strict weak
//! ordering compatible with the one used to create the
//! the tree. NodePtrPriorityCompare compares two node_ptrs.
//!
//! <b>Effects</b>: Inserts new_node into the tree before "pos"
//! and rotates the tree according to "pcomp".
//!
//! <b>Complexity</b>: Constant-time.
//!
//! <b>Throws</b>: If "pcomp" throws, strong guarantee.
//!
//! <b>Note</b>: If "pos" is not the successor of the newly inserted "new_node"
//! tree invariants might be broken.
template<class NodePtrPriorityCompare>
static node_ptr insert_before
(node_ptr header, node_ptr pos, node_ptr new_node, NodePtrPriorityCompare pcomp)
{
insert_commit_data commit_data;
tree_algorithms::insert_before_check(header, pos, commit_data);
rebalance_check_and_commit(header, new_node, pcomp, commit_data);
return new_node;
}
//! <b>Requires</b>: "header" must be the header node of a tree.
//! "new_node" must be, according to the used ordering no less than the
//! greatest inserted key.
//! NodePtrPriorityCompare is a priority function object that induces a strict weak
//! ordering compatible with the one used to create the
//! the tree. NodePtrPriorityCompare compares two node_ptrs.
//!
//! <b>Effects</b>: Inserts x into the tree in the last position
//! and rotates the tree according to "pcomp".
//!
//! <b>Complexity</b>: Constant-time.
//!
//! <b>Throws</b>: If "pcomp" throws, strong guarantee.
//!
//! <b>Note</b>: If "new_node" is less than the greatest inserted key
//! tree invariants are broken. This function is slightly faster than
//! using "insert_before".
template<class NodePtrPriorityCompare>
static void push_back(node_ptr header, node_ptr new_node, NodePtrPriorityCompare pcomp)
{
insert_commit_data commit_data;
tree_algorithms::push_back_check(header, commit_data);
rebalance_check_and_commit(header, new_node, pcomp, commit_data);
}
//! <b>Requires</b>: "header" must be the header node of a tree.
//! "new_node" must be, according to the used ordering, no greater than the
//! lowest inserted key.
//! NodePtrPriorityCompare is a priority function object that induces a strict weak
//! ordering compatible with the one used to create the
//! the tree. NodePtrPriorityCompare compares two node_ptrs.
//!
//! <b>Effects</b>: Inserts x into the tree in the first position
//! and rotates the tree according to "pcomp".
//!
//! <b>Complexity</b>: Constant-time.
//!
//! <b>Throws</b>: If "pcomp" throws, strong guarantee.
//!
//! <b>Note</b>: If "new_node" is greater than the lowest inserted key
//! tree invariants are broken. This function is slightly faster than
//! using "insert_before".
template<class NodePtrPriorityCompare>
static void push_front(node_ptr header, node_ptr new_node, NodePtrPriorityCompare pcomp)
{
insert_commit_data commit_data;
tree_algorithms::push_front_check(header, commit_data);
rebalance_check_and_commit(header, new_node, pcomp, commit_data);
}
//! <b>Requires</b>: "header" must be the header node of a tree.
//! KeyNodePtrCompare is a function object that induces a strict weak
//! ordering compatible with the strict weak ordering used to create the
@@ -720,8 +802,8 @@ class treap_algorithms
return tree_algorithms::is_header(p);
}
template<class NodePriorityCompare>
static void rebalance_for_erasure(node_ptr header, node_ptr z, NodePriorityCompare pcomp)
template<class NodePtrPriorityCompare>
static void rebalance_for_erasure(node_ptr header, node_ptr z, NodePtrPriorityCompare pcomp)
{
std::size_t n = 0;
rerotate_on_destroy rb(header, z, n);
@@ -742,6 +824,17 @@ class treap_algorithms
rb.release();
}
template<class NodePtrPriorityCompare>
static void rebalance_check_and_commit
(node_ptr h, node_ptr new_node, NodePtrPriorityCompare pcomp, insert_commit_data &commit_data)
{
rebalance_after_insertion_check(h, commit_data.node, new_node, pcomp, commit_data.rotations);
//No-throw
tree_algorithms::insert_unique_commit(h, new_node, commit_data);
rebalance_after_insertion_commit(h, new_node, commit_data.rotations);
}
template<class Key, class KeyNodePriorityCompare>
static void rebalance_after_insertion_check
( const_node_ptr header, const_node_ptr upnode, const Key &k
@@ -759,7 +852,7 @@ class treap_algorithms
static void rebalance_after_insertion_commit(node_ptr header, node_ptr p, std::size_t n)
{
// Now to n rotations
// Now execute n rotations
for( node_ptr p_parent = NodeTraits::get_parent(p)
; n--
; p_parent = NodeTraits::get_parent(p)){
@@ -773,8 +866,8 @@ class treap_algorithms
}
}
template<class NodePriorityCompare>
static bool check_invariant(const_node_ptr header, NodePriorityCompare pcomp)
template<class NodePtrPriorityCompare>
static bool check_invariant(const_node_ptr header, NodePtrPriorityCompare pcomp)
{
node_ptr beg = begin_node(header);
node_ptr end = end_node(header);
@@ -798,4 +891,4 @@ class treap_algorithms
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_TRIE_ALGORITHMS_HPP
#endif //BOOST_INTRUSIVE_TREAP_ALGORITHMS_HPP

View File

@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2008
// (C) Copyright Ion Gaztanaga 2007-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -351,6 +351,14 @@ class treap_set_impl
value_compare value_comp() const
{ return tree_.value_comp(); }
//! <b>Effects</b>: Returns the priority_compare object used by the treap_set.
//!
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: If priority_compare copy-constructor throws.
priority_compare priority_comp() const
{ return tree_.priority_comp(); }
//! <b>Effects</b>: Returns true if the container is empty.
//!
//! <b>Complexity</b>: Constant.
@@ -408,7 +416,8 @@ class treap_set_impl
//! <b>Complexity</b>: Average complexity for insert element is at
//! most logarithmic.
//!
//! <b>Throws</b>: If the internal value_compare ordering function throws. Strong guarantee.
//! <b>Throws</b>: If the internal value_compare or priority_compare ordering function throw.
//! Strong guarantee.
//!
//! <b>Note</b>: Does not affect the validity of iterators and references.
//! No copy-constructors are called.
@@ -426,7 +435,8 @@ class treap_set_impl
//! <b>Complexity</b>: Logarithmic in general, but it's amortized
//! constant time if t is inserted immediately before hint.
//!
//! <b>Throws</b>: If the internal value_compare ordering function throws. Strong guarantee.
//! <b>Throws</b>: If the internal value_compare or priority_compare ordering
//! functions throw. Strong guarantee.
//!
//! <b>Note</b>: Does not affect the validity of iterators and references.
//! No copy-constructors are called.
@@ -434,8 +444,10 @@ class treap_set_impl
{ return tree_.insert_unique(hint, value); }
//! <b>Requires</b>: key_value_comp must be a comparison function that induces
//! the same strict weak ordering as value_compare. The difference is that
//! key_value_comp compares an ascapegoatitrary key with the contained values.
//! the same strict weak ordering as value_compare.
//! key_value_pcomp must be a comparison function that induces
//! the same strict weak ordering as priority_compare. The difference is that
//! key_value_pcomp and key_value_comp compare an arbitrary key with the contained values.
//!
//! <b>Effects</b>: Checks if a value can be inserted in the treap_set, using
//! a user provided key instead of the value itself.
@@ -448,7 +460,8 @@ class treap_set_impl
//!
//! <b>Complexity</b>: Average complexity is at most logarithmic.
//!
//! <b>Throws</b>: If the key_value_comp ordering function throws. Strong guarantee.
//! <b>Throws</b>: If key_value_comp or key_value_pcomp ordering function throw.
//! Strong guarantee.
//!
//! <b>Notes</b>: This function is used to improve performance when constructing
//! a value_type is expensive: if there is an equivalent value
@@ -463,14 +476,17 @@ class treap_set_impl
//!
//! "commit_data" remains valid for a subsequent "insert_commit" only if no more
//! objects are inserted or erased from the treap_set.
template<class KeyType, class KeyValueCompare>
template<class KeyType, class KeyValueCompare, class KeyValuePriorityCompare>
std::pair<iterator, bool> insert_check
(const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data)
{ return tree_.insert_unique_check(key, key_value_comp, commit_data); }
( const KeyType &key, KeyValueCompare key_value_comp, KeyValuePriorityCompare key_value_pcomp
, insert_commit_data &commit_data)
{ return tree_.insert_unique_check(key, key_value_comp, key_value_pcomp, commit_data); }
//! <b>Requires</b>: key_value_comp must be a comparison function that induces
//! the same strict weak ordering as value_compare. The difference is that
//! key_value_comp compares an ascapegoatitrary key with the contained values.
//! the same strict weak ordering as value_compare.
//! key_value_pcomp must be a comparison function that induces
//! the same strict weak ordering as priority_compare. The difference is that
//! key_value_pcomp and key_value_comp compare an arbitrary key with the contained values.
//!
//! <b>Effects</b>: Checks if a value can be inserted in the treap_set, using
//! a user provided key instead of the value itself, using "hint"
@@ -485,7 +501,8 @@ class treap_set_impl
//! <b>Complexity</b>: Logarithmic in general, but it's amortized
//! constant time if t is inserted immediately before hint.
//!
//! <b>Throws</b>: If the key_value_comp ordering function throws. Strong guarantee.
//! <b>Throws</b>: If key_value_comp or key_value_pcomp ordering function throw.
//! Strong guarantee.
//!
//! <b>Notes</b>: This function is used to improve performance when constructing
//! a value_type is expensive: if there is an equivalent value
@@ -500,11 +517,12 @@ class treap_set_impl
//!
//! "commit_data" remains valid for a subsequent "insert_commit" only if no more
//! objects are inserted or erased from the treap_set.
template<class KeyType, class KeyValueCompare>
template<class KeyType, class KeyValueCompare, class KeyValuePriorityCompare>
std::pair<iterator, bool> insert_check
( const_iterator hint, const KeyType &key
,KeyValueCompare key_value_comp, insert_commit_data &commit_data)
{ return tree_.insert_unique_check(hint, key, key_value_comp, commit_data); }
, KeyValueCompare key_value_comp, KeyValuePriorityCompare key_value_pcomp
, insert_commit_data &commit_data)
{ return tree_.insert_unique_check(hint, key, key_value_comp, key_value_pcomp, commit_data); }
//! <b>Requires</b>: value must be an lvalue of type value_type. commit_data
//! must have been obtained from a previous call to "insert_check".
@@ -535,7 +553,8 @@ class treap_set_impl
//! size of the range. However, it is linear in N if the range is already sorted
//! by value_comp().
//!
//! <b>Throws</b>: If the internal value_compare ordering function throws. Basic guarantee.
//! <b>Throws</b>: If the internal value_compare or priority_compare ordering function
//! throw. Basic guarantee.
//!
//! <b>Note</b>: Does not affect the validity of iterators and references.
//! No copy-constructors are called.
@@ -543,13 +562,65 @@ class treap_set_impl
void insert(Iterator b, Iterator e)
{ tree_.insert_unique(b, e); }
//! <b>Requires</b>: value must be an lvalue, "pos" must be
//! a valid iterator (or end) and must be the succesor of value
//! once inserted according to the predicate. "value" must not be equal to any
//! inserted key according to the predicate.
//!
//! <b>Effects</b>: Inserts x into the treap before "pos".
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: If the internal priority_compare function throws. Strong guarantee.
//!
//! <b>Note</b>: This function does not check preconditions so if "pos" is not
//! the successor of "value" treap ordering invariant will be broken.
//! This is a low-level function to be used only for performance reasons
//! by advanced users.
iterator insert_before(const_iterator pos, reference value)
{ return tree_.insert_before(pos, value); }
//! <b>Requires</b>: value must be an lvalue, and it must be greater than
//! any inserted key according to the predicate.
//!
//! <b>Effects</b>: Inserts x into the treap in the last position.
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: If the internal priority_compare function throws. Strong guarantee.
//!
//! <b>Note</b>: This function does not check preconditions so if value is
//! less than the greatest inserted key treap ordering invariant will be broken.
//! This function is slightly more efficient than using "insert_before".
//! This is a low-level function to be used only for performance reasons
//! by advanced users.
void push_back(reference value)
{ tree_.push_back(value); }
//! <b>Requires</b>: value must be an lvalue, and it must be less
//! than any inserted key according to the predicate.
//!
//! <b>Effects</b>: Inserts x into the treap in the first position.
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: If the internal priority_compare function throws. Strong guarantee.
//!
//! <b>Note</b>: This function does not check preconditions so if value is
//! greater than the minimum inserted key treap ordering invariant will be broken.
//! This function is slightly more efficient than using "insert_before".
//! This is a low-level function to be used only for performance reasons
//! by advanced users.
void push_front(reference value)
{ tree_.push_front(value); }
//! <b>Effects</b>: Erases the element pointed to by pos.
//!
//! <b>Complexity</b>: Average complexity is constant time.
//!
//! <b>Returns</b>: An iterator to the element after the erased element.
//!
//! <b>Throws</b>: Nothing.
//! <b>Throws</b>: If the internal priority_compare function throws. Strong guarantee.
//!
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
@@ -563,7 +634,7 @@ class treap_set_impl
//!
//! <b>Returns</b>: An iterator to the element after the erased elements.
//!
//! <b>Throws</b>: Nothing.
//! <b>Throws</b>: If the internal priority_compare function throws. Basic guarantee.
//!
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
@@ -576,7 +647,8 @@ class treap_set_impl
//!
//! <b>Complexity</b>: O(log(size()) + this->count(value)).
//!
//! <b>Throws</b>: If the internal value_compare ordering function throws. Basic guarantee.
//! <b>Throws</b>: If internal value_compare or priority_compare
//! ordering functions throw. Basic guarantee.
//!
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
@@ -590,7 +662,8 @@ class treap_set_impl
//!
//! <b>Complexity</b>: O(log(size() + this->count(key, comp)).
//!
//! <b>Throws</b>: If the comp ordering function throws. Basic guarantee.
//! <b>Throws</b>: If comp or internal priority_compare
//! ordering functions throw. Basic guarantee.
//!
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
@@ -611,7 +684,7 @@ class treap_set_impl
//!
//! <b>Returns</b>: An iterator to the element after the erased element.
//!
//! <b>Throws</b>: Nothing.
//! <b>Throws</b>: If the internal priority_compare function throws. Strong guarantee.
//!
//! <b>Note</b>: Invalidates the iterators
//! to the erased elements.
@@ -635,7 +708,7 @@ class treap_set_impl
//!
//! <b>Returns</b>: An iterator to the element after the erased elements.
//!
//! <b>Throws</b>: Nothing.
//! <b>Throws</b>: If the internal priority_compare function throws. Basic guarantee.
//!
//! <b>Note</b>: Invalidates the iterators
//! to the erased elements.
@@ -652,7 +725,7 @@ class treap_set_impl
//!
//! <b>Complexity</b>: O(log(size() + this->count(value)). Basic guarantee.
//!
//! <b>Throws</b>: Nothing.
//! <b>Throws</b>: If the internal priority_compare function throws. Strong guarantee.
//!
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
@@ -670,7 +743,8 @@ class treap_set_impl
//!
//! <b>Complexity</b>: O(log(size() + this->count(key, comp)).
//!
//! <b>Throws</b>: If comp ordering function throws. Basic guarantee.
//! <b>Throws</b>: If comp or internal priority_compare ordering functions throw.
//! Basic guarantee.
//!
//! <b>Note</b>: Invalidates the iterators
//! to the erased elements.
@@ -1584,6 +1658,14 @@ class treap_multiset_impl
value_compare value_comp() const
{ return tree_.value_comp(); }
//! <b>Effects</b>: Returns the priority_compare object used by the treap_multiset.
//!
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: If priority_compare copy-constructor throws.
priority_compare priority_comp() const
{ return tree_.priority_comp(); }
//! <b>Effects</b>: Returns true if the container is empty.
//!
//! <b>Complexity</b>: Constant.
@@ -1638,7 +1720,8 @@ class treap_multiset_impl
//! <b>Complexity</b>: Average complexity for insert element is at
//! most logarithmic.
//!
//! <b>Throws</b>: If the internal value_compare ordering function throws. Strong guarantee.
//! <b>Throws</b>: If the internal value_compare or priority_compare ordering
//! function throws. Strong guarantee.
//!
//! <b>Note</b>: Does not affect the validity of iterators and references.
//! No copy-constructors are called.
@@ -1656,7 +1739,8 @@ class treap_multiset_impl
//! <b>Complexity</b>: Logarithmic in general, but it is amortized
//! constant time if t is inserted immediately before hint.
//!
//! <b>Throws</b>: If the internal value_compare ordering function throws. Strong guarantee.
//! <b>Throws</b>: If internal value_compare or priority_compare ordering functions throw.
//! Strong guarantee.
//!
//! <b>Note</b>: Does not affect the validity of iterators and references.
//! No copy-constructors are called.
@@ -1675,7 +1759,8 @@ class treap_multiset_impl
//! size of the range. However, it is linear in N if the range is already sorted
//! by value_comp().
//!
//! <b>Throws</b>: If the internal value_compare ordering function throws. Basic guarantee.
//! <b>Throws</b>: If internal value_compare or priority_compare ordering functions throw.
//! Basic guarantee.
//!
//! <b>Note</b>: Does not affect the validity of iterators and references.
//! No copy-constructors are called.
@@ -1683,13 +1768,64 @@ class treap_multiset_impl
void insert(Iterator b, Iterator e)
{ tree_.insert_equal(b, e); }
//! <b>Requires</b>: value must be an lvalue, "pos" must be
//! a valid iterator (or end) and must be the succesor of value
//! once inserted according to the predicate
//!
//! <b>Effects</b>: Inserts x into the treap before "pos".
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: If the internal priority_compare function throws. Strong guarantee.
//!
//! <b>Note</b>: This function does not check preconditions so if "pos" is not
//! the successor of "value" treap ordering invariant will be broken.
//! This is a low-level function to be used only for performance reasons
//! by advanced users.
iterator insert_before(const_iterator pos, reference value)
{ return tree_.insert_before(pos, value); }
//! <b>Requires</b>: value must be an lvalue, and it must be no less
//! than the greatest inserted key.
//!
//! <b>Effects</b>: Inserts x into the treap in the last position.
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: If the internal priority_compare function throws. Strong guarantee.
//!
//! <b>Note</b>: This function does not check preconditions so if value is
//! less than the greatest inserted key treap ordering invariant will be broken.
//! This function is slightly more efficient than using "insert_before".
//! This is a low-level function to be used only for performance reasons
//! by advanced users.
void push_back(reference value)
{ tree_.push_back(value); }
//! <b>Requires</b>: value must be an lvalue, and it must be no greater
//! than the minimum inserted key
//!
//! <b>Effects</b>: Inserts x into the treap in the first position.
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: If the internal priority_compare function throws. Strong guarantee.
//!
//! <b>Note</b>: This function does not check preconditions so if value is
//! greater than the minimum inserted key treap ordering invariant will be broken.
//! This function is slightly more efficient than using "insert_before".
//! This is a low-level function to be used only for performance reasons
//! by advanced users.
void push_front(reference value)
{ tree_.push_front(value); }
//! <b>Effects</b>: Erases the element pointed to by pos.
//!
//! <b>Complexity</b>: Average complexity is constant time.
//!
//! <b>Returns</b>: An iterator to the element after the erased element.
//!
//! <b>Throws</b>: Nothing.
//! <b>Throws</b>: If the internal priority_compare function throws. Strong guarantee.
//!
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
@@ -1703,7 +1839,7 @@ class treap_multiset_impl
//! <b>Complexity</b>: Average complexity for erase range is at most
//! O(log(size() + N)), where N is the number of elements in the range.
//!
//! <b>Throws</b>: Nothing.
//! <b>Throws</b>: If the internal priority_compare function throws. Basic guarantee.
//!
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
@@ -1716,7 +1852,8 @@ class treap_multiset_impl
//!
//! <b>Complexity</b>: O(log(size() + this->count(value)).
//!
//! <b>Throws</b>: If the internal value_compare ordering function throws. Basic guarantee.
//! <b>Throws</b>: If the internal value_compare or priority_compare ordering
//! functiona throw. Basic guarantee.
//!
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
@@ -1730,7 +1867,7 @@ class treap_multiset_impl
//!
//! <b>Complexity</b>: O(log(size() + this->count(key, comp)).
//!
//! <b>Throws</b>: If comp ordering function throws. Basic guarantee.
//! <b>Throws</b>: If comp or internal priority_compare ordering functions throw. Basic guarantee.
//!
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
@@ -1751,7 +1888,7 @@ class treap_multiset_impl
//!
//! <b>Complexity</b>: Average complexity for erase element is constant time.
//!
//! <b>Throws</b>: Nothing.
//! <b>Throws</b>: If the internal priority_compare function throws. Strong guarantee.
//!
//! <b>Note</b>: Invalidates the iterators
//! to the erased elements.
@@ -1775,7 +1912,7 @@ class treap_multiset_impl
//! <b>Complexity</b>: Average complexity for erase range is at most
//! O(log(size() + N)), where N is the number of elements in the range.
//!
//! <b>Throws</b>: Nothing.
//! <b>Throws</b>: If the internal priority_compare function throws. Basic guarantee.
//!
//! <b>Note</b>: Invalidates the iterators
//! to the erased elements.
@@ -1810,7 +1947,7 @@ class treap_multiset_impl
//!
//! <b>Complexity</b>: O(log(size() + this->count(key, comp)).
//!
//! <b>Throws</b>: If comp ordering function throws. Basic guarantee.
//! <b>Throws</b>: If comp or internal priority_compare ordering functions throw. Basic guarantee.
//!
//! <b>Note</b>: Invalidates the iterators
//! to the erased elements.

View File

@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2008
// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
// (C) Copyright Ion Gaztanaga 2006-2008
// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -395,8 +395,8 @@ class unordered_set_impl
//!
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased element. No destructors are called.
void erase(const_iterator i)
{ table_.erase(i); }
iterator erase(const_iterator i)
{ return table_.erase(i); }
//! <b>Effects</b>: Erases the range pointed to by b end e.
//!
@@ -407,8 +407,8 @@ class unordered_set_impl
//!
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
void erase(const_iterator b, const_iterator e)
{ table_.erase(b, e); }
iterator erase(const_iterator b, const_iterator e)
{ return table_.erase(b, e); }
//! <b>Effects</b>: Erases all the elements with the given value.
//!
@@ -460,15 +460,13 @@ class unordered_set_impl
//! <b>Note</b>: Invalidates the iterators
//! to the erased elements.
template<class Disposer>
iterator erase_and_dispose(const_iterator i, Disposer disposer)
iterator erase_and_dispose(const_iterator i, Disposer disposer
/// @cond
, typename detail::enable_if_c<!detail::is_convertible<Disposer, const_iterator>::value >::type * = 0
/// @endcond
)
{ return table_.erase_and_dispose(i, disposer); }
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class Disposer>
iterator erase_and_dispose(iterator i, Disposer disposer)
{ return this->erase_and_dispose(const_iterator(i), disposer); }
#endif
//! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//!
//! <b>Effects</b>: Erases the range pointed to by b end e.
@@ -1370,9 +1368,8 @@ class unordered_multiset_impl
//!
//! <b>Effects</b>: Equivalent to this->insert(t) for each element in [b, e).
//!
//! <b>Complexity</b>: Insert range is in general O(N * log(N)), where N is the
//! size of the range. However, it is linear in N if the range is already sorted
//! by value_comp().
//! <b>Complexity</b>: Average case is O(N), where N is the
//! size of the range.
//!
//! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee.
//!
@@ -1390,8 +1387,8 @@ class unordered_multiset_impl
//!
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased element. No destructors are called.
void erase(const_iterator i)
{ table_.erase(i); }
iterator erase(const_iterator i)
{ return table_.erase(i); }
//! <b>Effects</b>: Erases the range pointed to by b end e.
//!
@@ -1402,8 +1399,8 @@ class unordered_multiset_impl
//!
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
void erase(const_iterator b, const_iterator e)
{ table_.erase(b, e); }
iterator erase(const_iterator b, const_iterator e)
{ return table_.erase(b, e); }
//! <b>Effects</b>: Erases all the elements with the given value.
//!
@@ -1456,12 +1453,16 @@ class unordered_multiset_impl
//! <b>Note</b>: Invalidates the iterators
//! to the erased elements.
template<class Disposer>
void erase_and_dispose(const_iterator i, Disposer disposer)
{ table_.erase_and_dispose(i, disposer); }
iterator erase_and_dispose(const_iterator i, Disposer disposer
/// @cond
, typename detail::enable_if_c<!detail::is_convertible<Disposer, const_iterator>::value >::type * = 0
/// @endcond
)
{ return table_.erase_and_dispose(i, disposer); }
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class Disposer>
iterator erase_and_dispose(iterator i, Disposer disposer)
iterator erase_and_dispose(const_iterator i, Disposer disposer)
{ return this->erase_and_dispose(const_iterator(i), disposer); }
#endif
@@ -1478,8 +1479,8 @@ class unordered_multiset_impl
//! <b>Note</b>: Invalidates the iterators
//! to the erased elements.
template<class Disposer>
void erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer)
{ table_.erase_and_dispose(b, e, disposer); }
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer)
{ return table_.erase_and_dispose(b, e, disposer); }
//! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//!

View File

@@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
// (C) Copyright Ion Gaztanaga 2006-2008
// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -222,6 +222,7 @@ class unordered_set_base_hook
>::type
{
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
public:
//! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state.
//!
@@ -351,6 +352,7 @@ class unordered_set_member_hook
>::type
{
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
public:
//! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state.
//!