mirror of
https://github.com/boostorg/intrusive.git
synced 2025-08-03 22:44:43 +02:00
Merging into release branch for 1.49
[SVN r76247]
This commit is contained in:
@@ -74,7 +74,7 @@ class circular_slist_algorithms
|
|||||||
//!
|
//!
|
||||||
//! <b>Effects</b>: Returns true is "this_node" is the only node of a 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:
|
//! or it's a not inserted node:
|
||||||
//! <tt>return false == NodeTraits::get_next(this_node) || NodeTraits::get_next(this_node) == this_node</tt>
|
//! <tt>return node_ptr() == NodeTraits::get_next(this_node) || NodeTraits::get_next(this_node) == this_node</tt>
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Constant
|
//! <b>Complexity</b>: Constant
|
||||||
//!
|
//!
|
||||||
|
@@ -21,6 +21,12 @@
|
|||||||
#include <boost/static_assert.hpp>
|
#include <boost/static_assert.hpp>
|
||||||
#include <boost/move/move.hpp>
|
#include <boost/move/move.hpp>
|
||||||
|
|
||||||
|
//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
|
||||||
|
#if defined(__GNUC__) && !defined(__clang__) && ((__GNUC__*100 + __GNUC_MINOR__*10) >= 340) && ((__GNUC__*100 + __GNUC_MINOR__*10) <= 430)
|
||||||
|
#define BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace boost_intrusive_has_member_function_callable_with {
|
namespace boost_intrusive_has_member_function_callable_with {
|
||||||
|
|
||||||
struct dont_care
|
struct dont_care
|
||||||
@@ -107,6 +113,18 @@
|
|||||||
|
|
||||||
#if !defined(_MSC_VER) || (_MSC_VER != 1600)
|
#if !defined(_MSC_VER) || (_MSC_VER != 1600)
|
||||||
|
|
||||||
|
#if defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED)
|
||||||
|
|
||||||
|
template<typename Fun>
|
||||||
|
struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl)
|
||||||
|
<Fun, true BOOST_PP_ENUM_TRAILING(BOOST_PP_SUB(BOOST_PP_ITERATION_FINISH(), BOOST_PP_ITERATION()), BOOST_INTRUSIVE_PP_IDENTITY, void)>
|
||||||
|
{
|
||||||
|
//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
|
||||||
|
static const bool value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
//Special case for 0 args
|
//Special case for 0 args
|
||||||
template< class F
|
template< class F
|
||||||
, std::size_t N =
|
, std::size_t N =
|
||||||
@@ -141,6 +159,7 @@
|
|||||||
static const bool value = sizeof(Test< Fun >(0))
|
static const bool value = sizeof(Test< Fun >(0))
|
||||||
== sizeof(boost_intrusive_has_member_function_callable_with::yes_type);
|
== sizeof(boost_intrusive_has_member_function_callable_with::yes_type);
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
#else //#if !defined(_MSC_VER) || (_MSC_VER != 1600)
|
#else //#if !defined(_MSC_VER) || (_MSC_VER != 1600)
|
||||||
template<typename Fun>
|
template<typename Fun>
|
||||||
|
@@ -69,8 +69,32 @@ struct LowPriorityConversion
|
|||||||
static const bool value = (1 == sizeof(test<T>(0, 0))); \
|
static const bool value = (1 == sizeof(test<T>(0, 0))); \
|
||||||
\
|
\
|
||||||
typedef typename \
|
typedef typename \
|
||||||
::boost::intrusive::detail::if_c<value, T, DefaultWrap>::type::TNAME type; \
|
::boost::intrusive::detail::if_c \
|
||||||
} \
|
<value, T, DefaultWrap>::type::TNAME type; \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
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(boost::intrusive::detail:: \
|
||||||
|
LowPriorityConversion<int>, void*); \
|
||||||
|
\
|
||||||
|
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_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL) \
|
#define BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL) \
|
||||||
@@ -78,6 +102,11 @@ struct LowPriorityConversion
|
|||||||
boost_intrusive_default_type_ ## TNAME< T, TIMPL >::type \
|
boost_intrusive_default_type_ ## TNAME< T, TIMPL >::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 \
|
||||||
|
//
|
||||||
|
|
||||||
}}} //namespace boost::intrusive::detail
|
}}} //namespace boost::intrusive::detail
|
||||||
|
|
||||||
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
|
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
|
||||||
|
@@ -208,15 +208,15 @@ struct key_nodeptr_comp
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
typename enable_if_c<is_node_ptr<T>::value, const value_type &>::type
|
const value_type & key_forward
|
||||||
key_forward(const T &node) const
|
(const T &node, typename enable_if_c<is_node_ptr<T>::value>::type * = 0) const
|
||||||
{ return *cont_->get_real_value_traits().to_value_ptr(node); }
|
{ return *cont_->get_real_value_traits().to_value_ptr(node); }
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
typename enable_if_c<!is_node_ptr<T>::value, const T &>::type
|
const T & key_forward(const T &key, typename enable_if_c<!is_node_ptr<T>::value>::type* = 0) const
|
||||||
key_forward(const T &key) const
|
|
||||||
{ return key; }
|
{ return key; }
|
||||||
|
|
||||||
|
|
||||||
template<class KeyType, class KeyType2>
|
template<class KeyType, class KeyType2>
|
||||||
bool operator()(const KeyType &key1, const KeyType2 &key2) const
|
bool operator()(const KeyType &key1, const KeyType2 &key2) const
|
||||||
{ return base_t::get()(this->key_forward(key1), this->key_forward(key2)); }
|
{ return base_t::get()(this->key_forward(key1), this->key_forward(key2)); }
|
||||||
@@ -596,20 +596,20 @@ class exception_disposer
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class Container, class Disposer>
|
template<class Container, class Disposer, class SizeType>
|
||||||
class exception_array_disposer
|
class exception_array_disposer
|
||||||
{
|
{
|
||||||
Container *cont_;
|
Container *cont_;
|
||||||
Disposer &disp_;
|
Disposer &disp_;
|
||||||
typename Container::size_type &constructed_;
|
SizeType &constructed_;
|
||||||
|
|
||||||
exception_array_disposer(const exception_array_disposer&);
|
exception_array_disposer(const exception_array_disposer&);
|
||||||
exception_array_disposer &operator=(const exception_array_disposer&);
|
exception_array_disposer &operator=(const exception_array_disposer&);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef typename Container::size_type size_type;
|
|
||||||
exception_array_disposer
|
exception_array_disposer
|
||||||
(Container &cont, Disposer &disp, size_type &constructed)
|
(Container &cont, Disposer &disp, SizeType &constructed)
|
||||||
: cont_(&cont), disp_(disp), constructed_(constructed)
|
: cont_(&cont), disp_(disp), constructed_(constructed)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@@ -618,7 +618,7 @@ class exception_array_disposer
|
|||||||
|
|
||||||
~exception_array_disposer()
|
~exception_array_disposer()
|
||||||
{
|
{
|
||||||
size_type n = constructed_;
|
SizeType n = constructed_;
|
||||||
if(cont_){
|
if(cont_){
|
||||||
while(n--){
|
while(n--){
|
||||||
cont_[n].clear_and_dispose(disp_);
|
cont_[n].clear_and_dispose(disp_);
|
||||||
|
@@ -30,6 +30,7 @@
|
|||||||
#include <boost/intrusive/link_mode.hpp>
|
#include <boost/intrusive/link_mode.hpp>
|
||||||
#include <boost/intrusive/detail/ebo_functor_holder.hpp>
|
#include <boost/intrusive/detail/ebo_functor_holder.hpp>
|
||||||
#include <boost/intrusive/detail/clear_on_destructor_base.hpp>
|
#include <boost/intrusive/detail/clear_on_destructor_base.hpp>
|
||||||
|
#include <boost/intrusive/detail/utilities.hpp>
|
||||||
//Implementation utilities
|
//Implementation utilities
|
||||||
#include <boost/intrusive/trivial_value_traits.hpp>
|
#include <boost/intrusive/trivial_value_traits.hpp>
|
||||||
#include <boost/intrusive/unordered_set_hook.hpp>
|
#include <boost/intrusive/unordered_set_hook.hpp>
|
||||||
@@ -1131,7 +1132,7 @@ class hashtable_impl
|
|||||||
typedef node_cast_adaptor<detail::node_cloner<Cloner, hashtable_impl> > NodeCloner;
|
typedef node_cast_adaptor<detail::node_cloner<Cloner, hashtable_impl> > NodeCloner;
|
||||||
NodeDisposer node_disp(disposer, this);
|
NodeDisposer node_disp(disposer, this);
|
||||||
|
|
||||||
detail::exception_array_disposer<bucket_type, NodeDisposer>
|
detail::exception_array_disposer<bucket_type, NodeDisposer, size_type>
|
||||||
rollback(dst_buckets[0], node_disp, constructed);
|
rollback(dst_buckets[0], node_disp, constructed);
|
||||||
for( constructed = 0
|
for( constructed = 0
|
||||||
; constructed < dst_bucket_count
|
; constructed < dst_bucket_count
|
||||||
@@ -2080,10 +2081,12 @@ class hashtable_impl
|
|||||||
//is harmless, because all elements have been already unlinked and destroyed
|
//is harmless, because all elements have been already unlinked and destroyed
|
||||||
typedef detail::init_disposer<node_algorithms> NodeDisposer;
|
typedef detail::init_disposer<node_algorithms> NodeDisposer;
|
||||||
NodeDisposer node_disp;
|
NodeDisposer node_disp;
|
||||||
detail::exception_array_disposer<bucket_type, NodeDisposer>
|
bucket_type & newbuck = new_buckets[0];
|
||||||
rollback1(new_buckets[0], node_disp, new_buckets_len);
|
bucket_type & oldbuck = old_buckets[0];
|
||||||
detail::exception_array_disposer<bucket_type, NodeDisposer>
|
detail::exception_array_disposer<bucket_type, NodeDisposer, size_type>
|
||||||
rollback2(old_buckets[0], node_disp, old_buckets_len);
|
rollback1(newbuck, node_disp, new_buckets_len);
|
||||||
|
detail::exception_array_disposer<bucket_type, NodeDisposer, size_type>
|
||||||
|
rollback2(oldbuck, node_disp, old_buckets_len);
|
||||||
|
|
||||||
//Put size in a safe value for rollback exception
|
//Put size in a safe value for rollback exception
|
||||||
size_type size_backup = this->priv_size_traits().get_size();
|
size_type size_backup = this->priv_size_traits().get_size();
|
||||||
|
@@ -73,7 +73,7 @@ class linear_slist_algorithms
|
|||||||
//!
|
//!
|
||||||
//! <b>Effects</b>: Returns true is "this_node" is the only node of a 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:
|
//! or it's a not inserted node:
|
||||||
//! <tt>return false == NodeTraits::get_next(this_node) || NodeTraits::get_next(this_node) == this_node</tt>
|
//! <tt>return node_ptr() == NodeTraits::get_next(this_node) || NodeTraits::get_next(this_node) == this_node</tt>
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Constant
|
//! <b>Complexity</b>: Constant
|
||||||
//!
|
//!
|
||||||
|
@@ -67,9 +67,9 @@ struct pointer_traits
|
|||||||
#else
|
#else
|
||||||
typedef Ptr pointer;
|
typedef Ptr pointer;
|
||||||
//
|
//
|
||||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
|
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT
|
||||||
( boost::intrusive::detail::, Ptr, element_type
|
( boost::intrusive::detail::, Ptr, element_type
|
||||||
, typename boost::intrusive::detail::first_param<Ptr>::type) element_type;
|
, boost::intrusive::detail::first_param<Ptr>) element_type;
|
||||||
//
|
//
|
||||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
|
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
|
||||||
(boost::intrusive::detail::, Ptr, difference_type, std::ptrdiff_t) difference_type;
|
(boost::intrusive::detail::, Ptr, difference_type, std::ptrdiff_t) difference_type;
|
||||||
|
@@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
#include <boost/intrusive/detail/config_begin.hpp>
|
#include <boost/intrusive/detail/config_begin.hpp>
|
||||||
#include <boost/intrusive/detail/workaround.hpp>
|
#include <boost/intrusive/detail/workaround.hpp>
|
||||||
|
//Just for BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED
|
||||||
|
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <boost/move/move.hpp>
|
#include <boost/move/move.hpp>
|
||||||
|
|
||||||
@@ -94,6 +96,8 @@ class has_member_function_named_func
|
|||||||
|
|
||||||
#if !defined(_MSC_VER) || (_MSC_VER != 1600)
|
#if !defined(_MSC_VER) || (_MSC_VER != 1600)
|
||||||
|
|
||||||
|
#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>().func(), 0)>
|
template<class F, std::size_t N = sizeof(boost::move_detail::declval<F>().func(), 0)>
|
||||||
struct zeroarg_checker_func
|
struct zeroarg_checker_func
|
||||||
{
|
{
|
||||||
@@ -120,10 +124,22 @@ class has_member_function_named_func
|
|||||||
template <class U>
|
template <class U>
|
||||||
static has_member_function_callable_with::no_type Test(...);
|
static has_member_function_callable_with::no_type Test(...);
|
||||||
|
|
||||||
static const bool value = sizeof(Test< Fun >(0))
|
static const bool value
|
||||||
== sizeof(has_member_function_callable_with::yes_type);
|
= sizeof(Test< Fun >(0)) == sizeof(has_member_function_callable_with::yes_type);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
template<typename Fun>
|
||||||
|
struct has_member_function_callable_with_func_impl
|
||||||
|
<Fun, true , void , void , void>
|
||||||
|
{
|
||||||
|
//GCC [3.4-4.3) gives ICE when instantiating the 0 arg version so it is not supported.
|
||||||
|
static const bool value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
template<typename Fun>
|
template<typename Fun>
|
||||||
@@ -380,6 +396,7 @@ int main()
|
|||||||
{
|
{
|
||||||
using namespace boost::intrusive::intrusive_detail;
|
using namespace boost::intrusive::intrusive_detail;
|
||||||
|
|
||||||
|
#if !defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED)
|
||||||
{
|
{
|
||||||
int check1[ has_member_function_callable_with_func<functor>::value ? 1 : -1];
|
int check1[ has_member_function_callable_with_func<functor>::value ? 1 : -1];
|
||||||
int check2[!has_member_function_callable_with_func<functor2>::value ? 1 : -1];
|
int check2[!has_member_function_callable_with_func<functor2>::value ? 1 : -1];
|
||||||
@@ -390,6 +407,7 @@ int main()
|
|||||||
(void)check3;
|
(void)check3;
|
||||||
(void)check4;
|
(void)check4;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
{
|
{
|
||||||
int check1[ has_member_function_callable_with_func<functor, int>::value ? 1 : -1];
|
int check1[ has_member_function_callable_with_func<functor, int>::value ? 1 : -1];
|
||||||
|
Reference in New Issue
Block a user