Fix LWG 2934 - optional<const T> doesn't compare with T

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@299105 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Eric Fiselier
2017-03-30 20:06:52 +00:00
parent 5612bd42dc
commit 2b3c1c4d9b
14 changed files with 577 additions and 443 deletions

View File

@@ -921,14 +921,14 @@ private:
}; };
// Comparisons between optionals // Comparisons between optionals
template <class _Tp> template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr _LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t< enable_if_t<
is_convertible_v<decltype(_VSTD::declval<const _Tp&>() == is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
_VSTD::declval<const _Tp&>()), bool>, _VSTD::declval<const _Up&>()), bool>,
bool bool
> >
operator==(const optional<_Tp>& __x, const optional<_Tp>& __y) operator==(const optional<_Tp>& __x, const optional<_Up>& __y)
{ {
if (static_cast<bool>(__x) != static_cast<bool>(__y)) if (static_cast<bool>(__x) != static_cast<bool>(__y))
return false; return false;
@@ -937,14 +937,14 @@ operator==(const optional<_Tp>& __x, const optional<_Tp>& __y)
return *__x == *__y; return *__x == *__y;
} }
template <class _Tp> template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr _LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t< enable_if_t<
is_convertible_v<decltype(_VSTD::declval<const _Tp&>() != is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
_VSTD::declval<const _Tp&>()), bool>, _VSTD::declval<const _Up&>()), bool>,
bool bool
> >
operator!=(const optional<_Tp>& __x, const optional<_Tp>& __y) operator!=(const optional<_Tp>& __x, const optional<_Up>& __y)
{ {
if (static_cast<bool>(__x) != static_cast<bool>(__y)) if (static_cast<bool>(__x) != static_cast<bool>(__y))
return true; return true;
@@ -953,14 +953,14 @@ operator!=(const optional<_Tp>& __x, const optional<_Tp>& __y)
return *__x != *__y; return *__x != *__y;
} }
template <class _Tp> template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr _LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t< enable_if_t<
is_convertible_v<decltype(_VSTD::declval<const _Tp&>() < is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
_VSTD::declval<const _Tp&>()), bool>, _VSTD::declval<const _Up&>()), bool>,
bool bool
> >
operator<(const optional<_Tp>& __x, const optional<_Tp>& __y) operator<(const optional<_Tp>& __x, const optional<_Up>& __y)
{ {
if (!static_cast<bool>(__y)) if (!static_cast<bool>(__y))
return false; return false;
@@ -969,14 +969,14 @@ operator<(const optional<_Tp>& __x, const optional<_Tp>& __y)
return *__x < *__y; return *__x < *__y;
} }
template <class _Tp> template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr _LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t< enable_if_t<
is_convertible_v<decltype(_VSTD::declval<const _Tp&>() > is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
_VSTD::declval<const _Tp&>()), bool>, _VSTD::declval<const _Up&>()), bool>,
bool bool
> >
operator>(const optional<_Tp>& __x, const optional<_Tp>& __y) operator>(const optional<_Tp>& __x, const optional<_Up>& __y)
{ {
if (!static_cast<bool>(__x)) if (!static_cast<bool>(__x))
return false; return false;
@@ -985,14 +985,14 @@ operator>(const optional<_Tp>& __x, const optional<_Tp>& __y)
return *__x > *__y; return *__x > *__y;
} }
template <class _Tp> template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr _LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t< enable_if_t<
is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <= is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
_VSTD::declval<const _Tp&>()), bool>, _VSTD::declval<const _Up&>()), bool>,
bool bool
> >
operator<=(const optional<_Tp>& __x, const optional<_Tp>& __y) operator<=(const optional<_Tp>& __x, const optional<_Up>& __y)
{ {
if (!static_cast<bool>(__x)) if (!static_cast<bool>(__x))
return true; return true;
@@ -1001,14 +1001,14 @@ operator<=(const optional<_Tp>& __x, const optional<_Tp>& __y)
return *__x <= *__y; return *__x <= *__y;
} }
template <class _Tp> template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr _LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t< enable_if_t<
is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >= is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
_VSTD::declval<const _Tp&>()), bool>, _VSTD::declval<const _Up&>()), bool>,
bool bool
> >
operator>=(const optional<_Tp>& __x, const optional<_Tp>& __y) operator>=(const optional<_Tp>& __x, const optional<_Up>& __y)
{ {
if (!static_cast<bool>(__y)) if (!static_cast<bool>(__y))
return true; return true;
@@ -1115,146 +1115,146 @@ operator>=(nullopt_t, const optional<_Tp>& __x) noexcept
} }
// Comparisons with T // Comparisons with T
template <class _Tp> template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr _LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t< enable_if_t<
is_convertible_v<decltype(_VSTD::declval<const _Tp&>() == is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
_VSTD::declval<const _Tp&>()), bool>, _VSTD::declval<const _Up&>()), bool>,
bool bool
> >
operator==(const optional<_Tp>& __x, const _Tp& __v) operator==(const optional<_Tp>& __x, const _Up& __v)
{ {
return static_cast<bool>(__x) ? *__x == __v : false; return static_cast<bool>(__x) ? *__x == __v : false;
} }
template <class _Tp> template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr _LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t< enable_if_t<
is_convertible_v<decltype(_VSTD::declval<const _Tp&>() == is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
_VSTD::declval<const _Tp&>()), bool>, _VSTD::declval<const _Up&>()), bool>,
bool bool
> >
operator==(const _Tp& __v, const optional<_Tp>& __x) operator==(const _Tp& __v, const optional<_Up>& __x)
{ {
return static_cast<bool>(__x) ? __v == *__x : false; return static_cast<bool>(__x) ? __v == *__x : false;
} }
template <class _Tp> template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr _LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t< enable_if_t<
is_convertible_v<decltype(_VSTD::declval<const _Tp&>() != is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
_VSTD::declval<const _Tp&>()), bool>, _VSTD::declval<const _Up&>()), bool>,
bool bool
> >
operator!=(const optional<_Tp>& __x, const _Tp& __v) operator!=(const optional<_Tp>& __x, const _Up& __v)
{ {
return static_cast<bool>(__x) ? *__x != __v : true; return static_cast<bool>(__x) ? *__x != __v : true;
} }
template <class _Tp> template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr _LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t< enable_if_t<
is_convertible_v<decltype(_VSTD::declval<const _Tp&>() != is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
_VSTD::declval<const _Tp&>()), bool>, _VSTD::declval<const _Up&>()), bool>,
bool bool
> >
operator!=(const _Tp& __v, const optional<_Tp>& __x) operator!=(const _Tp& __v, const optional<_Up>& __x)
{ {
return static_cast<bool>(__x) ? __v != *__x : true; return static_cast<bool>(__x) ? __v != *__x : true;
} }
template <class _Tp> template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr _LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t< enable_if_t<
is_convertible_v<decltype(_VSTD::declval<const _Tp&>() < is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
_VSTD::declval<const _Tp&>()), bool>, _VSTD::declval<const _Up&>()), bool>,
bool bool
> >
operator<(const optional<_Tp>& __x, const _Tp& __v) operator<(const optional<_Tp>& __x, const _Up& __v)
{ {
return static_cast<bool>(__x) ? *__x < __v : true; return static_cast<bool>(__x) ? *__x < __v : true;
} }
template <class _Tp> template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr _LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t< enable_if_t<
is_convertible_v<decltype(_VSTD::declval<const _Tp&>() < is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
_VSTD::declval<const _Tp&>()), bool>, _VSTD::declval<const _Up&>()), bool>,
bool bool
> >
operator<(const _Tp& __v, const optional<_Tp>& __x) operator<(const _Tp& __v, const optional<_Up>& __x)
{ {
return static_cast<bool>(__x) ? __v < *__x : false; return static_cast<bool>(__x) ? __v < *__x : false;
} }
template <class _Tp> template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr _LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t< enable_if_t<
is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <= is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
_VSTD::declval<const _Tp&>()), bool>, _VSTD::declval<const _Up&>()), bool>,
bool bool
> >
operator<=(const optional<_Tp>& __x, const _Tp& __v) operator<=(const optional<_Tp>& __x, const _Up& __v)
{ {
return static_cast<bool>(__x) ? *__x <= __v : true; return static_cast<bool>(__x) ? *__x <= __v : true;
} }
template <class _Tp> template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr _LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t< enable_if_t<
is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <= is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
_VSTD::declval<const _Tp&>()), bool>, _VSTD::declval<const _Up&>()), bool>,
bool bool
> >
operator<=(const _Tp& __v, const optional<_Tp>& __x) operator<=(const _Tp& __v, const optional<_Up>& __x)
{ {
return static_cast<bool>(__x) ? __v <= *__x : false; return static_cast<bool>(__x) ? __v <= *__x : false;
} }
template <class _Tp> template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr _LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t< enable_if_t<
is_convertible_v<decltype(_VSTD::declval<const _Tp&>() > is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
_VSTD::declval<const _Tp&>()), bool>, _VSTD::declval<const _Up&>()), bool>,
bool bool
> >
operator>(const optional<_Tp>& __x, const _Tp& __v) operator>(const optional<_Tp>& __x, const _Up& __v)
{ {
return static_cast<bool>(__x) ? *__x > __v : false; return static_cast<bool>(__x) ? *__x > __v : false;
} }
template <class _Tp> template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr _LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t< enable_if_t<
is_convertible_v<decltype(_VSTD::declval<const _Tp&>() > is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
_VSTD::declval<const _Tp&>()), bool>, _VSTD::declval<const _Up&>()), bool>,
bool bool
> >
operator>(const _Tp& __v, const optional<_Tp>& __x) operator>(const _Tp& __v, const optional<_Up>& __x)
{ {
return static_cast<bool>(__x) ? __v > *__x : true; return static_cast<bool>(__x) ? __v > *__x : true;
} }
template <class _Tp> template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr _LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t< enable_if_t<
is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >= is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
_VSTD::declval<const _Tp&>()), bool>, _VSTD::declval<const _Up&>()), bool>,
bool bool
> >
operator>=(const optional<_Tp>& __x, const _Tp& __v) operator>=(const optional<_Tp>& __x, const _Up& __v)
{ {
return static_cast<bool>(__x) ? *__x >= __v : false; return static_cast<bool>(__x) ? *__x >= __v : false;
} }
template <class _Tp> template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr _LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t< enable_if_t<
is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >= is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
_VSTD::declval<const _Tp&>()), bool>, _VSTD::declval<const _Up&>()), bool>,
bool bool
> >
operator>=(const _Tp& __v, const optional<_Tp>& __x) operator>=(const _Tp& __v, const optional<_Up>& __x)
{ {
return static_cast<bool>(__x) ? __v >= *__x : true; return static_cast<bool>(__x) ? __v >= *__x : true;
} }

