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];