Merge pull request #64 from glenfe/develop

Update to Operators constexpr support
This commit is contained in:
Glen Fernandes 2020-04-12 13:33:17 -04:00 committed by GitHub
commit 6e6d0777e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 94 additions and 64 deletions

View File

@ -109,15 +109,11 @@
# 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 < v19.22
#ifdef BOOST_MSVC
#if BOOST_MSVC_FULL_VER >= 192200000
#define BOOST_OPS_CONSTEXPR constexpr
// Define BOOST_OPERATORS_CONSTEXPR to be like BOOST_CONSTEXPR but empty under MSVC < v19.22
#if BOOST_WORKAROUND(BOOST_MSVC, < 1922)
#define BOOST_OPERATORS_CONSTEXPR
#else
#define BOOST_OPS_CONSTEXPR
#endif
#else
#define BOOST_OPS_CONSTEXPR BOOST_CONSTEXPR
#define BOOST_OPERATORS_CONSTEXPR BOOST_CONSTEXPR
#endif
// In this section we supply the xxxx1 and xxxx2 forms of the operator
@ -143,34 +139,34 @@ template <typename T> class empty_base {};
template <class T, class U, class B = operators_detail::empty_base<T> >
struct less_than_comparable2 : B
{
friend BOOST_OPS_CONSTEXPR bool operator<=(const T& x, const U& y) { return !static_cast<bool>(x > y); }
friend BOOST_OPS_CONSTEXPR bool operator>=(const T& x, const U& y) { return !static_cast<bool>(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<bool>(y < x); }
friend BOOST_OPS_CONSTEXPR bool operator>=(const U& x, const T& y) { return !static_cast<bool>(y > x); }
friend BOOST_OPERATORS_CONSTEXPR bool operator<=(const T& x, const U& y) { return !static_cast<bool>(x > y); }
friend BOOST_OPERATORS_CONSTEXPR bool operator>=(const T& x, const U& y) { return !static_cast<bool>(x < y); }
friend BOOST_OPERATORS_CONSTEXPR bool operator>(const U& x, const T& y) { return y < x; }
friend BOOST_OPERATORS_CONSTEXPR bool operator<(const U& x, const T& y) { return y > x; }
friend BOOST_OPERATORS_CONSTEXPR bool operator<=(const U& x, const T& y) { return !static_cast<bool>(y < x); }
friend BOOST_OPERATORS_CONSTEXPR bool operator>=(const U& x, const T& y) { return !static_cast<bool>(y > x); }
};
template <class T, class B = operators_detail::empty_base<T> >
struct less_than_comparable1 : B
{
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<bool>(y < x); }
friend BOOST_OPS_CONSTEXPR bool operator>=(const T& x, const T& y) { return !static_cast<bool>(x < y); }
friend BOOST_OPERATORS_CONSTEXPR bool operator>(const T& x, const T& y) { return y < x; }
friend BOOST_OPERATORS_CONSTEXPR bool operator<=(const T& x, const T& y) { return !static_cast<bool>(y < x); }
friend BOOST_OPERATORS_CONSTEXPR bool operator>=(const T& x, const T& y) { return !static_cast<bool>(x < y); }
};
template <class T, class U, class B = operators_detail::empty_base<T> >
struct equality_comparable2 : B
{
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<bool>(x == y); }
friend BOOST_OPS_CONSTEXPR bool operator!=(const T& y, const U& x) { return !static_cast<bool>(y == x); }
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 T& y, const U& x) { return !static_cast<bool>(y == x); }
};
template <class T, class B = operators_detail::empty_base<T> >
struct equality_comparable1 : B
{
friend BOOST_OPS_CONSTEXPR bool operator!=(const T& x, const T& y) { return !static_cast<bool>(x == y); }
friend BOOST_OPERATORS_CONSTEXPR bool operator!=(const T& x, const T& y) { return !static_cast<bool>(x == y); }
};
// A macro which produces "name_2left" from "name".
@ -373,7 +369,7 @@ BOOST_BINARY_OPERATOR( right_shiftable, >> )
template <class T, class U, class B = operators_detail::empty_base<T> >
struct equivalent2 : B
{
friend BOOST_OPS_CONSTEXPR bool operator==(const T& x, const U& y)
friend BOOST_OPERATORS_CONSTEXPR bool operator==(const T& x, const U& y)
{
return !static_cast<bool>(x < y) && !static_cast<bool>(x > y);
}
@ -382,7 +378,7 @@ struct equivalent2 : B
template <class T, class B = operators_detail::empty_base<T> >
struct equivalent1 : B
{
friend BOOST_OPS_CONSTEXPR bool operator==(const T&x, const T&y)
friend BOOST_OPERATORS_CONSTEXPR bool operator==(const T&x, const T&y)
{
return !static_cast<bool>(x < y) && !static_cast<bool>(y < x);
}
@ -391,28 +387,28 @@ struct equivalent1 : B
template <class T, class U, class B = operators_detail::empty_base<T> >
struct partially_ordered2 : B
{
friend BOOST_OPS_CONSTEXPR bool operator<=(const T& x, const U& y)
friend BOOST_OPERATORS_CONSTEXPR bool operator<=(const T& x, const U& y)
{ return static_cast<bool>(x < y) || static_cast<bool>(x == y); }
friend BOOST_OPS_CONSTEXPR bool operator>=(const T& x, const U& y)
friend BOOST_OPERATORS_CONSTEXPR bool operator>=(const T& x, const U& y)
{ return static_cast<bool>(x > y) || static_cast<bool>(x == y); }
friend BOOST_OPS_CONSTEXPR bool operator>(const U& x, const T& y)
friend BOOST_OPERATORS_CONSTEXPR bool operator>(const U& x, const T& y)
{ return y < x; }
friend BOOST_OPS_CONSTEXPR bool operator<(const U& x, const T& y)
friend BOOST_OPERATORS_CONSTEXPR bool operator<(const U& x, const T& y)
{ return y > x; }
friend BOOST_OPS_CONSTEXPR bool operator<=(const U& x, const T& y)
friend BOOST_OPERATORS_CONSTEXPR bool operator<=(const U& x, const T& y)
{ return static_cast<bool>(y > x) || static_cast<bool>(y == x); }
friend BOOST_OPS_CONSTEXPR bool operator>=(const U& x, const T& y)
friend BOOST_OPERATORS_CONSTEXPR bool operator>=(const U& x, const T& y)
{ return static_cast<bool>(y < x) || static_cast<bool>(y == x); }
};
template <class T, class B = operators_detail::empty_base<T> >
struct partially_ordered1 : B
{
friend BOOST_OPS_CONSTEXPR bool operator>(const T& x, const T& y)
friend BOOST_OPERATORS_CONSTEXPR bool operator>(const T& x, const T& y)
{ return y < x; }
friend BOOST_OPS_CONSTEXPR bool operator<=(const T& x, const T& y)
friend BOOST_OPERATORS_CONSTEXPR bool operator<=(const T& x, const T& y)
{ return static_cast<bool>(x < y) || static_cast<bool>(x == y); }
friend BOOST_OPS_CONSTEXPR bool operator>=(const T& x, const T& y)
friend BOOST_OPERATORS_CONSTEXPR bool operator>=(const T& x, const T& y)
{ return static_cast<bool>(y < x) || static_cast<bool>(x == y); }
};

View File

@ -21,6 +21,7 @@ run compressed_pair_final_test.cpp ;
run iterators_test.cpp ;
run operators_test.cpp ;
compile operators_constexpr_test.cpp ;
compile result_of_test.cpp ;

View File

@ -0,0 +1,59 @@
/*
Copyright 2020 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_CONSTEXPR) && \
(!defined(BOOST_MSVC) || (BOOST_MSVC >= 1922))
#include <boost/operators.hpp>
#include <boost/static_assert.hpp>
namespace {
class Value
: boost::operators<Value> {
public:
BOOST_OPERATORS_CONSTEXPR explicit Value(int v)
: v_(v) { }
BOOST_OPERATORS_CONSTEXPR bool
operator<(const Value& x) const {
return v_ < x.v_;
}
BOOST_OPERATORS_CONSTEXPR bool
operator==(const Value& x) const {
return v_ == x.v_;
}
private:
int v_;
};
} // namespace
BOOST_STATIC_ASSERT(!static_cast<bool>(Value(1) == Value(2)));
BOOST_STATIC_ASSERT(Value(1) != Value(2));
BOOST_STATIC_ASSERT(Value(1) < Value(2));
BOOST_STATIC_ASSERT(Value(1) <= Value(2));
BOOST_STATIC_ASSERT(!static_cast<bool>(Value(1) > Value(2)));
BOOST_STATIC_ASSERT(!static_cast<bool>(Value(1) >= Value(2)));
BOOST_STATIC_ASSERT(!static_cast<bool>(Value(2) == Value(1)));
BOOST_STATIC_ASSERT(Value(2) != Value(1));
BOOST_STATIC_ASSERT(!static_cast<bool>(Value(2) < Value(1)));
BOOST_STATIC_ASSERT(!static_cast<bool>(Value(2) <= Value(1)));
BOOST_STATIC_ASSERT(Value(2) > Value(1));
BOOST_STATIC_ASSERT(Value(2) >= Value(1));
BOOST_STATIC_ASSERT(Value(1) == Value(1));
BOOST_STATIC_ASSERT(!static_cast<bool>(Value(1) != Value(1)));
BOOST_STATIC_ASSERT(!static_cast<bool>(Value(1) < Value(1)));
BOOST_STATIC_ASSERT(Value(1) <= Value(1));
BOOST_STATIC_ASSERT(!static_cast<bool>(Value(1) > Value(1)));
BOOST_STATIC_ASSERT(Value(1) >= Value(1));
#endif

View File

@ -50,9 +50,9 @@ namespace
void operator!() const;
public:
BOOST_OPS_CONSTEXPR convertible_to_bool( const bool value ) : _value( value ) {}
convertible_to_bool( const bool value ) : _value( value ) {}
BOOST_OPS_CONSTEXPR operator unspecified_bool_type() const
operator unspecified_bool_type() const
{ return _value ? &convertible_to_bool::_value : 0; }
};
@ -64,12 +64,12 @@ namespace
, boost::shiftable<Wrapped1<T> >
{
public:
BOOST_OPS_CONSTEXPR explicit Wrapped1( T v = T() ) : _value(v) {}
BOOST_OPS_CONSTEXPR T value() const { return _value; }
explicit Wrapped1( T v = T() ) : _value(v) {}
T value() const { return _value; }
BOOST_OPS_CONSTEXPR convertible_to_bool operator<(const Wrapped1& x) const
convertible_to_bool operator<(const Wrapped1& x) const
{ return _value < x._value; }
BOOST_OPS_CONSTEXPR convertible_to_bool operator==(const Wrapped1& x) const
convertible_to_bool operator==(const Wrapped1& x) const
{ return _value == x._value; }
Wrapped1& operator+=(const Wrapped1& x)
@ -932,31 +932,5 @@ main()
cout << "Performed tests on MyLongInt objects.\n";
// 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
#if !defined(BOOST_MSVC) || (_MSC_VER >= 1922)
static_assert( ! static_cast<bool>( MyInt{ 1 } == MyInt{ 2 } ), "" );
static_assert( MyInt{ 1 } != MyInt{ 2 }, "" );
static_assert( MyInt{ 1 } < MyInt{ 2 }, "" );
static_assert( MyInt{ 1 } <= MyInt{ 2 }, "" );
static_assert( ! static_cast<bool>( MyInt{ 1 } > MyInt{ 2 } ), "" );
static_assert( ! static_cast<bool>( MyInt{ 1 } >= MyInt{ 2 } ), "" );
static_assert( ! static_cast<bool>( MyInt{ 2 } == MyInt{ 1 } ), "" );
static_assert( MyInt{ 2 } != MyInt{ 1 }, "" );
static_assert( ! static_cast<bool>( MyInt{ 2 } < MyInt{ 1 } ), "" );
static_assert( ! static_cast<bool>( MyInt{ 2 } <= MyInt{ 1 } ), "" );
static_assert( MyInt{ 2 } > MyInt{ 1 }, "" );
static_assert( MyInt{ 2 } >= MyInt{ 1 }, "" );
static_assert( MyInt{ 1 } == MyInt{ 1 }, "" );
static_assert( ! static_cast<bool>( MyInt{ 1 } != MyInt{ 1 } ), "" );
static_assert( ! static_cast<bool>( MyInt{ 1 } < MyInt{ 1 } ), "" );
static_assert( MyInt{ 1 } <= MyInt{ 1 }, "" );
static_assert( ! static_cast<bool>( MyInt{ 1 } > MyInt{ 1 } ), "" );
static_assert( MyInt{ 1 } >= MyInt{ 1 }, "" );
#endif
#endif
return boost::report_errors();
}