View File

@@ -17,18 +17,17 @@
using std::optional; using std::optional;
struct X struct X {
{
int i_; int i_;
constexpr X(int i) : i_(i) {} constexpr X(int i) : i_(i) {}
}; };
constexpr bool operator == ( const X &lhs, const X &rhs ) constexpr bool operator==(const X& lhs, const X& rhs) {
{ return lhs.i_ == rhs.i_ ; } return lhs.i_ == rhs.i_;
}
int main() int main() {
{
{ {
typedef X T; typedef X T;
typedef optional<T> O; typedef optional<T> O;
@@ -50,4 +49,16 @@ int main()
static_assert((T(2) == o3), ""); static_assert((T(2) == o3), "");
static_assert((val == o3), ""); static_assert((val == o3), "");
} }
{
using O = optional<int>;
constexpr O o1(42);
static_assert(o1 == 42l, "");
static_assert(!(101l == o1), "");
}
{
using O = optional<const int>;
constexpr O o1(42);
static_assert(o1 == 42, "");
static_assert(!(101 == o1), "");
}
} }

View File

@@ -17,18 +17,15 @@
using std::optional; using std::optional;
struct X struct X {
{
int i_; int i_;
constexpr X(int i) : i_(i) {} constexpr X(int i) : i_(i) {}
}; };
constexpr bool operator > ( const X &lhs, const X &rhs ) constexpr bool operator>(const X& lhs, const X& rhs) { return lhs.i_ > rhs.i_; }
{ return lhs.i_ > rhs.i_ ; }
int main() int main() {
{
{ {
typedef X T; typedef X T;
typedef optional<T> O; typedef optional<T> O;
@@ -52,4 +49,16 @@ int main()
static_assert(!(val > o3), ""); // equal static_assert(!(val > o3), ""); // equal
static_assert((T(3) > o3), ""); static_assert((T(3) > o3), "");
} }
{
using O = optional<int>;
constexpr O o1(42);
static_assert(o1 > 11l, "");
static_assert(!(42l > o1), "");
}
{
using O = optional<const int>;
constexpr O o1(42);
static_assert(o1 > 11, "");
static_assert(!(42 > o1), "");
}
} }

