-> Use new Boost.Move meta utilities to avoid compilation errors in old compilers.

-> Implement equality operators as friend functions to make code clearer.
This commit is contained in:
Ion Gaztañaga
2015-04-12 12:56:04 +02:00
parent 1231ddd0e1
commit dd385e0ec5
22 changed files with 303 additions and 812 deletions

View File

@@ -404,33 +404,23 @@ class avltree_impl
//! @copydoc ::boost::intrusive::bstree::remove_node //! @copydoc ::boost::intrusive::bstree::remove_node
void remove_node(reference value); void remove_node(reference value);
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 #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
}; };
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
bool operator< (const avltree_impl<T, Options...> &x, const avltree_impl<T, Options...> &y);
template<class T, class ...Options>
bool operator==(const avltree_impl<T, Options...> &x, const avltree_impl<T, Options...> &y);
template<class T, class ...Options>
bool operator!= (const avltree_impl<T, Options...> &x, const avltree_impl<T, Options...> &y);
template<class T, class ...Options>
bool operator>(const avltree_impl<T, Options...> &x, const avltree_impl<T, Options...> &y);
template<class T, class ...Options>
bool operator<=(const avltree_impl<T, Options...> &x, const avltree_impl<T, Options...> &y);
template<class T, class ...Options>
bool operator>=(const avltree_impl<T, Options...> &x, const avltree_impl<T, Options...> &y);
template<class T, class ...Options>
void swap(avltree_impl<T, Options...> &x, avltree_impl<T, Options...> &y);
#endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
//! Helper metafunction to define a \c avltree that yields to the same type when the //! Helper metafunction to define a \c avltree that yields to the same type when the
//! same options (either explicitly or implicitly) are used. //! same options (either explicitly or implicitly) are used.

View File

@@ -1366,11 +1366,9 @@ class bstree_impl
//! <b>Note</b>: Invalidates the iterators (but not the references) //! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called. //! to the erased elements. No destructors are called.
template<class KeyType, class KeyValueCompare> template<class KeyType, class KeyValueCompare>
size_type erase(const KeyType& key, KeyValueCompare comp BOOST_INTRUSIVE_DOC1ST(size_type
/// @cond , typename detail::disable_if_convertible<KeyValueCompare BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I size_type>::type)
, typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0 erase(const KeyType& key, KeyValueCompare comp)
/// @endcond
)
{ {
std::pair<iterator,iterator> p = this->equal_range(key, comp); std::pair<iterator,iterator> p = this->equal_range(key, comp);
size_type n; size_type n;
@@ -1398,12 +1396,6 @@ class bstree_impl
return ret; return ret;
} }
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class Disposer>
iterator erase_and_dispose(iterator i, Disposer disposer)
{ return this->erase_and_dispose(const_iterator(i), disposer); }
#endif
//! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases all the elements with the given value. //! <b>Effects</b>: Erases all the elements with the given value.
@@ -1457,11 +1449,9 @@ class bstree_impl
//! <b>Note</b>: Invalidates the iterators //! <b>Note</b>: Invalidates the iterators
//! to the erased elements. //! to the erased elements.
template<class KeyType, class KeyValueCompare, class Disposer> template<class KeyType, class KeyValueCompare, class Disposer>
size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer BOOST_INTRUSIVE_DOC1ST(size_type
/// @cond , typename detail::disable_if_convertible<KeyValueCompare BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I size_type>::type)
, typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0 erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer)
/// @endcond
)
{ {
std::pair<iterator,iterator> p = this->equal_range(key, comp); std::pair<iterator,iterator> p = this->equal_range(key, comp);
size_type n; size_type n;
@@ -1956,6 +1946,32 @@ class bstree_impl
check(detail::empty_node_checker<ValueTraits>()); check(detail::empty_node_checker<ValueTraits>());
} }
friend bool operator==(const bstree_impl &x, const bstree_impl &y)
{
if(constant_time_size && x.size() != y.size()){
return false;
}
return boost::intrusive::algo_equal(x.cbegin(), x.cend(), y.cbegin(), y.cend());
}
friend bool operator!=(const bstree_impl &x, const bstree_impl &y)
{ return !(x == y); }
friend bool operator<(const bstree_impl &x, const bstree_impl &y)
{ return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
friend bool operator>(const bstree_impl &x, const bstree_impl &y)
{ return y < x; }
friend bool operator<=(const bstree_impl &x, const bstree_impl &y)
{ return !(x > y); }
friend bool operator>=(const bstree_impl &x, const bstree_impl &y)
{ return !(x < y); }
friend void swap(bstree_impl &x, bstree_impl &y)
{ x.swap(y); }
/// @cond /// @cond
private: private:
template<class Disposer> template<class Disposer>
@@ -1975,111 +1991,6 @@ class bstree_impl
/// @endcond /// @endcond
}; };
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
template<class ValueTraits, class VoidKeyComp, class SizeType, bool ConstantTimeSize, algo_types AlgoType, typename HeaderHolder>
#endif
inline bool operator<
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
(const bstree_impl<T, Options...> &x, const bstree_impl<T, Options...> &y)
#else
( const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &x
, const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &y)
#endif
{ return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
template<class ValueTraits, class VoidKeyComp, class SizeType, bool ConstantTimeSize, algo_types AlgoType, typename HeaderHolder>
#endif
bool operator==
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
(const bstree_impl<T, Options...> &x, const bstree_impl<T, Options...> &y)
#else
( const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &x
, const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &y)
#endif
{
typedef bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> tree_type;
if(tree_type::constant_time_size && x.size() != y.size()){
return false;
}
return boost::intrusive::algo_equal(x.cbegin(), x.cend(), y.cbegin(), y.cend());
}
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
template<class ValueTraits, class VoidKeyComp, class SizeType, bool ConstantTimeSize, algo_types AlgoType, typename HeaderHolder>
#endif
inline bool operator!=
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
(const bstree_impl<T, Options...> &x, const bstree_impl<T, Options...> &y)
#else
( const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &x
, const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &y)
#endif
{ return !(x == y); }
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
template<class ValueTraits, class VoidKeyComp, class SizeType, bool ConstantTimeSize, algo_types AlgoType, typename HeaderHolder>
#endif
inline bool operator>
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
(const bstree_impl<T, Options...> &x, const bstree_impl<T, Options...> &y)
#else
( const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &x
, const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &y)
#endif
{ return y < x; }
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
template<class ValueTraits, class VoidKeyComp, class SizeType, bool ConstantTimeSize, algo_types AlgoType, typename HeaderHolder>
#endif
inline bool operator<=
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
(const bstree_impl<T, Options...> &x, const bstree_impl<T, Options...> &y)
#else
( const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &x
, const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &y)
#endif
{ return !(y < x); }
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
template<class ValueTraits, class VoidKeyComp, class SizeType, bool ConstantTimeSize, algo_types AlgoType, typename HeaderHolder>
#endif
inline bool operator>=
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
(const bstree_impl<T, Options...> &x, const bstree_impl<T, Options...> &y)
#else
( const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &x
, const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &y)
#endif
{ return !(x < y); }
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
template<class ValueTraits, class VoidKeyComp, class SizeType, bool ConstantTimeSize, algo_types AlgoType, typename HeaderHolder>
#endif
inline void swap
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
(bstree_impl<T, Options...> &x, bstree_impl<T, Options...> &y)
#else
( bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &x
, bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &y)
#endif
{ x.swap(y); }
//! Helper metafunction to define a \c bstree that yields to the same type when the //! Helper metafunction to define a \c bstree that yields to the same type when the
//! same options (either explicitly or implicitly) are used. //! same options (either explicitly or implicitly) are used.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)

View File

@@ -37,10 +37,6 @@ namespace intrusive {
template <class NodePtr> template <class NodePtr>
struct insert_commit_data_t struct insert_commit_data_t
{ {
insert_commit_data_t()
: link_left(false)
, node()
{}
bool link_left; bool link_left;
NodePtr node; NodePtr node;
}; };

View File

@@ -107,9 +107,9 @@ BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(internal_base_hook, hooktags::is_ba
template <class T> template <class T>
struct internal_member_value_traits struct internal_member_value_traits
{ {
template <class U> static one test(...); template <class U> static yes_type test(...);
template <class U> static two test(typename U::member_value_traits* = 0); template <class U> static no_type test(typename U::member_value_traits* = 0);
static const bool value = sizeof(test<T>(0)) == sizeof(two); static const bool value = sizeof(test<T>(0)) == sizeof(no_type);
}; };
template<class SupposedValueTraits, class T, bool = is_default_hook_tag<SupposedValueTraits>::value> template<class SupposedValueTraits, class T, bool = is_default_hook_tag<SupposedValueTraits>::value>

View File

@@ -113,9 +113,9 @@ struct bucket_traits_impl
template <class NodeTraits> template <class NodeTraits>
struct hash_reduced_slist_node_traits struct hash_reduced_slist_node_traits
{ {
template <class U> static detail::one test(...); template <class U> static detail::no_type test(...);
template <class U> static detail::two test(typename U::reduced_slist_node_traits* = 0); template <class U> static detail::yes_type test(typename U::reduced_slist_node_traits*);
static const bool value = sizeof(test<NodeTraits>(0)) == sizeof(detail::two); static const bool value = sizeof(test<NodeTraits>(0)) == sizeof(detail::yes_type);
}; };
template <class NodeTraits> template <class NodeTraits>

View File

@@ -32,7 +32,7 @@ namespace detail {
template<class ValueTraits> template<class ValueTraits>
struct is_stateful_value_traits struct is_stateful_value_traits
{ {
static const bool value = !detail::is_empty_class<ValueTraits>::value; static const bool value = !detail::is_empty<ValueTraits>::value;
}; };
}}} }}}

