From 6b62dcc504be9bf9c44c89edc53e84d5b0efd401 Mon Sep 17 00:00:00 2001 From: Tony Lewis Date: Mon, 24 Dec 2018 07:02:31 +0000 Subject: [PATCH] Completely remove constexpr for MSVC --- include/boost/operators.hpp | 119 +++++++++++++++++++----------------- operators.htm | 24 +++++--- test/operators_test.cpp | 14 +++-- 3 files changed, 87 insertions(+), 70 deletions(-) diff --git a/include/boost/operators.hpp b/include/boost/operators.hpp index 3ef19cc..5fc8060 100644 --- a/include/boost/operators.hpp +++ b/include/boost/operators.hpp @@ -109,6 +109,13 @@ # pragma warning( disable : 4284 ) // complaint about return type of #endif // operator-> not begin a UDT +// Define BOOST_OPS_CONSTEXPR to be like BOOST_CONSTEXPR but empty under MSVC +#ifdef BOOST_MSVC +#define BOOST_OPS_CONSTEXPR +#else +#define BOOST_OPS_CONSTEXPR BOOST_CONSTEXPR +#endif + // In this section we supply the xxxx1 and xxxx2 forms of the operator // templates, which are explicitly targeted at the 1-type-argument and // 2-type-argument operator forms, respectively. @@ -132,34 +139,34 @@ template class empty_base {}; template > struct less_than_comparable2 : B { - friend BOOST_CONSTEXPR bool operator<=(const T& x, const U& y) { return !static_cast(x > y); } - friend BOOST_CONSTEXPR bool operator>=(const T& x, const U& y) { return !static_cast(x < y); } - friend BOOST_CONSTEXPR bool operator>(const U& x, const T& y) { return y < x; } - friend BOOST_CONSTEXPR bool operator<(const U& x, const T& y) { return y > x; } - friend BOOST_CONSTEXPR bool operator<=(const U& x, const T& y) { return !static_cast(y < x); } - friend BOOST_CONSTEXPR bool operator>=(const U& x, const T& y) { return !static_cast(y > x); } + friend BOOST_OPS_CONSTEXPR bool operator<=(const T& x, const U& y) { return !static_cast(x > y); } + friend BOOST_OPS_CONSTEXPR bool operator>=(const T& x, const U& y) { return !static_cast(x < y); } + friend BOOST_OPS_CONSTEXPR bool operator>(const U& x, const T& y) { return y < x; } + friend BOOST_OPS_CONSTEXPR bool operator<(const U& x, const T& y) { return y > x; } + friend BOOST_OPS_CONSTEXPR bool operator<=(const U& x, const T& y) { return !static_cast(y < x); } + friend BOOST_OPS_CONSTEXPR bool operator>=(const U& x, const T& y) { return !static_cast(y > x); } }; template > struct less_than_comparable1 : B { - friend BOOST_CONSTEXPR bool operator>(const T& x, const T& y) { return y < x; } - friend BOOST_CONSTEXPR bool operator<=(const T& x, const T& y) { return !static_cast(y < x); } - friend BOOST_CONSTEXPR bool operator>=(const T& x, const T& y) { return !static_cast(x < y); } + friend BOOST_OPS_CONSTEXPR bool operator>(const T& x, const T& y) { return y < x; } + friend BOOST_OPS_CONSTEXPR bool operator<=(const T& x, const T& y) { return !static_cast(y < x); } + friend BOOST_OPS_CONSTEXPR bool operator>=(const T& x, const T& y) { return !static_cast(x < y); } }; template > struct equality_comparable2 : B { - friend BOOST_CONSTEXPR bool operator==(const U& y, const T& x) { return x == y; } - friend BOOST_CONSTEXPR bool operator!=(const U& y, const T& x) { return !static_cast(x == y); } - friend BOOST_CONSTEXPR bool operator!=(const T& y, const U& x) { return !static_cast(y == x); } + friend BOOST_OPS_CONSTEXPR bool operator==(const U& y, const T& x) { return x == y; } + friend BOOST_OPS_CONSTEXPR bool operator!=(const U& y, const T& x) { return !static_cast(x == y); } + friend BOOST_OPS_CONSTEXPR bool operator!=(const T& y, const U& x) { return !static_cast(y == x); } }; template > struct equality_comparable1 : B { - friend BOOST_CONSTEXPR bool operator!=(const T& x, const T& y) { return !static_cast(x == y); } + friend BOOST_OPS_CONSTEXPR bool operator!=(const T& x, const T& y) { return !static_cast(x == y); } }; // A macro which produces "name_2left" from "name". @@ -220,38 +227,38 @@ struct NAME##1 : B \ // BOOST_OPERATOR2_LEFT(NAME) only looks cool, but doesn't provide // optimization opportunities to the compiler :) -#define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP ) \ -template > \ -struct NAME##2 : B \ -{ \ - friend BOOST_CONSTEXPR T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \ - friend BOOST_CONSTEXPR T operator OP( const U& lhs, T rhs ) { return rhs OP##= lhs; } \ -}; \ - \ -template > \ -struct NAME##1 : B \ -{ \ - friend BOOST_CONSTEXPR T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \ +#define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP ) \ +template > \ +struct NAME##2 : B \ +{ \ + friend BOOST_OPS_CONSTEXPR T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \ + friend BOOST_OPS_CONSTEXPR T operator OP( const U& lhs, T rhs ) { return rhs OP##= lhs; } \ +}; \ + \ +template > \ +struct NAME##1 : B \ +{ \ + friend BOOST_OPS_CONSTEXPR T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \ }; -#define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP ) \ -template > \ -struct NAME##2 : B \ -{ \ - friend BOOST_CONSTEXPR T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \ -}; \ - \ -template > \ -struct BOOST_OPERATOR2_LEFT(NAME) : B \ -{ \ - friend BOOST_CONSTEXPR T operator OP( const U& lhs, const T& rhs ) \ - { return T( lhs ) OP##= rhs; } \ -}; \ - \ -template > \ -struct NAME##1 : B \ -{ \ - friend BOOST_CONSTEXPR T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \ +#define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP ) \ +template > \ +struct NAME##2 : B \ +{ \ + friend BOOST_OPS_CONSTEXPR T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \ +}; \ + \ +template > \ +struct BOOST_OPERATOR2_LEFT(NAME) : B \ +{ \ + friend BOOST_OPS_CONSTEXPR T operator OP( const U& lhs, const T& rhs ) \ + { return T( lhs ) OP##= rhs; } \ +}; \ + \ +template > \ +struct NAME##1 : B \ +{ \ + friend BOOST_OPS_CONSTEXPR T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \ }; #endif // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS) @@ -343,13 +350,13 @@ struct NAME##1 : B \ template > \ struct NAME##2 : B \ { \ - friend BOOST_CONSTEXPR T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \ + friend BOOST_OPS_CONSTEXPR T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \ }; \ \ template > \ struct NAME##1 : B \ { \ - friend BOOST_CONSTEXPR T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \ + friend BOOST_OPS_CONSTEXPR T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \ }; #endif // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS) @@ -362,7 +369,7 @@ BOOST_BINARY_OPERATOR( right_shiftable, >> ) template > struct equivalent2 : B { - friend BOOST_CONSTEXPR bool operator==(const T& x, const U& y) + friend BOOST_OPS_CONSTEXPR bool operator==(const T& x, const U& y) { return !static_cast(x < y) && !static_cast(x > y); } @@ -371,7 +378,7 @@ struct equivalent2 : B template > struct equivalent1 : B { - friend BOOST_CONSTEXPR bool operator==(const T&x, const T&y) + friend BOOST_OPS_CONSTEXPR bool operator==(const T&x, const T&y) { return !static_cast(x < y) && !static_cast(y < x); } @@ -380,28 +387,28 @@ struct equivalent1 : B template > struct partially_ordered2 : B { - friend BOOST_CONSTEXPR bool operator<=(const T& x, const U& y) + friend BOOST_OPS_CONSTEXPR bool operator<=(const T& x, const U& y) { return static_cast(x < y) || static_cast(x == y); } - friend BOOST_CONSTEXPR bool operator>=(const T& x, const U& y) + friend BOOST_OPS_CONSTEXPR bool operator>=(const T& x, const U& y) { return static_cast(x > y) || static_cast(x == y); } - friend BOOST_CONSTEXPR bool operator>(const U& x, const T& y) + friend BOOST_OPS_CONSTEXPR bool operator>(const U& x, const T& y) { return y < x; } - friend BOOST_CONSTEXPR bool operator<(const U& x, const T& y) + friend BOOST_OPS_CONSTEXPR bool operator<(const U& x, const T& y) { return y > x; } - friend BOOST_CONSTEXPR bool operator<=(const U& x, const T& y) + friend BOOST_OPS_CONSTEXPR bool operator<=(const U& x, const T& y) { return static_cast(y > x) || static_cast(y == x); } - friend BOOST_CONSTEXPR bool operator>=(const U& x, const T& y) + friend BOOST_OPS_CONSTEXPR bool operator>=(const U& x, const T& y) { return static_cast(y < x) || static_cast(y == x); } }; template > struct partially_ordered1 : B { - friend BOOST_CONSTEXPR bool operator>(const T& x, const T& y) + friend BOOST_OPS_CONSTEXPR bool operator>(const T& x, const T& y) { return y < x; } - friend BOOST_CONSTEXPR bool operator<=(const T& x, const T& y) + friend BOOST_OPS_CONSTEXPR bool operator<=(const T& x, const T& y) { return static_cast(x < y) || static_cast(x == y); } - friend BOOST_CONSTEXPR bool operator>=(const T& x, const T& y) + friend BOOST_OPS_CONSTEXPR bool operator>=(const T& x, const T& y) { return static_cast(y < x) || static_cast(x == y); } }; diff --git a/operators.htm b/operators.htm index b985e91..9265b7c 100644 --- a/operators.htm +++ b/operators.htm @@ -499,7 +499,8 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4); Return convertible to bool. See the Ordering Note. - Since C++11 + Since C++11
+ (except MSVC) @@ -518,7 +519,8 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4); Returns convertible to bool. See the Ordering Note. - Since C++11 + Since C++11
+ (except MSVC) @@ -531,7 +533,8 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4); t == t1.
Return convertible to bool. - Since C++11 + Since C++11
+ (except MSVC) @@ -546,7 +549,8 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4); t == u.
Return convertible to bool. - Since C++11 + Since C++11
+ (except MSVC) @@ -892,7 +896,8 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4); Return convertible to bool. See the Ordering Note. - Since C++11 + Since C++11
+ (except MSVC) @@ -905,7 +910,8 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4); Returns convertible to bool. See the Ordering Note. - Since C++11 + Since C++11
+ (except MSVC) @@ -921,7 +927,8 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4); Returns convertible to bool. See the Ordering Note. - Since C++11 + Since C++11
+ (except MSVC) @@ -941,7 +948,8 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4); Returns convertible to bool. See the Ordering Note. - Since C++11 + Since C++11
+ (except MSVC) diff --git a/test/operators_test.cpp b/test/operators_test.cpp index fdc0cc4..82182fa 100644 --- a/test/operators_test.cpp +++ b/test/operators_test.cpp @@ -50,9 +50,9 @@ namespace void operator!() const; public: - BOOST_CONSTEXPR convertible_to_bool( const bool value ) : _value( value ) {} + BOOST_OPS_CONSTEXPR convertible_to_bool( const bool value ) : _value( value ) {} - BOOST_CONSTEXPR operator unspecified_bool_type() const + BOOST_OPS_CONSTEXPR operator unspecified_bool_type() const { return _value ? &convertible_to_bool::_value : 0; } }; @@ -64,12 +64,12 @@ namespace , boost::shiftable > { public: - BOOST_CONSTEXPR explicit Wrapped1( T v = T() ) : _value(v) {} - BOOST_CONSTEXPR T value() const { return _value; } + BOOST_OPS_CONSTEXPR explicit Wrapped1( T v = T() ) : _value(v) {} + BOOST_OPS_CONSTEXPR T value() const { return _value; } - BOOST_CONSTEXPR convertible_to_bool operator<(const Wrapped1& x) const + BOOST_OPS_CONSTEXPR convertible_to_bool operator<(const Wrapped1& x) const { return _value < x._value; } - BOOST_CONSTEXPR convertible_to_bool operator==(const Wrapped1& x) const + BOOST_OPS_CONSTEXPR convertible_to_bool operator==(const Wrapped1& x) const { return _value == x._value; } Wrapped1& operator+=(const Wrapped1& x) @@ -934,6 +934,7 @@ main() // Where C++11 constexpr is available, compile-time test some of the operators that are able to use it to propagate constexpr #ifndef BOOST_NO_CXX11_CONSTEXPR +#ifndef BOOST_MSVC static_assert( ! static_cast( MyInt{ 1 } == MyInt{ 2 } ), "" ); static_assert( MyInt{ 1 } != MyInt{ 2 }, "" ); static_assert( MyInt{ 1 } < MyInt{ 2 }, "" ); @@ -954,6 +955,7 @@ main() static_assert( MyInt{ 1 } <= MyInt{ 1 }, "" ); static_assert( ! static_cast( MyInt{ 1 } > MyInt{ 1 } ), "" ); static_assert( MyInt{ 1 } >= MyInt{ 1 }, "" ); +#endif #endif return boost::report_errors();