aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/include/std/optional
AgeCommit message (Collapse)AuthorFilesLines
2025-07-14libstdc++: Add comments to deleted std::swap overloads for LWG 2766Jonathan Wakely1-0/+2
We pre-emptively implemented part of LWG 2766, which still hasn't been approved. Add comments to the deleted swap overloads saying why they're there, because the standard doesn't require them. libstdc++-v3/ChangeLog: * include/bits/stl_pair.h (swap): Add comment to deleted overload. * include/bits/unique_ptr.h (swap): Likewise. * include/std/array (swap): Likewise. * include/std/optional (swap): Likewise. * include/std/tuple (swap): Likewise. * include/std/variant (swap): Likewise. * testsuite/23_containers/array/tuple_interface/get_neg.cc: Adjust dg-error line numbers.
2025-06-13libstdc++: add a workaround for format_kind<optional<T>> [PR120644]Giuseppe D'Angelo1-1/+1
The specialization of format_kind for optional is causing a problem when optional is imported and included. The comments on the PR strongly suggest that this is a frontend bug; this commit just works around the issue by specifying the type of format_kind<optional<T>> to be `range_format`, rather than leaving the compiler deduce it via `auto`. PR c++/120644 libstdc++-v3/ChangeLog: * include/std/optional (format_kind): Do not use `auto`.
2025-06-12libstdc++: add range support to std::optional (P3168)Giuseppe D'Angelo1-0/+47
This commit implements P3168 ("Give std::optional Range Support"), added for C++26. Both begin() and end() are straightforward, implemented using normal_iterator over a raw pointer. std::optional is also a view, so specialize enable_view for it. We also need to disable automatic formatting a std::optional as a range by specializing format_kind. In order to avoid dragging <format> when including <optional>, I've isolated format_kind and some supporting code into <bits/formatfwd.h> so that I can use that (comparatively) lighter header. libstdc++-v3/ChangeLog: * include/bits/formatfwd.h (format_kind): Move the definition (and some supporting code) from <format>. * include/std/format (format_kind): Likewise. * include/bits/version.def (optional_range_support): Add the feature-testing macro. * include/bits/version.h: Regenerate. * include/std/optional (iterator, const_iterator, begin, end): Add range support. (enable_view): Specialize for std::optional. (format_kind): Specialize for std::optional. * testsuite/20_util/optional/range.cc: New test. * testsuite/20_util/optional/version.cc: Test the new feature-testing macro.
2025-02-28libstdc++: Improve optional's <=> constraint recursion workaround [PR104606]Patrick Palka1-1/+2
It turns out the reason the behavior of this testcase changed after CWG 2369 is because validity of the substituted return type is now checked later, after constraints. So a more reliable workaround for this issue is to add a constraint to check the validity of the return type earlier, matching the pre-CWG 2369 semantics. PR libstdc++/104606 libstdc++-v3/ChangeLog: * include/std/optional (operator<=>): Revert r14-9771 change. Add constraint checking the validity of the return type compare_three_way_result_t before the three_way_comparable_with constraint. Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
2025-01-02Update copyright years.Jakub Jelinek1-1/+1
2024-12-03libstdc++: Fix constraints on std::optional converting constructors [PR117889]Jonathan Wakely1-2/+2
The converting constructors had the same bug as the converting assignments, so need the same fix as r15-5833-gc2c7d71eeeab7c. libstdc++-v3/ChangeLog: PR libstdc++/117889 PR libstdc++/117858 * include/std/optional (optional(const optional<U>&)): Fix copy and paste error in constraints. (optional(optional<U>&&)): Likewise. * testsuite/20_util/optional/assignment/117858.cc: Move to ... * testsuite/20_util/optional/cons/117858.cc: New test.
2024-11-30libstdc++: Fix constraints on std::optional converting assignments [PR117858]Jonathan Wakely1-2/+2
It looks like I copied these constraints from operator=(U&&) and didn't correct them to account for the parameter being optional<U> not U. libstdc++-v3/ChangeLog: PR libstdc++/117858 * include/std/optional (operator=(const optional<U>&)): Fix copy and paste error in constraints. (operator=(optional<U>&&)): Likewise. * testsuite/20_util/optional/assignment/117858.cc: New test.
2024-11-13libstdc++: Refactor std::hash specializationsJonathan Wakely1-12/+14
This attempts to simplify and clean up our std::hash code. The primary benefit is improved diagnostics for users when they do something wrong involving std::hash or unordered containers. An additional benefit is that for the unstable ABI (--enable-symvers=gnu-versioned-namespace) we can reduce the memory footprint of several std::hash specializations. In the current design, __hash_enum is a base class of the std::hash primary template, but the partial specialization of __hash_enum for non-enum types is disabled. This means that if a user forgets to specialize std::hash for their class type (or forgets to use a custom hash function for unordered containers) they get error messages about std::__hash_enum not being constructible. This is confusing when there is no enum type involved: why should users care about __hash_enum not being constructible if they're not trying to hash enums? This change makes the std::hash primary template only derive from __hash_enum when the template argument type is an enum. Otherwise, it derives directly from a new class template, __hash_not_enabled. This new class template defines the deleted members that cause a given std::hash specialization to be a disabled specialization (as per P0513R0). Now when users try to use a disabled specialization, they get more descriptive errors that mention __hash_not_enabled instead of __hash_enum. Additionally, adjust __hash_base to remove the deprecated result_type and argument_type typedefs for C++20 and later. In the current code we use a __poison_hash base class in the std::hash specializations for std::unique_ptr, std::optional, and std::variant. The primary template of __poison_hash has deleted special members, which is used to conditionally disable the derived std::hash specialization. This can also result in confusing diagnostics, because seeing "poison" in an enabled specialization is misleading. Only some uses of __poison_hash actually "poison" anything, i.e. cause a specialization to be disabled. In other cases it's just an empty base class that does nothing. This change removes __poison_hash and changes the std::hash specializations that were using it to conditionally derive from __hash_not_enabled instead. When the std::hash specialization is enabled, there is no more __poison_hash base class. However, to preserve the ABI properties of those std::hash specializations, we need to replace __poison_hash with some other empty base class. This is needed because in the current code std::hash<std::variant<int, const int>> has two __poison_hash<int> base classes, which must have unique addresses, so sizeof(std::hash<std::variant<int, const int>>) == 2. To preserve this unfortunate property, a new __hash_empty_base class is used as a base class to re-introduce du0plicate base classes that increase the class size. For the unstable ABI we don't use __hash_empty_base so the std::hash<std::variant<T...>> specializations are always size 1, and the class hierarchy is much simpler so will compile faster. Additionally, remove the result_type and argument_type typedefs from all disabled specializations of std::hash for std::unique_ptr, std::optional, and std::variant. Those typedefs are useless for disabled specializations, and although the standard doesn't say they must *not* be present for disabled specializations, it certainly only requires them for enabled specializations. Finally, for C++20 the typedefs are also removed from enabled specializations of std::hash for std::unique_ptr, std::optional, and std::variant. libstdc++-v3/ChangeLog: * doc/xml/manual/evolution.xml: Document removal of nested types from std::hash specializations. * doc/html/manual/api.html: Regenerate. * include/bits/functional_hash.h (__hash_base): Remove deprecated nested types for C++20. (__hash_empty_base): Define new class template. (__is_hash_enabled_for): Define new variable template. (__poison_hash): Remove. (__hash_not_enabled): Define new class template. (__hash_enum): Remove partial specialization for non-enums. (hash): Derive from __hash_not_enabled for non-enums, instead of __hash_enum. * include/bits/unique_ptr.h (__uniq_ptr_hash): Derive from __hash_base. Conditionally derive from __hash_empty_base. (__uniq_ptr_hash<>): Remove disabled specialization. (hash): Do not derive from __hash_base unconditionally. Conditionally derive from either __uniq_ptr_hash or __hash_not_enabled. * include/std/optional (__optional_hash_call_base): Remove. (__optional_hash): Define new class template. (hash): Derive from either (hash): Conditionally derive from either __optional_hash or __hash_not_enabled. Remove nested typedefs. * include/std/variant (_Base_dedup): Replace __poison_hash with __hash_empty_base. (__variant_hash_call_base_impl): Remove. (__variant_hash): Define new class template. (hash): Conditionally derive from either __variant_hash or __hash_not_enabled. Remove nested typedefs. * testsuite/20_util/optional/hash.cc: Check whether nested types are present. * testsuite/20_util/variant/hash.cc: Likewise. * testsuite/20_util/optional/hash_abi.cc: New test. * testsuite/20_util/unique_ptr/hash/abi.cc: New test. * testsuite/20_util/unique_ptr/hash/types.cc: New test. * testsuite/20_util/variant/hash_abi.cc: New test.
2024-09-25libstdc++: #ifdef out #pragma GCC system_headerJason Merrill1-0/+2
In r15-3714-gd3a7302ec5985a I added -Wsystem-headers to the libstdc++ build flags to help catch problems in the library. This patch takes a different approach, of disabling the #pragma system_header unless _GLIBCXX_SYSHDR is defined. As a result, the testsuites will treat them as non-system-headers to get better warning coverage during regression testing of both gcc and libstdc++, not just when building the library. My rationale for the #ifdef instead of just removing the #pragma is the three G++ tests that want to test libstdc++ system header behavior, so we need a way to select it. This doesn't affect installed libraries, as they get their system-header status from the lookup path. But testsuite_flags --build-includes gives -I directives rather than -isystem. This patch doesn't change the headers in config/ because I'm not compiling with most of them, so won't see any warnings that need fixing. Adjusting them could happen later, or we can not bother. libstdc++-v3/ChangeLog: * acinclude.m4 (WARN_FLAGS): Remove -Wsystem-headers. * configure: Regenerate. * include/bits/algorithmfwd.h: #ifdef out #pragma GCC system_header. * include/bits/atomic_base.h * include/bits/atomic_futex.h * include/bits/atomic_timed_wait.h * include/bits/atomic_wait.h * include/bits/basic_ios.h * include/bits/basic_string.h * include/bits/boost_concept_check.h * include/bits/char_traits.h * include/bits/charconv.h * include/bits/chrono.h * include/bits/chrono_io.h * include/bits/codecvt.h * include/bits/concept_check.h * include/bits/cpp_type_traits.h * include/bits/elements_of.h * include/bits/enable_special_members.h * include/bits/erase_if.h * include/bits/forward_list.h * include/bits/functional_hash.h * include/bits/gslice.h * include/bits/gslice_array.h * include/bits/hashtable.h * include/bits/indirect_array.h * include/bits/invoke.h * include/bits/ios_base.h * include/bits/iterator_concepts.h * include/bits/locale_classes.h * include/bits/locale_facets.h * include/bits/locale_facets_nonio.h * include/bits/localefwd.h * include/bits/mask_array.h * include/bits/max_size_type.h * include/bits/memory_resource.h * include/bits/memoryfwd.h * include/bits/move_only_function.h * include/bits/node_handle.h * include/bits/ostream_insert.h * include/bits/out_ptr.h * include/bits/parse_numbers.h * include/bits/postypes.h * include/bits/quoted_string.h * include/bits/range_access.h * include/bits/ranges_base.h * include/bits/refwrap.h * include/bits/sat_arith.h * include/bits/semaphore_base.h * include/bits/slice_array.h * include/bits/std_abs.h * include/bits/std_function.h * include/bits/std_mutex.h * include/bits/std_thread.h * include/bits/stl_iterator_base_funcs.h * include/bits/stl_iterator_base_types.h * include/bits/stl_tree.h * include/bits/stream_iterator.h * include/bits/streambuf_iterator.h * include/bits/stringfwd.h * include/bits/this_thread_sleep.h * include/bits/unique_lock.h * include/bits/uses_allocator_args.h * include/bits/utility.h * include/bits/valarray_after.h * include/bits/valarray_array.h * include/bits/valarray_before.h * include/bits/version.h * include/c_compatibility/fenv.h * include/c_compatibility/inttypes.h * include/c_compatibility/stdint.h * include/decimal/decimal.h * include/experimental/bits/net.h * include/experimental/bits/shared_ptr.h * include/ext/aligned_buffer.h * include/ext/alloc_traits.h * include/ext/atomicity.h * include/ext/concurrence.h * include/ext/numeric_traits.h * include/ext/pod_char_traits.h * include/ext/pointer.h * include/ext/stdio_filebuf.h * include/ext/stdio_sync_filebuf.h * include/ext/string_conversions.h * include/ext/type_traits.h * include/ext/vstring.h * include/ext/vstring_fwd.h * include/ext/vstring_util.h * include/parallel/algorithmfwd.h * include/parallel/numericfwd.h * include/tr1/functional_hash.h * include/tr1/hashtable.h * include/tr1/random.h * libsupc++/exception.h * libsupc++/hash_bytes.h * include/bits/basic_ios.tcc * include/bits/basic_string.tcc * include/bits/fstream.tcc * include/bits/istream.tcc * include/bits/locale_classes.tcc * include/bits/locale_facets.tcc * include/bits/locale_facets_nonio.tcc * include/bits/ostream.tcc * include/bits/sstream.tcc * include/bits/streambuf.tcc * include/bits/string_view.tcc * include/bits/version.tpl * include/experimental/bits/string_view.tcc * include/ext/pb_ds/detail/resize_policy/hash_prime_size_policy_imp.hpp * include/ext/random.tcc * include/ext/vstring.tcc * include/tr2/bool_set.tcc * include/tr2/dynamic_bitset.tcc * include/bits/c++config * include/c/cassert * include/c/cctype * include/c/cerrno * include/c/cfloat * include/c/ciso646 * include/c/climits * include/c/clocale * include/c/cmath * include/c/csetjmp * include/c/csignal * include/c/cstdarg * include/c/cstddef * include/c/cstdio * include/c/cstdlib * include/c/cstring * include/c/ctime * include/c/cuchar * include/c/cwchar * include/c/cwctype * include/c_global/cassert * include/c_global/ccomplex * include/c_global/cctype * include/c_global/cerrno * include/c_global/cfenv * include/c_global/cfloat * include/c_global/cinttypes * include/c_global/ciso646 * include/c_global/climits * include/c_global/clocale * include/c_global/cmath * include/c_global/csetjmp * include/c_global/csignal * include/c_global/cstdalign * include/c_global/cstdarg * include/c_global/cstdbool * include/c_global/cstddef * include/c_global/cstdint * include/c_global/cstdio * include/c_global/cstdlib * include/c_global/cstring * include/c_global/ctgmath * include/c_global/ctime * include/c_global/cuchar * include/c_global/cwchar * include/c_global/cwctype * include/c_std/cassert * include/c_std/cctype * include/c_std/cerrno * include/c_std/cfloat * include/c_std/ciso646 * include/c_std/climits * include/c_std/clocale * include/c_std/cmath * include/c_std/csetjmp * include/c_std/csignal * include/c_std/cstdarg * include/c_std/cstddef * include/c_std/cstdio * include/c_std/cstdlib * include/c_std/cstring * include/c_std/ctime * include/c_std/cuchar * include/c_std/cwchar * include/c_std/cwctype * include/debug/array * include/debug/bitset * include/debug/deque * include/debug/forward_list * include/debug/list * include/debug/map * include/debug/set * include/debug/string * include/debug/unordered_map * include/debug/unordered_set * include/debug/vector * include/decimal/decimal * include/experimental/algorithm * include/experimental/any * include/experimental/array * include/experimental/buffer * include/experimental/chrono * include/experimental/contract * include/experimental/deque * include/experimental/executor * include/experimental/filesystem * include/experimental/forward_list * include/experimental/functional * include/experimental/internet * include/experimental/io_context * include/experimental/iterator * include/experimental/list * include/experimental/map * include/experimental/memory * include/experimental/memory_resource * include/experimental/net * include/experimental/netfwd * include/experimental/numeric * include/experimental/propagate_const * include/experimental/ratio * include/experimental/regex * include/experimental/scope * include/experimental/set * include/experimental/socket * include/experimental/string * include/experimental/string_view * include/experimental/synchronized_value * include/experimental/system_error * include/experimental/timer * include/experimental/tuple * include/experimental/type_traits * include/experimental/unordered_map * include/experimental/unordered_set * include/experimental/vector * include/ext/algorithm * include/ext/cmath * include/ext/functional * include/ext/iterator * include/ext/memory * include/ext/numeric * include/ext/random * include/ext/rb_tree * include/ext/rope * include/parallel/algorithm * include/std/algorithm * include/std/any * include/std/array * include/std/atomic * include/std/barrier * include/std/bit * include/std/bitset * include/std/charconv * include/std/chrono * include/std/codecvt * include/std/complex * include/std/concepts * include/std/condition_variable * include/std/coroutine * include/std/deque * include/std/execution * include/std/expected * include/std/filesystem * include/std/format * include/std/forward_list * include/std/fstream * include/std/functional * include/std/future * include/std/generator * include/std/iomanip * include/std/ios * include/std/iosfwd * include/std/iostream * include/std/istream * include/std/iterator * include/std/latch * include/std/limits * include/std/list * include/std/locale * include/std/map * include/std/memory * include/std/memory_resource * include/std/mutex * include/std/numbers * include/std/numeric * include/std/optional * include/std/ostream * include/std/print * include/std/queue * include/std/random * include/std/ranges * include/std/ratio * include/std/regex * include/std/scoped_allocator * include/std/semaphore * include/std/set * include/std/shared_mutex * include/std/span * include/std/spanstream * include/std/sstream * include/std/stack * include/std/stacktrace * include/std/stdexcept * include/std/streambuf * include/std/string * include/std/string_view * include/std/syncstream * include/std/system_error * include/std/text_encoding * include/std/thread * include/std/tuple * include/std/type_traits * include/std/typeindex * include/std/unordered_map * include/std/unordered_set * include/std/utility * include/std/valarray * include/std/variant * include/std/vector * include/std/version * include/tr1/array * include/tr1/cfenv * include/tr1/cinttypes * include/tr1/cmath * include/tr1/complex * include/tr1/cstdbool * include/tr1/cstdint * include/tr1/cstdio * include/tr1/cstdlib * include/tr1/cwchar * include/tr1/cwctype * include/tr1/functional * include/tr1/memory * include/tr1/random * include/tr1/regex * include/tr1/tuple * include/tr1/type_traits * include/tr1/unordered_map * include/tr1/unordered_set * include/tr1/utility * include/tr2/bool_set * include/tr2/dynamic_bitset * include/tr2/type_traits * libsupc++/atomic_lockfree_defines.h * libsupc++/compare * libsupc++/cxxabi.h * libsupc++/cxxabi_forced.h * libsupc++/cxxabi_init_exception.h * libsupc++/exception * libsupc++/initializer_list * libsupc++/new * libsupc++/typeinfo: Likewise. * testsuite/20_util/ratio/operations/ops_overflow_neg.cc * testsuite/23_containers/array/tuple_interface/get_neg.cc * testsuite/23_containers/vector/cons/destructible_debug_neg.cc * testsuite/24_iterators/operations/prev_neg.cc * testsuite/ext/type_traits/add_unsigned_floating_neg.cc * testsuite/ext/type_traits/add_unsigned_integer_neg.cc * testsuite/ext/type_traits/remove_unsigned_floating_neg.cc * testsuite/ext/type_traits/remove_unsigned_integer_neg.cc: Adjust line numbers. gcc/testsuite/ChangeLog * g++.dg/analyzer/fanalyzer-show-events-in-system-headers-default.C * g++.dg/analyzer/fanalyzer-show-events-in-system-headers-no.C * g++.dg/diagnostic/disable.C: #define _GLIBCXX_SYSHDR.
2024-09-12libstdc++: Remove unused alias template in std::optionalJonathan Wakely1-2/+0
I added this __is_bool alias template in r15-2309-g6d86486292acbe but it isn't actually used so can be removed. libstdc++-v3/ChangeLog: * include/std/optional (__is_bool): Remove.
2024-08-23libstdc++: Implement LWG 3746 for std::optionalJonathan Wakely1-2/+10
This avoids constraint recursion in operator<=> for std::optional. The resolution was approved in Kona 2022. libstdc++-v3/ChangeLog: * include/std/optional (__is_derived_from_optional): New concept. (operator<=>): Use __is_derived_from_optional. * testsuite/20_util/optional/relops/lwg3746.cc: New test.
2024-08-20libstdc++: Remove redundant reclaration of std::optionalJonathan Wakely1-3/+0
We've already declared optional at the top of the header, so don't need to do it again. libstdc++-v3/ChangeLog: * include/std/optional: Remove redundant redeclaration.
2024-07-30libstdc++: Implement LWG 3886 for std::optional and std::expectedJonathan Wakely1-6/+6
This uses remove_cv_t<T> for the default template argument used for deducing a type for a braced-init-list used with std::optional and std::expected. libstdc++-v3/ChangeLog: * include/std/expected (expected(U&&), operator=(U&&)) (value_or): Use remove_cv_t on default template argument, as per LWG 3886. * include/std/optional (optional(U&&), operator=(U&&)) (value_or): Likewise. * testsuite/20_util/expected/lwg3886.cc: New test. * testsuite/20_util/optional/cons/lwg3886.cc: New test.
2024-07-25libstdc++: Reorder template params of std::optional comparisons (LWG 2945)Jonathan Wakely1-18/+18
libstdc++-v3/ChangeLog: * include/std/optional: Reorder parameters in comparison operators as per LWG 2945.
2024-07-25libstdc++: Use concepts and conditional explicit in std::optionalJonathan Wakely1-9/+121
For C++20 mode we can improve compile times by using conditional explicit to reduce the number of constructor overloads. We can also use requires-clauses instead of SFINAE to implement constraints on the constructors and assignment operators. libstdc++-v3/ChangeLog: * include/std/optional (optional): Use C++20 features to simplify overload sets for constructors and assignment operators.
2024-07-25libstdc++: Implement LWG 3836 for std::optional bool conversionsJonathan Wakely1-16/+42
libstdc++-v3/ChangeLog: * include/std/optional (optional): Constrain constructors to prevent problematic bool conversions, as per LWG 3836. * testsuite/20_util/optional/cons/lwg3836.cc: New test.
2024-07-25libstdc++: Use concepts to simplify std::optional base classesJonathan Wakely1-45/+121
In C++20 mode we can simplify some of the std::optional base class hierarchy using concepts. We can overload the destructor and copy constructor and move constructor with a trivial defaulted version and a constrained non-trivial version. This allows us to remove some class template partial specializations that were used to conditionally define those special members as trivial or non-trivial. This should not change any semantics, but should be less work for the compiler, due to not needing to match partial specializations, and completely removing one level of the inheritance hierarchy. libstdc++-v3/ChangeLog: * include/std/optional (_Optional_payload_base::_Storage) [C++20]: Define constrained non-trivial destructor. (_Optional_payload_base::_Storage<U, false>) [C++20]: Do not define partial specialization when primary template has constrained destructor. (_Optional_base) [C++20]: Define constrained trivial copy and move cons and move constructors. Define payload accessors here instead of inheriting them from _Optional_base_impl. (_Optional_base_impl, _Optional_base<T, false, true>) (_Optional_base<T, true, false>, _Optional_base<T, true, true>) [C++20]: Do not define.
2024-07-25libstdc++: Use _M_get() in std::optional internalsJonathan Wakely1-18/+20
Now that _base::_M_get() doesn't check the precondition, we can use _M_get() instead of operator*() for the internal uses where we've already checked the precondition holds. Add a using-declaration so that we don't need to lookup _M_get in the dependent base class, and make optional<U> a friend so that the converting constructors and assignment operators can use the parameter's _M_get member. libstdc++-v3/ChangeLog: * include/std/optional (optional): Add using-declaraction for _Base::_M_get and declare optional<U> as friend. (optional(const optional<U>&)): Use _M_get instead of operator*. (optional(optional<U>&&)): Likewise. (operator=(const optional<U>&)): Likewise. (operator=(optional<U>&&)): Likewise. (and_then, tansform): Likewise.
2024-07-25libstdc++: Move std::optional assertions out of _M_get()Jonathan Wakely1-14/+26
Currently we implement the precondition for accessing the contained value of a std::optional in the _M_get() accessor in the base class. This means that we always check the assertions even in internal functions that have an explicit check for a contained value being present, such as value() and value_or(U&&). Although those redundant assertions should get optimized out in most cases, they might hurt inliner heuristics and generally give the compiler more work to do. And they won't be optimized out at all for non-optimized builds. The current assertions also result in repeated invalid bug reports, such as PR 91281, PR 101659, PR 102712, and PR 107894. We can move the assertions from the internal accessors to the public member functions where the preconditions are specified. Reviewed-by: Ville Voutilainen <ville.voutilainen@gmail.com> libstdc++-v3/ChangeLog: * include/std/optional (_Optional_base_impl::_M_get()): Move assertions to ... (optional::operator->, optional::operator*): ... here.
2024-05-07libstdc++: Constrain equality ops for std::pair, std::tuple, std::variantJonathan Wakely1-13/+37
Implement the changes from P2944R3 which add constraints to the comparison operators of std::pair, std::tuple, and std::variant. The paper also changes std::optional, but we already constrain its comparisons using SFINAE on the return type. However, we need some additional constraints on the [optional.comp.with.t] operators that compare an optional with a value. The paper doesn't say to do that, but I think it's needed because otherwise when the comparison for two optional objects fails its constraints, the two overloads that are supposed to be for comparing to a non-optional become the best overload candidates, but are ambiguous (and we don't even get as far as checking the constraints for satisfaction). I reported LWG 4072 for this. The paper does not change std::expected, but probably should have done. I'll submit an LWG issue about that and implement it separately. Also add [[nodiscard]] to all these comparison operators. libstdc++-v3/ChangeLog: * include/bits/stl_pair.h (operator==): Add constraint. * include/bits/version.def (constrained_equality): Define. * include/bits/version.h: Regenerate. * include/std/optional: Define feature test macro. (__optional_rep_op_t): Use is_convertible_v instead of is_convertible. * include/std/tuple: Define feature test macro. (operator==, __tuple_cmp, operator<=>): Reimplement C++20 comparisons using lambdas. Add constraints. * include/std/utility: Define feature test macro. * include/std/variant: Define feature test macro. (_VARIANT_RELATION_FUNCTION_TEMPLATE): Add constraints. (variant): Remove unnecessary friend declarations for comparison operators. * testsuite/20_util/optional/relops/constrained.cc: New test. * testsuite/20_util/pair/comparison_operators/constrained.cc: New test. * testsuite/20_util/tuple/comparison_operators/constrained.cc: New test. * testsuite/20_util/variant/relops/constrained.cc: New test. * testsuite/20_util/tuple/comparison_operators/overloaded.cc: Disable for C++20 and later. * testsuite/20_util/tuple/comparison_operators/overloaded2.cc: Remove dg-error line for target c++20.
2024-04-03libstdc++: Reverse arguments in constraint for std::optional's <=> [PR104606]Jonathan Wakely1-1/+1
This is a workaround for a possible compiler bug that causes constraint recursion in the operator<=>(const optional<T>&, const U&) overload. libstdc++-v3/ChangeLog: PR libstdc++/104606 * include/std/optional (operator<=>(const optional<T>&, const U&)): Reverse order of three_way_comparable_with template arguments. * testsuite/20_util/optional/relops/104606.cc: New test.
2024-01-03Update copyright years.Jakub Jelinek1-1/+1
2023-11-21libstdc++: Add freestanding feature test macros (P2407R5)Jonathan Wakely1-0/+1
This C++26 change makes several classes "partially freestanding", but we already fully supported them in freestanding mode. All we need to do is define the new feature test macros and add tests for them. libstdc++-v3/ChangeLog: * include/bits/version.def (freestanding_algorithm) (freestanding_array, freestanding_optional) (freestanding_string_view, freestanding_variant): Add. * include/bits/version.h: Regenerate. * include/std/algorithm (__glibcxx_want_freestanding_algorithm): Define. * include/std/array (__glibcxx_want_freestanding_array): Define. * include/std/optional (__glibcxx_want_freestanding_optional): Define. * include/std/string_view (__glibcxx_want_freestanding_string_view): Define. * include/std/variant (__glibcxx_want_freestanding_variant): Define. * testsuite/20_util/optional/version.cc: Add checks for __cpp_lib_freestanding_optional. * testsuite/20_util/variant/version.cc: Add checks for __cpp_lib_freestanding_variant. * testsuite/23_containers/array/tuple_interface/get_neg.cc: Adjust dg-error line numbers. * testsuite/21_strings/basic_string_view/requirements/version.cc: New test. * testsuite/23_containers/array/requirements/version.cc: New test. * testsuite/25_algorithms/fill_n/requirements/version.cc: New test. * testsuite/25_algorithms/swap_ranges/requirements/version.cc: New test.
2023-11-13libstdc++: Micro-optimization for std::optional [PR112480]Jonathan Wakely1-0/+2
This small change removes a branch when clearing a std::optional<T> for types with no-op destructors. For types where the destructor can be optimized away (e.g. because it's trivial, or empty and can be inlined) the _M_destroy() function does nothing but set _M_engaged to false. Setting _M_engaged=false unconditionally is cheaper than only doing it when initially true, because it allows the compiler to remove a branch. The compiler thinks it would be incorrect to unconditionally introduce a store there, because it could conflict with reads in other threads, so it won't do that optimization itself. We know it's safe to do because we're in a non-const member function, so the standard forbids any potentially concurrent calls to other member functions of the same object. Making the store unconditional can't create a data race that isn't already present in the program. libstdc++-v3/ChangeLog: PR libstdc++/112480 * include/std/optional (_Optional_payload_base::_M_reset): Set _M_engaged to false unconditionally.
2023-11-06libstdc++: Improve static assert messages for monadic operationsJonathan Wakely1-6/+18
The monadic operations for std::optional and std::expected make use of internal helper traits __is_optional nad __is_expected, which are not very user-friendly when shown in diagnostics. Add messages to the assertions explaining the problem more clearly. libstdc++-v3/ChangeLog: * include/std/expected (expected::and_then, expected::or_else): Add string literals to static assertions. * include/std/optional (optional::and_then, optional::or_else): Likewise.
2023-08-16libstdc++: Replace all manual FTM definitions and useArsen Arsenović1-10/+5
libstdc++-v3/ChangeLog: * libsupc++/typeinfo: Switch to bits/version.h for __cpp_lib_constexpr_typeinfo. * libsupc++/new: Switch to bits/version.h for __cpp_lib_{launder,hardware_interference_size,destroying_delete}. (launder): Guard behind __cpp_lib_launder. (hardware_destructive_interference_size) (hardware_constructive_interference_size): Guard behind __cpp_lib_hardware_interference_size. * libsupc++/exception: Switch to bits/version.h for __cpp_lib_uncaught_exceptions. (uncaught_exceptions): Guard behind __cpp_lib_uncaught_exceptions. * libsupc++/compare: Switch to bits/version.h for __cpp_lib_three_way_comparison. (three_way_comparable, three_way_comparable_with) (compare_three_way, weak_order, strong_order, partial_order): Guard behind __cpp_lib_three_way_comparison >= 201907L. * include/std/chrono: Drop __cpp_lib_chrono definition. * include/std/vector: Switch to bits/version.h for __cpp_lib_erase_if. (erase, erase_if): Guard behind __cpp_lib_erase_if. * include/std/variant: Switch to bits/version.h for __cpp_lib_variant. Guard whole header behind that FTM. * include/std/utility: Switch to bits/version.h for __cpp_lib_{exchange_function,constexpr_algorithms,as_const}, __cpp_lib_{integer_comparison_functions,to_underlying}, and __cpp_lib_unreachable. (exchange): Guard behind __cpp_lib_exchange_function. (cmp_equal, cmp_not_equal, cmp_less, cmp_greater, cmp_less_equal) (cmp_greater_equal, in_range): Guard behind __cpp_lib_integer_comparison_functions. (to_underlying): Guard behind __cpp_lib_to_underlying. (unreachable): Guard behind __cpp_lib_unreachable. * include/std/type_traits: Switch to bits/version.h for __cpp_lib_is_{null_pointer,final,nothrow_convertible,aggregate}, __cpp_lib_is_{constant_evaluated,invocable,layout_compatible}, __cpp_lib_is_{pointer_interconvertible,scoped_enum,swappable}, __cpp_lib_{logical_traits,reference_from_temporary,remove_cvref}, __cpp_lib_{result_of_sfinae,transformation_trait_aliases}, __cpp_lib_{type_identity,type_trait_variable_templates}, __cpp_lib_{unwrap_ref,void_t,integral_constant_callable}, __cpp_lib_{bool_constant,bounded_array_traits}, and __cpp_lib_has_unique_object_representations. (integral_constant::operator()): Guard behind __cpp_lib_integral_constant_callable. (bool_constant): Guard behind __cpp_lib_bool_constant. (conjunction, disjunction, negation, conjunction_v, disjunction_v) (negation_v): Guard behind __cpp_lib_logical_traits. (is_null_pointer): Guard behind __cpp_lib_is_null_pointer. (is_final): Guard behind __cpp_lib_is_final. (is_nothrow_convertible, is_nothrow_convertible_v): Guard behind __cpp_lib_is_nothrow_convertible. (remove_const_t, remove_volatile_t, remove_cv_t) (add_const_t, add_volatile_t, add_cv_t): Guard behind __cpp_lib_transformation_trait_aliases. (void_t): Guard behind __cpp_lib_void_t. (is_swappable_with_v, is_nothrow_swappable_with_v) (is_swappable_with, is_nothrow_swappable_with): Guard behind __cpp_lib_is_swappable. (is_nothrow_invocable_r, is_invocable_r, invoke_result) (is_invocable, invoke_result_t): Guard behind __cpp_lib_is_invocable. (alignment_of_v, extent_v, has_virtual_destructor_v) (is_abstract_v, is_arithmetic_v, is_array_v) (is_assignable_v, is_base_of_v, is_class_v, is_compound_v) (is_constructible_v, is_const_v, is_convertible_v) (is_copy_assignable_v, is_copy_constructible_v) (is_default_constructible_v, is_destructible_v) (is_empty_v, is_enum_v, is_final_v, is_floating_point_v) (is_function_v, is_fundamental_v, is_integral_v) (is_invocable_r_v, is_invocable_v, is_literal_type_v) (is_lvalue_reference_v, is_member_function_pointer_v) (is_member_object_pointer_v, is_member_pointer_v) (is_move_assignable_v, is_move_constructible_v) (is_nothrow_assignable_v, is_nothrow_constructible_v) (is_nothrow_copy_assignable_v, is_nothrow_copy_constructible_v) (is_nothrow_default_constructible_v, is_nothrow_destructible_v) (is_nothrow_invocable_r_v, is_nothrow_invocable_v) (is_nothrow_move_assignable_v, is_nothrow_move_constructible_v) (is_null_pointer_v, is_object_v, is_pod_v, is_pointer_v) (is_polymorphic_v, is_reference_v, is_rvalue_reference_v) (is_same_v, is_scalar_v, is_signed_v, is_standard_layout_v) (is_trivially_assignable_v, is_trivially_constructible_v) (is_trivially_copyable_v, is_trivially_copy_assignable_v) (is_trivially_copy_constructible_v) (is_trivially_default_constructible_v) (is_trivially_destructible_v, is_trivially_move_assignable_v) (is_trivially_move_constructible_v, is_trivial_v, is_union_v) (is_unsigned_v, is_void_v, is_volatile_v, rank_v, as variadic): Guard behind __cpp_lib_type_trait_variable_templates. (has_unique_object_representations) (has_unique_object_representations_v): Guard behind __cpp_lib_has_unique_object_representation. (is_aggregate): Guard behind __cpp_lib_is_aggregate. (remove_cvref, remove_cvref_t): Guard behind __cpp_lib_remove_cvref. (type_identity, type_identity_t): Guard behind __cpp_lib_type_identity. (unwrap_reference, unwrap_reference_t, unwrap_ref_decay) (unwrap_ref_decay_t): Guard behind __cpp_lib_unwrap_ref. (is_bounded_array_v, is_unbounded_array_v, is_bounded_array) (is_unbounded_array): Guard behind __cpp_lib_bounded_array_traits. (is_scoped_enum, is_scoped_enum_v): Guard behind __cpp_lib_is_scoped_enum. (reference_constructs_from_temporary) (reference_constructs_from_temporary_v): Guard behind __cpp_lib_reference_from_temporary. * include/std/tuple: Switch to bits/version.h for __cpp_lib_{constexpr_tuple,tuple_by_type,apply_make_from_tuple}. (get<T>): Guard behind __cpp_lib_tuple_by_type. (apply): Guard behind __cpp_lib_apply. (make_from_tuple): Guard behind __cpp_lib_make_from_tuple. * include/std/syncstream: Switch to bits/version.h for __cpp_lib_syncbuf. Guard header behind that FTM. * include/std/string_view: Switch to bits/version.h for __cpp_lib_{string_{view,contains},constexpr_string_view} and __cpp_lib_starts_ends_with. (basic_string_view::starts_with, basic_string_view::ends_with): Guard behind __cpp_lib_starts_ends_with. [C++23 && _GLIBCXX_HOSTED && !defined(__cpp_lib_string_contains)]: Assert as impossible ithout a bug in C++23. * include/std/string: Switch to bits/version.h for __cpp_lib_erase_if. (erase, erase_if): Guard behind __cpp_lib_erase_if. * include/std/thread: Switch to bits/version.h for __cpp_lib_jthread. * include/std/stop_token: Switch to bits/version.h for __cpp_lib_jthread. * include/std/spanstream: Switch to bits/version.h for __cpp_lib_spanstream. Guard header behind that FTM. * include/std/span: Switch to bits/version.h for __cpp_lib_span. Guard header behind that FTM. * include/std/source_location: Switch to bits/version.h for __cpp_lib_source_location. Guard header with that FTM. * include/std/shared_mutex: Switch to bits/version.h for __cpp_lib_shared{,_timed}_mutex. (shared_mutex): Guard behind __cpp_lib_shared_mutex. * include/std/semaphore: Switch to bits/version.h for __cpp_lib_semaphore. Guard header behind that FTM. * include/std/ranges: Switch to bits/version.h for __cpp_lib_ranges_{zip,chunk{,_by},slide,join_with}, __cpp_lib_ranges_{repeat_stride,cartesian_product,as_rvalue}, and __cpp_lib_ranges_{as_const,enumerate,iota}. (ranges::zip et al, ranges::chunk et al, ranges::slide et al) (ranges::chunk_by et al, ranges::join_with et al) (ranges::stride et al, ranges::cartesian_product et al) (ranges::as_rvalue et al, ranges::as_const et al) (ranges::enumerate et al): Guard behind appropriate FTM. * include/std/optional: Switch to bits/version.h for __cpp_lib_optional. Guard header behind that FTM. * include/std/numeric: Switch to bits/version.h for __cpp_lib_{gcd{,_lcm},lcm,constexpr_numeric,interpolate} and __cpp_lib_parallel_algorithm. (gcd, lcm): Guard behind __cpp_lib_gcd_lcm. (midpoint): Guard behind __cpp_lib_interpolate. * include/std/numbers: Switch to bits/version.h for __cpp_lib_math_constants. Guard header behind that FTM. * include/std/mutex: Switch to bits/version.h for __cpp_lib_scoped_lock. (scoped_Lock): Guard behind __cpp_lib_scoped_lock. * include/std/memory_resource: Switch to bits/version.h for __cpp_lib_{polymorphic_allocator,memory_resource}. (synchronized_pool_resource): Guard behind __cpp_lib_memory_resource >= 201603L. (polymorphic_allocator): Guard behind __cpp_lib_polymorphic_allocator. * include/std/memory: Switch to bits/version.h for __cpp_lib_{parallel_algorithm,atomic_value_initialization}. * include/std/list: Switch to bits/version.h for __cpp_lib_erase_if. (erase, erase_if): Guard behind __cpp_lib_erase_if. * include/std/latch: Switch to bits/version.h for __cpp_lib_latch. Guard header behind that FTM. * include/std/iterator: Switch to bits/version.h for __cpp_lib_null_iterators. * include/std/iomanip: Switch to bits/version.h for __cpp_lib_quoted_string_io. (quoted): Guard behind __cpp_lib_quoted_string_io. * include/std/functional: Switch to bits/version.h for __cpp_lib_{invoke{,_r},constexpr_functional,bind_front} and __cpp_lib_{not_fn,booyer_moore_searcher}. (invoke): Guard behind __cpp_lib_invoke. (invoke_r): Guard behind __cpp_lib_invoke_r. (bind_front): Guard behind __cpp_lib_bind_front. (not_fn): Guard behind __cpp_lib_not_fn. (boyer_moore_searcher, boyer_moore_horspool_searcher): Guard definition behind __cpp_lib_boyer_moore_searcher. * include/std/forward_list: Switch to bits/version.h for __cpp_lib_erase_if. (erase, erase_if): Guard behind __cpp_lib_erase_if. * include/std/format: Switch to bits/version.h for __cpp_lib_format. Guard header behind that FTM. * include/std/filesystem: Switch to bits/version.h for __cpp_lib_filesystem. Guard header behind that FTM. * include/std/expected: Switch to bits/version.h for __cpp_lib_expected. Guard header behind it. * include/std/execution: Switch to bits/version.h for __cpp_lib_{execution,parallel_algorithm}. Guard header behind either. * include/std/deque: Switch to bits/version.h for __cpp_lib_erase_if. (erase, erase_if): Guard behind __cpp_lib_erase_if. * include/std/coroutine: Switch to bits/version.h for __cpp_lib_coroutine. Guard header behind that FTM. * include/std/concepts: Switch to bits/version.h for __cpp_lib_concepts. Guard header behind that FTM. * include/std/complex: Switch to bits/version.h for __cpp_lib_{complex_udls,constexpr_complex}. (operator""if, operator""i, operator""il): Guard behind __cpp_lib_complex_udls. * include/std/charconv: Swtich to bits/version.h for __cpp_lib_{to_chars,constexpr_charconv}. * include/std/bitset: Switch to bits/version.h for __cpp_lib_constexpr_bitset. * include/std/bit: Switch to bits/version.h for __cpp_lib_{bit_cast,byteswap,bitops,int_pow2,endian}. (bit_cast): Guard behind __cpp_lib_bit_cast. (byteswap): Guard behind __cpp_lib_byteswap. (rotl, rotr, countl_zero, countl_one, countr_zero, countr_one) (popcount): Guard behind __cpp_lib_bitops. (has_single_bit, bit_ceil, bit_floor, bit_width): Guard behind __cpp_lib_int_pow2. (endian): Guard behind __cpp_lib_endian. * include/std/barrier: Switch to bits/version.h for __cpp_lib_barrier. Guard header behind that FTM. * include/std/atomic: Switch to bits/version.h for __cpp_lib_atomic_{is_always_lock_free,float,ref} and __cpp_lib_lock_free_type_aliases. (*::is_always_lock_free): Guard behind __cpp_lib_atomic_is_always_lock_free. (atomic<float>): Guard behind __cpp_lib_atomic_float. (atomic_ref): Guard behind __cpp_lib_atomic_ref. (atomic_signed_lock_free, atomic_unsigned_lock_free): Guard behind __cpp_lib_atomic_lock_free_type_aliases. * include/std/array: Switch to bits/version.h for __cpp_lib_to_array. (to_array): Guard behind __cpp_lib_to_array. * include/std/any: Switch to bits/version.h for __cpp_lib_any. Guard header behind that FTM. * include/std/algorithm: Switch to bits/version.h for __cpp_lib_parallel_algorithm. * include/c_global/cstddef: Switch to bits/version.h for __cpp_lib_byte. (byte): Guard behind __cpp_lib_byte. * include/c_global/cmath: Switch to bits/version.h for __cpp_lib_{hypot,interpolate}. (hypot3): Guard behind __cpp_lib_hypot. (lerp): Guard behind __cpp_lib_interpolate. * include/c_compatibility/stdatomic.h: Switch to bits/stl_version.h for __cpp_lib_atomic. Guard header behind that FTM. * include/bits/utility.h: Switch to bits/version.h for __cpp_lib_{tuple_element_t,integer_sequence,ranges_zip}. (tuple_element_t): Guard behind __cpp_lib_tuple_element_t. (integer_sequence et al): Guard behind __cpp_lib_integer_sequence. * include/bits/uses_allocator_args.h: Switch to bits/version.h for __cpp_lib_make_obj_using_allocator. Guard header behind that FTM. * include/bits/unordered_map.h: Switch to bits/version.h for __cpp_lib_unordered_map_try_emplace. (try_emplace): Guard behind __cpp_lib_unordered_map_try_emplace. * include/bits/unique_ptr.h: Switch to bits/version.h for __cpp_lib_{constexpr_memory,make_unique}. (make_unique): Guard behind __cpp_lib_make_unique. * include/bits/stl_vector.h: Switch to bits/version.h for __cpp_lib_constexpr_vector. * include/bits/stl_uninitialized.h: Switch to bits/version.h for __cpp_lib_raw_memory_algorithms. (uninitialized_default_construct) (uninitialized_default_construct_n, uninitialized_move) (uninitialized_move_n, uninitialized_value_construct) (uninitialized_value_construct_n): Guard behind __cpp_lib_raw_memory_algorithms. * include/bits/stl_tree.h: Switch to bits/version.h for __cpp_lib_generic_associative_lookup. * include/bits/stl_stack.h: Switch to bits/version.h for __cpp_lib_adaptor_iterator_pair_constructor. (stack): Guard iterator-pair constructor behind __cpp_lib_adaptor_iterator_pair_constructor. * include/bits/stl_queue.h: Switch to bits/version.h for __cpp_lib_adaptor_iterator_pair_constructor. (queue): Guard iterator-pair constructor behind __cpp_lib_adaptor_iterator_pair_constructor. * include/bits/stl_pair.h: Switch to bits/version.h for __cpp_lib_{concepts,tuples_by_type}. (get): Guard type-getting overloads behind __cpp_lib_tuples_by_type. * include/bits/stl_map.h: Switch to bits/version.h for __cpp_lib_map_try_emplace. (map<>::try_emplace): Guard behind __cpp_lib_map_try_emplace. * include/bits/stl_list.h: Switch to bits/version.h for __cpp_lib_list_remove_return_type. (__remove_return_type, _GLIBCXX_LIST_REMOVE_RETURN_TYPE_TAG) [C++20]: guard behind __cpp_lib_list_remove_return_type instead. * include/bits/stl_iterator.h: Switch to bits/version.h for __cpp_lib_{constexpr_iterator,array_constexpr} and __cpp_lib_{make_reverse_iterator,move_iterator_concept}. (make_reverse_iterator): Guard behind __cpp_lib_make_reverse_iterator. (iterator_concept et al): Guard __cpp_lib_move_iterator_concept changes behind that FTM. * include/bits/stl_function.h: Switch to bits/version.h for __cpp_lib_transparent_operators. (equal_to, not_equal_to, greater, less, greater_equal) (less_equal, bit_and, bit_or, bit_xor, bit_not, logical_and) (logical_or, logical_not, plus, minus, multiplies, divides) (modulus, negate): Guard '= void' fwdecls behind __cpp_lib_transparent_operators. (plus<void>, minus<void>, multiplies<void>, divides<void>) (modulus<void>, negate<void>, logical_and<void>, logical_or<void>) (logical_not<void>, bit_and<void>, bit_or<void>, bit_xor<void>) (equal_to<void>, not_equal_to<void>, greater<void>, less<void>) (greater_equal<void>, less_equal<void>, bit_not<void>) (__has_is_transparent): Guard behind __cpp_lib_transparent_operators. * include/bits/stl_algobase.h: Switch to bits/version.h for __cpp_lib_robust_nonmodifying_seq_ops. (robust equal, mismatch): Guard behind __cpp_lib_nonmember_container_access. * include/bits/stl_algo.h: Swtich to bits/version.h for __cpp_lib_{clamp,sample}. (clamp): Guard behind __cpp_lib_clamp. (sample): Guard behind __cpp_lib_sample. * include/bits/specfun.h: Switch to bits/version.h for __cpp_lib_math_special_functions and __STDCPP_MATH_SPEC_FUNCS__. * include/bits/shared_ptr_base.h: Switch to bits/version.h for __cpp_lib_{smart_ptr_for_overwrite,shared_ptr_arrays}. (_Sp_overwrite_tag): Guard behind __cpp_lib_smart_ptr_for_overwrite. * include/bits/shared_ptr_atomic.h: Switch to bits/version.h for __cpp_lib_atomic_shared_ptr. * include/bits/shared_ptr.h: Switch to bits/version.h for __cpp_lib_{enable_shared_from_this,shared_ptr_weak_type}. (shared_ptr<T>::weak_type): Guard behind __cpp_lib_shared_ptr_weak_type. (enable_shared_from_this<T>::weak_from_this): Guard behind __cpp_lib_enable_shared_from_this. * include/bits/ranges_cmp.h: Switch to bits/version.h for __cpp_lib_ranges. * include/bits/ranges_algo.h: Switch to bits/version.h for __cpp_lib_{shift,ranges_{contains,find_last,fold,iota}}. * include/bits/range_access.h: Switch to bits/version.h for __cpp_lib_nonmember_container_access (size, empty, data): Guard behind __cpp_lib_nonmember_container_access. (ssize): Guard behind __cpp_lib_ssize. * include/bits/ptr_traits.h: Switch to bits/version.h. for __cpp_lib_{constexpr_memory,to_address}. (to_address): Guard behind __cpp_lib_to_address. * include/bits/node_handle.h: Switch to bits/version.h for __cpp_lib_node_extract. Guard header behind that FTM. * include/bits/move_only_function.h: Switch to bits/version.h for __cpp_lib_move_only_function. Guard header behind that FTM. * include/bits/move.h: Switch to bits/version.h for __cpp_lib_addressof_constexpr. * include/bits/ios_base.h: Switch to bits/version.h for __cpp_lib_ios_noreplace. (noreplace): Guard with __cpp_lib_ios_noreplace. * include/bits/hashtable.h: Switch to bits/version.h for __cpp_lib_generic_unordered_lookup. (_M_equal_range_tr, _M_count_tr, _M_find_tr): Guard behind __cpp_lib_generic_unordered_lookup. * include/bits/forward_list.h: Switch to bits/version.h for __cpp_lib_list_remove_return_type. (__remove_return_type): Guard behind __cpp_lib_list_remove_return_type. * include/bits/erase_if.h: Switch to bits/version.h for __cpp_lib_erase_if. * include/bits/cow_string.h: Switch to bits/version.h for __cpp_lib_constexpr_string. * include/bits/chrono.h: Swtich to bits/version.h for __cpp_lib_chrono{,_udls}. (ceil): Guard behind __cpp_lib_chrono. (operator""ns et al): Guard behind __cpp_lib_chrono_udls. * include/bits/char_traits.h: Switch to bits/version.h for __cpp_lib_constexpr_char_traits. * include/bits/basic_string.h: Switch to bits/version.h for __cpp_lib_{constexpr_string,string_{resize_and_overwrite,udls}}. (resize_and_overwrite): Guard behind __cpp_lib_string_resize_and_overwrite. (operator""s): Guard behind __cpp_lib_string_udls. * include/bits/atomic_wait.h: Switch to bits/version.h for __cpp_lib_atomic_wait. Guard header behind that FTM. * include/bits/atomic_base.h: Switch to bits/version.h for __cpp_lib_atomic_value_initialization and __cpp_lib_atomic_flag_test. (atomic_flag::test): Guard behind __cpp_lib_atomic_flag_test, rather than C++20. * include/bits/allocator.h: Switch to bits/version.h for __cpp_lib_incomplete_container_elements. * include/bits/alloc_traits.h: Switch to using bits/version.h for __cpp_lib_constexpr_dynamic_alloc and __cpp_lib_allocator_traits_is_always_equal. * include/bits/align.h: Switch to bits/version.h for defining __cpp_lib_assume_aligned. (assume_aligned): Guard with __cpp_lib_assume_aligned. * include/bits/algorithmfwd.h: Switch to bits/version.h for defining __cpp_lib_constexpr_algorithms. * include/std/stacktrace: Switch to bits/version.h for __cpp_lib_stacktrace. Guard header behind that FTM. * testsuite/23_containers/array/tuple_interface/get_neg.cc: Update line numbers.
2023-08-09libstdc++: Fix some -Wunused-parameter warningsJonathan Wakely1-2/+2
libstdc++-v3/ChangeLog: * include/bits/alloc_traits.h (allocate): Add [[maybe_unused]] attribute. * include/bits/regex_executor.tcc: Remove name of unused parameter. * include/bits/shared_ptr_atomic.h (atomic_is_lock_free): Likewise. * include/bits/stl_uninitialized.h: Likewise. * include/bits/streambuf_iterator.h (operator==): Likewise. * include/bits/uses_allocator.h: Likewise. * include/c_global/cmath (isfinite, isinf, isnan): Likewise. * include/std/chrono (zoned_time): Likewise. * include/std/future (__future_base::_S_allocate_result): Likewise. (packaged_task): Likewise. * include/std/optional (_Optional_payload_base): Likewise. * include/std/scoped_allocator (__inner_type_impl): Likewise. * include/std/tuple (_Tuple_impl): Likewise.
2023-03-30libstdc++: Use std::remove_cv_t in std::optional::transform [PR109340]Jonathan Wakely1-4/+4
We need to strip cv-qualifiers from the result of the callable passed to std::optional::transform. For std::expected::transform and std::expected::transform_error I noticed we were stripping cv-qualifiers but were also incorrectly stripping references. libstdc++-v3/ChangeLog: PR libstdc++/109340 * include/std/expected (expected::transform): Use std::remove_cv_t instead of std::remove_cvref_t. (expected::transform_error): Likewise. (expected<cv void, E>::transform): Likewise. (expected<cv void, E>::transform_error): Likewise. * include/std/optional (transform): Use std::remove_cv_t. * testsuite/20_util/optional/monadic/pr109340.cc: New test.
2023-03-30libstdc++: Enforce requirements on template argument of std::optionalJonathan Wakely1-1/+1
The standard does not allow std::optional<T&>, std::optional<T[1]>, std::optional<T()> etc. and although we do give errors, they come from down inside the internals of std::optional. We could improve the static assertions at the top of the class so that users get a more precise diagnostic: optional:721:21: error: static assertion failed 721 | static_assert(is_object_v<_Tp> && !is_array_v<_Tp>); libstdc++-v3/ChangeLog: * include/std/optional (optional): Adjust static assertion to reject arrays and functions as well as references. * testsuite/20_util/optional/requirements_neg.cc: New test.
2023-01-16Update copyright years.Jakub Jelinek1-1/+1
2022-04-14libstdc++: Fix missing and incorrect feature test macros [PR105269]Jonathan Wakely1-6/+6
libstdc++-v3/ChangeLog: PR libstdc++/105269 * include/bits/stl_vector.h (__cpp_lib_constexpr_vector): Define. * include/c_compatibility/stdatomic.h (__cpp_lib_stdatomic_h): Define. * include/std/optional (__cpp_lib_optional): Define new value for C++23. (__cpp_lib_monadic_optional): Remove. * include/std/version (__cpp_lib_constexpr_vector): Define. (__cpp_lib_stdatomic_h): Define. (__cpp_lib_optional): Define new value for C++23. (__cpp_lib_monadic_optional): Remove. * testsuite/20_util/optional/monadic/and_then.cc: Adjust. * testsuite/20_util/optional/requirements.cc: Adjust for C++23. * testsuite/20_util/optional/version.cc: Likewise. * testsuite/23_containers/vector/cons/constexpr.cc: Check feature test macro. * testsuite/29_atomics/headers/stdatomic.h/c_compat.cc: Likewise. * testsuite/20_util/optional/monadic/version.cc: Removed. * testsuite/23_containers/vector/requirements/version.cc: New test. * testsuite/29_atomics/headers/stdatomic.h/version.cc: New test.
2022-01-03Update copyright years.Jakub Jelinek1-1/+1
2021-10-21libstdc++: Remove constraints from std::optional monadic ops [PR102863]Jonathan Wakely1-8/+8
The constraints on transform and and_then can cause errors when checking satisfaction. The constraints that were present in R6 of the paper were moved for he final F8 revision, and so should have been included in the implementation. libstdc++-v3/ChangeLog: PR libstdc++/102863 * include/std/optional (optional::and_then, optional::transform): Remove requires-clause. * testsuite/20_util/optional/monadic/and_then.cc: Check overload resolution doesn't cause errors. * testsuite/20_util/optional/monadic/transform.cc: Likewise.
2021-10-19libstdc++: Implement monadic operations for std::optional (P0798R8)Jonathan Wakely1-5/+177
Another new addition to the C++23 working draft. The new member functions of std::optional are only defined for C++23, but the new members of _Optional_payload_base are defined for C++20 so that they can be used in non-propagating-cache in <ranges>. The _Optional_payload_base::_M_construct member can also be used in non-propagating-cache now, because it's constexpr since r12-4389. There will be an LWG issue about the feature test macro, suggesting that we should just bump the value of __cpp_lib_optional instead. I haven't done that here, but it can be changed once consensus is reached on the change. libstdc++-v3/ChangeLog: * include/std/optional (_Optional_payload_base::_Storage): Add constructor taking a callable function to invoke. (_Optional_payload_base::_M_apply): New function. (__cpp_lib_monadic_optional): Define for C++23. (optional::and_then, optional::transform, optional::or_else): Define for C++23. * include/std/ranges (__detail::__cached): Remove. (__detail::__non_propagating_cache): Remove use of __cached for contained value. Use _Optional_payload_base::_M_construct and _Optional_payload_base::_M_apply to set the contained value. * include/std/version (__cpp_lib_monadic_optional): Define. * testsuite/20_util/optional/monadic/and_then.cc: New test. * testsuite/20_util/optional/monadic/or_else.cc: New test. * testsuite/20_util/optional/monadic/or_else_neg.cc: New test. * testsuite/20_util/optional/monadic/transform.cc: New test. * testsuite/20_util/optional/monadic/version.cc: New test.
2021-10-14libstdc++: Add missing constexpr to std::optional (P2231R1)Jonathan Wakely1-15/+24
This implements the changes in P2231R1 which make std::optional fully constexpr in C++20. libstdc++-v3/ChangeLog: * include/bits/stl_construct.h (_Construct): Use std::construct_at when constant evaluated. * include/std/optional (_Storage, _Optional_payload, optional): Add constexpr as specified by P2231R1. * include/std/version (__cpp_lib_optional): Update value for C++20. * testsuite/20_util/optional/requirements.cc: Check feature test macro. * testsuite/20_util/optional/constexpr/assign.cc: New test. * testsuite/20_util/optional/constexpr/cons/conv.cc: New test. * testsuite/20_util/optional/constexpr/modifiers.cc: New test. * testsuite/20_util/optional/constexpr/swap.cc: New test. * testsuite/20_util/optional/version.cc: New test.
2021-09-16libstdc++: Add noexcept to std::nullopt_t constructorJonathan Wakely1-1/+1
Signed-off-by: Jonathan Wakely <jwakely@redhat.com> libstdc++-v3/ChangeLog: * include/std/optional (nullptr_t): Make constructor noexcept.
2021-07-27libstdc++: Simplify std::optional::value()Jonathan Wakely1-22/+21
The structure of these functions likely dates from the time before G++ fully supported C++14 extended constexpr, so that the throw expression had to be the operand of a conditional expression. That is not true now, so we can use a more straightforward version of the code. We can also simplify the declaration of __throw_bad_optional_access by using the C++11-style [[noreturn]] attribute so that a separate declaration isn't needed. libstdc++-v3/ChangeLog: * include/experimental/optional (__throw_bad_optional_access): Replace GNU attribute with C++11 attribute. (optional::value, optional::value_or): Use if statements instead of conditional expressions. * include/std/optional (__throw_bad_optional_access) (optional::value, optional::value_or): Likewise.
2021-07-27libstdc++: Reduce header dependencies on <array> and <utility>Jonathan Wakely1-2/+2
This refactoring reduces the memory usage and compilation time to parse a number of headers that depend on std::pair, std::tuple or std::array. Previously the headers for these class templates were all intertwined, due to the common dependency on std::tuple_size, std::tuple_element and their std::get overloads. This decouples the headers by moving some parts of <utility> into a new <bits/utility.h> header. This means that <array> and <tuple> no longer need to include the whole of <utility>, and <tuple> no longer needs to include <array>. This decoupling benefits headers such as <thread> and <scoped_allocator> which only need std::tuple, and so no longer have to parse std::array. Some other headers such as <any>, <optional> and <variant> no longer need to include <utility> just for the std::in_place tag types, so do not have to parse the std::pair definitions. Removing direct uses of <utility> also means that the std::rel_ops namespace is not transitively declared by other headers. Signed-off-by: Jonathan Wakely <jwakely@redhat.com> libstdc++-v3/ChangeLog: * include/Makefile.am: Add bits/utility.h header. * include/Makefile.in: Regenerate. * include/bits/utility.h: New file. * include/std/utility (tuple_size, tuple_element): Move to new header. * include/std/type_traits (__is_tuple_like_impl<tuple<T...>>): Move to <tuple>. (_Index_tuple, _Build_index_tuple, integer_sequence): Likewise. (in_place_t, in_place_index_t, in_place_type_t): Likewise. * include/bits/ranges_util.h: Include new header instead of <utility>. * include/bits/stl_pair.h (tuple_size, tuple_element): Move partial specializations for std::pair here. (get): Move overloads for std::pair here. * include/std/any: Include new header instead of <utility>. * include/std/array: Likewise. * include/std/memory_resource: Likewise. * include/std/optional: Likewise. * include/std/variant: Likewise. * include/std/tuple: Likewise. (__is_tuple_like_impl<tuple<T...>>): Move here. (get) Declare overloads for std::array. * include/std/version (__cpp_lib_tuples_by_type): Change type to long. * testsuite/20_util/optional/84601.cc: Include <utility>. * testsuite/20_util/specialized_algorithms/uninitialized_fill/constrained.cc: Likewise. * testsuite/23_containers/array/tuple_interface/get_neg.cc: Adjust dg-error line numbers. * testsuite/std/ranges/access/cbegin.cc: Include <utility>. * testsuite/std/ranges/access/cend.cc: Likewise. * testsuite/std/ranges/access/end.cc: Likewise. * testsuite/std/ranges/single_view.cc: Likewise.
2021-06-09libstdc++: Fix constraint on std::optional assignment [PR 100982]Jonathan Wakely1-1/+1
libstdc++-v3/ChangeLog: PR libstdc++/100982 * include/std/optional (optional::operator=(const optional<U>&)): Fix value category used in is_assignable check. * testsuite/20_util/optional/assignment/100982.cc: New test.
2021-06-07libstdc++: Constrain three-way comparison for std::optional [PR 98842]Jonathan Wakely1-0/+7
The operator<=>(const optional<T>&, const U&) operator is supposed to be constrained with three_way_comparable_with<U, T> so that it can only be used when T and U are weakly-equality-comparable and also three-way comparable. Adding that constrain completely breaks std::optional comparisons, because it causes constraint recursion. To avoid that, an additional check that U is not a specialization of std::optional is needed. That appears to be a defect in the standard and should be reported to LWG. Signed-off-by: Jonathan Wakely <jwakely@redhat.com> libstdc++-v3/ChangeLog: PR libstdc++/98842 * include/std/optional (operator<=>(const optional<T>& const U&)): Add missing constraint and add workaround for template recursion. * testsuite/20_util/optional/relops/three_way.cc: Check that type without equality comparison cannot be compared when wrapped in std::optional.
2021-01-04Update copyright years.Jakub Jelinek1-1/+1
2020-11-05libstdc++: Fix constraints on std::optional comparisons [PR 96269]Jonathan Wakely1-18/+48
The relational operators for std::optional were using the wrong types in the declval expressions used to constrain them. Instead of using const lvalues they were using non-const rvalues, which meant that a type might satisfy the constraints but then give an error when the function body was instantiated. libstdc++-v3/ChangeLog: PR libstdc++/96269 * include/std/optional (operator==, operator!=, operator<) (operator>, operator<=, operator>=): Fix types used in SFINAE constraints. * testsuite/20_util/optional/relops/96269.cc: New test.
2020-07-06libstdc++: Cleanup whitespace and type trait usage in <optional>Jonathan Wakely1-102/+107
This makes the formatting in <optional> consistent and also removes redundant && tokens from template arguments for traits like is_constructible and is_convertible. libstdc++-v3/ChangeLog: * include/std/optional (_Optional_payload_base, _Optional_base) (optional, __optional_hash_call_base): Adjust whitespace and other formatting. Remove redundant && tokens on template arguments to type traits.
2020-07-06libstdc++: Constrain std::make_optionalJonathan Wakely1-8/+17
The standard rquires that std::make_optional is constrained similarly to the std::optional constructors, which our implementation fails to do. As a conforming extension this also adds a noexcept-specifier to each std::make_optional overload. libstdc++-v3/ChangeLog: * include/std/optional (make_optional): Add enable_if constraints and noexcept-specifier to each overload. * testsuite/20_util/optional/make_optional-2.cc: New test.
2020-07-06libstdc++: Add noexcept to std::optional initialization (PR 96036)Jonathan Wakely1-6/+25
libstdc++-v3/ChangeLog: PR libstdc++/96036 * include/std/optional (optional): Add noexcept-specifier to every constructor, assignment operator, emplace function and dereference operator. * testsuite/20_util/optional/assignment/noexcept.cc: New test. * testsuite/20_util/optional/cons/noexcept.cc: New test.
2020-06-19libstdc++: Optimize std::optional default constructorMarc Glisse1-1/+1
The attached patch changes the code generated for std::optional<std::array<int,1024>>f(){return{};} from movq $0, (%rdi) movq %rdi, %r8 leaq 8(%rdi), %rdi xorl %eax, %eax movq $0, 4084(%rdi) movq %r8, %rcx andq $-8, %rdi subq %rdi, %rcx addl $4100, %ecx shrl $3, %ecx rep stosq movq %r8, %rax or with different tuning subq $8, %rsp movl $4100, %edx xorl %esi, %esi call memset addq $8, %rsp to the much shorter movb $0, 4096(%rdi) movq %rdi, %rax i.e. the same as the nullopt constructor. The constructor was already non-trivial, so we don't lose that. It passes the testsuite without regression, but there is no new testcase to verify the better codegen. libstdc++-v3/ChangeLog: * include/std/optional (optional()): Explicitly define it.
2020-06-09libstdc++: Define std::bad_optional_access constructor as defaultedJonathan Wakely1-4/+3
The standard requires that std::bad_optional_access' default constructor has a non-throwing exception specification. * include/std/optional (bad_optional_access): Define default constructor and destructor as defaulted. * testsuite/20_util/optional/bad_access.cc: New test.
2020-02-21libstdc++: Define <=> for tuple, optional and variantJonathan Wakely1-0/+26
Another piece of P1614R2. * include/std/optional (operator<=>(optional<T>, optional<U>)) (operator<=>(optional<T>, nullopt), operator<=>(optional<T>, U)): Define for C++20. * include/std/tuple (__tuple_cmp): New helper function for <=>. (operator<=>(tuple<T...>, tuple<U>...)): Define for C++20. * include/std/variant (operator<=>(variant<T...>, variant<T...>)) (operator<=>(monostate, monostate)): Define for C++20. * testsuite/20_util/optional/relops/three_way.cc: New test. * testsuite/20_util/tuple/comparison_operators/three_way.cc: New test. * testsuite/20_util/variant/89851.cc: Move to ... * testsuite/20_util/variant/relops/89851.cc: ... here. * testsuite/20_util/variant/90008.cc: Move to ... * testsuite/20_util/variant/relops/90008.cc: ... here. * testsuite/20_util/variant/relops/three_way.cc: New test.
2020-01-28Fix 2 typos in documentation of libstdc++.Martin Liska1-1/+1
PR libstdc++/93478 * include/std/atomic: Fix typo. * include/std/optional: Likewise.
2020-01-01Update copyright years.Jakub Jelinek1-1/+1
From-SVN: r279813