Fix compilation in case if key is void*

If key type is `void*`, wrong `operator()` is chosen because of the dummy argument that is used for SFINAE. As a result the key comparison adapter invokes the user's predicate with only one argument, which fails to compile.

Use a more distict type for SFINAE in the dummy arguments. Fixes ticket #12745.
This commit is contained in:
Andrey Semashev
2017-01-10 23:57:57 +04:00
committed by Andrey Semashev
parent 190900e1b0
commit b1da5c25b4

View File

@@ -59,6 +59,10 @@ struct key_nodeptr_comp
//Use public inheritance to avoid MSVC bugs with closures
: public key_nodeptr_comp_types<KeyTypeKeyCompare, ValueTraits, KeyOfValue>::base_t
{
private:
struct sfinae_type;
public:
typedef key_nodeptr_comp_types<KeyTypeKeyCompare, ValueTraits, KeyOfValue> types_t;
typedef typename types_t::value_traits value_traits;
typedef typename types_t::value_type value_type;
@@ -83,32 +87,32 @@ struct key_nodeptr_comp
//pred(pnode)
template<class T1>
BOOST_INTRUSIVE_FORCEINLINE bool operator()(const T1 &t1, typename enable_if_c< is_same_or_nodeptr_convertible<T1>::value >::type* =0) const
BOOST_INTRUSIVE_FORCEINLINE bool operator()(const T1 &t1, typename enable_if_c< is_same_or_nodeptr_convertible<T1>::value, sfinae_type* >::type = 0) const
{ return base().get()(key_of_value()(*traits_->to_value_ptr(t1))); }
//operator() 2 arg
//pred(pnode, pnode)
template<class T1, class T2>
BOOST_INTRUSIVE_FORCEINLINE bool operator()
(const T1 &t1, const T2 &t2, typename enable_if_c< is_same_or_nodeptr_convertible<T1>::value && is_same_or_nodeptr_convertible<T2>::value >::type* =0) const
(const T1 &t1, const T2 &t2, typename enable_if_c< is_same_or_nodeptr_convertible<T1>::value && is_same_or_nodeptr_convertible<T2>::value, sfinae_type* >::type = 0) const
{ return base()(*traits_->to_value_ptr(t1), *traits_->to_value_ptr(t2)); }
//pred(pnode, key)
template<class T1, class T2>
BOOST_INTRUSIVE_FORCEINLINE bool operator()
(const T1 &t1, const T2 &t2, typename enable_if_c< is_same_or_nodeptr_convertible<T1>::value && !is_same_or_nodeptr_convertible<T2>::value >::type* =0) const
(const T1 &t1, const T2 &t2, typename enable_if_c< is_same_or_nodeptr_convertible<T1>::value && !is_same_or_nodeptr_convertible<T2>::value, sfinae_type* >::type = 0) const
{ return base()(*traits_->to_value_ptr(t1), t2); }
//pred(key, pnode)
template<class T1, class T2>
BOOST_INTRUSIVE_FORCEINLINE bool operator()
(const T1 &t1, const T2 &t2, typename enable_if_c< !is_same_or_nodeptr_convertible<T1>::value && is_same_or_nodeptr_convertible<T2>::value >::type* =0) const
(const T1 &t1, const T2 &t2, typename enable_if_c< !is_same_or_nodeptr_convertible<T1>::value && is_same_or_nodeptr_convertible<T2>::value, sfinae_type* >::type = 0) const
{ return base()(t1, *traits_->to_value_ptr(t2)); }
//pred(key, key)
template<class T1, class T2>
BOOST_INTRUSIVE_FORCEINLINE bool operator()
(const T1 &t1, const T2 &t2, typename enable_if_c< !is_same_or_nodeptr_convertible<T1>::value && !is_same_or_nodeptr_convertible<T2>::value >::type* =0) const
(const T1 &t1, const T2 &t2, typename enable_if_c< !is_same_or_nodeptr_convertible<T1>::value && !is_same_or_nodeptr_convertible<T2>::value, sfinae_type* >::type = 0) const
{ return base()(t1, t2); }
const ValueTraits *const traits_;