diff --git a/include/boost/intrusive/circular_slist_algorithms.hpp b/include/boost/intrusive/circular_slist_algorithms.hpp
index 7cb8f5b..b843590 100644
--- a/include/boost/intrusive/circular_slist_algorithms.hpp
+++ b/include/boost/intrusive/circular_slist_algorithms.hpp
@@ -74,7 +74,7 @@ class circular_slist_algorithms
//!
//! Effects: Returns true is "this_node" is the only node of a circular list:
//! or it's a not inserted node:
- //! return false == NodeTraits::get_next(this_node) || NodeTraits::get_next(this_node) == this_node
+ //! return node_ptr() == NodeTraits::get_next(this_node) || NodeTraits::get_next(this_node) == this_node
//!
//! Complexity: Constant
//!
diff --git a/include/boost/intrusive/detail/has_member_function_callable_with.hpp b/include/boost/intrusive/detail/has_member_function_callable_with.hpp
index 895b02a..d34e73f 100644
--- a/include/boost/intrusive/detail/has_member_function_callable_with.hpp
+++ b/include/boost/intrusive/detail/has_member_function_callable_with.hpp
@@ -21,6 +21,12 @@
#include
#include
+ //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 {
struct dont_care
@@ -107,6 +113,18 @@
#if !defined(_MSC_VER) || (_MSC_VER != 1600)
+ #if defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED)
+
+ template
+ struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl)
+
+ {
+ //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
template< class F
, std::size_t N =
@@ -141,6 +159,7 @@
static const bool value = sizeof(Test< Fun >(0))
== sizeof(boost_intrusive_has_member_function_callable_with::yes_type);
};
+ #endif
#else //#if !defined(_MSC_VER) || (_MSC_VER != 1600)
template
diff --git a/include/boost/intrusive/detail/memory_util.hpp b/include/boost/intrusive/detail/memory_util.hpp
index 72e792a..ba2b729 100644
--- a/include/boost/intrusive/detail/memory_util.hpp
+++ b/include/boost/intrusive/detail/memory_util.hpp
@@ -69,13 +69,42 @@ struct LowPriorityConversion
static const bool value = (1 == sizeof(test(0, 0))); \
\
typedef typename \
- ::boost::intrusive::detail::if_c::type::TNAME type; \
- } \
+ ::boost::intrusive::detail::if_c \
+ ::type::TNAME type; \
+ }; \
+ \
+ template \
+ struct boost_intrusive_eval_default_type_ ## TNAME \
+ { \
+ template \
+ static char test(int, typename X::TNAME*); \
+ \
+ template \
+ static int test(boost::intrusive::detail:: \
+ LowPriorityConversion, void*); \
+ \
+ struct DefaultWrap \
+ { typedef typename DefaultType::type TNAME; }; \
+ \
+ static const bool value = (1 == sizeof(test(0, 0))); \
+ \
+ typedef typename \
+ ::boost::intrusive::detail::eval_if_c \
+ < value \
+ , ::boost::intrusive::detail::identity \
+ , ::boost::intrusive::detail::identity \
+ >::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::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_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
diff --git a/include/boost/intrusive/detail/utilities.hpp b/include/boost/intrusive/detail/utilities.hpp
index c9f2cb3..c041620 100644
--- a/include/boost/intrusive/detail/utilities.hpp
+++ b/include/boost/intrusive/detail/utilities.hpp
@@ -208,14 +208,14 @@ struct key_nodeptr_comp
};
template
- typename enable_if_c::value, const value_type &>::type
- key_forward(const T &node) const
+ const value_type & key_forward
+ (const T &node, typename enable_if_c::value>::type * = 0) const
{ return *cont_->get_real_value_traits().to_value_ptr(node); }
template
- typename enable_if_c::value, const T &>::type
- key_forward(const T &key) const
- { return key;}
+ const T & key_forward(const T &key, typename enable_if_c::value>::type* = 0) const
+ { return key; }
+
template
bool operator()(const KeyType &key1, const KeyType2 &key2) const
@@ -596,20 +596,20 @@ class exception_disposer
}
};
-template
+template
class exception_array_disposer
{
Container *cont_;
Disposer &disp_;
- typename Container::size_type &constructed_;
+ SizeType &constructed_;
exception_array_disposer(const exception_array_disposer&);
exception_array_disposer &operator=(const exception_array_disposer&);
public:
- typedef typename Container::size_type size_type;
+
exception_array_disposer
- (Container &cont, Disposer &disp, size_type &constructed)
+ (Container &cont, Disposer &disp, SizeType &constructed)
: cont_(&cont), disp_(disp), constructed_(constructed)
{}
@@ -618,7 +618,7 @@ class exception_array_disposer
~exception_array_disposer()
{
- size_type n = constructed_;
+ SizeType n = constructed_;
if(cont_){
while(n--){
cont_[n].clear_and_dispose(disp_);
diff --git a/include/boost/intrusive/hashtable.hpp b/include/boost/intrusive/hashtable.hpp
index 4e6e61a..bade5cb 100644
--- a/include/boost/intrusive/hashtable.hpp
+++ b/include/boost/intrusive/hashtable.hpp
@@ -30,6 +30,7 @@
#include
#include
#include
+#include
//Implementation utilities
#include
#include
@@ -1131,7 +1132,7 @@ class hashtable_impl
typedef node_cast_adaptor > NodeCloner;
NodeDisposer node_disp(disposer, this);
- detail::exception_array_disposer
+ detail::exception_array_disposer
rollback(dst_buckets[0], node_disp, constructed);
for( constructed = 0
; constructed < dst_bucket_count
@@ -2080,10 +2081,12 @@ class hashtable_impl
//is harmless, because all elements have been already unlinked and destroyed
typedef detail::init_disposer NodeDisposer;
NodeDisposer node_disp;
- detail::exception_array_disposer
- rollback1(new_buckets[0], node_disp, new_buckets_len);
- detail::exception_array_disposer
- rollback2(old_buckets[0], node_disp, old_buckets_len);
+ bucket_type & newbuck = new_buckets[0];
+ bucket_type & oldbuck = old_buckets[0];
+ detail::exception_array_disposer
+ rollback1(newbuck, node_disp, new_buckets_len);
+ detail::exception_array_disposer
+ rollback2(oldbuck, node_disp, old_buckets_len);
//Put size in a safe value for rollback exception
size_type size_backup = this->priv_size_traits().get_size();
diff --git a/include/boost/intrusive/linear_slist_algorithms.hpp b/include/boost/intrusive/linear_slist_algorithms.hpp
index 729a4bf..f335655 100644
--- a/include/boost/intrusive/linear_slist_algorithms.hpp
+++ b/include/boost/intrusive/linear_slist_algorithms.hpp
@@ -73,7 +73,7 @@ class linear_slist_algorithms
//!
//! Effects: Returns true is "this_node" is the only node of a circular list:
//! or it's a not inserted node:
- //! return false == NodeTraits::get_next(this_node) || NodeTraits::get_next(this_node) == this_node
+ //! return node_ptr() == NodeTraits::get_next(this_node) || NodeTraits::get_next(this_node) == this_node
//!
//! Complexity: Constant
//!
diff --git a/include/boost/intrusive/pointer_traits.hpp b/include/boost/intrusive/pointer_traits.hpp
index 28743f1..9f7d2fa 100644
--- a/include/boost/intrusive/pointer_traits.hpp
+++ b/include/boost/intrusive/pointer_traits.hpp
@@ -67,9 +67,9 @@ struct pointer_traits
#else
typedef Ptr pointer;
//
- typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
+ typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT
( boost::intrusive::detail::, Ptr, element_type
- , typename boost::intrusive::detail::first_param::type) element_type;
+ , boost::intrusive::detail::first_param) element_type;
//
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
(boost::intrusive::detail::, Ptr, difference_type, std::ptrdiff_t) difference_type;
diff --git a/test/has_member_function_callable_with.cpp b/test/has_member_function_callable_with.cpp
index fd5498a..5daefa8 100644
--- a/test/has_member_function_callable_with.cpp
+++ b/test/has_member_function_callable_with.cpp
@@ -10,6 +10,8 @@
#include
#include
+//Just for BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED
+#include
#include
#include
@@ -94,6 +96,8 @@ class has_member_function_named_func
#if !defined(_MSC_VER) || (_MSC_VER != 1600)
+ #if !defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED)
+
template().func(), 0)>
struct zeroarg_checker_func
{
@@ -120,10 +124,22 @@ class has_member_function_named_func
template
static has_member_function_callable_with::no_type Test(...);
- static const bool value = sizeof(Test< Fun >(0))
- == sizeof(has_member_function_callable_with::yes_type);
+ static const bool value
+ = sizeof(Test< Fun >(0)) == sizeof(has_member_function_callable_with::yes_type);
};
+ #else
+
+ template
+ struct has_member_function_callable_with_func_impl
+
+ {
+ //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
template
@@ -380,6 +396,7 @@ int main()
{
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::value ? 1 : -1];
int check2[!has_member_function_callable_with_func::value ? 1 : -1];
@@ -390,6 +407,7 @@ int main()
(void)check3;
(void)check4;
}
+ #endif
{
int check1[ has_member_function_callable_with_func::value ? 1 : -1];