The std::variant move assignment operator should not be trivial if the
variant is not trivially move constructible.
* include/std/variant (__detail::__variant::_Traits): Make
_S_trivial_copy_assign depend on _S_trivial_copy_ctor and make
_S_trivial_move_assign depend on _S_trivial_move_ctor, as per
P0602R4.
(__detail::__variant::_Copy_assign_alias): Only depend on
_S_trivial_copy_assign, which subsumes _S_trivial_copy_ctor now.
* testsuite/20_util/variant/compile.cc: Correct checks for trivial
move assignment operators.
From-SVN: r270510
Also refactor some constraints slightly to be more readable.
PR libstdc++/90165
* include/std/variant (variant::__not_self): New helper for the
is_same_v<remove_cvref_t<T>, variant>==false constraints.
(variant::__to_type_impl): Remove.
(variant::__to_type): Add default argument to check pack size, instead
of using __to_type_impl.
(variant::__accepted_type): Add default argument using __not_self.
(variant::__is_in_place_tag, variant::__not_in_place_tag): New helpers
for variant(T&&) constructor constraint.
(variant::variant(T&&)): Use __not_in_place_tag in constraints.
Extract __accepted_type into a named template parameter for reuse in
other constraints and in the exception specification.
(variant::variant(in_place_type_t<T>, Args&&...))
(variant::variant(in_place_type_t<T>, initializer_list<U>, Args&&...))
(variant::variant(in_place_index_t<T>, Args&&...))
(variant::variant(in_place_index_t<T>, initializer_list<U>, Args&&...))
(variant::operator=T&&)): Remove redundant && from trait arguments.
* testsuite/20_util/variant/compile.cc: Check variant(T&&) constructor
isn't used for in_place_type or in_place_index arguments.
From-SVN: r270509
The P0318R1 paper added to the C++2a draft recently was not the latest
version of the paper, and should have included these changes. These
changes will be made to the working draft via a Defect Report, so I'm
applying them to libstdc++ now.
* include/std/type_traits (unwrap_reference_t): Define for C++2a.
(unwrap_ref_decay): Remove inheritance from unwrap_reference.
* testsuite/20_util/unwrap_reference/1.cc: Adjust test to use alias.
From-SVN: r270506
A regression was introduced by the recent changes to provide the strong
exception safety guarantee for "never valueless" types that have O(1),
non-throwing move assignment. The problematic code is:
else if constexpr (__detail::__variant::_Never_valueless_alt<type>())
{
// This construction might throw:
variant __tmp(in_place_index<_Np>, __il,
std::forward<_Args>(__args)...);
// But _Never_valueless_alt<type> means this won't:
*this = std::move(__tmp);
}
When the variant is not assignable, the assignment is ill-formed, so
should not be attempted. When the variant has a copy assignment operator
but not a move assignment operator, the assignment performs a copy
assignment and that could throw, so should not be attempted.
The solution is to only take that branch when the variant has a move
assignment operator, which is determined by the _Traits::_S_move_assign
constant. When that is false the strong exception safety guarantee is
not possible, and so the __never_valueless function should also depend
on _S_move_assign.
While testing the fixes for this I noticed that the partial
specialization _Never_valueless_alt<basic_string<C,T,A>> incorrectly
assumed that is_nothrow_move_constructible<basic_string<C,T,A>> is
always true, but that's wrong for fully-dynamic COW strings. Fix the
partial specialization, and improve the comment describing
_Never_valueless_alt to be clear it depends on move construction as well
as move assignment.
Finally, I also observed that _Variant_storage<false, T...>::_M_valid()
was not taking advantage of the __never_valueless<T...>() function to
avoid a runtime check. Only the _Variant_storage<true, T...>::_M_valid()
function was using __never_valueless. That is also fixed.
PR libstdc++/87431
* include/bits/basic_string.h (_Never_valueless_alt): Make partial
specialization also depend on is_nothrow_move_constructible.
* include/std/variant (__detail::__variant::__never_valueless()):
Only true if the variant would have a move assignment operator.
(__detail::__variant::_Variant_storage<false, T...>::_M_valid()):
Check __never_valueless<T...>().
(variant::emplace): Only perform non-throwing move assignments
for never-valueless alternatives if the variant has a move assignment
operator.
* testsuite/20_util/variant/compile.cc: Check that never-valueless
types can be emplaced into non-assignable variants.
* testsuite/20_util/variant/run.cc: Check that never-valueless types
don't get copied when emplaced into non-assignable variants.
From-SVN: r270502
These earlier Darwin versions have “FP_≈” inside a
comment in architecture/{ppc,i386}/math.h, which is
included by math.h which causes the tests to fail.
The intent of the tests (i.e. to ensure that the
library itself does not emit non-ascii) is covered
by other platforms, including later Darwin editions.
2019-04-21 Iain Sandoe <iain@sandoe.co.uk>
* testsuite/17_intro/headers/c++1998/charset.cc: Skip for Darwin8
to Darwin10.
* testsuite/17_intro/headers/c++2011/charset.cc: Likewise.
* testsuite/17_intro/headers/c++2014/charset.cc: Likewise.
* testsuite/17_intro/headers/c++2017/charset.cc: Likewise.
* testsuite/17_intro/headers/c++2020/charset.cc: Likewise.
From-SVN: r270479
* include/pstl/algorithm_impl.h
(__internal::__brick_equal): use "4 iterator" version of
std::equal().
(__internal::__brick_equal): use simd for random access
iterators on unsequenced execution policies.
(__internal::__pattern_equal): add "4 iterator" version
(__internal::__pattern_equal): dispatch to simd __brick_equal
for vector-only execution policies.
(__internal::__pattern_equal): dispatch to __parallel_or for
parallel execution policies.
* include/pstl/glue_algorithm_impl.h
(std::equal): dispatch to "4 iterator" version of
__internal::__pattern_equal().
From-SVN: r270463
In order to make alias templates useful for SFINAE we instantiate them under
the prevailing 'complain' argument, so an error encountered while
instantiating during SFINAE context is silent. The problem in this PR comes
when we later look up the erroneous instantiation and don't give an error at
that point. Fixed by not adding an erroneous instantiation to the hash
table, so we instantiate it again when needed and get the error. This
required changes to a number of tests, which previously said "substitution
failed:" with no explanation of what the failure was; now we properly
explain.
* pt.c (tsubst_decl) [TYPE_DECL]: Don't put an erroneous decl in the
hash table when we're in SFINAE context.
From-SVN: r270433
While testing the fix I also discovered that operator== assumes the
elements are comparable with operator!= which is not required.
PR libstdc++/90105
* include/bits/forward_list.h (operator==): Do not use operator!= to
compare elements.
(forward_list<T, A>::sort(Comp)): When elements are equal take the one
earlier in the list, so that sort is stable.
* testsuite/23_containers/forward_list/operations/90105.cc: New test.
* testsuite/23_containers/forward_list/comparable.cc: Test with
types that meet the minimum EqualityComparable and LessThanComparable
requirements. Remove irrelevant comment.
From-SVN: r270427
The standard says the std::variant copy constructor is defined as
deleted unless all alternative types are copy constructible, but we were
making it also depend on move constructible. Fix the condition and
enhance the tests to check the semantics with pathological copy-only
types (i.e. supporting copying but having deleted moves).
The enhanced tests revealed a regression in copy assignment for
non-trivial alternative types, where the assignment would not be
performed because the condition in the _Copy_assign_base visitor is
false: is_same_v<remove_reference_t<T&>, remove_reference_t<const T&>>.
* include/std/variant (__detail::__variant::_Traits::_S_copy_assign):
Do not depend on whether all alternative types are move constructible.
(__detail::__variant::_Copy_assign_base::operator=): Remove cv-quals
from the operand when deciding whether to perform the assignment.
* testsuite/20_util/variant/compile.cc (DeletedMoves): Define type
with deleted move constructor and deleted move assignment operator.
(default_ctor, copy_ctor, move_ctor, copy_assign, move_assign): Check
behaviour of variants with DeletedMoves as an alternative.
* testsuite/20_util/variant/run.cc (DeletedMoves): Define same type.
(move_ctor, move_assign): Check that moving a variant with a
DeletedMoves alternative falls back to copying instead of moving.
From-SVN: r270425
The string literal is optional in C++17 and all these are empty so add
no value.
* testsuite/20_util/variant/compile.cc: Remove empty string literals
from static_assert declarations.
From-SVN: r270424
* testsuite/20_util/variant/compile.cc (MoveCtorOnly): Fix type to
actually match its name.
(MoveCtorAndSwapOnly): Define new type that adds swap to MoveCtorOnly.
(test_swap()): Fix result for MoveCtorOnly and check
MoveCtorAndSwapOnly.
From-SVN: r270423
In C++1z drafts up to N4606 the constexpr keyword was missing from the
detailed description of this function, despite being shown in the class
synopsis. That was fixed editorially for N4618, but our implementation
was not corrected to match.
* include/std/optional (optional::value_or(U&&) &&): Add missing
constexpr specifier.
* testsuite/20_util/optional/constexpr/observers/4.cc: Check value_or
for disengaged optionals and rvalue optionals.
* testsuite/20_util/optional/observers/4.cc: Likewise.
From-SVN: r270409
This also replaces calls to __TBB_ASSERT so that there are two macro
definitions provided by c++config -
__PSTL_ASSERT(_Condition)
__PSTL_ASSERT_MSG(_Condition, _Message)
* include/bits/c++config:
Add definition for __PSTL_ASSERT.
Add definition for __PSTL_ASSERT_MSG.
* include/pstl/algorithm_impl.h: Replace use of assert().
* include/pstl/numeric_impl.h: Replace use of assert().
* include/pstl/parallel_backend_tbb.h:
Replace use of assert().
Replace use of __TBB_ASSERT().
* include/pstl/parallel_backend_utils.h: Replace use of assert().
From-SVN: r270293
The epiphany-elf target aligns structs to 8 bytes, which causes the
static_assert(alignof(_Chunk) == 1) to fail.
Instead of requiring _Chunks to be positionable at any alignment, ensure
new buffers are aligned to alignof(_Chunk). Because the buffer size is a
power of two, we know that both the buffer size and sizeof(_Chunk) are
multiples of alignof(_Chunk). So is p is aligned to alignof(_Chunk) then
so is (p + size - sizeof(_Chunk)). So just ensure the new buffer is
aligned to at least alignof(_Chunk), which should already be true
because the caller requests at least alignof(max_align_t).
PR libstdc++/90046
* src/c++17/memory_resource.cc
(monotonic_buffer_resource::_Chunk::allocate): Increase alignment if
needed to allow placing a _Chunk at the end of the buffer.
(monotonic_buffer_resource::_M_new_buffer): Remove static_assert.
From-SVN: r270291
* doc/xml/faq.xml: Add information about emergency EH pool.
* doc/xml/manual/debug.xml: Update list of memory debugging tools.
Move outdated information on mt_allocator to a separate section.
* doc/xml/manual/evolution.xml: Clarify that GLIBCXX_FORCE_NEW
doesn't affect the default allocator.
From-SVN: r270264
Add a test for the regression introduced with r269422 and fixed with
r270056.
PR libstdc++/89851
* testsuite/20_util/variant/89851.cc: New test.
From-SVN: r270249
* include/std/variant: Adjust whitespace. Add comments.
(_Multi_array): Leave primary template undefined.
(_Multi_array<_Tp>): Define partial specialization for base case of
recursion.
(__gen_vtable_impl, __gen_vtable): Remove redundant && from type
which is always a reference.
(__gen_vtable::_S_apply()): Remove function, inline body into
default member initializer.
* testsuite/20_util/variant/visit.cc: Test with noncopyable types.
From-SVN: r270238
The __visitor_result_type helper didn't use std::invoke and so didn't
compile when the visitor was a pointer-to-member rather than a function
object. Use std::invoke_result instead.
* include/std/variant (__variant_idx_cookie): Add member type.
(__visitor_result_type): Remove.
(__do_visit): Use invoke_result instead of __visitor_result_type.
* testsuite/20_util/variant/visit.cc: New test.
From-SVN: r270237
* include/std/variant (__do_visit): Add a template parameter
for enforcing same return types for visit.
(__gen_vtable_impl): Likewise.
(_S_apply_single_alt): Adjust.
(__visit_invoke_impl): New. Handle casting to void.
(__do_visit_invoke): New. Enforces same return types.
(__do_visit_invoke_r): New. Converts return types.
(__visit_invoke): Adjust.
(__gen_vtable): Add a template parameter for enforcing
same return types for visit.
* testsuite/20_util/variant/visit_r.cc: Add a test for a visitor with
different return types.
* testsuite/20_util/variant/visit_neg.cc: New. Ensures that
visitors with different return types don't accidentally
compile with regular visitation.
From-SVN: r270216
The equality operators for directory iterators are not explicitly
specified in the standard, they're only required to meet the iterator
requirements. This means we don't need to declare them at namespace
scope and can implement them as hidden friends.
Also add 'noexcept' to directory_iterator's dereference operators.
* include/bits/fs_dir.h (directory_iterator::operator*)
(directory_iterator::operator->): Add noexcept.
(operator==, operator!=): Replace namespace-scope equality operators
for directory iterators with hidden friends.
From-SVN: r270175
Implement the proposed resolution of LWG 2708 by moving the _M_options
and _M_pending members out of the recursive_directory_iterator into the
shared _Dir_stack object. Because _Dir_stack is an opaque type, the
member functions that access the _M_options and _M_pending variables
cannot be inline. Move them into the library.
As a drive-by fix, add noexcept to the non-throwing member functions of
recursive_directory_iterator.
* config/abi/pre/gnu.ver: Export new symbols.
* include/bits/fs_dir.h (recursive_directory_iterator::options())
(recursive_directory_iterator::recursion_pending())
(recursive_directory_iterator::disable_recursion_pending()): Remove
inline definitions. Make noexcept.
(recursive_directory_iterator::depth())
(recursive_directory_iterator::operator*())
(recursive_directory_iterator::operator->()): Make noexcept.
(recursive_directory_iterator::_M_options)
(recursive_directory_iterator::_M_pending): Remove data members.
* src/c++17/fs_path.cc (_Dir_stack): Add constructor and data members.
(recursive_directory_iterator::recursive_directory_iterator): Remove
ctor-initializer. Use new constructor for _Dir_stack.
(recursive_directory_iterator::options())
(recursive_directory_iterator::recursion_pending())
(recursive_directory_iterator::disable_recursion_pending()): Add
non-inline definitions.
(recursive_directory_iterator::depth()): Make noexcept.
(recursive_directory_iterator::increment(error_code&))
(recursive_directory_iterator::pop(error_code&)): Adjust to new
location of options and recursion_pending members.
* testsuite/27_io/filesystem/iterators/recursion_pending.cc: New test.
* testsuite/util/testsuite_fs.h (__gnu_test::scoped_file): Add
user-declared move constructor and assignment operator, to make the
type move-only.
From-SVN: r270173
We need to handle DT_UNKNOWN earlier, not only during directory
recursion, so that the cached file_type value in the directory_entry
won't be used.
* src/c++17/fs_dir.cc (_Dir::advance(bool, error_code&)): Handle
d_type == DT_UNKNOWN immediately.
(_Dir::should_recurse(bool, error_code&)): Remove file_type::unknown
handling here.
* testsuite/27_io/filesystem/iterators/caching.cc: New test.
From-SVN: r270172
The standard says "If *this and p are the same object, has no effect."
Previously we ended up clearing the path.
* include/bits/fs_path.h (path::operator=(path&&)): Check for self
assignment.
* src/c++17/fs_path.cc (path::operator=(const path&)): Likewise.
* testsuite/27_io/filesystem/path/assign/copy.cc: Test self
assignment.
From-SVN: r270171
Avoid creating arbitrarily large objects on the stack when emplacing
trivially copyable objects into a variant. Currently we provide the
strong exception-safety guarantee for all trivially copyable types, by
constructing a second variant and then doing a non-throwing move
assignment from the temporary. This patch restricts that behaviour to
trivially copyable types that are no larger than 256 bytes. For larger
types the object will be emplaced directly into the variant, and if its
initialization throws then the variant becomes valueless.
Also implement Antony Polukhin's suggestion to whitelist specific types
that are not trivially copyable but can be efficiently move-assigned.
Emplacing those types will never cause a variant to become valueless.
The whitelisted types are: std::shared_ptr, std::weak_ptr,
std::unique_ptr, std::function, and std::any. Additionally,
std::basic_string, std::vector, and __gnu_debug::vector are whitelisted
if their allocator traits give them a non-throwing move assignment
operator. Specifically, this means std::string is whitelisted, but
std::pmr::string is not.
As part of this patch, additional if-constexpr branches are added for
the cases where the initialization is known to be non-throwing (so the
overhead of the try-catch block can be avoided) and where a scalar is
being produced by a potentially-throwing conversion operator (so that
the overhead of constructing and move-assigning a variant is avoided).
These changes should have no semantic effect, just better codegen.
PR libstdc++/87431 (again)
* include/bits/basic_string.h (__variant::_Never_valueless_alt):
Define partial specialization for basic_string.
* include/bits/shared_ptr.h (_Never_valueless_alt): Likewise for
shared_ptr and weak_ptr.
* include/bits/std_function.h (_Never_valueless_alt): Likewise for
function.
* include/bits/stl_vector.h (_Never_valueless_alt): Likewise for
vector.
* include/bits/unique_ptr.h (_Never_valueless_alt): Likewise for
unique_ptr.
* include/debug/vector (_Never_valueless_alt): Likewise for debug
vector.
* include/std/any (_Never_valueless_alt): Define explicit
specialization for any.
* include/std/variant (_Never_valueless_alt): Define primary template.
(__never_valueless): Use _Never_valueless_alt instead of
is_trivially_copyable.
(variant::emplace<N>(Args&&...)): Add special case for non-throwing
initializations to avoid try-catch overhead. Add special case for
scalars produced by potentially-throwing conversions. Use
_Never_valueless_alt instead of is_trivially_copyable for the
remaining strong exception-safety cases.
(variant::emplace<N>(initializer_list<U>, Args&&...)): Likewise.
* testsuite/20_util/variant/87431.cc: Run both test functions.
* testsuite/20_util/variant/exception_safety.cc: New test.
* testsuite/20_util/variant/run.cc: Use pmr::string instead of string,
so the variant becomes valueless.
From-SVN: r270170
The __glibcxx_assert macro should be used to check preconditions that
users must meet, not to check postconditions that the implementation
must meet. We have tests to verify std::variant meets its
postconditions, users shouldn't pay for those checks at runtime.
PR libstdc++/85184
* include/std/variant (_Copy_assign_base, _Move_assign_base, variant):
Remove assertions.
(variant::emplace<_Tp>): Remove result of emplace<N> directly.
From-SVN: r270117
These hash specializations should have been added when the pmr::string
and related typedefs were added.
* include/std/string (__hash_string_base): New class template defining
operator() for hashing strings.
(hash<pmr::string>, hash<pmr::u8string>, hash<pmr::u16string>)
(hash<pmr::u32string>, hash<pmr::wstring>): Define for C++17.
* testsuite/21_strings/basic_string/hash/hash.cc: New test.
* testsuite/21_strings/basic_string/hash/hash_char8_t.cc: New test.
From-SVN: r270116
Also use indices instead of types when checking whether
variants hold the same thing.
* include/std/variant (__do_visit): Add a template parameter
for index visitation, invoke with indices if index visitation
is used.
(__variant_idx_cookie): New.
(__visit_with_index): Likewise.
(_Copy_assign_base::operator=): Do single-visitation with
an index visitor.
(_Move_assign_base::operator=): Likewise.
(_Extra_visit_slot_needed): Adjust.
(__visit_invoke): Call with indices if it's an index visitor.
(relops): Do single-visitation with an index visitor.
(swap): Likewise.
(__visitor_result_type): New.
From-SVN: r270056
The static assertions added for PR libstdc++/48101 were at class scope
and so were evaluated too eagerly, when it might not be possible to
determine whether the function objects are invocable with the key types.
The problematic cases are where the key type is not known to be
convertible to the argument type(s) of the function object until later,
after a type has been completed. Specifically, if the key type is a
pointer to a derived class and the function object's argument type is a
pointer to a base class, then the derived-to-base conversion is only
valid once the derived type is complete.
By moving the static assertions to the destructor they will only be
evaluated when the destructor is instantiated, at which point whether
the key type can be passed to the function object should be knowable.
The ideal place to do the checks would be only when the function objects
are actually invoked, but that would mean adding the checks in numerous
places, so the destructor is used instead.
The tests need to be adjusted because the "required from here" line is
now the location of the destructor, not the point of instantiation in
the test file. For the map and multimap tests which check two
specializations, the dg-error matching the assertion text matches both
cases. Also check the diagnostic output for the template arguments, to
ensure both specializations trigger the assertion.
PR libstdc++/85965
* include/bits/hashtable.h (_Hashtable): Move static assertions to
destructor so they are not evaluated until the _Key type is complete.
* include/bits/stl_tree.h (_Rb_tree): Likewise.
* testsuite/23_containers/set/85965.cc: New test.
* testsuite/23_containers/unordered_set/85965.cc: New test.
* testsuite/23_containers/map/48101_neg.cc: Replace "here" errors
with regexp matching the corresponding _Rb_tree specialization.
* testsuite/23_containers/multimap/48101_neg.cc: Likewise.
* testsuite/23_containers/multiset/48101_neg.cc: Remove "here" error.
* testsuite/23_containers/set/48101_neg.cc: Likewise.
* testsuite/23_containers/unordered_map/48101_neg.cc: Likewise.
* testsuite/23_containers/unordered_multimap/48101_neg.cc: Likewise.
* testsuite/23_containers/unordered_multiset/48101_neg.cc: Likewise.
* testsuite/23_containers/unordered_set/48101_neg.cc: Likewise.
From-SVN: r269949
PR libstdc++/89825
Fix based on a suggestion by Antony Polukhin.
* include/std/variant (_Extra_visit_slot_needed): New.
(_Multi_array): Use it.
(_S_apply_all_alts): Likewise.
From-SVN: r269947
PR libstdc++/89824
Fix based on a suggestion by Antony Polukhin.
* include/std/variant (__gen_vtable): Don't reserve an
additional table slot, _Multi_array already does that.
From-SVN: r269941
PR libstdc++/89816
Fix based on a suggestion by Antony Polukhin.
* include/std/variant (__variant_construct): Capture a pointer
to the storage and visit just one variant.
From-SVN: r269940
The Doxygen docs do not have stable URLs, so linking to specific pages
doesn't work well.
* doc/xml/manual/backwards_compatibility.xml: Remove link to
Doxygen-generated pages with unstable URL.
* doc/xml/manual/concurrency_extensions.xml: Likewise.
* doc/xml/manual/extensions.xml: Likewise.
* doc/xml/manual/parallel_mode.xml: Likewise.
* doc/xml/manual/support.xml: Likewise.
From-SVN: r269881