Files
boost_intrusive/include/boost/intrusive/detail/utilities.hpp

303 lines
8.4 KiB
C++
Raw Normal View History

2007-05-04 21:22:02 +00:00
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2007
2007-05-04 21:22:02 +00:00
//
// 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_UTILITIES_HPP
#define BOOST_INTRUSIVE_DETAIL_UTILITIES_HPP
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/detail/pointer_to_other.hpp>
#include <boost/intrusive/detail/parent_from_member.hpp>
2007-06-23 13:01:38 +00:00
#include <boost/intrusive/detail/ebo_functor_holder.hpp>
2007-05-04 21:22:02 +00:00
#include <boost/intrusive/linking_policy.hpp>
2007-06-23 13:01:38 +00:00
#include <boost/intrusive/detail/mpl.hpp>
2007-05-04 21:22:02 +00:00
#include <cstddef>
2007-06-23 13:01:38 +00:00
#include <iterator>
2007-05-04 21:22:02 +00:00
namespace boost {
namespace intrusive {
namespace detail {
template<class SmartPtr>
struct smart_ptr_type
{
typedef typename SmartPtr::value_type value_type;
typedef value_type *pointer;
static pointer get (const SmartPtr &smartptr)
{ return smartptr.get();}
};
template<class T>
struct smart_ptr_type<T*>
{
typedef T value_type;
typedef value_type *pointer;
static pointer get (pointer ptr)
{ return ptr;}
};
//!Overload for smart pointers to avoid ADL problems with get_pointer
template<class Ptr>
inline typename smart_ptr_type<Ptr>::pointer
get_pointer(const Ptr &ptr)
{ return smart_ptr_type<Ptr>::get(ptr); }
//{ using boost::get_pointer; return get_pointer(ptr); }
2007-05-04 21:22:02 +00:00
//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)
{}
bool operator()(ConstReference t)const
{ return t_ == t; }
};
2007-06-23 13:01:38 +00:00
class null_disposer
2007-05-04 21:22:02 +00:00
{
public:
template <class Pointer>
void operator()(Pointer)
{}
};
template<bool ConstantSize, class SizeType>
struct size_holder
{
enum { constant_time_size = ConstantSize };
typedef SizeType size_type;
SizeType get_size() const
{ return size_; }
void set_size(SizeType size)
{ size_ = size; }
void decrement()
{ --size_; }
void increment()
{ ++size_; }
SizeType size_;
};
template<class SizeType>
struct size_holder<false, SizeType>
{
enum { constant_time_size = false };
typedef SizeType size_type;
size_type get_size() const
{ return 0; }
void set_size(size_type)
{}
void decrement()
{}
void increment()
{}
};
template<class T, class DerivationHookType, typename Tag>
2007-07-22 14:08:34 +00:00
struct derivation_hook_value_traits
2007-05-04 21:22:02 +00:00
{
public:
typedef typename DerivationHookType::node_traits node_traits;
typedef T value_type;
typedef typename node_traits::node_ptr node_ptr;
typedef typename node_traits::const_node_ptr const_node_ptr;
typedef typename boost::pointer_to_other<node_ptr, T>::type pointer;
typedef typename boost::pointer_to_other<node_ptr, const T>::type const_pointer;
typedef typename std::iterator_traits<pointer>::reference reference;
typedef typename std::iterator_traits<const_pointer>::reference const_reference;
enum { linking_policy = DerivationHookType::linking_policy };
static node_ptr to_node_ptr(reference value)
{ return static_cast<DerivationHookType &>(value).to_node_ptr(); }
static const_node_ptr to_node_ptr(const_reference value)
{ return static_cast<const DerivationHookType &>(value).to_node_ptr(); }
static pointer to_value_ptr(node_ptr n)
{
return static_cast<T*>(detail::get_pointer(DerivationHookType::to_hook_ptr(n)));
2007-05-04 21:22:02 +00:00
}
static const_pointer to_value_ptr(const_node_ptr n)
{
return static_cast<const T*>(detail::get_pointer(DerivationHookType::to_hook_ptr(n)));
2007-05-04 21:22:02 +00:00
}
};
template<class T, class MemberHookType, MemberHookType T::* P>
2007-07-22 14:08:34 +00:00
struct member_hook_value_traits
2007-05-04 21:22:02 +00:00
{
public:
typedef typename MemberHookType::node_traits node_traits;
typedef T value_type;
typedef typename node_traits::node_ptr node_ptr;
typedef typename node_traits::const_node_ptr const_node_ptr;
typedef typename boost::pointer_to_other<node_ptr, T>::type pointer;
typedef typename boost::pointer_to_other<node_ptr, const T>::type const_pointer;
2007-06-23 13:01:38 +00:00
typedef value_type & reference;
typedef const value_type & const_reference;
2007-05-04 21:22:02 +00:00
enum { linking_policy = MemberHookType::linking_policy };
public:
static node_ptr to_node_ptr(reference value)
{
MemberHookType* result = &(value.*P);
return result->to_node_ptr();
}
static const_node_ptr to_node_ptr(const_reference value)
{
const MemberHookType* result = &(value.*P);
return result->to_node_ptr();
}
static pointer to_value_ptr(node_ptr n)
{
2007-07-22 14:08:34 +00:00
return pointer
(
parent_from_member<value_type, MemberHookType>
(detail::get_pointer(MemberHookType::to_hook_ptr(n)), P)
);
2007-05-04 21:22:02 +00:00
}
static const_pointer to_value_ptr(const_node_ptr n)
{
2007-07-22 14:08:34 +00:00
return const_pointer
(
parent_from_member<value_type, MemberHookType>
(detail::get_pointer(MemberHookType::to_hook_ptr(n)), P)
);
2007-05-04 21:22:02 +00:00
}
};
template<class KeyValueCompare, class ValueTraits>
struct key_node_ptr_compare
2007-06-23 13:01:38 +00:00
: private detail::ebo_functor_holder<KeyValueCompare>
2007-05-04 21:22:02 +00:00
{
typedef typename ValueTraits::node_ptr node_ptr;
2007-06-23 13:01:38 +00:00
typedef detail::ebo_functor_holder<KeyValueCompare> base_t;
2007-05-04 21:22:02 +00:00
key_node_ptr_compare(KeyValueCompare kcomp)
: base_t(kcomp)
{}
template<class KeyType>
bool operator()(node_ptr node, const KeyType &key) const
{ return base_t::get()(*ValueTraits::to_value_ptr(node), key); }
template<class KeyType>
bool operator()(const KeyType &key, node_ptr node) const
{ return base_t::get()(key, *ValueTraits::to_value_ptr(node)); }
bool operator()(node_ptr node1, node_ptr node2) const
{
return base_t::get()
(*ValueTraits::to_value_ptr(node1), *ValueTraits::to_value_ptr(node2));
}
};
template<class F, class ValueTraits>
struct value_to_node_cloner
2007-06-23 13:01:38 +00:00
: private detail::ebo_functor_holder<F>
2007-05-04 21:22:02 +00:00
{
typedef typename ValueTraits::node_ptr node_ptr;
2007-06-23 13:01:38 +00:00
typedef detail::ebo_functor_holder<F> base_t;
2007-05-04 21:22:02 +00:00
value_to_node_cloner(F f)
: base_t(f)
{}
node_ptr operator()(node_ptr p)
{ return ValueTraits::to_node_ptr(*base_t::get()(*ValueTraits::to_value_ptr(p))); }
};
template<class F, class ValueTraits>
2007-06-23 13:01:38 +00:00
struct value_to_node_disposer
: private detail::ebo_functor_holder<F>
2007-05-04 21:22:02 +00:00
{
typedef typename ValueTraits::node_ptr node_ptr;
2007-06-23 13:01:38 +00:00
typedef detail::ebo_functor_holder<F> base_t;
value_to_node_disposer(F f)
2007-05-04 21:22:02 +00:00
: base_t(f)
{}
void operator()(node_ptr p)
{ base_t::get()(ValueTraits::to_value_ptr(p)); }
};
template <linking_policy Policy>
struct dispatcher
{};
template<class Container>
void destructor_impl(Container &cont, dispatcher<safe_link>)
2007-07-22 14:08:34 +00:00
{ (void)cont; BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT(!cont.is_linked()); }
2007-05-04 21:22:02 +00:00
template<class Container>
void destructor_impl(Container &cont, dispatcher<auto_unlink>)
{ cont.unlink(); }
template<class Container>
void destructor_impl(Container &, dispatcher<normal_link>)
2007-05-04 21:22:02 +00:00
{}
template<class Node, class MaybeClass>
struct node_plus_pred
2007-06-23 13:01:38 +00:00
: public ebo_functor_holder<MaybeClass>
2007-05-04 21:22:02 +00:00
, public Node
{
node_plus_pred()
{}
node_plus_pred(const Node &x, const MaybeClass &y)
2007-06-23 13:01:38 +00:00
: Node(x), ebo_functor_holder<MaybeClass>(y) {}
2007-05-04 21:22:02 +00:00
node_plus_pred(const MaybeClass &y)
2007-06-23 13:01:38 +00:00
: ebo_functor_holder<MaybeClass>(y) {}
2007-05-04 21:22:02 +00:00
Node &first()
{ return *this; }
const Node &first() const
{ return *this; }
MaybeClass &second()
2007-06-23 13:01:38 +00:00
{ return ebo_functor_holder<MaybeClass>::get(); }
2007-05-04 21:22:02 +00:00
const MaybeClass &second() const
2007-06-23 13:01:38 +00:00
{ return ebo_functor_holder<MaybeClass>::get(); }
2007-05-04 21:22:02 +00:00
static node_plus_pred *this_from_node(Node *n)
{ return static_cast<node_plus_pred*>(n); }
static node_plus_pred *this_from_node(const Node *n)
{ return static_cast<const node_plus_pred*>(n); }
};
} //namespace detail
} //namespace intrusive
} //namespace boost
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_DETAIL_UTILITIES_HPP