From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 107012 invoked by alias); 6 Feb 2020 13:41:00 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 106889 invoked by uid 89); 6 Feb 2020 13:40:59 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-17.9 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_SHORT,RCVD_IN_DNSWL_NONE autolearn=unavailable version=3.3.1 spammy= X-HELO: us-smtp-delivery-1.mimecast.com Received: from us-smtp-2.mimecast.com (HELO us-smtp-delivery-1.mimecast.com) (207.211.31.81) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 06 Feb 2020 13:40:56 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1580996455; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type; bh=fdKaqCVEoVymAquev5hxWKa/59zfF7xOetwcMXL2r9U=; b=ZXUKHYMNnVK7S3GzQpDw9+hblrGcUwckiiQQMRhNOT8AdopKqMjFLfHP0WkolP+wJ77Mnp gRTlb87SXJIv+p91trGmn3qTkdQBbyL2LTrHxNDghPlhuSjzfaZ0WyZDPIb7maNPHgyd/X 1E8es0pOur8eU5K4jlcM6QG8SdPVtSE= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-363-L9SYZNt1NqynYf4iThQyNg-1; Thu, 06 Feb 2020 08:40:50 -0500 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id D50E3102CE14; Thu, 6 Feb 2020 13:40:49 +0000 (UTC) Received: from localhost (unknown [10.33.36.45]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5C8C260BEC; Thu, 6 Feb 2020 13:40:49 +0000 (UTC) Date: Thu, 06 Feb 2020 13:41:00 -0000 From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [PATCH] libstdc++: Optimize C++20 comparison category types Message-ID: <20200206134048.GA946321@redhat.com> MIME-Version: 1.0 X-Clacks-Overhead: GNU Terry Pratchett X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: multipart/mixed; boundary="vtzGhvizbBRQ85DL" Content-Disposition: inline X-SW-Source: 2020-02/txt/msg00359.txt.bz2 --vtzGhvizbBRQ85DL Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Content-length: 1294 This reduces sizeof(std::partial_ordering) and optimizes conversion and comparison operators to avoid conditional branches where possible. * libsupc++/compare (__cmp_cat::_Ncmp::unordered): Change value to 2. (partial_ordering::_M_is_ordered): Remove data member. (partial_ordering): Use second bit of _M_value for unordered. Adjust comparison operators. (weak_ordering::operator partial_ordering): Simplify to remove branches. (operator<=3D>(unspecified, weak_ordering)): Likewise. (strong_ordering::operator partial_ordering): Likewise. (strong_ordering::operator weak_ordering): Likewise. (operator<=3D>(unspecified, strong_ordering)): Likewise. * testsuite/18_support/comparisons/categories/partialord.cc: New test. * testsuite/18_support/comparisons/categories/strongord.cc: New test. * testsuite/18_support/comparisons/categories/weakord.cc: New test. Tested powerpc64le-linux and x86_64-linux. This is an ABI change for the partial_ordering type, but that is why I think we should do it now, not after GCC 10 is released. The sooner the better, before these types are being widely used. I plan to commit this in the next 12 hours or so, unless there are (valid :-) objections. Thanks to Barry Revzin for pointing out there was room for these operators to be improved. --vtzGhvizbBRQ85DL Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="patch.txt" Content-Transfer-Encoding: quoted-printable Content-length: 21619 commit 556a60b573cd599d44f7dae3dccafb9d0694f088 Author: Jonathan Wakely Date: Thu Feb 6 13:31:36 2020 +0000 libstdc++: Optimize C++20 comparison category types =20=20=20=20 This reduces sizeof(std::partial_ordering) and optimizes conversion and comparison operators to avoid conditional branches where possible. =20=20=20=20 * libsupc++/compare (__cmp_cat::_Ncmp::unordered): Change value= to 2. (partial_ordering::_M_is_ordered): Remove data member. (partial_ordering): Use second bit of _M_value for unordered. A= djust comparison operators. (weak_ordering::operator partial_ordering): Simplify to remove branches. (operator<=3D>(unspecified, weak_ordering)): Likewise. (strong_ordering::operator partial_ordering): Likewise. (strong_ordering::operator weak_ordering): Likewise. (operator<=3D>(unspecified, strong_ordering)): Likewise. * testsuite/18_support/comparisons/categories/partialord.cc: Ne= w test. * testsuite/18_support/comparisons/categories/strongord.cc: New= test. * testsuite/18_support/comparisons/categories/weakord.cc: New t= est. diff --git a/libstdc++-v3/libsupc++/compare b/libstdc++-v3/libsupc++/compare index a7a29ef0440..8ac446a9bc5 100644 --- a/libstdc++-v3/libsupc++/compare +++ b/libstdc++-v3/libsupc++/compare @@ -50,7 +50,7 @@ namespace std { enum class _Ord { equivalent =3D 0, less =3D -1, greater =3D 1 }; =20 - enum class _Ncmp { _Unordered =3D -127 }; + enum class _Ncmp { _Unordered =3D 2 }; =20 struct __unspec { @@ -61,18 +61,20 @@ namespace std class partial_ordering { int _M_value; - bool _M_is_ordered; =20 constexpr explicit partial_ordering(__cmp_cat::_Ord __v) noexcept - : _M_value(int(__v)), _M_is_ordered(true) + : _M_value(int(__v)) { } =20 constexpr explicit partial_ordering(__cmp_cat::_Ncmp __v) noexcept - : _M_value(int(__v)), _M_is_ordered(false) + : _M_value(int(__v)) { } =20 + friend class weak_ordering; + friend class strong_ordering; + public: // valid values static const partial_ordering less; @@ -83,42 +85,42 @@ namespace std // comparisons friend constexpr bool operator=3D=3D(partial_ordering __v, __cmp_cat::__unspec) noexcept - { return __v._M_is_ordered && __v._M_value =3D=3D 0; } + { return __v._M_value =3D=3D 0; } =20 friend constexpr bool operator=3D=3D(partial_ordering, partial_ordering) noexcept =3D defaul= t; =20 friend constexpr bool operator< (partial_ordering __v, __cmp_cat::__unspec) noexcept - { return __v._M_is_ordered && __v._M_value < 0; } + { return __v._M_value =3D=3D -1; } =20 friend constexpr bool operator> (partial_ordering __v, __cmp_cat::__unspec) noexcept - { return __v._M_is_ordered && __v._M_value > 0; } + { return __v._M_value =3D=3D 1; } =20 friend constexpr bool operator<=3D(partial_ordering __v, __cmp_cat::__unspec) noexcept - { return __v._M_is_ordered && __v._M_value <=3D 0; } + { return __v._M_value <=3D 0; } =20 friend constexpr bool operator>=3D(partial_ordering __v, __cmp_cat::__unspec) noexcept - { return __v._M_is_ordered && __v._M_value >=3D 0; } + { return (__v._M_value & 1) =3D=3D __v._M_value; } =20 friend constexpr bool operator< (__cmp_cat::__unspec, partial_ordering __v) noexcept - { return __v._M_is_ordered && 0 < __v._M_value; } + { return __v._M_value =3D=3D 1; } =20 friend constexpr bool operator> (__cmp_cat::__unspec, partial_ordering __v) noexcept - { return __v._M_is_ordered && 0 > __v._M_value; } + { return __v._M_value =3D=3D -1; } =20 friend constexpr bool operator<=3D(__cmp_cat::__unspec, partial_ordering __v) noexcept - { return __v._M_is_ordered && 0 <=3D __v._M_value; } + { return (__v._M_value & 1) =3D=3D __v._M_value; } =20 friend constexpr bool operator>=3D(__cmp_cat::__unspec, partial_ordering __v) noexcept - { return __v._M_is_ordered && 0 >=3D __v._M_value; } + { return 0 >=3D __v._M_value; } =20 friend constexpr partial_ordering operator<=3D>(partial_ordering __v, __cmp_cat::__unspec) noexcept @@ -127,10 +129,8 @@ namespace std friend constexpr partial_ordering operator<=3D>(__cmp_cat::__unspec, partial_ordering __v) noexcept { - if (__v < 0) - return partial_ordering::greater; - else if (__v > 0) - return partial_ordering::less; + if (__v._M_value & 1) + return partial_ordering(__cmp_cat::_Ord(-__v._M_value)); else return __v; } @@ -157,6 +157,8 @@ namespace std weak_ordering(__cmp_cat::_Ord __v) noexcept : _M_value(int(__v)) { } =20 + friend class strong_ordering; + public: // valid values static const weak_ordering less; @@ -164,14 +166,7 @@ namespace std static const weak_ordering greater; =20 constexpr operator partial_ordering() const noexcept - { - if (_M_value =3D=3D 0) - return partial_ordering::equivalent; - else if (_M_value < 0) - return partial_ordering::less; - else - return partial_ordering::greater; - } + { return partial_ordering(__cmp_cat::_Ord(_M_value)); } =20 // comparisons friend constexpr bool @@ -219,14 +214,7 @@ namespace std =20 friend constexpr weak_ordering operator<=3D>(__cmp_cat::__unspec, weak_ordering __v) noexcept - { - if (__v < 0) - return weak_ordering::greater; - else if (__v > 0) - return weak_ordering::less; - else - return __v; - } + { return weak_ordering(__cmp_cat::_Ord(-__v._M_value)); } }; =20 // valid values' definitions @@ -256,24 +244,10 @@ namespace std static const strong_ordering greater; =20 constexpr operator partial_ordering() const noexcept - { - if (_M_value =3D=3D 0) - return partial_ordering::equivalent; - else if (_M_value < 0) - return partial_ordering::less; - else - return partial_ordering::greater; - } + { return partial_ordering(__cmp_cat::_Ord(_M_value)); } =20 constexpr operator weak_ordering() const noexcept - { - if (_M_value =3D=3D 0) - return weak_ordering::equivalent; - else if (_M_value < 0) - return weak_ordering::less; - else - return weak_ordering::greater; - } + { return weak_ordering(__cmp_cat::_Ord(_M_value)); } =20 // comparisons friend constexpr bool @@ -321,14 +295,7 @@ namespace std =20 friend constexpr strong_ordering operator<=3D>(__cmp_cat::__unspec, strong_ordering __v) noexcept - { - if (__v < 0) - return strong_ordering::greater; - else if (__v > 0) - return strong_ordering::less; - else - return __v; - } + { return strong_ordering(__cmp_cat::_Ord(-__v._M_value)); } }; =20 // valid values' definitions diff --git a/libstdc++-v3/testsuite/18_support/comparisons/categories/parti= alord.cc b/libstdc++-v3/testsuite/18_support/comparisons/categories/partial= ord.cc new file mode 100644 index 00000000000..01db2ca055e --- /dev/null +++ b/libstdc++-v3/testsuite/18_support/comparisons/categories/partialord.cc @@ -0,0 +1,86 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-std=3Dgnu++2a" } +// { dg-do compile { target c++2a } } + +#include + +using std::partial_ordering; + +static_assert( partial_ordering::less =3D=3D partial_ordering::less ); +static_assert( partial_ordering::less !=3D partial_ordering::equivalent ); +static_assert( partial_ordering::less !=3D partial_ordering::greater ); +static_assert( partial_ordering::less !=3D partial_ordering::unordered ); +static_assert( partial_ordering::equivalent =3D=3D partial_ordering::equiv= alent ); +static_assert( partial_ordering::equivalent !=3D partial_ordering::greater= ); +static_assert( partial_ordering::equivalent !=3D partial_ordering::unorder= ed ); +static_assert( partial_ordering::greater =3D=3D partial_ordering::greater = ); +static_assert( partial_ordering::greater !=3D partial_ordering::unordered = ); +static_assert( partial_ordering::unordered =3D=3D partial_ordering::unorde= red ); + +static_assert( ! (partial_ordering::less =3D=3D 0) ); +static_assert( partial_ordering::less < 0 ); +static_assert( ! (partial_ordering::less > 0) ); +static_assert( partial_ordering::less <=3D 0 ); +static_assert( ! (partial_ordering::less >=3D 0) ); +static_assert( ! (0 =3D=3D partial_ordering::less) ); +static_assert( ! (0 < partial_ordering::less) ); +static_assert( 0 > partial_ordering::less ); +static_assert( ! (0 <=3D partial_ordering::less) ); +static_assert( 0 >=3D partial_ordering::less ); +static_assert( (partial_ordering::less <=3D> 0) =3D=3D partial_ordering::l= ess ); +static_assert( (0 <=3D> partial_ordering::less) =3D=3D partial_ordering::g= reater ); + +static_assert( (partial_ordering::equivalent =3D=3D 0) ); +static_assert( ! (partial_ordering::equivalent < 0) ); +static_assert( ! (partial_ordering::equivalent > 0) ); +static_assert( partial_ordering::equivalent <=3D 0 ); +static_assert( partial_ordering::equivalent >=3D 0 ); +static_assert( 0 =3D=3D partial_ordering::equivalent ); +static_assert( ! (0 < partial_ordering::equivalent) ); +static_assert( ! (0 > partial_ordering::equivalent) ); +static_assert( 0 <=3D partial_ordering::equivalent ); +static_assert( 0 >=3D partial_ordering::equivalent ); +static_assert( (partial_ordering::equivalent <=3D> 0) =3D=3D partial_order= ing::equivalent ); +static_assert( (0 <=3D> partial_ordering::equivalent) =3D=3D partial_order= ing::equivalent ); + +static_assert( ! (partial_ordering::greater =3D=3D 0) ); +static_assert( ! (partial_ordering::greater < 0) ); +static_assert( partial_ordering::greater > 0 ); +static_assert( ! (partial_ordering::greater <=3D 0) ); +static_assert( partial_ordering::greater >=3D 0 ); +static_assert( ! (0 =3D=3D partial_ordering::greater) ); +static_assert( 0 < partial_ordering::greater ); +static_assert( ! (0 > partial_ordering::greater) ); +static_assert( 0 <=3D partial_ordering::greater ); +static_assert( ! (0 >=3D partial_ordering::greater) ); +static_assert( (partial_ordering::greater <=3D> 0) =3D=3D partial_ordering= ::greater ); +static_assert( (0 <=3D> partial_ordering::greater) =3D=3D partial_ordering= ::less ); + +static_assert( ! (partial_ordering::unordered =3D=3D 0) ); +static_assert( ! (partial_ordering::unordered < 0) ); +static_assert( ! (partial_ordering::unordered > 0) ); +static_assert( ! (partial_ordering::unordered <=3D 0) ); +static_assert( ! (partial_ordering::unordered >=3D 0) ); +static_assert( ! (0 =3D=3D partial_ordering::unordered) ); +static_assert( ! (0 < partial_ordering::unordered) ); +static_assert( ! (0 > partial_ordering::unordered) ); +static_assert( ! (0 <=3D partial_ordering::unordered) ); +static_assert( ! (0 >=3D partial_ordering::unordered) ); +static_assert( (partial_ordering::unordered <=3D> 0) =3D=3D partial_orderi= ng::unordered ); +static_assert( (0 <=3D> partial_ordering::unordered) =3D=3D partial_orderi= ng::unordered ); diff --git a/libstdc++-v3/testsuite/18_support/comparisons/categories/stron= gord.cc b/libstdc++-v3/testsuite/18_support/comparisons/categories/strongor= d.cc new file mode 100644 index 00000000000..0485e5a1463 --- /dev/null +++ b/libstdc++-v3/testsuite/18_support/comparisons/categories/strongord.cc @@ -0,0 +1,98 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-std=3Dgnu++2a" } +// { dg-do compile { target c++2a } } + +#include + +using std::strong_ordering; + +static_assert( strong_ordering::less =3D=3D strong_ordering::less ); +static_assert( strong_ordering::less !=3D strong_ordering::equal ); +static_assert( strong_ordering::less !=3D strong_ordering::equivalent ); +static_assert( strong_ordering::less !=3D strong_ordering::greater ); +static_assert( strong_ordering::equivalent =3D=3D strong_ordering::equival= ent ); +static_assert( strong_ordering::equivalent =3D=3D strong_ordering::equal ); +static_assert( strong_ordering::equivalent !=3D strong_ordering::greater ); +static_assert( strong_ordering::equal =3D=3D strong_ordering::equal ); +static_assert( strong_ordering::equal !=3D strong_ordering::greater ); +static_assert( strong_ordering::greater =3D=3D strong_ordering::greater ); + +static_assert( ! (strong_ordering::less =3D=3D 0) ); +static_assert( strong_ordering::less < 0 ); +static_assert( ! (strong_ordering::less > 0) ); +static_assert( strong_ordering::less <=3D 0 ); +static_assert( ! (strong_ordering::less >=3D 0) ); +static_assert( ! (0 =3D=3D strong_ordering::less) ); +static_assert( ! (0 < strong_ordering::less) ); +static_assert( 0 > strong_ordering::less ); +static_assert( ! (0 <=3D strong_ordering::less) ); +static_assert( 0 >=3D strong_ordering::less ); +static_assert( (strong_ordering::less <=3D> 0) =3D=3D strong_ordering::les= s ); +static_assert( (0 <=3D> strong_ordering::less) =3D=3D strong_ordering::gre= ater ); + +static_assert( (strong_ordering::equal =3D=3D 0) ); +static_assert( ! (strong_ordering::equal < 0) ); +static_assert( ! (strong_ordering::equal > 0) ); +static_assert( strong_ordering::equal <=3D 0 ); +static_assert( strong_ordering::equal >=3D 0 ); +static_assert( 0 =3D=3D strong_ordering::equal ); +static_assert( ! (0 < strong_ordering::equal) ); +static_assert( ! (0 > strong_ordering::equal) ); +static_assert( 0 <=3D strong_ordering::equal ); +static_assert( 0 >=3D strong_ordering::equal ); +static_assert( (strong_ordering::equal <=3D> 0) =3D=3D strong_ordering::eq= ual ); +static_assert( (0 <=3D> strong_ordering::equal) =3D=3D strong_ordering::eq= ual ); + +static_assert( (strong_ordering::equivalent =3D=3D 0) ); +static_assert( ! (strong_ordering::equivalent < 0) ); +static_assert( ! (strong_ordering::equivalent > 0) ); +static_assert( strong_ordering::equivalent <=3D 0 ); +static_assert( strong_ordering::equivalent >=3D 0 ); +static_assert( 0 =3D=3D strong_ordering::equivalent ); +static_assert( ! (0 < strong_ordering::equivalent) ); +static_assert( ! (0 > strong_ordering::equivalent) ); +static_assert( 0 <=3D strong_ordering::equivalent ); +static_assert( 0 >=3D strong_ordering::equivalent ); +static_assert( (strong_ordering::equivalent <=3D> 0) =3D=3D strong_orderin= g::equivalent ); +static_assert( (0 <=3D> strong_ordering::equivalent) =3D=3D strong_orderin= g::equivalent ); + +static_assert( ! (strong_ordering::greater =3D=3D 0) ); +static_assert( ! (strong_ordering::greater < 0) ); +static_assert( strong_ordering::greater > 0 ); +static_assert( ! (strong_ordering::greater <=3D 0) ); +static_assert( strong_ordering::greater >=3D 0 ); +static_assert( ! (0 =3D=3D strong_ordering::greater) ); +static_assert( 0 < strong_ordering::greater ); +static_assert( ! (0 > strong_ordering::greater) ); +static_assert( 0 <=3D strong_ordering::greater ); +static_assert( ! (0 >=3D strong_ordering::greater) ); +static_assert( (strong_ordering::greater <=3D> 0) =3D=3D strong_ordering::= greater ); +static_assert( (0 <=3D> strong_ordering::greater) =3D=3D strong_ordering::= less ); + +// Conversions +using std::partial_ordering; +static_assert( partial_ordering(strong_ordering::less) =3D=3D partial_orde= ring::less ); +static_assert( partial_ordering(strong_ordering::equal) =3D=3D partial_ord= ering::equivalent ); +static_assert( partial_ordering(strong_ordering::equivalent) =3D=3D partia= l_ordering::equivalent ); +static_assert( partial_ordering(strong_ordering::greater) =3D=3D partial_o= rdering::greater ); +using std::weak_ordering; +static_assert( weak_ordering(strong_ordering::less) =3D=3D weak_ordering::= less ); +static_assert( partial_ordering(strong_ordering::equal) =3D=3D weak_orderi= ng::equivalent ); +static_assert( partial_ordering(strong_ordering::equivalent) =3D=3D weak_o= rdering::equivalent ); +static_assert( weak_ordering(strong_ordering::greater) =3D=3D weak_orderin= g::greater ); diff --git a/libstdc++-v3/testsuite/18_support/comparisons/categories/weako= rd.cc b/libstdc++-v3/testsuite/18_support/comparisons/categories/weakord.cc new file mode 100644 index 00000000000..0720e1f86af --- /dev/null +++ b/libstdc++-v3/testsuite/18_support/comparisons/categories/weakord.cc @@ -0,0 +1,75 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-std=3Dgnu++2a" } +// { dg-do compile { target c++2a } } + +#include + +using std::weak_ordering; + +static_assert( weak_ordering::less =3D=3D weak_ordering::less ); +static_assert( weak_ordering::less !=3D weak_ordering::equivalent ); +static_assert( weak_ordering::less !=3D weak_ordering::greater ); +static_assert( weak_ordering::equivalent =3D=3D weak_ordering::equivalent = ); +static_assert( weak_ordering::equivalent !=3D weak_ordering::greater ); +static_assert( weak_ordering::greater =3D=3D weak_ordering::greater ); + +static_assert( ! (weak_ordering::less =3D=3D 0) ); +static_assert( weak_ordering::less < 0 ); +static_assert( ! (weak_ordering::less > 0) ); +static_assert( weak_ordering::less <=3D 0 ); +static_assert( ! (weak_ordering::less >=3D 0) ); +static_assert( ! (0 =3D=3D weak_ordering::less) ); +static_assert( ! (0 < weak_ordering::less) ); +static_assert( 0 > weak_ordering::less ); +static_assert( ! (0 <=3D weak_ordering::less) ); +static_assert( 0 >=3D weak_ordering::less ); +static_assert( (weak_ordering::less <=3D> 0) =3D=3D weak_ordering::less ); +static_assert( (0 <=3D> weak_ordering::less) =3D=3D weak_ordering::greater= ); + +static_assert( (weak_ordering::equivalent =3D=3D 0) ); +static_assert( ! (weak_ordering::equivalent < 0) ); +static_assert( ! (weak_ordering::equivalent > 0) ); +static_assert( weak_ordering::equivalent <=3D 0 ); +static_assert( weak_ordering::equivalent >=3D 0 ); +static_assert( 0 =3D=3D weak_ordering::equivalent ); +static_assert( ! (0 < weak_ordering::equivalent) ); +static_assert( ! (0 > weak_ordering::equivalent) ); +static_assert( 0 <=3D weak_ordering::equivalent ); +static_assert( 0 >=3D weak_ordering::equivalent ); +static_assert( (weak_ordering::equivalent <=3D> 0) =3D=3D weak_ordering::e= quivalent ); +static_assert( (0 <=3D> weak_ordering::equivalent) =3D=3D weak_ordering::e= quivalent ); + +static_assert( ! (weak_ordering::greater =3D=3D 0) ); +static_assert( ! (weak_ordering::greater < 0) ); +static_assert( weak_ordering::greater > 0 ); +static_assert( ! (weak_ordering::greater <=3D 0) ); +static_assert( weak_ordering::greater >=3D 0 ); +static_assert( ! (0 =3D=3D weak_ordering::greater) ); +static_assert( 0 < weak_ordering::greater ); +static_assert( ! (0 > weak_ordering::greater) ); +static_assert( 0 <=3D weak_ordering::greater ); +static_assert( ! (0 >=3D weak_ordering::greater) ); +static_assert( (weak_ordering::greater <=3D> 0) =3D=3D weak_ordering::grea= ter ); +static_assert( (0 <=3D> weak_ordering::greater) =3D=3D weak_ordering::less= ); + +// Conversions +using std::partial_ordering; +static_assert( partial_ordering(weak_ordering::less) =3D=3D partial_orderi= ng::less ); +static_assert( partial_ordering(weak_ordering::equivalent) =3D=3D partial_= ordering::equivalent ); +static_assert( partial_ordering(weak_ordering::greater) =3D=3D partial_ord= ering::greater ); --vtzGhvizbBRQ85DL--