View File

@@ -17,18 +17,17 @@
using std::optional; using std::optional;
struct X struct X {
{
int i_; int i_;
constexpr X(int i) : i_(i) {} constexpr X(int i) : i_(i) {}
}; };
constexpr bool operator >= ( const X &lhs, const X &rhs ) constexpr bool operator>=(const X& lhs, const X& rhs) {
{ return lhs.i_ >= rhs.i_ ; } return lhs.i_ >= rhs.i_;
}
int main() int main() {
{
{ {
typedef X T; typedef X T;
typedef optional<T> O; typedef optional<T> O;
@@ -52,4 +51,16 @@ int main()
static_assert((val >= o3), ""); // equal static_assert((val >= o3), ""); // equal
static_assert((T(3) >= o3), ""); static_assert((T(3) >= o3), "");
} }
{
using O = optional<int>;
constexpr O o1(42);
static_assert(o1 >= 42l, "");
static_assert(!(11l >= o1), "");
}
{
using O = optional<const int>;
constexpr O o1(42);
static_assert(o1 >= 42, "");
static_assert(!(11 >= o1), "");
}
} }

View File

@@ -17,18 +17,17 @@
using std::optional; using std::optional;
struct X struct X {
{
int i_; int i_;
constexpr X(int i) : i_(i) {} constexpr X(int i) : i_(i) {}
}; };
constexpr bool operator <= ( const X &lhs, const X &rhs ) constexpr bool operator<=(const X& lhs, const X& rhs) {
{ return lhs.i_ <= rhs.i_ ; } return lhs.i_ <= rhs.i_;
}
int main() int main() {
{
{ {
typedef X T; typedef X T;
typedef optional<T> O; typedef optional<T> O;
@@ -52,4 +51,16 @@ int main()
static_assert((val <= o3), ""); // equal static_assert((val <= o3), ""); // equal
static_assert(!(T(3) <= o3), ""); static_assert(!(T(3) <= o3), "");
} }
{
using O = optional<int>;
constexpr O o1(42);
static_assert(o1 <= 42l, "");
static_assert(!(101l <= o1), "");
}
{
using O = optional<const int>;
constexpr O o1(42);
static_assert(o1 <= 42, "");
static_assert(!(101 <= o1), "");
}
} }