View File

@@ -51,12 +51,13 @@ struct key_nodeptr_comp
//key_forward //key_forward
template<class T> template<class T>
const value_type & key_forward typename enable_if<is_node_ptr<T>, const value_type &>::type
(const T &node, typename enable_if_c<is_node_ptr<T>::value>::type * = 0) const key_forward(const T &node) const
{ return *traits_->to_value_ptr(node); } { return *traits_->to_value_ptr(node); }
template<class T> template<class T>
const T & key_forward(const T &key, typename enable_if_c<!is_node_ptr<T>::value>::type* = 0) const typename disable_if<is_node_ptr<T>, const T &>::type
const key_forward(const T &key) const
{ return key; } { return key; }
//operator() 1 arg //operator() 1 arg

View File

@@ -127,7 +127,7 @@ namespace detail {
{ return (n >> 1) + ((n & 1u) & (n != 1)); } { return (n >> 1) + ((n & 1u) & (n != 1)); }
template<std::size_t N> template<std::size_t N>
inline std::size_t floor_log2 (std::size_t x, integer<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 std::size_t Bits = N;
const bool Size_t_Bits_Power_2= !(Bits & (Bits-1)); const bool Size_t_Bits_Power_2= !(Bits & (Bits-1));
@@ -156,7 +156,7 @@ namespace detail {
//http://stackoverflow.com/questions/11376288/fast-computing-of-log2-for-64-bit-integers //http://stackoverflow.com/questions/11376288/fast-computing-of-log2-for-64-bit-integers
//Thanks to Desmond Hume //Thanks to Desmond Hume
inline std::size_t floor_log2 (std::size_t v, integer<std::size_t, 32>) inline std::size_t floor_log2 (std::size_t v, integral_constant<std::size_t, 32>)
{ {
static const int MultiplyDeBruijnBitPosition[32] = static const int MultiplyDeBruijnBitPosition[32] =
{ {
@@ -173,7 +173,7 @@ namespace detail {
return MultiplyDeBruijnBitPosition[(std::size_t)(v * 0x07C4ACDDU) >> 27]; return MultiplyDeBruijnBitPosition[(std::size_t)(v * 0x07C4ACDDU) >> 27];
} }
inline std::size_t floor_log2 (std::size_t v, integer<std::size_t, 64>) inline std::size_t floor_log2 (std::size_t v, integral_constant<std::size_t, 64>)
{ {
static const std::size_t MultiplyDeBruijnBitPosition[64] = { static const std::size_t MultiplyDeBruijnBitPosition[64] = {
63, 0, 58, 1, 59, 47, 53, 2, 63, 0, 58, 1, 59, 47, 53, 2,
@@ -198,7 +198,7 @@ namespace detail {
inline std::size_t floor_log2 (std::size_t x) inline std::size_t floor_log2 (std::size_t x)
{ {
const std::size_t Bits = sizeof(std::size_t)*CHAR_BIT; const std::size_t Bits = sizeof(std::size_t)*CHAR_BIT;
return floor_log2(x, integer<std::size_t, Bits>()); return floor_log2(x, integral_constant<std::size_t, Bits>());
} }
#endif #endif

View File

@@ -23,260 +23,47 @@
#endif #endif
#include <boost/intrusive/detail/config_begin.hpp> #include <boost/intrusive/detail/config_begin.hpp>
#include <boost/move/detail/type_traits.hpp>
#include <cstddef> #include <cstddef>
namespace boost { namespace boost {
namespace intrusive { namespace intrusive {
namespace detail { namespace detail {
template <typename T, typename U> using boost::move_detail::is_same;
struct is_same using boost::move_detail::add_const;
{ using boost::move_detail::remove_const;
static const bool value = false; using boost::move_detail::remove_cv;
}; using boost::move_detail::remove_reference;
using boost::move_detail::add_reference;
template <typename T> using boost::move_detail::remove_pointer;
struct is_same<T, T> using boost::move_detail::add_pointer;
{ using boost::move_detail::true_type;
static const bool value = true; using boost::move_detail::false_type;
}; using boost::move_detail::enable_if_c;
using boost::move_detail::enable_if;
template<typename T> using boost::move_detail::disable_if_c;
struct add_const using boost::move_detail::disable_if;
{ typedef const T type; }; using boost::move_detail::is_convertible;
using boost::move_detail::if_c;
template<typename T> using boost::move_detail::if_;
struct remove_const using boost::move_detail::identity;
{ typedef T type; }; using boost::move_detail::alignment_of;
using boost::move_detail::is_empty;
template<typename T> using boost::move_detail::addressof;
struct remove_const<const T> using boost::move_detail::integral_constant;
{ typedef T type; }; using boost::move_detail::enable_if_convertible;
using boost::move_detail::disable_if_convertible;
template<typename T> using boost::move_detail::bool_;
struct remove_cv using boost::move_detail::true_;
{ typedef T type; }; using boost::move_detail::false_;
using boost::move_detail::yes_type;
template<typename T> using boost::move_detail::no_type;
struct remove_cv<const T> using boost::move_detail::apply;
{ typedef T type; }; using boost::move_detail::eval_if_c;
using boost::move_detail::eval_if;
template<typename T> using boost::move_detail::unvoid_ref;
struct remove_cv<const volatile T> using boost::move_detail::add_const_if_c;
{ typedef T type; };
template<typename T>
struct remove_cv<volatile T>
{ typedef T type; };
template<class T>
struct remove_reference
{
typedef T type;
};
template<class T>
struct remove_reference<T&>
{
typedef T type;
};
template<class T>
struct remove_pointer
{
typedef T type;
};
template<class T>
struct remove_pointer<T*>
{
typedef T type;
};
template<class T>
struct add_pointer
{
typedef T *type;
};
typedef char one;
struct two {one _[2];};
template< bool C_ >
struct bool_
{
static const bool value = C_;
};
template< class Integer, Integer Value >
struct integer
{
static const Integer value = Value;
};
typedef bool_<true> true_;
typedef bool_<false> false_;
typedef true_ true_type;
typedef false_ false_type;
typedef char yes_type;
struct no_type
{
char padding[8];
};
template <bool B, class T = void>
struct enable_if_c {
typedef T type;
};
template <class T>
struct enable_if_c<false, T> {};
template <class Cond, class T = void>
struct enable_if : public enable_if_c<Cond::value, T>{};
template<class F, class Param>
struct apply
{
typedef typename F::template apply<Param>::type type;
};
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
template <class T, class U>
struct is_convertible
{
static const bool value = __is_convertible_to(T, U);
};
#else
template <class T, class U>
class is_convertible
{
typedef char true_t;
class false_t { char dummy[2]; };
//use any_conversion as first parameter since in MSVC
//overaligned types can't go through ellipsis
static false_t dispatch(...);
static true_t dispatch(U);
static typename remove_reference<T>::type &trigger();
public:
static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t);
};
#endif
template<
bool C
, typename T1
, typename T2
>
struct if_c
{
typedef T1 type;
};
template<
typename T1
, typename T2
>
struct if_c<false,T1,T2>
{
typedef T2 type;
};
template<
typename C
, typename T1
, typename T2
>
struct if_
{
typedef typename if_c<0 != C::value, T1, T2>::type type;
};
template<
bool C
, typename F1
, typename F2
>
struct eval_if_c
: if_c<C,F1,F2>::type
{};
template<
typename C
, typename T1
, typename T2
>
struct eval_if
: if_<C,T1,T2>::type
{};
// identity is an extension: it is not part of the standard.
template <class T>
struct identity
{
typedef T type;
};
template<class T, bool Add>
struct add_const_if_c
{
typedef typename if_c
< Add
, typename add_const<T>::type
, T
>::type type;
};
//boost::alignment_of yields to 10K lines of preprocessed code, so we
//need an alternative
template <typename T> struct alignment_of;
template <typename T>
struct alignment_of_hack
{
char c;
T t;
alignment_of_hack();
};
template <unsigned A, unsigned S>
struct alignment_logic
{
static const std::size_t value = A < S ? A : S;
};
template< typename T >
struct alignment_of
{
static const std::size_t value = alignment_logic
< sizeof(alignment_of_hack<T>) - sizeof(T)
, sizeof(T)
>::value;
};
template<class Class>
class is_empty_class
{
template <typename T>
struct empty_helper_t1 : public T
{
empty_helper_t1();
int i[256];
};
struct empty_helper_t2
{ int i[256]; };
public:
static const bool value = sizeof(empty_helper_t1<Class>) == sizeof(empty_helper_t2);
};
template<std::size_t S> template<std::size_t S>
struct ls_zeros struct ls_zeros
@@ -296,10 +83,6 @@ struct ls_zeros<1>
static const std::size_t value = 0; static const std::size_t value = 0;
}; };
template <typename T> struct unvoid_ref { typedef T &type; };
template <> struct unvoid_ref<void> { struct type_impl { }; typedef type_impl & type; };
template <> struct unvoid_ref<const void> { struct type_impl { }; typedef type_impl & type; };
// Infrastructure for providing a default type for T::TNAME if absent. // Infrastructure for providing a default type for T::TNAME if absent.
#define BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(TNAME) \ #define BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(TNAME) \
template <typename T, typename DefaultType> \ template <typename T, typename DefaultType> \
@@ -360,8 +143,8 @@ template <class T>\
struct TRAITS_PREFIX##_bool\ struct TRAITS_PREFIX##_bool\
{\ {\
template<bool Add>\ template<bool Add>\
struct two_or_three {one _[2 + Add];};\ struct two_or_three {yes_type _[2 + Add];};\
template <class U> static one test(...);\ template <class U> static yes_type test(...);\
template <class U> static two_or_three<U::TYPEDEF_TO_FIND> test (int);\ template <class U> static two_or_three<U::TYPEDEF_TO_FIND> test (int);\
static const std::size_t value = sizeof(test<T>(0));\ static const std::size_t value = sizeof(test<T>(0));\
};\ };\
@@ -369,7 +152,7 @@ struct TRAITS_PREFIX##_bool\
template <class T>\ template <class T>\
struct TRAITS_PREFIX##_bool_is_true\ struct TRAITS_PREFIX##_bool_is_true\
{\ {\
static const bool value = TRAITS_PREFIX##_bool<T>::value > sizeof(one)*2;\ static const bool value = TRAITS_PREFIX##_bool<T>::value > sizeof(yes_type)*2;\
};\ };\
// //
@@ -413,18 +196,6 @@ struct TRAITS_NAME \
{};\ {};\
// //
template <typename T>
inline T* addressof(T& obj)
{
return static_cast<T*>
(static_cast<void*>
(const_cast<char*>
(&reinterpret_cast<const char&>(obj))
)
);
}
} //namespace detail } //namespace detail
} //namespace intrusive } //namespace intrusive
} //namespace boost } //namespace boost

View File

@@ -23,6 +23,7 @@
#include <boost/intrusive/detail/config_begin.hpp> #include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/detail/iterator.hpp> #include <boost/intrusive/detail/iterator.hpp>
#include <boost/intrusive/detail/mpl.hpp>
namespace boost { namespace boost {
namespace intrusive { namespace intrusive {
@@ -49,10 +50,17 @@ class reverse_iterator
{} {}
template<class OtherIt> template<class OtherIt>
reverse_iterator(const reverse_iterator<OtherIt>& r) reverse_iterator( const reverse_iterator<OtherIt>& r
, typename boost::intrusive::detail::enable_if_convertible<OtherIt, It>::type* =0
)
: m_current(r.base()) : m_current(r.base())
{} {}
template<class OtherIt>
typename boost::intrusive::detail::enable_if_convertible<OtherIt, It, reverse_iterator &>::type
operator=( const reverse_iterator<OtherIt>& r)
{ m_current = r.base(); return *this; }
It base() const It base() const
{ return m_current; } { return m_current; }
@@ -109,22 +117,17 @@ class reverse_iterator
reverse_iterator& operator+=(difference_type off) reverse_iterator& operator+=(difference_type off)
{ m_current -= off; return *this; } { m_current -= off; return *this; }
friend reverse_iterator operator+(const reverse_iterator & l, difference_type off) friend reverse_iterator operator+(reverse_iterator l, difference_type off)
{ { l.m_current -= off; return l; }
reverse_iterator tmp(l.m_current);
tmp.m_current -= off; friend reverse_iterator operator+(difference_type off, reverse_iterator r)
return tmp; { return (r += off); }
}
reverse_iterator& operator-=(difference_type off) reverse_iterator& operator-=(difference_type off)
{ m_current += off; return *this; } { m_current += off; return *this; }
friend reverse_iterator operator-(const reverse_iterator & l, difference_type off) friend reverse_iterator operator-(reverse_iterator l, difference_type off)
{ { l.m_current += off; return l; }
reverse_iterator tmp(l.m_current);
tmp.m_current += off;
return tmp;
}
friend difference_type operator-(const reverse_iterator& l, const reverse_iterator& r) friend difference_type operator-(const reverse_iterator& l, const reverse_iterator& r)
{ return r.m_current - l.m_current; } { return r.m_current - l.m_current; }

View File

@@ -40,13 +40,11 @@ namespace intrusive {
template<class ValueTraits, bool IsConst> template<class ValueTraits, bool IsConst>
class tree_iterator class tree_iterator
{ {
protected: private:
typedef iiterator< ValueTraits, IsConst typedef iiterator< ValueTraits, IsConst
, std::bidirectional_iterator_tag> types_t; , std::bidirectional_iterator_tag> types_t;
typedef typename types_t::value_traits value_traits;
typedef ValueTraits value_traits;
typedef typename types_t::node_traits node_traits; typedef typename types_t::node_traits node_traits;
typedef typename types_t::node node; typedef typename types_t::node node;
typedef typename types_t::node_ptr node_ptr; typedef typename types_t::node_ptr node_ptr;
typedef typename types_t::const_value_traits_ptr const_value_traits_ptr; typedef typename types_t::const_value_traits_ptr const_value_traits_ptr;

View File

@@ -172,8 +172,8 @@ template <class T>
struct store_hash_bool struct store_hash_bool
{ {
template<bool Add> template<bool Add>
struct two_or_three {one _[2 + Add];}; struct two_or_three {yes_type _[2 + Add];};
template <class U> static one test(...); template <class U> static yes_type test(...);
template <class U> static two_or_three<U::store_hash> test (int); template <class U> static two_or_three<U::store_hash> test (int);
static const std::size_t value = sizeof(test<T>(0)); static const std::size_t value = sizeof(test<T>(0));
}; };
@@ -181,15 +181,15 @@ struct store_hash_bool
template <class T> template <class T>
struct store_hash_is_true struct store_hash_is_true
{ {
static const bool value = store_hash_bool<T>::value > sizeof(one)*2; static const bool value = store_hash_bool<T>::value > sizeof(yes_type)*2;
}; };
template <class T> template <class T>
struct optimize_multikey_bool struct optimize_multikey_bool
{ {
template<bool Add> template<bool Add>
struct two_or_three {one _[2 + Add];}; struct two_or_three {yes_type _[2 + Add];};
template <class U> static one test(...); template <class U> static yes_type test(...);
template <class U> static two_or_three<U::optimize_multikey> test (int); template <class U> static two_or_three<U::optimize_multikey> test (int);
static const std::size_t value = sizeof(test<T>(0)); static const std::size_t value = sizeof(test<T>(0));
}; };
@@ -197,7 +197,7 @@ struct optimize_multikey_bool
template <class T> template <class T>
struct optimize_multikey_is_true struct optimize_multikey_is_true
{ {
static const bool value = optimize_multikey_bool<T>::value > sizeof(one)*2; static const bool value = optimize_multikey_bool<T>::value > sizeof(yes_type)*2;
}; };
struct insert_commit_data_impl struct insert_commit_data_impl
@@ -1887,11 +1887,9 @@ class hashtable_impl
//! <b>Note</b>: Invalidates the iterators //! <b>Note</b>: Invalidates the iterators
//! to the erased elements. //! to the erased elements.
template<class Disposer> template<class Disposer>
void erase_and_dispose(const_iterator i, Disposer disposer BOOST_INTRUSIVE_DOC1ST(void
/// @cond , typename detail::disable_if_convertible<Disposer BOOST_INTRUSIVE_I const_iterator>::type)
, typename detail::enable_if_c<!detail::is_convertible<Disposer, const_iterator>::value >::type * = 0 erase_and_dispose(const_iterator i, Disposer disposer)
/// @endcond
)
{ {
this->priv_erase(i, disposer, optimize_multikey_t()); this->priv_erase(i, disposer, optimize_multikey_t());
this->priv_size_traits().decrement(); this->priv_size_traits().decrement();
@@ -2774,6 +2772,37 @@ class hashtable_impl
bound -= (bound != primes); bound -= (bound != primes);
return size_type(*bound); return size_type(*bound);
} }
friend bool operator==(const hashtable_impl &x, const hashtable_impl &y)
{
if(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(*ix);
if (iy == ey || !(*ix == *iy))
return false;
}
return true;
}
friend bool operator!=(const hashtable_impl &x, const hashtable_impl &y)
{ return !(x == y); }
friend bool operator<(const hashtable_impl &x, const hashtable_impl &y)
{ return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
friend bool operator>(const hashtable_impl &x, const hashtable_impl &y)
{ return y < x; }
friend bool operator<=(const hashtable_impl &x, const hashtable_impl &y)
{ return !(y < x); }
friend bool operator>=(const hashtable_impl &x, const hashtable_impl &y)
{ return !(x < y); }
/// @cond /// @cond
void check() const {} void check() const {}
private: private:

View File

@@ -1320,6 +1320,32 @@ class list_impl
BOOST_INTRUSIVE_INVARIANT_ASSERT(this->priv_size_traits().get_size() == node_count); BOOST_INTRUSIVE_INVARIANT_ASSERT(this->priv_size_traits().get_size() == node_count);
} }
friend bool operator==(const list_impl &x, const list_impl &y)
{
if(constant_time_size && x.size() != y.size()){
return false;
}
return ::boost::intrusive::algo_equal(x.cbegin(), x.cend(), y.cbegin(), y.cend());
}
friend bool operator!=(const list_impl &x, const list_impl &y)
{ return !(x == y); }
friend bool operator<(const list_impl &x, const list_impl &y)
{ return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
friend bool operator>(const list_impl &x, const list_impl &y)
{ return y < x; }
friend bool operator<=(const list_impl &x, const list_impl &y)
{ return !(y < x); }
friend bool operator>=(const list_impl &x, const list_impl &y)
{ return !(x < y); }
friend void swap(list_impl &x, list_impl &y)
{ x.swap(y); }
/// @cond /// @cond
private: private:
@@ -1338,103 +1364,6 @@ class list_impl
/// @endcond /// @endcond
}; };
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
template <class ValueTraits, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
#endif
inline bool operator<
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
(const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
#else
(const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &y)
#endif
{ return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
template <class ValueTraits, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
#endif
bool operator==
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
(const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
#else
(const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &y)
#endif
{
typedef list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> list_type;
const bool C = list_type::constant_time_size;
if(C && x.size() != y.size()){
return false;
}
return ::boost::intrusive::algo_equal(x.cbegin(), x.cend(), y.cbegin(), y.cend());
}
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
template <class ValueTraits, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
#endif
inline bool operator!=
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
(const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
#else
(const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &y)
#endif
{ return !(x == y); }
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
template <class ValueTraits, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
#endif
inline bool operator>
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
(const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
#else
(const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &y)
#endif
{ return y < x; }
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
template <class ValueTraits, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
#endif
inline bool operator<=
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
(const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
#else
(const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &y)
#endif
{ return !(y < x); }
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
template <class ValueTraits, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
#endif
inline bool operator>=
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
(const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
#else
(const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &y)
#endif
{ return !(x < y); }
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
template <class ValueTraits, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
#endif
inline void swap
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
(list_impl<T, Options...> &x, list_impl<T, Options...> &y)
#else
(list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &y)
#endif
{ x.swap(y); }
//! Helper metafunction to define a \c list that yields to the same type when the //! Helper metafunction to define a \c list that yields to the same type when the
//! same options (either explicitly or implicitly) are used. //! same options (either explicitly or implicitly) are used.

View File

@@ -406,33 +406,23 @@ class rbtree_impl
//! @copydoc ::boost::intrusive::bstree::remove_node //! @copydoc ::boost::intrusive::bstree::remove_node
void remove_node(reference value); void remove_node(reference value);
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 #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
}; };
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
bool operator< (const rbtree_impl<T, Options...> &x, const rbtree_impl<T, Options...> &y);
template<class T, class ...Options>
bool operator==(const rbtree_impl<T, Options...> &x, const rbtree_impl<T, Options...> &y);
template<class T, class ...Options>
bool operator!= (const rbtree_impl<T, Options...> &x, const rbtree_impl<T, Options...> &y);
template<class T, class ...Options>
bool operator>(const rbtree_impl<T, Options...> &x, const rbtree_impl<T, Options...> &y);
template<class T, class ...Options>
bool operator<=(const rbtree_impl<T, Options...> &x, const rbtree_impl<T, Options...> &y);
template<class T, class ...Options>
bool operator>=(const rbtree_impl<T, Options...> &x, const rbtree_impl<T, Options...> &y);
template<class T, class ...Options>
void swap(rbtree_impl<T, Options...> &x, rbtree_impl<T, Options...> &y);
#endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
//! Helper metafunction to define a \c rbtree that yields to the same type when the //! Helper metafunction to define a \c rbtree that yields to the same type when the
//! same options (either explicitly or implicitly) are used. //! same options (either explicitly or implicitly) are used.

View File

@@ -610,11 +610,9 @@ class sgtree_impl
//! @copydoc ::boost::intrusive::bstree::erase(const KeyType&,KeyValueCompare) //! @copydoc ::boost::intrusive::bstree::erase(const KeyType&,KeyValueCompare)
template<class KeyType, class KeyValueCompare> template<class KeyType, class KeyValueCompare>
size_type erase(const KeyType& key, KeyValueCompare comp BOOST_INTRUSIVE_DOC1ST(size_type
/// @cond , typename detail::disable_if_convertible<KeyValueCompare BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I size_type>::type)
, typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0 erase(const KeyType& key, KeyValueCompare comp)
/// @endcond
)
{ {
std::pair<iterator,iterator> p = this->equal_range(key, comp); std::pair<iterator,iterator> p = this->equal_range(key, comp);
size_type n; size_type n;
@@ -655,11 +653,9 @@ class sgtree_impl
//! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer) //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer)
template<class KeyType, class KeyValueCompare, class Disposer> template<class KeyType, class KeyValueCompare, class Disposer>
size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer BOOST_INTRUSIVE_DOC1ST(size_type
/// @cond , typename detail::disable_if_convertible<KeyValueCompare BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I size_type>::type)
, typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0 erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer)
/// @endcond
)
{ {
std::pair<iterator,iterator> p = this->equal_range(key, comp); std::pair<iterator,iterator> p = this->equal_range(key, comp);
size_type n; size_type n;
@@ -796,6 +792,20 @@ class sgtree_impl
//! @copydoc ::boost::intrusive::bstree::rebalance_subtree //! @copydoc ::boost::intrusive::bstree::rebalance_subtree
iterator rebalance_subtree(iterator root); iterator rebalance_subtree(iterator root);
friend bool operator< (const sgtree_impl &x, const sgtree_impl &y);
friend bool operator==(const sgtree_impl &x, const sgtree_impl &y);
friend bool operator!= (const sgtree_impl &x, const sgtree_impl &y);
friend bool operator>(const sgtree_impl &x, const sgtree_impl &y);
friend bool operator<=(const sgtree_impl &x, const sgtree_impl &y);
friend bool operator>=(const sgtree_impl &x, const sgtree_impl &y);
friend void swap(sgtree_impl &x, sgtree_impl &y);
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! <b>Returns</b>: The balance factor (alpha) used in this tree //! <b>Returns</b>: The balance factor (alpha) used in this tree
@@ -850,30 +860,6 @@ class sgtree_impl
/// @endcond /// @endcond
}; };
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
bool operator< (const sgtree_impl<T, Options...> &x, const sgtree_impl<T, Options...> &y);
template<class T, class ...Options>
bool operator==(const sgtree_impl<T, Options...> &x, const sgtree_impl<T, Options...> &y);
template<class T, class ...Options>
bool operator!= (const sgtree_impl<T, Options...> &x, const sgtree_impl<T, Options...> &y);
template<class T, class ...Options>
bool operator>(const sgtree_impl<T, Options...> &x, const sgtree_impl<T, Options...> &y);
template<class T, class ...Options>
bool operator<=(const sgtree_impl<T, Options...> &x, const sgtree_impl<T, Options...> &y);
template<class T, class ...Options>
bool operator>=(const sgtree_impl<T, Options...> &x, const sgtree_impl<T, Options...> &y);
template<class T, class ...Options>
void swap(sgtree_impl<T, Options...> &x, sgtree_impl<T, Options...> &y);
#endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
//! Helper metafunction to define a \c sgtree that yields to the same type when the //! Helper metafunction to define a \c sgtree that yields to the same type when the
//! same options (either explicitly or implicitly) are used. //! same options (either explicitly or implicitly) are used.

View File

@@ -1905,6 +1905,33 @@ class slist_impl
BOOST_INTRUSIVE_INVARIANT_ASSERT(this->priv_size_traits().get_size() == node_count); BOOST_INTRUSIVE_INVARIANT_ASSERT(this->priv_size_traits().get_size() == node_count);
} }
friend bool operator==(const slist_impl &x, const slist_impl &y)
{
if(constant_time_size && x.size() != y.size()){
return false;
}
return ::boost::intrusive::algo_equal(x.cbegin(), x.cend(), y.cbegin(), y.cend());
}
friend bool operator!=(const slist_impl &x, const slist_impl &y)
{ return !(x == y); }
friend bool operator<(const slist_impl &x, const slist_impl &y)
{ return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
friend bool operator>(const slist_impl &x, const slist_impl &y)
{ return y < x; }
friend bool operator<=(const slist_impl &x, const slist_impl &y)
{ return !(y < x); }
friend bool operator>=(const slist_impl &x, const slist_impl &y)
{ return !(x < y); }
friend void swap(slist_impl &x, slist_impl &y)
{ x.swap(y); }
private: private:
void priv_splice_after(const node_ptr & prev_pos_n, slist_impl &x, const node_ptr & before_f_n, const node_ptr & before_l_n) void priv_splice_after(const node_ptr & prev_pos_n, slist_impl &x, const node_ptr & before_f_n, const node_ptr & before_l_n)
{ {
@@ -2044,111 +2071,6 @@ class slist_impl
} }
}; };
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
template<class ValueTraits, class SizeType, std::size_t BoolFlags, typename HeaderHolder>
#endif
inline bool operator<
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
(const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
#else
( const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &x
, const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &y)
#endif
{ return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
template<class ValueTraits, class SizeType, std::size_t BoolFlags, typename HeaderHolder>
#endif
bool operator==
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
(const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
#else
( const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &x
, const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &y)
#endif
{
typedef slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> slist_type;
const bool C = slist_type::constant_time_size;
if(C && x.size() != y.size()){
return false;
}
return ::boost::intrusive::algo_equal(x.cbegin(), x.cend(), y.cbegin(), y.cend());
}
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
template<class ValueTraits, class SizeType, std::size_t BoolFlags, typename HeaderHolder>
#endif
inline bool operator!=
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
(const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
#else
( const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &x
, const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &y)
#endif
{ return !(x == y); }
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
template<class ValueTraits, class SizeType, std::size_t BoolFlags, typename HeaderHolder>
#endif
inline bool operator>
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
(const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
#else
( const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &x
, const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &y)
#endif
{ return y < x; }
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
template<class ValueTraits, class SizeType, std::size_t BoolFlags, typename HeaderHolder>
#endif
inline bool operator<=
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
(const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
#else
( const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &x
, const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &y)
#endif
{ return !(y < x); }
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
template<class ValueTraits, class SizeType, std::size_t BoolFlags, typename HeaderHolder>
#endif
inline bool operator>=
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
(const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
#else
( const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &x
, const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &y)
#endif
{ return !(x < y); }
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
template<class ValueTraits, class SizeType, std::size_t BoolFlags, typename HeaderHolder>
#endif
inline void swap
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
(slist_impl<T, Options...> &x, slist_impl<T, Options...> &y)
#else
( slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &x
, slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &y)
#endif
{ x.swap(y); }
//! Helper metafunction to define a \c slist that yields to the same type when the //! Helper metafunction to define a \c slist that yields to the same type when the
//! same options (either explicitly or implicitly) are used. //! same options (either explicitly or implicitly) are used.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)

View File

@@ -482,34 +482,24 @@ class splaytree_impl
//! @copydoc ::boost::intrusive::bstree::rebalance_subtree //! @copydoc ::boost::intrusive::bstree::rebalance_subtree
iterator rebalance_subtree(iterator root); iterator rebalance_subtree(iterator root);
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 #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
}; };
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
bool operator< (const splaytree_impl<T, Options...> &x, const splaytree_impl<T, Options...> &y);
template<class T, class ...Options>
bool operator==(const splaytree_impl<T, Options...> &x, const splaytree_impl<T, Options...> &y);
template<class T, class ...Options>
bool operator!= (const splaytree_impl<T, Options...> &x, const splaytree_impl<T, Options...> &y);
template<class T, class ...Options>
bool operator>(const splaytree_impl<T, Options...> &x, const splaytree_impl<T, Options...> &y);
template<class T, class ...Options>
bool operator<=(const splaytree_impl<T, Options...> &x, const splaytree_impl<T, Options...> &y);
template<class T, class ...Options>
bool operator>=(const splaytree_impl<T, Options...> &x, const splaytree_impl<T, Options...> &y);
template<class T, class ...Options>
void swap(splaytree_impl<T, Options...> &x, splaytree_impl<T, Options...> &y);
#endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
//! Helper metafunction to define a \c splaytree that yields to the same type when the //! Helper metafunction to define a \c splaytree that yields to the same type when the
//! same options (either explicitly or implicitly) are used. //! same options (either explicitly or implicitly) are used.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)

View File

@@ -774,11 +774,9 @@ class treap_impl
//! <b>Note</b>: Invalidates the iterators (but not the references) //! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called. //! to the erased elements. No destructors are called.
template<class KeyType, class KeyValueCompare> template<class KeyType, class KeyValueCompare>
size_type erase(const KeyType& key, KeyValueCompare comp BOOST_INTRUSIVE_DOC1ST(size_type
/// @cond , typename detail::disable_if_convertible<KeyValueCompare BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I size_type>::type)
, typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0 erase(const KeyType& key, KeyValueCompare comp)
/// @endcond
)
{ {
std::pair<iterator,iterator> p = this->equal_range(key, comp); std::pair<iterator,iterator> p = this->equal_range(key, comp);
size_type n; size_type n;
@@ -867,11 +865,9 @@ class treap_impl
//! <b>Note</b>: Invalidates the iterators //! <b>Note</b>: Invalidates the iterators
//! to the erased elements. //! to the erased elements.
template<class KeyType, class KeyValueCompare, class Disposer> template<class KeyType, class KeyValueCompare, class Disposer>
size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer BOOST_INTRUSIVE_DOC1ST(size_type
/// @cond , typename detail::disable_if_convertible<KeyValueCompare BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I size_type>::type)
, typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0 erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer)
/// @endcond
)
{ {
std::pair<iterator,iterator> p = this->equal_range(key, comp); std::pair<iterator,iterator> p = this->equal_range(key, comp);
size_type n; size_type n;
@@ -1030,6 +1026,20 @@ class treap_impl
//! @copydoc ::boost::intrusive::bstree::remove_node //! @copydoc ::boost::intrusive::bstree::remove_node
void remove_node(reference value); void remove_node(reference value);
friend bool operator< (const treap_impl &x, const treap_impl &y);
friend bool operator==(const treap_impl &x, const treap_impl &y);
friend bool operator!= (const treap_impl &x, const treap_impl &y);
friend bool operator>(const treap_impl &x, const treap_impl &y);
friend bool operator<=(const treap_impl &x, const treap_impl &y);
friend bool operator>=(const treap_impl &x, const treap_impl &y);
friend void swap(treap_impl &x, treap_impl &y);
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
/// @cond /// @cond
@@ -1051,30 +1061,6 @@ class treap_impl
/// @endcond /// @endcond
}; };
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
bool operator< (const treap_impl<T, Options...> &x, const treap_impl<T, Options...> &y);
template<class T, class ...Options>
bool operator==(const treap_impl<T, Options...> &x, const treap_impl<T, Options...> &y);
template<class T, class ...Options>
bool operator!= (const treap_impl<T, Options...> &x, const treap_impl<T, Options...> &y);
template<class T, class ...Options>
bool operator>(const treap_impl<T, Options...> &x, const treap_impl<T, Options...> &y);
template<class T, class ...Options>
bool operator<=(const treap_impl<T, Options...> &x, const treap_impl<T, Options...> &y);
template<class T, class ...Options>
bool operator>=(const treap_impl<T, Options...> &x, const treap_impl<T, Options...> &y);
template<class T, class ...Options>
void swap(treap_impl<T, Options...> &x, treap_impl<T, Options...> &y);
#endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
//! Helper metafunction to define a \c treap that yields to the same type when the //! Helper metafunction to define a \c treap that yields to the same type when the
//! same options (either explicitly or implicitly) are used. //! same options (either explicitly or implicitly) are used.

View File

@@ -473,11 +473,9 @@ class unordered_set_impl
//! <b>Note</b>: Invalidates the iterators //! <b>Note</b>: Invalidates the iterators
//! to the erased elements. //! to the erased elements.
template<class Disposer> template<class Disposer>
void erase_and_dispose(const_iterator i, Disposer disposer BOOST_INTRUSIVE_DOC1ST(void
/// @cond , typename detail::disable_if_convertible<Disposer BOOST_INTRUSIVE_I const_iterator>::type)
, typename detail::enable_if_c<!detail::is_convertible<Disposer, const_iterator>::value >::type * = 0 erase_and_dispose(const_iterator i, Disposer disposer)
/// @endcond
)
{ table_type::erase_and_dispose(i, disposer); } { table_type::erase_and_dispose(i, disposer); }
//! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -1503,19 +1501,11 @@ class unordered_multiset_impl
//! <b>Note</b>: Invalidates the iterators //! <b>Note</b>: Invalidates the iterators
//! to the erased elements. //! to the erased elements.
template<class Disposer> template<class Disposer>
void erase_and_dispose(const_iterator i, Disposer disposer BOOST_INTRUSIVE_DOC1ST(void
/// @cond , typename detail::disable_if_convertible<Disposer BOOST_INTRUSIVE_I const_iterator>::type)
, typename detail::enable_if_c<!detail::is_convertible<Disposer, const_iterator>::value >::type * = 0 erase_and_dispose(const_iterator i, Disposer disposer)
/// @endcond
)
{ table_type::erase_and_dispose(i, disposer); } { table_type::erase_and_dispose(i, disposer); }
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class Disposer>
void erase_and_dispose(const_iterator i, Disposer disposer)
{ this->erase_and_dispose(const_iterator(i), disposer); }
#endif
//! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases the range pointed to by b end e. //! <b>Effects</b>: Erases the range pointed to by b end e.

View File

@@ -127,10 +127,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "null_iterator", "null_itera
ProjectSection(ProjectDependencies) = postProject ProjectSection(ProjectDependencies) = postProject
EndProjectSection EndProjectSection
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "map_test", "..\..\..\container\proj\vc7ide\map_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792606}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global Global
GlobalSection(SolutionConfiguration) = preSolution GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug Debug = Debug
@@ -267,10 +263,6 @@ Global
{32A79B10-B2A0-C1B8-9458-9456152413B5}.Debug.Build.0 = Debug|Win32 {32A79B10-B2A0-C1B8-9458-9456152413B5}.Debug.Build.0 = Debug|Win32
{32A79B10-B2A0-C1B8-9458-9456152413B5}.Release.ActiveCfg = Release|Win32 {32A79B10-B2A0-C1B8-9458-9456152413B5}.Release.ActiveCfg = Release|Win32
{32A79B10-B2A0-C1B8-9458-9456152413B5}.Release.Build.0 = Release|Win32 {32A79B10-B2A0-C1B8-9458-9456152413B5}.Release.Build.0 = Release|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792606}.Debug.ActiveCfg = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792606}.Debug.Build.0 = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792606}.Release.ActiveCfg = Release|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792606}.Release.Build.0 = Release|Win32
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection EndGlobalSection

View File

@@ -54,8 +54,8 @@ class bounded_pointer
{} {}
template<class T2> template<class T2>
bounded_pointer(const bounded_pointer<T2> &other, typename boost::intrusive::detail::enable_if_c bounded_pointer( const bounded_pointer<T2> &other
<boost::intrusive::detail::is_convertible<T2*, T*>::value>::type* = 0) , typename boost::intrusive::detail::enable_if_convertible<T2*, T*>::type* = 0)
: m_offset(other.m_offset) : m_offset(other.m_offset)
{} {}
@@ -63,8 +63,7 @@ class bounded_pointer
{ m_offset = other.m_offset; return *this; } { m_offset = other.m_offset; return *this; }
template <class T2> template <class T2>
typename boost::intrusive::detail::enable_if_c typename boost::intrusive::detail::enable_if_convertible<T2*, T*, bounded_pointer&>::type
<boost::intrusive::detail::is_convertible<T2*, T*>::value, bounded_pointer&>::type
operator= (const bounded_pointer<T2> & other) operator= (const bounded_pointer<T2> & other)
{ m_offset = other.m_offset; return *this; } { m_offset = other.m_offset; return *this; }
@@ -172,14 +171,13 @@ class bounded_reference
{ assert(m_offset != max_offset); raw() = rhs.raw(); return *this; } { assert(m_offset != max_offset); raw() = rhs.raw(); return *this; }
template<class T2> template<class T2>
bounded_reference(const bounded_reference<T2> &other, typename boost::intrusive::detail::enable_if_c bounded_reference( const bounded_reference<T2> &other
<boost::intrusive::detail::is_convertible<T2&, T&>::value>::type* = 0) , typename boost::intrusive::detail::enable_if_convertible<T2*, T*>::type* = 0)
: m_offset(other.m_offset) : m_offset(other.m_offset)
{} {}
template <class T2> template <class T2>
typename boost::intrusive::detail::enable_if_c typename boost::intrusive::detail::enable_if_convertible<T2*, T*, bounded_reference&>::type
<boost::intrusive::detail::is_convertible<T2&, T&>::value, bounded_reference&>::type
operator= (const bounded_reference<T2> & other) operator= (const bounded_reference<T2> & other)
{ m_offset = other.m_offset; return *this; } { m_offset = other.m_offset; return *this; }

View File

@@ -76,6 +76,15 @@ void test_container( Container & c )
BOOST_TEST( c.size() == i ); BOOST_TEST( c.size() == i );
} }
static_cast<const Container&>(c).check(); static_cast<const Container&>(c).check();
//Very basic test for comparisons
{
BOOST_TEST(c == c);
BOOST_TEST(!(c != c));
BOOST_TEST(!(c < c));
BOOST_TEST(c <= c);
BOOST_TEST(!(c > c));
BOOST_TEST(c >= c);
}
} }