Jon pointed out that we have TODO: _Bfloat16 in <compare>.
Right now _S_fp_fmt() returns _Binary16 for _Float16, __fp16 as well
as __bf16 and it actually works because we don't have a special handling
of _Binary16. So, either we could just document that, but I'm a little bit
afraid if HPPA or MIPS don't start supporting _Float16 and/or __bf16.
If they do, we have the
#if defined __hppa__ || (defined __mips__ && !defined __mips_nan2008)
// IEEE 754-1985 allowed the meaning of the quiet/signaling
// bit to be reversed. Flip that to give desired ordering.
if (__builtin_isnan(__x) && __builtin_isnan(__y))
{
using _Int = decltype(__ix);
constexpr int __nantype = __fmt == _Binary32 ? 22
: __fmt == _Binary64 ? 51
: __fmt == _Binary128 ? 111
: -1;
constexpr _Int __bit = _Int(1) << __nantype;
__ix ^= __bit;
__iy ^= __bit;
}
#endif
code, the only one where we actually care whether something is
_Binary{32,64,128} (elsewhere we just care about the x86 and m68k 80bits
or double double or just floating point type's sizeof) and we'd need
to handle there _Binary16 and/or _Bfloat16.
So this patch uses different enum for it even when it isn't needed right
now, after all _Binary16 isn't needed either and we could just use
_Binary32...
2022-11-02 Jakub Jelinek <jakub@redhat.com>
* libsupc++/compare (_Strong_order::_Fp_fmt): Add _Bfloat16.
(_Strong_order::_Bfloat16): New static data member.
(_Strong_order::_S_fp_fmt): Return _Bfloat16 for std::bfloat16_t.
Once we no longer care about older compilers without this feature, we
can drop these static data members, so the names don't have to be
visible at class scope.
libstdc++-v3/ChangeLog:
* libsupc++/compare (_Strong_order) [!__cpp_using_enum]: Add
static data members for _Fp_fmt enumerators.
I mistakenly believed that VAX floats do not support NaN, but with GCC
__builtin_isnan(__builtin_nan("")) is true. That means my previous
change to <compare> is wrong, because it fails to handle NaN.
When std::numeric_limits<floating-point-type>::is_iec559 is false, as on
VAX, the standard only requires an ordering that is consistent with the
ordering observed by comparison operators. With this change the ordering
is -NaN < numbers < +NaN, and there is no support for different NaN bit
patterns (as I'm not even sure if GCC supports any for VAX).
libstdc++-v3/ChangeLog:
* libsupc++/compare (_Strong_order::_S_fp_cmp) [__vax__]:
Handle NaN.
The VAX float and double format does not support NaN, so the
std::partial_ordering returned by <=> will never be 'unordered'. We can
just use the partial_ordering value as the strong_ordering.
libstdc++-v3/ChangeLog:
* libsupc++/compare (_Strong_ordering::_S_fp_cmp) [__vax__]: Use
<=> comparison.
This removes a FIXME in <compare>, defining the total order for
floating-point types. I originally opened PR96526 to request a new
compiler built-in to implement this, but now that we have std::bit_cast
it can be done entirely in the library.
The implementation is based on the glibc definitions of totalorder,
totalorderf, totalorderl etc.
I think this works for all the types that satisfy std::floating_point
today, and should also work for the types expected to be added by P1467
except for std::bfloat16_t. It also supports some additional types that
don't currently satisfy std::floating_point, such as __float80, but we
probably do want that to satisfy the concept for non-strict modes.
libstdc++-v3/ChangeLog:
PR libstdc++/96526
* libsupc++/compare (strong_order): Add missing support for
floating-point types.
* testsuite/18_support/comparisons/algorithms/strong_order_floats.cc:
New test.
This adds std::__is_constant_evaluated() as a C++11 wrapper for
__builtin_is_constant_evaluated, but just returning false if the
built-in isn't supported by the compiler. This allows us to use it
throughout the library without checking __has_builtin every time.
Some uses in std::vector and std::string can only be constexpr when the
std::is_constant_evaluated() function actually works, so we might as
well guard them with a relevant macro and call that function directly,
rather than the built-in or std::__is_constant_evaluated().
The remaining checks of the __cpp_lib_is_constant_evaluated macro could
now be replaced by checking __cplusplus >= 202002 instead, but there's
no practical difference. We still need some kind of preprocessor check
there anyway.
libstdc++-v3/ChangeLog:
* doc/doxygen/user.cfg.in (PREDEFINED): Change macro name.
* include/bits/allocator.h (allocate, deallocate): Use
std::__is_constant_evaluated() unconditionally, instead of
checking whether std::is_constant_evaluated() (or the built-in)
can be used.
* include/bits/basic_string.h: Check new macro. call
std::is_constant_evaluated() directly in C++20-only code that is
guarded by a suitable macro.
* include/bits/basic_string.tcc: Likewise.
* include/bits/c++config (__is_constant_evaluated): Define.
(_GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED): Replace with ...
(_GLIBCXX_HAVE_IS_CONSTANT_EVALUATED): New macro.
* include/bits/char_traits.h (char_traits): Replace conditional
calls to std::is_constant_evaluated with unconditional calls to
std::__is_constant_evaluated.
* include/bits/cow_string.h: Use new macro.
* include/bits/ranges_algobase.h (__copy_or_move): Replace
conditional calls to std::is_constant_evaluated with unconditional
calls to std::__is_constant_evaluated.
(__copy_or_move_backward, __fill_n_fn): Likewise.
* include/bits/ranges_cmp.h (ranges::less): Likewise.
* include/bits/stl_algobase.h (lexicographical_compare_three_way):
Likewise.
* include/bits/stl_bvector.h: Call std::is_constant_evaluated
directly in C++20-only code that is guarded by a suitable macro.
* include/bits/stl_construct.h (_Construct, _Destroy, _Destroy_n):
Replace is_constant_evaluated with __is_constant_evaluated.
* include/bits/stl_function.h (greater, less, greater_equal)
(less_equal): Replace __builtin_is_constant_evaluated and
__builtin_constant_p with __is_constant_evaluated.
* include/bits/stl_vector.h: Call std::is_constant_evaluated()
in C++20-only code.
* include/debug/helper_functions.h (__check_singular): Use
__is_constant_evaluated instead of built-in, or remove check
entirely.
* include/std/array (operator<=>): Use __is_constant_evaluated
unconditionally.
* include/std/bit (__bit_ceil): Likewise.
* include/std/type_traits (is_constant_evaluated): Define using
'if consteval' if possible.
* include/std/version: Use new macro.
* libsupc++/compare: Use __is_constant_evaluated instead of
__builtin_is_constant_evaluated.
* testsuite/23_containers/array/tuple_interface/get_neg.cc:
Adjust dg-error lines.
This adds the [[nodiscard]] attribute to all conversion operators,
comparison operators, call operators and non-member functions in
<compare>. Nothing in this header except constructors has side effects.
Signed-off-by: Jonathan Wakely <jwakely@redhat.com>
libstdc++-v3/ChangeLog:
* libsupc++/compare (partial_ordering, weak_ordering)
(strong_ordering, is_eq, is_neq, is_lt, is_lteq, is_gt, is_gteq)
(compare_three_way, strong_order, weak_order, partial_order)
(compare_strong_order_fallback, compare_weak_order_fallback)
(compare_partial_order_fallback, __detail::__synth3way): Add
nodiscard attribute.
* testsuite/18_support/comparisons/categories/zero_neg.cc: Add
-Wno-unused-result to options.
This moves the same_as<decay_t<_Tp>, decay_t<_Up>> checks from the
[cmp.alg] function bodies into their constraints.
Also add a test for the compare_xxx_order_fallback algorithms.
libstdc++-v3/ChangeLog:
* libsupc++/compare (__decayed_same_as): New helper concept.
(strong_order, weak_order, partial_order): Constrain with new
concept instead of using static_assert.
(compare_strong_order_fallback, compare_weak_order_fallback)
(compare_partial_order_fallback): Likewise. Do not deduce return
types. Remove redundant if-constexpr checks.
* testsuite/18_support/comparisons/algorithms/fallback.cc: New test.
The proposed resolution for this library issue simplifies the
constraints for compare_three_way, ranges::equal_to, ranges::less etc.
so that they do not work with types which are convertible to pointers
but which fail to meet the usual syntactic requirements for the
comparisons.
This affects the example in PR libstdc++/93628 but doesn't fix the
problem described in that report.
libstdc++-v3/ChangeLog:
* include/bits/ranges_cmp.h (__eq_builtin_ptr_cmp): Remove.
(ranges::equal_to, ranges::not_equal_to): Do not constrain
with __eq_builtin_ptr_cmp.
(ranges::less, ranges::greater, ranges::less_equal)
(ranges::greater_equal): Do not constrain with
__less_builtin_ptr_cmp.
* libsupc++/compare (compare_three_way): Do not constrain with
__3way_builtin_ptr_cmp.
* testsuite/18_support/comparisons/object/builtin-ptr-three-way.cc: Moved to...
* testsuite/18_support/comparisons/object/lwg3530.cc: ...here.
* testsuite/20_util/function_objects/range.cmp/lwg3530.cc: New test.
With P1614R2 fully implemented (except for the <chrono> types which we
don't support at all) we can define the feature test macro to the new
value.
* include/std/version (__cpp_lib_three_way_comparison): Update value.
* libsupc++/compare (__cpp_lib_three_way_comparison): Likewise.
My "simplification" of std::compare_three_way's constraints in commit
f214ffb336 was incorrect, because
std::three_way_comparable_with imposes additional restrictions beyond
the <=> expression being valid.
* libsupc++/compare (compare_three_way): Fix constraint so that
BUILTIN-PTR-THREE-WAY does not require three_way_comparable_with.
* testsuite/18_support/comparisons/object/builtin-ptr-three-way.cc:
New test.
LWG 3324 changed the [cmp.alg] types to use std::compare_three_way
instead of the <=> operator, but we were still using the old
specification. In order to make the existing tests pass the N::X type
needs to be equality comparable, so that three_way_comparable is
satisfied and compare_three_way can be used.
As part of this change I noticed that the compare_three_way call
operator was unconditionally noexcept, which is incorrect.
* libsupc++/compare (compare_three_way): Fix noexcept-specifier.
(strong_order, weak_order, partial_order): Replace uses of <=> with
compare_three_way function object (LWG 3324).
* testsuite/18_support/comparisons/algorithms/partial_order.cc: Add
equality operator so that X satisfies three_way_comparable.
* testsuite/18_support/comparisons/algorithms/strong_order.cc:
Likewise.
* testsuite/18_support/comparisons/algorithms/weak_order.cc: Likewise.
This also removes a useless condition that was supposed to be removed by
the P1959R0 changes, but left in when that was implemented.
* libsupc++/compare (three_way_comparable): Remove always-false check
that should have been removed with weak_equality (P1959R0).
(three_way_comparable_with): Likewise. Reorder requirements (LWG 3360).
* include/std/concepts (__detail::__partially_ordered_with): Move here
from <compare>.
(totally_ordered, totally_ordered_with): Use __partially_ordered_with
to simplify definition (LWG 3331).
* libsupc++/compare (__detail::__partially_ordered_with): Move to
<concepts>.
This removes the complicated std::boolean concept, as agreed in Prague.
* include/bits/ranges_algo.h (__find_fn, __find_first_of_fn)
(__adjacent_find_fn): Cast result of predicate to bool.
* include/std/concepts (__boolean): Remove.
(__detail::__boolean_testable_impl, __detail::__boolean_testable): Add
new helper concepts.
(__detail::__weakly_eq_cmp_with, totally_ordered, totally_ordered_with)
(predicate): Use __boolean_testable instead of boolean.
* libsupc++/compare (__detail::__partially_ordered, _Synth3way):
Likewise.
This reduces the size and alignment of all three comparison category
types to a single byte. The partial_ordering::_M_is_ordered flag is
replaced by the value 0x02 in the _M_value member.
This also optimizes conversion and comparison operators to avoid
conditional branches where possible, by comparing _M_value to constants
or using bitwise operations to correctly handle the unordered state.
* libsupc++/compare (__cmp_cat::type): Define typedef for underlying
type of enumerations and comparison category types.
(__cmp_cat::_Ord, __cmp_cat::_Ncmp): Add underlying type.
(__cmp_cat::_Ncmp::unordered): Change value to 2.
(partial_ordering::_M_value, weak_ordering::_M_value)
(strong_ordering::_M_value): Change type to __cmp_cat::type.
(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<=>(unspecified, weak_ordering)): Likewise.
(strong_ordering::operator partial_ordering): Likewise.
(strong_ordering::operator weak_ordering): Likewise.
(operator<=>(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.
The __3way_builtin_ptr_cmp concept can use three_way_comparable_with to
check whether <=> is valid. Doing that makes it obvious that the
disjunction on compare_three_way::operator() is redundant, because
the second constraint subsumes the first.
The workaround for PR c++/91073 can also be removed as that bug is fixed
now.
* libsupc++/compare (__detail::__3way_builtin_ptr_cmp): Use
three_way_comparable_with.
(__detail::__3way_cmp_with): Remove workaround for fixed bug.
(compare_three_way::operator()): Remove redundant constraint from
requires-clause.
(__detail::_Synth3way::operator()): Use three_way_comparable_with
instead of workaround.
* testsuite/18_support/comparisons/object/93479.cc: Prune extra
output due to simplified constraints on compare_three_way::operator().
Currently types that cannot be compared using <=> but which are
convertible to pointers will be compared by converting to pointers
first. They should not be comparable.
PR libstdc++/93479
* libsupc++/compare (__3way_builtin_ptr_cmp): Require <=> to be valid.
* testsuite/18_support/comparisons/object/93479.cc: New test.
The _Eq and _Ord enumerations can be combined into one, reducing the
number of constructors needed for the comparison category types. The
redundant equal enumerator can be removed and equivalent used in its
place. The _Less and _Greater enumerators can be renamed because 'less'
and 'greater' are already reserved names anyway.
* libsupc++/compare (__cmp_cat::_Eq): Remove enumeration type.
(__cmp_cat::_Ord::equivalent): Add enumerator.
(__cmp_cat::_Ord::_Less, __cmp_cat::_Ord::_Greater): Rename to less
and greater.
(partial_ordering, weak_ordering, strong_ordering): Remove
constructors taking __cmp_cat::_Eq parameters. Use renamed
enumerators.
The contents of the <compare> header are not complete unless concepts
are supported, so the feature test macro should depend on the macro for
concepts.
As a result, the std::lexicographical_compare_three_way function will
not be defined unless concepts are supported, so there is no need to
check __cpp_lib_concepts before using concepts in those functions.
* include/bits/stl_algobase.h (__is_byte_iter, __min_cmp)
(lexicographical_compare_three_way): Do not depend on
__cpp_lib_concepts.
* include/std/version (__cpp_lib_three_way_comparison): Only define
when __cpp_lib_concepts is defined.
* libsupc++/compare (__cpp_lib_three_way_comparison): Likewise.
From-SVN: r279896
* libsupc++/compare (common_comparison_category): Define without using
concepts and optimise for compilation time.
(__detail::__cmp_cat_ids): Remove.
(__detail::__common_cmp_cat): Replace class template and
specializations with constexpr function.
From-SVN: r279307
This defines operator<=> as a non-member function template and does not
alter operator==. This contradicts the changes made by P1614R2, which
specify both as hidden friends, but that specification of operator<=> is
broken and the subject of a soon-to-be-published LWG issue.
* include/bits/stl_pair.h [__cpp_lib_three_way_comparison]
(operator<=>): Define for C++20.
* libsupc++/compare (__cmp2way_res_t): Rename to __cmp3way_res_t,
move into __detail namespace. Do not turn argument types into lvalues.
(__cmp3way_helper): Rename to __cmp3way_res_impl, move into __detail
namespace. Constrain with concepts instead of using void_t.
(compare_three_way_result): Adjust name of base class.
(compare_three_way_result_t): Use __cmp3way_res_impl directly.
(__detail::__3way_cmp_with): Add workaround for PR 91073.
(compare_three_way): Use workaround.
(__detail::__synth3way, __detail::__synth3way_t): Define new helpers
implementing synth-three-way and synth-three-way-result semantics.
* testsuite/20_util/pair/comparison_operators/constexpr_c++20.cc: New
test.
From-SVN: r278951
This is incomplete because std::strong_order doesn't support
floating-point types.
The partial_order and weak_order tests use VERIFY instead of
static_assert because of PR 92431.
* libsupc++/compare (strong_order, weak_order, partial_order)
(compare_strong_order_fallback, compare_weak_order_fallback)
(compare_partial_order_fallback): Define customization point objects
for C++20.
* testsuite/18_support/comparisons/algorithms/partial_order.cc: New
test.
* testsuite/18_support/comparisons/algorithms/strong_order.cc: New
test.
* testsuite/18_support/comparisons/algorithms/weak_order.cc: New test.
From-SVN: r278149
Shortly after I finished implementing the previous semantics, the
committee decided to remove the *_equality comparison categories, because
they were largely obsoleted by the earlier change that separated operator==
from its original dependency on operator<=>.
gcc/cp/
* method.c (enum comp_cat_tag, comp_cat_info): Remove *_equality.
(genericize_spaceship, common_comparison_type): Likewise.
* typeck.c (cp_build_binary_op): Move SPACESHIP_EXPR to be with the
relational operators, exclude other types no longer supported.
libstdc++-v3/
* libsupc++/compare: Remove strong_equality and weak_equality.
From-SVN: r277925
There are three major pieces to this support: scalar operator<=>,
synthesis of comparison operators, and rewritten/reversed overload
resolution (e.g. a < b becomes 0 > b <=> a).
Unlike other defaulted functions, where we use synthesized_method_walk to
semi-simulate what the definition of the function will be like, this patch
determines the characteristics of a comparison operator by trying to define
it.
My handling of non-dependent rewritten operators in templates can still use
some work: build_min_non_dep_op_overload can't understand the rewrites and
crashes, so I'm avoiding it for now by clearing *overload. This means we'll
do name lookup again at instantiation time, which can incorrectly mean a
different result. I'll poke at this more in stage 3.
I'm leaving out a fourth section ("strong structural equality") even though
I've implemented it, because it seems likely to change radically tomorrow.
Thanks to Tim van Deurzen and Jakub for implementing lexing of the <=>
operator, and Jonathan for the initial <compare> header.
gcc/cp/
* cp-tree.h (struct lang_decl_fn): Add maybe_deleted bitfield.
(DECL_MAYBE_DELETED): New.
(enum special_function_kind): Add sfk_comparison.
(LOOKUP_REWRITTEN, LOOKUP_REVERSED): New.
* call.c (struct z_candidate): Add rewritten and reversed methods.
(add_builtin_candidate): Handle SPACESHIP_EXPR.
(add_builtin_candidates): Likewise.
(add_candidates): Don't add a reversed candidate if the parms are
the same.
(add_operator_candidates): Split out from build_new_op_1. Handle
rewritten and reversed candidates.
(add_candidate): Swap conversions of reversed candidate.
(build_new_op_1): Swap them back. Build a second operation for
rewritten candidates.
(extract_call_expr): Handle rewritten calls.
(same_fn_or_template): New.
(joust): Handle rewritten and reversed candidates.
* class.c (add_implicitly_declared_members): Add implicit op==.
(classtype_has_op, classtype_has_defaulted_op): New.
* constexpr.c (cxx_eval_binary_expression): Handle SPACESHIP_EXPR.
(cxx_eval_constant_expression, potential_constant_expression_1):
Likewise.
* cp-gimplify.c (genericize_spaceship): New.
(cp_genericize_r): Use it.
* cp-objcp-common.c (cp_common_init_ts): Handle SPACESHIP_EXPR.
* decl.c (finish_function): Handle deleted function.
* decl2.c (grokfield): SET_DECL_FRIEND_CONTEXT on defaulted friend.
(mark_used): Check DECL_MAYBE_DELETED. Remove assumption that
defaulted functions are non-static members.
* error.c (dump_expr): Handle SPACESHIP_EXPR.
* method.c (type_has_trivial_fn): False for sfk_comparison.
(enum comp_cat_tag, struct comp_cat_info_t): New types.
(comp_cat_cache): New array variable.
(lookup_comparison_result, lookup_comparison_category)
(is_cat, cat_tag_for, spaceship_comp_cat)
(spaceship_type, genericize_spaceship)
(common_comparison_type, early_check_defaulted_comparison)
(comp_info, build_comparison_op): New.
(synthesize_method): Handle sfk_comparison. Handle deleted.
(get_defaulted_eh_spec, maybe_explain_implicit_delete)
(explain_implicit_non_constexpr, implicitly_declare_fn)
(defaulted_late_check, defaultable_fn_check): Handle sfk_comparison.
* name-lookup.c (get_std_name_hint): Add comparison categories.
* tree.c (special_function_p): Add sfk_comparison.
* typeck.c (cp_build_binary_op): Handle SPACESHIP_EXPR.
2019-11-05 Tim van Deurzen <tim@kompiler.org>
Add new tree code for the spaceship operator.
gcc/cp/
* cp-tree.def: Add new tree code.
* operators.def: New binary operator.
* parser.c: Add new token and tree code.
libcpp/
* cpplib.h: Add spaceship operator for C++.
* lex.c: Implement conditional lexing of spaceship operator for C++20.
2019-11-05 Jonathan Wakely <jwakely@redhat.com>
libstdc++-v3/
* libsupc++/compare: New header.
* libsupc++/Makefile.am (std_HEADERS): Add compare.
* include/std/version: Define __cpp_lib_three_way_comparison.
* include/std/functional: #include <compare>.
From-SVN: r277865