View File

@@ -17,18 +17,15 @@
using std::optional; using std::optional;
struct X struct X {
{
int i_; int i_;
constexpr X(int i) : i_(i) {} constexpr X(int i) : i_(i) {}
}; };
constexpr bool operator < ( const X &lhs, const X &rhs ) constexpr bool operator<(const X& lhs, const X& rhs) { return lhs.i_ < rhs.i_; }
{ return lhs.i_ < rhs.i_ ; }
int main() int main() {
{
{ {
typedef X T; typedef X T;
typedef optional<T> O; typedef optional<T> O;
@@ -52,4 +49,16 @@ int main()
static_assert(!(val < o3), ""); // equal static_assert(!(val < o3), ""); // equal
static_assert(!(T(3) < o3), ""); static_assert(!(T(3) < o3), "");
} }
{
using O = optional<int>;
constexpr O o1(42);
static_assert(o1 < 101l, "");
static_assert(!(42l < o1), "");
}
{
using O = optional<const int>;
constexpr O o1(42);
static_assert(o1 < 101, "");
static_assert(!(42 < o1), "");
}
} }

View File

@@ -17,18 +17,17 @@
using std::optional; using std::optional;
struct X struct X {
{
int i_; int i_;
constexpr X(int i) : i_(i) {} constexpr X(int i) : i_(i) {}
}; };
constexpr bool operator != ( const X &lhs, const X &rhs ) constexpr bool operator!=(const X& lhs, const X& rhs) {
{ return lhs.i_ != rhs.i_ ; } return lhs.i_ != rhs.i_;
}
int main() int main() {
{
{ {
typedef X T; typedef X T;
typedef optional<T> O; typedef optional<T> O;
@@ -50,4 +49,16 @@ int main()
static_assert(!(T(2) != o3), ""); static_assert(!(T(2) != o3), "");
static_assert(!(val != o3), ""); static_assert(!(val != o3), "");
} }
{
using O = optional<int>;
constexpr O o1(42);
static_assert(o1 != 101l, "");
static_assert(!(42l != o1), "");
}
{
using O = optional<const int>;
constexpr O o1(42);
static_assert(o1 != 101, "");
static_assert(!(42 != o1), "");
}
} }

View File

