mirror of
https://github.com/boostorg/utility.git
synced 2025-05-08 18:34:02 +00:00
Attempt to work around C++20 operator rewriting causinginfinite recursion.
Fixes https://github.com/boostorg/utility/issues/65.
This commit is contained in:
parent
37168a3f4b
commit
f3963f5375
@ -100,6 +100,11 @@
|
|||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
#include <boost/detail/workaround.hpp>
|
#include <boost/detail/workaround.hpp>
|
||||||
#include <boost/core/addressof.hpp>
|
#include <boost/core/addressof.hpp>
|
||||||
|
#if defined(__cpp_impl_three_way_comparison)
|
||||||
|
#include <boost/core/enable_if.hpp>
|
||||||
|
#include <boost/type_traits/is_same.hpp>
|
||||||
|
#include <boost/type_traits/declval.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__sgi) && !defined(__GNUC__)
|
#if defined(__sgi) && !defined(__GNUC__)
|
||||||
# pragma set woff 1234
|
# pragma set woff 1234
|
||||||
@ -158,9 +163,21 @@ struct less_than_comparable1 : B
|
|||||||
template <class T, class U, class B = operators_detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct equality_comparable2 : B
|
struct equality_comparable2 : B
|
||||||
{
|
{
|
||||||
|
#if defined(__cpp_impl_three_way_comparison)
|
||||||
|
template< typename R = decltype(boost::declval< T const& >() == boost::declval< U const& >()) >
|
||||||
|
friend BOOST_OPERATORS_CONSTEXPR
|
||||||
|
typename boost::enable_if_c< !boost::is_same< R, bool >::value, bool >::type
|
||||||
|
operator==(const U& y, const T& x) { return x == y; }
|
||||||
|
|
||||||
|
template< typename R = decltype(boost::declval< T const& >() == boost::declval< U const& >()) >
|
||||||
|
friend BOOST_OPERATORS_CONSTEXPR
|
||||||
|
typename boost::enable_if_c< !boost::is_same< R, bool >::value, bool >::type
|
||||||
|
operator!=(const U& y, const T& x) { return !static_cast<bool>(x == y); }
|
||||||
|
#else
|
||||||
friend BOOST_OPERATORS_CONSTEXPR bool operator==(const U& y, const T& x) { return x == y; }
|
friend BOOST_OPERATORS_CONSTEXPR bool operator==(const U& y, const T& x) { return x == y; }
|
||||||
friend BOOST_OPERATORS_CONSTEXPR bool operator!=(const U& y, const T& x) { return !static_cast<bool>(x == y); }
|
friend BOOST_OPERATORS_CONSTEXPR bool operator!=(const U& y, const T& x) { return !static_cast<bool>(x == y); }
|
||||||
friend BOOST_OPERATORS_CONSTEXPR bool operator!=(const T& y, const U& x) { return !static_cast<bool>(y == x); }
|
#endif
|
||||||
|
friend BOOST_OPERATORS_CONSTEXPR bool operator!=(const T& x, const U& y) { return !static_cast<bool>(x == y); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T, class B = operators_detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
|
@ -144,9 +144,11 @@ struct less_than_comparable1 : B
|
|||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
struct equality_comparable2 : B
|
struct equality_comparable2 : B
|
||||||
{
|
{
|
||||||
|
#if !defined(__cpp_impl_three_way_comparison)
|
||||||
friend bool operator==(const U& y, const T& x) { return x == y; }
|
friend bool operator==(const U& y, const T& x) { return x == y; }
|
||||||
friend bool operator!=(const U& y, const T& x) { return !static_cast<bool>(x == y); }
|
friend bool operator!=(const U& y, const T& x) { return !static_cast<bool>(x == y); }
|
||||||
friend bool operator!=(const T& y, const U& x) { return !static_cast<bool>(y == x); }
|
#endif
|
||||||
|
friend bool operator!=(const T& x, const U& y) { return !static_cast<bool>(x == y); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
@ -568,6 +568,25 @@ namespace
|
|||||||
int v;
|
int v;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Test type designed specifically to test C++20 operator rewriting support
|
||||||
|
struct my_int :
|
||||||
|
public boost::equality_comparable2< my_int, int >
|
||||||
|
{
|
||||||
|
explicit my_int(int n) : m_n(n) {}
|
||||||
|
|
||||||
|
operator int () const
|
||||||
|
{
|
||||||
|
return m_n;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator== (my_int that)
|
||||||
|
{
|
||||||
|
return that.m_n == m_n;
|
||||||
|
}
|
||||||
|
|
||||||
|
int m_n;
|
||||||
|
};
|
||||||
|
|
||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
|
|
||||||
|
|
||||||
@ -932,5 +951,11 @@ main()
|
|||||||
|
|
||||||
cout << "Performed tests on MyLongInt objects.\n";
|
cout << "Performed tests on MyLongInt objects.\n";
|
||||||
|
|
||||||
|
my_int my_n = my_int(10);
|
||||||
|
|
||||||
|
// Test if C++20 operator rewriting causes infinite recursion (https://github.com/boostorg/utility/issues/65)
|
||||||
|
BOOST_TEST(my_n == 10);
|
||||||
|
BOOST_TEST(my_n != 20);
|
||||||
|
|
||||||
return boost::report_errors();
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user