1
0
mirror of https://git.suyu.dev/suyu/suyu synced 2025-09-09 07:46:32 -05:00

Initial commit

This commit is contained in:
Crimson-Hawk
2024-03-05 16:42:40 +08:00
commit f1e4595ebf
39576 changed files with 7006612 additions and 0 deletions

View File

@@ -0,0 +1,2 @@
CRTLinkage: dynamic
LibraryLinkage: dynamic

View File

@@ -0,0 +1,8 @@
Package: boost-intrusive
Version: 1.79.0
Depends: boost-assert, boost-config, boost-container-hash, boost-core, boost-move, boost-static-assert, boost-vcpkg-helpers
Architecture: x64-windows
Multi-Arch: same
Abi: 531507e8bb60357a5f2420b0e6b640bce3890897679adb14e8d075f328c7d29d
Description: Boost intrusive module
Type: Port

View File

@@ -0,0 +1,338 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2013
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_ANY_HOOK_HPP
#define BOOST_INTRUSIVE_ANY_HOOK_HPP
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/intrusive/detail/any_node_and_algorithms.hpp>
#include <boost/intrusive/options.hpp>
#include <boost/intrusive/detail/generic_hook.hpp>
#include <boost/intrusive/detail/mpl.hpp>
#include <boost/intrusive/pointer_rebind.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
namespace boost {
namespace intrusive {
//! Helper metafunction to define a \c \c any_base_hook that yields to the same
//! type when the same options (either explicitly or implicitly) are used.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class ...Options>
#else
template<class O1 = void, class O2 = void, class O3 = void>
#endif
struct make_any_base_hook
{
/// @cond
typedef typename pack_options
< hook_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
O1, O2, O3
#else
Options...
#endif
>::type packed_options;
typedef generic_hook
< AnyAlgorithm
, any_node_traits<typename packed_options::void_pointer>
, typename packed_options::tag
, packed_options::link_mode
, AnyBaseHookId
> implementation_defined;
/// @endcond
typedef implementation_defined type;
};
//! Derive a class from this hook in order to store objects of that class
//! in an intrusive container.
//!
//! The hook admits the following options: \c tag<>, \c void_pointer<> and
//! \c link_mode<>.
//!
//! \c tag<> defines a tag to identify the node.
//! The same tag value can be used in different classes, but if a class is
//! derived from more than one \c any_base_hook, then each \c any_base_hook needs its
//! unique tag.
//!
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link, \c safe_link).
//!
//! \c void_pointer<> is the pointer type that will be used internally in the hook
//! and the container configured to use this hook.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class ...Options>
#else
template<class O1, class O2, class O3>
#endif
class any_base_hook
: public make_any_base_hook
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
<O1, O2, O3>
#else
<Options...>
#endif
::type
{
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
public:
//! <b>Effects</b>: If link_mode is or \c safe_link
//! initializes the node to an unlinked state.
//!
//! <b>Throws</b>: Nothing.
any_base_hook();
//! <b>Effects</b>: If link_mode is or \c safe_link
//! initializes the node to an unlinked state. The argument is ignored.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Rationale</b>: Providing a copy-constructor
//! makes classes using the hook STL-compliant without forcing the
//! user to do some additional work. \c swap can be used to emulate
//! move-semantics.
any_base_hook(const any_base_hook& );
//! <b>Effects</b>: Empty function. The argument is ignored.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Rationale</b>: Providing an assignment operator
//! makes classes using the hook STL-compliant without forcing the
//! user to do some additional work. \c swap can be used to emulate
//! move-semantics.
any_base_hook& operator=(const any_base_hook& );
//! <b>Effects</b>: If link_mode is \c normal_link, the destructor does
//! nothing (ie. no code is generated). If link_mode is \c safe_link and the
//! object is stored in a container an assertion is raised.
//!
//! <b>Throws</b>: Nothing.
~any_base_hook();
//! <b>Precondition</b>: link_mode must be \c safe_link.
//!
//! <b>Returns</b>: true, if the node belongs to a container, false
//! otherwise. This function can be used to test whether \c container::iterator_to
//! will return a valid iterator.
//!
//! <b>Complexity</b>: Constant
bool is_linked() const;
#endif
};
//! Helper metafunction to define a \c \c any_member_hook that yields to the same
//! type when the same options (either explicitly or implicitly) are used.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class ...Options>
#else
template<class O1 = void, class O2 = void, class O3 = void>
#endif
struct make_any_member_hook
{
/// @cond
typedef typename pack_options
< hook_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
O1, O2, O3
#else
Options...
#endif
>::type packed_options;
typedef generic_hook
< AnyAlgorithm
, any_node_traits<typename packed_options::void_pointer>
, member_tag
, packed_options::link_mode
, NoBaseHookId
> implementation_defined;
/// @endcond
typedef implementation_defined type;
};
//! Store this hook in a class to be inserted
//! in an intrusive container.
//!
//! The hook admits the following options: \c void_pointer<> and
//! \c link_mode<>.
//!
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link or \c safe_link).
//!
//! \c void_pointer<> is the pointer type that will be used internally in the hook
//! and the container configured to use this hook.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class ...Options>
#else
template<class O1, class O2, class O3>
#endif
class any_member_hook
: public make_any_member_hook
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
<O1, O2, O3>
#else
<Options...>
#endif
::type
{
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
public:
//! <b>Effects</b>: If link_mode is or \c safe_link
//! initializes the node to an unlinked state.
//!
//! <b>Throws</b>: Nothing.
any_member_hook() BOOST_NOEXCEPT;
//! <b>Effects</b>: If link_mode is or \c safe_link
//! initializes the node to an unlinked state. The argument is ignored.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Rationale</b>: Providing a copy-constructor
//! makes classes using the hook STL-compliant without forcing the
//! user to do some additional work. \c swap can be used to emulate
//! move-semantics.
any_member_hook(const any_member_hook&) BOOST_NOEXCEPT;
//! <b>Effects</b>: Empty function. The argument is ignored.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Rationale</b>: Providing an assignment operator
//! makes classes using the hook STL-compliant without forcing the
//! user to do some additional work. \c swap can be used to emulate
//! move-semantics.
any_member_hook& operator=(const any_member_hook&) BOOST_NOEXCEPT;
//! <b>Effects</b>: If link_mode is \c normal_link, the destructor does
//! nothing (ie. no code is generated). If link_mode is \c safe_link and the
//! object is stored in a container an assertion is raised.
//!
//! <b>Throws</b>: Nothing.
~any_member_hook();
//! <b>Precondition</b>: link_mode must be \c safe_link.
//!
//! <b>Returns</b>: true, if the node belongs to a container, false
//! otherwise. This function can be used to test whether \c container::iterator_to
//! will return a valid iterator.
//!
//! <b>Complexity</b>: Constant
bool is_linked() const BOOST_NOEXCEPT;
#endif
};
/// @cond
namespace detail{
BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(old_proto_value_traits_base_hook, hooktags::is_base_hook)
//!This option setter specifies that the container
//!must use the specified base hook
template<class BasicHook, template <class> class NodeTraits>
struct any_to_some_hook
{
typedef typename BasicHook::template pack<empty>::proto_value_traits old_proto_value_traits;
template<class Base>
struct pack : public Base
{
struct proto_value_traits
{
//proto_value_traits::hooktags::is_base_hook is used by get_value_traits
//to detect base hooks, so mark it in case BasicHook has it.
struct hooktags
{
static const bool is_base_hook = old_proto_value_traits_base_hook_bool_is_true
<old_proto_value_traits>::value;
};
typedef old_proto_value_traits basic_hook_t;
static const bool is_any_hook = true;
template<class VoidPtr>
struct node_traits_from_voidptr
{ typedef NodeTraits<VoidPtr> type; };
};
};
};
} //namespace detail{
/// @endcond
//!This option setter specifies that
//!any hook should behave as an slist hook
template<class BasicHook>
struct any_to_slist_hook
/// @cond
: public detail::any_to_some_hook<BasicHook, any_slist_node_traits>
/// @endcond
{};
//!This option setter specifies that
//!any hook should behave as an list hook
template<class BasicHook>
struct any_to_list_hook
/// @cond
: public detail::any_to_some_hook<BasicHook, any_list_node_traits>
/// @endcond
{};
//!This option setter specifies that
//!any hook should behave as a set hook
template<class BasicHook>
struct any_to_set_hook
/// @cond
: public detail::any_to_some_hook<BasicHook, any_rbtree_node_traits>
/// @endcond
{};
//!This option setter specifies that
//!any hook should behave as an avl_set hook
template<class BasicHook>
struct any_to_avl_set_hook
/// @cond
: public detail::any_to_some_hook<BasicHook, any_avltree_node_traits>
/// @endcond
{};
//!This option setter specifies that any
//!hook should behave as a bs_set hook
template<class BasicHook>
struct any_to_bs_set_hook
/// @cond
: public detail::any_to_some_hook<BasicHook, any_tree_node_traits>
/// @endcond
{};
//!This option setter specifies that any hook
//!should behave as an unordered set hook
template<class BasicHook>
struct any_to_unordered_set_hook
/// @cond
: public detail::any_to_some_hook<BasicHook, any_unordered_node_traits>
/// @endcond
{};
} //namespace intrusive
} //namespace boost
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_ANY_HOOK_HPP

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,293 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2013
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_AVL_SET_HOOK_HPP
#define BOOST_INTRUSIVE_AVL_SET_HOOK_HPP
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/intrusive/detail/avltree_node.hpp>
#include <boost/intrusive/avltree_algorithms.hpp>
#include <boost/intrusive/options.hpp>
#include <boost/intrusive/detail/generic_hook.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
namespace boost {
namespace intrusive {
//! Helper metafunction to define a \c avl_set_base_hook that yields to the same
//! type when the same options (either explicitly or implicitly) are used.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class ...Options>
#else
template<class O1 = void, class O2 = void, class O3 = void, class O4 = void>
#endif
struct make_avl_set_base_hook
{
/// @cond
typedef typename pack_options
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
<hook_defaults, O1, O2, O3, O4>
#else
<hook_defaults, Options...>
#endif
::type packed_options;
typedef generic_hook
< AvlTreeAlgorithms
, avltree_node_traits<typename packed_options::void_pointer, packed_options::optimize_size>
, typename packed_options::tag
, packed_options::link_mode
, AvlTreeBaseHookId
> implementation_defined;
/// @endcond
typedef implementation_defined type;
};
//! Derive a class from avl_set_base_hook in order to store objects in
//! in an avl_set/avl_multiset. avl_set_base_hook holds the data necessary to maintain
//! the avl_set/avl_multiset and provides an appropriate value_traits class for avl_set/avl_multiset.
//!
//! The hook admits the following options: \c tag<>, \c void_pointer<>,
//! \c link_mode<> and \c optimize_size<>.
//!
//! \c tag<> defines a tag to identify the node.
//! The same tag value can be used in different classes, but if a class is
//! derived from more than one \c list_base_hook, then each \c list_base_hook needs its
//! unique tag.
//!
//! \c void_pointer<> is the pointer type that will be used internally in the hook
//! and the container configured to use this hook.
//!
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
//! \c auto_unlink or \c safe_link).
//!
//! \c optimize_size<> will tell the hook to optimize the hook for size instead
//! of speed.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class ...Options>
#else
template<class O1, class O2, class O3, class O4>
#endif
class avl_set_base_hook
: public make_avl_set_base_hook
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
<O1, O2, O3, O4>
#else
<Options...>
#endif
::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.
//!
//! <b>Throws</b>: Nothing.
avl_set_base_hook();
//! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state. The argument is ignored.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Rationale</b>: Providing a copy-constructor
//! makes classes using the hook STL-compliant without forcing the
//! user to do some additional work. \c swap can be used to emulate
//! move-semantics.
avl_set_base_hook(const avl_set_base_hook& );
//! <b>Effects</b>: Empty function. The argument is ignored.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Rationale</b>: Providing an assignment operator
//! makes classes using the hook STL-compliant without forcing the
//! user to do some additional work. \c swap can be used to emulate
//! move-semantics.
avl_set_base_hook& operator=(const avl_set_base_hook& );
//! <b>Effects</b>: If link_mode is \c normal_link, the destructor does
//! nothing (ie. no code is generated). If link_mode is \c safe_link and the
//! object is stored in a set an assertion is raised. If link_mode is
//! \c auto_unlink and \c is_linked() is true, the node is unlinked.
//!
//! <b>Throws</b>: Nothing.
~avl_set_base_hook();
//! <b>Effects</b>: Swapping two nodes swaps the position of the elements
//! related to those nodes in one or two containers. That is, if the node
//! this is part of the element e1, the node x is part of the element e2
//! and both elements are included in the containers s1 and s2, then after
//! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1
//! at the position of e1. If one element is not in a container, then
//! after the swap-operation the other element is not in a container.
//! Iterators to e1 and e2 related to those nodes are invalidated.
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
void swap_nodes(avl_set_base_hook &other);
//! <b>Precondition</b>: link_mode must be \c safe_link or \c auto_unlink.
//!
//! <b>Returns</b>: true, if the node belongs to a container, false
//! otherwise. This function can be used to test whether \c set::iterator_to
//! will return a valid iterator.
//!
//! <b>Complexity</b>: Constant
bool is_linked() const;
//! <b>Effects</b>: Removes the node if it's inserted in a container.
//! This function is only allowed if link_mode is \c auto_unlink.
//!
//! <b>Throws</b>: Nothing.
void unlink();
#endif
};
//! Helper metafunction to define a \c avl_set_member_hook that yields to the same
//! type when the same options (either explicitly or implicitly) are used.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class ...Options>
#else
template<class O1 = void, class O2 = void, class O3 = void, class O4 = void>
#endif
struct make_avl_set_member_hook
{
/// @cond
typedef typename pack_options
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
<hook_defaults, O1, O2, O3, O4>
#else
<hook_defaults, Options...>
#endif
::type packed_options;
typedef generic_hook
< AvlTreeAlgorithms
, avltree_node_traits<typename packed_options::void_pointer, packed_options::optimize_size>
, member_tag
, packed_options::link_mode
, NoBaseHookId
> implementation_defined;
/// @endcond
typedef implementation_defined type;
};
//! Put a public data member avl_set_member_hook in order to store objects of this class in
//! an avl_set/avl_multiset. avl_set_member_hook holds the data necessary for maintaining the
//! avl_set/avl_multiset and provides an appropriate value_traits class for avl_set/avl_multiset.
//!
//! The hook admits the following options: \c void_pointer<>,
//! \c link_mode<> and \c optimize_size<>.
//!
//! \c void_pointer<> is the pointer type that will be used internally in the hook
//! and the container configured to use this hook.
//!
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
//! \c auto_unlink or \c safe_link).
//!
//! \c optimize_size<> will tell the hook to optimize the hook for size instead
//! of speed.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class ...Options>
#else
template<class O1, class O2, class O3, class O4>
#endif
class avl_set_member_hook
: public make_avl_set_member_hook
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
<O1, O2, O3, O4>
#else
<Options...>
#endif
::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.
//!
//! <b>Throws</b>: Nothing.
avl_set_member_hook();
//! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state. The argument is ignored.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Rationale</b>: Providing a copy-constructor
//! makes classes using the hook STL-compliant without forcing the
//! user to do some additional work. \c swap can be used to emulate
//! move-semantics.
avl_set_member_hook(const avl_set_member_hook& );
//! <b>Effects</b>: Empty function. The argument is ignored.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Rationale</b>: Providing an assignment operator
//! makes classes using the hook STL-compliant without forcing the
//! user to do some additional work. \c swap can be used to emulate
//! move-semantics.
avl_set_member_hook& operator=(const avl_set_member_hook& );
//! <b>Effects</b>: If link_mode is \c normal_link, the destructor does
//! nothing (ie. no code is generated). If link_mode is \c safe_link and the
//! object is stored in a set an assertion is raised. If link_mode is
//! \c auto_unlink and \c is_linked() is true, the node is unlinked.
//!
//! <b>Throws</b>: Nothing.
~avl_set_member_hook();
//! <b>Effects</b>: Swapping two nodes swaps the position of the elements
//! related to those nodes in one or two containers. That is, if the node
//! this is part of the element e1, the node x is part of the element e2
//! and both elements are included in the containers s1 and s2, then after
//! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1
//! at the position of e1. If one element is not in a container, then
//! after the swap-operation the other element is not in a container.
//! Iterators to e1 and e2 related to those nodes are invalidated.
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
void swap_nodes(avl_set_member_hook &other);
//! <b>Precondition</b>: link_mode must be \c safe_link or \c auto_unlink.
//!
//! <b>Returns</b>: true, if the node belongs to a container, false
//! otherwise. This function can be used to test whether \c set::iterator_to
//! will return a valid iterator.
//!
//! <b>Complexity</b>: Constant
bool is_linked() const;
//! <b>Effects</b>: Removes the node if it's inserted in a container.
//! This function is only allowed if link_mode is \c auto_unlink.
//!
//! <b>Throws</b>: Nothing.
void unlink();
#endif
};
} //namespace intrusive
} //namespace boost
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_AVL_SET_HOOK_HPP

View File

@@ -0,0 +1,588 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2013
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_AVLTREE_HPP
#define BOOST_INTRUSIVE_AVLTREE_HPP
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/intrusive_fwd.hpp>
#include <cstddef>
#include <boost/intrusive/detail/minimal_less_equal_header.hpp>
#include <boost/intrusive/detail/minimal_pair_header.hpp>
#include <boost/static_assert.hpp>
#include <boost/intrusive/avl_set_hook.hpp>
#include <boost/intrusive/detail/avltree_node.hpp>
#include <boost/intrusive/bstree.hpp>
#include <boost/intrusive/detail/tree_node.hpp>
#include <boost/intrusive/detail/ebo_functor_holder.hpp>
#include <boost/intrusive/detail/mpl.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/detail/get_value_traits.hpp>
#include <boost/intrusive/avltree_algorithms.hpp>
#include <boost/intrusive/link_mode.hpp>
#include <boost/move/utility_core.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
namespace boost {
namespace intrusive {
/// @cond
struct default_avltree_hook_applier
{ template <class T> struct apply{ typedef typename T::default_avltree_hook type; }; };
template<>
struct is_default_hook_tag<default_avltree_hook_applier>
{ static const bool value = true; };
struct avltree_defaults
: bstree_defaults
{
typedef default_avltree_hook_applier proto_value_traits;
};
/// @endcond
//! The class template avltree is an intrusive AVL tree container, that
//! is used to construct intrusive avl_set and avl_multiset containers.
//! The no-throw guarantee holds only, if the key_compare object
//! doesn't throw.
//!
//! The template parameter \c T is the type to be managed by the container.
//! The user can specify additional options and if no options are provided
//! default options are used.
//!
//! The container supports the following options:
//! \c base_hook<>/member_hook<>/value_traits<>,
//! \c constant_time_size<>, \c size_type<> and
//! \c compare<>.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
#endif
class avltree_impl
/// @cond
: public bstree_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType, ConstantTimeSize, AvlTreeAlgorithms, HeaderHolder>
/// @endcond
{
public:
typedef ValueTraits value_traits;
/// @cond
typedef bstree_impl< ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType
, ConstantTimeSize, AvlTreeAlgorithms
, HeaderHolder> tree_type;
typedef tree_type implementation_defined;
/// @endcond
typedef typename implementation_defined::pointer pointer;
typedef typename implementation_defined::const_pointer const_pointer;
typedef typename implementation_defined::value_type value_type;
typedef typename implementation_defined::key_type key_type;
typedef typename implementation_defined::key_of_value key_of_value;
typedef typename implementation_defined::reference reference;
typedef typename implementation_defined::const_reference const_reference;
typedef typename implementation_defined::difference_type difference_type;
typedef typename implementation_defined::size_type size_type;
typedef typename implementation_defined::value_compare value_compare;
typedef typename implementation_defined::key_compare key_compare;
typedef typename implementation_defined::iterator iterator;
typedef typename implementation_defined::const_iterator const_iterator;
typedef typename implementation_defined::reverse_iterator reverse_iterator;
typedef typename implementation_defined::const_reverse_iterator const_reverse_iterator;
typedef typename implementation_defined::node_traits node_traits;
typedef typename implementation_defined::node node;
typedef typename implementation_defined::node_ptr node_ptr;
typedef typename implementation_defined::const_node_ptr const_node_ptr;
typedef typename implementation_defined::node_algorithms node_algorithms;
static const bool constant_time_size = implementation_defined::constant_time_size;
/// @cond
private:
//noncopyable
BOOST_MOVABLE_BUT_NOT_COPYABLE(avltree_impl)
/// @endcond
public:
typedef typename implementation_defined::insert_commit_data insert_commit_data;
//! @copydoc ::boost::intrusive::bstree::bstree()
avltree_impl()
: tree_type()
{}
//! @copydoc ::boost::intrusive::bstree::bstree(const key_compare &,const value_traits &)
explicit avltree_impl( const key_compare &cmp, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits)
{}
//! @copydoc ::boost::intrusive::bstree::bstree(bool,Iterator,Iterator,const key_compare &,const value_traits &)
template<class Iterator>
avltree_impl( bool unique, Iterator b, Iterator e
, const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(unique, b, e, cmp, v_traits)
{}
//! @copydoc ::boost::intrusive::bstree::bstree(bstree &&)
avltree_impl(BOOST_RV_REF(avltree_impl) x)
: tree_type(BOOST_MOVE_BASE(tree_type, x))
{}
//! @copydoc ::boost::intrusive::bstree::operator=(bstree &&)
avltree_impl& operator=(BOOST_RV_REF(avltree_impl) x)
{ return static_cast<avltree_impl&>(tree_type::operator=(BOOST_MOVE_BASE(tree_type, x))); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree::~bstree()
~avltree_impl();
//! @copydoc ::boost::intrusive::bstree::begin()
iterator begin() BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::begin()const
const_iterator begin() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::cbegin()const
const_iterator cbegin() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::end()
iterator end() BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::end()const
const_iterator end() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::cend()const
const_iterator cend() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::rbegin()
reverse_iterator rbegin() BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::rbegin()const
const_reverse_iterator rbegin() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::crbegin()const
const_reverse_iterator crbegin() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::rend()
reverse_iterator rend() BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::rend()const
const_reverse_iterator rend() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::crend()const
const_reverse_iterator crend() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::root()
iterator root() BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::root()const
const_iterator root() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::croot()const
const_iterator croot() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(iterator)
static avltree_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(const_iterator)
static const avltree_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::container_from_iterator(iterator)
static avltree_impl &container_from_iterator(iterator it) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::container_from_iterator(const_iterator)
static const avltree_impl &container_from_iterator(const_iterator it) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::key_comp()const
key_compare key_comp() const;
//! @copydoc ::boost::intrusive::bstree::value_comp()const
value_compare value_comp() const;
//! @copydoc ::boost::intrusive::bstree::empty()const
bool empty() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::size()const
size_type size() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::swap
void swap(avltree_impl& other);
//! @copydoc ::boost::intrusive::bstree::clone_from(const bstree&,Cloner,Disposer)
template <class Cloner, class Disposer>
void clone_from(const avltree_impl &src, Cloner cloner, Disposer disposer);
#else //BOOST_INTRUSIVE_DOXYGEN_INVOKED
using tree_type::clone_from;
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree::clone_from(bstree&&,Cloner,Disposer)
template <class Cloner, class Disposer>
void clone_from(BOOST_RV_REF(avltree_impl) src, Cloner cloner, Disposer disposer)
{ tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree::insert_equal(reference)
iterator insert_equal(reference value);
//! @copydoc ::boost::intrusive::bstree::insert_equal(const_iterator,reference)
iterator insert_equal(const_iterator hint, reference value);
//! @copydoc ::boost::intrusive::bstree::insert_equal(Iterator,Iterator)
template<class Iterator>
void insert_equal(Iterator b, Iterator e);
//! @copydoc ::boost::intrusive::bstree::insert_unique(reference)
std::pair<iterator, bool> insert_unique(reference value);
//! @copydoc ::boost::intrusive::bstree::insert_unique(const_iterator,reference)
iterator insert_unique(const_iterator hint, reference value);
//! @copydoc ::boost::intrusive::bstree::insert_unique_check(const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_unique_check
(const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data);
//! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_unique_check
(const_iterator hint, const KeyType &key
,KeyTypeKeyCompare comp, insert_commit_data &commit_data);
//! @copydoc ::boost::intrusive::bstree::insert_unique_check(const key_type&,insert_commit_data&)
std::pair<iterator, bool> insert_unique_check
(const key_type &key, insert_commit_data &commit_data);
//! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const key_type&,insert_commit_data&)
std::pair<iterator, bool> insert_unique_check
(const_iterator hint, const key_type &key, insert_commit_data &commit_data);
//! @copydoc ::boost::intrusive::bstree::insert_unique_commit
iterator insert_unique_commit(reference value, const insert_commit_data &commit_data) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::insert_unique(Iterator,Iterator)
template<class Iterator>
void insert_unique(Iterator b, Iterator e);
//! @copydoc ::boost::intrusive::bstree::insert_before
iterator insert_before(const_iterator pos, reference value) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::push_back
void push_back(reference value) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::push_front
void push_front(reference value) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::erase(const_iterator)
iterator erase(const_iterator i) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::erase(const_iterator,const_iterator)
iterator erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::erase(const key_type &)
size_type erase(const key_type &key);
//! @copydoc ::boost::intrusive::bstree::erase(const KeyType&,KeyTypeKeyCompare)
template<class KeyType, class KeyTypeKeyCompare>
size_type erase(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,const_iterator,Disposer)
template<class Disposer>
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const key_type &, Disposer)
template<class Disposer>
size_type erase_and_dispose(const key_type &key, Disposer disposer);
//! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer)
template<class KeyType, class KeyTypeKeyCompare, class Disposer>
size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer);
//! @copydoc ::boost::intrusive::bstree::clear
void clear() BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::clear_and_dispose
template<class Disposer>
void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::count(const key_type &ke)const
size_type count(const key_type &key) const;
//! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyTypeKeyCompare)const
template<class KeyType, class KeyTypeKeyCompare>
size_type count(const KeyType& key, KeyTypeKeyCompare comp) const;
//! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)
iterator lower_bound(const key_type &key);
//! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)
template<class KeyType, class KeyTypeKeyCompare>
iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)const
const_iterator lower_bound(const key_type &key) const;
//! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)const
template<class KeyType, class KeyTypeKeyCompare>
const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
//! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &key)
iterator upper_bound(const key_type &key);
//! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)
template<class KeyType, class KeyTypeKeyCompare>
iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)const
const_iterator upper_bound(const key_type &key) const;
//! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)const
template<class KeyType, class KeyTypeKeyCompare>
const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
//! @copydoc ::boost::intrusive::bstree::find(const key_type &)
iterator find(const key_type &key);
//! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)
template<class KeyType, class KeyTypeKeyCompare>
iterator find(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::bstree::find(const key_type &)const
const_iterator find(const key_type &key) const;
//! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)const
template<class KeyType, class KeyTypeKeyCompare>
const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
//! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)
std::pair<iterator,iterator> equal_range(const key_type &key);
//! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)
template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> equal_range(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)const
std::pair<const_iterator, const_iterator>
equal_range(const key_type &key) const;
//! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)const
template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
equal_range(const KeyType& key, KeyTypeKeyCompare comp) const;
//! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)
std::pair<iterator,iterator> bounded_range
(const key_type &lower, const key_type &upper_key, bool left_closed, bool right_closed);
//! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
(const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
//! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)const
std::pair<const_iterator, const_iterator>
bounded_range(const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator> bounded_range
(const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::bstree::s_iterator_to(reference)
static iterator s_iterator_to(reference value) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::s_iterator_to(const_reference)
static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::iterator_to(reference)
iterator iterator_to(reference value) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::iterator_to(const_reference)const
const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::init_node(reference)
static void init_node(reference value) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::unlink_leftmost_without_rebalance
pointer unlink_leftmost_without_rebalance() BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::replace_node
void replace_node(iterator replace_this, reference with_this) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::remove_node
void remove_node(reference value) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::merge_unique(bstree<T, Options2...>&)
template<class T, class ...Options2>
void merge_unique(avltree<T, Options2...> &);
//! @copydoc ::boost::intrusive::bstree::merge_equal(bstree<T, Options2...>&)
template<class T, class ...Options2>
void merge_equal(avltree<T, Options2...> &);
friend bool operator< (const avltree_impl &x, const avltree_impl &y);
friend bool operator==(const avltree_impl &x, const avltree_impl &y);
friend bool operator!= (const avltree_impl &x, const avltree_impl &y);
friend bool operator>(const avltree_impl &x, const avltree_impl &y);
friend bool operator<=(const avltree_impl &x, const avltree_impl &y);
friend bool operator>=(const avltree_impl &x, const avltree_impl &y);
friend void swap(avltree_impl &x, avltree_impl &y);
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
};
//! Helper metafunction to define a \c avltree that yields to the same type when the
//! same options (either explicitly or implicitly) are used.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
, class O5 = void, class O6 = void>
#endif
struct make_avltree
{
/// @cond
typedef typename pack_options
< avltree_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
O1, O2, O3, O4, O5, O6
#else
Options...
#endif
>::type packed_options;
typedef typename detail::get_value_traits
<T, typename packed_options::proto_value_traits>::type value_traits;
typedef avltree_impl
< value_traits
, typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::size_type
, packed_options::constant_time_size
, typename packed_options::header_holder_type
> implementation_defined;
/// @endcond
typedef implementation_defined type;
};
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class avltree
: public make_avltree<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
O1, O2, O3, O4, O5, O6
#else
Options...
#endif
>::type
{
typedef typename make_avltree
<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
O1, O2, O3, O4, O5, O6
#else
Options...
#endif
>::type Base;
BOOST_MOVABLE_BUT_NOT_COPYABLE(avltree)
public:
typedef typename Base::key_compare key_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
typedef typename Base::reverse_iterator reverse_iterator;
typedef typename Base::const_reverse_iterator const_reverse_iterator;
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
BOOST_INTRUSIVE_FORCEINLINE avltree()
: Base()
{}
BOOST_INTRUSIVE_FORCEINLINE explicit avltree( const key_compare &cmp, const value_traits &v_traits = value_traits())
: Base(cmp, v_traits)
{}
template<class Iterator>
BOOST_INTRUSIVE_FORCEINLINE avltree( bool unique, Iterator b, Iterator e
, const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(unique, b, e, cmp, v_traits)
{}
BOOST_INTRUSIVE_FORCEINLINE avltree(BOOST_RV_REF(avltree) x)
: Base(BOOST_MOVE_BASE(Base, x))
{}
BOOST_INTRUSIVE_FORCEINLINE avltree& operator=(BOOST_RV_REF(avltree) x)
{ return static_cast<avltree &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
template <class Cloner, class Disposer>
BOOST_INTRUSIVE_FORCEINLINE void clone_from(const avltree &src, Cloner cloner, Disposer disposer)
{ Base::clone_from(src, cloner, disposer); }
template <class Cloner, class Disposer>
BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(avltree) src, Cloner cloner, Disposer disposer)
{ Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
BOOST_INTRUSIVE_FORCEINLINE static avltree &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT
{ return static_cast<avltree &>(Base::container_from_end_iterator(end_iterator)); }
BOOST_INTRUSIVE_FORCEINLINE static const avltree &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT
{ return static_cast<const avltree &>(Base::container_from_end_iterator(end_iterator)); }
BOOST_INTRUSIVE_FORCEINLINE static avltree &container_from_iterator(iterator it) BOOST_NOEXCEPT
{ return static_cast<avltree &>(Base::container_from_iterator(it)); }
BOOST_INTRUSIVE_FORCEINLINE static const avltree &container_from_iterator(const_iterator it) BOOST_NOEXCEPT
{ return static_cast<const avltree &>(Base::container_from_iterator(it)); }
};
#endif
} //namespace intrusive
} //namespace boost
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_AVLTREE_HPP

View File

@@ -0,0 +1,727 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Daniel K. O. 2005.
// (C) Copyright Ion Gaztanaga 2007-2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_AVLTREE_ALGORITHMS_HPP
#define BOOST_INTRUSIVE_AVLTREE_ALGORITHMS_HPP
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/intrusive_fwd.hpp>
#include <cstddef>
#include <boost/intrusive/detail/assert.hpp>
#include <boost/intrusive/detail/algo_type.hpp>
#include <boost/intrusive/detail/ebo_functor_holder.hpp>
#include <boost/intrusive/bstree_algorithms.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
namespace boost {
namespace intrusive {
/// @cond
template<class NodeTraits, class F>
struct avltree_node_cloner
//Use public inheritance to avoid MSVC bugs with closures
: public detail::ebo_functor_holder<F>
{
typedef typename NodeTraits::node_ptr node_ptr;
typedef detail::ebo_functor_holder<F> base_t;
BOOST_INTRUSIVE_FORCEINLINE avltree_node_cloner(F f)
: base_t(f)
{}
node_ptr operator()(node_ptr p)
{
node_ptr n = base_t::get()(p);
NodeTraits::set_balance(n, NodeTraits::get_balance(p));
return n;
}
node_ptr operator()(node_ptr p) const
{
node_ptr n = base_t::get()(p);
NodeTraits::set_balance(n, NodeTraits::get_balance(p));
return n;
}
};
namespace detail {
template<class ValueTraits, class NodePtrCompare, class ExtraChecker>
struct avltree_node_checker
: public bstree_node_checker<ValueTraits, NodePtrCompare, ExtraChecker>
{
typedef bstree_node_checker<ValueTraits, NodePtrCompare, ExtraChecker> base_checker_t;
typedef ValueTraits value_traits;
typedef typename value_traits::node_traits node_traits;
typedef typename node_traits::const_node_ptr const_node_ptr;
struct return_type
: public base_checker_t::return_type
{
return_type() : height(0) {}
int height;
};
avltree_node_checker(const NodePtrCompare& comp, ExtraChecker extra_checker)
: base_checker_t(comp, extra_checker)
{}
void operator () (const_node_ptr p,
const return_type& check_return_left, const return_type& check_return_right,
return_type& check_return)
{
const int height_diff = check_return_right.height - check_return_left.height; (void)height_diff;
BOOST_INTRUSIVE_INVARIANT_ASSERT(
(height_diff == -1 && node_traits::get_balance(p) == node_traits::negative()) ||
(height_diff == 0 && node_traits::get_balance(p) == node_traits::zero()) ||
(height_diff == 1 && node_traits::get_balance(p) == node_traits::positive())
);
check_return.height = 1 +
(check_return_left.height > check_return_right.height ? check_return_left.height : check_return_right.height);
base_checker_t::operator()(p, check_return_left, check_return_right, check_return);
}
};
} // namespace detail
/// @endcond
//! avltree_algorithms is configured with a NodeTraits class, which encapsulates the
//! information about the node to be manipulated. NodeTraits must support the
//! following interface:
//!
//! <b>Typedefs</b>:
//!
//! <tt>node</tt>: The type of the node that forms the binary search tree
//!
//! <tt>node_ptr</tt>: A pointer to a node
//!
//! <tt>const_node_ptr</tt>: A pointer to a const node
//!
//! <tt>balance</tt>: The type of the balance factor
//!
//! <b>Static functions</b>:
//!
//! <tt>static node_ptr get_parent(const_node_ptr n);</tt>
//!
//! <tt>static void set_parent(node_ptr n, node_ptr parent);</tt>
//!
//! <tt>static node_ptr get_left(const_node_ptr n);</tt>
//!
//! <tt>static void set_left(node_ptr n, node_ptr left);</tt>
//!
//! <tt>static node_ptr get_right(const_node_ptr n);</tt>
//!
//! <tt>static void set_right(node_ptr n, node_ptr right);</tt>
//!
//! <tt>static balance get_balance(const_node_ptr n);</tt>
//!
//! <tt>static void set_balance(node_ptr n, balance b);</tt>
//!
//! <tt>static balance negative();</tt>
//!
//! <tt>static balance zero();</tt>
//!
//! <tt>static balance positive();</tt>
template<class NodeTraits>
class avltree_algorithms
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
: public bstree_algorithms<NodeTraits>
#endif
{
public:
typedef typename NodeTraits::node node;
typedef NodeTraits node_traits;
typedef typename NodeTraits::node_ptr node_ptr;
typedef typename NodeTraits::const_node_ptr const_node_ptr;
typedef typename NodeTraits::balance balance;
/// @cond
private:
typedef bstree_algorithms<NodeTraits> bstree_algo;
/// @endcond
public:
//! This type is the information that will be
//! filled by insert_unique_check
typedef typename bstree_algo::insert_commit_data insert_commit_data;
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree_algorithms::get_header(const_node_ptr)
static node_ptr get_header(const_node_ptr n) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::begin_node
static node_ptr begin_node(const_node_ptr header) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::end_node
static node_ptr end_node(const_node_ptr header) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::swap_tree
static void swap_tree(node_ptr header1, node_ptr header2) BOOST_NOEXCEPT;
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(node_ptr,node_ptr)
static void swap_nodes(node_ptr node1, node_ptr node2) BOOST_NOEXCEPT
{
if(node1 == node2)
return;
node_ptr header1(bstree_algo::get_header(node1)), header2(bstree_algo::get_header(node2));
swap_nodes(node1, header1, node2, header2);
}
//! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(node_ptr,node_ptr,node_ptr,node_ptr)
static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2) BOOST_NOEXCEPT
{
if(node1 == node2) return;
bstree_algo::swap_nodes(node1, header1, node2, header2);
//Swap balance
balance c = NodeTraits::get_balance(node1);
NodeTraits::set_balance(node1, NodeTraits::get_balance(node2));
NodeTraits::set_balance(node2, c);
}
//! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(node_ptr,node_ptr)
static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node) BOOST_NOEXCEPT
{
if(node_to_be_replaced == new_node)
return;
replace_node(node_to_be_replaced, bstree_algo::get_header(node_to_be_replaced), new_node);
}
//! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(node_ptr,node_ptr,node_ptr)
static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node) BOOST_NOEXCEPT
{
bstree_algo::replace_node(node_to_be_replaced, header, new_node);
NodeTraits::set_balance(new_node, NodeTraits::get_balance(node_to_be_replaced));
}
//! @copydoc ::boost::intrusive::bstree_algorithms::unlink(node_ptr)
static void unlink(node_ptr node) BOOST_NOEXCEPT
{
node_ptr x = NodeTraits::get_parent(node);
if(x){
while(!is_header(x))
x = NodeTraits::get_parent(x);
erase(x, node);
}
}
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree_algorithms::unlink_leftmost_without_rebalance
static node_ptr unlink_leftmost_without_rebalance(node_ptr header) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::unique(const_node_ptr)
static bool unique(const_node_ptr node) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::size(const_node_ptr)
static std::size_t size(const_node_ptr header) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::next_node(node_ptr)
static node_ptr next_node(node_ptr node) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::prev_node(node_ptr)
static node_ptr prev_node(node_ptr node) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::init(node_ptr)
static void init(node_ptr node) BOOST_NOEXCEPT;
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! <b>Requires</b>: node must not be part of any tree.
//!
//! <b>Effects</b>: Initializes the header to represent an empty tree.
//! unique(header) == true.
//!
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Nodes</b>: If node is inserted in a tree, this function corrupts the tree.
static void init_header(node_ptr header) BOOST_NOEXCEPT
{
bstree_algo::init_header(header);
NodeTraits::set_balance(header, NodeTraits::zero());
}
//! @copydoc ::boost::intrusive::bstree_algorithms::erase(node_ptr,node_ptr)
static node_ptr erase(node_ptr header, node_ptr z) BOOST_NOEXCEPT
{
typename bstree_algo::data_for_rebalance info;
bstree_algo::erase(header, z, info);
rebalance_after_erasure(header, z, info);
return z;
}
//! @copydoc ::boost::intrusive::bstree_algorithms::transfer_unique
template<class NodePtrCompare>
static bool transfer_unique
(node_ptr header1, NodePtrCompare comp, node_ptr header2, node_ptr z)
{
typename bstree_algo::data_for_rebalance info;
bool const transferred = bstree_algo::transfer_unique(header1, comp, header2, z, info);
if(transferred){
rebalance_after_erasure(header2, z, info);
rebalance_after_insertion(header1, z);
}
return transferred;
}
//! @copydoc ::boost::intrusive::bstree_algorithms::transfer_equal
template<class NodePtrCompare>
static void transfer_equal
(node_ptr header1, NodePtrCompare comp, node_ptr header2, node_ptr z)
{
typename bstree_algo::data_for_rebalance info;
bstree_algo::transfer_equal(header1, comp, header2, z, info);
rebalance_after_erasure(header2, z, info);
rebalance_after_insertion(header1, z);
}
//! @copydoc ::boost::intrusive::bstree_algorithms::clone(const_node_ptr,node_ptr,Cloner,Disposer)
template <class Cloner, class Disposer>
static void clone
(const_node_ptr source_header, node_ptr target_header, Cloner cloner, Disposer disposer)
{
avltree_node_cloner<NodeTraits, Cloner> new_cloner(cloner);
bstree_algo::clone(source_header, target_header, new_cloner, disposer);
}
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree_algorithms::clear_and_dispose(node_ptr,Disposer)
template<class Disposer>
static void clear_and_dispose(node_ptr header, Disposer disposer) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const_node_ptr,const KeyType&,KeyNodePtrCompare)
template<class KeyType, class KeyNodePtrCompare>
static node_ptr lower_bound
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
//! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const_node_ptr,const KeyType&,KeyNodePtrCompare)
template<class KeyType, class KeyNodePtrCompare>
static node_ptr upper_bound
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
//! @copydoc ::boost::intrusive::bstree_algorithms::find(const_node_ptr,const KeyType&,KeyNodePtrCompare)
template<class KeyType, class KeyNodePtrCompare>
static node_ptr find
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
//! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const_node_ptr,const KeyType&,KeyNodePtrCompare)
template<class KeyType, class KeyNodePtrCompare>
static std::pair<node_ptr, node_ptr> equal_range
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
//! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const_node_ptr,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool)
template<class KeyType, class KeyNodePtrCompare>
static std::pair<node_ptr, node_ptr> bounded_range
(const_node_ptr header, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp
, bool left_closed, bool right_closed);
//! @copydoc ::boost::intrusive::bstree_algorithms::count(const_node_ptr,const KeyType&,KeyNodePtrCompare)
template<class KeyType, class KeyNodePtrCompare>
static std::size_t count(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_upper_bound(node_ptr,node_ptr,NodePtrCompare)
template<class NodePtrCompare>
static node_ptr insert_equal_upper_bound
(node_ptr h, node_ptr new_node, NodePtrCompare comp)
{
bstree_algo::insert_equal_upper_bound(h, new_node, comp);
rebalance_after_insertion(h, new_node);
return new_node;
}
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_lower_bound(node_ptr,node_ptr,NodePtrCompare)
template<class NodePtrCompare>
static node_ptr insert_equal_lower_bound
(node_ptr h, node_ptr new_node, NodePtrCompare comp)
{
bstree_algo::insert_equal_lower_bound(h, new_node, comp);
rebalance_after_insertion(h, new_node);
return new_node;
}
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal(node_ptr,node_ptr,node_ptr,NodePtrCompare)
template<class NodePtrCompare>
static node_ptr insert_equal
(node_ptr header, node_ptr hint, node_ptr new_node, NodePtrCompare comp)
{
bstree_algo::insert_equal(header, hint, new_node, comp);
rebalance_after_insertion(header, new_node);
return new_node;
}
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_before(node_ptr,node_ptr,node_ptr)
static node_ptr insert_before
(node_ptr header, node_ptr pos, node_ptr new_node) BOOST_NOEXCEPT
{
bstree_algo::insert_before(header, pos, new_node);
rebalance_after_insertion(header, new_node);
return new_node;
}
//! @copydoc ::boost::intrusive::bstree_algorithms::push_back(node_ptr,node_ptr)
static void push_back(node_ptr header, node_ptr new_node) BOOST_NOEXCEPT
{
bstree_algo::push_back(header, new_node);
rebalance_after_insertion(header, new_node);
}
//! @copydoc ::boost::intrusive::bstree_algorithms::push_front(node_ptr,node_ptr)
static void push_front(node_ptr header, node_ptr new_node) BOOST_NOEXCEPT
{
bstree_algo::push_front(header, new_node);
rebalance_after_insertion(header, new_node);
}
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const_node_ptr,const KeyType&,KeyNodePtrCompare,insert_commit_data&)
template<class KeyType, class KeyNodePtrCompare>
static std::pair<node_ptr, bool> insert_unique_check
(const_node_ptr header, const KeyType &key
,KeyNodePtrCompare comp, insert_commit_data &commit_data);
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const_node_ptr,node_ptr,const KeyType&,KeyNodePtrCompare,insert_commit_data&)
template<class KeyType, class KeyNodePtrCompare>
static std::pair<node_ptr, bool> insert_unique_check
(const_node_ptr header, node_ptr hint, const KeyType &key
,KeyNodePtrCompare comp, insert_commit_data &commit_data);
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_commit(node_ptr,node_ptr,const insert_commit_data &)
static void insert_unique_commit
(node_ptr header, node_ptr new_value, const insert_commit_data &commit_data) BOOST_NOEXCEPT
{
bstree_algo::insert_unique_commit(header, new_value, commit_data);
rebalance_after_insertion(header, new_value);
}
//! @copydoc ::boost::intrusive::bstree_algorithms::is_header
static bool is_header(const_node_ptr p) BOOST_NOEXCEPT
{ return NodeTraits::get_balance(p) == NodeTraits::zero() && bstree_algo::is_header(p); }
/// @cond
static bool verify(node_ptr header)
{
std::size_t height;
std::size_t count;
return verify_recursion(NodeTraits::get_parent(header), count, height);
}
private:
static bool verify_recursion(node_ptr n, std::size_t &count, std::size_t &height)
{
if (!n){
count = 0;
height = 0;
return true;
}
std::size_t leftcount, rightcount;
std::size_t leftheight, rightheight;
if(!verify_recursion(NodeTraits::get_left (n), leftcount, leftheight) ||
!verify_recursion(NodeTraits::get_right(n), rightcount, rightheight) ){
return false;
}
count = 1u + leftcount + rightcount;
height = 1u + (leftheight > rightheight ? leftheight : rightheight);
//If equal height, balance must be zero
if(rightheight == leftheight){
if(NodeTraits::get_balance(n) != NodeTraits::zero()){
BOOST_ASSERT(0);
return false;
}
}
//If right is taller than left, then the difference must be at least 1 and the balance positive
else if(rightheight > leftheight){
if(rightheight - leftheight > 1 ){
BOOST_ASSERT(0);
return false;
}
else if(NodeTraits::get_balance(n) != NodeTraits::positive()){
BOOST_ASSERT(0);
return false;
}
}
//If left is taller than right, then the difference must be at least 1 and the balance negative
else{
if(leftheight - rightheight > 1 ){
BOOST_ASSERT(0);
return false;
}
else if(NodeTraits::get_balance(n) != NodeTraits::negative()){
BOOST_ASSERT(0);
return false;
}
}
return true;
}
static void rebalance_after_erasure
( node_ptr header, node_ptr z, const typename bstree_algo::data_for_rebalance &info) BOOST_NOEXCEPT
{
if(info.y != z){
NodeTraits::set_balance(info.y, NodeTraits::get_balance(z));
}
//Rebalance avltree
rebalance_after_erasure_restore_invariants(header, info.x, info.x_parent);
}
static void rebalance_after_erasure_restore_invariants(node_ptr header, node_ptr x, node_ptr x_parent) BOOST_NOEXCEPT
{
for ( node_ptr root = NodeTraits::get_parent(header)
; x != root
; root = NodeTraits::get_parent(header), x_parent = NodeTraits::get_parent(x)) {
const balance x_parent_balance = NodeTraits::get_balance(x_parent);
//Don't cache x_is_leftchild or similar because x can be null and
//equal to both x_parent_left and x_parent_right
const node_ptr x_parent_left (NodeTraits::get_left(x_parent));
const node_ptr x_parent_right(NodeTraits::get_right(x_parent));
if(x_parent_balance == NodeTraits::zero()){
NodeTraits::set_balance( x_parent, x == x_parent_right ? NodeTraits::negative() : NodeTraits::positive() );
break; // the height didn't change, let's stop here
}
else if(x_parent_balance == NodeTraits::negative()){
if (x == x_parent_left) { ////x is left child or x and sibling are null
NodeTraits::set_balance(x_parent, NodeTraits::zero()); // balanced
x = x_parent;
}
else {
// x is right child (x_parent_left is the left child)
BOOST_INTRUSIVE_INVARIANT_ASSERT(x_parent_left);
if (NodeTraits::get_balance(x_parent_left) == NodeTraits::positive()) {
// x_parent_left MUST have a right child
BOOST_INTRUSIVE_INVARIANT_ASSERT(NodeTraits::get_right(x_parent_left));
x = avl_rotate_left_right(x_parent, x_parent_left, header);
}
else {
avl_rotate_right(x_parent, x_parent_left, header);
x = x_parent_left;
}
// if changed from negative to NodeTraits::positive(), no need to check above
if (NodeTraits::get_balance(x) == NodeTraits::positive()){
break;
}
}
}
else if(x_parent_balance == NodeTraits::positive()){
if (x == x_parent_right) { //x is right child or x and sibling are null
NodeTraits::set_balance(x_parent, NodeTraits::zero()); // balanced
x = x_parent;
}
else {
// x is left child (x_parent_right is the right child)
BOOST_INTRUSIVE_INVARIANT_ASSERT(x_parent_right);
if (NodeTraits::get_balance(x_parent_right) == NodeTraits::negative()) {
// x_parent_right MUST have then a left child
BOOST_INTRUSIVE_INVARIANT_ASSERT(NodeTraits::get_left(x_parent_right));
x = avl_rotate_right_left(x_parent, x_parent_right, header);
}
else {
avl_rotate_left(x_parent, x_parent_right, header);
x = x_parent_right;
}
// if changed from NodeTraits::positive() to negative, no need to check above
if (NodeTraits::get_balance(x) == NodeTraits::negative()){
break;
}
}
}
else{
BOOST_INTRUSIVE_INVARIANT_ASSERT(false); // never reached
}
}
}
static void rebalance_after_insertion(node_ptr header, node_ptr x) BOOST_NOEXCEPT
{
NodeTraits::set_balance(x, NodeTraits::zero());
// Rebalance.
for(node_ptr root = NodeTraits::get_parent(header); x != root; root = NodeTraits::get_parent(header)){
node_ptr const x_parent(NodeTraits::get_parent(x));
node_ptr const x_parent_left(NodeTraits::get_left(x_parent));
const balance x_parent_balance = NodeTraits::get_balance(x_parent);
const bool x_is_leftchild(x == x_parent_left);
if(x_parent_balance == NodeTraits::zero()){
// if x is left, parent will have parent->bal_factor = negative
// else, parent->bal_factor = NodeTraits::positive()
NodeTraits::set_balance( x_parent, x_is_leftchild ? NodeTraits::negative() : NodeTraits::positive() );
x = x_parent;
}
else if(x_parent_balance == NodeTraits::positive()){
// if x is a left child, parent->bal_factor = zero
if (x_is_leftchild)
NodeTraits::set_balance(x_parent, NodeTraits::zero());
else{ // x is a right child, needs rebalancing
if (NodeTraits::get_balance(x) == NodeTraits::negative())
avl_rotate_right_left(x_parent, x, header);
else
avl_rotate_left(x_parent, x, header);
}
break;
}
else if(x_parent_balance == NodeTraits::negative()){
// if x is a left child, needs rebalancing
if (x_is_leftchild) {
if (NodeTraits::get_balance(x) == NodeTraits::positive())
avl_rotate_left_right(x_parent, x, header);
else
avl_rotate_right(x_parent, x, header);
}
else
NodeTraits::set_balance(x_parent, NodeTraits::zero());
break;
}
else{
BOOST_INTRUSIVE_INVARIANT_ASSERT(false); // never reached
}
}
}
static void left_right_balancing(node_ptr a, node_ptr b, node_ptr c) BOOST_NOEXCEPT
{
// balancing...
const balance c_balance = NodeTraits::get_balance(c);
const balance zero_balance = NodeTraits::zero();
const balance posi_balance = NodeTraits::positive();
const balance nega_balance = NodeTraits::negative();
NodeTraits::set_balance(c, zero_balance);
if(c_balance == nega_balance){
NodeTraits::set_balance(a, posi_balance);
NodeTraits::set_balance(b, zero_balance);
}
else if(c_balance == zero_balance){
NodeTraits::set_balance(a, zero_balance);
NodeTraits::set_balance(b, zero_balance);
}
else if(c_balance == posi_balance){
NodeTraits::set_balance(a, zero_balance);
NodeTraits::set_balance(b, nega_balance);
}
else{
BOOST_INTRUSIVE_INVARIANT_ASSERT(false); // never reached
}
}
static node_ptr avl_rotate_left_right(const node_ptr a, const node_ptr a_oldleft, node_ptr hdr) BOOST_NOEXCEPT
{ // [note: 'a_oldleft' is 'b']
// | | //
// a(-2) c //
// / \ / \ //
// / \ ==> / \ //
// (pos)b [g] b a //
// / \ / \ / \ //
// [d] c [d] e f [g] //
// / \ //
// e f //
const node_ptr c = NodeTraits::get_right(a_oldleft);
bstree_algo::rotate_left_no_parent_fix(a_oldleft, c);
//No need to link c with a [NodeTraits::set_parent(c, a) + NodeTraits::set_left(a, c)]
//as c is not root and another rotation is coming
bstree_algo::rotate_right(a, c, NodeTraits::get_parent(a), hdr);
left_right_balancing(a, a_oldleft, c);
return c;
}
static node_ptr avl_rotate_right_left(const node_ptr a, const node_ptr a_oldright, node_ptr hdr) BOOST_NOEXCEPT
{ // [note: 'a_oldright' is 'b']
// | | //
// a(pos) c //
// / \ / \ //
// / \ / \ //
// [d] b(neg) ==> a b //
// / \ / \ / \ //
// c [g] [d] e f [g] //
// / \ //
// e f //
const node_ptr c (NodeTraits::get_left(a_oldright));
bstree_algo::rotate_right_no_parent_fix(a_oldright, c);
//No need to link c with a [NodeTraits::set_parent(c, a) + NodeTraits::set_right(a, c)]
//as c is not root and another rotation is coming.
bstree_algo::rotate_left(a, c, NodeTraits::get_parent(a), hdr);
left_right_balancing(a_oldright, a, c);
return c;
}
static void avl_rotate_left(node_ptr x, node_ptr x_oldright, node_ptr hdr) BOOST_NOEXCEPT
{
bstree_algo::rotate_left(x, x_oldright, NodeTraits::get_parent(x), hdr);
// reset the balancing factor
if (NodeTraits::get_balance(x_oldright) == NodeTraits::positive()) {
NodeTraits::set_balance(x, NodeTraits::zero());
NodeTraits::set_balance(x_oldright, NodeTraits::zero());
}
else { // this doesn't happen during insertions
NodeTraits::set_balance(x, NodeTraits::positive());
NodeTraits::set_balance(x_oldright, NodeTraits::negative());
}
}
static void avl_rotate_right(node_ptr x, node_ptr x_oldleft, node_ptr hdr) BOOST_NOEXCEPT
{
bstree_algo::rotate_right(x, x_oldleft, NodeTraits::get_parent(x), hdr);
// reset the balancing factor
if (NodeTraits::get_balance(x_oldleft) == NodeTraits::negative()) {
NodeTraits::set_balance(x, NodeTraits::zero());
NodeTraits::set_balance(x_oldleft, NodeTraits::zero());
}
else { // this doesn't happen during insertions
NodeTraits::set_balance(x, NodeTraits::negative());
NodeTraits::set_balance(x_oldleft, NodeTraits::positive());
}
}
/// @endcond
};
/// @cond
template<class NodeTraits>
struct get_algo<AvlTreeAlgorithms, NodeTraits>
{
typedef avltree_algorithms<NodeTraits> type;
};
template <class ValueTraits, class NodePtrCompare, class ExtraChecker>
struct get_node_checker<AvlTreeAlgorithms, ValueTraits, NodePtrCompare, ExtraChecker>
{
typedef detail::avltree_node_checker<ValueTraits, NodePtrCompare, ExtraChecker> type;
};
/// @endcond
} //namespace intrusive
} //namespace boost
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_AVLTREE_ALGORITHMS_HPP

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,288 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2013
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_BS_SET_HOOK_HPP
#define BOOST_INTRUSIVE_BS_SET_HOOK_HPP
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/intrusive/detail/tree_node.hpp>
#include <boost/intrusive/bstree_algorithms.hpp>
#include <boost/intrusive/options.hpp>
#include <boost/intrusive/detail/generic_hook.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
namespace boost {
namespace intrusive {
//! Helper metafunction to define a \c bs_set_base_hook that yields to the same
//! type when the same options (either explicitly or implicitly) are used.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class ...Options>
#else
template<class O1 = void, class O2 = void, class O3 = void>
#endif
struct make_bs_set_base_hook
{
/// @cond
typedef typename pack_options
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
< hook_defaults, O1, O2, O3>
#else
< hook_defaults, Options...>
#endif
::type packed_options;
typedef generic_hook
< BsTreeAlgorithms
, tree_node_traits<typename packed_options::void_pointer>
, typename packed_options::tag
, packed_options::link_mode
, BsTreeBaseHookId
> implementation_defined;
/// @endcond
typedef implementation_defined type;
};
//! Derive a class from bs_set_base_hook in order to store objects in
//! in a bs_set/bs_multiset. bs_set_base_hook holds the data necessary to maintain
//! the bs_set/bs_multiset and provides an appropriate value_traits class for bs_set/bs_multiset.
//!
//! The hook admits the following options: \c tag<>, \c void_pointer<>,
//! \c link_mode<>.
//!
//! \c tag<> defines a tag to identify the node.
//! The same tag value can be used in different classes, but if a class is
//! derived from more than one \c list_base_hook, then each \c list_base_hook needs its
//! unique tag.
//!
//! \c void_pointer<> is the pointer type that will be used internally in the hook
//! and the container configured to use this hook.
//!
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
//! \c auto_unlink or \c safe_link).
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class ...Options>
#else
template<class O1, class O2, class O3>
#endif
class bs_set_base_hook
: public make_bs_set_base_hook
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
<O1, O2, O3>
#else
<Options...>
#endif
::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.
//!
//! <b>Throws</b>: Nothing.
bs_set_base_hook();
//! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state. The argument is ignored.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Rationale</b>: Providing a copy-constructor
//! makes classes using the hook STL-compliant without forcing the
//! user to do some additional work. \c swap can be used to emulate
//! move-semantics.
bs_set_base_hook(const bs_set_base_hook& );
//! <b>Effects</b>: Empty function. The argument is ignored.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Rationale</b>: Providing an assignment operator
//! makes classes using the hook STL-compliant without forcing the
//! user to do some additional work. \c swap can be used to emulate
//! move-semantics.
bs_set_base_hook& operator=(const bs_set_base_hook& );
//! <b>Effects</b>: If link_mode is \c normal_link, the destructor does
//! nothing (ie. no code is generated). If link_mode is \c safe_link and the
//! object is stored in a set an assertion is raised. If link_mode is
//! \c auto_unlink and \c is_linked() is true, the node is unlinked.
//!
//! <b>Throws</b>: Nothing.
~bs_set_base_hook();
//! <b>Effects</b>: Swapping two nodes swaps the position of the elements
//! related to those nodes in one or two containers. That is, if the node
//! this is part of the element e1, the node x is part of the element e2
//! and both elements are included in the containers s1 and s2, then after
//! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1
//! at the position of e1. If one element is not in a container, then
//! after the swap-operation the other element is not in a container.
//! Iterators to e1 and e2 related to those nodes are invalidated.
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
void swap_nodes(bs_set_base_hook &other);
//! <b>Precondition</b>: link_mode must be \c safe_link or \c auto_unlink.
//!
//! <b>Returns</b>: true, if the node belongs to a container, false
//! otherwise. This function can be used to test whether \c set::iterator_to
//! will return a valid iterator.
//!
//! <b>Complexity</b>: Constant
bool is_linked() const;
//! <b>Effects</b>: Removes the node if it's inserted in a container.
//! This function is only allowed if link_mode is \c auto_unlink.
//!
//! <b>Throws</b>: Nothing.
void unlink();
#endif
};
//! Helper metafunction to define a \c bs_set_member_hook that yields to the same
//! type when the same options (either explicitly or implicitly) are used.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class ...Options>
#else
template<class O1 = void, class O2 = void, class O3 = void>
#endif
struct make_bs_set_member_hook
{
/// @cond
typedef typename pack_options
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
< hook_defaults, O1, O2, O3>
#else
< hook_defaults, Options...>
#endif
::type packed_options;
typedef generic_hook
< BsTreeAlgorithms
, tree_node_traits<typename packed_options::void_pointer>
, member_tag
, packed_options::link_mode
, NoBaseHookId
> implementation_defined;
/// @endcond
typedef implementation_defined type;
};
//! Put a public data member bs_set_member_hook in order to store objects of this class in
//! a bs_set/bs_multiset. bs_set_member_hook holds the data necessary for maintaining the
//! bs_set/bs_multiset and provides an appropriate value_traits class for bs_set/bs_multiset.
//!
//! The hook admits the following options: \c void_pointer<>, \c link_mode<>.
//!
//! \c void_pointer<> is the pointer type that will be used internally in the hook
//! and the container configured to use this hook.
//!
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
//! \c auto_unlink or \c safe_link).
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class ...Options>
#else
template<class O1, class O2, class O3>
#endif
class bs_set_member_hook
: public make_bs_set_member_hook
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
<O1, O2, O3>
#else
<Options...>
#endif
::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.
//!
//! <b>Throws</b>: Nothing.
bs_set_member_hook();
//! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state. The argument is ignored.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Rationale</b>: Providing a copy-constructor
//! makes classes using the hook STL-compliant without forcing the
//! user to do some additional work. \c swap can be used to emulate
//! move-semantics.
bs_set_member_hook(const bs_set_member_hook& );
//! <b>Effects</b>: Empty function. The argument is ignored.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Rationale</b>: Providing an assignment operator
//! makes classes using the hook STL-compliant without forcing the
//! user to do some additional work. \c swap can be used to emulate
//! move-semantics.
bs_set_member_hook& operator=(const bs_set_member_hook& );
//! <b>Effects</b>: If link_mode is \c normal_link, the destructor does
//! nothing (ie. no code is generated). If link_mode is \c safe_link and the
//! object is stored in a set an assertion is raised. If link_mode is
//! \c auto_unlink and \c is_linked() is true, the node is unlinked.
//!
//! <b>Throws</b>: Nothing.
~bs_set_member_hook();
//! <b>Effects</b>: Swapping two nodes swaps the position of the elements
//! related to those nodes in one or two containers. That is, if the node
//! this is part of the element e1, the node x is part of the element e2
//! and both elements are included in the containers s1 and s2, then after
//! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1
//! at the position of e1. If one element is not in a container, then
//! after the swap-operation the other element is not in a container.
//! Iterators to e1 and e2 related to those nodes are invalidated.
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
void swap_nodes(bs_set_member_hook &other);
//! <b>Precondition</b>: link_mode must be \c safe_link or \c auto_unlink.
//!
//! <b>Returns</b>: true, if the node belongs to a container, false
//! otherwise. This function can be used to test whether \c set::iterator_to
//! will return a valid iterator.
//!
//! <b>Complexity</b>: Constant
bool is_linked() const;
//! <b>Effects</b>: Removes the node if it's inserted in a container.
//! This function is only allowed if link_mode is \c auto_unlink.
//!
//! <b>Throws</b>: Nothing.
void unlink();
#endif
};
} //namespace intrusive
} //namespace boost
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_BS_SET_HOOK_HPP

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,466 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
// (C) Copyright Ion Gaztanaga 2006-2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_CIRCULAR_LIST_ALGORITHMS_HPP
#define BOOST_INTRUSIVE_CIRCULAR_LIST_ALGORITHMS_HPP
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/intrusive/detail/algo_type.hpp>
#include <boost/core/no_exceptions_support.hpp>
#include <cstddef>
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
namespace boost {
namespace intrusive {
//! circular_list_algorithms provides basic algorithms to manipulate nodes
//! forming a circular doubly linked list. An empty circular list is formed by a node
//! whose pointers point to itself.
//!
//! circular_list_algorithms is configured with a NodeTraits class, which encapsulates the
//! information about the node to be manipulated. NodeTraits must support the
//! following interface:
//!
//! <b>Typedefs</b>:
//!
//! <tt>node</tt>: The type of the node that forms the circular list
//!
//! <tt>node_ptr</tt>: A pointer to a node
//!
//! <tt>const_node_ptr</tt>: A pointer to a const node
//!
//! <b>Static functions</b>:
//!
//! <tt>static node_ptr get_previous(const_node_ptr n);</tt>
//!
//! <tt>static void set_previous(node_ptr n, node_ptr prev);</tt>
//!
//! <tt>static node_ptr get_next(const_node_ptr n);</tt>
//!
//! <tt>static void set_next(node_ptr n, node_ptr next);</tt>
template<class NodeTraits>
class circular_list_algorithms
{
public:
typedef typename NodeTraits::node node;
typedef typename NodeTraits::node_ptr node_ptr;
typedef typename NodeTraits::const_node_ptr const_node_ptr;
typedef NodeTraits node_traits;
//! <b>Effects</b>: Constructs an non-used list element, so that
//! inited(this_node) == true
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static void init(node_ptr this_node) BOOST_NOEXCEPT
{
const node_ptr null_node = node_ptr();
NodeTraits::set_next(this_node, null_node);
NodeTraits::set_previous(this_node, null_node);
}
//! <b>Effects</b>: Returns true is "this_node" is in a non-used state
//! as if it was initialized by the "init" function.
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
BOOST_INTRUSIVE_FORCEINLINE static bool inited(const_node_ptr this_node) BOOST_NOEXCEPT
{ return !NodeTraits::get_next(this_node); }
//! <b>Effects</b>: Constructs an empty list, making this_node the only
//! node of the circular list:
//! <tt>NodeTraits::get_next(this_node) == NodeTraits::get_previous(this_node)
//! == this_node</tt>.
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static void init_header(node_ptr this_node) BOOST_NOEXCEPT
{
NodeTraits::set_next(this_node, this_node);
NodeTraits::set_previous(this_node, this_node);
}
//! <b>Requires</b>: this_node must be in a circular list or be an empty circular list.
//!
//! <b>Effects</b>: Returns true is "this_node" is the only node of a circular list:
//! <tt>return NodeTraits::get_next(this_node) == this_node</tt>
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static bool unique(const_node_ptr this_node) BOOST_NOEXCEPT
{
node_ptr next = NodeTraits::get_next(this_node);
return !next || next == this_node;
}
//! <b>Requires</b>: this_node must be in a circular list or be an empty circular list.
//!
//! <b>Effects</b>: Returns the number of nodes in a circular list. If the circular list
//! is empty, returns 1.
//!
//! <b>Complexity</b>: Linear
//!
//! <b>Throws</b>: Nothing.
static std::size_t count(const_node_ptr this_node) BOOST_NOEXCEPT
{
std::size_t result = 0;
const_node_ptr p = this_node;
do{
p = NodeTraits::get_next(p);
++result;
}while (p != this_node);
return result;
}
//! <b>Requires</b>: this_node must be in a circular list or be an empty circular list.
//!
//! <b>Effects</b>: Unlinks the node from the circular list.
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static node_ptr unlink(node_ptr this_node) BOOST_NOEXCEPT
{
node_ptr next(NodeTraits::get_next(this_node));
node_ptr prev(NodeTraits::get_previous(this_node));
NodeTraits::set_next(prev, next);
NodeTraits::set_previous(next, prev);
return next;
}
//! <b>Requires</b>: b and e must be nodes of the same circular list or an empty range.
//!
//! <b>Effects</b>: Unlinks the node [b, e) from the circular list.
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static void unlink(node_ptr b, node_ptr e) BOOST_NOEXCEPT
{
if (b != e) {
node_ptr prevb(NodeTraits::get_previous(b));
NodeTraits::set_previous(e, prevb);
NodeTraits::set_next(prevb, e);
}
}
//! <b>Requires</b>: nxt_node must be a node of a circular list.
//!
//! <b>Effects</b>: Links this_node before nxt_node in the circular list.
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static void link_before(node_ptr nxt_node, node_ptr this_node) BOOST_NOEXCEPT
{
node_ptr prev(NodeTraits::get_previous(nxt_node));
NodeTraits::set_previous(this_node, prev);
NodeTraits::set_next(this_node, nxt_node);
//nxt_node might be an alias for prev->next_
//so use it before NodeTraits::set_next(prev, ...)
//is called and the reference changes its value
NodeTraits::set_previous(nxt_node, this_node);
NodeTraits::set_next(prev, this_node);
}
//! <b>Requires</b>: prev_node must be a node of a circular list.
//!
//! <b>Effects</b>: Links this_node after prev_node in the circular list.
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static void link_after(node_ptr prev_node, node_ptr this_node) BOOST_NOEXCEPT
{
node_ptr next(NodeTraits::get_next(prev_node));
NodeTraits::set_previous(this_node, prev_node);
NodeTraits::set_next(this_node, next);
//prev_node might be an alias for next->next_
//so use it before update it before NodeTraits::set_previous(next, ...)
//is called and the reference changes it's value
NodeTraits::set_next(prev_node, this_node);
NodeTraits::set_previous(next, this_node);
}
//! <b>Requires</b>: this_node and other_node must be nodes inserted
//! in circular lists or be empty circular lists.
//!
//! <b>Effects</b>: Swaps the position of the nodes: this_node is inserted in
//! other_nodes position in the second circular list and the other_node is inserted
//! in this_node's position in the first circular list.
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static void swap_nodes(node_ptr this_node, node_ptr other_node) BOOST_NOEXCEPT
{
if (other_node == this_node)
return;
bool this_inited = inited(this_node);
bool other_inited = inited(other_node);
if(this_inited){
init_header(this_node);
}
if(other_inited){
init_header(other_node);
}
node_ptr next_this(NodeTraits::get_next(this_node));
node_ptr prev_this(NodeTraits::get_previous(this_node));
node_ptr next_other(NodeTraits::get_next(other_node));
node_ptr prev_other(NodeTraits::get_previous(other_node));
//these first two swaps must happen before the other two
swap_prev(next_this, next_other);
swap_next(prev_this, prev_other);
swap_next(this_node, other_node);
swap_prev(this_node, other_node);
if(this_inited){
init(other_node);
}
if(other_inited){
init(this_node);
}
}
//! <b>Requires</b>: b and e must be nodes of the same circular list or an empty range.
//! and p must be a node of a different circular list or may not be an iterator in
// [b, e).
//!
//! <b>Effects</b>: Removes the nodes from [b, e) range from their circular list and inserts
//! them before p in p's circular list.
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static void transfer(node_ptr p, node_ptr b, node_ptr e) BOOST_NOEXCEPT
{
if (b != e && p != b && p != e) {
node_ptr prev_p(NodeTraits::get_previous(p));
node_ptr prev_b(NodeTraits::get_previous(b));
node_ptr prev_e(NodeTraits::get_previous(e));
NodeTraits::set_next(prev_e, p);
NodeTraits::set_previous(p, prev_e);
NodeTraits::set_next(prev_b, e);
NodeTraits::set_previous(e, prev_b);
NodeTraits::set_next(prev_p, b);
NodeTraits::set_previous(b, prev_p);
}
}
//! <b>Requires</b>: i must a node of a circular list
//! and p must be a node of a different circular list.
//!
//! <b>Effects</b>: Removes the node i from its circular list and inserts
//! it before p in p's circular list.
//! If p == i or p == NodeTraits::get_next(i), this function is a null operation.
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static void transfer(node_ptr p, node_ptr i) BOOST_NOEXCEPT
{
node_ptr n(NodeTraits::get_next(i));
if(n != p && i != p){
node_ptr prev_p(NodeTraits::get_previous(p));
node_ptr prev_i(NodeTraits::get_previous(i));
NodeTraits::set_next(prev_p, i);
NodeTraits::set_previous(i, prev_p);
NodeTraits::set_next(i, p);
NodeTraits::set_previous(p, i);
NodeTraits::set_previous(n, prev_i);
NodeTraits::set_next(prev_i, n);
}
}
//! <b>Effects</b>: Reverses the order of elements in the list.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: This function is linear time.
static void reverse(node_ptr p) BOOST_NOEXCEPT
{
node_ptr f(NodeTraits::get_next(p));
node_ptr i(NodeTraits::get_next(f)), e(p);
while(i != e) {
node_ptr n = i;
i = NodeTraits::get_next(i);
transfer(f, n, i);
f = n;
}
}
//! <b>Effects</b>: Moves the node p n positions towards the end of the list.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear to the number of moved positions.
static void move_backwards(node_ptr p, std::size_t n) BOOST_NOEXCEPT
{
//Null shift, nothing to do
if(!n) return;
node_ptr first = NodeTraits::get_next(p);
//size() == 0 or 1, nothing to do
if(first == NodeTraits::get_previous(p)) return;
unlink(p);
//Now get the new first node
while(n--){
first = NodeTraits::get_next(first);
}
link_before(first, p);
}
//! <b>Effects</b>: Moves the node p n positions towards the beginning of the list.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear to the number of moved positions.
static void move_forward(node_ptr p, std::size_t n) BOOST_NOEXCEPT
{
//Null shift, nothing to do
if(!n) return;
node_ptr last = NodeTraits::get_previous(p);
//size() == 0 or 1, nothing to do
if(last == NodeTraits::get_next(p)) return;
unlink(p);
//Now get the new last node
while(n--){
last = NodeTraits::get_previous(last);
}
link_after(last, p);
}
//! <b>Requires</b>: f and l must be in a circular list.
//!
//! <b>Effects</b>: Returns the number of nodes in the range [f, l).
//!
//! <b>Complexity</b>: Linear
//!
//! <b>Throws</b>: Nothing.
static std::size_t distance(const_node_ptr f, const_node_ptr l) BOOST_NOEXCEPT
{
std::size_t result = 0;
while(f != l){
f = NodeTraits::get_next(f);
++result;
}
return result;
}
struct stable_partition_info
{
std::size_t num_1st_partition;
std::size_t num_2nd_partition;
node_ptr beg_2st_partition;
};
template<class Pred>
static void stable_partition(node_ptr beg, node_ptr end, Pred pred, stable_partition_info &info)
{
node_ptr bcur = node_traits::get_previous(beg);
node_ptr cur = beg;
node_ptr new_f = end;
std::size_t num1 = 0, num2 = 0;
while(cur != end){
if(pred(cur)){
++num1;
bcur = cur;
cur = node_traits::get_next(cur);
}
else{
++num2;
node_ptr last_to_remove = bcur;
new_f = cur;
bcur = cur;
cur = node_traits::get_next(cur);
BOOST_TRY{
//Main loop
while(cur != end){
if(pred(cur)){ //Might throw
++num1;
//Process current node
node_traits::set_next (last_to_remove, cur);
node_traits::set_previous(cur, last_to_remove);
last_to_remove = cur;
node_ptr nxt = node_traits::get_next(cur);
node_traits::set_next (bcur, nxt);
node_traits::set_previous(nxt, bcur);
cur = nxt;
}
else{
++num2;
bcur = cur;
cur = node_traits::get_next(cur);
}
}
}
BOOST_CATCH(...){
node_traits::set_next (last_to_remove, new_f);
node_traits::set_previous(new_f, last_to_remove);
BOOST_RETHROW;
}
BOOST_CATCH_END
node_traits::set_next(last_to_remove, new_f);
node_traits::set_previous(new_f, last_to_remove);
break;
}
}
info.num_1st_partition = num1;
info.num_2nd_partition = num2;
info.beg_2st_partition = new_f;
}
private:
static void swap_prev(node_ptr this_node, node_ptr other_node) BOOST_NOEXCEPT
{
node_ptr temp(NodeTraits::get_previous(this_node));
NodeTraits::set_previous(this_node, NodeTraits::get_previous(other_node));
NodeTraits::set_previous(other_node, temp);
}
static void swap_next(node_ptr this_node, node_ptr other_node) BOOST_NOEXCEPT
{
node_ptr temp(NodeTraits::get_next(this_node));
NodeTraits::set_next(this_node, NodeTraits::get_next(other_node));
NodeTraits::set_next(other_node, temp);
}
};
/// @cond
template<class NodeTraits>
struct get_algo<CircularListAlgorithms, NodeTraits>
{
typedef circular_list_algorithms<NodeTraits> type;
};
/// @endcond
} //namespace intrusive
} //namespace boost
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_CIRCULAR_LIST_ALGORITHMS_HPP

View File

@@ -0,0 +1,406 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
// (C) Copyright Ion Gaztanaga 2006-2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_CIRCULAR_SLIST_ALGORITHMS_HPP
#define BOOST_INTRUSIVE_CIRCULAR_SLIST_ALGORITHMS_HPP
#include <cstddef>
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/intrusive/detail/common_slist_algorithms.hpp>
#include <boost/intrusive/detail/algo_type.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
namespace boost {
namespace intrusive {
//! circular_slist_algorithms provides basic algorithms to manipulate nodes
//! forming a circular singly linked list. An empty circular list is formed by a node
//! whose pointer to the next node points to itself.
//!
//! circular_slist_algorithms is configured with a NodeTraits class, which encapsulates the
//! information about the node to be manipulated. NodeTraits must support the
//! following interface:
//!
//! <b>Typedefs</b>:
//!
//! <tt>node</tt>: The type of the node that forms the circular list
//!
//! <tt>node_ptr</tt>: A pointer to a node
//!
//! <tt>const_node_ptr</tt>: A pointer to a const node
//!
//! <b>Static functions</b>:
//!
//! <tt>static node_ptr get_next(const_node_ptr n);</tt>
//!
//! <tt>static void set_next(node_ptr n, node_ptr next);</tt>
template<class NodeTraits>
class circular_slist_algorithms
/// @cond
: public detail::common_slist_algorithms<NodeTraits>
/// @endcond
{
/// @cond
typedef detail::common_slist_algorithms<NodeTraits> base_t;
/// @endcond
public:
typedef typename NodeTraits::node node;
typedef typename NodeTraits::node_ptr node_ptr;
typedef typename NodeTraits::const_node_ptr const_node_ptr;
typedef NodeTraits node_traits;
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
//! <b>Effects</b>: Constructs an non-used list element, putting the next
//! pointer to null:
//! <tt>NodeTraits::get_next(this_node) == node_ptr()</tt>
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static void init(node_ptr this_node) BOOST_NOEXCEPT;
//! <b>Requires</b>: this_node must be in a circular list or be an empty circular list.
//!
//! <b>Effects</b>: Returns true is "this_node" is the only node of a circular list:
//! or it's a not inserted node:
//! <tt>return node_ptr() == NodeTraits::get_next(this_node) || NodeTraits::get_next(this_node) == this_node</tt>
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static bool unique(const_node_ptr this_node) BOOST_NOEXCEPT;
//! <b>Effects</b>: Returns true is "this_node" has the same state as
//! if it was inited using "init(node_ptr)"
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static bool inited(const_node_ptr this_node) BOOST_NOEXCEPT;
//! <b>Requires</b>: prev_node must be in a circular list or be an empty circular list.
//!
//! <b>Effects</b>: Unlinks the next node of prev_node from the circular list.
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static void unlink_after(node_ptr prev_node) BOOST_NOEXCEPT;
//! <b>Requires</b>: prev_node and last_node must be in a circular list
//! or be an empty circular list.
//!
//! <b>Effects</b>: Unlinks the range (prev_node, last_node) from the circular list.
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static void unlink_after(node_ptr prev_node, node_ptr last_node) BOOST_NOEXCEPT;
//! <b>Requires</b>: prev_node must be a node of a circular list.
//!
//! <b>Effects</b>: Links this_node after prev_node in the circular list.
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static void link_after(node_ptr prev_node, node_ptr this_node) BOOST_NOEXCEPT;
//! <b>Requires</b>: b and e must be nodes of the same circular list or an empty range.
//! and p must be a node of a different circular list.
//!
//! <b>Effects</b>: Removes the nodes from (b, e] range from their circular list and inserts
//! them after p in p's circular list.
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static void transfer_after(node_ptr p, node_ptr b, node_ptr e) BOOST_NOEXCEPT;
#endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
//! <b>Effects</b>: Constructs an empty list, making this_node the only
//! node of the circular list:
//! <tt>NodeTraits::get_next(this_node) == this_node</tt>.
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
BOOST_INTRUSIVE_FORCEINLINE static void init_header(node_ptr this_node) BOOST_NOEXCEPT
{ NodeTraits::set_next(this_node, this_node); }
//! <b>Requires</b>: this_node and prev_init_node must be in the same circular list.
//!
//! <b>Effects</b>: Returns the previous node of this_node in the circular list starting.
//! the search from prev_init_node. The first node checked for equality
//! is NodeTraits::get_next(prev_init_node).
//!
//! <b>Complexity</b>: Linear to the number of elements between prev_init_node and this_node.
//!
//! <b>Throws</b>: Nothing.
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_previous_node(node_ptr prev_init_node, node_ptr this_node) BOOST_NOEXCEPT
{ return base_t::get_previous_node(prev_init_node, this_node); }
//! <b>Requires</b>: this_node must be in a circular list or be an empty circular list.
//!
//! <b>Effects</b>: Returns the previous node of this_node in the circular list.
//!
//! <b>Complexity</b>: Linear to the number of elements in the circular list.
//!
//! <b>Throws</b>: Nothing.
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_previous_node(node_ptr this_node) BOOST_NOEXCEPT
{ return base_t::get_previous_node(this_node, this_node); }
//! <b>Requires</b>: this_node must be in a circular list or be an empty circular list.
//!
//! <b>Effects</b>: Returns the previous node of the previous node of this_node in the circular list.
//!
//! <b>Complexity</b>: Linear to the number of elements in the circular list.
//!
//! <b>Throws</b>: Nothing.
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_previous_previous_node(node_ptr this_node) BOOST_NOEXCEPT
{ return get_previous_previous_node(this_node, this_node); }
//! <b>Requires</b>: this_node and p must be in the same circular list.
//!
//! <b>Effects</b>: Returns the previous node of the previous node of this_node in the
//! circular list starting. the search from p. The first node checked
//! for equality is NodeTraits::get_next((NodeTraits::get_next(p)).
//!
//! <b>Complexity</b>: Linear to the number of elements in the circular list.
//!
//! <b>Throws</b>: Nothing.
static node_ptr get_previous_previous_node(node_ptr p, node_ptr this_node) BOOST_NOEXCEPT
{
node_ptr p_next = NodeTraits::get_next(p);
node_ptr p_next_next = NodeTraits::get_next(p_next);
while (this_node != p_next_next){
p = p_next;
p_next = p_next_next;
p_next_next = NodeTraits::get_next(p_next);
}
return p;
}
//! <b>Requires</b>: this_node must be in a circular list or be an empty circular list.
//!
//! <b>Effects</b>: Returns the number of nodes in a circular list. If the circular list
//! is empty, returns 1.
//!
//! <b>Complexity</b>: Linear
//!
//! <b>Throws</b>: Nothing.
static std::size_t count(const_node_ptr this_node) BOOST_NOEXCEPT
{
std::size_t result = 0;
const_node_ptr p = this_node;
do{
p = NodeTraits::get_next(p);
++result;
} while (p != this_node);
return result;
}
//! <b>Requires</b>: this_node must be in a circular list, be an empty circular list or be inited.
//!
//! <b>Effects</b>: Unlinks the node from the circular list.
//!
//! <b>Complexity</b>: Linear to the number of elements in the circular list
//!
//! <b>Throws</b>: Nothing.
static void unlink(node_ptr this_node) BOOST_NOEXCEPT
{
if(NodeTraits::get_next(this_node))
base_t::unlink_after(get_previous_node(this_node));
}
//! <b>Requires</b>: nxt_node must be a node of a circular list.
//!
//! <b>Effects</b>: Links this_node before nxt_node in the circular list.
//!
//! <b>Complexity</b>: Linear to the number of elements in the circular list.
//!
//! <b>Throws</b>: Nothing.
BOOST_INTRUSIVE_FORCEINLINE static void link_before (node_ptr nxt_node, node_ptr this_node) BOOST_NOEXCEPT
{ base_t::link_after(get_previous_node(nxt_node), this_node); }
//! <b>Requires</b>: this_node and other_node must be nodes inserted
//! in circular lists or be empty circular lists.
//!
//! <b>Effects</b>: Swaps the position of the nodes: this_node is inserted in
//! other_nodes position in the second circular list and the other_node is inserted
//! in this_node's position in the first circular list.
//!
//! <b>Complexity</b>: Linear to number of elements of both lists
//!
//! <b>Throws</b>: Nothing.
static void swap_nodes(node_ptr this_node, node_ptr other_node) BOOST_NOEXCEPT
{
if (other_node == this_node)
return;
const node_ptr this_next = NodeTraits::get_next(this_node);
const node_ptr other_next = NodeTraits::get_next(other_node);
const bool this_null = !this_next;
const bool other_null = !other_next;
const bool this_empty = this_next == this_node;
const bool other_empty = other_next == other_node;
if(!(other_null || other_empty)){
NodeTraits::set_next(this_next == other_node ? other_node : get_previous_node(other_node), this_node );
}
if(!(this_null | this_empty)){
NodeTraits::set_next(other_next == this_node ? this_node : get_previous_node(this_node), other_node );
}
NodeTraits::set_next(this_node, other_empty ? this_node : (other_next == this_node ? other_node : other_next) );
NodeTraits::set_next(other_node, this_empty ? other_node : (this_next == other_node ? this_node : this_next ) );
}
//! <b>Effects</b>: Reverses the order of elements in the list.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: This function is linear to the contained elements.
static void reverse(node_ptr p) BOOST_NOEXCEPT
{
node_ptr i = NodeTraits::get_next(p), e(p);
for (;;) {
node_ptr nxt(NodeTraits::get_next(i));
if (nxt == e)
break;
base_t::transfer_after(e, i, nxt);
}
}
//! <b>Effects</b>: Moves the node p n positions towards the end of the list.
//!
//! <b>Returns</b>: The previous node of p after the function if there has been any movement,
//! Null if n leads to no movement.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear to the number of elements plus the number moved positions.
static node_ptr move_backwards(node_ptr p, std::size_t n) BOOST_NOEXCEPT
{
//Null shift, nothing to do
if(!n) return node_ptr();
node_ptr first = NodeTraits::get_next(p);
//count() == 1 or 2, nothing to do
if(NodeTraits::get_next(first) == p)
return node_ptr();
bool end_found = false;
node_ptr new_last = node_ptr();
//Now find the new last node according to the shift count.
//If we find p before finding the new last node
//unlink p, shortcut the search now that we know the size of the list
//and continue.
for(std::size_t i = 1; i <= n; ++i){
new_last = first;
first = NodeTraits::get_next(first);
if(first == p){
//Shortcut the shift with the modulo of the size of the list
n %= i;
if(!n)
return node_ptr();
i = 0;
//Unlink p and continue the new first node search
first = NodeTraits::get_next(p);
base_t::unlink_after(new_last);
end_found = true;
}
}
//If the p has not been found in the previous loop, find it
//starting in the new first node and unlink it
if(!end_found){
base_t::unlink_after(base_t::get_previous_node(first, p));
}
//Now link p after the new last node
base_t::link_after(new_last, p);
return new_last;
}
//! <b>Effects</b>: Moves the node p n positions towards the beginning of the list.
//!
//! <b>Returns</b>: The previous node of p after the function if there has been any movement,
//! Null if n leads equals to no movement.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear to the number of elements plus the number moved positions.
static node_ptr move_forward(node_ptr p, std::size_t n) BOOST_NOEXCEPT
{
//Null shift, nothing to do
if(!n) return node_ptr();
node_ptr first = node_traits::get_next(p);
//count() == 1 or 2, nothing to do
if(node_traits::get_next(first) == p) return node_ptr();
//Iterate until p is found to know where the current last node is.
//If the shift count is less than the size of the list, we can also obtain
//the position of the new last node after the shift.
node_ptr old_last(first), next_to_it, new_last(p);
std::size_t distance = 1;
while(p != (next_to_it = node_traits::get_next(old_last))){
if(++distance > n)
new_last = node_traits::get_next(new_last);
old_last = next_to_it;
}
//If the shift was bigger or equal than the size, obtain the equivalent
//forward shifts and find the new last node.
if(distance <= n){
//Now find the equivalent forward shifts.
//Shortcut the shift with the modulo of the size of the list
std::size_t new_before_last_pos = (distance - (n % distance))% distance;
//If the shift is a multiple of the size there is nothing to do
if(!new_before_last_pos) return node_ptr();
for( new_last = p
; new_before_last_pos--
; new_last = node_traits::get_next(new_last)){
//empty
}
}
//Now unlink p and link it after the new last node
base_t::unlink_after(old_last);
base_t::link_after(new_last, p);
return new_last;
}
};
/// @cond
template<class NodeTraits>
struct get_algo<CircularSListAlgorithms, NodeTraits>
{
typedef circular_slist_algorithms<NodeTraits> type;
};
/// @endcond
} //namespace intrusive
} //namespace boost
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_CIRCULAR_SLIST_ALGORITHMS_HPP

View File

@@ -0,0 +1,77 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2013
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DERIVATION_VALUE_TRAITS_HPP
#define BOOST_INTRUSIVE_DERIVATION_VALUE_TRAITS_HPP
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/intrusive/link_mode.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
namespace boost {
namespace intrusive {
//!This value traits template is used to create value traits
//!from user defined node traits where value_traits::value_type will
//!derive from node_traits::node
template<class T, class NodeTraits, link_mode_type LinkMode
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
= safe_link
#endif
>
struct derivation_value_traits
{
public:
typedef NodeTraits node_traits;
typedef T value_type;
typedef typename node_traits::node node;
typedef typename node_traits::node_ptr node_ptr;
typedef typename node_traits::const_node_ptr const_node_ptr;
typedef typename pointer_traits<node_ptr>::
template rebind_pointer<value_type>::type pointer;
typedef typename pointer_traits<node_ptr>::
template rebind_pointer<const value_type>::type const_pointer;
typedef typename boost::intrusive::
pointer_traits<pointer>::reference reference;
typedef typename boost::intrusive::
pointer_traits<const_pointer>::reference const_reference;
static const link_mode_type link_mode = LinkMode;
BOOST_INTRUSIVE_FORCEINLINE static node_ptr to_node_ptr(reference value) BOOST_NOEXCEPT
{ return node_ptr(&value); }
BOOST_INTRUSIVE_FORCEINLINE static const_node_ptr to_node_ptr(const_reference value) BOOST_NOEXCEPT
{ return node_ptr(&value); }
BOOST_INTRUSIVE_FORCEINLINE static pointer to_value_ptr(node_ptr n) BOOST_NOEXCEPT
{
return pointer_traits<pointer>::pointer_to(static_cast<reference>(*n));
}
BOOST_INTRUSIVE_FORCEINLINE static const_pointer to_value_ptr(const_node_ptr n) BOOST_NOEXCEPT
{
return pointer_traits<const_pointer>::pointer_to(static_cast<const_reference>(*n));
}
};
} //namespace intrusive
} //namespace boost
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_DERIVATION_VALUE_TRAITS_HPP

View File

@@ -0,0 +1,53 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2014-2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DETAIL_ALGO_TYPE_HPP
#define BOOST_INTRUSIVE_DETAIL_ALGO_TYPE_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
namespace boost {
namespace intrusive {
enum algo_types
{
CircularListAlgorithms,
CircularSListAlgorithms,
LinearSListAlgorithms,
CommonSListAlgorithms,
BsTreeAlgorithms,
RbTreeAlgorithms,
AvlTreeAlgorithms,
SgTreeAlgorithms,
SplayTreeAlgorithms,
TreapAlgorithms,
UnorderedAlgorithms,
UnorderedCircularSlistAlgorithms,
AnyAlgorithm
};
template<algo_types AlgoType, class NodeTraits>
struct get_algo;
template<algo_types AlgoType, class ValueTraits, class NodePtrCompare, class ExtraChecker>
struct get_node_checker;
} //namespace intrusive
} //namespace boost
#endif //BOOST_INTRUSIVE_DETAIL_ALGO_TYPE_HPP

View File

@@ -0,0 +1,90 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2014-2014.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DETAIL_ALGORITHM_HPP
#define BOOST_INTRUSIVE_DETAIL_ALGORITHM_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
namespace boost {
namespace intrusive {
struct algo_pred_equal
{
template<class T>
bool operator()(const T &x, const T &y) const
{ return x == y; }
};
struct algo_pred_less
{
template<class T>
bool operator()(const T &x, const T &y) const
{ return x < y; }
};
template<class InputIt1, class InputIt2, class BinaryPredicate>
bool algo_equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, BinaryPredicate p)
{
for (; first1 != last1; ++first1, ++first2) {
if (!p(*first1, *first2)) {
return false;
}
}
return true;
}
template<class InputIt1, class InputIt2>
bool algo_equal(InputIt1 first1, InputIt1 last1, InputIt2 first2)
{ return (algo_equal)(first1, last1, first2, algo_pred_equal()); }
template<class InputIt1, class InputIt2, class BinaryPredicate>
bool algo_equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, BinaryPredicate pred)
{
for (; first1 != last1 && first2 != last2; ++first1, ++first2)
if (!pred(*first1, *first2))
return false;
return first1 == last1 && first2 == last2;
}
template<class InputIt1, class InputIt2>
bool algo_equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2)
{ return (algo_equal)(first1, last1, first2, last2, algo_pred_equal()); }
template <class InputIterator1, class InputIterator2, class BinaryPredicate>
bool algo_lexicographical_compare (InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
BinaryPredicate pred)
{
while (first1 != last1){
if (first2 == last2 || *first2 < *first1) return false;
else if (pred(*first1, *first2)) return true;
++first1; ++first2;
}
return (first2 != last2);
}
template <class InputIterator1, class InputIterator2>
bool algo_lexicographical_compare (InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2)
{ return (algo_lexicographical_compare)(first1, last1, first2, last2, algo_pred_less()); }
} //namespace intrusive {
} //namespace boost {
#endif //#ifndef BOOST_INTRUSIVE_DETAIL_ALGORITHM_HPP

View File

@@ -0,0 +1,297 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_ANY_NODE_HPP
#define BOOST_INTRUSIVE_ANY_NODE_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/intrusive/detail/workaround.hpp>
#include <boost/intrusive/pointer_rebind.hpp>
#include <boost/intrusive/detail/mpl.hpp>
#include <boost/intrusive/detail/algo_type.hpp>
#include <cstddef>
namespace boost {
namespace intrusive {
template<class VoidPointer>
struct any_node
{
typedef any_node node;
typedef typename pointer_rebind<VoidPointer, node>::type node_ptr;
typedef typename pointer_rebind<VoidPointer, const node>::type const_node_ptr;
node_ptr node_ptr_1;
node_ptr node_ptr_2;
node_ptr node_ptr_3;
std::size_t size_t_1;
};
template<class VoidPointer>
struct any_list_node_traits
{
typedef any_node<VoidPointer> node;
typedef typename node::node_ptr node_ptr;
typedef typename node::const_node_ptr const_node_ptr;
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_next(const_node_ptr n)
{ return n->node_ptr_1; }
BOOST_INTRUSIVE_FORCEINLINE static void set_next(node_ptr n, node_ptr next)
{ n->node_ptr_1 = next; }
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_previous(const_node_ptr n)
{ return n->node_ptr_2; }
BOOST_INTRUSIVE_FORCEINLINE static void set_previous(node_ptr n, node_ptr prev)
{ n->node_ptr_2 = prev; }
};
template<class VoidPointer>
struct any_slist_node_traits
{
typedef any_node<VoidPointer> node;
typedef typename node::node_ptr node_ptr;
typedef typename node::const_node_ptr const_node_ptr;
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_next(const_node_ptr n)
{ return n->node_ptr_1; }
BOOST_INTRUSIVE_FORCEINLINE static void set_next(node_ptr n, node_ptr next)
{ n->node_ptr_1 = next; }
};
template<class VoidPointer>
struct any_unordered_node_traits
: public any_slist_node_traits<VoidPointer>
{
typedef any_slist_node_traits<VoidPointer> reduced_slist_node_traits;
typedef typename reduced_slist_node_traits::node node;
typedef typename reduced_slist_node_traits::node_ptr node_ptr;
typedef typename reduced_slist_node_traits::const_node_ptr const_node_ptr;
static const bool store_hash = true;
static const bool optimize_multikey = true;
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_next(const_node_ptr n)
{ return n->node_ptr_1; }
BOOST_INTRUSIVE_FORCEINLINE static void set_next(node_ptr n, node_ptr next)
{ n->node_ptr_1 = next; }
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_prev_in_group(const_node_ptr n)
{ return n->node_ptr_2; }
BOOST_INTRUSIVE_FORCEINLINE static void set_prev_in_group(node_ptr n, node_ptr prev)
{ n->node_ptr_2 = prev; }
BOOST_INTRUSIVE_FORCEINLINE static std::size_t get_hash(const_node_ptr n)
{ return n->size_t_1; }
BOOST_INTRUSIVE_FORCEINLINE static void set_hash(node_ptr n, std::size_t h)
{ n->size_t_1 = h; }
};
template<class VoidPointer>
struct any_rbtree_node_traits
{
typedef any_node<VoidPointer> node;
typedef typename node::node_ptr node_ptr;
typedef typename node::const_node_ptr const_node_ptr;
typedef std::size_t color;
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const_node_ptr n)
{ return n->node_ptr_1; }
BOOST_INTRUSIVE_FORCEINLINE static void set_parent(node_ptr n, node_ptr p)
{ n->node_ptr_1 = p; }
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const_node_ptr n)
{ return n->node_ptr_2; }
BOOST_INTRUSIVE_FORCEINLINE static void set_left(node_ptr n, node_ptr l)
{ n->node_ptr_2 = l; }
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const_node_ptr n)
{ return n->node_ptr_3; }
BOOST_INTRUSIVE_FORCEINLINE static void set_right(node_ptr n, node_ptr r)
{ n->node_ptr_3 = r; }
BOOST_INTRUSIVE_FORCEINLINE static color get_color(const_node_ptr n)
{ return n->size_t_1; }
BOOST_INTRUSIVE_FORCEINLINE static void set_color(node_ptr n, color c)
{ n->size_t_1 = c; }
BOOST_INTRUSIVE_FORCEINLINE static color black()
{ return 0u; }
BOOST_INTRUSIVE_FORCEINLINE static color red()
{ return 1u; }
};
template<class VoidPointer>
struct any_avltree_node_traits
{
typedef any_node<VoidPointer> node;
typedef typename node::node_ptr node_ptr;
typedef typename node::const_node_ptr const_node_ptr;
typedef std::size_t balance;
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const_node_ptr n)
{ return n->node_ptr_1; }
BOOST_INTRUSIVE_FORCEINLINE static void set_parent(node_ptr n, node_ptr p)
{ n->node_ptr_1 = p; }
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const_node_ptr n)
{ return n->node_ptr_2; }
BOOST_INTRUSIVE_FORCEINLINE static void set_left(node_ptr n, node_ptr l)
{ n->node_ptr_2 = l; }
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const_node_ptr n)
{ return n->node_ptr_3; }
BOOST_INTRUSIVE_FORCEINLINE static void set_right(node_ptr n, node_ptr r)
{ n->node_ptr_3 = r; }
BOOST_INTRUSIVE_FORCEINLINE static balance get_balance(const_node_ptr n)
{ return n->size_t_1; }
BOOST_INTRUSIVE_FORCEINLINE static void set_balance(node_ptr n, balance b)
{ n->size_t_1 = b; }
BOOST_INTRUSIVE_FORCEINLINE static balance negative()
{ return 0u; }
BOOST_INTRUSIVE_FORCEINLINE static balance zero()
{ return 1u; }
BOOST_INTRUSIVE_FORCEINLINE static balance positive()
{ return 2u; }
};
template<class VoidPointer>
struct any_tree_node_traits
{
typedef any_node<VoidPointer> node;
typedef typename node::node_ptr node_ptr;
typedef typename node::const_node_ptr const_node_ptr;
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const_node_ptr n)
{ return n->node_ptr_1; }
BOOST_INTRUSIVE_FORCEINLINE static void set_parent(node_ptr n, node_ptr p)
{ n->node_ptr_1 = p; }
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const_node_ptr n)
{ return n->node_ptr_2; }
BOOST_INTRUSIVE_FORCEINLINE static void set_left(node_ptr n, node_ptr l)
{ n->node_ptr_2 = l; }
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const_node_ptr n)
{ return n->node_ptr_3; }
BOOST_INTRUSIVE_FORCEINLINE static void set_right(node_ptr n, node_ptr r)
{ n->node_ptr_3 = r; }
};
template<class VoidPointer>
class any_node_traits
{
public:
typedef any_node<VoidPointer> node;
typedef typename node::node_ptr node_ptr;
typedef typename node::const_node_ptr const_node_ptr;
};
template<class VoidPointer>
class any_algorithms
{
template <class T>
static void function_not_available_for_any_hooks(typename detail::enable_if<detail::is_same<T, bool> >::type)
{}
public:
typedef any_node<VoidPointer> node;
typedef typename node::node_ptr node_ptr;
typedef typename node::const_node_ptr const_node_ptr;
typedef any_node_traits<VoidPointer> node_traits;
//! <b>Requires</b>: node must not be part of any tree.
//!
//! <b>Effects</b>: After the function unique(node) == true.
//!
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Nodes</b>: If node is inserted in a tree, this function corrupts the tree.
BOOST_INTRUSIVE_FORCEINLINE static void init(node_ptr node) BOOST_NOEXCEPT
{ node->node_ptr_1 = node_ptr(); };
//! <b>Effects</b>: Returns true if node is in the same state as if called init(node)
//!
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: Nothing.
BOOST_INTRUSIVE_FORCEINLINE static bool inited(const_node_ptr node)
{ return !node->node_ptr_1; };
BOOST_INTRUSIVE_FORCEINLINE static bool unique(const_node_ptr node) BOOST_NOEXCEPT
{ return !node->node_ptr_1; }
static void unlink(node_ptr)
{
//Auto-unlink hooks and unlink() are not available for any hooks
any_algorithms<VoidPointer>::template function_not_available_for_any_hooks<node_ptr>();
}
static void swap_nodes(node_ptr, node_ptr)
{
//Any nodes have no swap_nodes capability because they don't know
//what algorithm they must use to unlink the node from the container
any_algorithms<VoidPointer>::template function_not_available_for_any_hooks<node_ptr>();
}
};
///@cond
template<class NodeTraits>
struct get_algo<AnyAlgorithm, NodeTraits>
{
typedef typename pointer_rebind<typename NodeTraits::node_ptr, void>::type void_pointer;
typedef any_algorithms<void_pointer> type;
};
///@endcond
} //namespace intrusive
} //namespace boost
#endif //BOOST_INTRUSIVE_ANY_NODE_HPP

View File

@@ -0,0 +1,97 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2014-2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DETAIL_ARRAY_INITIALIZER_HPP
#define BOOST_INTRUSIVE_DETAIL_ARRAY_INITIALIZER_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/config.hpp>
#include <boost/core/no_exceptions_support.hpp>
#include <boost/move/detail/placement_new.hpp>
#include <boost/move/detail/force_ptr.hpp>
namespace boost {
namespace intrusive {
namespace detail {
//This is not standard, but should work with all compilers
union max_align
{
char char_;
short short_;
int int_;
long long_;
#ifdef BOOST_HAS_LONG_LONG
::boost::long_long_type long_long_;
#endif
float float_;
double double_;
long double long_double_;
void * void_ptr_;
};
template<class T, std::size_t N>
class array_initializer
{
public:
template<class CommonInitializer>
array_initializer(const CommonInitializer &init)
{
char *init_buf = (char*)rawbuf;
std::size_t i = 0;
BOOST_TRY{
for(; i != N; ++i){
::new(init_buf, boost_move_new_t()) T(init);
init_buf += sizeof(T);
}
}
BOOST_CATCH(...){
while(i--){
init_buf -= sizeof(T);
move_detail::force_ptr<T*>(init_buf)->~T();
}
BOOST_RETHROW;
}
BOOST_CATCH_END
}
operator T* ()
{ return (T*)(rawbuf); }
operator const T*() const
{ return (const T*)(rawbuf); }
~array_initializer()
{
char *init_buf = (char*)rawbuf + N*sizeof(T);
for(std::size_t i = 0; i != N; ++i){
init_buf -= sizeof(T);
move_detail::force_ptr<T*>(init_buf)->~T();
}
}
private:
detail::max_align rawbuf[(N*sizeof(T)-1)/sizeof(detail::max_align)+1];
};
} //namespace detail{
} //namespace intrusive{
} //namespace boost{
#endif //BOOST_INTRUSIVE_DETAIL_ARRAY_INITIALIZER_HPP

View File

@@ -0,0 +1,45 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2013
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DETAIL_ASSERT_HPP
#define BOOST_INTRUSIVE_DETAIL_ASSERT_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
#pragma once
#endif
#if !defined(BOOST_INTRUSIVE_INVARIANT_ASSERT)
#include <boost/assert.hpp>
#define BOOST_INTRUSIVE_INVARIANT_ASSERT BOOST_ASSERT
#elif defined(BOOST_INTRUSIVE_INVARIANT_ASSERT_INCLUDE)
#include BOOST_INTRUSIVE_INVARIANT_ASSERT_INCLUDE
#endif
#if !defined(BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT)
#include <boost/assert.hpp>
#define BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT BOOST_ASSERT
#elif defined(BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT_INCLUDE)
#include BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT_INCLUDE
#endif
#if !defined(BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT)
#include <boost/assert.hpp>
#define BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT BOOST_ASSERT
#elif defined(BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT_INCLUDE)
#include BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT_INCLUDE
#endif
#endif //BOOST_INTRUSIVE_DETAIL_ASSERT_HPP

View File

@@ -0,0 +1,193 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2013
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_AVLTREE_NODE_HPP
#define BOOST_INTRUSIVE_AVLTREE_NODE_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/detail/workaround.hpp>
#include <boost/intrusive/pointer_rebind.hpp>
#include <boost/intrusive/avltree_algorithms.hpp>
#include <boost/intrusive/pointer_plus_bits.hpp>
#include <boost/intrusive/detail/mpl.hpp>
namespace boost {
namespace intrusive {
/////////////////////////////////////////////////////////////////////////////
// //
// Generic node_traits for any pointer type //
// //
/////////////////////////////////////////////////////////////////////////////
//This is the compact representation: 3 pointers
template<class VoidPointer>
struct compact_avltree_node
{
typedef typename pointer_rebind<VoidPointer, compact_avltree_node<VoidPointer> >::type node_ptr;
typedef typename pointer_rebind<VoidPointer, const compact_avltree_node<VoidPointer> >::type const_node_ptr;
enum balance { negative_t, zero_t, positive_t };
node_ptr parent_, left_, right_;
};
//This is the normal representation: 3 pointers + enum
template<class VoidPointer>
struct avltree_node
{
typedef typename pointer_rebind<VoidPointer, avltree_node<VoidPointer> >::type node_ptr;
typedef typename pointer_rebind<VoidPointer, const avltree_node<VoidPointer> >::type const_node_ptr;
enum balance { negative_t, zero_t, positive_t };
node_ptr parent_, left_, right_;
balance balance_;
};
//This is the default node traits implementation
//using a node with 3 generic pointers plus an enum
template<class VoidPointer>
struct default_avltree_node_traits_impl
{
typedef avltree_node<VoidPointer> node;
typedef typename node::node_ptr node_ptr;
typedef typename node::const_node_ptr const_node_ptr;
typedef typename node::balance balance;
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const_node_ptr n)
{ return n->parent_; }
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(node_ptr n)
{ return n->parent_; }
BOOST_INTRUSIVE_FORCEINLINE static void set_parent(node_ptr n, node_ptr p)
{ n->parent_ = p; }
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const_node_ptr n)
{ return n->left_; }
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(node_ptr n)
{ return n->left_; }
BOOST_INTRUSIVE_FORCEINLINE static void set_left(node_ptr n, node_ptr l)
{ n->left_ = l; }
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const_node_ptr n)
{ return n->right_; }
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(node_ptr n)
{ return n->right_; }
BOOST_INTRUSIVE_FORCEINLINE static void set_right(node_ptr n, node_ptr r)
{ n->right_ = r; }
BOOST_INTRUSIVE_FORCEINLINE static balance get_balance(const_node_ptr n)
{ return n->balance_; }
BOOST_INTRUSIVE_FORCEINLINE static balance get_balance(node_ptr n)
{ return n->balance_; }
BOOST_INTRUSIVE_FORCEINLINE static void set_balance(node_ptr n, balance b)
{ n->balance_ = b; }
BOOST_INTRUSIVE_FORCEINLINE static balance negative()
{ return node::negative_t; }
BOOST_INTRUSIVE_FORCEINLINE static balance zero()
{ return node::zero_t; }
BOOST_INTRUSIVE_FORCEINLINE static balance positive()
{ return node::positive_t; }
};
//This is the compact node traits implementation
//using a node with 3 generic pointers
template<class VoidPointer>
struct compact_avltree_node_traits_impl
{
typedef compact_avltree_node<VoidPointer> node;
typedef typename node::node_ptr node_ptr;
typedef typename node::const_node_ptr const_node_ptr;
typedef typename node::balance balance;
typedef pointer_plus_bits<node_ptr, 2> ptr_bit;
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const_node_ptr n)
{ return ptr_bit::get_pointer(n->parent_); }
BOOST_INTRUSIVE_FORCEINLINE static void set_parent(node_ptr n, node_ptr p)
{ ptr_bit::set_pointer(n->parent_, p); }
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const_node_ptr n)
{ return n->left_; }
BOOST_INTRUSIVE_FORCEINLINE static void set_left(node_ptr n, node_ptr l)
{ n->left_ = l; }
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const_node_ptr n)
{ return n->right_; }
BOOST_INTRUSIVE_FORCEINLINE static void set_right(node_ptr n, node_ptr r)
{ n->right_ = r; }
BOOST_INTRUSIVE_FORCEINLINE static balance get_balance(const_node_ptr n)
{ return (balance)ptr_bit::get_bits(n->parent_); }
BOOST_INTRUSIVE_FORCEINLINE static void set_balance(node_ptr n, balance b)
{ ptr_bit::set_bits(n->parent_, (std::size_t)b); }
BOOST_INTRUSIVE_FORCEINLINE static balance negative()
{ return node::negative_t; }
BOOST_INTRUSIVE_FORCEINLINE static balance zero()
{ return node::zero_t; }
BOOST_INTRUSIVE_FORCEINLINE static balance positive()
{ return node::positive_t; }
};
//Dispatches the implementation based on the boolean
template<class VoidPointer, bool Compact>
struct avltree_node_traits_dispatch
: public default_avltree_node_traits_impl<VoidPointer>
{};
template<class VoidPointer>
struct avltree_node_traits_dispatch<VoidPointer, true>
: public compact_avltree_node_traits_impl<VoidPointer>
{};
//Inherit from rbtree_node_traits_dispatch depending on the embedding capabilities
template<class VoidPointer, bool OptimizeSize = false>
struct avltree_node_traits
: public avltree_node_traits_dispatch
< VoidPointer
, OptimizeSize &&
max_pointer_plus_bits
< VoidPointer
, detail::alignment_of<compact_avltree_node<VoidPointer> >::value
>::value >= 2u
>
{};
} //namespace intrusive
} //namespace boost
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_AVLTREE_NODE_HPP

View File

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

View File

@@ -0,0 +1,198 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_COMMON_SLIST_ALGORITHMS_HPP
#define BOOST_INTRUSIVE_COMMON_SLIST_ALGORITHMS_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/intrusive/detail/assert.hpp>
#include <boost/intrusive/detail/algo_type.hpp>
#include <boost/core/no_exceptions_support.hpp>
#include <cstddef>
namespace boost {
namespace intrusive {
namespace detail {
template<class NodeTraits>
class common_slist_algorithms
{
public:
typedef typename NodeTraits::node node;
typedef typename NodeTraits::node_ptr node_ptr;
typedef typename NodeTraits::const_node_ptr const_node_ptr;
typedef NodeTraits node_traits;
static node_ptr get_previous_node(node_ptr p, node_ptr this_node)
{
for( node_ptr p_next
; this_node != (p_next = NodeTraits::get_next(p))
; p = p_next){
//Logic error: possible use of linear lists with
//operations only permitted with circular lists
BOOST_INTRUSIVE_INVARIANT_ASSERT(p);
}
return p;
}
BOOST_INTRUSIVE_FORCEINLINE static void init(node_ptr this_node) BOOST_NOEXCEPT
{ NodeTraits::set_next(this_node, node_ptr()); }
static bool unique(const_node_ptr this_node) BOOST_NOEXCEPT
{
node_ptr next = NodeTraits::get_next(this_node);
return !next || next == this_node;
}
BOOST_INTRUSIVE_FORCEINLINE static bool inited(const_node_ptr this_node) BOOST_NOEXCEPT
{ return !NodeTraits::get_next(this_node); }
static void unlink_after(node_ptr prev_node) BOOST_NOEXCEPT
{
const_node_ptr this_node(NodeTraits::get_next(prev_node));
NodeTraits::set_next(prev_node, NodeTraits::get_next(this_node));
}
BOOST_INTRUSIVE_FORCEINLINE static void unlink_after(node_ptr prev_node, node_ptr last_node) BOOST_NOEXCEPT
{ NodeTraits::set_next(prev_node, last_node); }
static void link_after(node_ptr prev_node, node_ptr this_node) BOOST_NOEXCEPT
{
NodeTraits::set_next(this_node, NodeTraits::get_next(prev_node));
NodeTraits::set_next(prev_node, this_node);
}
static void incorporate_after(node_ptr bp, node_ptr b, node_ptr be) BOOST_NOEXCEPT
{
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) BOOST_NOEXCEPT
{
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);
}
}
struct stable_partition_info
{
std::size_t num_1st_partition;
std::size_t num_2nd_partition;
node_ptr beg_2st_partition;
node_ptr new_last_node;
};
template<class Pred>
static void stable_partition(node_ptr before_beg, node_ptr end, Pred pred, stable_partition_info &info)
{
node_ptr bcur = before_beg;
node_ptr cur = node_traits::get_next(bcur);
node_ptr new_f = end;
std::size_t num1 = 0, num2 = 0;
while(cur != end){
if(pred(cur)){
++num1;
bcur = cur;
cur = node_traits::get_next(cur);
}
else{
++num2;
node_ptr last_to_remove = bcur;
new_f = cur;
bcur = cur;
cur = node_traits::get_next(cur);
BOOST_TRY{
//Main loop
while(cur != end){
if(pred(cur)){ //Might throw
++num1;
//Process current node
node_traits::set_next(last_to_remove, cur);
last_to_remove = cur;
node_ptr nxt = node_traits::get_next(cur);
node_traits::set_next(bcur, nxt);
cur = nxt;
}
else{
++num2;
bcur = cur;
cur = node_traits::get_next(cur);
}
}
}
BOOST_CATCH(...){
node_traits::set_next(last_to_remove, new_f);
BOOST_RETHROW;
}
BOOST_CATCH_END
node_traits::set_next(last_to_remove, new_f);
break;
}
}
info.num_1st_partition = num1;
info.num_2nd_partition = num2;
info.beg_2st_partition = new_f;
info.new_last_node = bcur;
}
//! <b>Requires</b>: f and l must be in a circular list.
//!
//! <b>Effects</b>: Returns the number of nodes in the range [f, l).
//!
//! <b>Complexity</b>: Linear
//!
//! <b>Throws</b>: Nothing.
static std::size_t distance(const_node_ptr f, const_node_ptr l) BOOST_NOEXCEPT
{
const_node_ptr i(f);
std::size_t result = 0;
while(i != l){
i = NodeTraits::get_next(i);
++result;
}
return result;
}
};
/// @endcond
} //namespace detail
/// @cond
template<class NodeTraits>
struct get_algo<CommonSListAlgorithms, NodeTraits>
{
typedef detail::common_slist_algorithms<NodeTraits> type;
};
} //namespace intrusive
} //namespace boost
#endif //BOOST_INTRUSIVE_COMMON_SLIST_ALGORITHMS_HPP

View File

@@ -0,0 +1,44 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2013
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONFIG_HPP
#include <boost/config.hpp>
#endif
#ifdef BOOST_MSVC
#pragma warning (push)
#pragma warning (disable : 4619) // there is no warning number 'XXXX'
#pragma warning (disable : 4275) // non DLL-interface classkey "identifier" used as base for DLL-interface classkey "identifier"
#pragma warning (disable : 4251) // "identifier" : class "type" needs to have dll-interface to be used by clients of class "type2"
#pragma warning (disable : 4675) // "method" should be declared "static" and have exactly one parameter
#pragma warning (disable : 4996) // "function": was declared deprecated
#pragma warning (disable : 4503) // "identifier" : decorated name length exceeded, name was truncated
#pragma warning (disable : 4284) // odd return type for operator->
#pragma warning (disable : 4244) // possible loss of data
#pragma warning (disable : 4521) ////Disable "multiple copy constructors specified"
#pragma warning (disable : 4127) //conditional expression is constant
#pragma warning (disable : 4146) // unary minus operator applied to unsigned type, result still unsigned
#pragma warning (disable : 4267) //conversion from 'X' to 'Y', possible loss of data
#pragma warning (disable : 4541) //'typeid' used on polymorphic type 'boost::exception' with /GR-
#pragma warning (disable : 4512) //'typeid' used on polymorphic type 'boost::exception' with /GR-
#pragma warning (disable : 4522) // "class" : multiple assignment operators specified
#pragma warning (disable : 4706) //assignment within conditional expression
#pragma warning (disable : 4710) // function not inlined
#pragma warning (disable : 4714) // "function": marked as __forceinline not inlined
#pragma warning (disable : 4711) // function selected for automatic inline expansion
#pragma warning (disable : 4786) // identifier truncated in debug info
#pragma warning (disable : 4996) // "function": was declared deprecated
#endif
//#define BOOST_INTRUSIVE_USE_ITERATOR_FACADE
//#define BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE

View File

@@ -0,0 +1,15 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2013
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#if defined BOOST_MSVC
#pragma warning (pop)
#endif

View File

@@ -0,0 +1,70 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2014-2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DETAIL_DEFAULT_HEADER_HOLDER_HPP
#define BOOST_INTRUSIVE_DETAIL_DEFAULT_HEADER_HOLDER_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/intrusive/detail/workaround.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/move/detail/to_raw_pointer.hpp>
namespace boost {
namespace intrusive {
namespace detail {
// trivial header node holder
template < typename NodeTraits >
struct default_header_holder : public NodeTraits::node
{
typedef NodeTraits node_traits;
typedef typename node_traits::node node;
typedef typename node_traits::node_ptr node_ptr;
typedef typename node_traits::const_node_ptr const_node_ptr;
default_header_holder() : node() {}
BOOST_INTRUSIVE_FORCEINLINE const_node_ptr get_node() const
{ return pointer_traits< const_node_ptr >::pointer_to(*static_cast< const node* >(this)); }
BOOST_INTRUSIVE_FORCEINLINE node_ptr get_node()
{ return pointer_traits< node_ptr >::pointer_to(*static_cast< node* >(this)); }
// (unsafe) downcast used to implement container-from-iterator
BOOST_INTRUSIVE_FORCEINLINE static default_header_holder* get_holder(node_ptr p)
{ return static_cast< default_header_holder* >(boost::movelib::to_raw_pointer(p)); }
};
// type function producing the header node holder
template < typename ValueTraits, typename HeaderHolder >
struct get_header_holder_type
{
typedef HeaderHolder type;
};
template < typename ValueTraits >
struct get_header_holder_type< ValueTraits, void >
{
typedef default_header_holder< typename ValueTraits::node_traits > type;
};
} //namespace detail
} //namespace intrusive
} //namespace boost
#endif //BOOST_INTRUSIVE_DETAIL_DEFAULT_HEADER_HOLDER_HPP

View File

@@ -0,0 +1,292 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Joaquin M Lopez Munoz 2006-2013
// (C) Copyright Ion Gaztanaga 2014-2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DETAIL_EBO_HOLDER_HPP
#define BOOST_INTRUSIVE_DETAIL_EBO_HOLDER_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/intrusive/detail/workaround.hpp>
#include <boost/move/utility_core.hpp>
namespace boost {
namespace intrusive {
namespace detail {
#if defined(BOOST_MSVC) || defined(__BORLANDC_)
#define BOOST_INTRUSIVE_TT_DECL __cdecl
#else
#define BOOST_INTRUSIVE_TT_DECL
#endif
#if defined(_MSC_EXTENSIONS) && !defined(__BORLAND__) && !defined(_WIN64) && !defined(_M_ARM) && !defined(_M_ARM64) && !defined(UNDER_CE)
#define BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS
#endif
template <typename T>
struct is_unary_or_binary_function_impl
{ static const bool value = false; };
// see boost ticket #4094
// avoid duplicate definitions of is_unary_or_binary_function_impl
#ifndef BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS
template <typename R>
struct is_unary_or_binary_function_impl<R (*)()>
{ static const bool value = true; };
template <typename R>
struct is_unary_or_binary_function_impl<R (*)(...)>
{ static const bool value = true; };
#else // BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS
template <typename R>
struct is_unary_or_binary_function_impl<R (__stdcall*)()>
{ static const bool value = true; };
#ifndef _MANAGED
template <typename R>
struct is_unary_or_binary_function_impl<R (__fastcall*)()>
{ static const bool value = true; };
#endif
template <typename R>
struct is_unary_or_binary_function_impl<R (__cdecl*)()>
{ static const bool value = true; };
template <typename R>
struct is_unary_or_binary_function_impl<R (__cdecl*)(...)>
{ static const bool value = true; };
#endif
// see boost ticket #4094
// avoid duplicate definitions of is_unary_or_binary_function_impl
#ifndef BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS
template <typename R, class T0>
struct is_unary_or_binary_function_impl<R (*)(T0)>
{ static const bool value = true; };
template <typename R, class T0>
struct is_unary_or_binary_function_impl<R (*)(T0...)>
{ static const bool value = true; };
#else // BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS
template <typename R, class T0>
struct is_unary_or_binary_function_impl<R (__stdcall*)(T0)>
{ static const bool value = true; };
#ifndef _MANAGED
template <typename R, class T0>
struct is_unary_or_binary_function_impl<R (__fastcall*)(T0)>
{ static const bool value = true; };
#endif
template <typename R, class T0>
struct is_unary_or_binary_function_impl<R (__cdecl*)(T0)>
{ static const bool value = true; };
template <typename R, class T0>
struct is_unary_or_binary_function_impl<R (__cdecl*)(T0...)>
{ static const bool value = true; };
#endif
// see boost ticket #4094
// avoid duplicate definitions of is_unary_or_binary_function_impl
#ifndef BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS
template <typename R, class T0, class T1>
struct is_unary_or_binary_function_impl<R (*)(T0, T1)>
{ static const bool value = true; };
template <typename R, class T0, class T1>
struct is_unary_or_binary_function_impl<R (*)(T0, T1...)>
{ static const bool value = true; };
#else // BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS
template <typename R, class T0, class T1>
struct is_unary_or_binary_function_impl<R (__stdcall*)(T0, T1)>
{ static const bool value = true; };
#ifndef _MANAGED
template <typename R, class T0, class T1>
struct is_unary_or_binary_function_impl<R (__fastcall*)(T0, T1)>
{ static const bool value = true; };
#endif
template <typename R, class T0, class T1>
struct is_unary_or_binary_function_impl<R (__cdecl*)(T0, T1)>
{ static const bool value = true; };
template <typename R, class T0, class T1>
struct is_unary_or_binary_function_impl<R (__cdecl*)(T0, T1...)>
{ static const bool value = true; };
#endif
template <typename T>
struct is_unary_or_binary_function_impl<T&>
{ static const bool value = false; };
template<typename T>
struct is_unary_or_binary_function : is_unary_or_binary_function_impl<T>
{};
template<typename T, typename Tag = void, bool = is_unary_or_binary_function<T>::value>
class ebo_functor_holder
{
BOOST_COPYABLE_AND_MOVABLE(ebo_functor_holder)
public:
typedef T functor_type;
BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder()
: t_()
{}
BOOST_INTRUSIVE_FORCEINLINE explicit ebo_functor_holder(const T &t)
: t_(t)
{}
BOOST_INTRUSIVE_FORCEINLINE explicit ebo_functor_holder(BOOST_RV_REF(T) t)
: t_(::boost::move(t))
{}
template<class Arg1, class Arg2>
BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder(BOOST_FWD_REF(Arg1) arg1, BOOST_FWD_REF(Arg2) arg2)
: t_(::boost::forward<Arg1>(arg1), ::boost::forward<Arg2>(arg2))
{}
BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder(const ebo_functor_holder &x)
: t_(x.t_)
{}
BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder(BOOST_RV_REF(ebo_functor_holder) x)
: t_(x.t_)
{}
BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(BOOST_COPY_ASSIGN_REF(ebo_functor_holder) x)
{
this->get() = x.get();
return *this;
}
BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(BOOST_RV_REF(ebo_functor_holder) x)
{
this->get() = ::boost::move(x.get());
return *this;
}
BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(const T &x)
{
this->get() = x;
return *this;
}
BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(BOOST_RV_REF(T) x)
{
this->get() = ::boost::move(x);
return *this;
}
BOOST_INTRUSIVE_FORCEINLINE T& get(){return t_;}
BOOST_INTRUSIVE_FORCEINLINE const T& get()const{return t_;}
private:
T t_;
};
template<typename T, typename Tag>
class ebo_functor_holder<T, Tag, false>
: public T
{
BOOST_COPYABLE_AND_MOVABLE(ebo_functor_holder)
public:
typedef T functor_type;
BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder()
: T()
{}
BOOST_INTRUSIVE_FORCEINLINE explicit ebo_functor_holder(const T &t)
: T(t)
{}
BOOST_INTRUSIVE_FORCEINLINE explicit ebo_functor_holder(BOOST_RV_REF(T) t)
: T(::boost::move(t))
{}
template<class Arg1, class Arg2>
BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder(BOOST_FWD_REF(Arg1) arg1, BOOST_FWD_REF(Arg2) arg2)
: T(::boost::forward<Arg1>(arg1), ::boost::forward<Arg2>(arg2))
{}
BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder(const ebo_functor_holder &x)
: T(static_cast<const T&>(x))
{}
BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder(BOOST_RV_REF(ebo_functor_holder) x)
: T(BOOST_MOVE_BASE(T, x))
{}
BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(BOOST_COPY_ASSIGN_REF(ebo_functor_holder) x)
{
const ebo_functor_holder&r = x;
this->get() = r;
return *this;
}
BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(BOOST_RV_REF(ebo_functor_holder) x)
{
this->get() = ::boost::move(x.get());
return *this;
}
BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(const T &x)
{
this->get() = x;
return *this;
}
BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(BOOST_RV_REF(T) x)
{
this->get() = ::boost::move(x);
return *this;
}
BOOST_INTRUSIVE_FORCEINLINE T& get(){return *this;}
BOOST_INTRUSIVE_FORCEINLINE const T& get()const{return *this;}
};
} //namespace detail {
} //namespace intrusive {
} //namespace boost {
#endif //#ifndef BOOST_INTRUSIVE_DETAIL_EBO_HOLDER_HPP

View File

@@ -0,0 +1,44 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2014-2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DETAIL_EMPTY_NODE_CHECKER_HPP
#define BOOST_INTRUSIVE_DETAIL_EMPTY_NODE_CHECKER_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
namespace boost {
namespace intrusive {
namespace detail {
template<class ValueTraits>
struct empty_node_checker
{
typedef ValueTraits value_traits;
typedef typename value_traits::node_traits node_traits;
typedef typename node_traits::const_node_ptr const_node_ptr;
struct return_type {};
void operator () (const_node_ptr, const return_type&, const return_type&, return_type&) {}
};
} //namespace detail{
} //namespace intrusive{
} //namespace boost{
#endif //BOOST_INTRUSIVE_DETAIL_EMPTY_NODE_CHECKER_HPP

View File

@@ -0,0 +1,50 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2014-2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DETAIL_EQUAL_TO_VALUE_HPP
#define BOOST_INTRUSIVE_DETAIL_EQUAL_TO_VALUE_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/intrusive/detail/workaround.hpp>
namespace boost {
namespace intrusive {
namespace detail {
//This functor compares a stored value
//and the one passed as an argument
template<class ConstReference>
class equal_to_value
{
ConstReference t_;
public:
equal_to_value(ConstReference t)
: t_(t)
{}
BOOST_INTRUSIVE_FORCEINLINE bool operator()(ConstReference t)const
{ return t_ == t; }
};
} //namespace detail{
} //namespace intrusive{
} //namespace boost{
#endif //BOOST_INTRUSIVE_DETAIL_EQUAL_TO_VALUE_HPP

View File

@@ -0,0 +1,90 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2014-2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DETAIL_EXCEPTION_DISPOSER_HPP
#define BOOST_INTRUSIVE_DETAIL_EXCEPTION_DISPOSER_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/intrusive/detail/workaround.hpp>
namespace boost {
namespace intrusive {
namespace detail {
template<class Container, class Disposer>
class exception_disposer
{
Container *cont_;
Disposer &disp_;
exception_disposer(const exception_disposer&);
exception_disposer &operator=(const exception_disposer&);
public:
exception_disposer(Container &cont, Disposer &disp)
: cont_(&cont), disp_(disp)
{}
BOOST_INTRUSIVE_FORCEINLINE void release()
{ cont_ = 0; }
~exception_disposer()
{
if(cont_){
cont_->clear_and_dispose(disp_);
}
}
};
template<class Container, class Disposer, class SizeType>
class exception_array_disposer
{
Container *cont_;
Disposer &disp_;
SizeType &constructed_;
exception_array_disposer(const exception_array_disposer&);
exception_array_disposer &operator=(const exception_array_disposer&);
public:
exception_array_disposer
(Container &cont, Disposer &disp, SizeType &constructed)
: cont_(&cont), disp_(disp), constructed_(constructed)
{}
BOOST_INTRUSIVE_FORCEINLINE void release()
{ cont_ = 0; }
~exception_array_disposer()
{
SizeType n = constructed_;
if(cont_){
while(n--){
cont_[n].clear_and_dispose(disp_);
}
}
}
};
} //namespace detail{
} //namespace intrusive{
} //namespace boost{
#endif //BOOST_INTRUSIVE_DETAIL_EXCEPTION_DISPOSER_HPP

View File

@@ -0,0 +1,92 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2009-2013.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
// This code was modified from the code posted by Alexandre Courpron in his
// article "Interface Detection" in The Code Project:
// http://www.codeproject.com/KB/architecture/Detector.aspx
///////////////////////////////////////////////////////////////////////////////
// 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
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
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
#endif //@ifndef BOOST_INTRUSIVE_DETAIL_FUNCTION_DETECTOR_HPP

View File

@@ -0,0 +1,223 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2013
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_GENERIC_HOOK_HPP
#define BOOST_INTRUSIVE_GENERIC_HOOK_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/link_mode.hpp>
#include <boost/intrusive/detail/mpl.hpp>
#include <boost/intrusive/detail/assert.hpp>
#include <boost/intrusive/detail/node_holder.hpp>
#include <boost/intrusive/detail/algo_type.hpp>
#include <boost/static_assert.hpp>
namespace boost {
namespace intrusive {
/// @cond
namespace detail {
template <link_mode_type LinkMode>
struct link_dispatch
{};
template<class Hook>
BOOST_INTRUSIVE_FORCEINLINE void destructor_impl(Hook &hook, detail::link_dispatch<safe_link>)
{ //If this assertion raises, you might have destroyed an object
//while it was still inserted in a container that is alive.
//If so, remove the object from the container before destroying it.
(void)hook; BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT(!hook.is_linked());
}
template<class Hook>
BOOST_INTRUSIVE_FORCEINLINE void destructor_impl(Hook &hook, detail::link_dispatch<auto_unlink>)
{ hook.unlink(); }
template<class Hook>
BOOST_INTRUSIVE_FORCEINLINE void destructor_impl(Hook &, detail::link_dispatch<normal_link>)
{}
} //namespace detail {
enum base_hook_type
{ NoBaseHookId
, ListBaseHookId
, SlistBaseHookId
, RbTreeBaseHookId
, HashBaseHookId
, AvlTreeBaseHookId
, BsTreeBaseHookId
, TreapTreeBaseHookId
, AnyBaseHookId
};
template <class HookTags, unsigned int>
struct hook_tags_definer{};
template <class HookTags>
struct hook_tags_definer<HookTags, ListBaseHookId>
{ typedef HookTags default_list_hook; };
template <class HookTags>
struct hook_tags_definer<HookTags, SlistBaseHookId>
{ typedef HookTags default_slist_hook; };
template <class HookTags>
struct hook_tags_definer<HookTags, RbTreeBaseHookId>
{ typedef HookTags default_rbtree_hook; };
template <class HookTags>
struct hook_tags_definer<HookTags, HashBaseHookId>
{ typedef HookTags default_hashtable_hook; };
template <class HookTags>
struct hook_tags_definer<HookTags, AvlTreeBaseHookId>
{ typedef HookTags default_avltree_hook; };
template <class HookTags>
struct hook_tags_definer<HookTags, BsTreeBaseHookId>
{ typedef HookTags default_bstree_hook; };
template <class HookTags>
struct hook_tags_definer<HookTags, AnyBaseHookId>
{ typedef HookTags default_any_hook; };
template
< class NodeTraits
, class Tag
, link_mode_type LinkMode
, base_hook_type BaseHookType
>
struct hooktags_impl
{
static const link_mode_type link_mode = LinkMode;
typedef Tag tag;
typedef NodeTraits node_traits;
static const bool is_base_hook = !detail::is_same<Tag, member_tag>::value;
static const bool safemode_or_autounlink = is_safe_autounlink<link_mode>::value;
static const unsigned int type = BaseHookType;
};
/// @endcond
template
< boost::intrusive::algo_types Algo
, class NodeTraits
, class Tag
, link_mode_type LinkMode
, base_hook_type BaseHookType
>
class generic_hook
/// @cond
//If the hook is a base hook, derive generic hook from node_holder
//so that a unique base class is created to convert from the node
//to the type. This mechanism will be used by bhtraits.
//
//If the hook is a member hook, generic hook will directly derive
//from the hook.
: public detail::if_c
< detail::is_same<Tag, member_tag>::value
, typename NodeTraits::node
, node_holder<typename NodeTraits::node, Tag, BaseHookType>
>::type
//If this is the a default-tagged base hook derive from a class that
//will define an special internal typedef. Containers will be able to detect this
//special typedef and obtain generic_hook's internal types in order to deduce
//value_traits for this hook.
, public hook_tags_definer
< generic_hook<Algo, NodeTraits, Tag, LinkMode, BaseHookType>
, detail::is_same<Tag, dft_tag>::value ? BaseHookType : NoBaseHookId>
/// @endcond
{
/// @cond
typedef typename get_algo<Algo, NodeTraits>::type node_algorithms;
typedef typename node_algorithms::node node;
typedef typename node_algorithms::node_ptr node_ptr;
typedef typename node_algorithms::const_node_ptr const_node_ptr;
public:
typedef hooktags_impl
< NodeTraits
, Tag, LinkMode, BaseHookType> hooktags;
BOOST_INTRUSIVE_FORCEINLINE node_ptr this_ptr() BOOST_NOEXCEPT
{ return pointer_traits<node_ptr>::pointer_to(static_cast<node&>(*this)); }
BOOST_INTRUSIVE_FORCEINLINE const_node_ptr this_ptr() const BOOST_NOEXCEPT
{ return pointer_traits<const_node_ptr>::pointer_to(static_cast<const node&>(*this)); }
public:
/// @endcond
BOOST_INTRUSIVE_FORCEINLINE generic_hook() BOOST_NOEXCEPT
{
if(hooktags::safemode_or_autounlink){
node_algorithms::init(this->this_ptr());
}
}
BOOST_INTRUSIVE_FORCEINLINE generic_hook(const generic_hook& ) BOOST_NOEXCEPT
{
if(hooktags::safemode_or_autounlink){
node_algorithms::init(this->this_ptr());
}
}
BOOST_INTRUSIVE_FORCEINLINE generic_hook& operator=(const generic_hook& ) BOOST_NOEXCEPT
{ return *this; }
BOOST_INTRUSIVE_FORCEINLINE ~generic_hook()
{
destructor_impl
(*this, detail::link_dispatch<hooktags::link_mode>());
}
BOOST_INTRUSIVE_FORCEINLINE void swap_nodes(generic_hook &other) BOOST_NOEXCEPT
{
node_algorithms::swap_nodes
(this->this_ptr(), other.this_ptr());
}
BOOST_INTRUSIVE_FORCEINLINE bool is_linked() const BOOST_NOEXCEPT
{
//is_linked() can be only used in safe-mode or auto-unlink
BOOST_STATIC_ASSERT(( hooktags::safemode_or_autounlink ));
return !node_algorithms::unique(this->this_ptr());
}
BOOST_INTRUSIVE_FORCEINLINE void unlink() BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT(( (int)hooktags::link_mode == (int)auto_unlink ));
node_ptr n(this->this_ptr());
if(!node_algorithms::inited(n)){
node_algorithms::unlink(n);
node_algorithms::init(n);
}
}
};
} //namespace intrusive
} //namespace boost
#endif //BOOST_INTRUSIVE_GENERIC_HOOK_HPP

View File

@@ -0,0 +1,222 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2014-2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DETAIL_GET_VALUE_TRAITS_HPP
#define BOOST_INTRUSIVE_DETAIL_GET_VALUE_TRAITS_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/detail/mpl.hpp>
#include <boost/intrusive/detail/hook_traits.hpp>
namespace boost {
namespace intrusive {
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
template<class SupposedValueTraits>
struct is_default_hook_tag
{ static const bool value = false; };
namespace detail{
template <class T, class BaseHook>
struct concrete_hook_base_value_traits
{
typedef typename BaseHook::hooktags tags;
typedef bhtraits
< T
, typename tags::node_traits
, tags::link_mode
, typename tags::tag
, tags::type> type;
};
template <class BaseHook>
struct concrete_hook_base_value_traits<void, BaseHook>
{
typedef typename BaseHook::hooktags type;
};
template <class T, class AnyToSomeHook_ProtoValueTraits>
struct any_hook_base_value_traits
{
//AnyToSomeHook value_traits derive from a generic_hook
//The generic_hook is configured with any_node_traits
//and AnyToSomeHook::value_traits with the correct
//node traits for the container, so use node_traits
//from AnyToSomeHook_ProtoValueTraits and the rest of
//elements from the hooktags member of the generic_hook
typedef typename AnyToSomeHook_ProtoValueTraits::basic_hook_t basic_hook_t;
typedef typename pointer_rebind
< typename basic_hook_t::hooktags::node_traits::node_ptr
, void>::type void_pointer;
typedef typename AnyToSomeHook_ProtoValueTraits::template
node_traits_from_voidptr<void_pointer>::type node_traits;
typedef bhtraits
< T
, node_traits
, basic_hook_t::hooktags::link_mode
, typename basic_hook_t::hooktags::tag
, basic_hook_t::hooktags::type
> type;
};
template <class AnyToSomeHook_ProtoValueTraits>
struct any_hook_base_value_traits<void, AnyToSomeHook_ProtoValueTraits>
{
typedef typename AnyToSomeHook_ProtoValueTraits::basic_hook_t basic_hook_t;
typedef typename pointer_rebind
< typename basic_hook_t::hooktags::node_traits::node_ptr
, void>::type void_pointer;
struct type
{
typedef typename AnyToSomeHook_ProtoValueTraits::template
node_traits_from_voidptr<void_pointer>::type node_traits;
};
};
template<class MemberHook>
struct get_member_value_traits
{
typedef typename MemberHook::member_value_traits type;
};
BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(internal_any_hook, is_any_hook)
BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(internal_base_hook, hooktags::is_base_hook)
template <class T>
struct internal_member_value_traits
{
template <class U> static yes_type test(...);
template <class U> static no_type test(typename U::member_value_traits* = 0);
static const bool value = sizeof(test<T>(0)) == sizeof(no_type);
};
template<class SupposedValueTraits, class T, bool = is_default_hook_tag<SupposedValueTraits>::value>
struct supposed_value_traits;
template<class T, class BaseHook, bool = internal_any_hook_bool_is_true<BaseHook>::value>
struct get_base_value_traits;
template<class SupposedValueTraits, class T, bool = internal_base_hook_bool_is_true<SupposedValueTraits>::value>
struct supposed_base_value_traits;
template<class SupposedValueTraits, bool = internal_member_value_traits<SupposedValueTraits>::value>
struct supposed_member_value_traits;
template<class SupposedValueTraits, bool = internal_any_hook_bool_is_true<SupposedValueTraits>::value>
struct any_or_concrete_value_traits;
//Base any hook
template<class T, class BaseHook>
struct get_base_value_traits<T, BaseHook, true>
: any_hook_base_value_traits<T, BaseHook>
{};
//Non-any base hook
template<class T, class BaseHook>
struct get_base_value_traits<T, BaseHook, false>
: concrete_hook_base_value_traits<T, BaseHook>
{};
//...It's a default hook
template<class SupposedValueTraits, class T>
struct supposed_value_traits<SupposedValueTraits, T, true>
{ typedef typename SupposedValueTraits::template apply<T>::type type; };
//...Not a default hook
template<class SupposedValueTraits, class T>
struct supposed_value_traits<SupposedValueTraits, T, false>
{ typedef SupposedValueTraits type; };
//...It's a base hook
template<class BaseHook, class T>
struct supposed_base_value_traits<BaseHook, T, true>
: get_base_value_traits<T, BaseHook>
{};
//...Not a base hook, try if it's a member or value_traits
template<class SupposedValueTraits, class T>
struct supposed_base_value_traits<SupposedValueTraits, T, false>
: supposed_member_value_traits<SupposedValueTraits>
{};
//...It's a member hook
template<class MemberHook>
struct supposed_member_value_traits<MemberHook, true>
: get_member_value_traits<MemberHook>
{};
//...Not a member hook
template<class SupposedValueTraits>
struct supposed_member_value_traits<SupposedValueTraits, false>
: any_or_concrete_value_traits<SupposedValueTraits>
{};
template<class AnyToSomeHook_ProtoValueTraits>
struct any_or_concrete_value_traits<AnyToSomeHook_ProtoValueTraits, true>
{
//A hook node (non-base, e.g.: member or other value traits
typedef typename AnyToSomeHook_ProtoValueTraits::basic_hook_t basic_hook_t;
typedef typename pointer_rebind
<typename basic_hook_t::node_ptr, void>::type void_pointer;
typedef typename AnyToSomeHook_ProtoValueTraits::template
node_traits_from_voidptr<void_pointer>::type any_node_traits;
struct type : basic_hook_t
{
typedef any_node_traits node_traits;
};
};
template<class SupposedValueTraits>
struct any_or_concrete_value_traits<SupposedValueTraits, false>
{
typedef SupposedValueTraits type;
};
////////////////////////////////////////
// get_value_traits / get_node_traits
////////////////////////////////////////
template<class T, class SupposedValueTraits>
struct get_value_traits
: supposed_base_value_traits<typename supposed_value_traits<SupposedValueTraits, T>::type, T>
{};
template<class SupposedValueTraits>
struct get_node_traits
{
typedef typename get_value_traits<void, SupposedValueTraits>::type::node_traits type;
};
} //namespace detail{
#endif //BOOST_INTRUSIVE_DOXYGEN_INVOKED
} //namespace intrusive {
} //namespace boost {
#include <boost/intrusive/detail/config_end.hpp>
#endif //#ifndef BOOST_INTRUSIVE_DETAIL_GET_VALUE_TRAITS_HPP

View File

@@ -0,0 +1,366 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2014-2014. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_CALLABLE_WITH_HPP
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_CALLABLE_WITH_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
//In case no decltype and no variadics, mark that we don't support 0 arg calls due to
//compiler ICE in GCC 3.4/4.0/4.1 and, wrong SFINAE for GCC 4.2/4.3/MSVC10/MSVC11
#if defined(BOOST_NO_CXX11_DECLTYPE) && defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
# if defined(BOOST_GCC) && (BOOST_GCC < 40400)
# define BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED
# elif defined(BOOST_INTEL) && (BOOST_INTEL < 1200)
# define BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED
# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1800)
# define BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED
# endif
#endif //#if defined(BOOST_NO_CXX11_DECLTYPE) && defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <cstddef>
#include <boost/move/utility_core.hpp>
#include <boost/move/detail/fwd_macros.hpp>
namespace boost_intrusive_hmfcw {
typedef char yes_type;
struct no_type{ char dummy[2]; };
struct dont_care
{
dont_care(...);
};
#if defined(BOOST_NO_CXX11_DECLTYPE)
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class T>
struct make_dontcare
{
typedef dont_care type;
};
#endif
struct private_type
{
static private_type p;
private_type const &operator,(int) const;
};
template<typename T>
no_type is_private_type(T const &);
yes_type is_private_type(private_type const &);
#endif //#if defined(BOOST_NO_CXX11_DECLTYPE)
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_DECLTYPE)
template<typename T> struct remove_cv { typedef T type; };
template<typename T> struct remove_cv<const T> { typedef T type; };
template<typename T> struct remove_cv<const volatile T> { typedef T type; };
template<typename T> struct remove_cv<volatile T> { typedef T type; };
#endif
} //namespace boost_intrusive_hmfcw {
#endif //BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_CALLABLE_WITH_HPP
#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME
#error "You MUST define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME before including this header!"
#endif
#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN
#error "You MUST define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN before including this header!"
#endif
#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX
#error "You MUST define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX before including this header!"
#endif
#if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX < BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN
#error "BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX value MUST be greater or equal than BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN!"
#endif
#if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX == 0
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF
#else
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF ,
#endif
#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG
#error "BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG not defined!"
#endif
#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END
#error "BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END not defined!"
#endif
BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_DECLTYPE)
//With decltype and variadic templaes, things are pretty easy
template<typename Fun, class ...Args>
struct BOOST_MOVE_CAT(has_member_function_callable_with_,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
{
template<class U>
static decltype(boost::move_detail::declval<U>().
BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(::boost::move_detail::declval<Args>()...)
, boost_intrusive_hmfcw::yes_type()) Test(U* f);
template<class U>
static boost_intrusive_hmfcw::no_type Test(...);
static const bool value = sizeof(Test<Fun>((Fun*)0)) == sizeof(boost_intrusive_hmfcw::yes_type);
};
#else //defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_DECLTYPE)
/////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
//
// has_member_function_callable_with_impl_XXX
// declaration, special case and 0 arg specializaton
//
/////////////////////////////////////////////////////////
template <typename Type>
class BOOST_MOVE_CAT(has_member_function_named_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
{
struct BaseMixin
{
void BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME()
{} //Some compilers require the definition or linker errors happen
};
struct Base
: public boost_intrusive_hmfcw::remove_cv<Type>::type, public BaseMixin
{ //Declare the unneeded default constructor as some old compilers wrongly require it with is_convertible
Base(){}
};
template <typename T, T t> class Helper{};
template <typename U>
static boost_intrusive_hmfcw::no_type deduce
(U*, Helper<void (BaseMixin::*)(), &U::BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME>* = 0);
static boost_intrusive_hmfcw::yes_type deduce(...);
public:
static const bool value = sizeof(boost_intrusive_hmfcw::yes_type) == sizeof(deduce((Base*)0));
};
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
/////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
//
// has_member_function_callable_with_impl_XXX for 1 to N arguments
//
/////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
//defined(BOOST_NO_CXX11_DECLTYPE) must be true
template<class Fun>
struct FunWrapTmpl : Fun
{
using Fun::BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME;
FunWrapTmpl();
template<class ...DontCares>
boost_intrusive_hmfcw::private_type BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(DontCares...) const;
};
template<typename Fun, bool HasFunc, class ...Args>
struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME);
//No BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME member specialization
template<typename Fun, class ...Args>
struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
<Fun, false, Args...>
{
static const bool value = false;
};
template<typename Fun, class ...Args>
struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<Fun, true, Args...>
{
static bool const value = (sizeof(boost_intrusive_hmfcw::no_type) == sizeof(boost_intrusive_hmfcw::is_private_type
( (::boost::move_detail::declval
< FunWrapTmpl<Fun> >().
BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(::boost::move_detail::declval<Args>()...), 0) )
)
);
};
template<typename Fun, class ...Args>
struct BOOST_MOVE_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
: public BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
<Fun
, BOOST_MOVE_CAT(has_member_function_named_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<Fun>::value
, Args...>
{};
#else //defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
/////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
//
// has_member_function_callable_with_impl_XXX specializations
//
/////////////////////////////////////////////////////////
template<typename Fun, bool HasFunc BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF BOOST_MOVE_CAT(BOOST_MOVE_CLASSDFLT,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX)>
struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME);
//No BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME member specialization
template<typename Fun BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF BOOST_MOVE_CAT(BOOST_MOVE_CLASS,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX)>
struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
<Fun, false BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF BOOST_MOVE_CAT(BOOST_MOVE_TARG,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX)>
{
static const bool value = false;
};
#if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN == 0
//0 arg specialization when BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME is present
#if !defined(BOOST_NO_CXX11_DECLTYPE)
template<typename Fun>
struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<Fun, true>
{
template<class U>
static decltype(boost::move_detail::declval<U>().BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME()
, boost_intrusive_hmfcw::yes_type()) Test(U* f);
template<class U>
static boost_intrusive_hmfcw::no_type Test(...);
static const bool value = sizeof(Test<Fun>((Fun*)0)) == sizeof(boost_intrusive_hmfcw::yes_type);
};
#else //defined(BOOST_NO_CXX11_DECLTYPE)
#if !defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED)
template<class F, std::size_t N = sizeof(boost::move_detail::declval<F>().BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(), 0)>
struct BOOST_MOVE_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
{ boost_intrusive_hmfcw::yes_type dummy[N ? 1 : 2]; };
template<typename Fun>
struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<Fun, true>
{
template<class U> static BOOST_MOVE_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<U>
Test(BOOST_MOVE_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<U>*);
template<class U> static boost_intrusive_hmfcw::no_type Test(...);
static const bool value = sizeof(Test< Fun >(0)) == sizeof(boost_intrusive_hmfcw::yes_type);
};
#else //defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED)
template<typename Fun>
struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<Fun, true>
{ //Some compilers gives ICE when instantiating the 0 arg version so it is not supported.
static const bool value = true;
};
#endif//!defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED)
#endif //!defined(BOOST_NO_CXX11_DECLTYPE)
#endif //#if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN == 0
#if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX > 0
//1 to N arg specialization when BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME is present
//Declare some unneeded default constructor as some old compilers wrongly require it with is_convertible
#if defined(BOOST_NO_CXX11_DECLTYPE)
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATION(N)\
\
template<class Fun>\
struct BOOST_MOVE_CAT(FunWrap##N, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)\
: Fun\
{\
using Fun::BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME;\
BOOST_MOVE_CAT(FunWrap##N, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)();\
boost_intrusive_hmfcw::private_type BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME\
(BOOST_MOVE_REPEAT##N(boost_intrusive_hmfcw::dont_care)) const;\
};\
\
template<typename Fun, BOOST_MOVE_CLASS##N>\
struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<Fun, true, BOOST_MOVE_TARG##N>\
{\
static bool const value = (sizeof(boost_intrusive_hmfcw::no_type) == sizeof(boost_intrusive_hmfcw::is_private_type\
( (::boost::move_detail::declval\
< BOOST_MOVE_CAT(FunWrap##N, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<Fun> >().\
BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(BOOST_MOVE_DECLVAL##N), 0) )\
)\
);\
};\
//
#else
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATION(N)\
template<typename Fun, BOOST_MOVE_CLASS##N>\
struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)\
<Fun, true, BOOST_MOVE_TARG##N>\
{\
template<class U>\
static decltype(boost::move_detail::declval<U>().\
BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(BOOST_MOVE_DECLVAL##N)\
, boost_intrusive_hmfcw::yes_type()) Test(U* f);\
template<class U>\
static boost_intrusive_hmfcw::no_type Test(...);\
static const bool value = sizeof(Test<Fun>((Fun*)0)) == sizeof(boost_intrusive_hmfcw::yes_type);\
};\
//
#endif
////////////////////////////////////
// Build and invoke BOOST_MOVE_ITERATE_NTOM macrofunction, note that N has to be at least 1
////////////////////////////////////
#if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN == 0
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATE_MIN 1
#else
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATE_MIN BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN
#endif
BOOST_MOVE_CAT
(BOOST_MOVE_CAT(BOOST_MOVE_CAT(BOOST_MOVE_ITERATE_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATE_MIN), TO)
,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX)
(BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATION)
#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATION
#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATE_MIN
////////////////////////////////////
// End of BOOST_MOVE_ITERATE_NTOM
////////////////////////////////////
#endif //BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX > 0
/////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
//
// has_member_function_callable_with_FUNC
//
/////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
//Otherwise use the preprocessor
template<typename Fun BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF BOOST_MOVE_CAT(BOOST_MOVE_CLASSDFLT,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX)>
struct BOOST_MOVE_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
: public BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
<Fun
, BOOST_MOVE_CAT(has_member_function_named_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<Fun>::value
BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF BOOST_MOVE_CAT(BOOST_MOVE_TARG,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX)>
{};
#endif //defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#endif
BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END
//Undef local macros
#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF
//Undef user defined macros
#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME
#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN
#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX
#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG
#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END

View File

@@ -0,0 +1,92 @@
// Copyright 2005-2014 Daniel James.
// 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)
//
// Based on Peter Dimov's proposal
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
// issue 6.18.
//
// This also contains public domain code from MurmurHash. From the
// MurmurHash header:
//
// MurmurHash3 was written by Austin Appleby, and is placed in the public
// domain. The author hereby disclaims copyright to this source code.
//
// Copyright 2021 Ion Gaztanaga
// Refactored the original boost/container_hash/hash.hpp to avoid
// any heavy std header dependencies to just combine two hash
// values represented in a std::size_t type.
#ifndef BOOST_INTRUSIVE_DETAIL_HASH_COMBINE_HPP
#define BOOST_INTRUSIVE_DETAIL_HASH_COMBINE_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/cstdint.hpp>
#if defined(_MSC_VER)
# include <stdlib.h>
# define BOOST_INTRUSIVE_HASH_ROTL32(x, r) _rotl(x,r)
#else
# define BOOST_INTRUSIVE_HASH_ROTL32(x, r) (x << r) | (x >> (32 - r))
#endif
namespace boost {
namespace intrusive {
namespace detail {
template <typename SizeT>
inline void hash_combine_size_t(SizeT& seed, SizeT value)
{
seed ^= value + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
inline void hash_combine_size_t(boost::uint32_t& h1, boost::uint32_t k1)
{
const uint32_t c1 = 0xcc9e2d51;
const uint32_t c2 = 0x1b873593;
k1 *= c1;
k1 = BOOST_INTRUSIVE_HASH_ROTL32(k1,15);
k1 *= c2;
h1 ^= k1;
h1 = BOOST_INTRUSIVE_HASH_ROTL32(h1,13);
h1 = h1*5+0xe6546b64;
}
// Don't define 64-bit hash combine on platforms without 64 bit integers,
// and also not for 32-bit gcc as it warns about the 64-bit constant.
#if !defined(BOOST_NO_INT64_T) && \
!(defined(__GNUC__) && ULONG_MAX == 0xffffffff)
inline void hash_combine_size_t(boost::uint64_t& h, boost::uint64_t k)
{
const boost::uint64_t m = UINT64_C(0xc6a4a7935bd1e995);
const int r = 47;
k *= m;
k ^= k >> r;
k *= m;
h ^= k;
h *= m;
// Completely arbitrary number, to prevent 0's
// from hashing to 0.
h += 0xe6546b64;
}
#endif // BOOST_NO_INT64_T
} //namespace detail {
} //namespace intrusive {
} //namespace boost {
#endif //BOOST_INTRUSIVE_DETAIL_HASH_COMBINE_HPP

View File

@@ -0,0 +1,295 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_HASHTABLE_NODE_HPP
#define BOOST_INTRUSIVE_HASHTABLE_NODE_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/intrusive/detail/workaround.hpp>
#include <boost/intrusive/detail/assert.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/detail/mpl.hpp>
#include <boost/intrusive/trivial_value_traits.hpp>
#include <boost/intrusive/slist.hpp> //make_slist
#include <cstddef>
#include <climits>
#include <boost/move/core.hpp>
namespace boost {
namespace intrusive {
template <class Slist>
struct bucket_impl : public Slist
{
typedef Slist slist_type;
BOOST_INTRUSIVE_FORCEINLINE bucket_impl()
{}
BOOST_INTRUSIVE_FORCEINLINE bucket_impl(const bucket_impl &)
{}
BOOST_INTRUSIVE_FORCEINLINE ~bucket_impl()
{
//This bucket is still being used!
BOOST_INTRUSIVE_INVARIANT_ASSERT(Slist::empty());
}
BOOST_INTRUSIVE_FORCEINLINE bucket_impl &operator=(const bucket_impl&)
{
//This bucket is still in use!
BOOST_INTRUSIVE_INVARIANT_ASSERT(Slist::empty());
return *this;
}
};
template<class Slist>
struct bucket_traits_impl
{
private:
BOOST_COPYABLE_AND_MOVABLE(bucket_traits_impl)
public:
/// @cond
typedef typename pointer_traits
<typename Slist::pointer>::template rebind_pointer
< bucket_impl<Slist> >::type bucket_ptr;
typedef Slist slist;
typedef typename Slist::size_type size_type;
/// @endcond
BOOST_INTRUSIVE_FORCEINLINE bucket_traits_impl(bucket_ptr buckets, size_type len)
: buckets_(buckets), buckets_len_(len)
{}
BOOST_INTRUSIVE_FORCEINLINE bucket_traits_impl(const bucket_traits_impl &x)
: buckets_(x.buckets_), buckets_len_(x.buckets_len_)
{}
BOOST_INTRUSIVE_FORCEINLINE bucket_traits_impl(BOOST_RV_REF(bucket_traits_impl) x)
: buckets_(x.buckets_), buckets_len_(x.buckets_len_)
{ x.buckets_ = bucket_ptr(); x.buckets_len_ = 0; }
BOOST_INTRUSIVE_FORCEINLINE bucket_traits_impl& operator=(BOOST_RV_REF(bucket_traits_impl) x)
{
buckets_ = x.buckets_; buckets_len_ = x.buckets_len_;
x.buckets_ = bucket_ptr(); x.buckets_len_ = 0; return *this;
}
BOOST_INTRUSIVE_FORCEINLINE bucket_traits_impl& operator=(BOOST_COPY_ASSIGN_REF(bucket_traits_impl) x)
{
buckets_ = x.buckets_; buckets_len_ = x.buckets_len_; return *this;
}
BOOST_INTRUSIVE_FORCEINLINE bucket_ptr bucket_begin() const
{ return buckets_; }
BOOST_INTRUSIVE_FORCEINLINE size_type bucket_count() const BOOST_NOEXCEPT
{ return buckets_len_; }
private:
bucket_ptr buckets_;
size_type buckets_len_;
};
template <class NodeTraits>
struct hash_reduced_slist_node_traits
{
template <class U> static detail::no_type test(...);
template <class U> static detail::yes_type test(typename U::reduced_slist_node_traits*);
static const bool value = sizeof(test<NodeTraits>(0)) == sizeof(detail::yes_type);
};
template <class NodeTraits>
struct apply_reduced_slist_node_traits
{
typedef typename NodeTraits::reduced_slist_node_traits type;
};
template <class NodeTraits>
struct reduced_slist_node_traits
{
typedef typename detail::eval_if_c
< hash_reduced_slist_node_traits<NodeTraits>::value
, apply_reduced_slist_node_traits<NodeTraits>
, detail::identity<NodeTraits>
>::type type;
};
template<class NodeTraits>
struct get_slist_impl
{
typedef trivial_value_traits<NodeTraits, normal_link> trivial_traits;
//Reducing symbol length
struct type : make_slist
< typename NodeTraits::node
, boost::intrusive::value_traits<trivial_traits>
, boost::intrusive::constant_time_size<false>
, boost::intrusive::size_type<std::size_t>
>::type
{};
};
template<class BucketValueTraits, bool IsConst>
class hashtable_iterator
{
typedef typename BucketValueTraits::value_traits value_traits;
typedef typename BucketValueTraits::bucket_traits bucket_traits;
typedef iiterator< value_traits, IsConst
, std::forward_iterator_tag> types_t;
public:
typedef typename types_t::iterator_type::difference_type difference_type;
typedef typename types_t::iterator_type::value_type value_type;
typedef typename types_t::iterator_type::pointer pointer;
typedef typename types_t::iterator_type::reference reference;
typedef typename types_t::iterator_type::iterator_category iterator_category;
private:
typedef typename value_traits::node_traits node_traits;
typedef typename node_traits::node_ptr node_ptr;
typedef typename get_slist_impl
< typename reduced_slist_node_traits
<node_traits>::type >::type slist_impl;
typedef typename slist_impl::iterator siterator;
typedef typename slist_impl::const_iterator const_siterator;
typedef bucket_impl<slist_impl> bucket_type;
typedef typename pointer_traits
<pointer>::template rebind_pointer
< const BucketValueTraits >::type const_bucketvaltraits_ptr;
typedef typename slist_impl::size_type size_type;
class nat;
typedef typename
detail::if_c< IsConst
, hashtable_iterator<BucketValueTraits, false>
, nat>::type nonconst_iterator;
BOOST_INTRUSIVE_FORCEINLINE static node_ptr downcast_bucket(typename bucket_type::node_ptr p)
{
return pointer_traits<node_ptr>::
pointer_to(static_cast<typename node_traits::node&>(*p));
}
public:
BOOST_INTRUSIVE_FORCEINLINE hashtable_iterator ()
: slist_it_() //Value initialization to achieve "null iterators" (N3644)
{}
BOOST_INTRUSIVE_FORCEINLINE explicit hashtable_iterator(siterator ptr, const BucketValueTraits *cont)
: slist_it_ (ptr)
, traitsptr_ (cont ? pointer_traits<const_bucketvaltraits_ptr>::pointer_to(*cont) : const_bucketvaltraits_ptr() )
{}
BOOST_INTRUSIVE_FORCEINLINE hashtable_iterator(const hashtable_iterator &other)
: slist_it_(other.slist_it()), traitsptr_(other.get_bucket_value_traits())
{}
BOOST_INTRUSIVE_FORCEINLINE hashtable_iterator(const nonconst_iterator &other)
: slist_it_(other.slist_it()), traitsptr_(other.get_bucket_value_traits())
{}
BOOST_INTRUSIVE_FORCEINLINE const siterator &slist_it() const
{ return slist_it_; }
BOOST_INTRUSIVE_FORCEINLINE hashtable_iterator<BucketValueTraits, false> unconst() const
{ return hashtable_iterator<BucketValueTraits, false>(this->slist_it(), this->get_bucket_value_traits()); }
BOOST_INTRUSIVE_FORCEINLINE hashtable_iterator& operator++()
{ this->increment(); return *this; }
BOOST_INTRUSIVE_FORCEINLINE hashtable_iterator &operator=(const hashtable_iterator &other)
{ slist_it_ = other.slist_it(); traitsptr_ = other.get_bucket_value_traits(); return *this; }
BOOST_INTRUSIVE_FORCEINLINE hashtable_iterator operator++(int)
{
hashtable_iterator result (*this);
this->increment();
return result;
}
BOOST_INTRUSIVE_FORCEINLINE friend bool operator== (const hashtable_iterator& i, const hashtable_iterator& i2)
{ return i.slist_it_ == i2.slist_it_; }
BOOST_INTRUSIVE_FORCEINLINE friend bool operator!= (const hashtable_iterator& i, const hashtable_iterator& i2)
{ return !(i == i2); }
BOOST_INTRUSIVE_FORCEINLINE reference operator*() const
{ return *this->operator ->(); }
BOOST_INTRUSIVE_FORCEINLINE pointer operator->() const
{
return this->priv_value_traits().to_value_ptr
(downcast_bucket(slist_it_.pointed_node()));
}
BOOST_INTRUSIVE_FORCEINLINE const_bucketvaltraits_ptr get_bucket_value_traits() const
{ return traitsptr_; }
BOOST_INTRUSIVE_FORCEINLINE const value_traits &priv_value_traits() const
{ return traitsptr_->priv_value_traits(); }
BOOST_INTRUSIVE_FORCEINLINE const bucket_traits &priv_bucket_traits() const
{ return traitsptr_->priv_bucket_traits(); }
private:
void increment()
{
const bucket_traits &rbuck_traits = this->priv_bucket_traits();
bucket_type* const buckets = boost::movelib::to_raw_pointer(rbuck_traits.bucket_begin());
const size_type buckets_len = rbuck_traits.bucket_count();
++slist_it_;
const typename slist_impl::node_ptr n = slist_it_.pointed_node();
const siterator first_bucket_bbegin = buckets->end();
if(first_bucket_bbegin.pointed_node() <= n && n <= buckets[buckets_len-1].cend().pointed_node()){
//If one-past the node is inside the bucket then look for the next non-empty bucket
//1. get the bucket_impl from the iterator
const bucket_type &b = static_cast<const bucket_type&>
(bucket_type::slist_type::container_from_end_iterator(slist_it_));
//2. Now just calculate the index b has in the bucket array
size_type n_bucket = static_cast<size_type>(&b - buckets);
//3. Iterate until a non-empty bucket is found
do{
if (++n_bucket >= buckets_len){ //bucket overflow, return end() iterator
slist_it_ = buckets->before_begin();
return;
}
}
while (buckets[n_bucket].empty());
slist_it_ = buckets[n_bucket].begin();
}
else{
//++slist_it_ yield to a valid object
}
}
siterator slist_it_;
const_bucketvaltraits_ptr traitsptr_;
};
} //namespace intrusive {
} //namespace boost {
#endif

View File

@@ -0,0 +1,195 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DETAIL_HOOK_TRAITS_HPP
#define BOOST_INTRUSIVE_DETAIL_HOOK_TRAITS_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/intrusive/detail/workaround.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/detail/parent_from_member.hpp>
#include <boost/intrusive/link_mode.hpp>
#include <boost/intrusive/detail/mpl.hpp>
#include <boost/move/detail/to_raw_pointer.hpp>
#include <boost/intrusive/detail/node_holder.hpp>
namespace boost {
namespace intrusive {
template<class T, class NodePtr, class Tag, unsigned int Type>
struct bhtraits_base
{
public:
typedef NodePtr node_ptr;
typedef typename pointer_traits<node_ptr>::element_type node;
typedef node_holder<node, Tag, Type> node_holder_type;
typedef T value_type;
typedef typename pointer_traits<node_ptr>::
template rebind_pointer<const node>::type const_node_ptr;
typedef typename pointer_traits<node_ptr>::
template rebind_pointer<T>::type pointer;
typedef typename pointer_traits<node_ptr>::
template rebind_pointer<const T>::type const_pointer;
//typedef typename pointer_traits<pointer>::reference reference;
//typedef typename pointer_traits<const_pointer>::reference const_reference;
typedef T & reference;
typedef const T & const_reference;
typedef node_holder_type & node_holder_reference;
typedef const node_holder_type & const_node_holder_reference;
typedef node& node_reference;
typedef const node & const_node_reference;
BOOST_INTRUSIVE_FORCEINLINE static pointer to_value_ptr(node_ptr n)
{
pointer p = pointer_traits<pointer>::pointer_to
(static_cast<reference>(static_cast<node_holder_reference>(*n)));
BOOST_ASSERT(!!p);
return p;
}
BOOST_INTRUSIVE_FORCEINLINE static const_pointer to_value_ptr(const_node_ptr n)
{
const_pointer p = pointer_traits<const_pointer>::pointer_to
(static_cast<const_reference>(static_cast<const_node_holder_reference>(*n)));
BOOST_ASSERT(!!p);
return p;
}
BOOST_INTRUSIVE_FORCEINLINE static node_ptr to_node_ptr(reference value)
{
node_ptr p = pointer_traits<node_ptr>::pointer_to
(static_cast<node_reference>(static_cast<node_holder_reference>(value)));
BOOST_ASSERT(!!p);
return p;
}
BOOST_INTRUSIVE_FORCEINLINE static const_node_ptr to_node_ptr(const_reference value)
{
const_node_ptr p = pointer_traits<const_node_ptr>::pointer_to
(static_cast<const_node_reference>(static_cast<const_node_holder_reference>(value)));
BOOST_ASSERT(!!p);
return p;
}
};
template<class T, class NodeTraits, link_mode_type LinkMode, class Tag, unsigned int Type>
struct bhtraits
: public bhtraits_base<T, typename NodeTraits::node_ptr, Tag, Type>
{
static const link_mode_type link_mode = LinkMode;
typedef NodeTraits node_traits;
};
template<class T, class Hook, Hook T::* P>
struct mhtraits
{
public:
typedef Hook hook_type;
typedef typename hook_type::hooktags::node_traits node_traits;
typedef typename node_traits::node node;
typedef T value_type;
typedef typename node_traits::node_ptr node_ptr;
typedef typename node_traits::const_node_ptr const_node_ptr;
typedef typename pointer_traits<node_ptr>::
template rebind_pointer<T>::type pointer;
typedef typename pointer_traits<node_ptr>::
template rebind_pointer<const T>::type const_pointer;
typedef T & reference;
typedef const T & const_reference;
typedef node& node_reference;
typedef const node & const_node_reference;
typedef hook_type& hook_reference;
typedef const hook_type & const_hook_reference;
static const link_mode_type link_mode = Hook::hooktags::link_mode;
BOOST_INTRUSIVE_FORCEINLINE static node_ptr to_node_ptr(reference value)
{
return pointer_traits<node_ptr>::pointer_to
(static_cast<node_reference>(static_cast<hook_reference>(value.*P)));
}
BOOST_INTRUSIVE_FORCEINLINE static const_node_ptr to_node_ptr(const_reference value)
{
return pointer_traits<const_node_ptr>::pointer_to
(static_cast<const_node_reference>(static_cast<const_hook_reference>(value.*P)));
}
BOOST_INTRUSIVE_FORCEINLINE static pointer to_value_ptr(node_ptr n)
{
return pointer_traits<pointer>::pointer_to
(*detail::parent_from_member<T, Hook>
(static_cast<Hook*>(boost::movelib::to_raw_pointer(n)), P));
}
BOOST_INTRUSIVE_FORCEINLINE static const_pointer to_value_ptr(const_node_ptr n)
{
return pointer_traits<const_pointer>::pointer_to
(*detail::parent_from_member<T, Hook>
(static_cast<const Hook*>(boost::movelib::to_raw_pointer(n)), P));
}
};
template<class Functor>
struct fhtraits
{
public:
typedef typename Functor::hook_type hook_type;
typedef typename Functor::hook_ptr hook_ptr;
typedef typename Functor::const_hook_ptr const_hook_ptr;
typedef typename hook_type::hooktags::node_traits node_traits;
typedef typename node_traits::node node;
typedef typename Functor::value_type value_type;
typedef typename node_traits::node_ptr node_ptr;
typedef typename node_traits::const_node_ptr const_node_ptr;
typedef typename pointer_traits<node_ptr>::
template rebind_pointer<value_type>::type pointer;
typedef typename pointer_traits<node_ptr>::
template rebind_pointer<const value_type>::type const_pointer;
typedef value_type & reference;
typedef const value_type & const_reference;
static const link_mode_type link_mode = hook_type::hooktags::link_mode;
static node_ptr to_node_ptr(reference value)
{ return static_cast<node*>(boost::movelib::to_raw_pointer(Functor::to_hook_ptr(value))); }
static const_node_ptr to_node_ptr(const_reference value)
{ return static_cast<const node*>(boost::movelib::to_raw_pointer(Functor::to_hook_ptr(value))); }
static pointer to_value_ptr(node_ptr n)
{ return Functor::to_value_ptr(to_hook_ptr(n)); }
static const_pointer to_value_ptr(const_node_ptr n)
{ return Functor::to_value_ptr(to_hook_ptr(n)); }
private:
static hook_ptr to_hook_ptr(node_ptr n)
{ return hook_ptr(&*static_cast<hook_type*>(&*n)); }
static const_hook_ptr to_hook_ptr(const_node_ptr n)
{ return const_hook_ptr(&*static_cast<const hook_type*>(&*n)); }
};
} //namespace intrusive
} //namespace boost
#endif //BOOST_INTRUSIVE_DETAIL_HOOK_TRAITS_HPP

View File

@@ -0,0 +1,122 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DETAIL_IITERATOR_HPP
#define BOOST_INTRUSIVE_DETAIL_IITERATOR_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/intrusive/detail/workaround.hpp>
#include <boost/intrusive/detail/iterator.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/detail/mpl.hpp>
#include <boost/intrusive/detail/is_stateful_value_traits.hpp>
namespace boost {
namespace intrusive {
template<class ValueTraits>
struct value_traits_pointers
{
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
(boost::intrusive::detail::
, ValueTraits, value_traits_ptr
, typename boost::intrusive::pointer_traits<typename ValueTraits::node_traits::node_ptr>::template
rebind_pointer<ValueTraits>::type) value_traits_ptr;
typedef typename boost::intrusive::pointer_traits<value_traits_ptr>::template
rebind_pointer<ValueTraits const>::type const_value_traits_ptr;
};
template<class ValueTraits, bool IsConst, class Category>
struct iiterator
{
typedef ValueTraits value_traits;
typedef typename value_traits::node_traits node_traits;
typedef typename node_traits::node node;
typedef typename node_traits::node_ptr node_ptr;
typedef ::boost::intrusive::pointer_traits<node_ptr> nodepointer_traits_t;
typedef typename nodepointer_traits_t::template
rebind_pointer<void>::type void_pointer;
typedef typename ValueTraits::value_type value_type;
typedef typename ValueTraits::pointer nonconst_pointer;
typedef typename ValueTraits::const_pointer yesconst_pointer;
typedef typename ::boost::intrusive::pointer_traits
<nonconst_pointer>::reference nonconst_reference;
typedef typename ::boost::intrusive::pointer_traits
<yesconst_pointer>::reference yesconst_reference;
typedef typename nodepointer_traits_t::difference_type difference_type;
typedef typename detail::if_c
<IsConst, yesconst_pointer, nonconst_pointer>::type pointer;
typedef typename detail::if_c
<IsConst, yesconst_reference, nonconst_reference>::type reference;
typedef iterator
< Category
, value_type
, difference_type
, pointer
, reference
> iterator_type;
typedef typename value_traits_pointers
<ValueTraits>::value_traits_ptr value_traits_ptr;
typedef typename value_traits_pointers
<ValueTraits>::const_value_traits_ptr const_value_traits_ptr;
static const bool stateful_value_traits =
detail::is_stateful_value_traits<value_traits>::value;
};
template<class NodePtr, class StoredPointer, bool StatefulValueTraits = true>
struct iiterator_members
{
BOOST_INTRUSIVE_FORCEINLINE iiterator_members()
: nodeptr_()//Value initialization to achieve "null iterators" (N3644)
{}
BOOST_INTRUSIVE_FORCEINLINE iiterator_members(const NodePtr &n_ptr, const StoredPointer &data)
: nodeptr_(n_ptr), ptr_(data)
{}
BOOST_INTRUSIVE_FORCEINLINE StoredPointer get_ptr() const
{ return ptr_; }
NodePtr nodeptr_;
StoredPointer ptr_;
};
template<class NodePtr, class StoredPointer>
struct iiterator_members<NodePtr, StoredPointer, false>
{
BOOST_INTRUSIVE_FORCEINLINE iiterator_members()
: nodeptr_()//Value initialization to achieve "null iterators" (N3644)
{}
BOOST_INTRUSIVE_FORCEINLINE iiterator_members(const NodePtr &n_ptr, const StoredPointer &)
: nodeptr_(n_ptr)
{}
BOOST_INTRUSIVE_FORCEINLINE StoredPointer get_ptr() const
{ return StoredPointer(); }
NodePtr nodeptr_;
};
} //namespace intrusive
} //namespace boost
#endif //BOOST_INTRUSIVE_DETAIL_IITERATOR_HPP

View File

@@ -0,0 +1,81 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2009-2013.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DETAIL_IS_STATEFUL_VALUE_TRAITS_HPP
#define BOOST_INTRUSIVE_DETAIL_IS_STATEFUL_VALUE_TRAITS_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#if defined(_MSC_VER) && (_MSC_VER <= 1310)
#include <boost/intrusive/detail/mpl.hpp>
namespace boost {
namespace intrusive {
namespace detail {
template<class ValueTraits>
struct is_stateful_value_traits
{
static const bool value = !detail::is_empty<ValueTraits>::value;
};
}}}
#else
#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) )))
;
};
}}}
#endif
#endif //@ifndef BOOST_INTRUSIVE_DETAIL_IS_STATEFUL_VALUE_TRAITS_HPP

View File

@@ -0,0 +1,292 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2014-2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DETAIL_ITERATOR_HPP
#define BOOST_INTRUSIVE_DETAIL_ITERATOR_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <cstddef>
#include <boost/intrusive/detail/std_fwd.hpp>
#include <boost/intrusive/detail/workaround.hpp>
#include <boost/move/detail/iterator_traits.hpp>
#include <boost/move/detail/meta_utils_core.hpp>
namespace boost{
namespace iterators{
struct incrementable_traversal_tag;
struct single_pass_traversal_tag;
struct forward_traversal_tag;
struct bidirectional_traversal_tag;
struct random_access_traversal_tag;
namespace detail{
template <class Category, class Traversal>
struct iterator_category_with_traversal;
} //namespace boost{
} //namespace iterators{
} //namespace detail{
namespace boost {
namespace intrusive {
using boost::movelib::iterator_traits;
using boost::movelib::iter_difference;
using boost::movelib::iter_value;
using boost::movelib::iter_category;
using boost::movelib::iter_size;
////////////////////
// iterator
////////////////////
template<class Category, class T, class Difference, class Pointer, class Reference>
struct iterator
{
typedef Category iterator_category;
typedef T value_type;
typedef Difference difference_type;
typedef Pointer pointer;
typedef Reference reference;
};
////////////////////////////////////////////////////////////////////////////////
// Conversion from boost::iterator traversals to std tags
////////////////////////////////////////////////////////////////////////////////
template<class Tag>
struct get_std_category_from_tag
{
typedef Tag type;
};
template <class Category>
struct get_std_category_from_tag
<boost::iterators::detail::iterator_category_with_traversal
<Category, boost::iterators::incrementable_traversal_tag> >
{
typedef std::input_iterator_tag type;
};
template <class Category>
struct get_std_category_from_tag
<boost::iterators::detail::iterator_category_with_traversal
<Category, boost::iterators::single_pass_traversal_tag> >
{
typedef std::input_iterator_tag type;
};
template <class Category>
struct get_std_category_from_tag
<boost::iterators::detail::iterator_category_with_traversal
<Category, boost::iterators::forward_traversal_tag> >
{
typedef std::input_iterator_tag type;
};
template <class Category>
struct get_std_category_from_tag
<boost::iterators::detail::iterator_category_with_traversal
<Category, boost::iterators::bidirectional_traversal_tag> >
{
typedef std::bidirectional_iterator_tag type;
};
template <class Category>
struct get_std_category_from_tag
<boost::iterators::detail::iterator_category_with_traversal
<Category, boost::iterators::random_access_traversal_tag> >
{
typedef std::random_access_iterator_tag type;
};
template<class It>
struct get_std_category_from_it
: get_std_category_from_tag< typename boost::intrusive::iter_category<It>::type >
{};
////////////////////////////////////////
// iterator_[dis|en]able_if_tag
////////////////////////////////////////
template<class I, class Tag, class R = void>
struct iterator_enable_if_tag
: ::boost::move_detail::enable_if_c
< ::boost::move_detail::is_same
< typename get_std_category_from_it<I>::type
, Tag
>::value
, R>
{};
template<class I, class Tag, class R = void>
struct iterator_disable_if_tag
: ::boost::move_detail::enable_if_c
< !::boost::move_detail::is_same
< typename get_std_category_from_it<I>::type
, Tag
>::value
, R>
{};
////////////////////////////////////////
// iterator_[dis|en]able_if_tag
////////////////////////////////////////
template<class I, class Tag, class Tag2, class R = void>
struct iterator_enable_if_convertible_tag
: ::boost::move_detail::enable_if_c
< ::boost::move_detail::is_same_or_convertible
< typename get_std_category_from_it<I>::type
, Tag
>::value &&
!::boost::move_detail::is_same_or_convertible
< typename get_std_category_from_it<I>::type
, Tag2
>::value
, R>
{};
////////////////////////////////////////
// iterator_[dis|en]able_if_tag_difference_type
////////////////////////////////////////
template<class I, class Tag>
struct iterator_enable_if_tag_difference_type
: iterator_enable_if_tag<I, Tag, typename boost::intrusive::iter_difference<I>::type>
{};
template<class I, class Tag>
struct iterator_disable_if_tag_difference_type
: iterator_disable_if_tag<I, Tag, typename boost::intrusive::iter_difference<I>::type>
{};
////////////////////
// advance
////////////////////
template<class InputIt>
BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_tag<InputIt, std::input_iterator_tag>::type
iterator_advance(InputIt& it, typename iter_difference<InputIt>::type n)
{
while(n--)
++it;
}
template<class InputIt>
typename iterator_enable_if_tag<InputIt, std::forward_iterator_tag>::type
iterator_advance(InputIt& it, typename iter_difference<InputIt>::type n)
{
while(n--)
++it;
}
template<class InputIt>
BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_tag<InputIt, std::bidirectional_iterator_tag>::type
iterator_advance(InputIt& it, typename iter_difference<InputIt>::type n)
{
for (; 0 < n; --n)
++it;
for (; n < 0; ++n)
--it;
}
template<class InputIt, class Distance>
BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_tag<InputIt, std::random_access_iterator_tag>::type
iterator_advance(InputIt& it, Distance n)
{
it += n;
}
template<class It>
BOOST_INTRUSIVE_FORCEINLINE
void iterator_uadvance(It& it, typename iter_size<It>::type n)
{
(iterator_advance)(it, (typename iterator_traits<It>::difference_type)n);
}
////////////////////////////////////////
// iterator_distance
////////////////////////////////////////
template<class InputIt> inline
typename iterator_disable_if_tag_difference_type
<InputIt, std::random_access_iterator_tag>::type
iterator_distance(InputIt first, InputIt last)
{
typename iter_difference<InputIt>::type off = 0;
while(first != last){
++off;
++first;
}
return off;
}
template<class InputIt>
BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_tag_difference_type
<InputIt, std::random_access_iterator_tag>::type
iterator_distance(InputIt first, InputIt last)
{
typename iter_difference<InputIt>::type off = last - first;
return off;
}
////////////////////////////////////////
// iterator_udistance
////////////////////////////////////////
template<class It>
BOOST_INTRUSIVE_FORCEINLINE typename iter_size<It>::type
iterator_udistance(It first, It last)
{
return (typename iter_size<It>::type)(iterator_distance)(first, last);
}
////////////////////////////////////////
// iterator_next
////////////////////////////////////////
template<class InputIt>
BOOST_INTRUSIVE_FORCEINLINE InputIt iterator_next(InputIt it, typename iter_difference<InputIt>::type n)
{
(iterator_advance)(it, n);
return it;
}
template<class InputIt>
BOOST_INTRUSIVE_FORCEINLINE InputIt iterator_unext(InputIt it, typename iterator_traits<InputIt>::size_type n)
{
(iterator_uadvance)(it, n);
return it;
}
////////////////////////////////////////
// iterator_arrow_result
////////////////////////////////////////
template<class I>
BOOST_INTRUSIVE_FORCEINLINE typename iterator_traits<I>::pointer iterator_arrow_result(const I &i)
{ return i.operator->(); }
template<class T>
BOOST_INTRUSIVE_FORCEINLINE T * iterator_arrow_result(T *p)
{ return p; }
} //namespace intrusive
} //namespace boost
#endif //BOOST_INTRUSIVE_DETAIL_ITERATOR_HPP

View File

@@ -0,0 +1,125 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2014-2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DETAIL_KEY_NODEPTR_COMP_HPP
#define BOOST_INTRUSIVE_DETAIL_KEY_NODEPTR_COMP_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/intrusive/detail/mpl.hpp>
#include <boost/intrusive/detail/ebo_functor_holder.hpp>
#include <boost/intrusive/detail/tree_value_compare.hpp>
namespace boost {
namespace intrusive {
namespace detail {
template < class KeyTypeKeyCompare
, class ValueTraits
, class KeyOfValue
>
struct key_nodeptr_comp_types
{
typedef ValueTraits value_traits;
typedef typename value_traits::value_type value_type;
typedef typename value_traits::node_ptr node_ptr;
typedef typename value_traits::const_node_ptr const_node_ptr;
typedef typename detail::if_c
< detail::is_same<KeyOfValue, void>::value
, detail::identity<value_type>
, KeyOfValue
>::type key_of_value;
typedef tree_value_compare
<typename ValueTraits::pointer, KeyTypeKeyCompare, key_of_value> base_t;
};
//This function object transforms a key comparison type to
//a function that can compare nodes or nodes with nodes or keys.
template < class KeyTypeKeyCompare
, class ValueTraits
, class KeyOfValue = void
>
struct key_nodeptr_comp
//Use public inheritance to avoid MSVC bugs with closures
: public key_nodeptr_comp_types<KeyTypeKeyCompare, ValueTraits, KeyOfValue>::base_t
{
private:
struct sfinae_type;
public:
typedef key_nodeptr_comp_types<KeyTypeKeyCompare, ValueTraits, KeyOfValue> types_t;
typedef typename types_t::value_traits value_traits;
typedef typename types_t::value_type value_type;
typedef typename types_t::node_ptr node_ptr;
typedef typename types_t::const_node_ptr const_node_ptr;
typedef typename types_t::base_t base_t;
typedef typename types_t::key_of_value key_of_value;
template <class P1>
struct is_same_or_nodeptr_convertible
{
static const bool same_type = is_same<P1,const_node_ptr>::value || is_same<P1,node_ptr>::value;
static const bool value = same_type || is_convertible<P1, const_node_ptr>::value;
};
BOOST_INTRUSIVE_FORCEINLINE base_t base() const
{ return static_cast<const base_t&>(*this); }
BOOST_INTRUSIVE_FORCEINLINE key_nodeptr_comp(KeyTypeKeyCompare kcomp, const ValueTraits *traits)
: base_t(kcomp), traits_(traits)
{}
//pred(pnode)
template<class T1>
BOOST_INTRUSIVE_FORCEINLINE bool operator()(const T1 &t1, typename enable_if_c< is_same_or_nodeptr_convertible<T1>::value, sfinae_type* >::type = 0) const
{ return base().get()(key_of_value()(*traits_->to_value_ptr(t1))); }
//operator() 2 arg
//pred(pnode, pnode)
template<class T1, class T2>
BOOST_INTRUSIVE_FORCEINLINE bool operator()
(const T1 &t1, const T2 &t2, typename enable_if_c< is_same_or_nodeptr_convertible<T1>::value && is_same_or_nodeptr_convertible<T2>::value, sfinae_type* >::type = 0) const
{ return base()(*traits_->to_value_ptr(t1), *traits_->to_value_ptr(t2)); }
//pred(pnode, key)
template<class T1, class T2>
BOOST_INTRUSIVE_FORCEINLINE bool operator()
(const T1 &t1, const T2 &t2, typename enable_if_c< is_same_or_nodeptr_convertible<T1>::value && !is_same_or_nodeptr_convertible<T2>::value, sfinae_type* >::type = 0) const
{ return base()(*traits_->to_value_ptr(t1), t2); }
//pred(key, pnode)
template<class T1, class T2>
BOOST_INTRUSIVE_FORCEINLINE bool operator()
(const T1 &t1, const T2 &t2, typename enable_if_c< !is_same_or_nodeptr_convertible<T1>::value && is_same_or_nodeptr_convertible<T2>::value, sfinae_type* >::type = 0) const
{ return base()(t1, *traits_->to_value_ptr(t2)); }
//pred(key, key)
template<class T1, class T2>
BOOST_INTRUSIVE_FORCEINLINE bool operator()
(const T1 &t1, const T2 &t2, typename enable_if_c< !is_same_or_nodeptr_convertible<T1>::value && !is_same_or_nodeptr_convertible<T2>::value, sfinae_type* >::type = 0) const
{ return base()(t1, t2); }
const ValueTraits *const traits_;
};
} //namespace detail{
} //namespace intrusive{
} //namespace boost{
#endif //BOOST_INTRUSIVE_DETAIL_KEY_NODEPTR_COMP_HPP

View File

@@ -0,0 +1,146 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
// (C) Copyright Ion Gaztanaga 2006-2013
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_LIST_ITERATOR_HPP
#define BOOST_INTRUSIVE_LIST_ITERATOR_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/intrusive/detail/workaround.hpp>
#include <boost/intrusive/detail/std_fwd.hpp>
#include <boost/intrusive/detail/iiterator.hpp>
#include <boost/intrusive/detail/mpl.hpp>
namespace boost {
namespace intrusive {
// list_iterator provides some basic functions for a
// node oriented bidirectional iterator:
template<class ValueTraits, bool IsConst>
class list_iterator
{
private:
typedef iiterator
<ValueTraits, IsConst, std::bidirectional_iterator_tag> types_t;
static const bool stateful_value_traits = types_t::stateful_value_traits;
typedef ValueTraits value_traits;
typedef typename types_t::node_traits node_traits;
typedef typename types_t::node node;
typedef typename types_t::node_ptr node_ptr;
typedef typename types_t::const_value_traits_ptr const_value_traits_ptr;
class nat;
typedef typename
detail::if_c< IsConst
, list_iterator<value_traits, false>
, nat>::type nonconst_iterator;
public:
typedef typename types_t::iterator_type::difference_type difference_type;
typedef typename types_t::iterator_type::value_type value_type;
typedef typename types_t::iterator_type::pointer pointer;
typedef typename types_t::iterator_type::reference reference;
typedef typename types_t::iterator_type::iterator_category iterator_category;
BOOST_INTRUSIVE_FORCEINLINE list_iterator()
{}
BOOST_INTRUSIVE_FORCEINLINE explicit list_iterator(node_ptr nodeptr, const_value_traits_ptr traits_ptr)
: members_(nodeptr, traits_ptr)
{}
BOOST_INTRUSIVE_FORCEINLINE list_iterator(const list_iterator &other)
: members_(other.pointed_node(), other.get_value_traits())
{}
BOOST_INTRUSIVE_FORCEINLINE list_iterator(const nonconst_iterator &other)
: members_(other.pointed_node(), other.get_value_traits())
{}
BOOST_INTRUSIVE_FORCEINLINE list_iterator &operator=(const list_iterator &other)
{ members_.nodeptr_ = other.members_.nodeptr_; return *this; }
BOOST_INTRUSIVE_FORCEINLINE node_ptr pointed_node() const
{ return members_.nodeptr_; }
BOOST_INTRUSIVE_FORCEINLINE list_iterator &operator=(node_ptr nodeptr)
{ members_.nodeptr_ = nodeptr; return *this; }
BOOST_INTRUSIVE_FORCEINLINE const_value_traits_ptr get_value_traits() const
{ return members_.get_ptr(); }
public:
BOOST_INTRUSIVE_FORCEINLINE list_iterator& operator++()
{
node_ptr p = node_traits::get_next(members_.nodeptr_);
members_.nodeptr_ = p;
return static_cast<list_iterator&> (*this);
}
BOOST_INTRUSIVE_FORCEINLINE list_iterator operator++(int)
{
list_iterator result (*this);
members_.nodeptr_ = node_traits::get_next(members_.nodeptr_);
return result;
}
BOOST_INTRUSIVE_FORCEINLINE list_iterator& operator--()
{
members_.nodeptr_ = node_traits::get_previous(members_.nodeptr_);
return static_cast<list_iterator&> (*this);
}
BOOST_INTRUSIVE_FORCEINLINE list_iterator operator--(int)
{
list_iterator result (*this);
members_.nodeptr_ = node_traits::get_previous(members_.nodeptr_);
return result;
}
BOOST_INTRUSIVE_FORCEINLINE friend bool operator== (const list_iterator& l, const list_iterator& r)
{ return l.pointed_node() == r.pointed_node(); }
BOOST_INTRUSIVE_FORCEINLINE friend bool operator!= (const list_iterator& l, const list_iterator& r)
{ return !(l == r); }
BOOST_INTRUSIVE_FORCEINLINE reference operator*() const
{ return *operator->(); }
BOOST_INTRUSIVE_FORCEINLINE pointer operator->() const
{ return this->operator_arrow(detail::bool_<stateful_value_traits>()); }
BOOST_INTRUSIVE_FORCEINLINE list_iterator<ValueTraits, false> unconst() const
{ return list_iterator<ValueTraits, false>(this->pointed_node(), this->get_value_traits()); }
private:
BOOST_INTRUSIVE_FORCEINLINE pointer operator_arrow(detail::false_) const
{ return ValueTraits::to_value_ptr(members_.nodeptr_); }
BOOST_INTRUSIVE_FORCEINLINE pointer operator_arrow(detail::true_) const
{ return this->get_value_traits()->to_value_ptr(members_.nodeptr_); }
iiterator_members<node_ptr, const_value_traits_ptr, stateful_value_traits> members_;
};
} //namespace intrusive
} //namespace boost
#endif //BOOST_INTRUSIVE_LIST_ITERATOR_HPP

View File

@@ -0,0 +1,72 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
// (C) Copyright Ion Gaztanaga 2006-2013
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_LIST_NODE_HPP
#define BOOST_INTRUSIVE_LIST_NODE_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/intrusive/detail/workaround.hpp>
#include <boost/intrusive/pointer_rebind.hpp>
namespace boost {
namespace intrusive {
// list_node_traits can be used with circular_list_algorithms and supplies
// a list_node holding the pointers needed for a double-linked list
// it is used by list_derived_node and list_member_node
template<class VoidPointer>
struct list_node
{
typedef typename pointer_rebind<VoidPointer, list_node>::type node_ptr;
node_ptr next_;
node_ptr prev_;
};
template<class VoidPointer>
struct list_node_traits
{
typedef list_node<VoidPointer> node;
typedef typename node::node_ptr node_ptr;
typedef typename pointer_rebind<VoidPointer, const node>::type const_node_ptr;
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_previous(const_node_ptr n)
{ return n->prev_; }
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_previous(node_ptr n)
{ return n->prev_; }
BOOST_INTRUSIVE_FORCEINLINE static void set_previous(node_ptr n, node_ptr prev)
{ n->prev_ = prev; }
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_next(const_node_ptr n)
{ return n->next_; }
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_next(node_ptr n)
{ return n->next_; }
BOOST_INTRUSIVE_FORCEINLINE static void set_next(node_ptr n, node_ptr next)
{ n->next_ = next; }
};
} //namespace intrusive
} //namespace boost
#endif //BOOST_INTRUSIVE_LIST_NODE_HPP

View File

@@ -0,0 +1,242 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2014-2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DETAIL_MATH_HPP
#define BOOST_INTRUSIVE_DETAIL_MATH_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <cstddef>
#include <climits>
#include <boost/intrusive/detail/mpl.hpp>
#include <cstring>
namespace boost {
namespace intrusive {
namespace detail {
///////////////////////////
// floor_log2 Dispatcher
////////////////////////////
#if defined(_MSC_VER) && (_MSC_VER >= 1300)
}}} //namespace boost::intrusive::detail
//Use _BitScanReverseXX intrinsics
#if defined(_M_X64) || defined(_M_AMD64) || defined(_M_IA64) //64 bit target
#define BOOST_INTRUSIVE_BSR_INTRINSIC_64_BIT
#endif
#ifndef __INTRIN_H_ // Avoid including any windows system header
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
#if defined(BOOST_INTRUSIVE_BSR_INTRINSIC_64_BIT) //64 bit target
unsigned char _BitScanReverse64(unsigned long *index, unsigned __int64 mask);
#pragma intrinsic(_BitScanReverse64)
#else //32 bit target
unsigned char _BitScanReverse(unsigned long *index, unsigned long mask);
#pragma intrinsic(_BitScanReverse)
#endif
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // __INTRIN_H_
#ifdef BOOST_INTRUSIVE_BSR_INTRINSIC_64_BIT
#define BOOST_INTRUSIVE_BSR_INTRINSIC _BitScanReverse64
#undef BOOST_INTRUSIVE_BSR_INTRINSIC_64_BIT
#else
#define BOOST_INTRUSIVE_BSR_INTRINSIC _BitScanReverse
#endif
namespace boost {
namespace intrusive {
namespace detail {
inline std::size_t floor_log2 (std::size_t x)
{
unsigned long log2;
BOOST_INTRUSIVE_BSR_INTRINSIC( &log2, x );
return static_cast<std::size_t>(log2);
}
#undef BOOST_INTRUSIVE_BSR_INTRINSIC
#elif defined(__GNUC__) && ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) //GCC >=3.4
//Compile-time error in case of missing specialization
template<class Uint>
struct builtin_clz_dispatch;
#if defined(BOOST_HAS_LONG_LONG)
template<>
struct builtin_clz_dispatch< ::boost::ulong_long_type >
{
static ::boost::ulong_long_type call(::boost::ulong_long_type n)
{ return (::boost::ulong_long_type)__builtin_clzll(n); }
};
#endif
template<>
struct builtin_clz_dispatch<unsigned long>
{
static unsigned long call(unsigned long n)
{ return (unsigned long)__builtin_clzl(n); }
};
template<>
struct builtin_clz_dispatch<unsigned int>
{
static unsigned int call(unsigned int n)
{ return (unsigned int)__builtin_clz(n); }
};
inline std::size_t floor_log2(std::size_t n)
{
return sizeof(std::size_t)*CHAR_BIT - std::size_t(1) - builtin_clz_dispatch<std::size_t>::call(n);
}
#else //Portable methods
////////////////////////////
// Generic method
////////////////////////////
inline std::size_t floor_log2_get_shift(std::size_t n, true_ )//power of two size_t
{ return n >> 1; }
inline std::size_t floor_log2_get_shift(std::size_t n, false_ )//non-power of two size_t
{ return (n >> 1) + ((n & 1u) & (n != 1)); }
template<std::size_t N>
inline std::size_t floor_log2 (std::size_t x, integral_constant<std::size_t, N>)
{
const std::size_t Bits = N;
const bool Size_t_Bits_Power_2= !(Bits & (Bits-1));
std::size_t n = x;
std::size_t log2 = 0;
std::size_t remaining_bits = Bits;
std::size_t shift = floor_log2_get_shift(remaining_bits, bool_<Size_t_Bits_Power_2>());
while(shift){
std::size_t tmp = n >> shift;
if (tmp){
log2 += shift, n = tmp;
}
shift = floor_log2_get_shift(shift, bool_<Size_t_Bits_Power_2>());
}
return log2;
}
inline std::size_t floor_log2 (std::size_t x)
{
const std::size_t Bits = sizeof(std::size_t)*CHAR_BIT;
return floor_log2(x, integral_constant<std::size_t, Bits>());
}
#endif
//Thanks to Laurent de Soras in
//http://www.flipcode.com/archives/Fast_log_Function.shtml
inline float fast_log2 (float val)
{
unsigned x;
std::memcpy(&x, &val, sizeof(float));
const int log_2 = int((x >> 23) & 255) - 128;
x &= ~(unsigned(255u) << 23u);
x += unsigned(127) << 23u;
std::memcpy(&val, &x, sizeof(float));
//1+log2(m), m ranging from 1 to 2
//3rd degree polynomial keeping first derivate continuity.
//For less precision the line can be commented out
val = ((-1.f/3.f) * val + 2.f) * val - (2.f/3.f);
return val + static_cast<float>(log_2);
}
inline bool is_pow2(std::size_t x)
{ return (x & (x-1)) == 0; }
template<std::size_t N>
struct static_is_pow2
{
static const bool value = (N & (N-1)) == 0;
};
inline std::size_t ceil_log2 (std::size_t x)
{
return static_cast<std::size_t>(!(is_pow2)(x)) + floor_log2(x);
}
inline std::size_t ceil_pow2 (std::size_t x)
{
return std::size_t(1u) << (ceil_log2)(x);
}
inline std::size_t previous_or_equal_pow2(std::size_t x)
{
return std::size_t(1u) << floor_log2(x);
}
template<class SizeType, std::size_t N>
struct numbits_eq
{
static const bool value = sizeof(SizeType)*CHAR_BIT == N;
};
template<class SizeType, class Enabler = void >
struct sqrt2_pow_max;
template <class SizeType>
struct sqrt2_pow_max<SizeType, typename voider<typename enable_if< numbits_eq<SizeType, 32> >::type>::type>
{
static const SizeType value = 0xb504f334;
static const std::size_t pow = 31;
};
#ifndef BOOST_NO_INT64_T
template <class SizeType>
struct sqrt2_pow_max<SizeType, typename voider<typename enable_if< numbits_eq<SizeType, 64> >::type>::type>
{
static const SizeType value = 0xb504f333f9de6484ull;
static const std::size_t pow = 63;
};
#endif //BOOST_NO_INT64_T
// Returns floor(pow(sqrt(2), x * 2 + 1)).
// Defined for X from 0 up to the number of bits in size_t minus 1.
inline std::size_t sqrt2_pow_2xplus1 (std::size_t x)
{
const std::size_t value = (std::size_t)sqrt2_pow_max<std::size_t>::value;
const std::size_t pow = (std::size_t)sqrt2_pow_max<std::size_t>::pow;
return (value >> (pow - x)) + 1;
}
} //namespace detail
} //namespace intrusive
} //namespace boost
#endif //BOOST_INTRUSIVE_DETAIL_MATH_HPP

View File

@@ -0,0 +1,30 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2014-2015
//
// 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_MINIMAL_LESS_EQUAL_HEADER_HPP
#define BOOST_INTRUSIVE_DETAIL_MINIMAL_LESS_EQUAL_HEADER_HPP
#
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#
#//Try to avoid including <functional>, as it's quite big in C++11
#if defined(BOOST_GNU_STDLIB)
# include <bits/stl_function.h>
#else
# include <functional> //Fallback
#endif
#
#endif //BOOST_INTRUSIVE_DETAIL_MINIMAL_LESS_EQUAL_HEADER_HPP

View File

@@ -0,0 +1,30 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2014-2015
//
// 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_MINIMAL_PAIR_HEADER_HPP
#define BOOST_INTRUSIVE_DETAIL_MINIMAL_PAIR_HEADER_HPP
#
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#
#//Try to avoid including <utility>, as it's quite big in C++11
#if defined(BOOST_GNU_STDLIB)
# include <bits/stl_pair.h>
#else
# include <utility> //Fallback
#endif
#
#endif //BOOST_INTRUSIVE_DETAIL_MINIMAL_PAIR_HEADER_HPP

View File

@@ -0,0 +1,217 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2014
// (C) Copyright Microsoft Corporation 2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DETAIL_MPL_HPP
#define BOOST_INTRUSIVE_DETAIL_MPL_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/move/detail/type_traits.hpp>
#include <cstddef>
namespace boost {
namespace intrusive {
namespace detail {
using boost::move_detail::is_same;
using boost::move_detail::add_const;
using boost::move_detail::remove_const;
using boost::move_detail::remove_cv;
using boost::move_detail::remove_reference;
using boost::move_detail::add_reference;
using boost::move_detail::remove_pointer;
using boost::move_detail::add_pointer;
using boost::move_detail::true_type;
using boost::move_detail::false_type;
using boost::move_detail::voider;
using boost::move_detail::enable_if_c;
using boost::move_detail::enable_if;
using boost::move_detail::disable_if_c;
using boost::move_detail::disable_if;
using boost::move_detail::is_convertible;
using boost::move_detail::if_c;
using boost::move_detail::if_;
using boost::move_detail::is_const;
using boost::move_detail::identity;
using boost::move_detail::alignment_of;
using boost::move_detail::is_empty;
using boost::move_detail::addressof;
using boost::move_detail::integral_constant;
using boost::move_detail::enable_if_convertible;
using boost::move_detail::disable_if_convertible;
using boost::move_detail::bool_;
using boost::move_detail::true_;
using boost::move_detail::false_;
using boost::move_detail::yes_type;
using boost::move_detail::no_type;
using boost::move_detail::apply;
using boost::move_detail::eval_if_c;
using boost::move_detail::eval_if;
using boost::move_detail::unvoid_ref;
using boost::move_detail::add_const_if_c;
template<std::size_t S>
struct ls_zeros
{
static const std::size_t value = (S & std::size_t(1)) ? 0 : (1 + ls_zeros<(S>>1u)>::value);
};
template<>
struct ls_zeros<0>
{
static const std::size_t value = 0;
};
template<>
struct ls_zeros<1>
{
static const std::size_t value = 0;
};
// Infrastructure for providing a default type for T::TNAME if absent.
#define BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(TNAME) \
template <typename T> \
struct boost_intrusive_has_type_ ## TNAME \
{ \
template <typename X> \
static char test(int, typename X::TNAME*); \
\
template <typename X> \
static int test(...); \
\
static const bool value = (1 == sizeof(test<T>(0, 0))); \
}; \
\
template <typename T, typename DefaultType> \
struct boost_intrusive_default_type_ ## TNAME \
{ \
struct DefaultWrap { typedef DefaultType TNAME; }; \
\
typedef typename \
::boost::intrusive::detail::if_c \
< boost_intrusive_has_type_ ## TNAME<T>::value \
, T, DefaultWrap>::type::TNAME type; \
}; \
//
#define BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL) \
typename INSTANTIATION_NS_PREFIX \
boost_intrusive_default_type_ ## TNAME< T, TIMPL >::type \
//
#define BOOST_INTRUSIVE_HAS_TYPE(INSTANTIATION_NS_PREFIX, T, TNAME) \
INSTANTIATION_NS_PREFIX \
boost_intrusive_has_type_ ## TNAME< T >::value \
//
#define BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(TNAME)\
template <typename T, typename DefaultType> \
struct boost_intrusive_eval_default_type_ ## TNAME \
{ \
template <typename X> \
static char test(int, typename X::TNAME*); \
\
template <typename X> \
static int test(...); \
\
struct DefaultWrap \
{ typedef typename DefaultType::type TNAME; }; \
\
static const bool value = (1 == sizeof(test<T>(0, 0))); \
\
typedef typename \
::boost::intrusive::detail::eval_if_c \
< value \
, ::boost::intrusive::detail::identity<T> \
, ::boost::intrusive::detail::identity<DefaultWrap> \
>::type::TNAME type; \
}; \
//
#define BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL) \
typename INSTANTIATION_NS_PREFIX \
boost_intrusive_eval_default_type_ ## TNAME< T, TIMPL >::type \
//
#define BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(TRAITS_PREFIX, TYPEDEF_TO_FIND) \
template <class T>\
struct TRAITS_PREFIX##_bool\
{\
template<bool Add>\
struct two_or_three {yes_type _[2u + (unsigned)Add];};\
template <class U> static yes_type test(...);\
template <class U> static two_or_three<U::TYPEDEF_TO_FIND> test (int);\
static const std::size_t value = sizeof(test<T>(0));\
};\
\
template <class T>\
struct TRAITS_PREFIX##_bool_is_true\
{\
static const bool value = TRAITS_PREFIX##_bool<T>::value > sizeof(yes_type)*2;\
};\
//
#define BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(TRAITS_NAME, FUNC_NAME) \
template <typename U, typename Signature> \
class TRAITS_NAME \
{ \
private: \
template<Signature> struct helper;\
template<typename T> \
static ::boost::intrusive::detail::yes_type test(helper<&T::FUNC_NAME>*); \
template<typename T> static ::boost::intrusive::detail::no_type test(...); \
public: \
static const bool value = sizeof(test<U>(0)) == sizeof(::boost::intrusive::detail::yes_type); \
}; \
//
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED(TRAITS_NAME, FUNC_NAME) \
template <typename Type> \
struct TRAITS_NAME \
{ \
struct BaseMixin \
{ \
void FUNC_NAME(); \
}; \
struct Base : public Type, public BaseMixin { Base(); }; \
template <typename T, T t> class Helper{}; \
template <typename U> \
static ::boost::intrusive::detail::no_type test(U*, Helper<void (BaseMixin::*)(), &U::FUNC_NAME>* = 0); \
static ::boost::intrusive::detail::yes_type test(...); \
static const bool value = sizeof(::boost::intrusive::detail::yes_type) == sizeof(test((Base*)(0))); \
};\
//
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED_IGNORE_SIGNATURE(TRAITS_NAME, FUNC_NAME) \
BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED(TRAITS_NAME##_ignore_signature, FUNC_NAME) \
\
template <typename Type, class> \
struct TRAITS_NAME \
: public TRAITS_NAME##_ignore_signature<Type> \
{};\
//
} //namespace detail
} //namespace intrusive
} //namespace boost
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_DETAIL_MPL_HPP

View File

@@ -0,0 +1,105 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2014-2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DETAIL_NODE_CLONER_DISPOSER_HPP
#define BOOST_INTRUSIVE_DETAIL_NODE_CLONER_DISPOSER_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/intrusive/link_mode.hpp>
#include <boost/intrusive/detail/mpl.hpp>
#include <boost/intrusive/detail/ebo_functor_holder.hpp>
#include <boost/intrusive/detail/algo_type.hpp>
#include <boost/intrusive/detail/assert.hpp>
namespace boost {
namespace intrusive {
namespace detail {
template<class F, class ValueTraits, algo_types AlgoType, bool IsConst = true>
struct node_cloner
//Use public inheritance to avoid MSVC bugs with closures
: public ebo_functor_holder<F>
{
typedef ValueTraits value_traits;
typedef typename value_traits::node_traits node_traits;
typedef typename node_traits::node_ptr node_ptr;
typedef ebo_functor_holder<F> base_t;
typedef typename get_algo< AlgoType
, node_traits>::type node_algorithms;
static const bool safemode_or_autounlink =
is_safe_autounlink<value_traits::link_mode>::value;
typedef typename value_traits::value_type value_type;
typedef typename value_traits::pointer pointer;
typedef typename value_traits::const_pointer const_pointer;
typedef typename node_traits::node node;
typedef typename value_traits::const_node_ptr const_node_ptr;
typedef typename pointer_traits<pointer>::reference reference;
typedef typename pointer_traits
<const_pointer>::reference const_reference;
typedef typename if_c<IsConst, const_reference, reference>::type reference_type;
node_cloner(F f, const ValueTraits *traits)
: base_t(f), traits_(traits)
{}
// tree-based containers use this method, which is proxy-reference friendly
BOOST_INTRUSIVE_FORCEINLINE node_ptr operator()(node_ptr p)
{
reference_type v = *traits_->to_value_ptr(p);
node_ptr n = traits_->to_node_ptr(*base_t::get()(v));
//Cloned node must be in default mode if the linking mode requires it
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(n));
return n;
}
const ValueTraits * const traits_;
};
template<class F, class ValueTraits, algo_types AlgoType>
struct node_disposer
//Use public inheritance to avoid MSVC bugs with closures
: public ebo_functor_holder<F>
{
typedef ValueTraits value_traits;
typedef typename value_traits::node_traits node_traits;
typedef typename node_traits::node_ptr node_ptr;
typedef ebo_functor_holder<F> base_t;
typedef typename get_algo< AlgoType
, node_traits>::type node_algorithms;
static const bool safemode_or_autounlink =
is_safe_autounlink<value_traits::link_mode>::value;
node_disposer(F f, const ValueTraits *cont)
: base_t(f), traits_(cont)
{}
BOOST_INTRUSIVE_FORCEINLINE void operator()(node_ptr p)
{
BOOST_IF_CONSTEXPR(safemode_or_autounlink)
node_algorithms::init(p);
base_t::get()(traits_->to_value_ptr(p));
}
const ValueTraits * const traits_;
};
} //namespace detail{
} //namespace intrusive{
} //namespace boost{
#endif //BOOST_INTRUSIVE_DETAIL_NODE_CLONER_DISPOSER_HPP

View File

@@ -0,0 +1,35 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2014-2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DETAIL_NODE_HOLDER_HPP
#define BOOST_INTRUSIVE_DETAIL_NODE_HOLDER_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
namespace boost {
namespace intrusive {
template<class Node, class Tag, unsigned int>
struct node_holder
: public Node
{};
} //namespace intrusive{
} //namespace boost{
#endif //BOOST_INTRUSIVE_DETAIL_NODE_HOLDER_HPP

View File

@@ -0,0 +1,130 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2014-2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DETAIL_NODE_TO_VALUE_HPP
#define BOOST_INTRUSIVE_DETAIL_NODE_TO_VALUE_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/detail/mpl.hpp>
#include <boost/intrusive/detail/is_stateful_value_traits.hpp>
namespace boost {
namespace intrusive {
namespace detail {
template<class VoidPointer>
struct dummy_constptr
{
typedef typename boost::intrusive::pointer_traits<VoidPointer>::
template rebind_pointer<const void>::type ConstVoidPtr;
explicit dummy_constptr(ConstVoidPtr)
{}
dummy_constptr()
{}
ConstVoidPtr get_ptr() const
{ return ConstVoidPtr(); }
};
template<class VoidPointer>
struct constptr
{
typedef typename boost::intrusive::pointer_traits<VoidPointer>::
template rebind_pointer<const void>::type ConstVoidPtr;
constptr()
{}
explicit constptr(const ConstVoidPtr &ptr)
: const_void_ptr_(ptr)
{}
const void *get_ptr() const
{ return boost::movelib::to_raw_pointer(const_void_ptr_); }
ConstVoidPtr const_void_ptr_;
};
template <class VoidPointer, bool store_ptr>
struct select_constptr
{
typedef typename if_c
< store_ptr
, constptr<VoidPointer>
, dummy_constptr<VoidPointer>
>::type type;
};
template<class ValueTraits, bool IsConst>
struct node_to_value
: public select_constptr
< typename pointer_traits
<typename ValueTraits::pointer>::template rebind_pointer<void>::type
, is_stateful_value_traits<ValueTraits>::value
>::type
{
static const bool stateful_value_traits = is_stateful_value_traits<ValueTraits>::value;
typedef typename select_constptr
< typename pointer_traits
<typename ValueTraits::pointer>::
template rebind_pointer<void>::type
, stateful_value_traits >::type Base;
typedef ValueTraits value_traits;
typedef typename value_traits::value_type value_type;
typedef typename value_traits::node_traits::node node;
typedef typename add_const_if_c
<value_type, IsConst>::type vtype;
typedef typename add_const_if_c
<node, IsConst>::type ntype;
typedef typename pointer_traits
<typename ValueTraits::pointer>::
template rebind_pointer<ntype>::type npointer;
typedef typename pointer_traits<npointer>::
template rebind_pointer<const ValueTraits>::type const_value_traits_ptr;
node_to_value(const_value_traits_ptr ptr)
: Base(ptr)
{}
typedef vtype & result_type;
typedef ntype & first_argument_type;
const_value_traits_ptr get_value_traits() const
{ return pointer_traits<const_value_traits_ptr>::static_cast_from(Base::get_ptr()); }
result_type to_value(first_argument_type arg, false_) const
{ return *(value_traits::to_value_ptr(pointer_traits<npointer>::pointer_to(arg))); }
result_type to_value(first_argument_type arg, true_) const
{ return *(this->get_value_traits()->to_value_ptr(pointer_traits<npointer>::pointer_to(arg))); }
result_type operator()(first_argument_type arg) const
{ return this->to_value(arg, bool_<stateful_value_traits>()); }
};
} //namespace detail{
} //namespace intrusive{
} //namespace boost{
#endif //BOOST_INTRUSIVE_DETAIL_NODE_TO_VALUE_HPP

View File

@@ -0,0 +1,121 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2013
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DETAIL_PARENT_FROM_MEMBER_HPP
#define BOOST_INTRUSIVE_DETAIL_PARENT_FROM_MEMBER_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/detail/workaround.hpp>
#include <cstddef>
#if defined(_MSC_VER)
#define BOOST_INTRUSIVE_MSVC_ABI_PTR_TO_MEMBER
#include <boost/static_assert.hpp>
#endif
namespace boost {
namespace intrusive {
namespace detail {
template<class Parent, class Member>
BOOST_INTRUSIVE_FORCEINLINE std::ptrdiff_t offset_from_pointer_to_member(const Member Parent::* ptr_to_member)
{
//The implementation of a pointer to member is compiler dependent.
#if defined(BOOST_INTRUSIVE_MSVC_ABI_PTR_TO_MEMBER)
//MSVC compliant compilers use their the first 32 bits as offset (even in 64 bit mode)
union caster_union
{
const Member Parent::* ptr_to_member;
int offset;
} caster;
//MSVC ABI can use up to 3 int32 to represent pointer to member data
//with virtual base classes, in those cases there is no simple to
//obtain the address of the parent. So static assert to avoid runtime errors
BOOST_STATIC_ASSERT( sizeof(caster) == sizeof(int) );
caster.ptr_to_member = ptr_to_member;
return std::ptrdiff_t(caster.offset);
//Additional info on MSVC behaviour for the future. For 2/3 int ptr-to-member
//types dereference seems to be:
//
// vboffset = [compile_time_offset if 2-int ptr2memb] /
// [ptr2memb.i32[2] if 3-int ptr2memb].
// vbtable = *(this + vboffset);
// adj = vbtable[ptr2memb.i32[1]];
// var = adj + (this + vboffset) + ptr2memb.i32[0];
//
//To reverse the operation we need to
// - obtain vboffset (in 2-int ptr2memb implementation only)
// - Go to Parent's vbtable and obtain adjustment at index ptr2memb.i32[1]
// - parent = member - adj - vboffset - ptr2memb.i32[0]
//
//Even accessing to RTTI we might not be able to obtain this information
//so anyone who thinks it's possible, please send a patch.
//This works with gcc, msvc, ac++, ibmcpp
#elif defined(__GNUC__) || defined(__HP_aCC) || defined(BOOST_INTEL) || \
defined(__IBMCPP__) || defined(__DECCXX)
const Parent * const parent = 0;
const char *const member = static_cast<const char*>(static_cast<const void*>(&(parent->*ptr_to_member)));
return std::ptrdiff_t(member - static_cast<const char*>(static_cast<const void*>(parent)));
#else
//This is the traditional C-front approach: __MWERKS__, __DMC__, __SUNPRO_CC
union caster_union
{
const Member Parent::* ptr_to_member;
std::ptrdiff_t offset;
} caster;
caster.ptr_to_member = ptr_to_member;
return caster.offset - 1;
#endif
}
template<class Parent, class Member>
BOOST_INTRUSIVE_FORCEINLINE Parent *parent_from_member(Member *member, const Member Parent::* ptr_to_member)
{
return static_cast<Parent*>
(
static_cast<void*>
(
static_cast<char*>(static_cast<void*>(member)) - offset_from_pointer_to_member(ptr_to_member)
)
);
}
template<class Parent, class Member>
BOOST_INTRUSIVE_FORCEINLINE const Parent *parent_from_member(const Member *member, const Member Parent::* ptr_to_member)
{
return static_cast<const Parent*>
(
static_cast<const void*>
(
static_cast<const char*>(static_cast<const void*>(member)) - offset_from_pointer_to_member(ptr_to_member)
)
);
}
} //namespace detail {
} //namespace intrusive {
} //namespace boost {
#include <boost/intrusive/detail/config_end.hpp>
#endif //#ifndef BOOST_INTRUSIVE_DETAIL_PARENT_FROM_MEMBER_HPP

View File

@@ -0,0 +1,205 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
// (C) Copyright Ion Gaztanaga 2006-2013.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_RBTREE_NODE_HPP
#define BOOST_INTRUSIVE_RBTREE_NODE_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/detail/workaround.hpp>
#include <boost/intrusive/pointer_rebind.hpp>
#include <boost/intrusive/rbtree_algorithms.hpp>
#include <boost/intrusive/pointer_plus_bits.hpp>
#include <boost/intrusive/detail/mpl.hpp>
#include <boost/intrusive/detail/tree_node.hpp>
namespace boost {
namespace intrusive {
/////////////////////////////////////////////////////////////////////////////
// //
// Generic node_traits for any pointer type //
// //
/////////////////////////////////////////////////////////////////////////////
//This is the compact representation: 3 pointers
template<class VoidPointer>
struct compact_rbtree_node
{
typedef compact_rbtree_node<VoidPointer> node;
typedef typename pointer_rebind<VoidPointer, node >::type node_ptr;
typedef typename pointer_rebind<VoidPointer, const node >::type const_node_ptr;
enum color { red_t, black_t };
node_ptr parent_, left_, right_;
};
//This is the normal representation: 3 pointers + enum
template<class VoidPointer>
struct rbtree_node
{
typedef rbtree_node<VoidPointer> node;
typedef typename pointer_rebind<VoidPointer, node >::type node_ptr;
typedef typename pointer_rebind<VoidPointer, const node >::type const_node_ptr;
enum color { red_t, black_t };
node_ptr parent_, left_, right_;
color color_;
};
//This is the default node traits implementation
//using a node with 3 generic pointers plus an enum
template<class VoidPointer>
struct default_rbtree_node_traits_impl
{
typedef rbtree_node<VoidPointer> node;
typedef typename node::node_ptr node_ptr;
typedef typename node::const_node_ptr const_node_ptr;
typedef typename node::color color;
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const_node_ptr n)
{ return n->parent_; }
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(node_ptr n)
{ return n->parent_; }
BOOST_INTRUSIVE_FORCEINLINE static void set_parent(node_ptr n, node_ptr p)
{ n->parent_ = p; }
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const_node_ptr n)
{ return n->left_; }
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(node_ptr n)
{ return n->left_; }
BOOST_INTRUSIVE_FORCEINLINE static void set_left(node_ptr n, node_ptr l)
{ n->left_ = l; }
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const_node_ptr n)
{ return n->right_; }
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(node_ptr n)
{ return n->right_; }
BOOST_INTRUSIVE_FORCEINLINE static void set_right(node_ptr n, node_ptr r)
{ n->right_ = r; }
BOOST_INTRUSIVE_FORCEINLINE static color get_color(const_node_ptr n)
{ return n->color_; }
BOOST_INTRUSIVE_FORCEINLINE static color get_color(node_ptr n)
{ return n->color_; }
BOOST_INTRUSIVE_FORCEINLINE static void set_color(node_ptr n, color c)
{ n->color_ = c; }
BOOST_INTRUSIVE_FORCEINLINE static color black()
{ return node::black_t; }
BOOST_INTRUSIVE_FORCEINLINE static color red()
{ return node::red_t; }
};
//This is the compact node traits implementation
//using a node with 3 generic pointers
template<class VoidPointer>
struct compact_rbtree_node_traits_impl
{
typedef compact_rbtree_node<VoidPointer> node;
typedef typename node::node_ptr node_ptr;
typedef typename node::const_node_ptr const_node_ptr;
typedef pointer_plus_bits<node_ptr, 1> ptr_bit;
typedef typename node::color color;
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const_node_ptr n)
{ return ptr_bit::get_pointer(n->parent_); }
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(node_ptr n)
{ return ptr_bit::get_pointer(n->parent_); }
BOOST_INTRUSIVE_FORCEINLINE static void set_parent(node_ptr n, node_ptr p)
{ ptr_bit::set_pointer(n->parent_, p); }
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const_node_ptr n)
{ return n->left_; }
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(node_ptr n)
{ return n->left_; }
BOOST_INTRUSIVE_FORCEINLINE static void set_left(node_ptr n, node_ptr l)
{ n->left_ = l; }
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const_node_ptr n)
{ return n->right_; }
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(node_ptr n)
{ return n->right_; }
BOOST_INTRUSIVE_FORCEINLINE static void set_right(node_ptr n, node_ptr r)
{ n->right_ = r; }
BOOST_INTRUSIVE_FORCEINLINE static color get_color(const_node_ptr n)
{ return (color)ptr_bit::get_bits(n->parent_); }
BOOST_INTRUSIVE_FORCEINLINE static color get_color(node_ptr n)
{ return (color)ptr_bit::get_bits(n->parent_); }
BOOST_INTRUSIVE_FORCEINLINE static void set_color(node_ptr n, color c)
{ ptr_bit::set_bits(n->parent_, c != 0); }
BOOST_INTRUSIVE_FORCEINLINE static color black()
{ return node::black_t; }
BOOST_INTRUSIVE_FORCEINLINE static color red()
{ return node::red_t; }
};
//Dispatches the implementation based on the boolean
template<class VoidPointer, bool Compact>
struct rbtree_node_traits_dispatch
: public default_rbtree_node_traits_impl<VoidPointer>
{};
template<class VoidPointer>
struct rbtree_node_traits_dispatch<VoidPointer, true>
: public compact_rbtree_node_traits_impl<VoidPointer>
{};
//Inherit from rbtree_node_traits_dispatch depending on the embedding capabilities
template<class VoidPointer, bool OptimizeSize = false>
struct rbtree_node_traits
: public rbtree_node_traits_dispatch
< VoidPointer
, OptimizeSize &&
(max_pointer_plus_bits
< VoidPointer
, detail::alignment_of<compact_rbtree_node<VoidPointer> >::value
>::value >= 1)
>
{};
} //namespace intrusive
} //namespace boost
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_RBTREE_NODE_HPP

View File

@@ -0,0 +1,28 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2014-2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DETAIL_REVERSE_ITERATOR_HPP
#define BOOST_INTRUSIVE_DETAIL_REVERSE_ITERATOR_HPP
#include <boost/move/detail/reverse_iterator.hpp>
namespace boost {
namespace intrusive {
using boost::movelib::reverse_iterator;
using boost::movelib::make_reverse_iterator;
} //namespace intrusive {
} //namespace boost {
#endif //BOOST_INTRUSIVE_DETAIL_REVERSE_ITERATOR_HPP

View File

@@ -0,0 +1,52 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2014-2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DETAIL_SIMPLE_DISPOSERS_HPP
#define BOOST_INTRUSIVE_DETAIL_SIMPLE_DISPOSERS_HPP
#include <boost/intrusive/detail/workaround.hpp>
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
namespace boost {
namespace intrusive {
namespace detail {
class null_disposer
{
public:
template <class Pointer>
void operator()(Pointer)
{}
};
template<class NodeAlgorithms>
class init_disposer
{
typedef typename NodeAlgorithms::node_ptr node_ptr;
public:
BOOST_INTRUSIVE_FORCEINLINE void operator()(node_ptr p)
{ NodeAlgorithms::init(p); }
};
} //namespace detail{
} //namespace intrusive{
} //namespace boost{
#endif //BOOST_INTRUSIVE_DETAIL_SIMPLE_DISPOSERS_HPP

View File

@@ -0,0 +1,91 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2014-2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DETAIL_SIZE_HOLDER_HPP
#define BOOST_INTRUSIVE_DETAIL_SIZE_HOLDER_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/intrusive/detail/workaround.hpp>
namespace boost {
namespace intrusive {
namespace detail {
template<bool ConstantSize, class SizeType, class Tag = void>
struct size_holder
{
static const bool constant_time_size = ConstantSize;
typedef SizeType size_type;
BOOST_INTRUSIVE_FORCEINLINE SizeType get_size() const
{ return size_; }
BOOST_INTRUSIVE_FORCEINLINE void set_size(SizeType size)
{ size_ = size; }
BOOST_INTRUSIVE_FORCEINLINE void decrement()
{ --size_; }
BOOST_INTRUSIVE_FORCEINLINE void increment()
{ ++size_; }
BOOST_INTRUSIVE_FORCEINLINE void increase(SizeType n)
{ size_ += n; }
BOOST_INTRUSIVE_FORCEINLINE void decrease(SizeType n)
{ size_ -= n; }
BOOST_INTRUSIVE_FORCEINLINE void swap(size_holder &other)
{ SizeType tmp(size_); size_ = other.size_; other.size_ = tmp; }
SizeType size_;
};
template<class SizeType, class Tag>
struct size_holder<false, SizeType, Tag>
{
static const bool constant_time_size = false;
typedef SizeType size_type;
BOOST_INTRUSIVE_FORCEINLINE size_type get_size() const
{ return 0; }
BOOST_INTRUSIVE_FORCEINLINE void set_size(size_type)
{}
BOOST_INTRUSIVE_FORCEINLINE void decrement()
{}
BOOST_INTRUSIVE_FORCEINLINE void increment()
{}
BOOST_INTRUSIVE_FORCEINLINE void increase(SizeType)
{}
BOOST_INTRUSIVE_FORCEINLINE void decrease(SizeType)
{}
BOOST_INTRUSIVE_FORCEINLINE void swap(size_holder){}
};
} //namespace detail{
} //namespace intrusive{
} //namespace boost{
#endif //BOOST_INTRUSIVE_DETAIL_SIZE_HOLDER_HPP

View File

@@ -0,0 +1,137 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
// (C) Copyright Ion Gaztanaga 2006-2013
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_SLIST_ITERATOR_HPP
#define BOOST_INTRUSIVE_SLIST_ITERATOR_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/detail/workaround.hpp>
#include <boost/intrusive/detail/std_fwd.hpp>
#include <boost/intrusive/detail/iiterator.hpp>
#include <boost/intrusive/detail/mpl.hpp>
namespace boost {
namespace intrusive {
// slist_iterator provides some basic functions for a
// node oriented bidirectional iterator:
template<class ValueTraits, bool IsConst>
class slist_iterator
{
private:
typedef iiterator
<ValueTraits, IsConst, std::forward_iterator_tag> types_t;
static const bool stateful_value_traits = types_t::stateful_value_traits;
typedef ValueTraits value_traits;
typedef typename types_t::node_traits node_traits;
typedef typename types_t::node node;
typedef typename types_t::node_ptr node_ptr;
typedef typename types_t::const_value_traits_ptr const_value_traits_ptr;
class nat;
typedef typename
detail::if_c< IsConst
, slist_iterator<value_traits, false>
, nat>::type nonconst_iterator;
public:
typedef typename types_t::iterator_type::difference_type difference_type;
typedef typename types_t::iterator_type::value_type value_type;
typedef typename types_t::iterator_type::pointer pointer;
typedef typename types_t::iterator_type::reference reference;
typedef typename types_t::iterator_type::iterator_category iterator_category;
BOOST_INTRUSIVE_FORCEINLINE slist_iterator()
{}
BOOST_INTRUSIVE_FORCEINLINE explicit slist_iterator(node_ptr nodeptr, const_value_traits_ptr traits_ptr)
: members_(nodeptr, traits_ptr)
{}
BOOST_INTRUSIVE_FORCEINLINE slist_iterator(const slist_iterator &other)
: members_(other.pointed_node(), other.get_value_traits())
{}
BOOST_INTRUSIVE_FORCEINLINE slist_iterator(const nonconst_iterator &other)
: members_(other.pointed_node(), other.get_value_traits())
{}
BOOST_INTRUSIVE_FORCEINLINE slist_iterator &operator=(const slist_iterator &other)
{ members_.nodeptr_ = other.members_.nodeptr_; return *this; }
BOOST_INTRUSIVE_FORCEINLINE node_ptr pointed_node() const
{ return members_.nodeptr_; }
BOOST_INTRUSIVE_FORCEINLINE slist_iterator &operator=(node_ptr n)
{ members_.nodeptr_ = n; return static_cast<slist_iterator&>(*this); }
BOOST_INTRUSIVE_FORCEINLINE const_value_traits_ptr get_value_traits() const
{ return members_.get_ptr(); }
public:
BOOST_INTRUSIVE_FORCEINLINE slist_iterator& operator++()
{
members_.nodeptr_ = node_traits::get_next(members_.nodeptr_);
return static_cast<slist_iterator&> (*this);
}
BOOST_INTRUSIVE_FORCEINLINE slist_iterator operator++(int)
{
slist_iterator result (*this);
members_.nodeptr_ = node_traits::get_next(members_.nodeptr_);
return result;
}
BOOST_INTRUSIVE_FORCEINLINE friend bool operator== (const slist_iterator& l, const slist_iterator& r)
{ return l.pointed_node() == r.pointed_node(); }
BOOST_INTRUSIVE_FORCEINLINE friend bool operator!= (const slist_iterator& l, const slist_iterator& r)
{ return !(l == r); }
BOOST_INTRUSIVE_FORCEINLINE reference operator*() const
{ return *operator->(); }
BOOST_INTRUSIVE_FORCEINLINE pointer operator->() const
{ return this->operator_arrow(detail::bool_<stateful_value_traits>()); }
BOOST_INTRUSIVE_FORCEINLINE slist_iterator<ValueTraits, false> unconst() const
{ return slist_iterator<ValueTraits, false>(this->pointed_node(), this->get_value_traits()); }
private:
BOOST_INTRUSIVE_FORCEINLINE pointer operator_arrow(detail::false_) const
{ return ValueTraits::to_value_ptr(members_.nodeptr_); }
BOOST_INTRUSIVE_FORCEINLINE pointer operator_arrow(detail::true_) const
{ return this->get_value_traits()->to_value_ptr(members_.nodeptr_); }
iiterator_members<node_ptr, const_value_traits_ptr, stateful_value_traits> members_;
};
} //namespace intrusive
} //namespace boost
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_SLIST_ITERATOR_HPP

View File

@@ -0,0 +1,64 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
// (C) Copyright Ion Gaztanaga 2006-2013
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_SLIST_NODE_HPP
#define BOOST_INTRUSIVE_SLIST_NODE_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/detail/workaround.hpp>
#include <boost/intrusive/pointer_rebind.hpp>
namespace boost {
namespace intrusive {
template<class VoidPointer>
struct slist_node
{
typedef typename pointer_rebind<VoidPointer, slist_node>::type node_ptr;
node_ptr next_;
};
// slist_node_traits can be used with circular_slist_algorithms and supplies
// a slist_node holding the pointers needed for a singly-linked list
// it is used by slist_base_hook and slist_member_hook
template<class VoidPointer>
struct slist_node_traits
{
typedef slist_node<VoidPointer> node;
typedef typename node::node_ptr node_ptr;
typedef typename pointer_rebind<VoidPointer, const node>::type const_node_ptr;
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_next(const_node_ptr n)
{ return n->next_; }
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_next(node_ptr n)
{ return n->next_; }
BOOST_INTRUSIVE_FORCEINLINE static void set_next(node_ptr n, node_ptr next)
{ n->next_ = next; }
};
} //namespace intrusive
} //namespace boost
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_SLIST_NODE_HPP

View File

@@ -0,0 +1,43 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2014-2014. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DETAIL_STD_FWD_HPP
#define BOOST_INTRUSIVE_DETAIL_STD_FWD_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
//////////////////////////////////////////////////////////////////////////////
// Standard predeclarations
//////////////////////////////////////////////////////////////////////////////
#include <boost/move/detail/std_ns_begin.hpp>
BOOST_MOVE_STD_NS_BEG
template<class T>
struct less;
template<class T>
struct equal_to;
struct input_iterator_tag;
struct forward_iterator_tag;
struct bidirectional_iterator_tag;
struct random_access_iterator_tag;
BOOST_MOVE_STD_NS_END
#include <boost/move/detail/std_ns_end.hpp>
#endif //#ifndef BOOST_INTRUSIVE_DETAIL_STD_FWD_HPP

View File

@@ -0,0 +1,172 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2013
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DETAIL_TRANSFORM_ITERATOR_HPP
#define BOOST_INTRUSIVE_DETAIL_TRANSFORM_ITERATOR_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/detail/workaround.hpp>
#include <boost/intrusive/detail/mpl.hpp>
#include <boost/intrusive/detail/iterator.hpp>
namespace boost {
namespace intrusive {
namespace detail {
template <class PseudoReference>
struct operator_arrow_proxy
{
BOOST_INTRUSIVE_FORCEINLINE operator_arrow_proxy(const PseudoReference &px)
: m_value(px)
{}
BOOST_INTRUSIVE_FORCEINLINE PseudoReference* operator->() const { return &m_value; }
// This function is needed for MWCW and BCC, which won't call operator->
// again automatically per 13.3.1.2 para 8
// operator T*() const { return &m_value; }
mutable PseudoReference m_value;
};
template <class T>
struct operator_arrow_proxy<T&>
{
BOOST_INTRUSIVE_FORCEINLINE operator_arrow_proxy(T &px)
: m_value(px)
{}
BOOST_INTRUSIVE_FORCEINLINE T* operator->() const { return &m_value; }
// This function is needed for MWCW and BCC, which won't call operator->
// again automatically per 13.3.1.2 para 8
// operator T*() const { return &m_value; }
T &m_value;
};
template <class Iterator, class UnaryFunction>
class transform_iterator
{
public:
typedef typename Iterator::iterator_category iterator_category;
typedef typename detail::remove_reference<typename UnaryFunction::result_type>::type value_type;
typedef typename Iterator::difference_type difference_type;
typedef operator_arrow_proxy<typename UnaryFunction::result_type> pointer;
typedef typename UnaryFunction::result_type reference;
explicit transform_iterator(const Iterator &it, const UnaryFunction &f = UnaryFunction())
: members_(it, f)
{}
explicit transform_iterator()
: members_()
{}
BOOST_INTRUSIVE_FORCEINLINE Iterator get_it() const
{ return members_.m_it; }
//Constructors
BOOST_INTRUSIVE_FORCEINLINE transform_iterator& operator++()
{ increment(); return *this; }
BOOST_INTRUSIVE_FORCEINLINE transform_iterator operator++(int)
{
transform_iterator result (*this);
increment();
return result;
}
BOOST_INTRUSIVE_FORCEINLINE friend bool operator== (const transform_iterator& i, const transform_iterator& i2)
{ return i.equal(i2); }
BOOST_INTRUSIVE_FORCEINLINE friend bool operator!= (const transform_iterator& i, const transform_iterator& i2)
{ return !(i == i2); }
BOOST_INTRUSIVE_FORCEINLINE friend typename Iterator::difference_type operator- (const transform_iterator& i, const transform_iterator& i2)
{ return i2.distance_to(i); }
//Arithmetic
transform_iterator& operator+=(typename Iterator::difference_type off)
{ this->advance(off); return *this; }
BOOST_INTRUSIVE_FORCEINLINE transform_iterator operator+(typename Iterator::difference_type off) const
{
transform_iterator other(*this);
other.advance(off);
return other;
}
BOOST_INTRUSIVE_FORCEINLINE friend transform_iterator operator+(typename Iterator::difference_type off, const transform_iterator& right)
{ return right + off; }
BOOST_INTRUSIVE_FORCEINLINE transform_iterator& operator-=(typename Iterator::difference_type off)
{ this->advance(-off); return *this; }
BOOST_INTRUSIVE_FORCEINLINE transform_iterator operator-(typename Iterator::difference_type off) const
{ return *this + (-off); }
BOOST_INTRUSIVE_FORCEINLINE typename UnaryFunction::result_type operator*() const
{ return dereference(); }
BOOST_INTRUSIVE_FORCEINLINE operator_arrow_proxy<typename UnaryFunction::result_type>
operator->() const
{ return operator_arrow_proxy<typename UnaryFunction::result_type>(dereference()); }
private:
struct members
: UnaryFunction
{
BOOST_INTRUSIVE_FORCEINLINE members(const Iterator &it, const UnaryFunction &f)
: UnaryFunction(f), m_it(it)
{}
BOOST_INTRUSIVE_FORCEINLINE members()
{}
Iterator m_it;
} members_;
BOOST_INTRUSIVE_FORCEINLINE void increment()
{ ++members_.m_it; }
BOOST_INTRUSIVE_FORCEINLINE void decrement()
{ --members_.m_it; }
BOOST_INTRUSIVE_FORCEINLINE bool equal(const transform_iterator &other) const
{ return members_.m_it == other.members_.m_it; }
BOOST_INTRUSIVE_FORCEINLINE bool less(const transform_iterator &other) const
{ return other.members_.m_it < members_.m_it; }
typename UnaryFunction::result_type dereference() const
{ return members_(*members_.m_it); }
void advance(typename Iterator::difference_type n)
{ boost::intrusive::iterator_advance(members_.m_it, n); }
typename Iterator::difference_type distance_to(const transform_iterator &other)const
{ return boost::intrusive::iterator_distance(other.members_.m_it, members_.m_it); }
};
} //namespace detail
} //namespace intrusive
} //namespace boost
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_DETAIL_TRANSFORM_ITERATOR_HPP

View File

@@ -0,0 +1,184 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2013
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_TREE_ITERATOR_HPP
#define BOOST_INTRUSIVE_TREE_ITERATOR_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/detail/workaround.hpp>
#include <boost/intrusive/detail/std_fwd.hpp>
#include <boost/intrusive/detail/iiterator.hpp>
#include <boost/intrusive/detail/bstree_algorithms_base.hpp>
namespace boost {
namespace intrusive {
/////////////////////////////////////////////////////////////////////////////
// //
// Implementation of the tree iterator //
// //
/////////////////////////////////////////////////////////////////////////////
// tree_iterator provides some basic functions for a
// node oriented bidirectional iterator:
template<class ValueTraits, bool IsConst>
class tree_iterator
{
private:
typedef iiterator< ValueTraits, IsConst
, std::bidirectional_iterator_tag> types_t;
typedef typename types_t::value_traits value_traits;
typedef typename types_t::node_traits node_traits;
typedef typename types_t::node node;
typedef typename types_t::node_ptr node_ptr;
typedef typename types_t::const_value_traits_ptr const_value_traits_ptr;
typedef bstree_algorithms_base<node_traits> node_algorithms;
static const bool stateful_value_traits = types_t::stateful_value_traits;
void unspecified_bool_type_func() const {}
typedef void (tree_iterator::*unspecified_bool_type)() const;
class nat;
typedef typename
detail::if_c< IsConst
, tree_iterator<value_traits, false>
, nat>::type nonconst_iterator;
public:
typedef typename types_t::iterator_type::difference_type difference_type;
typedef typename types_t::iterator_type::value_type value_type;
typedef typename types_t::iterator_type::pointer pointer;
typedef typename types_t::iterator_type::reference reference;
typedef typename types_t::iterator_type::iterator_category iterator_category;
BOOST_INTRUSIVE_FORCEINLINE tree_iterator()
{}
BOOST_INTRUSIVE_FORCEINLINE explicit tree_iterator(node_ptr nodeptr, const_value_traits_ptr traits_ptr)
: members_(nodeptr, traits_ptr)
{}
BOOST_INTRUSIVE_FORCEINLINE tree_iterator(const tree_iterator &other)
: members_(other.pointed_node(), other.get_value_traits())
{}
BOOST_INTRUSIVE_FORCEINLINE tree_iterator(const nonconst_iterator &other)
: members_(other.pointed_node(), other.get_value_traits())
{}
BOOST_INTRUSIVE_FORCEINLINE tree_iterator &operator=(const tree_iterator &other)
{ members_.nodeptr_ = other.members_.nodeptr_; return *this; }
BOOST_INTRUSIVE_FORCEINLINE tree_iterator &operator=(node_ptr nodeptr)
{ members_.nodeptr_ = nodeptr; return *this; }
BOOST_INTRUSIVE_FORCEINLINE node_ptr pointed_node() const
{ return members_.nodeptr_; }
public:
BOOST_INTRUSIVE_FORCEINLINE tree_iterator& operator++()
{
members_.nodeptr_ = node_algorithms::next_node(members_.nodeptr_);
return *this;
}
tree_iterator operator++(int)
{
tree_iterator result (*this);
members_.nodeptr_ = node_algorithms::next_node(members_.nodeptr_);
return result;
}
BOOST_INTRUSIVE_FORCEINLINE tree_iterator& operator--()
{
members_.nodeptr_ = node_algorithms::prev_node(members_.nodeptr_);
return *this;
}
tree_iterator operator--(int)
{
tree_iterator result (*this);
members_.nodeptr_ = node_algorithms::prev_node(members_.nodeptr_);
return result;
}
BOOST_INTRUSIVE_FORCEINLINE tree_iterator& go_left()
{
members_.nodeptr_ = node_traits::get_left(members_.nodeptr_);
return *this;
}
BOOST_INTRUSIVE_FORCEINLINE tree_iterator& go_right()
{
members_.nodeptr_ = node_traits::get_right(members_.nodeptr_);
return *this;
}
BOOST_INTRUSIVE_FORCEINLINE tree_iterator& go_parent()
{
members_.nodeptr_ = node_traits::get_parent(members_.nodeptr_);
return *this;
}
BOOST_INTRUSIVE_FORCEINLINE operator unspecified_bool_type() const
{ return members_.nodeptr_ ? &tree_iterator::unspecified_bool_type_func : 0; }
BOOST_INTRUSIVE_FORCEINLINE bool operator! () const
{ return !members_.nodeptr_; }
BOOST_INTRUSIVE_FORCEINLINE friend bool operator== (const tree_iterator& l, const tree_iterator& r)
{ return l.pointed_node() == r.pointed_node(); }
BOOST_INTRUSIVE_FORCEINLINE friend bool operator!= (const tree_iterator& l, const tree_iterator& r)
{ return !(l == r); }
BOOST_INTRUSIVE_FORCEINLINE reference operator*() const
{ return *operator->(); }
BOOST_INTRUSIVE_FORCEINLINE pointer operator->() const
{ return this->operator_arrow(detail::bool_<stateful_value_traits>()); }
BOOST_INTRUSIVE_FORCEINLINE const_value_traits_ptr get_value_traits() const
{ return members_.get_ptr(); }
tree_iterator end_iterator_from_it() const
{
return tree_iterator(node_algorithms::get_header(this->pointed_node()), this->get_value_traits());
}
tree_iterator<value_traits, false> unconst() const
{ return tree_iterator<value_traits, false>(this->pointed_node(), this->get_value_traits()); }
private:
BOOST_INTRUSIVE_FORCEINLINE pointer operator_arrow(detail::false_) const
{ return ValueTraits::to_value_ptr(members_.nodeptr_); }
BOOST_INTRUSIVE_FORCEINLINE pointer operator_arrow(detail::true_) const
{ return this->get_value_traits()->to_value_ptr(members_.nodeptr_); }
iiterator_members<node_ptr, const_value_traits_ptr, stateful_value_traits> members_;
};
} //namespace intrusive
} //namespace boost
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_TREE_ITERATOR_HPP

View File

@@ -0,0 +1,80 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2013
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_TREE_NODE_HPP
#define BOOST_INTRUSIVE_TREE_NODE_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/detail/workaround.hpp>
#include <boost/intrusive/pointer_rebind.hpp>
namespace boost {
namespace intrusive {
template<class VoidPointer>
struct tree_node
{
typedef typename pointer_rebind<VoidPointer, tree_node>::type node_ptr;
node_ptr parent_, left_, right_;
};
template<class VoidPointer>
struct tree_node_traits
{
typedef tree_node<VoidPointer> node;
typedef typename node::node_ptr node_ptr;
typedef typename pointer_rebind<VoidPointer, const node>::type const_node_ptr;
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const_node_ptr n)
{ return n->parent_; }
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(node_ptr n)
{ return n->parent_; }
BOOST_INTRUSIVE_FORCEINLINE static void set_parent(node_ptr n, node_ptr p)
{ n->parent_ = p; }
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const_node_ptr n)
{ return n->left_; }
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(node_ptr n)
{ return n->left_; }
BOOST_INTRUSIVE_FORCEINLINE static void set_left(node_ptr n, node_ptr l)
{ n->left_ = l; }
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const_node_ptr n)
{ return n->right_; }
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(node_ptr n)
{ return n->right_; }
BOOST_INTRUSIVE_FORCEINLINE static void set_right(node_ptr n, node_ptr r)
{ n->right_ = r; }
};
} //namespace intrusive
} //namespace boost
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_TREE_NODE_HPP

View File

@@ -0,0 +1,186 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2015-2015. 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/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DETAIL_TREE_VALUE_COMPARE_HPP
#define BOOST_INTRUSIVE_DETAIL_TREE_VALUE_COMPARE_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/intrusive/detail/workaround.hpp>
#include <boost/intrusive/detail/mpl.hpp>
#include <boost/intrusive/detail/ebo_functor_holder.hpp>
#include <boost/intrusive/pointer_traits.hpp>
namespace boost{
namespace intrusive{
//Needed to support smart references to value types
template <class From, class ValuePtr>
struct disable_if_smartref_to
: detail::disable_if_c
< detail::is_same
<From, typename pointer_traits
<ValuePtr>
::reference>::value
|| detail::is_same
<From, typename pointer_traits
< typename pointer_rebind
< ValuePtr
, const typename boost::movelib::pointer_element<ValuePtr>::type>::type>
::reference>::value
>
{};
//This function object takes a KeyCompare function object
//and compares values that contains keys using KeyOfValue
template< class ValuePtr, class KeyCompare, class KeyOfValue, class Ret = bool
, bool = boost::intrusive::detail::is_same
<typename boost::movelib::pointer_element<ValuePtr>::type, typename KeyOfValue::type>::value >
struct tree_value_compare
: public boost::intrusive::detail::ebo_functor_holder<KeyCompare>
{
typedef typename
boost::movelib::pointer_element<ValuePtr>::type value_type;
typedef KeyCompare key_compare;
typedef KeyOfValue key_of_value;
typedef typename KeyOfValue::type key_type;
typedef boost::intrusive::detail::ebo_functor_holder<KeyCompare> base_t;
BOOST_INTRUSIVE_FORCEINLINE tree_value_compare()
: base_t()
{}
BOOST_INTRUSIVE_FORCEINLINE explicit tree_value_compare(const key_compare &kcomp)
: base_t(kcomp)
{}
BOOST_INTRUSIVE_FORCEINLINE tree_value_compare (const tree_value_compare &x)
: base_t(x.base_t::get())
{}
BOOST_INTRUSIVE_FORCEINLINE tree_value_compare &operator=(const tree_value_compare &x)
{ this->base_t::get() = x.base_t::get(); return *this; }
BOOST_INTRUSIVE_FORCEINLINE tree_value_compare &operator=(const key_compare &x)
{ this->base_t::get() = x; return *this; }
BOOST_INTRUSIVE_FORCEINLINE const key_compare &key_comp() const
{ return static_cast<const key_compare &>(*this); }
BOOST_INTRUSIVE_FORCEINLINE Ret operator()(const key_type &key) const
{ return this->key_comp()(key); }
BOOST_INTRUSIVE_FORCEINLINE Ret operator()(const value_type &value) const
{ return this->key_comp()(KeyOfValue()(value)); }
template<class U>
BOOST_INTRUSIVE_FORCEINLINE Ret operator()( const U &nonkey
, typename disable_if_smartref_to<U, ValuePtr>::type* = 0) const
{ return this->key_comp()(nonkey); }
BOOST_INTRUSIVE_FORCEINLINE Ret operator()(const key_type &key1, const key_type &key2) const
{ return this->key_comp()(key1, key2); }
BOOST_INTRUSIVE_FORCEINLINE Ret operator()(const value_type &value1, const value_type &value2) const
{ return this->key_comp()(KeyOfValue()(value1), KeyOfValue()(value2)); }
BOOST_INTRUSIVE_FORCEINLINE Ret operator()(const key_type &key1, const value_type &value2) const
{ return this->key_comp()(key1, KeyOfValue()(value2)); }
BOOST_INTRUSIVE_FORCEINLINE Ret operator()(const value_type &value1, const key_type &key2) const
{ return this->key_comp()(KeyOfValue()(value1), key2); }
template<class U>
BOOST_INTRUSIVE_FORCEINLINE Ret operator()( const key_type &key1, const U &nonkey2
, typename disable_if_smartref_to<U, ValuePtr>::type* = 0) const
{ return this->key_comp()(key1, nonkey2); }
template<class U>
BOOST_INTRUSIVE_FORCEINLINE Ret operator()( const U &nonkey1, const key_type &key2
, typename disable_if_smartref_to<U, ValuePtr>::type* = 0) const
{ return this->key_comp()(nonkey1, key2); }
template<class U>
BOOST_INTRUSIVE_FORCEINLINE Ret operator()( const value_type &value1, const U &nonvalue2
, typename disable_if_smartref_to<U, ValuePtr>::type* = 0) const
{ return this->key_comp()(KeyOfValue()(value1), nonvalue2); }
template<class U>
BOOST_INTRUSIVE_FORCEINLINE Ret operator()( const U &nonvalue1, const value_type &value2
, typename disable_if_smartref_to<U, ValuePtr>::type* = 0) const
{ return this->key_comp()(nonvalue1, KeyOfValue()(value2)); }
};
template<class ValuePtr, class KeyCompare, class KeyOfValue, class Ret>
struct tree_value_compare<ValuePtr, KeyCompare, KeyOfValue, Ret, true>
: public boost::intrusive::detail::ebo_functor_holder<KeyCompare>
{
typedef typename
boost::movelib::pointer_element<ValuePtr>::type value_type;
typedef KeyCompare key_compare;
typedef KeyOfValue key_of_value;
typedef typename KeyOfValue::type key_type;
typedef boost::intrusive::detail::ebo_functor_holder<KeyCompare> base_t;
BOOST_INTRUSIVE_FORCEINLINE tree_value_compare()
: base_t()
{}
BOOST_INTRUSIVE_FORCEINLINE explicit tree_value_compare(const key_compare &kcomp)
: base_t(kcomp)
{}
BOOST_INTRUSIVE_FORCEINLINE tree_value_compare (const tree_value_compare &x)
: base_t(x.base_t::get())
{}
BOOST_INTRUSIVE_FORCEINLINE tree_value_compare &operator=(const tree_value_compare &x)
{ this->base_t::get() = x.base_t::get(); return *this; }
BOOST_INTRUSIVE_FORCEINLINE tree_value_compare &operator=(const key_compare &x)
{ this->base_t::get() = x; return *this; }
BOOST_INTRUSIVE_FORCEINLINE const key_compare &key_comp() const
{ return static_cast<const key_compare &>(*this); }
BOOST_INTRUSIVE_FORCEINLINE Ret operator()(const key_type &key) const
{ return this->key_comp()(key); }
template<class U>
BOOST_INTRUSIVE_FORCEINLINE Ret operator()( const U &nonkey
, typename disable_if_smartref_to<U, ValuePtr>::type* = 0) const
{ return this->key_comp()(nonkey); }
BOOST_INTRUSIVE_FORCEINLINE Ret operator()(const key_type &key1, const key_type &key2) const
{ return this->key_comp()(key1, key2); }
template<class U>
BOOST_INTRUSIVE_FORCEINLINE Ret operator()( const key_type &key1, const U &nonkey2
, typename disable_if_smartref_to<U, ValuePtr>::type* = 0) const
{ return this->key_comp()(key1, nonkey2); }
template<class U>
BOOST_INTRUSIVE_FORCEINLINE Ret operator()(const U &nonkey1, const key_type &key2
, typename disable_if_smartref_to<U, ValuePtr>::type* = 0) const
{ return this->key_comp()(nonkey1, key2); }
};
} //namespace intrusive{
} //namespace boost{
#endif //#ifdef BOOST_INTRUSIVE_DETAIL_TREE_VALUE_COMPARE_HPP

View File

@@ -0,0 +1,49 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2014-2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DETAIL_TWIN_HPP
#define BOOST_INTRUSIVE_DETAIL_TWIN_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
//A tiny utility to avoid pulling std::pair / utility for
//very simple algorithms/types
namespace boost {
namespace intrusive {
template <class T>
struct twin
{
typedef T type;
twin()
: first(), second()
{}
twin(const type &f, const type &s)
: first(f), second(s)
{}
T first;
T second;
};
} //namespace intrusive{
} //namespace boost{
#endif //BOOST_INTRUSIVE_DETAIL_TWIN_HPP

View File

@@ -0,0 +1,55 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DETAIL_UNCAST_HPP
#define BOOST_INTRUSIVE_DETAIL_UNCAST_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/detail/mpl.hpp>
namespace boost {
namespace intrusive {
namespace detail {
template<class ConstNodePtr>
struct uncast_types
{
typedef typename pointer_traits<ConstNodePtr>::element_type element_type;
typedef typename remove_const<element_type>::type non_const_type;
typedef typename pointer_traits<ConstNodePtr>::
template rebind_pointer<non_const_type>::type non_const_pointer;
typedef pointer_traits<non_const_pointer> non_const_traits;
};
template<class ConstNodePtr>
static typename uncast_types<ConstNodePtr>::non_const_pointer
uncast(const ConstNodePtr & ptr)
{
return uncast_types<ConstNodePtr>::non_const_traits::const_cast_from(ptr);
}
} //namespace detail {
} //namespace intrusive
} //namespace boost
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_DETAIL_UTILITIES_HPP

View File

@@ -0,0 +1,42 @@
#ifndef BOOST_INTRUSIVE_DETAIL_VALUE_FUNCTORS_HPP
#define BOOST_INTRUSIVE_DETAIL_VALUE_FUNCTORS_HPP
///////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2017-2021. 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_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
namespace boost {
namespace intrusive {
//Functors for member algorithm defaults
template<class ValueType>
struct value_less
{
bool operator()(const ValueType &a, const ValueType &b) const
{ return a < b; }
};
template<class ValueType>
struct value_equal
{
bool operator()(const ValueType &a, const ValueType &b) const
{ return a == b; }
};
} //namespace intrusive {
} //namespace boost {
#endif //BOOST_INTRUSIVE_DETAIL_VALUE_FUNCTORS_HPP

View File

@@ -0,0 +1,58 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DETAIL_WORKAROUND_HPP
#define BOOST_INTRUSIVE_DETAIL_WORKAROUND_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#ifndef BOOST_CONFIG_HPP
#include <boost/config.hpp>
#endif
// MSVC-12 ICEs when variadic templates are enabled.
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && (!defined(BOOST_MSVC) || BOOST_MSVC >= 1900)
#define BOOST_INTRUSIVE_VARIADIC_TEMPLATES
#endif
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#define BOOST_INTRUSIVE_PERFECT_FORWARDING
#endif
//Macros for documentation purposes. For code, expands to the argument
#define BOOST_INTRUSIVE_IMPDEF(TYPE) TYPE
#define BOOST_INTRUSIVE_SEEDOC(TYPE) TYPE
#define BOOST_INTRUSIVE_DOC1ST(TYPE1, TYPE2) TYPE2
#define BOOST_INTRUSIVE_I ,
#define BOOST_INTRUSIVE_DOCIGN(T1) T1
//#define BOOST_INTRUSIVE_DISABLE_FORCEINLINE
#if defined(BOOST_INTRUSIVE_DISABLE_FORCEINLINE)
#define BOOST_INTRUSIVE_FORCEINLINE inline
#elif defined(BOOST_INTRUSIVE_FORCEINLINE_IS_BOOST_FORCELINE)
#define BOOST_INTRUSIVE_FORCEINLINE BOOST_FORCEINLINE
#elif defined(BOOST_MSVC) && (_MSC_VER < 1900 || defined(_DEBUG))
//"__forceinline" and MSVC seems to have some bugs in old versions and in debug mode
#define BOOST_INTRUSIVE_FORCEINLINE inline
#elif defined(BOOST_GCC) && (__GNUC__ <= 5)
//Older GCCs have problems with forceinline
#define BOOST_INTRUSIVE_FORCEINLINE inline
#else
#define BOOST_INTRUSIVE_FORCEINLINE BOOST_FORCEINLINE
#endif
#endif //#ifndef BOOST_INTRUSIVE_DETAIL_WORKAROUND_HPP

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,766 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2013
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_FWD_HPP
#define BOOST_INTRUSIVE_FWD_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#
#ifndef BOOST_CSTDINT_HPP
# include <boost/cstdint.hpp>
#endif
#
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
//! \file
//! This header file forward declares most Intrusive classes.
//!
//! It forward declares the following containers and hooks:
//! - boost::intrusive::slist / boost::intrusive::slist_base_hook / boost::intrusive::slist_member_hook
//! - boost::intrusive::list / boost::intrusive::list_base_hook / boost::intrusive::list_member_hook
//! - boost::intrusive::bstree / boost::intrusive::bs_set / boost::intrusive::bs_multiset /
//! boost::intrusive::bs_set_base_hook / boost::intrusive::bs_set_member_hook
//! - boost::intrusive::rbtree / boost::intrusive::set / boost::intrusive::multiset /
//! boost::intrusive::set_base_hook / boost::intrusive::set_member_hook
//! - boost::intrusive::avltree / boost::intrusive::avl_set / boost::intrusive::avl_multiset /
//! boost::intrusive::avl_set_base_hook / boost::intrusive::avl_set_member_hook
//! - boost::intrusive::splaytree / boost::intrusive::splay_set / boost::intrusive::splay_multiset
//! - boost::intrusive::sgtree / boost::intrusive::sg_set / boost::intrusive::sg_multiset
//! - boost::intrusive::treap / boost::intrusive::treap_set / boost::intrusive::treap_multiset
//! - boost::intrusive::hashtable / boost::intrusive::unordered_set / boost::intrusive::unordered_multiset /
//! boost::intrusive::unordered_set_base_hook / boost::intrusive::unordered_set_member_hook /
//! - boost::intrusive::any_base_hook / boost::intrusive::any_member_hook
//!
//! It forward declares the following container or hook options:
//! - boost::intrusive::constant_time_size / boost::intrusive::size_type / boost::intrusive::compare / boost::intrusive::equal
//! - boost::intrusive::floating_point / boost::intrusive::priority / boost::intrusive::hash
//! - boost::intrusive::value_traits / boost::intrusive::member_hook / boost::intrusive::function_hook / boost::intrusive::base_hook
//! - boost::intrusive::void_pointer / boost::intrusive::tag / boost::intrusive::link_mode
//! - boost::intrusive::optimize_size / boost::intrusive::linear / boost::intrusive::cache_last
//! - boost::intrusive::bucket_traits / boost::intrusive::store_hash / boost::intrusive::optimize_multikey
//! - boost::intrusive::power_2_buckets / boost::intrusive::cache_begin / boost::intrusive::compare_hash / boost::intrusive::incremental
//!
//! It forward declares the following value traits utilities:
//! - boost::intrusive::value_traits / boost::intrusive::derivation_value_traits /
//! boost::intrusive::trivial_value_traits
//!
//! Finally it forward declares the following general purpose utilities:
//! - boost::intrusive::pointer_plus_bits / boost::intrusive::priority_compare.
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
#include <cstddef>
#include <boost/intrusive/link_mode.hpp>
#include <boost/intrusive/detail/workaround.hpp>
namespace boost {
namespace intrusive {
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
# ifdef BOOST_HAS_INTPTR_T
using ::boost::uintptr_t;
# else
typedef std::size_t uintptr_t;
# endif
#endif
////////////////////////////
// Node algorithms
////////////////////////////
//Algorithms predeclarations
template<class NodeTraits>
class circular_list_algorithms;
template<class NodeTraits>
class circular_slist_algorithms;
template<class NodeTraits>
class linear_slist_algorithms;
template<class NodeTraits>
class bstree_algorithms;
template<class NodeTraits>
class rbtree_algorithms;
template<class NodeTraits>
class avltree_algorithms;
template<class NodeTraits>
class sgtree_algorithms;
template<class NodeTraits>
class splaytree_algorithms;
template<class NodeTraits>
class treap_algorithms;
////////////////////////////
// Containers
////////////////////////////
//slist
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template
< class T
, class O1 = void
, class O2 = void
, class O3 = void
, class O4 = void
, class O5 = void
, class O6 = void
>
#else
template<class T, class ...Options>
#endif
class slist;
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template
< class O1 = void
, class O2 = void
, class O3 = void
>
#else
template<class ...Options>
#endif
class slist_base_hook;
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template
< class O1 = void
, class O2 = void
, class O3 = void
>
#else
template<class ...Options>
#endif
class slist_member_hook;
//list
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template
< class T
, class O1 = void
, class O2 = void
, class O3 = void
, class O4 = void
>
#else
template<class T, class ...Options>
#endif
class list;
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template
< class O1 = void
, class O2 = void
, class O3 = void
>
#else
template<class ...Options>
#endif
class list_base_hook;
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template
< class O1 = void
, class O2 = void
, class O3 = void
>
#else
template<class ...Options>
#endif
class list_member_hook;
//rbtree/set/multiset
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template
< class T
, class O1 = void
, class O2 = void
, class O3 = void
, class O4 = void
, class O5 = void
, class O6 = void
>
#else
template<class T, class ...Options>
#endif
class rbtree;
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template
< class T
, class O1 = void
, class O2 = void
, class O3 = void
, class O4 = void
, class O5 = void
, class O6 = void
>
#else
template<class T, class ...Options>
#endif
class set;
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template
< class T
, class O1 = void
, class O2 = void
, class O3 = void
, class O4 = void
, class O5 = void
, class O6 = void
>
#else
template<class T, class ...Options>
#endif
class multiset;
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template
< class O1 = void
, class O2 = void
, class O3 = void
, class O4 = void
>
#else
template<class ...Options>
#endif
class set_base_hook;
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template
< class O1 = void
, class O2 = void
, class O3 = void
, class O4 = void
>
#else
template<class ...Options>
#endif
class set_member_hook;
//splaytree/splay_set/splay_multiset
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template
< class T
, class O1 = void
, class O2 = void
, class O3 = void
, class O4 = void
, class O5 = void
, class O6 = void
>
#else
template<class T, class ...Options>
#endif
class splaytree;
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template
< class T
, class O1 = void
, class O2 = void
, class O3 = void
, class O4 = void
, class O5 = void
, class O6 = void
>
#else
template<class T, class ...Options>
#endif
class splay_set;
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template
< class T
, class O1 = void
, class O2 = void
, class O3 = void
, class O4 = void
, class O5 = void
, class O6 = void
>
#else
template<class T, class ...Options>
#endif
class splay_multiset;
//avltree/avl_set/avl_multiset
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template
< class T
, class O1 = void
, class O2 = void
, class O3 = void
, class O4 = void
, class O5 = void
, class O6 = void
>
#else
template<class T, class ...Options>
#endif
class avltree;
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template
< class T
, class O1 = void
, class O2 = void
, class O3 = void
, class O4 = void
, class O5 = void
, class O6 = void
>
#else
template<class T, class ...Options>
#endif
class avl_set;
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template
< class T
, class O1 = void
, class O2 = void
, class O3 = void
, class O4 = void
, class O5 = void
, class O6 = void
>
#else
template<class T, class ...Options>
#endif
class avl_multiset;
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template
< class O1 = void
, class O2 = void
, class O3 = void
, class O4 = void
>
#else
template<class ...Options>
#endif
class avl_set_base_hook;
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template
< class O1 = void
, class O2 = void
, class O3 = void
, class O4 = void
>
#else
template<class ...Options>
#endif
class avl_set_member_hook;
//treap/treap_set/treap_multiset
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template
< class T
, class O1 = void
, class O2 = void
, class O3 = void
, class O4 = void
, class O5 = void
, class O6 = void
, class O7 = void
>
#else
template<class T, class ...Options>
#endif
class treap;
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template
< class T
, class O1 = void
, class O2 = void
, class O3 = void
, class O4 = void
, class O5 = void
, class O6 = void
, class O7 = void
>
#else
template<class T, class ...Options>
#endif
class treap_set;
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template
< class T
, class O1 = void
, class O2 = void
, class O3 = void
, class O4 = void
, class O5 = void
, class O6 = void
, class O7 = void
>
#else
template<class T, class ...Options>
#endif
class treap_multiset;
//sgtree/sg_set/sg_multiset
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template
< class T
, class O1 = void
, class O2 = void
, class O3 = void
, class O4 = void
, class O5 = void
, class O6 = void
>
#else
template<class T, class ...Options>
#endif
class sgtree;
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template
< class T
, class O1 = void
, class O2 = void
, class O3 = void
, class O4 = void
, class O5 = void
, class O6 = void
>
#else
template<class T, class ...Options>
#endif
class sg_set;
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template
< class T
, class O1 = void
, class O2 = void
, class O3 = void
, class O4 = void
, class O5 = void
, class O6 = void
>
#else
template<class T, class ...Options>
#endif
class sg_multiset;
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template
< class T
, class O1 = void
, class O2 = void
, class O3 = void
, class O4 = void
, class O5 = void
, class O6 = void
>
#else
template<class T, class ...Options>
#endif
class bstree;
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template
< class T
, class O1 = void
, class O2 = void
, class O3 = void
, class O4 = void
, class O5 = void
, class O6 = void
>
#else
template<class T, class ...Options>
#endif
class bs_set;
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template
< class T
, class O1 = void
, class O2 = void
, class O3 = void
, class O4 = void
, class O5 = void
, class O6 = void
>
#else
template<class T, class ...Options>
#endif
class bs_multiset;
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template
< class O1 = void
, class O2 = void
, class O3 = void
>
#else
template<class ...Options>
#endif
class bs_set_base_hook;
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template
< class O1 = void
, class O2 = void
, class O3 = void
>
#else
template<class ...Options>
#endif
class bs_set_member_hook;
//hashtable/unordered_set/unordered_multiset
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template
< class T
, class O1 = void
, class O2 = void
, class O3 = void
, class O4 = void
, class O5 = void
, class O6 = void
, class O7 = void
, class O8 = void
, class O9 = void
, class O10 = void
>
#else
template<class T, class ...Options>
#endif
class hashtable;
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template
< class T
, class O1 = void
, class O2 = void
, class O3 = void
, class O4 = void
, class O5 = void
, class O6 = void
, class O7 = void
, class O8 = void
, class O9 = void
, class O10 = void
>
#else
template<class T, class ...Options>
#endif
class unordered_set;
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template
< class T
, class O1 = void
, class O2 = void
, class O3 = void
, class O4 = void
, class O5 = void
, class O6 = void
, class O7 = void
, class O8 = void
, class O9 = void
, class O10 = void
>
#else
template<class T, class ...Options>
#endif
class unordered_multiset;
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template
< class O1 = void
, class O2 = void
, class O3 = void
, class O4 = void
>
#else
template<class ...Options>
#endif
class unordered_set_base_hook;
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template
< class O1 = void
, class O2 = void
, class O3 = void
, class O4 = void
>
#else
template<class ...Options>
#endif
class unordered_set_member_hook;
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template
< class O1 = void
, class O2 = void
, class O3 = void
>
#else
template<class ...Options>
#endif
class any_base_hook;
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template
< class O1 = void
, class O2 = void
, class O3 = void
>
#else
template<class ...Options>
#endif
class any_member_hook;
//Options
template<bool Enabled>
struct constant_time_size;
template<typename SizeType>
struct size_type;
template<typename Compare>
struct compare;
template<bool Enabled>
struct floating_point;
template<typename Equal>
struct equal;
template<typename Priority>
struct priority;
template<typename Hash>
struct hash;
template<typename ValueTraits> struct value_traits;
template< typename Parent
, typename MemberHook
, MemberHook Parent::* PtrToMember>
struct member_hook;
template<typename Functor>
struct function_hook;
template<typename BaseHook>
struct base_hook;
template<typename VoidPointer>
struct void_pointer;
template<typename Tag>
struct tag;
template<link_mode_type LinkType>
struct link_mode;
template<bool Enabled> struct
optimize_size;
template<bool Enabled>
struct linear;
template<bool Enabled>
struct cache_last;
template<typename BucketTraits>
struct bucket_traits;
template<bool Enabled>
struct store_hash;
template<bool Enabled>
struct optimize_multikey;
template<bool Enabled>
struct power_2_buckets;
template<bool Enabled>
struct cache_begin;
template<bool Enabled>
struct compare_hash;
template<bool Enabled>
struct incremental;
//Value traits
template<typename ValueTraits>
struct value_traits;
template< typename Parent
, typename MemberHook
, MemberHook Parent::* PtrToMember>
struct member_hook;
template< typename Functor>
struct function_hook;
template<typename BaseHook>
struct base_hook;
template<class T, class NodeTraits, link_mode_type LinkMode = safe_link>
struct derivation_value_traits;
template<class NodeTraits, link_mode_type LinkMode = normal_link>
struct trivial_value_traits;
//Additional utilities
template<typename VoidPointer, std::size_t Alignment>
struct max_pointer_plus_bits;
template<std::size_t Alignment>
struct max_pointer_plus_bits<void *, Alignment>;
template<typename Pointer, std::size_t NumBits>
struct pointer_plus_bits;
template<typename T, std::size_t NumBits>
struct pointer_plus_bits<T *, NumBits>;
template<typename Ptr>
struct pointer_traits;
template<typename T>
struct pointer_traits<T *>;
} //namespace intrusive {
} //namespace boost {
#endif //#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
#endif //#ifndef BOOST_INTRUSIVE_FWD_HPP

View File

@@ -0,0 +1,349 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
// (C) Copyright Ion Gaztanaga 2006-2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_LINEAR_SLIST_ALGORITHMS_HPP
#define BOOST_INTRUSIVE_LINEAR_SLIST_ALGORITHMS_HPP
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/intrusive/detail/common_slist_algorithms.hpp>
#include <boost/intrusive/detail/algo_type.hpp>
#include <cstddef>
#include <boost/intrusive/detail/twin.hpp> //for node_pair
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
namespace boost {
namespace intrusive {
//! linear_slist_algorithms provides basic algorithms to manipulate nodes
//! forming a linear singly linked list.
//!
//! linear_slist_algorithms is configured with a NodeTraits class, which encapsulates the
//! information about the node to be manipulated. NodeTraits must support the
//! following interface:
//!
//! <b>Typedefs</b>:
//!
//! <tt>node</tt>: The type of the node that forms the linear list
//!
//! <tt>node_ptr</tt>: A pointer to a node
//!
//! <tt>const_node_ptr</tt>: A pointer to a const node
//!
//! <b>Static functions</b>:
//!
//! <tt>static node_ptr get_next(const_node_ptr n);</tt>
//!
//! <tt>static void set_next(node_ptr n, node_ptr next);</tt>
template<class NodeTraits>
class linear_slist_algorithms
/// @cond
: public detail::common_slist_algorithms<NodeTraits>
/// @endcond
{
/// @cond
typedef detail::common_slist_algorithms<NodeTraits> base_t;
/// @endcond
public:
typedef typename NodeTraits::node node;
typedef typename NodeTraits::node_ptr node_ptr;
typedef typename NodeTraits::const_node_ptr const_node_ptr;
typedef NodeTraits node_traits;
//A simple struct containing:
//
// typedef node_ptr type;
// node_ptr first;
// node_ptr second;
typedef twin<node_ptr> node_pair;
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
//! <b>Effects</b>: Constructs an non-used list element, putting the next
//! pointer to null:
//! <tt>NodeTraits::get_next(this_node) == node_ptr()</tt>
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static void init(node_ptr this_node) BOOST_NOEXCEPT;
//! <b>Requires</b>: this_node must be in a circular list or be an empty circular list.
//!
//! <b>Effects</b>: Returns true is "this_node" is the only node of a circular list:
//! or it's a not inserted node:
//! <tt>return node_ptr() == NodeTraits::get_next(this_node) || NodeTraits::get_next(this_node) == this_node</tt>
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static bool unique(const_node_ptr this_node) BOOST_NOEXCEPT;
//! <b>Effects</b>: Returns true is "this_node" has the same state as if
//! it was inited using "init(node_ptr)"
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static bool inited(const_node_ptr this_node) BOOST_NOEXCEPT;
//! <b>Requires</b>: prev_node must be in a circular list or be an empty circular list.
//!
//! <b>Effects</b>: Unlinks the next node of prev_node from the circular list.
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static void unlink_after(node_ptr prev_node) BOOST_NOEXCEPT;
//! <b>Requires</b>: prev_node and last_node must be in a circular list
//! or be an empty circular list.
//!
//! <b>Effects</b>: Unlinks the range (prev_node, last_node) from the linear list.
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static void unlink_after(node_ptr prev_node, node_ptr last_node) BOOST_NOEXCEPT;
//! <b>Requires</b>: prev_node must be a node of a linear list.
//!
//! <b>Effects</b>: Links this_node after prev_node in the linear list.
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static void link_after(node_ptr prev_node, node_ptr this_node) BOOST_NOEXCEPT;
//! <b>Requires</b>: b and e must be nodes of the same linear list or an empty range.
//! and p must be a node of a different linear list.
//!
//! <b>Effects</b>: Removes the nodes from (b, e] range from their linear list and inserts
//! them after p in p's linear list.
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static void transfer_after(node_ptr p, node_ptr b, node_ptr e) BOOST_NOEXCEPT;
#endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
//! <b>Effects</b>: Constructs an empty list, making this_node the only
//! node of the circular list:
//! <tt>NodeTraits::get_next(this_node) == this_node</tt>.
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
BOOST_INTRUSIVE_FORCEINLINE static void init_header(node_ptr this_node) BOOST_NOEXCEPT
{ NodeTraits::set_next(this_node, node_ptr ()); }
//! <b>Requires</b>: this_node and prev_init_node must be in the same linear list.
//!
//! <b>Effects</b>: Returns the previous node of this_node in the linear list starting.
//! the search from prev_init_node. The first node checked for equality
//! is NodeTraits::get_next(prev_init_node).
//!
//! <b>Complexity</b>: Linear to the number of elements between prev_init_node and this_node.
//!
//! <b>Throws</b>: Nothing.
BOOST_INTRUSIVE_FORCEINLINE static node_ptr
get_previous_node(node_ptr prev_init_node, node_ptr this_node) BOOST_NOEXCEPT
{ return base_t::get_previous_node(prev_init_node, this_node); }
//! <b>Requires</b>: this_node must be in a linear list or be an empty linear list.
//!
//! <b>Effects</b>: Returns the number of nodes in a linear list. If the linear list
//! is empty, returns 1.
//!
//! <b>Complexity</b>: Linear
//!
//! <b>Throws</b>: Nothing.
static std::size_t count(const_node_ptr this_node) BOOST_NOEXCEPT
{
std::size_t result = 0;
const_node_ptr p = this_node;
do{
p = NodeTraits::get_next(p);
++result;
} while (p);
return result;
}
//! <b>Requires</b>: this_node and other_node must be nodes inserted
//! in linear lists or be empty linear lists.
//!
//! <b>Effects</b>: Moves all the nodes previously chained after this_node after other_node
//! and vice-versa.
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
BOOST_INTRUSIVE_FORCEINLINE static void swap_trailing_nodes(node_ptr this_node, node_ptr other_node) BOOST_NOEXCEPT
{
node_ptr this_nxt = NodeTraits::get_next(this_node);
node_ptr other_nxt = NodeTraits::get_next(other_node);
NodeTraits::set_next(this_node, other_nxt);
NodeTraits::set_next(other_node, this_nxt);
}
//! <b>Effects</b>: Reverses the order of elements in the list.
//!
//! <b>Returns</b>: The new first node of the list.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: This function is linear to the contained elements.
static node_ptr reverse(node_ptr p) BOOST_NOEXCEPT
{
if(!p) return node_ptr();
node_ptr i = NodeTraits::get_next(p);
node_ptr first(p);
while(i){
node_ptr nxti(NodeTraits::get_next(i));
base_t::unlink_after(p);
NodeTraits::set_next(i, first);
first = i;
i = nxti;
}
return first;
}
//! <b>Effects</b>: Moves the first n nodes starting at p to the end of the list.
//!
//! <b>Returns</b>: A pair containing the new first and last node of the list or
//! if there has been any movement, a null pair if n leads to no movement.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear to the number of elements plus the number moved positions.
static node_pair move_first_n_backwards(node_ptr p, std::size_t n) BOOST_NOEXCEPT
{
node_pair ret;
//Null shift, or count() == 0 or 1, nothing to do
if(!n || !p || !NodeTraits::get_next(p)){
return ret;
}
node_ptr first = p;
bool end_found = false;
node_ptr new_last = node_ptr();
node_ptr old_last = node_ptr();
//Now find the new last node according to the shift count.
//If we find 0 before finding the new last node
//unlink p, shortcut the search now that we know the size of the list
//and continue.
for(std::size_t i = 1; i <= n; ++i){
new_last = first;
first = NodeTraits::get_next(first);
if(first == node_ptr()){
//Shortcut the shift with the modulo of the size of the list
n %= i;
if(!n) return ret;
old_last = new_last;
i = 0;
//Unlink p and continue the new first node search
first = p;
//unlink_after(new_last);
end_found = true;
}
}
//If the p has not been found in the previous loop, find it
//starting in the new first node and unlink it
if(!end_found){
old_last = base_t::get_previous_node(first, node_ptr());
}
//Now link p after the new last node
NodeTraits::set_next(old_last, p);
NodeTraits::set_next(new_last, node_ptr());
ret.first = first;
ret.second = new_last;
return ret;
}
//! <b>Effects</b>: Moves the first n nodes starting at p to the beginning of the list.
//!
//! <b>Returns</b>: A pair containing the new first and last node of the list or
//! if there has been any movement, a null pair if n leads to no movement.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear to the number of elements plus the number moved positions.
static node_pair move_first_n_forward(node_ptr p, std::size_t n) BOOST_NOEXCEPT
{
node_pair ret;
//Null shift, or count() == 0 or 1, nothing to do
if(!n || !p || !NodeTraits::get_next(p))
return ret;
node_ptr first = p;
//Iterate until p is found to know where the current last node is.
//If the shift count is less than the size of the list, we can also obtain
//the position of the new last node after the shift.
node_ptr old_last(first), next_to_it, new_last(p);
std::size_t distance = 1;
while(!!(next_to_it = node_traits::get_next(old_last))){
if(distance++ > n)
new_last = node_traits::get_next(new_last);
old_last = next_to_it;
}
//If the shift was bigger or equal than the size, obtain the equivalent
//forward shifts and find the new last node.
if(distance <= n){
//Now find the equivalent forward shifts.
//Shortcut the shift with the modulo of the size of the list
std::size_t new_before_last_pos = (distance - (n % distance))% distance;
//If the shift is a multiple of the size there is nothing to do
if(!new_before_last_pos)
return ret;
for( new_last = p
; --new_before_last_pos
; new_last = node_traits::get_next(new_last)){
//empty
}
}
//Get the first new node
node_ptr new_first(node_traits::get_next(new_last));
//Now put the old beginning after the old end
NodeTraits::set_next(old_last, p);
NodeTraits::set_next(new_last, node_ptr());
ret.first = new_first;
ret.second = new_last;
return ret;
}
};
/// @cond
template<class NodeTraits>
struct get_algo<LinearSListAlgorithms, NodeTraits>
{
typedef linear_slist_algorithms<NodeTraits> type;
};
/// @endcond
} //namespace intrusive
} //namespace boost
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_LINEAR_SLIST_ALGORITHMS_HPP

View File

@@ -0,0 +1,63 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2013
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_LINK_MODE_HPP
#define BOOST_INTRUSIVE_LINK_MODE_HPP
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
namespace boost {
namespace intrusive {
//!This enumeration defines the type of value_traits that can be defined
//!for Boost.Intrusive containers
enum link_mode_type{
//!If this linking policy is specified in a value_traits class
//!as the link_mode, containers
//!configured with such value_traits won't set the hooks
//!of the erased values to a default state. Containers also won't
//!check that the hooks of the new values are default initialized.
normal_link,
//!If this linking policy is specified in a value_traits class
//!as the link_mode, containers
//!configured with such value_traits will set the hooks
//!of the erased values to a default state. Containers also will
//!check that the hooks of the new values are default initialized.
safe_link,
//!Same as "safe_link" but the user type is an auto-unlink
//!type, so the containers with constant-time size features won't be
//!compatible with value_traits configured with this policy.
//!Containers also know that the a value can be silently erased from
//!the container without using any function provided by the containers.
auto_unlink
};
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
template <link_mode_type link_mode>
struct is_safe_autounlink
{
static const bool value =
(int)link_mode == (int)auto_unlink ||
(int)link_mode == (int)safe_link;
};
#endif //BOOST_INTRUSIVE_DOXYGEN_INVOKED
} //namespace intrusive
} //namespace boost
#endif //BOOST_INTRUSIVE_LINK_MODE_HPP

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,289 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
// (C) Copyright Ion Gaztanaga 2006-2013
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_LIST_HOOK_HPP
#define BOOST_INTRUSIVE_LIST_HOOK_HPP
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/intrusive/detail/list_node.hpp>
#include <boost/intrusive/circular_list_algorithms.hpp>
#include <boost/intrusive/options.hpp>
#include <boost/intrusive/detail/generic_hook.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
namespace boost {
namespace intrusive {
//! Helper metafunction to define a \c \c list_base_hook that yields to the same
//! type when the same options (either explicitly or implicitly) are used.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class ...Options>
#else
template<class O1 = void, class O2 = void, class O3 = void>
#endif
struct make_list_base_hook
{
/// @cond
typedef typename pack_options
< hook_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
O1, O2, O3
#else
Options...
#endif
>::type packed_options;
typedef generic_hook
< CircularListAlgorithms
, list_node_traits<typename packed_options::void_pointer>
, typename packed_options::tag
, packed_options::link_mode
, ListBaseHookId
> implementation_defined;
/// @endcond
typedef implementation_defined type;
};
//! Derive a class from this hook in order to store objects of that class
//! in an list.
//!
//! The hook admits the following options: \c tag<>, \c void_pointer<> and
//! \c link_mode<>.
//!
//! \c tag<> defines a tag to identify the node.
//! The same tag value can be used in different classes, but if a class is
//! derived from more than one \c list_base_hook, then each \c list_base_hook needs its
//! unique tag.
//!
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
//! \c auto_unlink or \c safe_link).
//!
//! \c void_pointer<> is the pointer type that will be used internally in the hook
//! and the container configured to use this hook.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class ...Options>
#else
template<class O1, class O2, class O3>
#endif
class list_base_hook
: public make_list_base_hook
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
<O1, O2, O3>
#else
<Options...>
#endif
::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.
//!
//! <b>Throws</b>: Nothing.
list_base_hook() BOOST_NOEXCEPT;
//! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state. The argument is ignored.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Rationale</b>: Providing a copy-constructor
//! makes classes using the hook STL-compliant without forcing the
//! user to do some additional work. \c swap can be used to emulate
//! move-semantics.
list_base_hook(const list_base_hook& ) BOOST_NOEXCEPT;
//! <b>Effects</b>: Empty function. The argument is ignored.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Rationale</b>: Providing an assignment operator
//! makes classes using the hook STL-compliant without forcing the
//! user to do some additional work. \c swap can be used to emulate
//! move-semantics.
list_base_hook& operator=(const list_base_hook& ) BOOST_NOEXCEPT;
//! <b>Effects</b>: If link_mode is \c normal_link, the destructor does
//! nothing (ie. no code is generated). If link_mode is \c safe_link and the
//! object is stored in an list an assertion is raised. If link_mode is
//! \c auto_unlink and \c is_linked() is true, the node is unlinked.
//!
//! <b>Throws</b>: Nothing.
~list_base_hook();
//! <b>Effects</b>: Swapping two nodes swaps the position of the elements
//! related to those nodes in one or two containers. That is, if the node
//! this is part of the element e1, the node x is part of the element e2
//! and both elements are included in the containers s1 and s2, then after
//! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1
//! at the position of e1. If one element is not in a container, then
//! after the swap-operation the other element is not in a container.
//! Iterators to e1 and e2 related to those nodes are invalidated.
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
void swap_nodes(list_base_hook &other) BOOST_NOEXCEPT;
//! <b>Precondition</b>: link_mode must be \c safe_link or \c auto_unlink.
//!
//! <b>Returns</b>: true, if the node belongs to a container, false
//! otherwise. This function can be used to test whether \c list::iterator_to
//! will return a valid iterator.
//!
//! <b>Complexity</b>: Constant
bool is_linked() const;
//! <b>Effects</b>: Removes the node if it's inserted in a container.
//! This function is only allowed if link_mode is \c auto_unlink.
//!
//! <b>Throws</b>: Nothing.
void unlink() BOOST_NOEXCEPT;
#endif
};
//! Helper metafunction to define a \c \c list_member_hook that yields to the same
//! type when the same options (either explicitly or implicitly) are used.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class ...Options>
#else
template<class O1 = void, class O2 = void, class O3 = void>
#endif
struct make_list_member_hook
{
/// @cond
typedef typename pack_options
< hook_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
O1, O2, O3
#else
Options...
#endif
>::type packed_options;
typedef generic_hook
< CircularListAlgorithms
, list_node_traits<typename packed_options::void_pointer>
, member_tag
, packed_options::link_mode
, NoBaseHookId
> implementation_defined;
/// @endcond
typedef implementation_defined type;
};
//! Store this hook in a class to be inserted
//! in an list.
//!
//! The hook admits the following options: \c void_pointer<> and
//! \c link_mode<>.
//!
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
//! \c auto_unlink or \c safe_link).
//!
//! \c void_pointer<> is the pointer type that will be used internally in the hook
//! and the container configured to use this hook.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class ...Options>
#else
template<class O1, class O2, class O3>
#endif
class list_member_hook
: public make_list_member_hook
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
<O1, O2, O3>
#else
<Options...>
#endif
::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.
//!
//! <b>Throws</b>: Nothing.
list_member_hook() BOOST_NOEXCEPT;
//! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state. The argument is ignored.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Rationale</b>: Providing a copy-constructor
//! makes classes using the hook STL-compliant without forcing the
//! user to do some additional work. \c swap can be used to emulate
//! move-semantics.
list_member_hook(const list_member_hook& ) BOOST_NOEXCEPT;
//! <b>Effects</b>: Empty function. The argument is ignored.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Rationale</b>: Providing an assignment operator
//! makes classes using the hook STL-compliant without forcing the
//! user to do some additional work. \c swap can be used to emulate
//! move-semantics.
list_member_hook& operator=(const list_member_hook& ) BOOST_NOEXCEPT;
//! <b>Effects</b>: If link_mode is \c normal_link, the destructor does
//! nothing (ie. no code is generated). If link_mode is \c safe_link and the
//! object is stored in an list an assertion is raised. If link_mode is
//! \c auto_unlink and \c is_linked() is true, the node is unlinked.
//!
//! <b>Throws</b>: Nothing.
~list_member_hook();
//! <b>Effects</b>: Swapping two nodes swaps the position of the elements
//! related to those nodes in one or two containers. That is, if the node
//! this is part of the element e1, the node x is part of the element e2
//! and both elements are included in the containers s1 and s2, then after
//! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1
//! at the position of e1. If one element is not in a container, then
//! after the swap-operation the other element is not in a container.
//! Iterators to e1 and e2 related to those nodes are invalidated.
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
void swap_nodes(list_member_hook &other) BOOST_NOEXCEPT;
//! <b>Precondition</b>: link_mode must be \c safe_link or \c auto_unlink.
//!
//! <b>Returns</b>: true, if the node belongs to a container, false
//! otherwise. This function can be used to test whether \c list::iterator_to
//! will return a valid iterator.
//!
//! <b>Complexity</b>: Constant
bool is_linked() const;
//! <b>Effects</b>: Removes the node if it's inserted in a container.
//! This function is only allowed if link_mode is \c auto_unlink.
//!
//! <b>Throws</b>: Nothing.
void unlink() BOOST_NOEXCEPT;
#endif
};
} //namespace intrusive
} //namespace boost
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_LIST_HOOK_HPP

View File

@@ -0,0 +1,85 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2013
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_MEMBER_VALUE_TRAITS_HPP
#define BOOST_INTRUSIVE_MEMBER_VALUE_TRAITS_HPP
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/intrusive/link_mode.hpp>
#include <boost/intrusive/detail/parent_from_member.hpp>
#include <boost/move/detail/to_raw_pointer.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
namespace boost {
namespace intrusive {
//!This value traits template is used to create value traits
//!from user defined node traits where value_traits::value_type will
//!store a node_traits::node
template< class T, class NodeTraits
, typename NodeTraits::node T::* PtrToMember
, link_mode_type LinkMode
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
= safe_link
#endif
>
struct member_value_traits
{
public:
typedef NodeTraits node_traits;
typedef T value_type;
typedef typename node_traits::node node;
typedef typename node_traits::node_ptr node_ptr;
typedef typename node_traits::const_node_ptr const_node_ptr;
typedef pointer_traits<node_ptr> node_ptr_traits;
typedef typename pointer_traits<node_ptr>::template
rebind_pointer<T>::type pointer;
typedef typename pointer_traits<node_ptr>::template
rebind_pointer<const T>::type const_pointer;
//typedef typename pointer_traits<pointer>::reference reference;
//typedef typename pointer_traits<const_pointer>::reference const_reference;
typedef value_type & reference;
typedef const value_type & const_reference;
static const link_mode_type link_mode = LinkMode;
BOOST_INTRUSIVE_FORCEINLINE static node_ptr to_node_ptr(reference value) BOOST_NOEXCEPT
{ return pointer_traits<node_ptr>::pointer_to(value.*PtrToMember); }
BOOST_INTRUSIVE_FORCEINLINE static const_node_ptr to_node_ptr(const_reference value) BOOST_NOEXCEPT
{ return pointer_traits<const_node_ptr>::pointer_to(value.*PtrToMember); }
BOOST_INTRUSIVE_FORCEINLINE static pointer to_value_ptr(node_ptr n) BOOST_NOEXCEPT
{
return pointer_traits<pointer>::pointer_to(*detail::parent_from_member<value_type, node>
(boost::movelib::to_raw_pointer(n), PtrToMember));
}
BOOST_INTRUSIVE_FORCEINLINE static const_pointer to_value_ptr(const_node_ptr n) BOOST_NOEXCEPT
{
return pointer_traits<const_pointer>::pointer_to(*detail::parent_from_member<value_type, node>
(boost::movelib::to_raw_pointer(n), PtrToMember));
}
};
} //namespace intrusive
} //namespace boost
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_MEMBER_VALUE_TRAITS_HPP

View File

@@ -0,0 +1,264 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_OPTIONS_HPP
#define BOOST_INTRUSIVE_OPTIONS_HPP
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/intrusive/link_mode.hpp>
#include <boost/intrusive/pack_options.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
namespace boost {
namespace intrusive {
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
struct empty
{};
template<class Functor>
struct fhtraits;
template<class T, class Hook, Hook T::* P>
struct mhtraits;
struct dft_tag;
struct member_tag;
template<class SupposedValueTraits>
struct is_default_hook_tag;
#endif //#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//!This option setter specifies if the intrusive
//!container stores its size as a member to
//!obtain constant-time size() member.
BOOST_INTRUSIVE_OPTION_CONSTANT(constant_time_size, bool, Enabled, constant_time_size)
//!This option setter specifies a container header holder type
BOOST_INTRUSIVE_OPTION_TYPE(header_holder_type, HeaderHolder, HeaderHolder, header_holder_type)
//!This option setter specifies the type that
//!the container will use to store its size.
BOOST_INTRUSIVE_OPTION_TYPE(size_type, SizeType, SizeType, size_type)
//!This option setter specifies the strict weak ordering
//!comparison functor for the value type
BOOST_INTRUSIVE_OPTION_TYPE(compare, Compare, Compare, compare)
//!This option setter specifies a function object
//!that specifies the type of the key of an associative
//!container and an operator to obtain it from a value type.
//!
//!This function object must the define a `type` member typedef and
//!a member with signature `type [const&] operator()(const value_type &) const`
//!that will return the key from a value_type of an associative container
BOOST_INTRUSIVE_OPTION_TYPE(key_of_value, KeyOfValue, KeyOfValue, key_of_value)
//!This option setter specifies a function object
//!that specifies the type of the priority of a treap
//!container and an operator to obtain it from a value type.
//!
//!This function object must the define a `type` member typedef and
//!a member with signature `type [const&] operator()(const value_type &) const`
//!that will return the priority from a value_type of a treap container
BOOST_INTRUSIVE_OPTION_TYPE(priority_of_value, PrioOfValue, PrioOfValue, priority_of_value)
//!This option setter for scapegoat containers specifies if
//!the intrusive scapegoat container should use a non-variable
//!alpha value that does not need floating-point operations.
//!
//!If activated, the fixed alpha value is 1/sqrt(2). This
//!option also saves some space in the container since
//!the alpha value and some additional data does not need
//!to be stored in the container.
//!
//!If the user only needs an alpha value near 1/sqrt(2), this
//!option also improves performance since avoids logarithm
//!and division operations when rebalancing the tree.
BOOST_INTRUSIVE_OPTION_CONSTANT(floating_point, bool, Enabled, floating_point)
//!This option setter specifies the equality
//!functor for the value type
BOOST_INTRUSIVE_OPTION_TYPE(equal, Equal, Equal, equal)
//!This option setter specifies the priority comparison
//!functor for the value type
BOOST_INTRUSIVE_OPTION_TYPE(priority, Priority, Priority, priority)
//!This option setter specifies the hash
//!functor for the value type
BOOST_INTRUSIVE_OPTION_TYPE(hash, Hash, Hash, hash)
//!This option setter specifies the relationship between the type
//!to be managed by the container (the value type) and the node to be
//!used in the node algorithms. It also specifies the linking policy.
BOOST_INTRUSIVE_OPTION_TYPE(value_traits, ValueTraits, ValueTraits, proto_value_traits)
//#define BOOST_INTRUSIVE_COMMA ,
//#define BOOST_INTRUSIVE_LESS <
//#define BOOST_INTRUSIVE_MORE >
//BOOST_INTRUSIVE_OPTION_TYPE (member_hook, Parent BOOST_INTRUSIVE_COMMA class MemberHook BOOST_INTRUSIVE_COMMA MemberHook Parent::* PtrToMember , mhtraits BOOST_INTRUSIVE_LESS Parent BOOST_INTRUSIVE_COMMA MemberHook BOOST_INTRUSIVE_COMMA PtrToMember BOOST_INTRUSIVE_MORE , proto_value_traits)
//template< class Parent , class MemberHook , MemberHook Parent::* PtrToMember>
//struct member_hook {
// template<class Base> struct pack : Base {
// typedef mhtraits < Parent , MemberHook , PtrToMember > proto_value_traits;
// };
//};
//
//#undef BOOST_INTRUSIVE_COMMA
//#undef BOOST_INTRUSIVE_LESS
//#undef BOOST_INTRUSIVE_MORE
//!This option setter specifies the member hook the
//!container must use.
template< typename Parent
, typename MemberHook
, MemberHook Parent::* PtrToMember>
struct member_hook
{
// @cond
// typedef typename MemberHook::hooktags::node_traits node_traits;
// typedef typename node_traits::node node_type;
// typedef node_type Parent::* Ptr2MemNode;
// typedef mhtraits
// < Parent
// , node_traits
// //This cast is really ugly but necessary to reduce template bloat.
// //Since we control the layout between the hook and the node, and there is
// //always single inheritance, the offset of the node is exactly the offset of
// //the hook. Since the node type is shared between all member hooks, this saves
// //quite a lot of symbol stuff.
// , (Ptr2MemNode)PtrToMember
// , MemberHook::hooktags::link_mode> member_value_traits;
typedef mhtraits <Parent, MemberHook, PtrToMember> member_value_traits;
template<class Base>
struct pack : Base
{
typedef member_value_traits proto_value_traits;
};
/// @endcond
};
//!This option setter specifies the function object that will
//!be used to convert between values to be inserted in a container
//!and the hook to be used for that purpose.
BOOST_INTRUSIVE_OPTION_TYPE(function_hook, Functor, fhtraits<Functor>, proto_value_traits)
//!This option setter specifies that the container
//!must use the specified base hook
BOOST_INTRUSIVE_OPTION_TYPE(base_hook, BaseHook, BaseHook, proto_value_traits)
//!This option setter specifies the type of
//!a void pointer. This will instruct the hook
//!to use this type of pointer instead of the
//!default one
BOOST_INTRUSIVE_OPTION_TYPE(void_pointer, VoidPointer, VoidPointer, void_pointer)
//!This option setter specifies the type of
//!the tag of a base hook. A type cannot have two
//!base hooks of the same type, so a tag can be used
//!to differentiate two base hooks with otherwise same type
BOOST_INTRUSIVE_OPTION_TYPE(tag, Tag, Tag, tag)
//!This option setter specifies the link mode
//!(normal_link, safe_link or auto_unlink)
BOOST_INTRUSIVE_OPTION_CONSTANT(link_mode, link_mode_type, LinkType, link_mode)
//!This option setter specifies if the hook
//!should be optimized for size instead of for speed.
BOOST_INTRUSIVE_OPTION_CONSTANT(optimize_size, bool, Enabled, optimize_size)
//!This option setter specifies if the slist container should
//!use a linear implementation instead of a circular one.
BOOST_INTRUSIVE_OPTION_CONSTANT(linear, bool, Enabled, linear)
//!If true, slist also stores a pointer to the last element of the singly linked list.
//!This allows O(1) swap and splice_after(iterator, slist &) for circular slists and makes
//!possible new functions like push_back(reference) and back().
BOOST_INTRUSIVE_OPTION_CONSTANT(cache_last, bool, Enabled, cache_last)
//!This option setter specifies the bucket traits
//!class for unordered associative containers. When this option is specified,
//!instead of using the default bucket traits, a user defined holder will be defined
BOOST_INTRUSIVE_OPTION_TYPE(bucket_traits, BucketTraits, BucketTraits, bucket_traits)
//!This option setter specifies if the unordered hook
//!should offer room to store the hash value.
//!Storing the hash in the hook will speed up rehashing
//!processes in applications where rehashing is frequent,
//!rehashing might throw or the value is heavy to hash.
BOOST_INTRUSIVE_OPTION_CONSTANT(store_hash, bool, Enabled, store_hash)
//!This option setter specifies if the unordered hook
//!should offer room to store another link to another node
//!with the same key.
//!Storing this link will speed up lookups and insertions on
//!unordered_multiset containers with a great number of elements
//!with the same key.
BOOST_INTRUSIVE_OPTION_CONSTANT(optimize_multikey, bool, Enabled, optimize_multikey)
//!This option setter specifies if the bucket array will be always power of two.
//!This allows using masks instead of the default modulo operation to determine
//!the bucket number from the hash value, leading to better performance.
//!In debug mode, if power of two buckets mode is activated, the bucket length
//!will be checked with assertions.
BOOST_INTRUSIVE_OPTION_CONSTANT(power_2_buckets, bool, Enabled, power_2_buckets)
//!This option setter specifies if the container will cache a pointer to the first
//!non-empty bucket so that begin() is always constant-time.
//!This is specially helpful when we can have containers with a few elements
//!but with big bucket arrays (that is, hashtables with low load factors).
BOOST_INTRUSIVE_OPTION_CONSTANT(cache_begin, bool, Enabled, cache_begin)
//!This option setter specifies if the container will compare the hash value
//!before comparing objects. This option can't be specified if store_hash<>
//!is not true.
//!This is specially helpful when we have containers with a high load factor.
//!and the comparison function is much more expensive that comparing already
//!stored hash values.
BOOST_INTRUSIVE_OPTION_CONSTANT(compare_hash, bool, Enabled, compare_hash)
//!This option setter specifies if the hash container will use incremental
//!hashing. With incremental hashing the cost of hash table expansion is spread
//!out across each hash table insertion operation, as opposed to be incurred all at once.
//!Therefore linear hashing is well suited for interactive applications or real-time
//!appplications where the worst-case insertion time of non-incremental hash containers
//!(rehashing the whole bucket array) is not admisible.
BOOST_INTRUSIVE_OPTION_CONSTANT(incremental, bool, Enabled, incremental)
/// @cond
struct hook_defaults
{
typedef void* void_pointer;
static const link_mode_type link_mode = safe_link;
typedef dft_tag tag;
static const bool optimize_size = false;
static const bool store_hash = false;
static const bool linear = false;
static const bool optimize_multikey = false;
};
/// @endcond
} //namespace intrusive {
} //namespace boost {
#include <boost/intrusive/detail/config_end.hpp>
#endif //#ifndef BOOST_INTRUSIVE_OPTIONS_HPP

View File

@@ -0,0 +1,382 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2013-2013
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_PACK_OPTIONS_HPP
#define BOOST_INTRUSIVE_PACK_OPTIONS_HPP
#include <boost/intrusive/detail/config_begin.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <cstddef>
namespace boost {
namespace intrusive {
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class Prev, class Next>
struct do_pack
{
//Use "pack" member template to pack options
typedef typename Next::template pack<Prev> type;
};
template<class Prev>
struct do_pack<Prev, void>
{
//Avoid packing "void" to shorten template names
typedef Prev type;
};
template
< class DefaultOptions
, class O1 = void
, class O2 = void
, class O3 = void
, class O4 = void
, class O5 = void
, class O6 = void
, class O7 = void
, class O8 = void
, class O9 = void
, class O10 = void
, class O11 = void
>
struct pack_options
{
// join options
typedef
typename do_pack
< typename do_pack
< typename do_pack
< typename do_pack
< typename do_pack
< typename do_pack
< typename do_pack
< typename do_pack
< typename do_pack
< typename do_pack
< typename do_pack
< DefaultOptions
, O1
>::type
, O2
>::type
, O3
>::type
, O4
>::type
, O5
>::type
, O6
>::type
, O7
>::type
, O8
>::type
, O9
>::type
, O10
>::type
, O11
>::type
type;
};
#else
//index_tuple
template<std::size_t... Indexes>
struct index_tuple{};
//build_number_seq
template<std::size_t Num, typename Tuple = index_tuple<> >
struct build_number_seq;
template<std::size_t Num, std::size_t... Indexes>
struct build_number_seq<Num, index_tuple<Indexes...> >
: build_number_seq<Num - 1, index_tuple<Indexes..., sizeof...(Indexes)> >
{};
template<std::size_t... Indexes>
struct build_number_seq<0, index_tuple<Indexes...> >
{ typedef index_tuple<Indexes...> type; };
template<class ...Types>
struct typelist
{};
//invert_typelist
template<class T>
struct invert_typelist;
template<std::size_t I, typename Tuple>
struct typelist_element;
template<std::size_t I, typename Head, typename... Tail>
struct typelist_element<I, typelist<Head, Tail...> >
{
typedef typename typelist_element<I-1, typelist<Tail...> >::type type;
};
template<typename Head, typename... Tail>
struct typelist_element<0, typelist<Head, Tail...> >
{
typedef Head type;
};
template<std::size_t ...Ints, class ...Types>
typelist<typename typelist_element<(sizeof...(Types) - 1) - Ints, typelist<Types...> >::type...>
inverted_typelist(index_tuple<Ints...>, typelist<Types...>)
{
return typelist<typename typelist_element<(sizeof...(Types) - 1) - Ints, typelist<Types...> >::type...>();
}
//sizeof_typelist
template<class Typelist>
struct sizeof_typelist;
template<class ...Types>
struct sizeof_typelist< typelist<Types...> >
{
static const std::size_t value = sizeof...(Types);
};
//invert_typelist_impl
template<class Typelist, class Indexes>
struct invert_typelist_impl;
template<class Typelist, std::size_t ...Ints>
struct invert_typelist_impl< Typelist, index_tuple<Ints...> >
{
static const std::size_t last_idx = sizeof_typelist<Typelist>::value - 1;
typedef typelist
<typename typelist_element<last_idx - Ints, Typelist>::type...> type;
};
template<class Typelist, std::size_t Int>
struct invert_typelist_impl< Typelist, index_tuple<Int> >
{
typedef Typelist type;
};
template<class Typelist>
struct invert_typelist_impl< Typelist, index_tuple<> >
{
typedef Typelist type;
};
//invert_typelist
template<class Typelist>
struct invert_typelist;
template<class ...Types>
struct invert_typelist< typelist<Types...> >
{
typedef typelist<Types...> typelist_t;
typedef typename build_number_seq<sizeof...(Types)>::type indexes_t;
typedef typename invert_typelist_impl<typelist_t, indexes_t>::type type;
};
//Do pack
template<class Typelist>
struct do_pack;
template<>
struct do_pack<typelist<> >;
template<class Prev>
struct do_pack<typelist<Prev> >
{
typedef Prev type;
};
template<class Prev, class Last>
struct do_pack<typelist<Prev, Last> >
{
typedef typename Prev::template pack<Last> type;
};
template<class ...Others>
struct do_pack<typelist<void, Others...> >
{
typedef typename do_pack<typelist<Others...> >::type type;
};
template<class Prev, class ...Others>
struct do_pack<typelist<Prev, Others...> >
{
typedef typename Prev::template pack
<typename do_pack<typelist<Others...> >::type> type;
};
template<class DefaultOptions, class ...Options>
struct pack_options
{
typedef typelist<DefaultOptions, Options...> typelist_t;
typedef typename invert_typelist<typelist_t>::type inverted_typelist;
typedef typename do_pack<inverted_typelist>::type type;
};
#endif //!defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
#define BOOST_INTRUSIVE_OPTION_TYPE(OPTION_NAME, TYPE, TYPEDEF_EXPR, TYPEDEF_NAME) \
template< class TYPE> \
struct OPTION_NAME \
{ \
template<class Base> \
struct pack : Base \
{ \
typedef TYPEDEF_EXPR TYPEDEF_NAME; \
}; \
}; \
//
#define BOOST_INTRUSIVE_OPTION_CONSTANT(OPTION_NAME, TYPE, VALUE, CONSTANT_NAME) \
template< TYPE VALUE> \
struct OPTION_NAME \
{ \
template<class Base> \
struct pack : Base \
{ \
static const TYPE CONSTANT_NAME = VALUE; \
}; \
}; \
//
#else //#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! This class is a utility that takes:
//! - a default options class defining initial static constant
//! and typedefs
//! - several options defined with BOOST_INTRUSIVE_OPTION_CONSTANT and
//! BOOST_INTRUSIVE_OPTION_TYPE
//!
//! and packs them together in a new type that defines all options as
//! member typedefs or static constant values. Given options of form:
//!
//! \code
//! BOOST_INTRUSIVE_OPTION_TYPE(my_pointer, VoidPointer, VoidPointer, my_pointer_type)
//! BOOST_INTRUSIVE_OPTION_CONSTANT(incremental, bool, Enabled, is_incremental)
//! \endcode
//!
//! the following expression
//!
//! \code
//!
//! struct default_options
//! {
//! typedef long int_type;
//! static const int int_constant = -1;
//! };
//!
//! pack_options< default_options, my_pointer<void*>, incremental<true> >::type
//! \endcode
//!
//! will create a type that will contain the following typedefs/constants
//!
//! \code
//! struct unspecified_type
//! {
//! //Default options
//! typedef long int_type;
//! static const int int_constant = -1;
//!
//! //Packed options (will ovewrite any default option)
//! typedef void* my_pointer_type;
//! static const bool is_incremental = true;
//! };
//! \endcode
//!
//! If an option is specified in the default options argument and later
//! redefined as an option, the last definition will prevail.
template<class DefaultOptions, class ...Options>
struct pack_options
{
typedef unspecified_type type;
};
//! Defines an option class of name OPTION_NAME that can be used to specify a type
//! of type TYPE...
//!
//! \code
//! struct OPTION_NAME<class TYPE>
//! { unspecified_content };
//! \endcode
//!
//! ...that after being combined with
//! <code>boost::intrusive::pack_options</code>,
//! will typedef TYPE as a typedef of name TYPEDEF_NAME. Example:
//!
//! \code
//! //[includes and namespaces omitted for brevity]
//!
//! //This macro will create the following class:
//! // template<class VoidPointer>
//! // struct my_pointer
//! // { unspecified_content };
//! BOOST_INTRUSIVE_OPTION_TYPE(my_pointer, VoidPointer, boost::remove_pointer<VoidPointer>::type, my_pointer_type)
//!
//! struct empty_default{};
//!
//! typedef pack_options< empty_default, typename my_pointer<void*> >::type::my_pointer_type type;
//!
//! BOOST_STATIC_ASSERT(( boost::is_same<type, void>::value ));
//!
//! \endcode
#define BOOST_INTRUSIVE_OPTION_TYPE(OPTION_NAME, TYPE, TYPEDEF_EXPR, TYPEDEF_NAME)
//! Defines an option class of name OPTION_NAME that can be used to specify a constant
//! of type TYPE with value VALUE...
//!
//! \code
//! struct OPTION_NAME<TYPE VALUE>
//! { unspecified_content };
//! \endcode
//!
//! ...that after being combined with
//! <code>boost::intrusive::pack_options</code>,
//! will contain a CONSTANT_NAME static constant of value VALUE. Example:
//!
//! \code
//! //[includes and namespaces omitted for brevity]
//!
//! //This macro will create the following class:
//! // template<bool Enabled>
//! // struct incremental
//! // { unspecified_content };
//! BOOST_INTRUSIVE_OPTION_CONSTANT(incremental, bool, Enabled, is_incremental)
//!
//! struct empty_default{};
//!
//! const bool is_incremental = pack_options< empty_default, incremental<true> >::type::is_incremental;
//!
//! BOOST_STATIC_ASSERT(( is_incremental == true ));
//!
//! \endcode
#define BOOST_INTRUSIVE_OPTION_CONSTANT(OPTION_NAME, TYPE, VALUE, CONSTANT_NAME)
#endif //#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
} //namespace intrusive {
} //namespace boost {
#include <boost/intrusive/detail/config_end.hpp>
#endif //#ifndef BOOST_INTRUSIVE_PACK_OPTIONS_HPP

View File

@@ -0,0 +1,49 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2010-2013
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_PARENT_FROM_MEMBER_HPP
#define BOOST_INTRUSIVE_PARENT_FROM_MEMBER_HPP
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/detail/workaround.hpp>
#include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/intrusive/detail/parent_from_member.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
namespace boost {
namespace intrusive {
//! Given a pointer to a member and its corresponding pointer to data member,
//! this function returns the pointer of the parent containing that member.
//! Note: this function does not work with pointer to members that rely on
//! virtual inheritance.
template<class Parent, class Member>
BOOST_INTRUSIVE_FORCEINLINE Parent *get_parent_from_member(Member *member, const Member Parent::* ptr_to_member) BOOST_NOEXCEPT
{ return ::boost::intrusive::detail::parent_from_member(member, ptr_to_member); }
//! Given a const pointer to a member and its corresponding const pointer to data member,
//! this function returns the const pointer of the parent containing that member.
//! Note: this function does not work with pointer to members that rely on
//! virtual inheritance.
template<class Parent, class Member>
BOOST_INTRUSIVE_FORCEINLINE const Parent *get_parent_from_member(const Member *member, const Member Parent::* ptr_to_member) BOOST_NOEXCEPT
{ return ::boost::intrusive::detail::parent_from_member(member, ptr_to_member); }
} //namespace intrusive {
} //namespace boost {
#include <boost/intrusive/detail/config_end.hpp>
#endif //#ifndef BOOST_INTRUSIVE_PARENT_FROM_MEMBER_HPP

View File

@@ -0,0 +1,112 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2013
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_POINTER_PLUS_BITS_HPP
#define BOOST_INTRUSIVE_POINTER_PLUS_BITS_HPP
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/intrusive/detail/mpl.hpp> //ls_zeros
#include <boost/intrusive/detail/assert.hpp> //BOOST_INTRUSIVE_INVARIANT_ASSERT
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
//GCC reports uninitialized values when an uninitialized pointer plus bits type
//is asigned some bits or some pointer value, but that's ok, because we don't want
//to default initialize parts that are not being updated.
#if defined(BOOST_GCC)
# if (BOOST_GCC >= 40600)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wuninitialized"
# if (BOOST_GCC >= 40700)
# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
# endif
# endif
#endif
namespace boost {
namespace intrusive {
//!This trait class is used to know if a pointer
//!can embed extra bits of information if
//!it's going to be used to point to objects
//!with an alignment of "Alignment" bytes.
template<class VoidPointer, std::size_t Alignment>
struct max_pointer_plus_bits
{
static const std::size_t value = 0;
};
//!This is a specialization for raw pointers.
//!Raw pointers can embed extra bits in the lower bits
//!if the alignment is multiple of 2pow(NumBits).
template<std::size_t Alignment>
struct max_pointer_plus_bits<void*, Alignment>
{
static const std::size_t value = detail::ls_zeros<Alignment>::value;
};
//!This is class that is supposed to have static methods
//!to embed extra bits of information in a pointer.
//!This is a declaration and there is no default implementation,
//!because operations to embed the bits change with every pointer type.
//!
//!An implementation that detects that a pointer type whose
//!has_pointer_plus_bits<>::value is non-zero can make use of these
//!operations to embed the bits in the pointer.
template<class Pointer, std::size_t NumBits>
struct pointer_plus_bits
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
{}
#endif
;
//!This is the specialization to embed extra bits of information
//!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>
{
static const uintptr_t Mask = uintptr_t((uintptr_t(1u) << NumBits) - 1);
typedef T* pointer;
BOOST_INTRUSIVE_FORCEINLINE static pointer get_pointer(pointer n) BOOST_NOEXCEPT
{ return pointer(uintptr_t(n) & uintptr_t(~Mask)); }
BOOST_INTRUSIVE_FORCEINLINE static void set_pointer(pointer &n, pointer p) BOOST_NOEXCEPT
{
BOOST_INTRUSIVE_INVARIANT_ASSERT(0 == (uintptr_t(p) & Mask));
n = pointer(uintptr_t(p) | (uintptr_t(n) & Mask));
}
BOOST_INTRUSIVE_FORCEINLINE static std::size_t get_bits(pointer n) BOOST_NOEXCEPT
{ return std::size_t(uintptr_t(n) & Mask); }
BOOST_INTRUSIVE_FORCEINLINE static void set_bits(pointer &n, std::size_t c) BOOST_NOEXCEPT
{
BOOST_INTRUSIVE_INVARIANT_ASSERT(uintptr_t(c) <= Mask);
n = pointer(uintptr_t((get_pointer)(n)) | uintptr_t(c));
}
};
} //namespace intrusive
} //namespace boost
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
# pragma GCC diagnostic pop
#endif
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_POINTER_PLUS_BITS_HPP

View File

@@ -0,0 +1,188 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2014-2014. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_POINTER_REBIND_HPP
#define BOOST_INTRUSIVE_POINTER_REBIND_HPP
#ifndef BOOST_INTRUSIVE_DETAIL_WORKAROUND_HPP
#include <boost/intrusive/detail/workaround.hpp>
#endif //BOOST_INTRUSIVE_DETAIL_WORKAROUND_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
namespace boost {
namespace intrusive {
///////////////////////////
//struct pointer_rebind_mode
///////////////////////////
template <typename Ptr, typename U>
struct pointer_has_rebind
{
template <typename V> struct any
{ any(const V&) { } };
template <typename X>
static char test(int, typename X::template rebind<U>*);
template <typename X>
static int test(any<int>, void*);
static const bool value = (1 == sizeof(test<Ptr>(0, 0)));
};
template <typename Ptr, typename U>
struct pointer_has_rebind_other
{
template <typename V> struct any
{ any(const V&) { } };
template <typename X>
static char test(int, typename X::template rebind<U>::other*);
template <typename X>
static int test(any<int>, void*);
static const bool value = (1 == sizeof(test<Ptr>(0, 0)));
};
template <typename Ptr, typename U>
struct pointer_rebind_mode
{
static const unsigned int rebind = (unsigned int)pointer_has_rebind<Ptr, U>::value;
static const unsigned int rebind_other = (unsigned int)pointer_has_rebind_other<Ptr, U>::value;
static const unsigned int mode = rebind + rebind*rebind_other;
};
////////////////////////
//struct pointer_rebinder
////////////////////////
template <typename Ptr, typename U, unsigned int RebindMode>
struct pointer_rebinder;
// Implementation of pointer_rebinder<U>::type if Ptr has
// its own rebind<U>::other type (C++03)
template <typename Ptr, typename U>
struct pointer_rebinder< Ptr, U, 2u >
{
typedef typename Ptr::template rebind<U>::other type;
};
// Implementation of pointer_rebinder<U>::type if Ptr has
// its own rebind template.
template <typename Ptr, typename U>
struct pointer_rebinder< Ptr, U, 1u >
{
typedef typename Ptr::template rebind<U> type;
};
// Specialization of pointer_rebinder if Ptr does not
// have its own rebind template but has a the form Ptr<A, An...>,
// where An... comprises zero or more type parameters.
// Many types fit this form, hence many pointers will get a
// reasonable default for rebind.
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <template <class, class...> class Ptr, typename A, class... An, class U>
struct pointer_rebinder<Ptr<A, An...>, U, 0u >
{
typedef Ptr<U, An...> type;
};
//Needed for non-conforming compilers like GCC 4.3
template <template <class> class Ptr, typename A, class U>
struct pointer_rebinder<Ptr<A>, U, 0u >
{
typedef Ptr<U> type;
};
#else //C++03 compilers
template <template <class> class Ptr //0arg
, typename A
, class U>
struct pointer_rebinder<Ptr<A>, U, 0u>
{ typedef Ptr<U> type; };
template <template <class, class> class Ptr //1arg
, typename A, class P0
, class U>
struct pointer_rebinder<Ptr<A, P0>, U, 0u>
{ typedef Ptr<U, P0> type; };
template <template <class, class, class> class Ptr //2arg
, typename A, class P0, class P1
, class U>
struct pointer_rebinder<Ptr<A, P0, P1>, U, 0u>
{ typedef Ptr<U, P0, P1> type; };
template <template <class, class, class, class> class Ptr //3arg
, typename A, class P0, class P1, class P2
, class U>
struct pointer_rebinder<Ptr<A, P0, P1, P2>, U, 0u>
{ typedef Ptr<U, P0, P1, P2> type; };
template <template <class, class, class, class, class> class Ptr //4arg
, typename A, class P0, class P1, class P2, class P3
, class U>
struct pointer_rebinder<Ptr<A, P0, P1, P2, P3>, U, 0u>
{ typedef Ptr<U, P0, P1, P2, P3> type; };
template <template <class, class, class, class, class, class> class Ptr //5arg
, typename A, class P0, class P1, class P2, class P3, class P4
, class U>
struct pointer_rebinder<Ptr<A, P0, P1, P2, P3, P4>, U, 0u>
{ typedef Ptr<U, P0, P1, P2, P3, P4> type; };
template <template <class, class, class, class, class, class, class> class Ptr //6arg
, typename A, class P0, class P1, class P2, class P3, class P4, class P5
, class U>
struct pointer_rebinder<Ptr<A, P0, P1, P2, P3, P4, P5>, U, 0u>
{ typedef Ptr<U, P0, P1, P2, P3, P4, P5> type; };
template <template <class, class, class, class, class, class, class, class> class Ptr //7arg
, typename A, class P0, class P1, class P2, class P3, class P4, class P5, class P6
, class U>
struct pointer_rebinder<Ptr<A, P0, P1, P2, P3, P4, P5, P6>, U, 0u>
{ typedef Ptr<U, P0, P1, P2, P3, P4, P5, P6> type; };
template <template <class, class, class, class, class, class, class, class, class> class Ptr //8arg
, typename A, class P0, class P1, class P2, class P3, class P4, class P5, class P6, class P7
, class U>
struct pointer_rebinder<Ptr<A, P0, P1, P2, P3, P4, P5, P6, P7>, U, 0u>
{ typedef Ptr<U, P0, P1, P2, P3, P4, P5, P6, P7> type; };
template <template <class, class, class, class, class, class, class, class, class, class> class Ptr //9arg
, typename A, class P0, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8
, class U>
struct pointer_rebinder<Ptr<A, P0, P1, P2, P3, P4, P5, P6, P7, P8>, U, 0u>
{ typedef Ptr<U, P0, P1, P2, P3, P4, P5, P6, P7, P8> type; };
#endif //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <typename Ptr, typename U>
struct pointer_rebind
: public pointer_rebinder<Ptr, U, pointer_rebind_mode<Ptr, U>::mode>
{};
template <typename T, typename U>
struct pointer_rebind<T*, U>
{ typedef U* type; };
} //namespace container {
} //namespace boost {
#endif // defined(BOOST_INTRUSIVE_POINTER_REBIND_HPP)

View File

@@ -0,0 +1,326 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Pablo Halpern 2009. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2011-2014. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_POINTER_TRAITS_HPP
#define BOOST_INTRUSIVE_POINTER_TRAITS_HPP
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/detail/workaround.hpp>
#include <boost/intrusive/pointer_rebind.hpp>
#include <boost/move/detail/pointer_element.hpp>
#include <boost/intrusive/detail/mpl.hpp>
#include <cstddef>
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
namespace boost {
namespace intrusive {
namespace detail {
#if !defined(BOOST_MSVC) || (BOOST_MSVC > 1310)
BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(has_member_function_callable_with_pointer_to, pointer_to)
BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(has_member_function_callable_with_dynamic_cast_from, dynamic_cast_from)
BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(has_member_function_callable_with_static_cast_from, static_cast_from)
BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(has_member_function_callable_with_const_cast_from, const_cast_from)
#else
BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED_IGNORE_SIGNATURE(has_member_function_callable_with_pointer_to, pointer_to)
BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED_IGNORE_SIGNATURE(has_member_function_callable_with_dynamic_cast_from, dynamic_cast_from)
BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED_IGNORE_SIGNATURE(has_member_function_callable_with_static_cast_from, static_cast_from)
BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED_IGNORE_SIGNATURE(has_member_function_callable_with_const_cast_from, const_cast_from)
#endif
BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(element_type)
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(difference_type)
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(size_type)
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(reference)
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(value_traits_ptr)
} //namespace detail {
//! pointer_traits is the implementation of C++11 std::pointer_traits class with some
//! extensions like castings.
//!
//! pointer_traits supplies a uniform interface to certain attributes of pointer-like types.
//!
//! <b>Note</b>: When defining a custom family of pointers or references to be used with BI
//! library, make sure the public static conversion functions accessed through
//! the `pointer_traits` interface (`*_cast_from` and `pointer_to`) can
//! properly convert between const and nonconst referred member types
//! <b>without the use of implicit constructor calls</b>. It is suggested these
//! conversions be implemented as function templates, where the template
//! argument is the type of the object being converted from.
template <typename Ptr>
struct pointer_traits
{
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//!The pointer type
//!queried by this pointer_traits instantiation
typedef Ptr pointer;
//!Ptr::element_type if such a type exists; otherwise, T if Ptr is a class
//!template instantiation of the form SomePointer<T, Args>, where Args is zero or
//!more type arguments ; otherwise , the specialization is ill-formed.
typedef unspecified_type element_type;
//!Ptr::difference_type if such a type exists; otherwise,
//!std::ptrdiff_t.
typedef unspecified_type difference_type;
//!Ptr::rebind<U> if such a type exists; otherwise, SomePointer<U, Args> if Ptr is
//!a class template instantiation of the form SomePointer<T, Args>, where Args is zero or
//!more type arguments ; otherwise, the instantiation of rebind is ill-formed.
//!
//!For portable code for C++03 and C++11, <pre>typename rebind_pointer<U>::type</pre>
//!shall be used instead of rebind<U> to obtain a pointer to U.
template <class U> using rebind = unspecified;
//!Ptr::reference if such a type exists (non-standard extension); otherwise, element_type &
//!
typedef unspecified_type reference;
#else
typedef Ptr pointer;
//
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT
( boost::intrusive::detail::, Ptr, element_type
, boost::movelib::detail::first_param<Ptr>) element_type;
//
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
(boost::intrusive::detail::, Ptr, difference_type, std::ptrdiff_t) difference_type;
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
( boost::intrusive::detail::, Ptr, size_type
, typename boost::move_detail::
make_unsigned<difference_type>::type) size_type;
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
( boost::intrusive::detail::, Ptr, reference
, typename boost::intrusive::detail::unvoid_ref<element_type>::type) reference;
//
template <class U> struct rebind_pointer
{
typedef typename boost::intrusive::pointer_rebind<Ptr, U>::type type;
};
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template <class U> using rebind = typename boost::intrusive::pointer_rebind<Ptr, U>::type;
#endif
#endif //#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
//! <b>Remark</b>: If element_type is (possibly cv-qualified) void, r type is unspecified; otherwise,
//! it is element_type &.
//!
//! <b>Returns</b>: A dereferenceable pointer to r obtained by calling Ptr::pointer_to(reference).
//! Non-standard extension: If such function does not exist, returns pointer(addressof(r));
//!
//! <b>Note</b>: For non-conforming compilers only the existence of a member function called
//! <code>pointer_to</code> is checked.
BOOST_INTRUSIVE_FORCEINLINE static pointer pointer_to(reference r) BOOST_NOEXCEPT
{
//Non-standard extension, it does not require Ptr::pointer_to. If not present
//tries to converts &r to pointer.
const bool value = boost::intrusive::detail::
has_member_function_callable_with_pointer_to
<Ptr, Ptr (*)(reference)>::value;
boost::intrusive::detail::bool_<value> flag;
return pointer_traits::priv_pointer_to(flag, r);
}
//! <b>Remark</b>: Non-standard extension.
//!
//! <b>Returns</b>: A dereferenceable pointer to r obtained by calling the static template function
//! Ptr::static_cast_from(UPpr/const UPpr &).
//! If such function does not exist, returns pointer_to(static_cast<element_type&>(*uptr))
//!
//! <b>Note</b>: For non-conforming compilers only the existence of a member function called
//! <code>static_cast_from</code> is checked.
template<class UPtr>
BOOST_INTRUSIVE_FORCEINLINE static pointer static_cast_from(const UPtr &uptr) BOOST_NOEXCEPT
{
typedef const UPtr &RefArg;
const bool value = boost::intrusive::detail::
has_member_function_callable_with_static_cast_from
<pointer, pointer(*)(RefArg)>::value
|| boost::intrusive::detail::
has_member_function_callable_with_static_cast_from
<pointer, pointer(*)(UPtr)>::value;
return pointer_traits::priv_static_cast_from(boost::intrusive::detail::bool_<value>(), uptr);
}
//! <b>Remark</b>: Non-standard extension.
//!
//! <b>Returns</b>: A dereferenceable pointer to r obtained by calling the static template function
//! Ptr::const_cast_from<UPtr>(UPpr/const UPpr &).
//! If such function does not exist, returns pointer_to(const_cast<element_type&>(*uptr))
//!
//! <b>Note</b>: For non-conforming compilers only the existence of a member function called
//! <code>const_cast_from</code> is checked.
template<class UPtr>
BOOST_INTRUSIVE_FORCEINLINE static pointer const_cast_from(const UPtr &uptr) BOOST_NOEXCEPT
{
typedef const UPtr &RefArg;
const bool value = boost::intrusive::detail::
has_member_function_callable_with_const_cast_from
<pointer, pointer(*)(RefArg)>::value
|| boost::intrusive::detail::
has_member_function_callable_with_const_cast_from
<pointer, pointer(*)(UPtr)>::value;
return pointer_traits::priv_const_cast_from(boost::intrusive::detail::bool_<value>(), uptr);
}
//! <b>Remark</b>: Non-standard extension.
//!
//! <b>Returns</b>: A dereferenceable pointer to r obtained by calling the static template function
//! Ptr::dynamic_cast_from<UPtr>(UPpr/const UPpr &).
//! If such function does not exist, returns pointer_to(*dynamic_cast<element_type*>(&*uptr))
//!
//! <b>Note</b>: For non-conforming compilers only the existence of a member function called
//! <code>dynamic_cast_from</code> is checked.
template<class UPtr>
BOOST_INTRUSIVE_FORCEINLINE static pointer dynamic_cast_from(const UPtr &uptr) BOOST_NOEXCEPT
{
typedef const UPtr &RefArg;
const bool value = boost::intrusive::detail::
has_member_function_callable_with_dynamic_cast_from
<pointer, pointer(*)(RefArg)>::value
|| boost::intrusive::detail::
has_member_function_callable_with_dynamic_cast_from
<pointer, pointer(*)(UPtr)>::value;
return pointer_traits::priv_dynamic_cast_from(boost::intrusive::detail::bool_<value>(), uptr);
}
///@cond
private:
//priv_to_raw_pointer
template <class T>
BOOST_INTRUSIVE_FORCEINLINE static T* to_raw_pointer(T* p) BOOST_NOEXCEPT
{ return p; }
template <class Pointer>
BOOST_INTRUSIVE_FORCEINLINE static typename pointer_traits<Pointer>::element_type*
to_raw_pointer(const Pointer &p) BOOST_NOEXCEPT
{ return pointer_traits::to_raw_pointer(p.operator->()); }
//priv_pointer_to
BOOST_INTRUSIVE_FORCEINLINE static pointer priv_pointer_to(boost::intrusive::detail::true_, reference r) BOOST_NOEXCEPT
{ return Ptr::pointer_to(r); }
BOOST_INTRUSIVE_FORCEINLINE static pointer priv_pointer_to(boost::intrusive::detail::false_, reference r) BOOST_NOEXCEPT
{ return pointer(boost::intrusive::detail::addressof(r)); }
//priv_static_cast_from
template<class UPtr>
BOOST_INTRUSIVE_FORCEINLINE static pointer priv_static_cast_from(boost::intrusive::detail::true_, const UPtr &uptr) BOOST_NOEXCEPT
{ return Ptr::static_cast_from(uptr); }
template<class UPtr>
BOOST_INTRUSIVE_FORCEINLINE static pointer priv_static_cast_from(boost::intrusive::detail::false_, const UPtr &uptr) BOOST_NOEXCEPT
{ return uptr ? pointer_to(*static_cast<element_type*>(to_raw_pointer(uptr))) : pointer(); }
//priv_const_cast_from
template<class UPtr>
BOOST_INTRUSIVE_FORCEINLINE static pointer priv_const_cast_from(boost::intrusive::detail::true_, const UPtr &uptr) BOOST_NOEXCEPT
{ return Ptr::const_cast_from(uptr); }
template<class UPtr>
BOOST_INTRUSIVE_FORCEINLINE static pointer priv_const_cast_from(boost::intrusive::detail::false_, const UPtr &uptr) BOOST_NOEXCEPT
{ return uptr ? pointer_to(const_cast<element_type&>(*uptr)) : pointer(); }
//priv_dynamic_cast_from
template<class UPtr>
BOOST_INTRUSIVE_FORCEINLINE static pointer priv_dynamic_cast_from(boost::intrusive::detail::true_, const UPtr &uptr) BOOST_NOEXCEPT
{ return Ptr::dynamic_cast_from(uptr); }
template<class UPtr>
BOOST_INTRUSIVE_FORCEINLINE static pointer priv_dynamic_cast_from(boost::intrusive::detail::false_, const UPtr &uptr) BOOST_NOEXCEPT
{ return uptr ? pointer_to(dynamic_cast<element_type&>(*uptr)) : pointer(); }
///@endcond
};
///@cond
// Remove cv qualification from Ptr parameter to pointer_traits:
template <typename Ptr>
struct pointer_traits<const Ptr> : pointer_traits<Ptr> {};
template <typename Ptr>
struct pointer_traits<volatile Ptr> : pointer_traits<Ptr> { };
template <typename Ptr>
struct pointer_traits<const volatile Ptr> : pointer_traits<Ptr> { };
// Remove reference from Ptr parameter to pointer_traits:
template <typename Ptr>
struct pointer_traits<Ptr&> : pointer_traits<Ptr> { };
///@endcond
//! Specialization of pointer_traits for raw pointers
//!
template <typename T>
struct pointer_traits<T*>
{
typedef T element_type;
typedef T* pointer;
typedef std::ptrdiff_t difference_type;
typedef std::size_t size_type;
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
typedef T & reference;
//!typedef for <pre>U *</pre>
//!
//!For portable code for C++03 and C++11, <pre>typename rebind_pointer<U>::type</pre>
//!shall be used instead of rebind<U> to obtain a pointer to U.
template <class U> using rebind = U*;
#else
typedef typename boost::intrusive::detail::unvoid_ref<element_type>::type reference;
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template <class U> using rebind = U*;
#endif
#endif
template <class U> struct rebind_pointer
{ typedef U* type; };
//! <b>Returns</b>: addressof(r)
//!
BOOST_INTRUSIVE_FORCEINLINE static pointer pointer_to(reference r) BOOST_NOEXCEPT
{ return boost::intrusive::detail::addressof(r); }
//! <b>Returns</b>: static_cast<pointer>(uptr)
//!
template<class U>
BOOST_INTRUSIVE_FORCEINLINE static pointer static_cast_from(U *uptr) BOOST_NOEXCEPT
{ return static_cast<pointer>(uptr); }
//! <b>Returns</b>: const_cast<pointer>(uptr)
//!
template<class U>
BOOST_INTRUSIVE_FORCEINLINE static pointer const_cast_from(U *uptr) BOOST_NOEXCEPT
{ return const_cast<pointer>(uptr); }
//! <b>Returns</b>: dynamic_cast<pointer>(uptr)
//!
template<class U>
BOOST_INTRUSIVE_FORCEINLINE static pointer dynamic_cast_from(U *uptr) BOOST_NOEXCEPT
{ return dynamic_cast<pointer>(uptr); }
};
} //namespace container {
} //namespace boost {
#include <boost/intrusive/detail/config_end.hpp>
#endif // ! defined(BOOST_INTRUSIVE_POINTER_TRAITS_HPP)

View File

@@ -0,0 +1,82 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2008
//
// 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_PRIORITY_COMPARE_HPP
#define BOOST_INTRUSIVE_PRIORITY_COMPARE_HPP
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/detail/workaround.hpp>
#include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/intrusive/detail/minimal_less_equal_header.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
namespace boost {
namespace intrusive {
/// @cond
template<class U>
void priority_order();
/// @endcond
template <class T = void>
struct priority_compare
{
//Compatibility with std::binary_function
typedef T first_argument_type;
typedef T second_argument_type;
typedef bool result_type;
BOOST_INTRUSIVE_FORCEINLINE bool operator()(const T &val, const T &val2) const
{
return priority_order(val, val2);
}
};
template <>
struct priority_compare<void>
{
template<class T, class U>
BOOST_INTRUSIVE_FORCEINLINE bool operator()(const T &t, const U &u) const
{
return priority_order(t, u);
}
};
/// @cond
template<class PrioComp, class T>
struct get_prio_comp
{
typedef PrioComp type;
};
template<class T>
struct get_prio_comp<void, T>
{
typedef ::boost::intrusive::priority_compare<T> type;
};
/// @endcond
} //namespace intrusive
} //namespace boost
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_PRIORITY_COMPARE_HPP

View File

@@ -0,0 +1,591 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_RBTREE_HPP
#define BOOST_INTRUSIVE_RBTREE_HPP
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/intrusive_fwd.hpp>
#include <cstddef>
#include <boost/intrusive/detail/minimal_less_equal_header.hpp>
#include <boost/intrusive/detail/minimal_pair_header.hpp> //std::pair
#include <boost/intrusive/set_hook.hpp>
#include <boost/intrusive/detail/rbtree_node.hpp>
#include <boost/intrusive/bstree.hpp>
#include <boost/intrusive/detail/tree_node.hpp>
#include <boost/intrusive/detail/mpl.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/detail/get_value_traits.hpp>
#include <boost/intrusive/rbtree_algorithms.hpp>
#include <boost/intrusive/link_mode.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/static_assert.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
namespace boost {
namespace intrusive {
/// @cond
struct default_rbtree_hook_applier
{ template <class T> struct apply{ typedef typename T::default_rbtree_hook type; }; };
template<>
struct is_default_hook_tag<default_rbtree_hook_applier>
{ static const bool value = true; };
struct rbtree_defaults
: bstree_defaults
{
typedef default_rbtree_hook_applier proto_value_traits;
};
/// @endcond
//! The class template rbtree is an intrusive red-black tree container, that
//! is used to construct intrusive set and multiset containers. The no-throw
//! guarantee holds only, if the key_compare object
//! doesn't throw.
//!
//! The template parameter \c T is the type to be managed by the container.
//! The user can specify additional options and if no options are provided
//! default options are used.
//!
//! The container supports the following options:
//! \c base_hook<>/member_hook<>/value_traits<>,
//! \c constant_time_size<>, \c size_type<> and
//! \c compare<>.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
#endif
class rbtree_impl
/// @cond
: public bstree_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType, ConstantTimeSize, RbTreeAlgorithms, HeaderHolder>
/// @endcond
{
public:
typedef ValueTraits value_traits;
/// @cond
typedef bstree_impl< ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType
, ConstantTimeSize, RbTreeAlgorithms
, HeaderHolder> tree_type;
typedef tree_type implementation_defined;
/// @endcond
typedef typename implementation_defined::pointer pointer;
typedef typename implementation_defined::const_pointer const_pointer;
typedef typename implementation_defined::value_type value_type;
typedef typename implementation_defined::key_type key_type;
typedef typename implementation_defined::key_of_value key_of_value;
typedef typename implementation_defined::reference reference;
typedef typename implementation_defined::const_reference const_reference;
typedef typename implementation_defined::difference_type difference_type;
typedef typename implementation_defined::size_type size_type;
typedef typename implementation_defined::value_compare value_compare;
typedef typename implementation_defined::key_compare key_compare;
typedef typename implementation_defined::iterator iterator;
typedef typename implementation_defined::const_iterator const_iterator;
typedef typename implementation_defined::reverse_iterator reverse_iterator;
typedef typename implementation_defined::const_reverse_iterator const_reverse_iterator;
typedef typename implementation_defined::node_traits node_traits;
typedef typename implementation_defined::node node;
typedef typename implementation_defined::node_ptr node_ptr;
typedef typename implementation_defined::const_node_ptr const_node_ptr;
typedef typename implementation_defined::node_algorithms node_algorithms;
static const bool constant_time_size = implementation_defined::constant_time_size;
/// @cond
private:
//noncopyable
BOOST_MOVABLE_BUT_NOT_COPYABLE(rbtree_impl)
/// @endcond
public:
typedef typename implementation_defined::insert_commit_data insert_commit_data;
//! @copydoc ::boost::intrusive::bstree::bstree()
rbtree_impl()
: tree_type()
{}
//! @copydoc ::boost::intrusive::bstree::bstree(const key_compare &,const value_traits &)
explicit rbtree_impl( const key_compare &cmp, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits)
{}
//! @copydoc ::boost::intrusive::bstree::bstree(bool,Iterator,Iterator,const key_compare &,const value_traits &)
template<class Iterator>
rbtree_impl( bool unique, Iterator b, Iterator e
, const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(unique, b, e, cmp, v_traits)
{}
//! @copydoc ::boost::intrusive::bstree::bstree(bstree &&)
rbtree_impl(BOOST_RV_REF(rbtree_impl) x)
: tree_type(BOOST_MOVE_BASE(tree_type, x))
{}
//! @copydoc ::boost::intrusive::bstree::operator=(bstree &&)
rbtree_impl& operator=(BOOST_RV_REF(rbtree_impl) x)
{ return static_cast<rbtree_impl&>(tree_type::operator=(BOOST_MOVE_BASE(tree_type, x))); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree::~bstree()
~rbtree_impl();
//! @copydoc ::boost::intrusive::bstree::begin()
iterator begin() BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::begin()const
const_iterator begin() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::cbegin()const
const_iterator cbegin() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::end()
iterator end() BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::end()const
const_iterator end() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::cend()const
const_iterator cend() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::rbegin()
reverse_iterator rbegin() BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::rbegin()const
const_reverse_iterator rbegin() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::crbegin()const
const_reverse_iterator crbegin() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::rend()
reverse_iterator rend() BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::rend()const
const_reverse_iterator rend() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::crend()const
const_reverse_iterator crend() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::root()
iterator root() BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::root()const
const_iterator root() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::croot()const
const_iterator croot() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(iterator)
static rbtree_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(const_iterator)
static const rbtree_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::container_from_iterator(iterator)
static rbtree_impl &container_from_iterator(iterator it) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::container_from_iterator(const_iterator)
static const rbtree_impl &container_from_iterator(const_iterator it) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::key_comp()const
key_compare key_comp() const;
//! @copydoc ::boost::intrusive::bstree::value_comp()const
value_compare value_comp() const;
//! @copydoc ::boost::intrusive::bstree::empty()const
bool empty() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::size()const
size_type size() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::swap
void swap(rbtree_impl& other);
//! @copydoc ::boost::intrusive::bstree::clone_from(const bstree&,Cloner,Disposer)
template <class Cloner, class Disposer>
void clone_from(const rbtree_impl &src, Cloner cloner, Disposer disposer);
#else //BOOST_INTRUSIVE_DOXYGEN_INVOKED
using tree_type::clone_from;
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree::clone_from(bstree&&,Cloner,Disposer)
template <class Cloner, class Disposer>
void clone_from(BOOST_RV_REF(rbtree_impl) src, Cloner cloner, Disposer disposer)
{ tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree::clone_from(bstree&&,Cloner,Disposer)
template <class Cloner, class Disposer>
void clone_from(rbtree_impl &&src, Cloner cloner, Disposer disposer);
//! @copydoc ::boost::intrusive::bstree::insert_equal(reference)
iterator insert_equal(reference value);
//! @copydoc ::boost::intrusive::bstree::insert_equal(const_iterator,reference)
iterator insert_equal(const_iterator hint, reference value);
//! @copydoc ::boost::intrusive::bstree::insert_equal(Iterator,Iterator)
template<class Iterator>
void insert_equal(Iterator b, Iterator e);
//! @copydoc ::boost::intrusive::bstree::insert_unique(reference)
std::pair<iterator, bool> insert_unique(reference value);
//! @copydoc ::boost::intrusive::bstree::insert_unique(const_iterator,reference)
iterator insert_unique(const_iterator hint, reference value);
//! @copydoc ::boost::intrusive::bstree::insert_unique_check(const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_unique_check
(const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data);
//! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_unique_check
(const_iterator hint, const KeyType &key
,KeyTypeKeyCompare comp, insert_commit_data &commit_data);
//! @copydoc ::boost::intrusive::bstree::insert_unique_check(const key_type&,insert_commit_data&)
std::pair<iterator, bool> insert_unique_check
(const key_type &key, insert_commit_data &commit_data);
//! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const key_type&,insert_commit_data&)
std::pair<iterator, bool> insert_unique_check
(const_iterator hint, const key_type &key, insert_commit_data &commit_data);
//! @copydoc ::boost::intrusive::bstree::insert_unique_commit
iterator insert_unique_commit(reference value, const insert_commit_data &commit_data) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::insert_unique(Iterator,Iterator)
template<class Iterator>
void insert_unique(Iterator b, Iterator e);
//! @copydoc ::boost::intrusive::bstree::insert_before
iterator insert_before(const_iterator pos, reference value) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::push_back
void push_back(reference value) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::push_front
void push_front(reference value) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::erase(const_iterator)
iterator erase(const_iterator i) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::erase(const_iterator,const_iterator)
iterator erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::erase(const key_type &key)
size_type erase(const key_type &key);
//! @copydoc ::boost::intrusive::bstree::erase(const KeyType&,KeyTypeKeyCompare)
template<class KeyType, class KeyTypeKeyCompare>
size_type erase(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,const_iterator,Disposer)
template<class Disposer>
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const key_type &, Disposer)
template<class Disposer>
size_type erase_and_dispose(const key_type &key, Disposer disposer);
//! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer)
template<class KeyType, class KeyTypeKeyCompare, class Disposer>
size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer);
//! @copydoc ::boost::intrusive::bstree::clear
void clear() BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::clear_and_dispose
template<class Disposer>
void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::count(const key_type &)const
size_type count(const key_type &key) const;
//! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyTypeKeyCompare)const
template<class KeyType, class KeyTypeKeyCompare>
size_type count(const KeyType& key, KeyTypeKeyCompare comp) const;
//! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)
iterator lower_bound(const key_type &key);
//! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)
template<class KeyType, class KeyTypeKeyCompare>
iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)const
const_iterator lower_bound(const key_type &key) const;
//! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)const
template<class KeyType, class KeyTypeKeyCompare>
const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
//! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)
iterator upper_bound(const key_type &key);
//! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)
template<class KeyType, class KeyTypeKeyCompare>
iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)const
const_iterator upper_bound(const key_type &key) const;
//! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)const
template<class KeyType, class KeyTypeKeyCompare>
const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
//! @copydoc ::boost::intrusive::bstree::find(const key_type &)
iterator find(const key_type &key);
//! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)
template<class KeyType, class KeyTypeKeyCompare>
iterator find(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::bstree::find(const key_type &)const
const_iterator find(const key_type &key) const;
//! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)const
template<class KeyType, class KeyTypeKeyCompare>
const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
//! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)
std::pair<iterator,iterator> equal_range(const key_type &key);
//! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)
template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> equal_range(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)const
std::pair<const_iterator, const_iterator>
equal_range(const key_type &key) const;
//! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)const
template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
equal_range(const KeyType& key, KeyTypeKeyCompare comp) const;
//! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)
std::pair<iterator,iterator> bounded_range
(const key_type &lower, const key_type &upper_key, bool left_closed, bool right_closed);
//! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
(const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
//! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)const
std::pair<const_iterator, const_iterator>
bounded_range(const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator> bounded_range
(const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::bstree::s_iterator_to(reference)
static iterator s_iterator_to(reference value) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::s_iterator_to(const_reference)
static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::iterator_to(reference)
iterator iterator_to(reference value) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::iterator_to(const_reference)const
const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::init_node(reference)
static void init_node(reference value) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::unlink_leftmost_without_rebalance
pointer unlink_leftmost_without_rebalance() BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::replace_node
void replace_node(iterator replace_this, reference with_this) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::remove_node
void remove_node(reference value) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::merge_unique(bstree<T, Options2...>&)
template<class T, class ...Options2>
void merge_unique(rbtree<T, Options2...> &);
//! @copydoc ::boost::intrusive::bstree::merge_equal(bstree<T, Options2...>&)
template<class T, class ...Options2>
void merge_equal(rbtree<T, Options2...> &);
friend bool operator< (const rbtree_impl &x, const rbtree_impl &y);
friend bool operator==(const rbtree_impl &x, const rbtree_impl &y);
friend bool operator!= (const rbtree_impl &x, const rbtree_impl &y);
friend bool operator>(const rbtree_impl &x, const rbtree_impl &y);
friend bool operator<=(const rbtree_impl &x, const rbtree_impl &y);
friend bool operator>=(const rbtree_impl &x, const rbtree_impl &y);
friend void swap(rbtree_impl &x, rbtree_impl &y);
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
};
//! Helper metafunction to define a \c rbtree that yields to the same type when the
//! same options (either explicitly or implicitly) are used.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
, class O5 = void, class O6 = void>
#endif
struct make_rbtree
{
/// @cond
typedef typename pack_options
< rbtree_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
O1, O2, O3, O4, O5, O6
#else
Options...
#endif
>::type packed_options;
typedef typename detail::get_value_traits
<T, typename packed_options::proto_value_traits>::type value_traits;
typedef rbtree_impl
< value_traits
, typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::size_type
, packed_options::constant_time_size
, typename packed_options::header_holder_type
> implementation_defined;
/// @endcond
typedef implementation_defined type;
};
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class rbtree
: public make_rbtree<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
O1, O2, O3, O4, O5, O6
#else
Options...
#endif
>::type
{
typedef typename make_rbtree
<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
O1, O2, O3, O4, O5, O6
#else
Options...
#endif
>::type Base;
BOOST_MOVABLE_BUT_NOT_COPYABLE(rbtree)
public:
typedef typename Base::key_compare key_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
typedef typename Base::reverse_iterator reverse_iterator;
typedef typename Base::const_reverse_iterator const_reverse_iterator;
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
BOOST_INTRUSIVE_FORCEINLINE rbtree()
: Base()
{}
BOOST_INTRUSIVE_FORCEINLINE explicit rbtree( const key_compare &cmp, const value_traits &v_traits = value_traits())
: Base(cmp, v_traits)
{}
template<class Iterator>
BOOST_INTRUSIVE_FORCEINLINE rbtree( bool unique, Iterator b, Iterator e
, const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(unique, b, e, cmp, v_traits)
{}
BOOST_INTRUSIVE_FORCEINLINE rbtree(BOOST_RV_REF(rbtree) x)
: Base(BOOST_MOVE_BASE(Base, x))
{}
BOOST_INTRUSIVE_FORCEINLINE rbtree& operator=(BOOST_RV_REF(rbtree) x)
{ return static_cast<rbtree &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
template <class Cloner, class Disposer>
BOOST_INTRUSIVE_FORCEINLINE void clone_from(const rbtree &src, Cloner cloner, Disposer disposer)
{ Base::clone_from(src, cloner, disposer); }
template <class Cloner, class Disposer>
BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(rbtree) src, Cloner cloner, Disposer disposer)
{ Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
BOOST_INTRUSIVE_FORCEINLINE static rbtree &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT
{ return static_cast<rbtree &>(Base::container_from_end_iterator(end_iterator)); }
BOOST_INTRUSIVE_FORCEINLINE static const rbtree &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT
{ return static_cast<const rbtree &>(Base::container_from_end_iterator(end_iterator)); }
BOOST_INTRUSIVE_FORCEINLINE static rbtree &container_from_iterator(iterator it) BOOST_NOEXCEPT
{ return static_cast<rbtree &>(Base::container_from_iterator(it)); }
BOOST_INTRUSIVE_FORCEINLINE static const rbtree &container_from_iterator(const_iterator it) BOOST_NOEXCEPT
{ return static_cast<const rbtree &>(Base::container_from_iterator(it)); }
};
#endif
} //namespace intrusive
} //namespace boost
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_RBTREE_HPP

View File

@@ -0,0 +1,622 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
// (C) Copyright Ion Gaztanaga 2006-2014.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
//
// The tree destruction algorithm is based on Julienne Walker and The EC Team code:
//
// This code is in the public domain. Anyone may use it or change it in any way that
// they see fit. The author assumes no responsibility for damages incurred through
// use of the original code or any variations thereof.
//
// It is requested, but not required, that due credit is given to the original author
// and anyone who has modified the code through a header comment, such as this one.
#ifndef BOOST_INTRUSIVE_RBTREE_ALGORITHMS_HPP
#define BOOST_INTRUSIVE_RBTREE_ALGORITHMS_HPP
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/intrusive_fwd.hpp>
#include <cstddef>
#include <boost/intrusive/detail/assert.hpp>
#include <boost/intrusive/detail/algo_type.hpp>
#include <boost/intrusive/bstree_algorithms.hpp>
#include <boost/intrusive/detail/ebo_functor_holder.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
namespace boost {
namespace intrusive {
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
template<class NodeTraits, class F>
struct rbtree_node_cloner
//Use public inheritance to avoid MSVC bugs with closures
: public detail::ebo_functor_holder<F>
{
typedef typename NodeTraits::node_ptr node_ptr;
typedef detail::ebo_functor_holder<F> base_t;
explicit rbtree_node_cloner(F f)
: base_t(f)
{}
node_ptr operator()(node_ptr p)
{
node_ptr n = base_t::get()(p);
NodeTraits::set_color(n, NodeTraits::get_color(p));
return n;
}
};
namespace detail {
template<class ValueTraits, class NodePtrCompare, class ExtraChecker>
struct rbtree_node_checker
: public bstree_node_checker<ValueTraits, NodePtrCompare, ExtraChecker>
{
typedef bstree_node_checker<ValueTraits, NodePtrCompare, ExtraChecker> base_checker_t;
typedef ValueTraits value_traits;
typedef typename value_traits::node_traits node_traits;
typedef typename node_traits::const_node_ptr const_node_ptr;
typedef typename node_traits::node_ptr node_ptr;
struct return_type
: public base_checker_t::return_type
{
return_type() : black_count_(0) {}
std::size_t black_count_;
};
rbtree_node_checker(const NodePtrCompare& comp, ExtraChecker extra_checker)
: base_checker_t(comp, extra_checker)
{}
void operator () (const_node_ptr p,
const return_type& check_return_left, const return_type& check_return_right,
return_type& check_return)
{
if (node_traits::get_color(p) == node_traits::red()){
//Red nodes have black children
const node_ptr p_left(node_traits::get_left(p)); (void)p_left;
const node_ptr p_right(node_traits::get_right(p)); (void)p_right;
BOOST_INTRUSIVE_INVARIANT_ASSERT(!p_left || node_traits::get_color(p_left) == node_traits::black());
BOOST_INTRUSIVE_INVARIANT_ASSERT(!p_right || node_traits::get_color(p_right) == node_traits::black());
//Red node can't be root
BOOST_INTRUSIVE_INVARIANT_ASSERT(node_traits::get_parent(node_traits::get_parent(p)) != p);
}
//Every path to p contains the same number of black nodes
const std::size_t l_black_count = check_return_left.black_count_;
BOOST_INTRUSIVE_INVARIANT_ASSERT(l_black_count == check_return_right.black_count_);
check_return.black_count_ = l_black_count +
static_cast<std::size_t>(node_traits::get_color(p) == node_traits::black());
base_checker_t::operator()(p, check_return_left, check_return_right, check_return);
}
};
} // namespace detail
#endif //#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! rbtree_algorithms provides basic algorithms to manipulate
//! nodes forming a red-black tree. The insertion and deletion algorithms are
//! based on those in Cormen, Leiserson, and Rivest, Introduction to Algorithms
//! (MIT Press, 1990), except that
//!
//! (1) the header node is maintained with links not only to the root
//! but also to the leftmost node of the tree, to enable constant time
//! begin(), and to the rightmost node of the tree, to enable linear time
//! performance when used with the generic set algorithms (set_union,
//! etc.);
//!
//! (2) when a node being deleted has two children its successor node is
//! relinked into its place, rather than copied, so that the only
//! pointers invalidated are those referring to the deleted node.
//!
//! rbtree_algorithms is configured with a NodeTraits class, which encapsulates the
//! information about the node to be manipulated. NodeTraits must support the
//! following interface:
//!
//! <b>Typedefs</b>:
//!
//! <tt>node</tt>: The type of the node that forms the binary search tree
//!
//! <tt>node_ptr</tt>: A pointer to a node
//!
//! <tt>const_node_ptr</tt>: A pointer to a const node
//!
//! <tt>color</tt>: The type that can store the color of a node
//!
//! <b>Static functions</b>:
//!
//! <tt>static node_ptr get_parent(const_node_ptr n);</tt>
//!
//! <tt>static void set_parent(node_ptr n, node_ptr parent);</tt>
//!
//! <tt>static node_ptr get_left(const_node_ptr n);</tt>
//!
//! <tt>static void set_left(node_ptr n, node_ptr left);</tt>
//!
//! <tt>static node_ptr get_right(const_node_ptr n);</tt>
//!
//! <tt>static void set_right(node_ptr n, node_ptr right);</tt>
//!
//! <tt>static color get_color(const_node_ptr n);</tt>
//!
//! <tt>static void set_color(node_ptr n, color c);</tt>
//!
//! <tt>static color black();</tt>
//!
//! <tt>static color red();</tt>
template<class NodeTraits>
class rbtree_algorithms
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
: public bstree_algorithms<NodeTraits>
#endif
{
public:
typedef NodeTraits node_traits;
typedef typename NodeTraits::node node;
typedef typename NodeTraits::node_ptr node_ptr;
typedef typename NodeTraits::const_node_ptr const_node_ptr;
typedef typename NodeTraits::color color;
/// @cond
private:
typedef bstree_algorithms<NodeTraits> bstree_algo;
/// @endcond
public:
//! This type is the information that will be
//! filled by insert_unique_check
typedef typename bstree_algo::insert_commit_data insert_commit_data;
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree_algorithms::get_header(const_node_ptr)
static node_ptr get_header(const_node_ptr n) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::begin_node
static node_ptr begin_node(const_node_ptr header) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::end_node
static node_ptr end_node(const_node_ptr header) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::swap_tree
static void swap_tree(node_ptr header1, node_ptr header2) BOOST_NOEXCEPT;
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(node_ptr,node_ptr)
static void swap_nodes(node_ptr node1, node_ptr node2) BOOST_NOEXCEPT
{
if(node1 == node2)
return;
node_ptr header1(bstree_algo::get_header(node1)), header2(bstree_algo::get_header(node2));
swap_nodes(node1, header1, node2, header2);
}
//! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(node_ptr,node_ptr,node_ptr,node_ptr)
static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2) BOOST_NOEXCEPT
{
if(node1 == node2) return;
bstree_algo::swap_nodes(node1, header1, node2, header2);
//Swap color
color c = NodeTraits::get_color(node1);
NodeTraits::set_color(node1, NodeTraits::get_color(node2));
NodeTraits::set_color(node2, c);
}
//! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(node_ptr,node_ptr)
static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node) BOOST_NOEXCEPT
{
if(node_to_be_replaced == new_node)
return;
replace_node(node_to_be_replaced, bstree_algo::get_header(node_to_be_replaced), new_node);
}
//! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(node_ptr,node_ptr,node_ptr)
static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node) BOOST_NOEXCEPT
{
bstree_algo::replace_node(node_to_be_replaced, header, new_node);
NodeTraits::set_color(new_node, NodeTraits::get_color(node_to_be_replaced));
}
//! @copydoc ::boost::intrusive::bstree_algorithms::unlink(node_ptr)
static void unlink(node_ptr node) BOOST_NOEXCEPT
{
node_ptr x = NodeTraits::get_parent(node);
if(x){
while(!is_header(x))
x = NodeTraits::get_parent(x);
erase(x, node);
}
}
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree_algorithms::unlink_leftmost_without_rebalance
static node_ptr unlink_leftmost_without_rebalance(node_ptr header) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::unique(const_node_ptr)
static bool unique(const_node_ptr node) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::size(const_node_ptr)
static std::size_t size(const_node_ptr header) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::next_node(const_node_ptr)
static node_ptr next_node(node_ptr node) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::prev_node(const_node_ptr)
static node_ptr prev_node(node_ptr node) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::init(node_ptr)
static void init(node_ptr node) BOOST_NOEXCEPT;
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree_algorithms::init_header(node_ptr)
static void init_header(node_ptr header) BOOST_NOEXCEPT
{
bstree_algo::init_header(header);
NodeTraits::set_color(header, NodeTraits::red());
}
//! @copydoc ::boost::intrusive::bstree_algorithms::erase(node_ptr,node_ptr)
static node_ptr erase(node_ptr header, node_ptr z) BOOST_NOEXCEPT
{
typename bstree_algo::data_for_rebalance info;
bstree_algo::erase(header, z, info);
rebalance_after_erasure(header, z, info);
return z;
}
//! @copydoc ::boost::intrusive::bstree_algorithms::transfer_unique
template<class NodePtrCompare>
static bool transfer_unique
(node_ptr header1, NodePtrCompare comp, node_ptr header2, node_ptr z)
{
typename bstree_algo::data_for_rebalance info;
bool const transferred = bstree_algo::transfer_unique(header1, comp, header2, z, info);
if(transferred){
rebalance_after_erasure(header2, z, info);
rebalance_after_insertion(header1, z);
}
return transferred;
}
//! @copydoc ::boost::intrusive::bstree_algorithms::transfer_equal
template<class NodePtrCompare>
static void transfer_equal
(node_ptr header1, NodePtrCompare comp, node_ptr header2, node_ptr z)
{
typename bstree_algo::data_for_rebalance info;
bstree_algo::transfer_equal(header1, comp, header2, z, info);
rebalance_after_erasure(header2, z, info);
rebalance_after_insertion(header1, z);
}
//! @copydoc ::boost::intrusive::bstree_algorithms::clone(const_node_ptr,node_ptr,Cloner,Disposer)
template <class Cloner, class Disposer>
static void clone
(const_node_ptr source_header, node_ptr target_header, Cloner cloner, Disposer disposer)
{
rbtree_node_cloner<NodeTraits, Cloner> new_cloner(cloner);
bstree_algo::clone(source_header, target_header, new_cloner, disposer);
}
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree_algorithms::clear_and_dispose(const_node_ptr,Disposer)
template<class Disposer>
static void clear_and_dispose(node_ptr header, Disposer disposer) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const_node_ptr,const KeyType&,KeyNodePtrCompare)
template<class KeyType, class KeyNodePtrCompare>
static node_ptr lower_bound
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
//! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const_node_ptr,const KeyType&,KeyNodePtrCompare)
template<class KeyType, class KeyNodePtrCompare>
static node_ptr upper_bound
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
//! @copydoc ::boost::intrusive::bstree_algorithms::find(const_node_ptr, const KeyType&,KeyNodePtrCompare)
template<class KeyType, class KeyNodePtrCompare>
static node_ptr find
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
//! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const_node_ptr,const KeyType&,KeyNodePtrCompare)
template<class KeyType, class KeyNodePtrCompare>
static std::pair<node_ptr, node_ptr> equal_range
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
//! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const_node_ptr,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool)
template<class KeyType, class KeyNodePtrCompare>
static std::pair<node_ptr, node_ptr> bounded_range
(const_node_ptr eader, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp
, bool left_closed, bool right_closed);
//! @copydoc ::boost::intrusive::bstree_algorithms::count(const_node_ptr,const KeyType&,KeyNodePtrCompare)
template<class KeyType, class KeyNodePtrCompare>
static std::size_t count(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_upper_bound(node_ptr,node_ptr,NodePtrCompare)
template<class NodePtrCompare>
static node_ptr insert_equal_upper_bound
(node_ptr h, node_ptr new_node, NodePtrCompare comp)
{
bstree_algo::insert_equal_upper_bound(h, new_node, comp);
rebalance_after_insertion(h, new_node);
return new_node;
}
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_lower_bound(node_ptr,node_ptr,NodePtrCompare)
template<class NodePtrCompare>
static node_ptr insert_equal_lower_bound
(node_ptr h, node_ptr new_node, NodePtrCompare comp)
{
bstree_algo::insert_equal_lower_bound(h, new_node, comp);
rebalance_after_insertion(h, new_node);
return new_node;
}
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal(node_ptr,node_ptr,node_ptr,NodePtrCompare)
template<class NodePtrCompare>
static node_ptr insert_equal
(node_ptr header, node_ptr hint, node_ptr new_node, NodePtrCompare comp)
{
bstree_algo::insert_equal(header, hint, new_node, comp);
rebalance_after_insertion(header, new_node);
return new_node;
}
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_before(node_ptr,node_ptr,node_ptr)
static node_ptr insert_before
(node_ptr header, node_ptr pos, node_ptr new_node) BOOST_NOEXCEPT
{
bstree_algo::insert_before(header, pos, new_node);
rebalance_after_insertion(header, new_node);
return new_node;
}
//! @copydoc ::boost::intrusive::bstree_algorithms::push_back(node_ptr,node_ptr)
static void push_back(node_ptr header, node_ptr new_node) BOOST_NOEXCEPT
{
bstree_algo::push_back(header, new_node);
rebalance_after_insertion(header, new_node);
}
//! @copydoc ::boost::intrusive::bstree_algorithms::push_front(node_ptr,node_ptr)
static void push_front(node_ptr header, node_ptr new_node) BOOST_NOEXCEPT
{
bstree_algo::push_front(header, new_node);
rebalance_after_insertion(header, new_node);
}
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const_node_ptr,const KeyType&,KeyNodePtrCompare,insert_commit_data&)
template<class KeyType, class KeyNodePtrCompare>
static std::pair<node_ptr, bool> insert_unique_check
(const_node_ptr header, const KeyType &key
,KeyNodePtrCompare comp, insert_commit_data &commit_data);
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const_node_ptr,const_node_ptr,const KeyType&,KeyNodePtrCompare,insert_commit_data&)
template<class KeyType, class KeyNodePtrCompare>
static std::pair<node_ptr, bool> insert_unique_check
(const_node_ptr header, node_ptr hint, const KeyType &key
,KeyNodePtrCompare comp, insert_commit_data &commit_data);
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_commit(node_ptr,node_ptr,const insert_commit_data&)
static void insert_unique_commit
(node_ptr header, node_ptr new_value, const insert_commit_data &commit_data) BOOST_NOEXCEPT
{
bstree_algo::insert_unique_commit(header, new_value, commit_data);
rebalance_after_insertion(header, new_value);
}
//! @copydoc ::boost::intrusive::bstree_algorithms::is_header
static bool is_header(const_node_ptr p) BOOST_NOEXCEPT
{
return NodeTraits::get_color(p) == NodeTraits::red() &&
bstree_algo::is_header(p);
}
/// @cond
private:
static void rebalance_after_erasure
( node_ptr header, node_ptr z, const typename bstree_algo::data_for_rebalance &info) BOOST_NOEXCEPT
{
color new_z_color;
if(info.y != z){
new_z_color = NodeTraits::get_color(info.y);
NodeTraits::set_color(info.y, NodeTraits::get_color(z));
}
else{
new_z_color = NodeTraits::get_color(z);
}
//Rebalance rbtree if needed
if(new_z_color != NodeTraits::red()){
rebalance_after_erasure_restore_invariants(header, info.x, info.x_parent);
}
}
static void rebalance_after_erasure_restore_invariants(node_ptr header, node_ptr x, node_ptr x_parent) BOOST_NOEXCEPT
{
while(1){
if(x_parent == header || (x && NodeTraits::get_color(x) != NodeTraits::black())){
break;
}
//Don't cache x_is_leftchild or similar because x can be null and
//equal to both x_parent_left and x_parent_right
const node_ptr x_parent_left(NodeTraits::get_left(x_parent));
if(x == x_parent_left){ //x is left child
node_ptr w = NodeTraits::get_right(x_parent);
BOOST_INTRUSIVE_INVARIANT_ASSERT(w);
if(NodeTraits::get_color(w) == NodeTraits::red()){
NodeTraits::set_color(w, NodeTraits::black());
NodeTraits::set_color(x_parent, NodeTraits::red());
bstree_algo::rotate_left(x_parent, w, NodeTraits::get_parent(x_parent), header);
w = NodeTraits::get_right(x_parent);
BOOST_INTRUSIVE_INVARIANT_ASSERT(w);
}
node_ptr const w_left (NodeTraits::get_left(w));
node_ptr const w_right(NodeTraits::get_right(w));
if((!w_left || NodeTraits::get_color(w_left) == NodeTraits::black()) &&
(!w_right || NodeTraits::get_color(w_right) == NodeTraits::black())){
NodeTraits::set_color(w, NodeTraits::red());
x = x_parent;
x_parent = NodeTraits::get_parent(x_parent);
}
else {
if(!w_right || NodeTraits::get_color(w_right) == NodeTraits::black()){
NodeTraits::set_color(w_left, NodeTraits::black());
NodeTraits::set_color(w, NodeTraits::red());
bstree_algo::rotate_right(w, w_left, NodeTraits::get_parent(w), header);
w = NodeTraits::get_right(x_parent);
BOOST_INTRUSIVE_INVARIANT_ASSERT(w);
}
NodeTraits::set_color(w, NodeTraits::get_color(x_parent));
NodeTraits::set_color(x_parent, NodeTraits::black());
const node_ptr new_wright(NodeTraits::get_right(w));
if(new_wright)
NodeTraits::set_color(new_wright, NodeTraits::black());
bstree_algo::rotate_left(x_parent, NodeTraits::get_right(x_parent), NodeTraits::get_parent(x_parent), header);
break;
}
}
else {
// same as above, with right_ <-> left_.
node_ptr w = x_parent_left;
if(NodeTraits::get_color(w) == NodeTraits::red()){
NodeTraits::set_color(w, NodeTraits::black());
NodeTraits::set_color(x_parent, NodeTraits::red());
bstree_algo::rotate_right(x_parent, w, NodeTraits::get_parent(x_parent), header);
w = NodeTraits::get_left(x_parent);
BOOST_INTRUSIVE_INVARIANT_ASSERT(w);
}
node_ptr const w_left (NodeTraits::get_left(w));
node_ptr const w_right(NodeTraits::get_right(w));
if((!w_right || NodeTraits::get_color(w_right) == NodeTraits::black()) &&
(!w_left || NodeTraits::get_color(w_left) == NodeTraits::black())){
NodeTraits::set_color(w, NodeTraits::red());
x = x_parent;
x_parent = NodeTraits::get_parent(x_parent);
}
else {
if(!w_left || NodeTraits::get_color(w_left) == NodeTraits::black()){
NodeTraits::set_color(w_right, NodeTraits::black());
NodeTraits::set_color(w, NodeTraits::red());
bstree_algo::rotate_left(w, w_right, NodeTraits::get_parent(w), header);
w = NodeTraits::get_left(x_parent);
BOOST_INTRUSIVE_INVARIANT_ASSERT(w);
}
NodeTraits::set_color(w, NodeTraits::get_color(x_parent));
NodeTraits::set_color(x_parent, NodeTraits::black());
const node_ptr new_wleft(NodeTraits::get_left(w));
if(new_wleft)
NodeTraits::set_color(new_wleft, NodeTraits::black());
bstree_algo::rotate_right(x_parent, NodeTraits::get_left(x_parent), NodeTraits::get_parent(x_parent), header);
break;
}
}
}
if(x)
NodeTraits::set_color(x, NodeTraits::black());
}
static void rebalance_after_insertion(node_ptr header, node_ptr p) BOOST_NOEXCEPT
{
NodeTraits::set_color(p, NodeTraits::red());
while(1){
node_ptr p_parent(NodeTraits::get_parent(p));
const node_ptr p_grandparent(NodeTraits::get_parent(p_parent));
if(p_parent == header || NodeTraits::get_color(p_parent) == NodeTraits::black() || p_grandparent == header){
break;
}
NodeTraits::set_color(p_grandparent, NodeTraits::red());
node_ptr const p_grandparent_left (NodeTraits::get_left (p_grandparent));
bool const p_parent_is_left_child = p_parent == p_grandparent_left;
node_ptr const x(p_parent_is_left_child ? NodeTraits::get_right(p_grandparent) : p_grandparent_left);
if(x && NodeTraits::get_color(x) == NodeTraits::red()){
NodeTraits::set_color(x, NodeTraits::black());
NodeTraits::set_color(p_parent, NodeTraits::black());
p = p_grandparent;
}
else{ //Final step
const bool p_is_left_child(NodeTraits::get_left(p_parent) == p);
if(p_parent_is_left_child){ //p_parent is left child
if(!p_is_left_child){ //p is right child
bstree_algo::rotate_left_no_parent_fix(p_parent, p);
//No need to link p and p_grandparent:
// [NodeTraits::set_parent(p, p_grandparent) + NodeTraits::set_left(p_grandparent, p)]
//as p_grandparent is not the header, another rotation is coming and p_parent
//will be the left child of p_grandparent
p_parent = p;
}
bstree_algo::rotate_right(p_grandparent, p_parent, NodeTraits::get_parent(p_grandparent), header);
}
else{ //p_parent is right child
if(p_is_left_child){ //p is left child
bstree_algo::rotate_right_no_parent_fix(p_parent, p);
//No need to link p and p_grandparent:
// [NodeTraits::set_parent(p, p_grandparent) + NodeTraits::set_right(p_grandparent, p)]
//as p_grandparent is not the header, another rotation is coming and p_parent
//will be the right child of p_grandparent
p_parent = p;
}
bstree_algo::rotate_left(p_grandparent, p_parent, NodeTraits::get_parent(p_grandparent), header);
}
NodeTraits::set_color(p_parent, NodeTraits::black());
break;
}
}
NodeTraits::set_color(NodeTraits::get_parent(header), NodeTraits::black());
}
/// @endcond
};
/// @cond
template<class NodeTraits>
struct get_algo<RbTreeAlgorithms, NodeTraits>
{
typedef rbtree_algorithms<NodeTraits> type;
};
template <class ValueTraits, class NodePtrCompare, class ExtraChecker>
struct get_node_checker<RbTreeAlgorithms, ValueTraits, NodePtrCompare, ExtraChecker>
{
typedef detail::rbtree_node_checker<ValueTraits, NodePtrCompare, ExtraChecker> type;
};
/// @endcond
} //namespace intrusive
} //namespace boost
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_RBTREE_ALGORITHMS_HPP

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,296 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
// (C) Copyright Ion Gaztanaga 2006-2013
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_SET_HOOK_HPP
#define BOOST_INTRUSIVE_SET_HOOK_HPP
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/intrusive/detail/rbtree_node.hpp>
#include <boost/intrusive/rbtree_algorithms.hpp>
#include <boost/intrusive/options.hpp>
#include <boost/intrusive/detail/generic_hook.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
namespace boost {
namespace intrusive {
//! Helper metafunction to define a \c set_base_hook that yields to the same
//! type when the same options (either explicitly or implicitly) are used.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class ...Options>
#else
template<class O1 = void, class O2 = void, class O3 = void, class O4 = void>
#endif
struct make_set_base_hook
{
/// @cond
typedef typename pack_options
< hook_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
O1, O2, O3, O4
#else
Options...
#endif
>::type packed_options;
typedef generic_hook
< RbTreeAlgorithms
, rbtree_node_traits<typename packed_options::void_pointer, packed_options::optimize_size>
, typename packed_options::tag
, packed_options::link_mode
, RbTreeBaseHookId
> implementation_defined;
/// @endcond
typedef implementation_defined type;
};
//! Derive a class from set_base_hook in order to store objects in
//! in a set/multiset. set_base_hook holds the data necessary to maintain
//! the set/multiset and provides an appropriate value_traits class for set/multiset.
//!
//! The hook admits the following options: \c tag<>, \c void_pointer<>,
//! \c link_mode<> and \c optimize_size<>.
//!
//! \c tag<> defines a tag to identify the node.
//! The same tag value can be used in different classes, but if a class is
//! derived from more than one \c list_base_hook, then each \c list_base_hook needs its
//! unique tag.
//!
//! \c void_pointer<> is the pointer type that will be used internally in the hook
//! and the container configured to use this hook.
//!
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
//! \c auto_unlink or \c safe_link).
//!
//! \c optimize_size<> will tell the hook to optimize the hook for size instead
//! of speed.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class ...Options>
#else
template<class O1, class O2, class O3, class O4>
#endif
class set_base_hook
: public make_set_base_hook<
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
O1, O2, O3, O4
#else
Options...
#endif
>::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.
//!
//! <b>Throws</b>: Nothing.
set_base_hook() BOOST_NOEXCEPT;
//! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state. The argument is ignored.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Rationale</b>: Providing a copy-constructor
//! makes classes using the hook STL-compliant without forcing the
//! user to do some additional work. \c swap can be used to emulate
//! move-semantics.
set_base_hook(const set_base_hook& ) BOOST_NOEXCEPT;
//! <b>Effects</b>: Empty function. The argument is ignored.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Rationale</b>: Providing an assignment operator
//! makes classes using the hook STL-compliant without forcing the
//! user to do some additional work. \c swap can be used to emulate
//! move-semantics.
set_base_hook& operator=(const set_base_hook& ) BOOST_NOEXCEPT;
//! <b>Effects</b>: If link_mode is \c normal_link, the destructor does
//! nothing (ie. no code is generated). If link_mode is \c safe_link and the
//! object is stored in a set an assertion is raised. If link_mode is
//! \c auto_unlink and \c is_linked() is true, the node is unlinked.
//!
//! <b>Throws</b>: Nothing.
~set_base_hook();
//! <b>Effects</b>: Swapping two nodes swaps the position of the elements
//! related to those nodes in one or two containers. That is, if the node
//! this is part of the element e1, the node x is part of the element e2
//! and both elements are included in the containers s1 and s2, then after
//! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1
//! at the position of e1. If one element is not in a container, then
//! after the swap-operation the other element is not in a container.
//! Iterators to e1 and e2 related to those nodes are invalidated.
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
void swap_nodes(set_base_hook &other) BOOST_NOEXCEPT;
//! <b>Precondition</b>: link_mode must be \c safe_link or \c auto_unlink.
//!
//! <b>Returns</b>: true, if the node belongs to a container, false
//! otherwise. This function can be used to test whether \c set::iterator_to
//! will return a valid iterator.
//!
//! <b>Complexity</b>: Constant
bool is_linked() const BOOST_NOEXCEPT;
//! <b>Effects</b>: Removes the node if it's inserted in a container.
//! This function is only allowed if link_mode is \c auto_unlink.
//!
//! <b>Throws</b>: Nothing.
void unlink() BOOST_NOEXCEPT;
#endif
};
//! Helper metafunction to define a \c set_member_hook that yields to the same
//! type when the same options (either explicitly or implicitly) are used.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class ...Options>
#else
template<class O1 = void, class O2 = void, class O3 = void, class O4 = void>
#endif
struct make_set_member_hook
{
/// @cond
typedef typename pack_options
< hook_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
O1, O2, O3, O4
#else
Options...
#endif
>::type packed_options;
typedef generic_hook
< RbTreeAlgorithms
, rbtree_node_traits<typename packed_options::void_pointer, packed_options::optimize_size>
, member_tag
, packed_options::link_mode
, NoBaseHookId
> implementation_defined;
/// @endcond
typedef implementation_defined type;
};
//! Put a public data member set_member_hook in order to store objects of this class in
//! a set/multiset. set_member_hook holds the data necessary for maintaining the
//! set/multiset and provides an appropriate value_traits class for set/multiset.
//!
//! The hook admits the following options: \c void_pointer<>,
//! \c link_mode<> and \c optimize_size<>.
//!
//! \c void_pointer<> is the pointer type that will be used internally in the hook
//! and the container configured to use this hook.
//!
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
//! \c auto_unlink or \c safe_link).
//!
//! \c optimize_size<> will tell the hook to optimize the hook for size instead
//! of speed.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class ...Options>
#else
template<class O1, class O2, class O3, class O4>
#endif
class set_member_hook
: public make_set_member_hook<
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
O1, O2, O3, O4
#else
Options...
#endif
>::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.
//!
//! <b>Throws</b>: Nothing.
set_member_hook() BOOST_NOEXCEPT;
//! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state. The argument is ignored.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Rationale</b>: Providing a copy-constructor
//! makes classes using the hook STL-compliant without forcing the
//! user to do some additional work. \c swap can be used to emulate
//! move-semantics.
set_member_hook(const set_member_hook& ) BOOST_NOEXCEPT;
//! <b>Effects</b>: Empty function. The argument is ignored.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Rationale</b>: Providing an assignment operator
//! makes classes using the hook STL-compliant without forcing the
//! user to do some additional work. \c swap can be used to emulate
//! move-semantics.
set_member_hook& operator=(const set_member_hook& ) BOOST_NOEXCEPT;
//! <b>Effects</b>: If link_mode is \c normal_link, the destructor does
//! nothing (ie. no code is generated). If link_mode is \c safe_link and the
//! object is stored in a set an assertion is raised. If link_mode is
//! \c auto_unlink and \c is_linked() is true, the node is unlinked.
//!
//! <b>Throws</b>: Nothing.
~set_member_hook();
//! <b>Effects</b>: Swapping two nodes swaps the position of the elements
//! related to those nodes in one or two containers. That is, if the node
//! this is part of the element e1, the node x is part of the element e2
//! and both elements are included in the containers s1 and s2, then after
//! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1
//! at the position of e1. If one element is not in a container, then
//! after the swap-operation the other element is not in a container.
//! Iterators to e1 and e2 related to those nodes are invalidated.
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
void swap_nodes(set_member_hook &other) BOOST_NOEXCEPT;
//! <b>Precondition</b>: link_mode must be \c safe_link or \c auto_unlink.
//!
//! <b>Returns</b>: true, if the node belongs to a container, false
//! otherwise. This function can be used to test whether \c set::iterator_to
//! will return a valid iterator.
//!
//! <b>Complexity</b>: Constant
bool is_linked() const BOOST_NOEXCEPT;
//! <b>Effects</b>: Removes the node if it's inserted in a container.
//! This function is only allowed if link_mode is \c auto_unlink.
//!
//! <b>Throws</b>: Nothing.
void unlink() BOOST_NOEXCEPT;
#endif
};
} //namespace intrusive
} //namespace boost
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_SET_HOOK_HPP

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,420 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
//
// Scapegoat tree algorithms are taken from the paper titled:
// "Scapegoat Trees" by Igal Galperin Ronald L. Rivest.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_SGTREE_ALGORITHMS_HPP
#define BOOST_INTRUSIVE_SGTREE_ALGORITHMS_HPP
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/intrusive_fwd.hpp>
#include <cstddef>
#include <boost/intrusive/detail/algo_type.hpp>
#include <boost/intrusive/bstree_algorithms.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
namespace boost {
namespace intrusive {
//! sgtree_algorithms is configured with a NodeTraits class, which encapsulates the
//! information about the node to be manipulated. NodeTraits must support the
//! following interface:
//!
//! <b>Typedefs</b>:
//!
//! <tt>node</tt>: The type of the node that forms the binary search tree
//!
//! <tt>node_ptr</tt>: A pointer to a node
//!
//! <tt>const_node_ptr</tt>: A pointer to a const node
//!
//! <b>Static functions</b>:
//!
//! <tt>static node_ptr get_parent(const_node_ptr n);</tt>
//!
//! <tt>static void set_parent(node_ptr n, node_ptr parent);</tt>
//!
//! <tt>static node_ptr get_left(const_node_ptr n);</tt>
//!
//! <tt>static void set_left(node_ptr n, node_ptr left);</tt>
//!
//! <tt>static node_ptr get_right(const_node_ptr n);</tt>
//!
//! <tt>static void set_right(node_ptr n, node_ptr right);</tt>
template<class NodeTraits>
class sgtree_algorithms
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
: public bstree_algorithms<NodeTraits>
#endif
{
public:
typedef typename NodeTraits::node node;
typedef NodeTraits node_traits;
typedef typename NodeTraits::node_ptr node_ptr;
typedef typename NodeTraits::const_node_ptr const_node_ptr;
/// @cond
private:
typedef bstree_algorithms<NodeTraits> bstree_algo;
/// @endcond
public:
//! This type is the information that will be
//! filled by insert_unique_check
struct insert_commit_data
: bstree_algo::insert_commit_data
{
std::size_t depth;
};
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree_algorithms::get_header(const_node_ptr)
static node_ptr get_header(const_node_ptr n) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::begin_node
static node_ptr begin_node(const_node_ptr header) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::end_node
static node_ptr end_node(const_node_ptr header) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::swap_tree
static void swap_tree(node_ptr header1, node_ptr header2) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(node_ptr,node_ptr)
static void swap_nodes(node_ptr node1, node_ptr node2) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(node_ptr,node_ptr,node_ptr,node_ptr)
static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(node_ptr,node_ptr)
static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(node_ptr,node_ptr,node_ptr)
static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node) BOOST_NOEXCEPT;
//Unlink is not possible since tree metadata is needed to update the tree
//!static void unlink(node_ptr node) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::unlink_leftmost_without_rebalance
static node_ptr unlink_leftmost_without_rebalance(node_ptr header) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::unique(const_node_ptr)
static bool unique(const_node_ptr node) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::size(const_node_ptr)
static std::size_t size(const_node_ptr header) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::next_node(node_ptr)
static node_ptr next_node(node_ptr node) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::prev_node(node_ptr)
static node_ptr prev_node(node_ptr node) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::init(node_ptr)
static void init(node_ptr node) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::init_header(node_ptr)
static void init_header(node_ptr header) BOOST_NOEXCEPT;
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree_algorithms::erase(node_ptr,node_ptr)
template<class AlphaByMaxSize>
static node_ptr erase(node_ptr header, node_ptr z, std::size_t tree_size, std::size_t &max_tree_size, AlphaByMaxSize alpha_by_maxsize)
{
bstree_algo::erase(header, z);
--tree_size;
if (tree_size > 0 &&
tree_size < static_cast<std::size_t>(alpha_by_maxsize(max_tree_size))){
bstree_algo::rebalance(header);
max_tree_size = tree_size;
}
return z;
}
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree_algorithms::clone(const_node_ptr,node_ptr,Cloner,Disposer)
template <class Cloner, class Disposer>
static void clone
(const_node_ptr source_header, node_ptr target_header, Cloner cloner, Disposer disposer);
//! @copydoc ::boost::intrusive::bstree_algorithms::clear_and_dispose(node_ptr,Disposer)
template<class Disposer>
static void clear_and_dispose(node_ptr header, Disposer disposer) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const_node_ptr,const KeyType&,KeyNodePtrCompare)
template<class KeyType, class KeyNodePtrCompare>
static node_ptr lower_bound
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
//! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const_node_ptr,const KeyType&,KeyNodePtrCompare)
template<class KeyType, class KeyNodePtrCompare>
static node_ptr upper_bound
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
//! @copydoc ::boost::intrusive::bstree_algorithms::find(const_node_ptr, const KeyType&,KeyNodePtrCompare)
template<class KeyType, class KeyNodePtrCompare>
static node_ptr find
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
//! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const_node_ptr,const KeyType&,KeyNodePtrCompare)
template<class KeyType, class KeyNodePtrCompare>
static std::pair<node_ptr, node_ptr> equal_range
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
//! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const_node_ptr,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool)
template<class KeyType, class KeyNodePtrCompare>
static std::pair<node_ptr, node_ptr> bounded_range
(const_node_ptr header, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp
, bool left_closed, bool right_closed);
//! @copydoc ::boost::intrusive::bstree_algorithms::count(const_node_ptr,const KeyType&,KeyNodePtrCompare)
template<class KeyType, class KeyNodePtrCompare>
static std::size_t count(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_upper_bound(node_ptr,node_ptr,NodePtrCompare)
template<class NodePtrCompare, class H_Alpha>
static node_ptr insert_equal_upper_bound
(node_ptr h, node_ptr new_node, NodePtrCompare comp
,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size)
{
std::size_t depth;
bstree_algo::insert_equal_upper_bound(h, new_node, comp, &depth);
rebalance_after_insertion(new_node, depth, tree_size+1, h_alpha, max_tree_size);
return new_node;
}
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_lower_bound(node_ptr,node_ptr,NodePtrCompare)
template<class NodePtrCompare, class H_Alpha>
static node_ptr insert_equal_lower_bound
(node_ptr h, node_ptr new_node, NodePtrCompare comp
,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size)
{
std::size_t depth;
bstree_algo::insert_equal_lower_bound(h, new_node, comp, &depth);
rebalance_after_insertion(new_node, depth, tree_size+1, h_alpha, max_tree_size);
return new_node;
}
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal(node_ptr,node_ptr,node_ptr,NodePtrCompare)
template<class NodePtrCompare, class H_Alpha>
static node_ptr insert_equal
(node_ptr header, node_ptr hint, node_ptr new_node, NodePtrCompare comp
,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size)
{
std::size_t depth;
bstree_algo::insert_equal(header, hint, new_node, comp, &depth);
rebalance_after_insertion(new_node, depth, tree_size+1, h_alpha, max_tree_size);
return new_node;
}
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_before(node_ptr,node_ptr,node_ptr)
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;
bstree_algo::insert_before(header, pos, new_node, &depth);
rebalance_after_insertion(new_node, depth, tree_size+1, h_alpha, max_tree_size);
return new_node;
}
//! @copydoc ::boost::intrusive::bstree_algorithms::push_back(node_ptr,node_ptr)
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) BOOST_NOEXCEPT
{
std::size_t depth;
bstree_algo::push_back(header, new_node, &depth);
rebalance_after_insertion(new_node, depth, tree_size+1, h_alpha, max_tree_size);
}
//! @copydoc ::boost::intrusive::bstree_algorithms::push_front(node_ptr,node_ptr)
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) BOOST_NOEXCEPT
{
std::size_t depth;
bstree_algo::push_front(header, new_node, &depth);
rebalance_after_insertion(new_node, depth, tree_size+1, h_alpha, max_tree_size);
}
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const_node_ptr,const KeyType&,KeyNodePtrCompare,insert_commit_data&)
template<class KeyType, class KeyNodePtrCompare>
static std::pair<node_ptr, bool> insert_unique_check
(const_node_ptr header, const KeyType &key
,KeyNodePtrCompare comp, insert_commit_data &commit_data)
{
std::size_t depth;
std::pair<node_ptr, bool> ret =
bstree_algo::insert_unique_check(header, key, comp, commit_data, &depth);
commit_data.depth = depth;
return ret;
}
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const_node_ptr,node_ptr,const KeyType&,KeyNodePtrCompare,insert_commit_data&)
template<class KeyType, class KeyNodePtrCompare>
static std::pair<node_ptr, bool> insert_unique_check
(const_node_ptr header, node_ptr hint, const KeyType &key
,KeyNodePtrCompare comp, insert_commit_data &commit_data)
{
std::size_t depth;
std::pair<node_ptr, bool> ret =
bstree_algo::insert_unique_check
(header, hint, key, comp, commit_data, &depth);
commit_data.depth = depth;
return ret;
}
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_commit(node_ptr,node_ptr,const insert_commit_data&)
template<class H_Alpha>
BOOST_INTRUSIVE_FORCEINLINE static void insert_unique_commit
(node_ptr header, node_ptr new_value, const insert_commit_data &commit_data
,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size)
{ return insert_commit(header, new_value, commit_data, tree_size, h_alpha, max_tree_size); }
//! @copydoc ::boost::intrusive::bstree_algorithms::transfer_unique
template<class NodePtrCompare, class H_Alpha, class AlphaByMaxSize>
static bool transfer_unique
( node_ptr header1, NodePtrCompare comp, std::size_t tree1_size, std::size_t &max_tree1_size
, node_ptr header2, node_ptr z, std::size_t tree2_size, std::size_t &max_tree2_size
,H_Alpha h_alpha, AlphaByMaxSize alpha_by_maxsize)
{
insert_commit_data commit_data;
bool const transferable = insert_unique_check(header1, z, comp, commit_data).second;
if(transferable){
erase(header2, z, tree2_size, max_tree2_size, alpha_by_maxsize);
insert_commit(header1, z, commit_data, tree1_size, h_alpha, max_tree1_size);
}
return transferable;
}
//! @copydoc ::boost::intrusive::bstree_algorithms::transfer_equal
template<class NodePtrCompare, class H_Alpha, class AlphaByMaxSize>
static void transfer_equal
( node_ptr header1, NodePtrCompare comp, std::size_t tree1_size, std::size_t &max_tree1_size
, node_ptr header2, node_ptr z, std::size_t tree2_size, std::size_t &max_tree2_size
,H_Alpha h_alpha, AlphaByMaxSize alpha_by_maxsize)
{
insert_commit_data commit_data;
insert_equal_upper_bound_check(header1, z, comp, commit_data);
erase(header2, z, tree2_size, max_tree2_size, alpha_by_maxsize);
insert_commit(header1, z, commit_data, tree1_size, h_alpha, max_tree1_size);
}
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree_algorithms::is_header
static bool is_header(const_node_ptr p) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::is_header
static void rebalance(node_ptr header) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::rebalance_subtree
static node_ptr rebalance_subtree(node_ptr old_root) BOOST_NOEXCEPT
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
/// @cond
private:
template<class KeyType, class KeyNodePtrCompare>
static void insert_equal_upper_bound_check
(node_ptr header, const KeyType &key
,KeyNodePtrCompare comp, insert_commit_data &commit_data)
{
std::size_t depth;
bstree_algo::insert_equal_upper_bound_check(header, key, comp, commit_data, &depth);
commit_data.depth = depth;
}
template<class H_Alpha>
static void insert_commit
(node_ptr header, node_ptr new_value, const insert_commit_data &commit_data
,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size) BOOST_NOEXCEPT
{
bstree_algo::insert_unique_commit(header, new_value, commit_data);
rebalance_after_insertion(new_value, commit_data.depth, tree_size+1, h_alpha, max_tree_size);
}
template<class H_Alpha>
static void rebalance_after_insertion
(node_ptr x, std::size_t depth
, std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size) BOOST_NOEXCEPT
{
if(tree_size > max_tree_size)
max_tree_size = tree_size;
if(tree_size > 2 && //Nothing to do with only the root
//Check if the root node is unbalanced
//Scapegoat paper depth counts root depth as zero and "depth" counts root as 1,
//but since "depth" is the depth of the ancestor of x, i == depth
depth > h_alpha(tree_size)){
//Find the first non height-balanced node
//as described in the section 4.2 of the paper.
//This method is the alternative method described
//in the paper. Authors claim that this method
//may tend to yield more balanced trees on the average
//than the weight balanced method.
node_ptr s = x;
std::size_t size = 1;
for(std::size_t ancestor = 1; ancestor != depth; ++ancestor){
const node_ptr s_parent = NodeTraits::get_parent(s);
const node_ptr s_parent_left = NodeTraits::get_left(s_parent);
//Obtain parent's size (previous size + parent + sibling tree)
const node_ptr s_sibling = s_parent_left == s ? NodeTraits::get_right(s_parent) : s_parent_left;
size += 1 + bstree_algo::subtree_size(s_sibling);
s = s_parent;
if(ancestor > h_alpha(size)){ //is 's' scapegoat?
bstree_algo::rebalance_subtree(s);
return;
}
}
//The whole tree must be rebuilt
max_tree_size = tree_size;
bstree_algo::rebalance_subtree(NodeTraits::get_parent(s));
}
}
/// @endcond
};
/// @cond
template<class NodeTraits>
struct get_algo<SgTreeAlgorithms, NodeTraits>
{
typedef sgtree_algorithms<NodeTraits> type;
};
template <class ValueTraits, class NodePtrCompare, class ExtraChecker>
struct get_node_checker<SgTreeAlgorithms, ValueTraits, NodePtrCompare, ExtraChecker>
{
typedef detail::bstree_node_checker<ValueTraits, NodePtrCompare, ExtraChecker> type;
};
/// @endcond
} //namespace intrusive
} //namespace boost
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_SGTREE_ALGORITHMS_HPP

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,298 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
// (C) Copyright Ion Gaztanaga 2006-2013
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_SLIST_HOOK_HPP
#define BOOST_INTRUSIVE_SLIST_HOOK_HPP
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/intrusive/detail/slist_node.hpp>
#include <boost/intrusive/circular_slist_algorithms.hpp>
#include <boost/intrusive/link_mode.hpp>
#include <boost/intrusive/options.hpp>
#include <boost/intrusive/detail/generic_hook.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
namespace boost {
namespace intrusive {
//! Helper metafunction to define a \c slist_base_hook that yields to the same
//! type when the same options (either explicitly or implicitly) are used.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class ...Options>
#else
template<class O1 = void, class O2 = void, class O3 = void>
#endif
struct make_slist_base_hook
{
/// @cond
typedef typename pack_options
< hook_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
O1, O2, O3
#else
Options...
#endif
>::type packed_options;
typedef generic_hook
< CircularSListAlgorithms
, slist_node_traits<typename packed_options::void_pointer>
, typename packed_options::tag
, packed_options::link_mode
, SlistBaseHookId
> implementation_defined;
/// @endcond
typedef implementation_defined type;
};
//! Derive a class from slist_base_hook in order to store objects in
//! in an list. slist_base_hook holds the data necessary to maintain the
//! list and provides an appropriate value_traits class for list.
//!
//! The hook admits the following options: \c tag<>, \c void_pointer<> and
//! \c link_mode<>.
//!
//! \c tag<> defines a tag to identify the node.
//! The same tag value can be used in different classes, but if a class is
//! derived from more than one \c list_base_hook, then each \c list_base_hook needs its
//! unique tag.
//!
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
//! \c auto_unlink or \c safe_link).
//!
//! \c void_pointer<> is the pointer type that will be used internally in the hook
//! and the container configured to use this hook.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class ...Options>
#else
template<class O1, class O2, class O3>
#endif
class slist_base_hook
: public make_slist_base_hook<
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
O1, O2, O3
#else
Options...
#endif
>::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.
//!
//! <b>Throws</b>: Nothing.
slist_base_hook() BOOST_NOEXCEPT;
//! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state. The argument is ignored.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Rationale</b>: Providing a copy-constructor
//! makes classes using the hook STL-compliant without forcing the
//! user to do some additional work. \c swap can be used to emulate
//! move-semantics.
slist_base_hook(const slist_base_hook& ) BOOST_NOEXCEPT;
//! <b>Effects</b>: Empty function. The argument is ignored.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Rationale</b>: Providing an assignment operator
//! makes classes using the hook STL-compliant without forcing the
//! user to do some additional work. \c swap can be used to emulate
//! move-semantics.
slist_base_hook& operator=(const slist_base_hook& ) BOOST_NOEXCEPT;
//! <b>Effects</b>: If link_mode is \c normal_link, the destructor does
//! nothing (ie. no code is generated). If link_mode is \c safe_link and the
//! object is stored in an slist an assertion is raised. If link_mode is
//! \c auto_unlink and \c is_linked() is true, the node is unlinked.
//!
//! <b>Throws</b>: Nothing.
~slist_base_hook();
//! <b>Effects</b>: Swapping two nodes swaps the position of the elements
//! related to those nodes in one or two containers. That is, if the node
//! this is part of the element e1, the node x is part of the element e2
//! and both elements are included in the containers s1 and s2, then after
//! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1
//! at the position of e1. If one element is not in a container, then
//! after the swap-operation the other element is not in a container.
//! Iterators to e1 and e2 related to those nodes are invalidated.
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
void swap_nodes(slist_base_hook &other) BOOST_NOEXCEPT;
//! <b>Precondition</b>: link_mode must be \c safe_link or \c auto_unlink.
//!
//! <b>Returns</b>: true, if the node belongs to a container, false
//! otherwise. This function can be used to test whether \c slist::iterator_to
//! will return a valid iterator.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant
bool is_linked() const BOOST_NOEXCEPT;
//! <b>Effects</b>: Removes the node if it's inserted in a container.
//! This function is only allowed if link_mode is \c auto_unlink.
//!
//! <b>Throws</b>: Nothing.
void unlink() BOOST_NOEXCEPT;
#endif
};
//! Helper metafunction to define a \c slist_member_hook that yields to the same
//! type when the same options (either explicitly or implicitly) are used.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class ...Options>
#else
template<class O1 = void, class O2 = void, class O3 = void>
#endif
struct make_slist_member_hook
{
/// @cond
typedef typename pack_options
< hook_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
O1, O2, O3
#else
Options...
#endif
>::type packed_options;
typedef generic_hook
< CircularSListAlgorithms
, slist_node_traits<typename packed_options::void_pointer>
, member_tag
, packed_options::link_mode
, NoBaseHookId
> implementation_defined;
/// @endcond
typedef implementation_defined type;
};
//! Put a public data member slist_member_hook in order to store objects of this class in
//! an list. slist_member_hook holds the data necessary for maintaining the list and
//! provides an appropriate value_traits class for list.
//!
//! The hook admits the following options: \c void_pointer<> and
//! \c link_mode<>.
//!
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
//! \c auto_unlink or \c safe_link).
//!
//! \c void_pointer<> is the pointer type that will be used internally in the hook
//! and the container configured to use this hook.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class ...Options>
#else
template<class O1, class O2, class O3>
#endif
class slist_member_hook
: public make_slist_member_hook<
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
O1, O2, O3
#else
Options...
#endif
>::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.
//!
//! <b>Throws</b>: Nothing.
slist_member_hook();
//! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state. The argument is ignored.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Rationale</b>: Providing a copy-constructor
//! makes classes using the hook STL-compliant without forcing the
//! user to do some additional work. \c swap can be used to emulate
//! move-semantics.
slist_member_hook(const slist_member_hook& );
//! <b>Effects</b>: Empty function. The argument is ignored.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Rationale</b>: Providing an assignment operator
//! makes classes using the hook STL-compliant without forcing the
//! user to do some additional work. \c swap can be used to emulate
//! move-semantics.
slist_member_hook& operator=(const slist_member_hook& );
//! <b>Effects</b>: If link_mode is \c normal_link, the destructor does
//! nothing (ie. no code is generated). If link_mode is \c safe_link and the
//! object is stored in an slist an assertion is raised. If link_mode is
//! \c auto_unlink and \c is_linked() is true, the node is unlinked.
//!
//! <b>Throws</b>: Nothing.
~slist_member_hook();
//! <b>Effects</b>: Swapping two nodes swaps the position of the elements
//! related to those nodes in one or two containers. That is, if the node
//! this is part of the element e1, the node x is part of the element e2
//! and both elements are included in the containers s1 and s2, then after
//! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1
//! at the position of e1. If one element is not in a container, then
//! after the swap-operation the other element is not in a container.
//! Iterators to e1 and e2 related to those nodes are invalidated.
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
void swap_nodes(slist_member_hook &other);
//! <b>Precondition</b>: link_mode must be \c safe_link or \c auto_unlink.
//!
//! <b>Returns</b>: true, if the node belongs to a container, false
//! otherwise. This function can be used to test whether \c slist::iterator_to
//! will return a valid iterator.
//!
//! <b>Note</b>: If this member is called when the value is inserted in a
//! slist with the option linear<true>, this function will return "false"
//! for the last element, as it is not linked to anything (the next element is null),
//! so use with care.
//!
//! <b>Complexity</b>: Constant
bool is_linked() const;
//! <b>Effects</b>: Removes the node if it's inserted in a container.
//! This function is only allowed if link_mode is \c auto_unlink.
//!
//! <b>Throws</b>: Nothing.
void unlink();
#endif
};
} //namespace intrusive
} //namespace boost
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_SLIST_HOOK_HPP

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,666 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_SPLAYTREE_HPP
#define BOOST_INTRUSIVE_SPLAYTREE_HPP
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/intrusive_fwd.hpp>
#include <cstddef>
#include <boost/intrusive/detail/minimal_less_equal_header.hpp>
#include <boost/intrusive/detail/minimal_pair_header.hpp> //std::pair
#include <boost/static_assert.hpp>
#include <boost/intrusive/bstree.hpp>
#include <boost/intrusive/detail/tree_node.hpp>
#include <boost/intrusive/detail/mpl.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/detail/function_detector.hpp>
#include <boost/intrusive/detail/get_value_traits.hpp>
#include <boost/intrusive/splaytree_algorithms.hpp>
#include <boost/intrusive/link_mode.hpp>
#include <boost/intrusive/detail/key_nodeptr_comp.hpp>
#include <boost/move/utility_core.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
namespace boost {
namespace intrusive {
/// @cond
struct splaytree_defaults
: bstree_defaults
{};
/// @endcond
//! The class template splaytree is an intrusive splay tree container that
//! is used to construct intrusive splay_set and splay_multiset containers. The no-throw
//! guarantee holds only, if the key_compare object
//! doesn't throw.
//!
//! The template parameter \c T is the type to be managed by the container.
//! The user can specify additional options and if no options are provided
//! default options are used.
//!
//! The container supports the following options:
//! \c base_hook<>/member_hook<>/value_traits<>,
//! \c constant_time_size<>, \c size_type<> and
//! \c compare<>.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
#endif
class splaytree_impl
/// @cond
: public bstree_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType, ConstantTimeSize, SplayTreeAlgorithms, HeaderHolder>
/// @endcond
{
public:
typedef ValueTraits value_traits;
/// @cond
typedef bstree_impl< ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType
, ConstantTimeSize, SplayTreeAlgorithms
, HeaderHolder> tree_type;
typedef tree_type implementation_defined;
/// @endcond
typedef typename implementation_defined::pointer pointer;
typedef typename implementation_defined::const_pointer const_pointer;
typedef typename implementation_defined::value_type value_type;
typedef typename implementation_defined::key_type key_type;
typedef typename implementation_defined::key_of_value key_of_value;
typedef typename implementation_defined::reference reference;
typedef typename implementation_defined::const_reference const_reference;
typedef typename implementation_defined::difference_type difference_type;
typedef typename implementation_defined::size_type size_type;
typedef typename implementation_defined::value_compare value_compare;
typedef typename implementation_defined::key_compare key_compare;
typedef typename implementation_defined::iterator iterator;
typedef typename implementation_defined::const_iterator const_iterator;
typedef typename implementation_defined::reverse_iterator reverse_iterator;
typedef typename implementation_defined::const_reverse_iterator const_reverse_iterator;
typedef typename implementation_defined::node_traits node_traits;
typedef typename implementation_defined::node node;
typedef typename implementation_defined::node_ptr node_ptr;
typedef typename implementation_defined::const_node_ptr const_node_ptr;
typedef typename implementation_defined::node_algorithms node_algorithms;
static const bool constant_time_size = implementation_defined::constant_time_size;
/// @cond
private:
//noncopyable
BOOST_MOVABLE_BUT_NOT_COPYABLE(splaytree_impl)
/// @endcond
public:
typedef typename implementation_defined::insert_commit_data insert_commit_data;
//! @copydoc ::boost::intrusive::bstree::bstree()
splaytree_impl()
: tree_type()
{}
//! @copydoc ::boost::intrusive::bstree::bstree(const key_compare &,const value_traits &)
explicit splaytree_impl( const key_compare &cmp, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits)
{}
//! @copydoc ::boost::intrusive::bstree::bstree(bool,Iterator,Iterator,const key_compare &,const value_traits &)
template<class Iterator>
splaytree_impl( bool unique, Iterator b, Iterator e
, const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits)
{
if(unique)
this->insert_unique(b, e);
else
this->insert_equal(b, e);
}
//! @copydoc ::boost::intrusive::bstree::bstree(bstree &&)
splaytree_impl(BOOST_RV_REF(splaytree_impl) x)
: tree_type(BOOST_MOVE_BASE(tree_type, x))
{}
//! @copydoc ::boost::intrusive::bstree::operator=(bstree &&)
splaytree_impl& operator=(BOOST_RV_REF(splaytree_impl) x)
{ return static_cast<splaytree_impl&>(tree_type::operator=(BOOST_MOVE_BASE(tree_type, x))); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree::~bstree()
~splaytree_impl();
//! @copydoc ::boost::intrusive::bstree::begin()
iterator begin() BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::begin()const
const_iterator begin() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::cbegin()const
const_iterator cbegin() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::end()
iterator end() BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::end()const
const_iterator end() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::cend()const
const_iterator cend() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::rbegin()
reverse_iterator rbegin() BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::rbegin()const
const_reverse_iterator rbegin() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::crbegin()const
const_reverse_iterator crbegin() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::rend()
reverse_iterator rend() BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::rend()const
const_reverse_iterator rend() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::crend()const
const_reverse_iterator crend() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::root()
iterator root() BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::root()const
const_iterator root() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::croot()const
const_iterator croot() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(iterator)
static splaytree_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(const_iterator)
static const splaytree_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::container_from_iterator(iterator)
static splaytree_impl &container_from_iterator(iterator it) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::container_from_iterator(const_iterator)
static const splaytree_impl &container_from_iterator(const_iterator it) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::key_comp()const
key_compare key_comp() const;
//! @copydoc ::boost::intrusive::bstree::value_comp()const
value_compare value_comp() const;
//! @copydoc ::boost::intrusive::bstree::empty()const
bool empty() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::size()const
size_type size() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::swap
void swap(splaytree_impl& other);
//! @copydoc ::boost::intrusive::bstree::clone_from(const bstree&,Cloner,Disposer)
//! Additional notes: it also copies the alpha factor from the source container.
template <class Cloner, class Disposer>
void clone_from(const splaytree_impl &src, Cloner cloner, Disposer disposer);
#else //BOOST_INTRUSIVE_DOXYGEN_INVOKED
using tree_type::clone_from;
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree::clone_from(bstree&&,Cloner,Disposer)
template <class Cloner, class Disposer>
void clone_from(BOOST_RV_REF(splaytree_impl) src, Cloner cloner, Disposer disposer)
{ tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree::insert_equal(reference)
iterator insert_equal(reference value);
//! @copydoc ::boost::intrusive::bstree::insert_equal(const_iterator,reference)
iterator insert_equal(const_iterator hint, reference value);
//! @copydoc ::boost::intrusive::bstree::insert_equal(Iterator,Iterator)
template<class Iterator>
void insert_equal(Iterator b, Iterator e);
//! @copydoc ::boost::intrusive::bstree::insert_unique(reference)
std::pair<iterator, bool> insert_unique(reference value);
//! @copydoc ::boost::intrusive::bstree::insert_unique(const_iterator,reference)
iterator insert_unique(const_iterator hint, reference value);
//! @copydoc ::boost::intrusive::bstree::insert_unique_check(const key_type&,insert_commit_data&)
std::pair<iterator, bool> insert_unique_check
(const key_type &key, insert_commit_data &commit_data);
//! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const key_type&,insert_commit_data&)
std::pair<iterator, bool> insert_unique_check
(const_iterator hint, const key_type &key, insert_commit_data &commit_data);
//! @copydoc ::boost::intrusive::bstree::insert_unique_check(const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_unique_check
(const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data);
//! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_unique_check
(const_iterator hint, const KeyType &key
,KeyTypeKeyCompare comp, insert_commit_data &commit_data);
//! @copydoc ::boost::intrusive::bstree::insert_unique_commit
iterator insert_unique_commit(reference value, const insert_commit_data &commit_data) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::insert_unique(Iterator,Iterator)
template<class Iterator>
void insert_unique(Iterator b, Iterator e);
//! @copydoc ::boost::intrusive::bstree::insert_before
iterator insert_before(const_iterator pos, reference value) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::push_back
void push_back(reference value) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::push_front
void push_front(reference value) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::erase(const_iterator)
iterator erase(const_iterator i) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::erase(const_iterator,const_iterator)
iterator erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::erase(const key_type &)
size_type erase(const key_type &key);
//! @copydoc ::boost::intrusive::bstree::erase(const KeyType&,KeyTypeKeyCompare)
template<class KeyType, class KeyTypeKeyCompare>
size_type erase(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,const_iterator,Disposer)
template<class Disposer>
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const key_type &, Disposer)
template<class Disposer>
size_type erase_and_dispose(const key_type &key, Disposer disposer);
//! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer)
template<class KeyType, class KeyTypeKeyCompare, class Disposer>
size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer);
//! @copydoc ::boost::intrusive::bstree::clear
void clear() BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::clear_and_dispose
template<class Disposer>
void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::count(const key_type &)const
//! Additional note: non-const function, splaying is performed.
size_type count(const key_type &key);
//! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyTypeKeyCompare)const
//! Additional note: non-const function, splaying is performed.
template<class KeyType, class KeyTypeKeyCompare>
size_type count(const KeyType &key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::bstree::count(const key_type &)const
//! Additional note: const function, no splaying is performed
size_type count(const key_type &key) const;
//! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyTypeKeyCompare)const
//! Additional note: const function, no splaying is performed
template<class KeyType, class KeyTypeKeyCompare>
size_type count(const KeyType &key, KeyTypeKeyCompare comp) const;
//! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)
//! Additional note: non-const function, splaying is performed.
iterator lower_bound(const key_type &key);
//! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)const
//! Additional note: const function, no splaying is performed
const_iterator lower_bound(const key_type &key) const;
//! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)
//! Additional note: non-const function, splaying is performed for the first
//! element of the equal range of "key"
template<class KeyType, class KeyTypeKeyCompare>
iterator lower_bound(const KeyType &key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)const
//! Additional note: const function, no splaying is performed
template<class KeyType, class KeyTypeKeyCompare>
const_iterator lower_bound(const KeyType &key, KeyTypeKeyCompare comp) const;
//! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)
//! Additional note: non-const function, splaying is performed for the first
//! element of the equal range of "value"
iterator upper_bound(const key_type &key);
//! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)const
//! Additional note: const function, no splaying is performed
const_iterator upper_bound(const key_type &key) const;
//! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)
//! Additional note: non-const function, splaying is performed for the first
//! element of the equal range of "key"
template<class KeyType, class KeyTypeKeyCompare>
iterator upper_bound(const KeyType &key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)const
//! Additional note: const function, no splaying is performed
template<class KeyType, class KeyTypeKeyCompare>
const_iterator upper_bound(const KeyType &key, KeyTypeKeyCompare comp) const;
//! @copydoc ::boost::intrusive::bstree::find(const key_type &)
//! Additional note: non-const function, splaying is performed for the first
//! element of the equal range of "value"
iterator find(const key_type &key);
//! @copydoc ::boost::intrusive::bstree::find(const key_type &)const
//! Additional note: const function, no splaying is performed
const_iterator find(const key_type &key) const;
//! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)
//! Additional note: non-const function, splaying is performed for the first
//! element of the equal range of "key"
template<class KeyType, class KeyTypeKeyCompare>
iterator find(const KeyType &key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)const
//! Additional note: const function, no splaying is performed
template<class KeyType, class KeyTypeKeyCompare>
const_iterator find(const KeyType &key, KeyTypeKeyCompare comp) const;
//! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)
//! Additional note: non-const function, splaying is performed for the first
//! element of the equal range of "value"
std::pair<iterator, iterator> equal_range(const key_type &key);
//! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)const
//! Additional note: const function, no splaying is performed
std::pair<const_iterator, const_iterator> equal_range(const key_type &key) const;
//! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)
//! Additional note: non-const function, splaying is performed for the first
//! element of the equal range of "key"
template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, iterator> equal_range(const KeyType &key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)const
//! Additional note: const function, no splaying is performed
template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator> equal_range(const KeyType &key, KeyTypeKeyCompare comp) const;
//! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)
std::pair<iterator,iterator> bounded_range
(const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed);
//! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
(const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
//! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)const
std::pair<const_iterator, const_iterator> bounded_range
(const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator> bounded_range
(const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::bstree::s_iterator_to(reference)
static iterator s_iterator_to(reference value) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::s_iterator_to(const_reference)
static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::iterator_to(reference)
iterator iterator_to(reference value) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::iterator_to(const_reference)const
const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::init_node(reference)
static void init_node(reference value) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::unlink_leftmost_without_rebalance
pointer unlink_leftmost_without_rebalance() BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::replace_node
void replace_node(iterator replace_this, reference with_this) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::remove_node
void remove_node(reference value) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::merge_unique(bstree<T, Options2...>&)
template<class T, class ...Options2>
void merge_unique(splaytree<T, Options2...> &);
//! @copydoc ::boost::intrusive::bstree::merge_equal(bstree<T, Options2...>&)
template<class T, class ...Options2>
void merge_equal(splaytree<T, Options2...> &);
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! <b>Requires</b>: i must be a valid iterator of *this.
//!
//! <b>Effects</b>: Rearranges the container so that the element pointed by i
//! is placed as the root of the tree, improving future searches of this value.
//!
//! <b>Complexity</b>: Amortized logarithmic.
//!
//! <b>Throws</b>: Nothing.
void splay_up(iterator i) BOOST_NOEXCEPT
{ return node_algorithms::splay_up(i.pointed_node(), tree_type::header_ptr()); }
//! <b>Effects</b>: Rearranges the container so that if *this stores an element
//! with a key equivalent to value the element is placed as the root of the
//! tree. If the element is not present returns the last node compared with the key.
//! If the tree is empty, end() is returned.
//!
//! <b>Complexity</b>: Amortized logarithmic.
//!
//! <b>Returns</b>: An iterator to the new root of the tree, end() if the tree is empty.
//!
//! <b>Throws</b>: If the comparison functor throws.
template<class KeyType, class KeyTypeKeyCompare>
iterator splay_down(const KeyType &key, KeyTypeKeyCompare comp)
{
detail::key_nodeptr_comp<value_compare, value_traits>
key_node_comp(comp, &this->get_value_traits());
node_ptr r = node_algorithms::splay_down(tree_type::header_ptr(), key, key_node_comp);
return iterator(r, this->priv_value_traits_ptr());
}
//! <b>Effects</b>: Rearranges the container so that if *this stores an element
//! with a key equivalent to value the element is placed as the root of the
//! tree.
//!
//! <b>Complexity</b>: Amortized logarithmic.
//!
//! <b>Returns</b>: An iterator to the new root of the tree, end() if the tree is empty.
//!
//! <b>Throws</b>: If the predicate throws.
iterator splay_down(const key_type &key)
{ return this->splay_down(key, this->key_comp()); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree::rebalance
void rebalance() BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree::rebalance_subtree
iterator rebalance_subtree(iterator root) BOOST_NOEXCEPT;
friend bool operator< (const splaytree_impl &x, const splaytree_impl &y);
friend bool operator==(const splaytree_impl &x, const splaytree_impl &y);
friend bool operator!= (const splaytree_impl &x, const splaytree_impl &y);
friend bool operator>(const splaytree_impl &x, const splaytree_impl &y);
friend bool operator<=(const splaytree_impl &x, const splaytree_impl &y);
friend bool operator>=(const splaytree_impl &x, const splaytree_impl &y);
friend void swap(splaytree_impl &x, splaytree_impl &y);
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
};
//! Helper metafunction to define a \c splaytree that yields to the same type when the
//! same options (either explicitly or implicitly) are used.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
, class O5 = void, class O6 = void>
#endif
struct make_splaytree
{
/// @cond
typedef typename pack_options
< splaytree_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
O1, O2, O3, O4, O5, O6
#else
Options...
#endif
>::type packed_options;
typedef typename detail::get_value_traits
<T, typename packed_options::proto_value_traits>::type value_traits;
typedef splaytree_impl
< value_traits
, typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::size_type
, packed_options::constant_time_size
, typename packed_options::header_holder_type
> implementation_defined;
/// @endcond
typedef implementation_defined type;
};
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class splaytree
: public make_splaytree<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
O1, O2, O3, O4, O5, O6
#else
Options...
#endif
>::type
{
typedef typename make_splaytree
<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
O1, O2, O3, O4, O5, O6
#else
Options...
#endif
>::type Base;
BOOST_MOVABLE_BUT_NOT_COPYABLE(splaytree)
public:
typedef typename Base::key_compare key_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
typedef typename Base::reverse_iterator reverse_iterator;
typedef typename Base::const_reverse_iterator const_reverse_iterator;
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
BOOST_INTRUSIVE_FORCEINLINE splaytree()
: Base()
{}
BOOST_INTRUSIVE_FORCEINLINE explicit splaytree( const key_compare &cmp, const value_traits &v_traits = value_traits())
: Base(cmp, v_traits)
{}
template<class Iterator>
BOOST_INTRUSIVE_FORCEINLINE splaytree( bool unique, Iterator b, Iterator e
, const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(unique, b, e, cmp, v_traits)
{}
BOOST_INTRUSIVE_FORCEINLINE splaytree(BOOST_RV_REF(splaytree) x)
: Base(BOOST_MOVE_BASE(Base, x))
{}
BOOST_INTRUSIVE_FORCEINLINE splaytree& operator=(BOOST_RV_REF(splaytree) x)
{ return static_cast<splaytree &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
template <class Cloner, class Disposer>
BOOST_INTRUSIVE_FORCEINLINE void clone_from(const splaytree &src, Cloner cloner, Disposer disposer)
{ Base::clone_from(src, cloner, disposer); }
template <class Cloner, class Disposer>
BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(splaytree) src, Cloner cloner, Disposer disposer)
{ Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
BOOST_INTRUSIVE_FORCEINLINE static splaytree &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT
{ return static_cast<splaytree &>(Base::container_from_end_iterator(end_iterator)); }
BOOST_INTRUSIVE_FORCEINLINE static const splaytree &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT
{ return static_cast<const splaytree &>(Base::container_from_end_iterator(end_iterator)); }
BOOST_INTRUSIVE_FORCEINLINE static splaytree &container_from_iterator(iterator it) BOOST_NOEXCEPT
{ return static_cast<splaytree &>(Base::container_from_iterator(it)); }
BOOST_INTRUSIVE_FORCEINLINE static const splaytree &container_from_iterator(const_iterator it) BOOST_NOEXCEPT
{ return static_cast<const splaytree &>(Base::container_from_iterator(it)); }
};
#endif
} //namespace intrusive
} //namespace boost
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_SPLAYTREE_HPP

View File

@@ -0,0 +1,754 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
// The implementation of splay trees is based on the article and code published
// in C++ Users Journal "Implementing Splay Trees in C++" (September 1, 2005).
//
// The splay code has been modified and (supposedly) improved by Ion Gaztanaga.
//
// Here is the copyright notice of the original file containing the splay code:
//
// splay_tree.h -- implementation of a STL compatible splay tree.
//
// Copyright (c) 2004 Ralf Mattethat
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_SPLAYTREE_ALGORITHMS_HPP
#define BOOST_INTRUSIVE_SPLAYTREE_ALGORITHMS_HPP
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/intrusive/detail/assert.hpp>
#include <boost/intrusive/detail/algo_type.hpp>
#include <boost/intrusive/detail/uncast.hpp>
#include <boost/intrusive/bstree_algorithms.hpp>
#include <cstddef>
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
namespace boost {
namespace intrusive {
/// @cond
namespace detail {
template<class NodeTraits>
struct splaydown_assemble_and_fix_header
{
typedef typename NodeTraits::node_ptr node_ptr;
splaydown_assemble_and_fix_header(node_ptr t, node_ptr header, node_ptr leftmost, node_ptr rightmost) BOOST_NOEXCEPT
: t_(t)
, null_node_(header)
, l_(null_node_)
, r_(null_node_)
, leftmost_(leftmost)
, rightmost_(rightmost)
{}
~splaydown_assemble_and_fix_header()
{
this->assemble();
//Now recover the original header except for the
//splayed root node.
//"t_" is the current root and "null_node_" is the header node
NodeTraits::set_parent(null_node_, t_);
NodeTraits::set_parent(t_, null_node_);
//Recover leftmost/rightmost pointers
NodeTraits::set_left (null_node_, leftmost_);
NodeTraits::set_right(null_node_, rightmost_);
}
private:
void assemble() BOOST_NOEXCEPT
{
//procedure assemble;
// left(r), right(l) := right(t), left(t);
// left(t), right(t) := right(null), left(null);
//end assemble;
{ // left(r), right(l) := right(t), left(t);
node_ptr const old_t_left = NodeTraits::get_left(t_);
node_ptr const old_t_right = NodeTraits::get_right(t_);
NodeTraits::set_right(l_, old_t_left);
NodeTraits::set_left (r_, old_t_right);
if(old_t_left){
NodeTraits::set_parent(old_t_left, l_);
}
if(old_t_right){
NodeTraits::set_parent(old_t_right, r_);
}
}
{ // left(t), right(t) := right(null), left(null);
node_ptr const null_right = NodeTraits::get_right(null_node_);
node_ptr const null_left = NodeTraits::get_left(null_node_);
NodeTraits::set_left (t_, null_right);
NodeTraits::set_right(t_, null_left);
if(null_right){
NodeTraits::set_parent(null_right, t_);
}
if(null_left){
NodeTraits::set_parent(null_left, t_);
}
}
}
public:
node_ptr t_, null_node_, l_, r_, leftmost_, rightmost_;
};
} //namespace detail {
/// @endcond
//! A splay tree is an implementation of a binary search tree. The tree is
//! self balancing using the splay algorithm as described in
//!
//! "Self-Adjusting Binary Search Trees
//! by Daniel Dominic Sleator and Robert Endre Tarjan
//! AT&T Bell Laboratories, Murray Hill, NJ
//! Journal of the ACM, Vol 32, no 3, July 1985, pp 652-686
//!
//! splaytree_algorithms is configured with a NodeTraits class, which encapsulates the
//! information about the node to be manipulated. NodeTraits must support the
//! following interface:
//!
//! <b>Typedefs</b>:
//!
//! <tt>node</tt>: The type of the node that forms the binary search tree
//!
//! <tt>node_ptr</tt>: A pointer to a node
//!
//! <tt>const_node_ptr</tt>: A pointer to a const node
//!
//! <b>Static functions</b>:
//!
//! <tt>static node_ptr get_parent(const_node_ptr n);</tt>
//!
//! <tt>static void set_parent(node_ptr n, node_ptr parent);</tt>
//!
//! <tt>static node_ptr get_left(const_node_ptr n);</tt>
//!
//! <tt>static void set_left(node_ptr n, node_ptr left);</tt>
//!
//! <tt>static node_ptr get_right(const_node_ptr n);</tt>
//!
//! <tt>static void set_right(node_ptr n, node_ptr right);</tt>
template<class NodeTraits>
class splaytree_algorithms
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
: public bstree_algorithms<NodeTraits>
#endif
{
/// @cond
private:
typedef bstree_algorithms<NodeTraits> bstree_algo;
/// @endcond
public:
typedef typename NodeTraits::node node;
typedef NodeTraits node_traits;
typedef typename NodeTraits::node_ptr node_ptr;
typedef typename NodeTraits::const_node_ptr const_node_ptr;
//! This type is the information that will be
//! filled by insert_unique_check
typedef typename bstree_algo::insert_commit_data insert_commit_data;
public:
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree_algorithms::get_header(const_node_ptr)
static node_ptr get_header(const_node_ptr n) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::begin_node
static node_ptr begin_node(const_node_ptr header) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::end_node
static node_ptr end_node(const_node_ptr header) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::swap_tree
static void swap_tree(node_ptr header1, node_ptr header2);
//! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(node_ptr,node_ptr)
static void swap_nodes(node_ptr node1, node_ptr node2) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(node_ptr,node_ptr,node_ptr,node_ptr)
static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(node_ptr,node_ptr)
static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(node_ptr,node_ptr,node_ptr)
static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::unlink(node_ptr)
static void unlink(node_ptr node) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::unlink_leftmost_without_rebalance
static node_ptr unlink_leftmost_without_rebalance(node_ptr header) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::unique(const_node_ptr)
static bool unique(const_node_ptr node) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::size(const_node_ptr)
static std::size_t size(const_node_ptr header) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::next_node(node_ptr)
static node_ptr next_node(node_ptr node) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::prev_node(node_ptr)
static node_ptr prev_node(node_ptr node) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::init(node_ptr)
static void init(node_ptr node) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::init_header(node_ptr)
static void init_header(node_ptr header) BOOST_NOEXCEPT;
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree_algorithms::erase(node_ptr,node_ptr)
//! Additional notes: the previous node of z is splayed to speed up range deletions.
static void erase(node_ptr header, node_ptr z) BOOST_NOEXCEPT
{
//posibility 1
if(NodeTraits::get_left(z)){
splay_up(bstree_algo::prev_node(z), header);
}
//possibility 2
//if(NodeTraits::get_left(z)){
// node_ptr l = NodeTraits::get_left(z);
// splay_up(l, header);
//}
//if(NodeTraits::get_left(z)){
// node_ptr l = bstree_algo::prev_node(z);
// splay_up_impl(l, z);
//}
//possibility 4
//splay_up(z, header);
bstree_algo::erase(header, z);
}
//! @copydoc ::boost::intrusive::bstree_algorithms::transfer_unique
template<class NodePtrCompare>
static bool transfer_unique
(node_ptr header1, NodePtrCompare comp, node_ptr header2, node_ptr z)
{
typename bstree_algo::insert_commit_data commit_data;
bool const transferable = bstree_algo::insert_unique_check(header1, z, comp, commit_data).second;
if(transferable){
erase(header2, z);
bstree_algo::insert_commit(header1, z, commit_data);
splay_up(z, header1);
}
return transferable;
}
//! @copydoc ::boost::intrusive::bstree_algorithms::transfer_equal
template<class NodePtrCompare>
static void transfer_equal
(node_ptr header1, NodePtrCompare comp, node_ptr header2, node_ptr z)
{
insert_commit_data commit_data;
splay_down(header1, z, comp);
bstree_algo::insert_equal_upper_bound_check(header1, z, comp, commit_data);
erase(header2, z);
bstree_algo::insert_commit(header1, z, commit_data);
}
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree_algorithms::clone(const_node_ptr,node_ptr,Cloner,Disposer)
template <class Cloner, class Disposer>
static void clone
(const_node_ptr source_header, node_ptr target_header, Cloner cloner, Disposer disposer);
//! @copydoc ::boost::intrusive::bstree_algorithms::clear_and_dispose(node_ptr,Disposer)
template<class Disposer>
static void clear_and_dispose(node_ptr header, Disposer disposer) BOOST_NOEXCEPT;
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree_algorithms::count(const_node_ptr,const KeyType&,KeyNodePtrCompare)
//! Additional notes: an element with key `key` is splayed.
template<class KeyType, class KeyNodePtrCompare>
static std::size_t count
(node_ptr header, const KeyType &key, KeyNodePtrCompare comp)
{
std::pair<node_ptr, node_ptr> ret = equal_range(header, key, comp);
std::size_t n = 0;
while(ret.first != ret.second){
++n;
ret.first = next_node(ret.first);
}
return n;
}
//! @copydoc ::boost::intrusive::bstree_algorithms::count(const_node_ptr,const KeyType&,KeyNodePtrCompare)
//! Additional note: no splaying is performed
template<class KeyType, class KeyNodePtrCompare>
static std::size_t count
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp)
{ return bstree_algo::count(header, key, comp); }
//! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const_node_ptr,const KeyType&,KeyNodePtrCompare)
//! Additional notes: the first node of the range is splayed.
template<class KeyType, class KeyNodePtrCompare>
static node_ptr lower_bound
(node_ptr header, const KeyType &key, KeyNodePtrCompare comp)
{
splay_down(detail::uncast(header), key, comp);
node_ptr y = bstree_algo::lower_bound(header, key, comp);
//splay_up(y, detail::uncast(header));
return y;
}
//! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const_node_ptr,const KeyType&,KeyNodePtrCompare)
//! Additional note: no splaying is performed
template<class KeyType, class KeyNodePtrCompare>
static node_ptr lower_bound
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp)
{ return bstree_algo::lower_bound(header, key, comp); }
//! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const_node_ptr,const KeyType&,KeyNodePtrCompare)
//! Additional notes: the first node of the range is splayed.
template<class KeyType, class KeyNodePtrCompare>
static node_ptr upper_bound
(node_ptr header, const KeyType &key, KeyNodePtrCompare comp)
{
splay_down(detail::uncast(header), key, comp);
node_ptr y = bstree_algo::upper_bound(header, key, comp);
//splay_up(y, detail::uncast(header));
return y;
}
//! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const_node_ptr,const KeyType&,KeyNodePtrCompare)
//! Additional note: no splaying is performed
template<class KeyType, class KeyNodePtrCompare>
static node_ptr upper_bound
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp)
{ return bstree_algo::upper_bound(header, key, comp); }
//! @copydoc ::boost::intrusive::bstree_algorithms::find(const_node_ptr, const KeyType&,KeyNodePtrCompare)
//! Additional notes: the found node of the lower bound is splayed.
template<class KeyType, class KeyNodePtrCompare>
static node_ptr find
(node_ptr header, const KeyType &key, KeyNodePtrCompare comp)
{
splay_down(detail::uncast(header), key, comp);
return bstree_algo::find(header, key, comp);
}
//! @copydoc ::boost::intrusive::bstree_algorithms::find(const_node_ptr, const KeyType&,KeyNodePtrCompare)
//! Additional note: no splaying is performed
template<class KeyType, class KeyNodePtrCompare>
static node_ptr find
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp)
{ return bstree_algo::find(header, key, comp); }
//! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const_node_ptr,const KeyType&,KeyNodePtrCompare)
//! Additional notes: the first node of the range is splayed.
template<class KeyType, class KeyNodePtrCompare>
static std::pair<node_ptr, node_ptr> equal_range
(node_ptr header, const KeyType &key, KeyNodePtrCompare comp)
{
splay_down(detail::uncast(header), key, comp);
std::pair<node_ptr, node_ptr> ret = bstree_algo::equal_range(header, key, comp);
//splay_up(ret.first, detail::uncast(header));
return ret;
}
//! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const_node_ptr,const KeyType&,KeyNodePtrCompare)
//! Additional note: no splaying is performed
template<class KeyType, class KeyNodePtrCompare>
static std::pair<node_ptr, node_ptr> equal_range
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp)
{ return bstree_algo::equal_range(header, key, comp); }
//! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound_range(const_node_ptr,const KeyType&,KeyNodePtrCompare)
//! Additional notes: the first node of the range is splayed.
template<class KeyType, class KeyNodePtrCompare>
static std::pair<node_ptr, node_ptr> lower_bound_range
(node_ptr header, const KeyType &key, KeyNodePtrCompare comp)
{
splay_down(detail::uncast(header), key, comp);
std::pair<node_ptr, node_ptr> ret = bstree_algo::lower_bound_range(header, key, comp);
//splay_up(ret.first, detail::uncast(header));
return ret;
}
//! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound_range(const_node_ptr,const KeyType&,KeyNodePtrCompare)
//! Additional note: no splaying is performed
template<class KeyType, class KeyNodePtrCompare>
static std::pair<node_ptr, node_ptr> lower_bound_range
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp)
{ return bstree_algo::lower_bound_range(header, key, comp); }
//! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const_node_ptr,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool)
//! Additional notes: the first node of the range is splayed.
template<class KeyType, class KeyNodePtrCompare>
static std::pair<node_ptr, node_ptr> bounded_range
(node_ptr header, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp
, bool left_closed, bool right_closed)
{
splay_down(detail::uncast(header), lower_key, comp);
std::pair<node_ptr, node_ptr> ret =
bstree_algo::bounded_range(header, lower_key, upper_key, comp, left_closed, right_closed);
//splay_up(ret.first, detail::uncast(header));
return ret;
}
//! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const_node_ptr,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool)
//! Additional note: no splaying is performed
template<class KeyType, class KeyNodePtrCompare>
static std::pair<node_ptr, node_ptr> bounded_range
(const_node_ptr header, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp
, bool left_closed, bool right_closed)
{ return bstree_algo::bounded_range(header, lower_key, upper_key, comp, left_closed, right_closed); }
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_upper_bound(node_ptr,node_ptr,NodePtrCompare)
//! Additional note: the inserted node is splayed
template<class NodePtrCompare>
static node_ptr insert_equal_upper_bound
(node_ptr header, node_ptr new_node, NodePtrCompare comp)
{
splay_down(header, new_node, comp);
return bstree_algo::insert_equal_upper_bound(header, new_node, comp);
}
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_lower_bound(node_ptr,node_ptr,NodePtrCompare)
//! Additional note: the inserted node is splayed
template<class NodePtrCompare>
static node_ptr insert_equal_lower_bound
(node_ptr header, node_ptr new_node, NodePtrCompare comp)
{
splay_down(header, new_node, comp);
return bstree_algo::insert_equal_lower_bound(header, new_node, comp);
}
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal(node_ptr,node_ptr,node_ptr,NodePtrCompare)
//! Additional note: the inserted node is splayed
template<class NodePtrCompare>
static node_ptr insert_equal
(node_ptr header, node_ptr hint, node_ptr new_node, NodePtrCompare comp)
{
splay_down(header, new_node, comp);
return bstree_algo::insert_equal(header, hint, new_node, comp);
}
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_before(node_ptr,node_ptr,node_ptr)
//! Additional note: the inserted node is splayed
static node_ptr insert_before
(node_ptr header, node_ptr pos, node_ptr new_node) BOOST_NOEXCEPT
{
bstree_algo::insert_before(header, pos, new_node);
splay_up(new_node, header);
return new_node;
}
//! @copydoc ::boost::intrusive::bstree_algorithms::push_back(node_ptr,node_ptr)
//! Additional note: the inserted node is splayed
static void push_back(node_ptr header, node_ptr new_node) BOOST_NOEXCEPT
{
bstree_algo::push_back(header, new_node);
splay_up(new_node, header);
}
//! @copydoc ::boost::intrusive::bstree_algorithms::push_front(node_ptr,node_ptr)
//! Additional note: the inserted node is splayed
static void push_front(node_ptr header, node_ptr new_node) BOOST_NOEXCEPT
{
bstree_algo::push_front(header, new_node);
splay_up(new_node, header);
}
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const_node_ptr,const KeyType&,KeyNodePtrCompare,insert_commit_data&)
//! Additional note: nodes with the given key are splayed
template<class KeyType, class KeyNodePtrCompare>
static std::pair<node_ptr, bool> insert_unique_check
(node_ptr header, const KeyType &key
,KeyNodePtrCompare comp, insert_commit_data &commit_data)
{
splay_down(header, key, comp);
return bstree_algo::insert_unique_check(header, key, comp, commit_data);
}
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const_node_ptr,node_ptr,const KeyType&,KeyNodePtrCompare,insert_commit_data&)
//! Additional note: nodes with the given key are splayed
template<class KeyType, class KeyNodePtrCompare>
static std::pair<node_ptr, bool> insert_unique_check
(node_ptr header, node_ptr hint, const KeyType &key
,KeyNodePtrCompare comp, insert_commit_data &commit_data)
{
splay_down(header, key, comp);
return bstree_algo::insert_unique_check(header, hint, key, comp, commit_data);
}
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_commit(node_ptr,node_ptr,const insert_commit_data&)
static void insert_unique_commit
(node_ptr header, node_ptr new_value, const insert_commit_data &commit_data) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::is_header
static bool is_header(const_node_ptr p) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::rebalance
static void rebalance(node_ptr header) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::rebalance_subtree
static node_ptr rebalance_subtree(node_ptr old_root) BOOST_NOEXCEPT;
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
// bottom-up splay, use data_ as parent for n | complexity : logarithmic | exception : nothrow
static void splay_up(node_ptr node, node_ptr header) BOOST_NOEXCEPT
{ priv_splay_up<true>(node, header); }
// top-down splay | complexity : logarithmic | exception : strong, note A
template<class KeyType, class KeyNodePtrCompare>
static node_ptr splay_down(node_ptr header, const KeyType &key, KeyNodePtrCompare comp, bool *pfound = 0)
{ return priv_splay_down<true>(header, key, comp, pfound); }
private:
/// @cond
// bottom-up splay, use data_ as parent for n | complexity : logarithmic | exception : nothrow
template<bool SimpleSplay>
static void priv_splay_up(node_ptr node, node_ptr header) BOOST_NOEXCEPT
{
// If (node == header) do a splay for the right most node instead
// this is to boost performance of equal_range/count on equivalent containers in the case
// where there are many equal elements at the end
node_ptr n((node == header) ? NodeTraits::get_right(header) : node);
node_ptr t(header);
if( n == t ) return;
for( ;; ){
node_ptr p(NodeTraits::get_parent(n));
node_ptr g(NodeTraits::get_parent(p));
if( p == t ) break;
if( g == t ){
// zig
rotate(n);
}
else if ((NodeTraits::get_left(p) == n && NodeTraits::get_left(g) == p) ||
(NodeTraits::get_right(p) == n && NodeTraits::get_right(g) == p) ){
// zig-zig
rotate(p);
rotate(n);
}
else {
// zig-zag
rotate(n);
if(!SimpleSplay){
rotate(n);
}
}
}
}
template<bool SimpleSplay, class KeyType, class KeyNodePtrCompare>
static node_ptr priv_splay_down(node_ptr header, const KeyType &key, KeyNodePtrCompare comp, bool *pfound = 0)
{
//Most splay tree implementations use a dummy/null node to implement.
//this function. This has some problems for a generic library like Intrusive:
//
// * The node might not have a default constructor.
// * The default constructor could throw.
//
//We already have a header node. Leftmost and rightmost nodes of the tree
//are not changed when splaying (because the invariants of the tree don't
//change) We can back up them, use the header as the null node and
//reassign old values after the function has been completed.
node_ptr const old_root = NodeTraits::get_parent(header);
node_ptr const leftmost = NodeTraits::get_left(header);
node_ptr const rightmost = NodeTraits::get_right(header);
if(leftmost == rightmost){ //Empty or unique node
if(pfound){
*pfound = old_root && !comp(key, old_root) && !comp(old_root, key);
}
return old_root ? old_root : header;
}
else{
//Initialize "null node" (the header in our case)
NodeTraits::set_left (header, node_ptr());
NodeTraits::set_right(header, node_ptr());
//Class that will backup leftmost/rightmost from header, commit the assemble(),
//and will restore leftmost/rightmost to header even if "comp" throws
detail::splaydown_assemble_and_fix_header<NodeTraits> commit(old_root, header, leftmost, rightmost);
bool found = false;
for( ;; ){
if(comp(key, commit.t_)){
node_ptr const t_left = NodeTraits::get_left(commit.t_);
if(!t_left)
break;
if(comp(key, t_left)){
bstree_algo::rotate_right_no_parent_fix(commit.t_, t_left);
commit.t_ = t_left;
if( !NodeTraits::get_left(commit.t_) )
break;
link_right(commit.t_, commit.r_);
}
else{
link_right(commit.t_, commit.r_);
if(!SimpleSplay && comp(t_left, key)){
if( !NodeTraits::get_right(commit.t_) )
break;
link_left(commit.t_, commit.l_);
}
}
}
else if(comp(commit.t_, key)){
node_ptr const t_right = NodeTraits::get_right(commit.t_);
if(!t_right)
break;
if(comp(t_right, key)){
bstree_algo::rotate_left_no_parent_fix(commit.t_, t_right);
commit.t_ = t_right;
if( !NodeTraits::get_right(commit.t_) )
break;
link_left(commit.t_, commit.l_);
}
else{
link_left(commit.t_, commit.l_);
if(!SimpleSplay && comp(key, t_right)){
if( !NodeTraits::get_left(commit.t_) )
break;
link_right(commit.t_, commit.r_);
}
}
}
else{
found = true;
break;
}
}
//commit.~splaydown_assemble_and_fix_header<NodeTraits>() will first
//"assemble()" + link the new root & recover header's leftmost & rightmost
if(pfound){
*pfound = found;
}
return commit.t_;
}
}
// break link to left child node and attach it to left tree pointed to by l | complexity : constant | exception : nothrow
static void link_left(node_ptr & t, node_ptr & l) BOOST_NOEXCEPT
{
//procedure link_left;
// t, l, right(l) := right(t), t, t
//end link_left
NodeTraits::set_right(l, t);
NodeTraits::set_parent(t, l);
l = t;
t = NodeTraits::get_right(t);
}
// break link to right child node and attach it to right tree pointed to by r | complexity : constant | exception : nothrow
static void link_right(node_ptr & t, node_ptr & r) BOOST_NOEXCEPT
{
//procedure link_right;
// t, r, left(r) := left(t), t, t
//end link_right;
NodeTraits::set_left(r, t);
NodeTraits::set_parent(t, r);
r = t;
t = NodeTraits::get_left(t);
}
// rotate n with its parent | complexity : constant | exception : nothrow
static void rotate(node_ptr n) BOOST_NOEXCEPT
{
//procedure rotate_left;
// t, right(t), left(right(t)) := right(t), left(right(t)), t
//end rotate_left;
node_ptr p = NodeTraits::get_parent(n);
node_ptr g = NodeTraits::get_parent(p);
//Test if g is header before breaking tree
//invariants that would make is_header invalid
bool g_is_header = bstree_algo::is_header(g);
if(NodeTraits::get_left(p) == n){
NodeTraits::set_left(p, NodeTraits::get_right(n));
if(NodeTraits::get_left(p))
NodeTraits::set_parent(NodeTraits::get_left(p), p);
NodeTraits::set_right(n, p);
}
else{ // must be ( p->right == n )
NodeTraits::set_right(p, NodeTraits::get_left(n));
if(NodeTraits::get_right(p))
NodeTraits::set_parent(NodeTraits::get_right(p), p);
NodeTraits::set_left(n, p);
}
NodeTraits::set_parent(p, n);
NodeTraits::set_parent(n, g);
if(g_is_header){
if(NodeTraits::get_parent(g) == p)
NodeTraits::set_parent(g, n);
else{//must be ( g->right == p )
BOOST_INTRUSIVE_INVARIANT_ASSERT(false);
NodeTraits::set_right(g, n);
}
}
else{
if(NodeTraits::get_left(g) == p)
NodeTraits::set_left(g, n);
else //must be ( g->right == p )
NodeTraits::set_right(g, n);
}
}
/// @endcond
};
/// @cond
template<class NodeTraits>
struct get_algo<SplayTreeAlgorithms, NodeTraits>
{
typedef splaytree_algorithms<NodeTraits> type;
};
template <class ValueTraits, class NodePtrCompare, class ExtraChecker>
struct get_node_checker<SplayTreeAlgorithms, ValueTraits, NodePtrCompare, ExtraChecker>
{
typedef detail::bstree_node_checker<ValueTraits, NodePtrCompare, ExtraChecker> type;
};
/// @endcond
} //namespace intrusive
} //namespace boost
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_SPLAYTREE_ALGORITHMS_HPP

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,700 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2014.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_TREAP_ALGORITHMS_HPP
#define BOOST_INTRUSIVE_TREAP_ALGORITHMS_HPP
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/intrusive_fwd.hpp>
#include <cstddef>
#include <boost/intrusive/detail/assert.hpp>
#include <boost/intrusive/detail/algo_type.hpp>
#include <boost/intrusive/bstree_algorithms.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
namespace boost {
namespace intrusive {
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
namespace detail
{
template<class ValueTraits, class NodePtrPrioCompare, class ExtraChecker>
struct treap_node_extra_checker
: public ExtraChecker
{
typedef ExtraChecker base_checker_t;
typedef ValueTraits value_traits;
typedef typename value_traits::node_traits node_traits;
typedef typename node_traits::const_node_ptr const_node_ptr;
typedef typename base_checker_t::return_type return_type;
treap_node_extra_checker(const NodePtrPrioCompare& prio_comp, ExtraChecker extra_checker)
: base_checker_t(extra_checker), prio_comp_(prio_comp)
{}
void operator () (const_node_ptr p,
const return_type& check_return_left, const return_type& check_return_right,
return_type& check_return)
{
BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_traits::get_left(p) || !prio_comp_(node_traits::get_left(p), p));
BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_traits::get_right(p) || !prio_comp_(node_traits::get_right(p), p));
base_checker_t::operator()(p, check_return_left, check_return_right, check_return);
}
const NodePtrPrioCompare prio_comp_;
};
} // namespace detail
#endif //#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! treap_algorithms provides basic algorithms to manipulate
//! nodes forming a treap.
//!
//! (1) the header node is maintained with links not only to the root
//! but also to the leftmost node of the tree, to enable constant time
//! begin(), and to the rightmost node of the tree, to enable linear time
//! performance when used with the generic set algorithms (set_union,
//! etc.);
//!
//! (2) when a node being deleted has two children its successor node is
//! relinked into its place, rather than copied, so that the only
//! pointers invalidated are those referring to the deleted node.
//!
//! treap_algorithms is configured with a NodeTraits class, which encapsulates the
//! information about the node to be manipulated. NodeTraits must support the
//! following interface:
//!
//! <b>Typedefs</b>:
//!
//! <tt>node</tt>: The type of the node that forms the treap
//!
//! <tt>node_ptr</tt>: A pointer to a node
//!
//! <tt>const_node_ptr</tt>: A pointer to a const node
//!
//! <b>Static functions</b>:
//!
//! <tt>static node_ptr get_parent(const_node_ptr n);</tt>
//!
//! <tt>static void set_parent(node_ptr n, node_ptr parent);</tt>
//!
//! <tt>static node_ptr get_left(const_node_ptr n);</tt>
//!
//! <tt>static void set_left(node_ptr n, node_ptr left);</tt>
//!
//! <tt>static node_ptr get_right(const_node_ptr n);</tt>
//!
//! <tt>static void set_right(node_ptr n, node_ptr right);</tt>
template<class NodeTraits>
class treap_algorithms
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
: public bstree_algorithms<NodeTraits>
#endif
{
public:
typedef NodeTraits node_traits;
typedef typename NodeTraits::node node;
typedef typename NodeTraits::node_ptr node_ptr;
typedef typename NodeTraits::const_node_ptr const_node_ptr;
/// @cond
private:
typedef bstree_algorithms<NodeTraits> bstree_algo;
class rerotate_on_destroy
{
rerotate_on_destroy& operator=(const rerotate_on_destroy&);
public:
rerotate_on_destroy(node_ptr header, node_ptr p, std::size_t &n)
: header_(header), p_(p), n_(n), remove_it_(true)
{}
~rerotate_on_destroy()
{
if(remove_it_){
rotate_up_n(header_, p_, n_);
}
}
void release()
{ remove_it_ = false; }
const node_ptr header_;
const node_ptr p_;
std::size_t &n_;
bool remove_it_;
};
static void rotate_up_n(const node_ptr header, const node_ptr p, std::size_t n)
{
node_ptr p_parent(NodeTraits::get_parent(p));
node_ptr p_grandparent(NodeTraits::get_parent(p_parent));
while(n--){
if(p == NodeTraits::get_left(p_parent)){ //p is left child
bstree_algo::rotate_right(p_parent, p, p_grandparent, header);
}
else{ //p is right child
bstree_algo::rotate_left(p_parent, p, p_grandparent, header);
}
p_parent = p_grandparent;
p_grandparent = NodeTraits::get_parent(p_parent);
}
}
/// @endcond
public:
//! This type is the information that will be
//! filled by insert_unique_check
struct insert_commit_data
/// @cond
: public bstree_algo::insert_commit_data
/// @endcond
{
/// @cond
std::size_t rotations;
/// @endcond
};
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree_algorithms::get_header(const_node_ptr)
static node_ptr get_header(const_node_ptr n) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::begin_node
static node_ptr begin_node(const_node_ptr header) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::end_node
static node_ptr end_node(const_node_ptr header) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::swap_tree
static void swap_tree(node_ptr header1, node_ptr header2) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(node_ptr,node_ptr)
static void swap_nodes(node_ptr node1, node_ptr node2) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(node_ptr,node_ptr,node_ptr,node_ptr)
static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(node_ptr,node_ptr)
static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(node_ptr,node_ptr,node_ptr)
static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node) BOOST_NOEXCEPT;
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree_algorithms::unlink(node_ptr)
template<class NodePtrPriorityCompare>
static void unlink(node_ptr node, NodePtrPriorityCompare pcomp)
{
node_ptr x = NodeTraits::get_parent(node);
if(x){
while(!bstree_algo::is_header(x))
x = NodeTraits::get_parent(x);
erase(x, node, pcomp);
}
}
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree_algorithms::unlink_leftmost_without_rebalance
static node_ptr unlink_leftmost_without_rebalance(node_ptr header) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::unique(const_node_ptr)
static bool unique(const_node_ptr node) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::size(const_node_ptr)
static std::size_t size(const_node_ptr header) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::next_node(node_ptr)
static node_ptr next_node(node_ptr node) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::prev_node(node_ptr)
static node_ptr prev_node(node_ptr node) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::init(node_ptr)
static void init(node_ptr node) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::init_header(node_ptr)
static void init_header(node_ptr header) BOOST_NOEXCEPT;
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree_algorithms::erase(node_ptr,node_ptr)
template<class NodePtrPriorityCompare>
static node_ptr erase(node_ptr header, node_ptr z, NodePtrPriorityCompare pcomp)
{
rebalance_for_erasure(header, z, pcomp);
bstree_algo::erase(header, z);
return z;
}
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree_algorithms::clone(const_node_ptr,node_ptr,Cloner,Disposer)
template <class Cloner, class Disposer>
static void clone
(const_node_ptr source_header, node_ptr target_header, Cloner cloner, Disposer disposer);
//! @copydoc ::boost::intrusive::bstree_algorithms::clear_and_dispose(node_ptr,Disposer)
template<class Disposer>
static void clear_and_dispose(node_ptr header, Disposer disposer) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const_node_ptr,const KeyType&,KeyNodePtrCompare)
template<class KeyType, class KeyNodePtrCompare>
static node_ptr lower_bound
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
//! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const_node_ptr,const KeyType&,KeyNodePtrCompare)
template<class KeyType, class KeyNodePtrCompare>
static node_ptr upper_bound
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
//! @copydoc ::boost::intrusive::bstree_algorithms::find(const_node_ptr, const KeyType&,KeyNodePtrCompare)
template<class KeyType, class KeyNodePtrCompare>
static node_ptr find
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
//! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const_node_ptr,const KeyType&,KeyNodePtrCompare)
template<class KeyType, class KeyNodePtrCompare>
static std::pair<node_ptr, node_ptr> equal_range
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
//! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const_node_ptr,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool)
template<class KeyType, class KeyNodePtrCompare>
static std::pair<node_ptr, node_ptr> bounded_range
(const_node_ptr header, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp
, bool left_closed, bool right_closed);
//! @copydoc ::boost::intrusive::bstree_algorithms::count(const_node_ptr,const KeyType&,KeyNodePtrCompare)
template<class KeyType, class KeyNodePtrCompare>
static std::size_t count(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! <b>Requires</b>: "h" 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.
//! 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" and rotates the tree according to "pcomp".
//!
//! <b>Complexity</b>: Average complexity for insert element is at
//! most logarithmic.
//!
//! <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, NodePtrPriorityCompare pcomp)
{
insert_commit_data commit_data;
bstree_algo::insert_equal_upper_bound_check(h, new_node, comp, commit_data);
rebalance_check_and_commit(h, new_node, pcomp, commit_data);
return new_node;
}
//! <b>Requires</b>: "h" 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.
//! 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" 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 NodePtrPriorityCompare>
static node_ptr insert_equal_lower_bound
(node_ptr h, node_ptr new_node, NodePtrCompare comp, NodePtrPriorityCompare pcomp)
{
insert_commit_data commit_data;
bstree_algo::insert_equal_lower_bound_check(h, new_node, comp, commit_data);
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.
//! 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. "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" 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, NodePtrPriorityCompare pcomp)
{
insert_commit_data commit_data;
bstree_algo::insert_equal_check(h, hint, new_node, comp, commit_data);
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;
bstree_algo::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;
bstree_algo::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;
bstree_algo::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
//! the tree. NodePtrCompare compares KeyType with a node_ptr.
//!
//! <b>Effects</b>: Checks if there is an equivalent node to "key" in the
//! tree according to "comp" and obtains the needed information to realize
//! a constant-time node insertion if there is no equivalent node.
//!
//! <b>Returns</b>: If there is an equivalent value
//! returns a pair containing a node_ptr to the already present node
//! and false. If there is not equivalent key can be inserted returns true
//! in the returned pair's boolean and fills "commit_data" that is meant to
//! be used with the "insert_commit" function to achieve a constant-time
//! insertion function.
//!
//! <b>Complexity</b>: Average complexity is at most logarithmic.
//!
//! <b>Throws</b>: If "comp" throws.
//!
//! <b>Notes</b>: This function is used to improve performance when constructing
//! a node is expensive and the user does not want to have two equivalent nodes
//! in the tree: if there is an equivalent value
//! the constructed object must be discarded. Many times, the part of the
//! node that is used to impose the order is much cheaper to construct
//! than the node and this function offers the possibility to use that part
//! to check if the insertion will be successful.
//!
//! If the check is successful, the user can construct the node and use
//! "insert_commit" to insert the node in constant-time. This gives a total
//! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)).
//!
//! "commit_data" remains valid for a subsequent "insert_unique_commit" only
//! if no more objects are inserted or erased from the set.
template<class KeyType, class KeyNodePtrCompare, class PrioType, class PrioNodePtrPrioCompare>
static std::pair<node_ptr, bool> insert_unique_check
( const_node_ptr header
, const KeyType &key, KeyNodePtrCompare comp
, const PrioType &prio, PrioNodePtrPrioCompare pcomp
, insert_commit_data &commit_data)
{
std::pair<node_ptr, bool> ret =
bstree_algo::insert_unique_check(header, key, comp, commit_data);
if(ret.second)
rebalance_after_insertion_check(header, commit_data.node, prio, pcomp, commit_data.rotations);
return ret;
}
//! <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
//! the tree. NodePtrCompare compares KeyType with a node_ptr.
//! "hint" is node from the "header"'s tree.
//!
//! <b>Effects</b>: Checks if there is an equivalent node to "key" in the
//! tree according to "comp" using "hint" as a hint to where it should be
//! inserted and obtains the needed information to realize
//! a constant-time node insertion if there is no equivalent node.
//! If "hint" is the upper_bound the function has constant time
//! complexity (two comparisons in the worst case).
//!
//! <b>Returns</b>: If there is an equivalent value
//! returns a pair containing a node_ptr to the already present node
//! and false. If there is not equivalent key can be inserted returns true
//! in the returned pair's boolean and fills "commit_data" that is meant to
//! be used with the "insert_commit" function to achieve a constant-time
//! insertion function.
//!
//! <b>Complexity</b>: Average complexity is at most logarithmic, but it is
//! amortized constant time if new_node should be inserted immediately before "hint".
//!
//! <b>Throws</b>: If "comp" throws.
//!
//! <b>Notes</b>: This function is used to improve performance when constructing
//! a node is expensive and the user does not want to have two equivalent nodes
//! in the tree: if there is an equivalent value
//! the constructed object must be discarded. Many times, the part of the
//! node that is used to impose the order is much cheaper to construct
//! than the node and this function offers the possibility to use that part
//! to check if the insertion will be successful.
//!
//! If the check is successful, the user can construct the node and use
//! "insert_commit" to insert the node in constant-time. This gives a total
//! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)).
//!
//! "commit_data" remains valid for a subsequent "insert_unique_commit" only
//! if no more objects are inserted or erased from the set.
template<class KeyType, class KeyNodePtrCompare, class PrioType, class PrioNodePtrPrioCompare>
static std::pair<node_ptr, bool> insert_unique_check
( const_node_ptr header, node_ptr hint
, const KeyType &key, KeyNodePtrCompare comp
, const PrioType &prio, PrioNodePtrPrioCompare pcomp
, insert_commit_data &commit_data)
{
std::pair<node_ptr, bool> ret =
bstree_algo::insert_unique_check(header, hint, key, comp, commit_data);
if(ret.second)
rebalance_after_insertion_check(header, commit_data.node, prio, pcomp, commit_data.rotations);
return ret;
}
//! <b>Requires</b>: "header" must be the header node of a tree.
//! "commit_data" must have been obtained from a previous call to
//! "insert_unique_check". No objects should have been inserted or erased
//! from the set between the "insert_unique_check" that filled "commit_data"
//! and the call to "insert_commit".
//!
//!
//! <b>Effects</b>: Inserts new_node in the set using the information obtained
//! from the "commit_data" that a previous "insert_check" filled.
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Notes</b>: This function has only sense if a "insert_unique_check" has been
//! previously executed to fill "commit_data". No value should be inserted or
//! erased between the "insert_check" and "insert_commit" calls.
static void insert_unique_commit
(node_ptr header, node_ptr new_node, const insert_commit_data &commit_data) BOOST_NOEXCEPT
{
bstree_algo::insert_unique_commit(header, new_node, commit_data);
rotate_up_n(header, new_node, commit_data.rotations);
}
//! @copydoc ::boost::intrusive::bstree_algorithms::transfer_unique
template<class NodePtrCompare, class PrioNodePtrPrioCompare>
static bool transfer_unique
(node_ptr header1, NodePtrCompare comp, PrioNodePtrPrioCompare pcomp, node_ptr header2, node_ptr z)
{
insert_commit_data commit_data;
bool const transferable = insert_unique_check(header1, z, comp, z, pcomp, commit_data).second;
if(transferable){
erase(header2, z, pcomp);
insert_unique_commit(header1, z, commit_data);
}
return transferable;
}
//! @copydoc ::boost::intrusive::bstree_algorithms::transfer_equal
template<class NodePtrCompare, class PrioNodePtrPrioCompare>
static void transfer_equal
(node_ptr header1, NodePtrCompare comp, PrioNodePtrPrioCompare pcomp, node_ptr header2, node_ptr z)
{
insert_commit_data commit_data;
bstree_algo::insert_equal_upper_bound_check(header1, z, comp, commit_data);
rebalance_after_insertion_check(header1, commit_data.node, z, pcomp, commit_data.rotations);
rebalance_for_erasure(header2, z, pcomp);
bstree_algo::erase(header2, z);
bstree_algo::insert_unique_commit(header1, z, commit_data);
rotate_up_n(header1, z, commit_data.rotations);
}
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree_algorithms::is_header
static bool is_header(const_node_ptr p) BOOST_NOEXCEPT;
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
/// @cond
private:
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);
node_ptr z_left = NodeTraits::get_left(z);
node_ptr z_right = NodeTraits::get_right(z);
while(z_left || z_right){
const node_ptr z_parent(NodeTraits::get_parent(z));
if(!z_right || (z_left && pcomp(z_left, z_right))){
bstree_algo::rotate_right(z, z_left, z_parent, header);
}
else{
bstree_algo::rotate_left(z, z_right, z_parent, header);
}
++n;
z_left = NodeTraits::get_left(z);
z_right = NodeTraits::get_right(z);
}
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
bstree_algo::insert_unique_commit(h, new_node, commit_data);
rotate_up_n(h, new_node, commit_data.rotations);
}
template<class Key, class KeyNodePriorityCompare>
static void rebalance_after_insertion_check
(const_node_ptr header, const_node_ptr up, const Key &k
, KeyNodePriorityCompare pcomp, std::size_t &num_rotations)
{
const_node_ptr upnode(up);
//First check rotations since pcomp can throw
num_rotations = 0;
std::size_t n = 0;
while(upnode != header && pcomp(k, upnode)){
++n;
upnode = NodeTraits::get_parent(upnode);
}
num_rotations = n;
}
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);
while(beg != end){
node_ptr p = NodeTraits::get_parent(beg);
if(p != header){
if(pcomp(beg, p))
return false;
}
beg = next_node(beg);
}
return true;
}
/// @endcond
};
/// @cond
template<class NodeTraits>
struct get_algo<TreapAlgorithms, NodeTraits>
{
typedef treap_algorithms<NodeTraits> type;
};
template <class ValueTraits, class NodePtrCompare, class ExtraChecker>
struct get_node_checker<TreapAlgorithms, ValueTraits, NodePtrCompare, ExtraChecker>
{
typedef detail::bstree_node_checker<ValueTraits, NodePtrCompare, ExtraChecker> type;
};
/// @endcond
} //namespace intrusive
} //namespace boost
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_TREAP_ALGORITHMS_HPP

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,61 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2013
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_TRIVIAL_VALUE_TRAITS_HPP
#define BOOST_INTRUSIVE_TRIVIAL_VALUE_TRAITS_HPP
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/detail/workaround.hpp>
#include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/intrusive/link_mode.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
namespace boost {
namespace intrusive {
//!This value traits template is used to create value traits
//!from user defined node traits where value_traits::value_type and
//!node_traits::node should be equal
template<class NodeTraits, link_mode_type LinkMode
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
= safe_link
#endif
>
struct trivial_value_traits
{
typedef NodeTraits node_traits;
typedef typename node_traits::node_ptr node_ptr;
typedef typename node_traits::const_node_ptr const_node_ptr;
typedef typename node_traits::node value_type;
typedef node_ptr pointer;
typedef const_node_ptr const_pointer;
static const link_mode_type link_mode = LinkMode;
BOOST_INTRUSIVE_FORCEINLINE static node_ptr to_node_ptr (value_type &value) BOOST_NOEXCEPT
{ return pointer_traits<node_ptr>::pointer_to(value); }
BOOST_INTRUSIVE_FORCEINLINE static const_node_ptr to_node_ptr (const value_type &value) BOOST_NOEXCEPT
{ return pointer_traits<const_node_ptr>::pointer_to(value); }
BOOST_INTRUSIVE_FORCEINLINE static pointer to_value_ptr(node_ptr n) BOOST_NOEXCEPT
{ return n; }
BOOST_INTRUSIVE_FORCEINLINE static const_pointer to_value_ptr(const_node_ptr n) BOOST_NOEXCEPT
{ return n; }
};
} //namespace intrusive
} //namespace boost
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_TRIVIAL_VALUE_TRAITS_HPP

View File

@@ -0,0 +1,994 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
// (C) Copyright Ion Gaztanaga 2006-2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_UNORDERED_SET_HPP
#define BOOST_INTRUSIVE_UNORDERED_SET_HPP
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/intrusive/hashtable.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/static_assert.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
namespace boost {
namespace intrusive {
//! The class template unordered_set is an intrusive container, that mimics most of
//! the interface of std::tr1::unordered_set as described in the C++ TR1.
//!
//! unordered_set is a semi-intrusive container: each object to be stored in the
//! container must contain a proper hook, but the container also needs
//! additional auxiliary memory to work: unordered_set needs a pointer to an array
//! of type `bucket_type` to be passed in the constructor. This bucket array must
//! have at least the same lifetime as the container. This makes the use of
//! unordered_set more complicated than purely intrusive containers.
//! `bucket_type` is default-constructible, copyable and assignable
//!
//! The template parameter \c T is the type to be managed by the container.
//! The user can specify additional options and if no options are provided
//! default options are used.
//!
//! The container supports the following options:
//! \c base_hook<>/member_hook<>/value_traits<>,
//! \c constant_time_size<>, \c size_type<>, \c hash<> and \c equal<>
//! \c bucket_traits<>, \c power_2_buckets<> and \c cache_begin<>.
//!
//! unordered_set only provides forward iterators but it provides 4 iterator types:
//! iterator and const_iterator to navigate through the whole container and
//! local_iterator and const_local_iterator to navigate through the values
//! stored in a single bucket. Local iterators are faster and smaller.
//!
//! It's not recommended to use non constant-time size unordered_sets because several
//! key functions, like "empty()", become non-constant time functions. Non
//! constant-time size unordered_sets are mainly provided to support auto-unlink hooks.
//!
//! unordered_set, unlike std::unordered_set, does not make automatic rehashings nor
//! offers functions related to a load factor. Rehashing can be explicitly requested
//! and the user must provide a new bucket array that will be used from that moment.
//!
//! Since no automatic rehashing is done, iterators are never invalidated when
//! inserting or erasing elements. Iterators are only invalidated when rehasing.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyHash, class VoidOrKeyEqual, class SizeType, class BucketTraits, std::size_t BoolFlags>
#endif
class unordered_set_impl
: public hashtable_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual, BucketTraits, SizeType, BoolFlags|hash_bool_flags::unique_keys_pos>
{
/// @cond
private:
typedef hashtable_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual, BucketTraits, SizeType, BoolFlags|hash_bool_flags::unique_keys_pos> table_type;
template<class Iterator, class MaybeConstThis, class KeyType, class KeyHasher, class KeyEqual>
static std::pair<Iterator,Iterator> priv_equal_range(MaybeConstThis &c, const KeyType& key, KeyHasher hash_func, KeyEqual equal_func)
{
Iterator const it = c.find(key, hash_func, equal_func);
std::pair<Iterator,Iterator> ret(it, it);
if(it != c.end())
++ret.second;
return ret;
}
//! This class is
//! movable
BOOST_MOVABLE_BUT_NOT_COPYABLE(unordered_set_impl)
typedef table_type implementation_defined;
/// @endcond
public:
typedef typename implementation_defined::value_type value_type;
typedef typename implementation_defined::key_type key_type;
typedef typename implementation_defined::key_of_value key_of_value;
typedef typename implementation_defined::value_traits value_traits;
typedef typename implementation_defined::bucket_traits bucket_traits;
typedef typename implementation_defined::pointer pointer;
typedef typename implementation_defined::const_pointer const_pointer;
typedef typename implementation_defined::reference reference;
typedef typename implementation_defined::const_reference const_reference;
typedef typename implementation_defined::difference_type difference_type;
typedef typename implementation_defined::size_type size_type;
typedef typename implementation_defined::key_equal key_equal;
typedef typename implementation_defined::hasher hasher;
typedef typename implementation_defined::bucket_type bucket_type;
typedef typename implementation_defined::bucket_ptr bucket_ptr;
typedef typename implementation_defined::iterator iterator;
typedef typename implementation_defined::const_iterator const_iterator;
typedef typename implementation_defined::insert_commit_data insert_commit_data;
typedef typename implementation_defined::local_iterator local_iterator;
typedef typename implementation_defined::const_local_iterator const_local_iterator;
typedef typename implementation_defined::node_traits node_traits;
typedef typename implementation_defined::node node;
typedef typename implementation_defined::node_ptr node_ptr;
typedef typename implementation_defined::const_node_ptr const_node_ptr;
typedef typename implementation_defined::node_algorithms node_algorithms;
public:
//! @copydoc ::boost::intrusive::hashtable::hashtable(const bucket_traits &,const hasher &,const key_equal &,const value_traits &)
BOOST_INTRUSIVE_FORCEINLINE explicit unordered_set_impl( const bucket_traits &b_traits
, const hasher & hash_func = hasher()
, const key_equal &equal_func = key_equal()
, const value_traits &v_traits = value_traits())
: table_type(b_traits, hash_func, equal_func, v_traits)
{}
//! @copydoc ::boost::intrusive::hashtable::hashtable(bool,Iterator,Iterator,const bucket_traits &,const hasher &,const key_equal &,const value_traits &)
template<class Iterator>
BOOST_INTRUSIVE_FORCEINLINE unordered_set_impl( Iterator b
, Iterator e
, const bucket_traits &b_traits
, const hasher & hash_func = hasher()
, const key_equal &equal_func = key_equal()
, const value_traits &v_traits = value_traits())
: table_type(true, b, e, b_traits, hash_func, equal_func, v_traits)
{}
//! @copydoc ::boost::intrusive::hashtable::hashtable(hashtable&&)
BOOST_INTRUSIVE_FORCEINLINE unordered_set_impl(BOOST_RV_REF(unordered_set_impl) x)
: table_type(BOOST_MOVE_BASE(table_type, x))
{}
//! @copydoc ::boost::intrusive::hashtable::operator=(hashtable&&)
BOOST_INTRUSIVE_FORCEINLINE unordered_set_impl& operator=(BOOST_RV_REF(unordered_set_impl) x)
{ return static_cast<unordered_set_impl&>(table_type::operator=(BOOST_MOVE_BASE(table_type, x))); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::hashtable::~hashtable()
~unordered_set_impl();
//! @copydoc ::boost::intrusive::hashtable::begin()
iterator begin() BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::begin()const
const_iterator begin() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::cbegin()const
const_iterator cbegin() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::end()
iterator end() BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::end()const
const_iterator end() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::cend()const
const_iterator cend() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::hash_function()const
hasher hash_function() const;
//! @copydoc ::boost::intrusive::hashtable::key_eq()const
key_equal key_eq() const;
//! @copydoc ::boost::intrusive::hashtable::empty()const
bool empty() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::size()const
size_type size() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::hashtable
void swap(unordered_set_impl& other);
//! @copydoc ::boost::intrusive::hashtable::clone_from(const hashtable&,Cloner,Disposer)
template <class Cloner, class Disposer>
void clone_from(const unordered_set_impl &src, Cloner cloner, Disposer disposer);
#else
using table_type::clone_from;
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::hashtable::clone_from(hashtable&&,Cloner,Disposer)
template <class Cloner, class Disposer>
BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(unordered_set_impl) src, Cloner cloner, Disposer disposer)
{ table_type::clone_from(BOOST_MOVE_BASE(table_type, src), cloner, disposer); }
//! @copydoc ::boost::intrusive::hashtable::insert_unique(reference)
BOOST_INTRUSIVE_FORCEINLINE std::pair<iterator, bool> insert(reference value)
{ return table_type::insert_unique(value); }
//! @copydoc ::boost::intrusive::hashtable::insert_unique(Iterator,Iterator)
template<class Iterator>
BOOST_INTRUSIVE_FORCEINLINE void insert(Iterator b, Iterator e)
{ table_type::insert_unique(b, e); }
//! @copydoc ::boost::intrusive::hashtable::insert_unique_check(const key_type&,insert_commit_data&)
BOOST_INTRUSIVE_FORCEINLINE std::pair<iterator, bool> insert_check(const key_type &key, insert_commit_data &commit_data)
{ return table_type::insert_unique_check(key, commit_data); }
//! @copydoc ::boost::intrusive::hashtable::insert_unique_check(const KeyType&,KeyHasher,KeyEqual,insert_commit_data&)
template<class KeyType, class KeyHasher, class KeyEqual>
BOOST_INTRUSIVE_FORCEINLINE std::pair<iterator, bool> insert_check
(const KeyType &key, KeyHasher hash_func, KeyEqual key_value_equal, insert_commit_data &commit_data)
{ return table_type::insert_unique_check(key, hash_func, key_value_equal, commit_data); }
//! @copydoc ::boost::intrusive::hashtable::insert_unique_commit
BOOST_INTRUSIVE_FORCEINLINE iterator insert_commit(reference value, const insert_commit_data &commit_data) BOOST_NOEXCEPT
{ return table_type::insert_unique_commit(value, commit_data); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::hashtable::erase(const_iterator)
void erase(const_iterator i);
//! @copydoc ::boost::intrusive::hashtable::erase(const_iterator,const_iterator)
void erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::erase(const key_type &)
size_type erase(const key_type &key);
//! @copydoc ::boost::intrusive::hashtable::erase(const KeyType&,KeyHasher,KeyEqual)
template<class KeyType, class KeyHasher, class KeyEqual>
size_type erase(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func);
//! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
BOOST_INTRUSIVE_DOC1ST(void
, typename detail::disable_if_convertible<Disposer BOOST_INTRUSIVE_I const_iterator>::type)
erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const_iterator,const_iterator,Disposer)
template<class Disposer>
void erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const key_type &,Disposer)
template<class Disposer>
size_type erase_and_dispose(const key_type &key, Disposer disposer);
//! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const KeyType&,KeyHasher,KeyEqual,Disposer)
template<class KeyType, class KeyHasher, class KeyEqual, class Disposer>
size_type erase_and_dispose(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func, Disposer disposer);
//! @copydoc ::boost::intrusive::hashtable::clear
void clear() BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::clear_and_dispose
template<class Disposer>
void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::count(const key_type &)const
size_type count(const key_type &key) const;
//! @copydoc ::boost::intrusive::hashtable::count(const KeyType&,KeyHasher,KeyEqual)const
template<class KeyType, class KeyHasher, class KeyEqual>
size_type count(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func) const;
//! @copydoc ::boost::intrusive::hashtable::find(const key_type &)
iterator find(const key_type &key);
//! @copydoc ::boost::intrusive::hashtable::find(const KeyType &,KeyHasher,KeyEqual)
template<class KeyType, class KeyHasher, class KeyEqual>
iterator find(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func);
//! @copydoc ::boost::intrusive::hashtable::count(const key_type &)const
const_iterator find(const key_type &key) const;
//! @copydoc ::boost::intrusive::hashtable::find(const KeyType &,KeyHasher,KeyEqual)const
template<class KeyType, class KeyHasher, class KeyEqual>
const_iterator find(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func) const;
#endif
//! @copydoc ::boost::intrusive::hashtable::equal_range(const key_type&)
std::pair<iterator,iterator> equal_range(const key_type &key)
{ return this->equal_range(key, this->hash_function(), this->key_eq()); }
//! @copydoc ::boost::intrusive::hashtable::equal_range(const KeyType &,KeyHasher,KeyEqual)
template<class KeyType, class KeyHasher, class KeyEqual>
std::pair<iterator,iterator> equal_range(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func)
{ return this->priv_equal_range<iterator>(*this, key, hash_func, equal_func); }
//! @copydoc ::boost::intrusive::hashtable::equal_range(const key_type&)const
std::pair<const_iterator, const_iterator>
equal_range(const key_type &key) const
{ return this->equal_range(key, this->hash_function(), this->key_eq()); }
//! @copydoc ::boost::intrusive::hashtable::equal_range(const KeyType &,KeyHasher,KeyEqual)const
template<class KeyType, class KeyHasher, class KeyEqual>
std::pair<const_iterator, const_iterator>
equal_range(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func) const
{ return this->priv_equal_range<const_iterator>(*this, key, hash_func, equal_func); }
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
//! @copydoc ::boost::intrusive::hashtable::iterator_to(reference)
iterator iterator_to(reference value) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::iterator_to(const_reference)const
const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::s_local_iterator_to(reference)
static local_iterator s_local_iterator_to(reference value) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::s_local_iterator_to(const_reference)
static const_local_iterator s_local_iterator_to(const_reference value) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::local_iterator_to(reference)
local_iterator local_iterator_to(reference value) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::local_iterator_to(const_reference)
const_local_iterator local_iterator_to(const_reference value) const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::bucket_count
size_type bucket_count() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::bucket_size
size_type bucket_size(size_type n) const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::bucket(const key_type&)const
size_type bucket(const key_type& k) const;
//! @copydoc ::boost::intrusive::hashtable::bucket(const KeyType&,KeyHasher)const
template<class KeyType, class KeyHasher>
size_type bucket(const KeyType& k, KeyHasher hash_func) const;
//! @copydoc ::boost::intrusive::hashtable::bucket_pointer
bucket_ptr bucket_pointer() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::begin(size_type)
local_iterator begin(size_type n) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::begin(size_type)const
const_local_iterator begin(size_type n) const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::cbegin(size_type)const
const_local_iterator cbegin(size_type n) const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::end(size_type)
local_iterator end(size_type n) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::end(size_type)const
const_local_iterator end(size_type n) const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::cend(size_type)const
const_local_iterator cend(size_type n) const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::rehash(const bucket_traits &)
void rehash(const bucket_traits &new_bucket_traits);
//! @copydoc ::boost::intrusive::hashtable::full_rehash
void full_rehash();
//! @copydoc ::boost::intrusive::hashtable::incremental_rehash(bool)
bool incremental_rehash(bool grow = true);
//! @copydoc ::boost::intrusive::hashtable::incremental_rehash(const bucket_traits &)
bool incremental_rehash(const bucket_traits &new_bucket_traits);
//! @copydoc ::boost::intrusive::hashtable::split_count
size_type split_count() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::suggested_upper_bucket_count
static size_type suggested_upper_bucket_count(size_type n) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::suggested_lower_bucket_count
static size_type suggested_lower_bucket_count(size_type n) BOOST_NOEXCEPT;
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
friend bool operator==(const unordered_set_impl &x, const unordered_set_impl &y)
{
if(table_type::constant_time_size && x.size() != y.size()){
return false;
}
//Find each element of x in y
for (const_iterator ix = x.cbegin(), ex = x.cend(), ey = y.cend(); ix != ex; ++ix){
const_iterator iy = y.find(key_of_value()(*ix));
if (iy == ey || !(*ix == *iy))
return false;
}
return true;
}
friend bool operator!=(const unordered_set_impl &x, const unordered_set_impl &y)
{ return !(x == y); }
friend bool operator<(const unordered_set_impl &x, const unordered_set_impl &y)
{ return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
friend bool operator>(const unordered_set_impl &x, const unordered_set_impl &y)
{ return y < x; }
friend bool operator<=(const unordered_set_impl &x, const unordered_set_impl &y)
{ return !(y < x); }
friend bool operator>=(const unordered_set_impl &x, const unordered_set_impl &y)
{ return !(x < y); }
};
//! Helper metafunction to define an \c unordered_set that yields to the same type when the
//! same options (either explicitly or implicitly) are used.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
, class O5 = void, class O6 = void
, class O7 = void, class O8 = void
, class O9 = void, class O10= void
>
#endif
struct make_unordered_set
{
/// @cond
typedef typename pack_options
< hashtable_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
O1, O2, O3, O4, O5, O6, O7, O8, O9, O10
#else
Options...
#endif
>::type packed_options;
typedef typename detail::get_value_traits
<T, typename packed_options::proto_value_traits>::type value_traits;
typedef typename make_bucket_traits
<T, true, packed_options>::type bucket_traits;
typedef unordered_set_impl
< value_traits
, typename packed_options::key_of_value
, typename packed_options::hash
, typename packed_options::equal
, typename packed_options::size_type
, bucket_traits
, (std::size_t(true)*hash_bool_flags::unique_keys_pos)
| (std::size_t(packed_options::constant_time_size)*hash_bool_flags::constant_time_size_pos)
| (std::size_t(packed_options::power_2_buckets)*hash_bool_flags::power_2_buckets_pos)
| (std::size_t(packed_options::cache_begin)*hash_bool_flags::cache_begin_pos)
| (std::size_t(packed_options::compare_hash)*hash_bool_flags::compare_hash_pos)
| (std::size_t(packed_options::incremental)*hash_bool_flags::incremental_pos)
> implementation_defined;
/// @endcond
typedef implementation_defined type;
};
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class T, class O1, class O2, class O3, class O4, class O5, class O6, class O7, class O8, class O9, class O10>
#else
template<class T, class ...Options>
#endif
class unordered_set
: public make_unordered_set<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
O1, O2, O3, O4, O5, O6, O7, O8, O9, O10
#else
Options...
#endif
>::type
{
typedef typename make_unordered_set
<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
O1, O2, O3, O4, O5, O6, O7, O8, O9, O10
#else
Options...
#endif
>::type Base;
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename Base::value_traits::value_type, T>::value));
BOOST_MOVABLE_BUT_NOT_COPYABLE(unordered_set)
public:
typedef typename Base::value_traits value_traits;
typedef typename Base::bucket_traits bucket_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
typedef typename Base::bucket_ptr bucket_ptr;
typedef typename Base::size_type size_type;
typedef typename Base::hasher hasher;
typedef typename Base::key_equal key_equal;
BOOST_INTRUSIVE_FORCEINLINE
explicit unordered_set ( const bucket_traits &b_traits
, const hasher & hash_func = hasher()
, const key_equal &equal_func = key_equal()
, const value_traits &v_traits = value_traits())
: Base(b_traits, hash_func, equal_func, v_traits)
{}
template<class Iterator>
BOOST_INTRUSIVE_FORCEINLINE
unordered_set
( Iterator b, Iterator e
, const bucket_traits &b_traits
, const hasher & hash_func = hasher()
, const key_equal &equal_func = key_equal()
, const value_traits &v_traits = value_traits())
: Base(b, e, b_traits, hash_func, equal_func, v_traits)
{}
BOOST_INTRUSIVE_FORCEINLINE unordered_set(BOOST_RV_REF(unordered_set) x)
: Base(BOOST_MOVE_BASE(Base, x))
{}
BOOST_INTRUSIVE_FORCEINLINE unordered_set& operator=(BOOST_RV_REF(unordered_set) x)
{ return static_cast<unordered_set&>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
template <class Cloner, class Disposer>
BOOST_INTRUSIVE_FORCEINLINE void clone_from(const unordered_set &src, Cloner cloner, Disposer disposer)
{ Base::clone_from(src, cloner, disposer); }
template <class Cloner, class Disposer>
BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(unordered_set) src, Cloner cloner, Disposer disposer)
{ Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
};
#endif
//! The class template unordered_multiset is an intrusive container, that mimics most of
//! the interface of std::tr1::unordered_multiset as described in the C++ TR1.
//!
//! unordered_multiset is a semi-intrusive container: each object to be stored in the
//! container must contain a proper hook, but the container also needs
//! additional auxiliary memory to work: unordered_multiset needs a pointer to an array
//! of type `bucket_type` to be passed in the constructor. This bucket array must
//! have at least the same lifetime as the container. This makes the use of
//! unordered_multiset more complicated than purely intrusive containers.
//! `bucket_type` is default-constructible, copyable and assignable
//!
//! The template parameter \c T is the type to be managed by the container.
//! The user can specify additional options and if no options are provided
//! default options are used.
//!
//! The container supports the following options:
//! \c base_hook<>/member_hook<>/value_traits<>,
//! \c constant_time_size<>, \c size_type<>, \c hash<> and \c equal<>
//! \c bucket_traits<>, \c power_2_buckets<> and \c cache_begin<>.
//!
//! unordered_multiset only provides forward iterators but it provides 4 iterator types:
//! iterator and const_iterator to navigate through the whole container and
//! local_iterator and const_local_iterator to navigate through the values
//! stored in a single bucket. Local iterators are faster and smaller.
//!
//! It's not recommended to use non constant-time size unordered_multisets because several
//! key functions, like "empty()", become non-constant time functions. Non
//! constant-time size unordered_multisets are mainly provided to support auto-unlink hooks.
//!
//! unordered_multiset, unlike std::unordered_set, does not make automatic rehashings nor
//! offers functions related to a load factor. Rehashing can be explicitly requested
//! and the user must provide a new bucket array that will be used from that moment.
//!
//! Since no automatic rehashing is done, iterators are never invalidated when
//! inserting or erasing elements. Iterators are only invalidated when rehasing.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyHash, class VoidOrKeyEqual, class SizeType, class BucketTraits, std::size_t BoolFlags>
#endif
class unordered_multiset_impl
: public hashtable_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual, BucketTraits, SizeType, BoolFlags>
{
/// @cond
private:
typedef hashtable_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual, BucketTraits, SizeType, BoolFlags> table_type;
/// @endcond
//Movable
BOOST_MOVABLE_BUT_NOT_COPYABLE(unordered_multiset_impl)
typedef table_type implementation_defined;
public:
typedef typename implementation_defined::value_type value_type;
typedef typename implementation_defined::key_type key_type;
typedef typename implementation_defined::value_traits value_traits;
typedef typename implementation_defined::bucket_traits bucket_traits;
typedef typename implementation_defined::pointer pointer;
typedef typename implementation_defined::const_pointer const_pointer;
typedef typename implementation_defined::reference reference;
typedef typename implementation_defined::const_reference const_reference;
typedef typename implementation_defined::difference_type difference_type;
typedef typename implementation_defined::size_type size_type;
typedef typename implementation_defined::key_equal key_equal;
typedef typename implementation_defined::hasher hasher;
typedef typename implementation_defined::bucket_type bucket_type;
typedef typename implementation_defined::bucket_ptr bucket_ptr;
typedef typename implementation_defined::iterator iterator;
typedef typename implementation_defined::const_iterator const_iterator;
typedef typename implementation_defined::insert_commit_data insert_commit_data;
typedef typename implementation_defined::local_iterator local_iterator;
typedef typename implementation_defined::const_local_iterator const_local_iterator;
typedef typename implementation_defined::node_traits node_traits;
typedef typename implementation_defined::node node;
typedef typename implementation_defined::node_ptr node_ptr;
typedef typename implementation_defined::const_node_ptr const_node_ptr;
typedef typename implementation_defined::node_algorithms node_algorithms;
public:
//! @copydoc ::boost::intrusive::hashtable::hashtable(const bucket_traits &,const hasher &,const key_equal &,const value_traits &)
BOOST_INTRUSIVE_FORCEINLINE explicit unordered_multiset_impl ( const bucket_traits &b_traits
, const hasher & hash_func = hasher()
, const key_equal &equal_func = key_equal()
, const value_traits &v_traits = value_traits())
: table_type(b_traits, hash_func, equal_func, v_traits)
{}
//! @copydoc ::boost::intrusive::hashtable::hashtable(bool,Iterator,Iterator,const bucket_traits &,const hasher &,const key_equal &,const value_traits &)
template<class Iterator>
BOOST_INTRUSIVE_FORCEINLINE unordered_multiset_impl ( Iterator b
, Iterator e
, const bucket_traits &b_traits
, const hasher & hash_func = hasher()
, const key_equal &equal_func = key_equal()
, const value_traits &v_traits = value_traits())
: table_type(false, b, e, b_traits, hash_func, equal_func, v_traits)
{}
//! <b>Effects</b>: to-do
//!
BOOST_INTRUSIVE_FORCEINLINE unordered_multiset_impl(BOOST_RV_REF(unordered_multiset_impl) x)
: table_type(BOOST_MOVE_BASE(table_type, x))
{}
//! <b>Effects</b>: to-do
//!
BOOST_INTRUSIVE_FORCEINLINE unordered_multiset_impl& operator=(BOOST_RV_REF(unordered_multiset_impl) x)
{ return static_cast<unordered_multiset_impl&>(table_type::operator=(BOOST_MOVE_BASE(table_type, x))); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::hashtable::~hashtable()
~unordered_multiset_impl();
//! @copydoc ::boost::intrusive::hashtable::begin()
iterator begin() BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::begin()const
const_iterator begin() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::cbegin()const
const_iterator cbegin() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::end()
iterator end() BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::end()const
const_iterator end() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::cend()const
const_iterator cend() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::hash_function()const
hasher hash_function() const;
//! @copydoc ::boost::intrusive::hashtable::key_eq()const
key_equal key_eq() const;
//! @copydoc ::boost::intrusive::hashtable::empty()const
bool empty() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::size()const
size_type size() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::hashtable
void swap(unordered_multiset_impl& other);
//! @copydoc ::boost::intrusive::hashtable::clone_from(const hashtable&,Cloner,Disposer)
template <class Cloner, class Disposer>
void clone_from(const unordered_multiset_impl &src, Cloner cloner, Disposer disposer);
#else
using table_type::clone_from;
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::hashtable::clone_from(hashtable&&,Cloner,Disposer)
template <class Cloner, class Disposer>
BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(unordered_multiset_impl) src, Cloner cloner, Disposer disposer)
{ table_type::clone_from(BOOST_MOVE_BASE(table_type, src), cloner, disposer); }
//! @copydoc ::boost::intrusive::hashtable::insert_equal(reference)
BOOST_INTRUSIVE_FORCEINLINE iterator insert(reference value)
{ return table_type::insert_equal(value); }
//! @copydoc ::boost::intrusive::hashtable::insert_equal(Iterator,Iterator)
template<class Iterator>
BOOST_INTRUSIVE_FORCEINLINE void insert(Iterator b, Iterator e)
{ table_type::insert_equal(b, e); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::hashtable::erase(const_iterator)
void erase(const_iterator i);
//! @copydoc ::boost::intrusive::hashtable::erase(const_iterator,const_iterator)
void erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::erase(const key_type &)
size_type erase(const key_type &key);
//! @copydoc ::boost::intrusive::hashtable::erase(const KeyType&,KeyHasher,KeyEqual)
template<class KeyType, class KeyHasher, class KeyEqual>
size_type erase(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func);
//! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
BOOST_INTRUSIVE_DOC1ST(void
, typename detail::disable_if_convertible<Disposer BOOST_INTRUSIVE_I const_iterator>::type)
erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const_iterator,const_iterator,Disposer)
template<class Disposer>
void erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const key_type &,Disposer)
template<class Disposer>
size_type erase_and_dispose(const key_type &key, Disposer disposer);
//! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const KeyType&,KeyHasher,KeyEqual,Disposer)
template<class KeyType, class KeyHasher, class KeyEqual, class Disposer>
size_type erase_and_dispose(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func, Disposer disposer);
//! @copydoc ::boost::intrusive::hashtable::clear
void clear() BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::clear_and_dispose
template<class Disposer>
void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::count(const key_type &)const
size_type count(const key_type &key) const;
//! @copydoc ::boost::intrusive::hashtable::count(const KeyType&,KeyHasher,KeyEqual)const
template<class KeyType, class KeyHasher, class KeyEqual>
size_type count(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func) const;
//! @copydoc ::boost::intrusive::hashtable::find(const key_type &)
iterator find(const key_type &key);
//! @copydoc ::boost::intrusive::hashtable::find(const KeyType &,KeyHasher,KeyEqual)
template<class KeyType, class KeyHasher, class KeyEqual>
iterator find(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func);
//! @copydoc ::boost::intrusive::hashtable::count(const key_type &)const
const_iterator find(const key_type &key) const;
//! @copydoc ::boost::intrusive::hashtable::find(const KeyType &,KeyHasher,KeyEqual)const
template<class KeyType, class KeyHasher, class KeyEqual>
const_iterator find(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func) const;
//! @copydoc ::boost::intrusive::hashtable::equal_range(const key_type&)
std::pair<iterator,iterator> equal_range(const key_type &key);
//! @copydoc ::boost::intrusive::hashtable::equal_range(const KeyType &,KeyHasher,KeyEqual)
template<class KeyType, class KeyHasher, class KeyEqual>
std::pair<iterator,iterator> equal_range(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func);
//! @copydoc ::boost::intrusive::hashtable::equal_range(const key_type&)const
std::pair<const_iterator, const_iterator>
equal_range(const key_type &key) const;
//! @copydoc ::boost::intrusive::hashtable::equal_range(const KeyType &,KeyHasher,KeyEqual)const
template<class KeyType, class KeyHasher, class KeyEqual>
std::pair<const_iterator, const_iterator>
equal_range(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func) const;
//! @copydoc ::boost::intrusive::hashtable::iterator_to(reference)
iterator iterator_to(reference value) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::iterator_to(const_reference)const
const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::s_local_iterator_to(reference)
static local_iterator s_local_iterator_to(reference value) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::s_local_iterator_to(const_reference)
static const_local_iterator s_local_iterator_to(const_reference value) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::local_iterator_to(reference)
local_iterator local_iterator_to(reference value) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::local_iterator_to(const_reference)
const_local_iterator local_iterator_to(const_reference value) const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::bucket_count
size_type bucket_count() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::bucket_size
size_type bucket_size(size_type n) const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::bucket(const key_type&)const
size_type bucket(const key_type& k) const;
//! @copydoc ::boost::intrusive::hashtable::bucket(const KeyType&,KeyHasher)const
template<class KeyType, class KeyHasher>
size_type bucket(const KeyType& k, KeyHasher hash_func) const;
//! @copydoc ::boost::intrusive::hashtable::bucket_pointer
bucket_ptr bucket_pointer() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::begin(size_type)
local_iterator begin(size_type n) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::begin(size_type)const
const_local_iterator begin(size_type n) const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::cbegin(size_type)const
const_local_iterator cbegin(size_type n) const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::end(size_type)
local_iterator end(size_type n) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::end(size_type)const
const_local_iterator end(size_type n) const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::cend(size_type)const
const_local_iterator cend(size_type n) const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::rehash(const bucket_traits &)
void rehash(const bucket_traits &new_bucket_traits);
//! @copydoc ::boost::intrusive::hashtable::full_rehash
void full_rehash();
//! @copydoc ::boost::intrusive::hashtable::incremental_rehash(bool)
bool incremental_rehash(bool grow = true);
//! @copydoc ::boost::intrusive::hashtable::incremental_rehash(const bucket_traits &)
bool incremental_rehash(const bucket_traits &new_bucket_traits);
//! @copydoc ::boost::intrusive::hashtable::split_count
size_type split_count() const BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::suggested_upper_bucket_count
static size_type suggested_upper_bucket_count(size_type n) BOOST_NOEXCEPT;
//! @copydoc ::boost::intrusive::hashtable::suggested_lower_bucket_count
static size_type suggested_lower_bucket_count(size_type n) BOOST_NOEXCEPT;
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
};
//! Helper metafunction to define an \c unordered_multiset that yields to the same type when the
//! same options (either explicitly or implicitly) are used.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
, class O5 = void, class O6 = void
, class O7 = void, class O8 = void
, class O9 = void, class O10= void
>
#endif
struct make_unordered_multiset
{
/// @cond
typedef typename pack_options
< hashtable_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
O1, O2, O3, O4, O5, O6, O7, O8, O9, O10
#else
Options...
#endif
>::type packed_options;
typedef typename detail::get_value_traits
<T, typename packed_options::proto_value_traits>::type value_traits;
typedef typename make_bucket_traits
<T, true, packed_options>::type bucket_traits;
typedef unordered_multiset_impl
< value_traits
, typename packed_options::key_of_value
, typename packed_options::hash
, typename packed_options::equal
, typename packed_options::size_type
, bucket_traits
, (std::size_t(false)*hash_bool_flags::unique_keys_pos)
| (std::size_t(packed_options::constant_time_size)*hash_bool_flags::constant_time_size_pos)
| (std::size_t(packed_options::power_2_buckets)*hash_bool_flags::power_2_buckets_pos)
| (std::size_t(packed_options::cache_begin)*hash_bool_flags::cache_begin_pos)
| (std::size_t(packed_options::compare_hash)*hash_bool_flags::compare_hash_pos)
| (std::size_t(packed_options::incremental)*hash_bool_flags::incremental_pos)
> implementation_defined;
/// @endcond
typedef implementation_defined type;
};
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class T, class O1, class O2, class O3, class O4, class O5, class O6, class O7, class O8, class O9, class O10>
#else
template<class T, class ...Options>
#endif
class unordered_multiset
: public make_unordered_multiset<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
O1, O2, O3, O4, O5, O6, O7, O8, O9, O10
#else
Options...
#endif
>::type
{
typedef typename make_unordered_multiset
<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
O1, O2, O3, O4, O5, O6, O7, O8, O9, O10
#else
Options...
#endif
>::type Base;
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename Base::value_traits::value_type, T>::value));
BOOST_MOVABLE_BUT_NOT_COPYABLE(unordered_multiset)
public:
typedef typename Base::value_traits value_traits;
typedef typename Base::bucket_traits bucket_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
typedef typename Base::bucket_ptr bucket_ptr;
typedef typename Base::size_type size_type;
typedef typename Base::hasher hasher;
typedef typename Base::key_equal key_equal;
BOOST_INTRUSIVE_FORCEINLINE
explicit unordered_multiset( const bucket_traits &b_traits
, const hasher & hash_func = hasher()
, const key_equal &equal_func = key_equal()
, const value_traits &v_traits = value_traits())
: Base(b_traits, hash_func, equal_func, v_traits)
{}
template<class Iterator>
BOOST_INTRUSIVE_FORCEINLINE
unordered_multiset( Iterator b
, Iterator e
, const bucket_traits &b_traits
, const hasher & hash_func = hasher()
, const key_equal &equal_func = key_equal()
, const value_traits &v_traits = value_traits())
: Base(b, e, b_traits, hash_func, equal_func, v_traits)
{}
BOOST_INTRUSIVE_FORCEINLINE unordered_multiset(BOOST_RV_REF(unordered_multiset) x)
: Base(BOOST_MOVE_BASE(Base, x))
{}
BOOST_INTRUSIVE_FORCEINLINE unordered_multiset& operator=(BOOST_RV_REF(unordered_multiset) x)
{ return static_cast<unordered_multiset&>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
template <class Cloner, class Disposer>
BOOST_INTRUSIVE_FORCEINLINE void clone_from(const unordered_multiset &src, Cloner cloner, Disposer disposer)
{ Base::clone_from(src, cloner, disposer); }
template <class Cloner, class Disposer>
BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(unordered_multiset) src, Cloner cloner, Disposer disposer)
{ Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
};
#endif
} //namespace intrusive
} //namespace boost
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_UNORDERED_SET_HPP

View File

@@ -0,0 +1,459 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
// (C) Copyright Ion Gaztanaga 2006-2013
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_UNORDERED_SET_HOOK_HPP
#define BOOST_INTRUSIVE_UNORDERED_SET_HOOK_HPP
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/slist_hook.hpp>
#include <boost/intrusive/options.hpp>
#include <boost/intrusive/detail/generic_hook.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
namespace boost {
namespace intrusive {
/// @cond
template<class VoidPointer, bool StoreHash, bool OptimizeMultiKey>
struct unordered_node
: public slist_node<VoidPointer>
{
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer
< unordered_node<VoidPointer, StoreHash, OptimizeMultiKey> >::type
node_ptr;
node_ptr prev_in_group_;
std::size_t hash_;
};
template<class VoidPointer>
struct unordered_node<VoidPointer, false, true>
: public slist_node<VoidPointer>
{
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer
< unordered_node<VoidPointer, false, true> >::type
node_ptr;
node_ptr prev_in_group_;
};
template<class VoidPointer>
struct unordered_node<VoidPointer, true, false>
: public slist_node<VoidPointer>
{
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer
< unordered_node<VoidPointer, true, false> >::type
node_ptr;
std::size_t hash_;
};
template<class VoidPointer, bool StoreHash, bool OptimizeMultiKey>
struct unordered_node_traits
: public slist_node_traits<VoidPointer>
{
typedef slist_node_traits<VoidPointer> reduced_slist_node_traits;
typedef unordered_node<VoidPointer, StoreHash, OptimizeMultiKey> node;
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer
< node >::type node_ptr;
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer
< const node >::type const_node_ptr;
static const bool store_hash = StoreHash;
static const bool optimize_multikey = OptimizeMultiKey;
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_next(const_node_ptr n) BOOST_NOEXCEPT
{ return pointer_traits<node_ptr>::static_cast_from(n->next_); }
BOOST_INTRUSIVE_FORCEINLINE static void set_next(node_ptr n, node_ptr next) BOOST_NOEXCEPT
{ n->next_ = next; }
BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_prev_in_group(const_node_ptr n) BOOST_NOEXCEPT
{ return n->prev_in_group_; }
BOOST_INTRUSIVE_FORCEINLINE static void set_prev_in_group(node_ptr n, node_ptr prev) BOOST_NOEXCEPT
{ n->prev_in_group_ = prev; }
BOOST_INTRUSIVE_FORCEINLINE static std::size_t get_hash(const_node_ptr n) BOOST_NOEXCEPT
{ return n->hash_; }
BOOST_INTRUSIVE_FORCEINLINE static void set_hash(node_ptr n, std::size_t h) BOOST_NOEXCEPT
{ n->hash_ = h; }
};
template<class NodeTraits>
struct unordered_group_adapter
{
typedef typename NodeTraits::node node;
typedef typename NodeTraits::node_ptr node_ptr;
typedef typename NodeTraits::const_node_ptr const_node_ptr;
static node_ptr get_next(const_node_ptr n)
{ return NodeTraits::get_prev_in_group(n); }
static void set_next(node_ptr n, node_ptr next)
{ NodeTraits::set_prev_in_group(n, next); }
};
template<class NodeTraits>
struct unordered_algorithms
: public circular_slist_algorithms<NodeTraits>
{
typedef circular_slist_algorithms<NodeTraits> base_type;
typedef unordered_group_adapter<NodeTraits> group_traits;
typedef circular_slist_algorithms<group_traits> group_algorithms;
typedef NodeTraits node_traits;
typedef typename NodeTraits::node node;
typedef typename NodeTraits::node_ptr node_ptr;
typedef typename NodeTraits::const_node_ptr const_node_ptr;
BOOST_INTRUSIVE_FORCEINLINE static void init(typename base_type::node_ptr n) BOOST_NOEXCEPT
{
base_type::init(n);
group_algorithms::init(n);
}
BOOST_INTRUSIVE_FORCEINLINE static void init_header(typename base_type::node_ptr n) BOOST_NOEXCEPT
{
base_type::init_header(n);
group_algorithms::init_header(n);
}
BOOST_INTRUSIVE_FORCEINLINE static void unlink(typename base_type::node_ptr n) BOOST_NOEXCEPT
{
base_type::unlink(n);
group_algorithms::unlink(n);
}
};
//Class to avoid defining the same algo as a circular list, as hooks would be ambiguous between them
template<class Algo>
struct uset_algo_wrapper : public Algo
{};
template<class VoidPointer, bool StoreHash, bool OptimizeMultiKey>
struct get_uset_node_traits
{
typedef typename detail::if_c
< (StoreHash || OptimizeMultiKey)
, unordered_node_traits<VoidPointer, StoreHash, OptimizeMultiKey>
, slist_node_traits<VoidPointer>
>::type type;
};
template<bool OptimizeMultiKey>
struct get_uset_algo_type
{
static const algo_types value = OptimizeMultiKey ? UnorderedAlgorithms : UnorderedCircularSlistAlgorithms;
};
template<class NodeTraits>
struct get_algo<UnorderedAlgorithms, NodeTraits>
{
typedef unordered_algorithms<NodeTraits> type;
};
template<class NodeTraits>
struct get_algo<UnorderedCircularSlistAlgorithms, NodeTraits>
{
typedef uset_algo_wrapper< circular_slist_algorithms<NodeTraits> > type;
};
/// @endcond
//! Helper metafunction to define a \c unordered_set_base_hook that yields to the same
//! type when the same options (either explicitly or implicitly) are used.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class ...Options>
#else
template<class O1 = void, class O2 = void, class O3 = void, class O4 = void>
#endif
struct make_unordered_set_base_hook
{
/// @cond
typedef typename pack_options
< hook_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
O1, O2, O3, O4
#else
Options...
#endif
>::type packed_options;
typedef generic_hook
< get_uset_algo_type <packed_options::optimize_multikey>::value
, typename get_uset_node_traits < typename packed_options::void_pointer
, packed_options::store_hash
, packed_options::optimize_multikey
>::type
, typename packed_options::tag
, packed_options::link_mode
, HashBaseHookId
> implementation_defined;
/// @endcond
typedef implementation_defined type;
};
//! Derive a class from unordered_set_base_hook in order to store objects in
//! in an unordered_set/unordered_multi_set. unordered_set_base_hook holds the data necessary to maintain
//! the unordered_set/unordered_multi_set and provides an appropriate value_traits class for unordered_set/unordered_multi_set.
//!
//! The hook admits the following options: \c tag<>, \c void_pointer<>,
//! \c link_mode<>, \c store_hash<> and \c optimize_multikey<>.
//!
//! \c tag<> defines a tag to identify the node.
//! The same tag value can be used in different classes, but if a class is
//! derived from more than one \c list_base_hook, then each \c list_base_hook needs its
//! unique tag.
//!
//! \c void_pointer<> is the pointer type that will be used internally in the hook
//! and the container configured to use this hook.
//!
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
//! \c auto_unlink or \c safe_link).
//!
//! \c store_hash<> will tell the hook to store the hash of the value
//! to speed up rehashings.
//!
//! \c optimize_multikey<> will tell the hook to store a link to form a group
//! with other value with the same value to speed up searches and insertions
//! in unordered_multisets with a great number of with equivalent keys.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class ...Options>
#else
template<class O1, class O2, class O3, class O4>
#endif
class unordered_set_base_hook
: public make_unordered_set_base_hook<
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
O1, O2, O3, O4
#else
Options...
#endif
>::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.
//!
//! <b>Throws</b>: Nothing.
unordered_set_base_hook() BOOST_NOEXCEPT;
//! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state. The argument is ignored.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Rationale</b>: Providing a copy-constructor
//! makes classes using the hook STL-compliant without forcing the
//! user to do some additional work. \c swap can be used to emulate
//! move-semantics.
unordered_set_base_hook(const unordered_set_base_hook& ) BOOST_NOEXCEPT;
//! <b>Effects</b>: Empty function. The argument is ignored.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Rationale</b>: Providing an assignment operator
//! makes classes using the hook STL-compliant without forcing the
//! user to do some additional work. \c swap can be used to emulate
//! move-semantics.
unordered_set_base_hook& operator=(const unordered_set_base_hook& ) BOOST_NOEXCEPT;
//! <b>Effects</b>: If link_mode is \c normal_link, the destructor does
//! nothing (ie. no code is generated). If link_mode is \c safe_link and the
//! object is stored in an unordered_set an assertion is raised. If link_mode is
//! \c auto_unlink and \c is_linked() is true, the node is unlinked.
//!
//! <b>Throws</b>: Nothing.
~unordered_set_base_hook();
//! <b>Effects</b>: Swapping two nodes swaps the position of the elements
//! related to those nodes in one or two containers. That is, if the node
//! this is part of the element e1, the node x is part of the element e2
//! and both elements are included in the containers s1 and s2, then after
//! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1
//! at the position of e1. If one element is not in a container, then
//! after the swap-operation the other element is not in a container.
//! Iterators to e1 and e2 related to those nodes are invalidated.
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
void swap_nodes(unordered_set_base_hook &other) BOOST_NOEXCEPT;
//! <b>Precondition</b>: link_mode must be \c safe_link or \c auto_unlink.
//!
//! <b>Returns</b>: true, if the node belongs to a container, false
//! otherwise. This function can be used to test whether \c unordered_set::iterator_to
//! will return a valid iterator.
//!
//! <b>Complexity</b>: Constant
bool is_linked() const BOOST_NOEXCEPT;
//! <b>Effects</b>: Removes the node if it's inserted in a container.
//! This function is only allowed if link_mode is \c auto_unlink.
//!
//! <b>Throws</b>: Nothing.
void unlink() BOOST_NOEXCEPT;
#endif
};
//! Helper metafunction to define a \c unordered_set_member_hook that yields to the same
//! type when the same options (either explicitly or implicitly) are used.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class ...Options>
#else
template<class O1 = void, class O2 = void, class O3 = void, class O4 = void>
#endif
struct make_unordered_set_member_hook
{
/// @cond
typedef typename pack_options
< hook_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
O1, O2, O3, O4
#else
Options...
#endif
>::type packed_options;
typedef generic_hook
< get_uset_algo_type <packed_options::optimize_multikey>::value
, typename get_uset_node_traits < typename packed_options::void_pointer
, packed_options::store_hash
, packed_options::optimize_multikey
>::type
, member_tag
, packed_options::link_mode
, NoBaseHookId
> implementation_defined;
/// @endcond
typedef implementation_defined type;
};
//! Put a public data member unordered_set_member_hook in order to store objects of this class in
//! an unordered_set/unordered_multi_set. unordered_set_member_hook holds the data necessary for maintaining the
//! unordered_set/unordered_multi_set and provides an appropriate value_traits class for unordered_set/unordered_multi_set.
//!
//! The hook admits the following options: \c void_pointer<>,
//! \c link_mode<> and \c store_hash<>.
//!
//! \c void_pointer<> is the pointer type that will be used internally in the hook
//! and the container configured to use this hook.
//!
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
//! \c auto_unlink or \c safe_link).
//!
//! \c store_hash<> will tell the hook to store the hash of the value
//! to speed up rehashings.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
template<class ...Options>
#else
template<class O1, class O2, class O3, class O4>
#endif
class unordered_set_member_hook
: public make_unordered_set_member_hook<
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
O1, O2, O3, O4
#else
Options...
#endif
>::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.
//!
//! <b>Throws</b>: Nothing.
unordered_set_member_hook();
//! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state. The argument is ignored.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Rationale</b>: Providing a copy-constructor
//! makes classes using the hook STL-compliant without forcing the
//! user to do some additional work. \c swap can be used to emulate
//! move-semantics.
unordered_set_member_hook(const unordered_set_member_hook& );
//! <b>Effects</b>: Empty function. The argument is ignored.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Rationale</b>: Providing an assignment operator
//! makes classes using the hook STL-compliant without forcing the
//! user to do some additional work. \c swap can be used to emulate
//! move-semantics.
unordered_set_member_hook& operator=(const unordered_set_member_hook& );
//! <b>Effects</b>: If link_mode is \c normal_link, the destructor does
//! nothing (ie. no code is generated). If link_mode is \c safe_link and the
//! object is stored in an unordered_set an assertion is raised. If link_mode is
//! \c auto_unlink and \c is_linked() is true, the node is unlinked.
//!
//! <b>Throws</b>: Nothing.
~unordered_set_member_hook();
//! <b>Effects</b>: Swapping two nodes swaps the position of the elements
//! related to those nodes in one or two containers. That is, if the node
//! this is part of the element e1, the node x is part of the element e2
//! and both elements are included in the containers s1 and s2, then after
//! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1
//! at the position of e1. If one element is not in a container, then
//! after the swap-operation the other element is not in a container.
//! Iterators to e1 and e2 related to those nodes are invalidated.
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
void swap_nodes(unordered_set_member_hook &other);
//! <b>Precondition</b>: link_mode must be \c safe_link or \c auto_unlink.
//!
//! <b>Returns</b>: true, if the node belongs to a container, false
//! otherwise. This function can be used to test whether \c unordered_set::iterator_to
//! will return a valid iterator.
//!
//! <b>Complexity</b>: Constant
bool is_linked() const;
//! <b>Effects</b>: Removes the node if it's inserted in a container.
//! This function is only allowed if link_mode is \c auto_unlink.
//!
//! <b>Throws</b>: Nothing.
void unlink();
#endif
};
} //namespace intrusive
} //namespace boost
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_UNORDERED_SET_HOOK_HPP

View File

@@ -0,0 +1,23 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,4 @@
The package boost is compatible with built-in CMake targets:
find_package(Boost REQUIRED [COMPONENTS <libs>...])
target_link_libraries(main PRIVATE Boost::boost Boost::<lib1> Boost::<lib2> ...)

View File

@@ -0,0 +1,115 @@
{
"$schema": "https://raw.githubusercontent.com/spdx/spdx-spec/v2.2.1/schemas/spdx-schema.json",
"spdxVersion": "SPDX-2.2",
"dataLicense": "CC0-1.0",
"SPDXID": "SPDXRef-DOCUMENT",
"documentNamespace": "https://spdx.org/spdxdocs/boost-intrusive-x64-windows-1.79.0-ac7c3969-b03a-4c33-990d-aa05c8cc05e7",
"name": "boost-intrusive:x64-windows@1.79.0 531507e8bb60357a5f2420b0e6b640bce3890897679adb14e8d075f328c7d29d",
"creationInfo": {
"creators": [
"Tool: vcpkg-9268e366206712e38102b28dbd1617697a99ff2e"
],
"created": "2022-07-23T08:23:20Z"
},
"relationships": [
{
"spdxElementId": "SPDXRef-port",
"relationshipType": "GENERATES",
"relatedSpdxElement": "SPDXRef-binary"
},
{
"spdxElementId": "SPDXRef-port",
"relationshipType": "CONTAINS",
"relatedSpdxElement": "SPDXRef-file-0"
},
{
"spdxElementId": "SPDXRef-port",
"relationshipType": "CONTAINS",
"relatedSpdxElement": "SPDXRef-file-1"
},
{
"spdxElementId": "SPDXRef-binary",
"relationshipType": "GENERATED_FROM",
"relatedSpdxElement": "SPDXRef-port"
},
{
"spdxElementId": "SPDXRef-file-0",
"relationshipType": "CONTAINED_BY",
"relatedSpdxElement": "SPDXRef-port"
},
{
"spdxElementId": "SPDXRef-file-1",
"relationshipType": "CONTAINED_BY",
"relatedSpdxElement": "SPDXRef-port"
},
{
"spdxElementId": "SPDXRef-file-1",
"relationshipType": "DEPENDENCY_MANIFEST_OF",
"relatedSpdxElement": "SPDXRef-port"
}
],
"packages": [
{
"name": "boost-intrusive",
"SPDXID": "SPDXRef-port",
"versionInfo": "1.79.0",
"downloadLocation": "NOASSERTION",
"homepage": "https://github.com/boostorg/intrusive",
"licenseConcluded": "BSL-1.0",
"licenseDeclared": "NOASSERTION",
"copyrightText": "NOASSERTION",
"description": "Boost intrusive module",
"comment": "This is the port (recipe) consumed by vcpkg."
},
{
"name": "boost-intrusive:x64-windows",
"SPDXID": "SPDXRef-binary",
"versionInfo": "531507e8bb60357a5f2420b0e6b640bce3890897679adb14e8d075f328c7d29d",
"downloadLocation": "NONE",
"licenseConcluded": "BSL-1.0",
"licenseDeclared": "NOASSERTION",
"copyrightText": "NOASSERTION",
"comment": "This is a binary package built by vcpkg."
},
{
"SPDXID": "SPDXRef-resource-1",
"name": "boostorg/intrusive",
"downloadLocation": "git+https://github.com/boostorg/intrusive@boost-1.79.0",
"licenseConcluded": "NOASSERTION",
"licenseDeclared": "NOASSERTION",
"copyrightText": "NOASSERTION",
"checksums": [
{
"algorithm": "SHA512",
"checksumValue": "4536cc104c2538d2c7a4e22882a27c47732b69ead76fd49d75592f582bc1873a0731753eb421ad67576467d731169333a1e95a39efb0e977512a58b407d59fb4"
}
]
}
],
"files": [
{
"fileName": "./portfile.cmake",
"SPDXID": "SPDXRef-file-0",
"checksums": [
{
"algorithm": "SHA256",
"checksumValue": "24cdc2e4b581124984c2cf273df6455e563642eb64beeeedb65e42006c8a8a92"
}
],
"licenseConcluded": "NOASSERTION",
"copyrightText": "NOASSERTION"
},
{
"fileName": "./vcpkg.json",
"SPDXID": "SPDXRef-file-1",
"checksums": [
{
"algorithm": "SHA256",
"checksumValue": "2befd9117d9f4fd1ee187cb66e97a1f9d919721734e6514c34d767d5176e5828"
}
],
"licenseConcluded": "NOASSERTION",
"copyrightText": "NOASSERTION"
}
]
}

Some files were not shown because too many files have changed in this diff Show More