@@ -18,18 +18,17 @@
using std::optional; using std::optional;
struct X struct X {
{
int i_; int i_;
constexpr X(int i) : i_(i) {} constexpr X(int i) : i_(i) {}
}; };
constexpr bool operator == ( const X &lhs, const X &rhs ) constexpr bool operator==(const X& lhs, const X& rhs) {
{ return lhs.i_ == rhs.i_ ; } return lhs.i_ == rhs.i_;
}
int main() int main() {
{
{ {
typedef X T; typedef X T;
typedef optional<T> O; typedef optional<T> O;
@@ -69,6 +68,19 @@ int main()
static_assert(o5 == o3, ""); static_assert(o5 == o3, "");
static_assert(!(o5 == o4), ""); static_assert(!(o5 == o4), "");
static_assert(o5 == o5, ""); static_assert(o5 == o5, "");
}
{
using O1 = optional<int>;
using O2 = optional<long>;
constexpr O1 o1(42);
static_assert(o1 == O2(42), "");
static_assert(!(O2(101) == o1), "");
}
{
using O1 = optional<int>;
using O2 = optional<const int>;
constexpr O1 o1(42);
static_assert(o1 == O2(42), "");
static_assert(!(O2(101) == o1), "");
} }
} }

View File

@@ -16,18 +16,17 @@
using std::optional; using std::optional;
struct X struct X {
{
int i_; int i_;
constexpr X(int i) : i_(i) {} constexpr X(int i) : i_(i) {}
}; };
constexpr bool operator >= ( const X &lhs, const X &rhs ) constexpr bool operator>=(const X& lhs, const X& rhs) {
{ return lhs.i_ >= rhs.i_ ; } return lhs.i_ >= rhs.i_;
}
int main() int main() {
{
{ {
typedef optional<X> O; typedef optional<X> O;
@@ -67,4 +66,18 @@ int main()
static_assert(!(o5 >= o4), ""); static_assert(!(o5 >= o4), "");
static_assert((o5 >= o5), ""); static_assert((o5 >= o5), "");
} }
{
using O1 = optional<int>;
using O2 = optional<long>;
constexpr O1 o1(42);
static_assert(o1 >= O2(42), "");
static_assert(!(O2(11) >= o1), "");
}
{
using O1 = optional<int>;
using O2 = optional<const int>;
constexpr O1 o1(42);
static_assert(o1 >= O2(42), "");
static_assert(!(O2(1) >= o1), "");
}
} }

View File

@@ -16,18 +16,15 @@
using std::optional; using std::optional;
struct X struct X {
{
int i_; int i_;
constexpr X(int i) : i_(i) {} constexpr X(int i) : i_(i) {}
}; };
constexpr bool operator > ( const X &lhs, const X &rhs ) constexpr bool operator>(const X& lhs, const X& rhs) { return lhs.i_ > rhs.i_; }
{ return lhs.i_ > rhs.i_ ; }
int main() int main() {
{
{ {
typedef optional<X> O; typedef optional<X> O;
@@ -67,4 +64,18 @@ int main()
static_assert(!(o5 > o4), ""); static_assert(!(o5 > o4), "");
static_assert(!(o5 > o5), ""); static_assert(!(o5 > o5), "");
} }
{
using O1 = optional<int>;
using O2 = optional<long>;
constexpr O1 o1(42);
static_assert(o1 > O2(1), "");
static_assert(!(O2(42) > o1), "");
}
{
using O1 = optional<int>;
using O2 = optional<const int>;
constexpr O1 o1(42);
static_assert(o1 > O2(1), "");
static_assert(!(O2(42) > o1), "");
}
} }

View File

@@ -16,18 +16,17 @@
using std::optional; using std::optional;
struct X struct X {
{
int i_; int i_;
constexpr X(int i) : i_(i) {} constexpr X(int i) : i_(i) {}
}; };
constexpr bool operator <= ( const X &lhs, const X &rhs ) constexpr bool operator<=(const X& lhs, const X& rhs) {
{ return lhs.i_ <= rhs.i_ ; } return lhs.i_ <= rhs.i_;
}
int main() int main() {
{
{ {
typedef optional<X> O; typedef optional<X> O;
@@ -67,4 +66,18 @@ int main()
static_assert((o5 <= o4), ""); static_assert((o5 <= o4), "");
static_assert((o5 <= o5), ""); static_assert((o5 <= o5), "");
} }
{
using O1 = optional<int>;
using O2 = optional<long>;
constexpr O1 o1(42);
static_assert(o1 <= O2(42), "");
static_assert(!(O2(101) <= o1), "");
}
{
using O1 = optional<int>;
using O2 = optional<const int>;
constexpr O1 o1(42);
static_assert(o1 <= O2(42), "");
static_assert(!(O2(101) <= o1), "");
}
} }

View File

@@ -16,18 +16,15 @@
using std::optional; using std::optional;
struct X struct X {
{
int i_; int i_;
constexpr X(int i) : i_(i) {} constexpr X(int i) : i_(i) {}
}; };
constexpr bool operator < ( const X &lhs, const X &rhs ) constexpr bool operator<(const X& lhs, const X& rhs) { return lhs.i_ < rhs.i_; }
{ return lhs.i_ < rhs.i_ ; }
int main() int main() {
{
{ {
typedef optional<X> O; typedef optional<X> O;
@@ -67,4 +64,18 @@ int main()
static_assert((o5 < o4), ""); static_assert((o5 < o4), "");
static_assert(!(o5 < o5), ""); static_assert(!(o5 < o5), "");
} }
{
using O1 = optional<int>;
using O2 = optional<long>;
constexpr O1 o1(42);
static_assert(o1 < O2(101), "");
static_assert(!(O2(101) < o1), "");
}
{
using O1 = optional<int>;
using O2 = optional<const int>;
constexpr O1 o1(42);
static_assert(o1 < O2(101), "");
static_assert(!(O2(101) < o1), "");
}
} }

View File

@@ -18,18 +18,17 @@
using std::optional; using std::optional;
struct X struct X {
{
int i_; int i_;
constexpr X(int i) : i_(i) {} constexpr X(int i) : i_(i) {}
}; };
constexpr bool operator != ( const X &lhs, const X &rhs ) constexpr bool operator!=(const X& lhs, const X& rhs) {
{ return lhs.i_ != rhs.i_ ; } return lhs.i_ != rhs.i_;
}
int main() int main() {
{
{ {
typedef X T; typedef X T;
typedef optional<T> O; typedef optional<T> O;
@@ -69,6 +68,19 @@ int main()
static_assert(!(o5 != o3), ""); static_assert(!(o5 != o3), "");
static_assert((o5 != o4), ""); static_assert((o5 != o4), "");
static_assert(!(o5 != o5), ""); static_assert(!(o5 != o5), "");
}
{
using O1 = optional<int>;
using O2 = optional<long>;
constexpr O1 o1(42);
static_assert(o1 != O2(101), "");
static_assert(!(O2(42) != o1), "");
}
{
using O1 = optional<int>;
using O2 = optional<const int>;
constexpr O1 o1(42);
static_assert(o1 != O2(101), "");
static_assert(!(O2(42) != o1), "");
} }
} }

View File

@@ -482,7 +482,7 @@
<tr><td><a href="http://wg21.link/LWG2908">2908</a></td><td>The less-than operator for shared pointers could do more</td><td>Kona</td><td></td></tr> <tr><td><a href="http://wg21.link/LWG2908">2908</a></td><td>The less-than operator for shared pointers could do more</td><td>Kona</td><td></td></tr>
<tr><td><a href="http://wg21.link/LWG2911">2911</a></td><td>An is_aggregate type trait is needed</td><td>Kona</td><td></td></tr> <tr><td><a href="http://wg21.link/LWG2911">2911</a></td><td>An is_aggregate type trait is needed</td><td>Kona</td><td></td></tr>
<tr><td><a href="http://wg21.link/LWG2921">2921</a></td><td>packaged_task and type-erased allocators</td><td>Kona</td><td></td></tr> <tr><td><a href="http://wg21.link/LWG2921">2921</a></td><td>packaged_task and type-erased allocators</td><td>Kona</td><td></td></tr>
<tr><td><a href="http://wg21.link/LWG2934">2934</a></td><td>optional&lt;const T&gt; doesn't compare with T</td><td>Kona</td><td></td></tr> <tr><td><a href="http://wg21.link/LWG2934">2934</a></td><td>optional&lt;const T&gt; doesn't compare with T</td><td>Kona</td><td>Complete</td></tr>
<!-- <!--
<tr><td><a href="http://wg21.link/LWG1214">1214</a></td><td>Insufficient/inconsistent key immutability requirements for associative containers</td><td>Urbana</td><td></td></tr> <tr><td><a href="http://wg21.link/LWG1214">1214</a></td><td>Insufficient/inconsistent key immutability requirements for associative containers</td><td>Urbana</td><td></td></tr>
--> -->