Commit Graph

4400 Commits

Author SHA1 Message Date
Jonathan Wakely
2203a80a72 libstdc++: Implement LWG 561 for std::inserter
libstdc++-v3/ChangeLog:

	* include/bits/stl_iterator.h (inserter): Do not deduce
	iterator type (LWG 561).
	* testsuite/24_iterators/insert_iterator/dr561.cc: New test.
2020-08-10 12:09:59 +01:00
Jonathan Wakely
8bd92d8097 libstdc++: Check __cpp_exceptions in basic_string::reserve()
If exceptions are disabled then reallocating could abort, so ignore
shrink-to-fit requests.

libstdc++-v3/ChangeLog:

	* include/bits/basic_string.tcc [_GLIBCXX_USE_CXX11_ABI=0]
	(basic_string::reserve()): Do nothing if exceptions are not
	enabled.
2020-08-10 12:02:18 +01:00
Andrew Luo
140cf935cd libstdc++: Implement P0966 std::string::reserve should not shrink
Remove ability for reserve(n) to reduce a string's capacity. Add a new
reserve() overload that makes a shrink-to-fit request, and make
shrink_to_fit() use that.

libstdc++-v3/ChangeLog:

2020-07-30  Andrew Luo  <andrewluotechnologies@outlook.com>
	    Jonathan Wakely  <jwakely@redhat.com>

	* config/abi/pre/gnu.ver (GLIBCXX_3.4): Use less greedy
	patterns for basic_string members.
	(GLIBCXX_3.4.29): Export new basic_string::reserve symbols.
	* doc/xml/manual/status_cxx2020.xml: Update P0966 status.
	* include/bits/basic_string.h (shrink_to_fit()): Call reserve().
	(reserve(size_type)): Remove default argument.
	(reserve()): Declare new overload.
	[!_GLIBCXX_USE_CXX11_ABI] (shrink_to_fit, reserve): Likewise.
	* include/bits/basic_string.tcc (reserve(size_type)): Remove
	support for shrinking capacity.
	(reserve()): Perform shrink-to-fit operation.
	[!_GLIBCXX_USE_CXX11_ABI] (reserve): Likewise.
	* testsuite/21_strings/basic_string/capacity/1.cc: Adjust to
	reflect new behavior.
	* testsuite/21_strings/basic_string/capacity/char/1.cc:
	Likewise.
	* testsuite/21_strings/basic_string/capacity/char/18654.cc:
	Likewise.
	* testsuite/21_strings/basic_string/capacity/char/2.cc:
	Likewise.
	* testsuite/21_strings/basic_string/capacity/wchar_t/1.cc:
	Likewise.
	* testsuite/21_strings/basic_string/capacity/wchar_t/18654.cc:
	Likewise.
	* testsuite/21_strings/basic_string/capacity/wchar_t/2.cc:
	Likewise.
2020-08-06 19:49:07 +01:00
Jonathan Wakely
4e39f563c0 libstdc++: Do not set eofbit eagerly in operator>>(istream&, char(&)[N])
Similar to the bugs I fixed recently in istream::ignore, we incorrectly
set eofbit too often in operator>>(istream&, string&) and
operator>>(istream&.  char(&)[N]).

We should only set eofbit if we reach EOF but would have kept going
otherwise. If we've already extracted the maximum number of characters
(whether that's because of the buffer size or the istream's width())
then we should not set eofbit.

libstdc++-v3/ChangeLog:

	* include/bits/basic_string.tcc
	(operator>>(basic_istream&, basic_string&)): Do not set eofbit
	if extraction stopped after in.width() characters.
	* src/c++98/istream-string.cc (operator>>(istream&, string&)):
	Likewise.
	* include/bits/istream.tcc (__istream_extract): Do not set
	eofbit if extraction stopped after n-1 characters.
	* src/c++98/istream.cc (__istream_extract): Likewise.
	* testsuite/21_strings/basic_string/inserters_extractors/char/13.cc: New test.
	* testsuite/21_strings/basic_string/inserters_extractors/wchar_t/13.cc: New test.
	* testsuite/27_io/basic_istream/extractors_character/char/5.cc: New test.
	* testsuite/27_io/basic_istream/extractors_character/wchar_t/5.cc: New test.
2020-08-06 19:23:14 +01:00
Jonathan Wakely
17abcc7734 libstdc++: Replace operator>>(istream&, char*) [LWG 2499]
P0487R1 resolved LWG 2499 for C++20 by removing the operator>> overloads
that have high risk of buffer overflows. They were replaced by
equivalents that only accept a reference to an array, and so can
guarantee not to write past the end of the array.

In order to support both the old and new functionality, this patch
introduces a new overloaded __istream_extract function which takes a
maximum length. The new operator>> overloads use the array size as the
maximum length. The old overloads now use __builtin_object_size to
determine the available buffer size if available (which requires -O2) or
use numeric_limits<streamsize>::max()/sizeof(char_type) otherwise. This
is a change in behaviour, as the old overloads previously always used
numeric_limits<streamsize>::max(), without considering sizeof(char_type)
and without attempting to prevent overflows.

Because they now do little more than call __istream_extract, the old
operator>> overloads are very small inline functions. This means there
is no advantage to explicitly instantiating them in the library (in fact
that would prevent the __builtin_object_size checks from ever working).
As a result, the explicit instantiation declarations can be removed from
the header. The explicit instantiation definitions are still needed, for
backwards compatibility with existing code that expects to link to the
definitions in the library.

While working on this change I noticed that src/c++11/istream-inst.cc
has the following explicit instantiation definition:
  template istream& operator>>(istream&, char*);
This had no effect (and so should not have been present in that file),
because there was an explicit specialization declared in <istream> and
defined in src/++98/istream.cc. However, this change removes the
explicit specialization, and now the explicit instantiation definition
is necessary to ensure the symbol gets defined in the library.

libstdc++-v3/ChangeLog:

	* config/abi/pre/gnu.ver (GLIBCXX_3.4.29): Export new symbols.
	* include/bits/istream.tcc (__istream_extract): New function
	template implementing both of operator>>(istream&, char*) and
	operator>>(istream&, char(&)[N]). Add explicit instantiation
	declaration for it. Remove explicit instantiation declarations
	for old function templates.
	* include/std/istream (__istream_extract): Declare.
	(operator>>(basic_istream<C,T>&, C*)): Define inline and simply
	call __istream_extract.
	(operator>>(basic_istream<char,T>&, signed char*)): Likewise.
	(operator>>(basic_istream<char,T>&, unsigned char*)): Likewise.
	(operator>>(basic_istream<C,T>&, C(7)[N])): Define for LWG 2499.
	(operator>>(basic_istream<char,T>&, signed char(&)[N])):
	Likewise.
	(operator>>(basic_istream<char,T>&, unsigned char(&)[N])):
	Likewise.
	* include/std/streambuf (basic_streambuf): Declare char overload
	of __istream_extract as a friend.
	* src/c++11/istream-inst.cc: Add explicit instantiation
	definition for wchar_t overload of __istream_extract. Remove
	explicit instantiation definitions of old operator>> overloads
	for versioned-namespace build.
	* src/c++98/istream.cc (operator>>(istream&, char*)): Replace
	with __istream_extract(istream&, char*, streamsize).
	* testsuite/27_io/basic_istream/extractors_character/char/3.cc:
	Do not use variable-length array.
	* testsuite/27_io/basic_istream/extractors_character/char/4.cc:
	Do not run test for C++20.
	* testsuite/27_io/basic_istream/extractors_character/char/9555-ic.cc:
	Do not test writing to pointers for C++20.
	* testsuite/27_io/basic_istream/extractors_character/char/9826.cc:
	Use array instead of pointer.
	* testsuite/27_io/basic_istream/extractors_character/wchar_t/3.cc:
	Do not use variable-length array.
	* testsuite/27_io/basic_istream/extractors_character/wchar_t/4.cc:
	Do not run test for C++20.
	* testsuite/27_io/basic_istream/extractors_character/wchar_t/9555-ic.cc:
	Do not test writing to pointers for C++20.
	* testsuite/27_io/basic_istream/extractors_character/char/lwg2499.cc:
	New test.
	* testsuite/27_io/basic_istream/extractors_character/char/lwg2499_neg.cc:
	New test.
	* testsuite/27_io/basic_istream/extractors_character/char/overflow.cc:
	New test.
	* testsuite/27_io/basic_istream/extractors_character/wchar_t/lwg2499.cc:
	New test.
	* testsuite/27_io/basic_istream/extractors_character/wchar_t/lwg2499_neg.cc:
	New test.
2020-08-05 22:17:18 +01:00
François Dumont
6f00ccbad3 libstdc++: Fix and improve std::vector<bool> implementation.
Do not consider allocator noexcept qualification for vector<bool> move
constructor.
Improve swap performance using TBAA like in main vector implementation. Bypass
_M_initialize_dispatch/_M_assign_dispatch in post-c++11 modes.

libstdc++-v3/ChangeLog:

	* include/bits/stl_bvector.h
	[_GLIBCXX_INLINE_VERSION](_Bvector_impl_data::_M_start): Define as
	_Bit_type*.
	(_Bvector_impl_data(const _Bvector_impl_data&)): Default.
	(_Bvector_impl_data(_Bvector_impl_data&&)): Delegate to latter.
	(_Bvector_impl_data::operator=(const _Bvector_impl_data&)): Default.
	(_Bvector_impl_data::_M_move_data(_Bvector_impl_data&&)): Use latter.
	(_Bvector_impl_data::_M_reset()): Likewise.
	(_Bvector_impl_data::_M_swap_data): New.
	(_Bvector_impl::_Bvector_impl(_Bvector_impl&&)): Implement explicitely.
	(_Bvector_impl::_Bvector_impl(_Bit_alloc_type&&, _Bvector_impl&&)): New.
	(_Bvector_base::_Bvector_base(_Bvector_base&&, const allocator_type&)):
	New, use latter.
	(vector::vector(vector&&, const allocator_type&, true_type)): New, use
	latter.
	(vector::vector(vector&&, const allocator_type&, false_type)): New.
	(vector::vector(vector&&, const allocator_type&)): Use latters.
	(vector::vector(const vector&, const allocator_type&)): Adapt.
	[__cplusplus >= 201103](vector::vector(_InputIt, _InputIt,
	const allocator_type&)): Use _M_initialize_range.
	(vector::operator[](size_type)): Use iterator operator[].
	(vector::operator[](size_type) const): Use const_iterator operator[].
	(vector::swap(vector&)): Add assertions on allocators. Use _M_swap_data.
	[__cplusplus >= 201103](vector::insert(const_iterator, _InputIt,
	_InputIt)): Use _M_insert_range.
	(vector::_M_initialize(size_type)): Adapt.
	[__cplusplus >= 201103](vector::_M_initialize_dispatch): Remove.
	[__cplusplus >= 201103](vector::_M_insert_dispatch): Remove.
	* python/libstdcxx/v6/printers.py (StdVectorPrinter._iterator): Stop
	using start _M_offset.
	(StdVectorPrinter.to_string): Likewise.
	* testsuite/23_containers/vector/bool/allocator/swap.cc: Adapt.
	* testsuite/23_containers/vector/bool/cons/noexcept_move_construct.cc:
	Add check.
2020-07-31 23:18:51 +02:00
Jonathan Wakely
8abab28bb5 libstdc++: Remove condition around friend declaration (PR 96382)
libstdc++-v3/ChangeLog:

	PR libstdc++/96382
	* include/bits/stl_iterator.h (reverse_iterator): Friend
	declaration should not depend on __cplusplus.
2020-07-31 19:55:46 +01:00
Jonathan Wakely
684d6ee140 libstdc++: Make COW string use allocator_traits for nested types
When compiled as C++20 the COW std::string fails due to assuming that
the allocator always defines size_type and difference_type. That has
been incorrect since C++11, but we got away with it for specializations
using std::allocator until those members were removed in C++20.

libstdc++-v3/ChangeLog:

	* include/bits/basic_string.h (size_type, difference_type):
	Use allocator_traits to obtain the allocator's size_type and
	difference_type.
2020-07-30 20:58:09 +01:00
Jonathan Wakely
9e67b4356e libstdc++: cv bool can't be an integer-like type (LWG 3467)
libstdc++-v3/ChangeLog:

	* include/bits/iterator_concepts.h (__detail::__cv_bool): New
	helper concept.
	(__detail::__integral_nonbool): Likewise.
	(__detail::__is_integer_like): Use __integral_nonbool.
	* testsuite/std/ranges/access/lwg3467.cc: New test.
2020-07-30 13:09:18 +01:00
François Dumont
acc1d1a954 libstdc++: Review _Local_iterator/_Local_const_iterator implementations.
_Local_iterator_base inherits _Node_iterator_base and so share the same
comparison operators. It avoids to expose special method _M_curr for debug
mode to compare such iterators.

libstdc++-v3/ChangeLog:

	* include/bits/hashtable_policy.h (_Node_iterator_base()): New.
	(operator==(const _Node_iterator_base&, const _Node_iterator_base&)):
	Make hidden friend.
	(operator!=(const _Node_iterator_base&, const _Node_iterator_base&)):
	Make hidden friend.
	(_Local_iterator_base<>): Inherits _Node_iterator_base.
	(_Local_iterator_base<>::_M_cur): Remove.
	(_Local_iterator_base<>::_M_curr()): Remove.
	(operator==(const _Local_iterator_base&, const _Local_iterator_base&)):
	Remove.
	(operator!=(const _Local_iterator_base&, const _Local_iterator_base&)):
	Remove.
	* include/debug/unordered_map (unordered_map<>::_M_invalidate): Adapt.
	(unordered_multimap<>::_M_invalidate): Adapt.
	* include/debug/unordered_set (unordered_set<>::_M_invalidate): Adapt.
	(unordered_multiset<>::_M_invalidate): Adapt.
2020-07-29 20:46:09 +02:00
François Dumont
12324b9a93 libstdc++: Fix unordered containers move constructors noexcept qualification
_Hashtable move constructor is wrongly qualified as noexcept(true) regardless of
_Equal and _H1 copy constructor qualifications.
_Hashtable allocator-aware move constructor is missing its noexcept
qualification like the depending unordered containers ones.

libstdc++-v3/ChangeLog:

	* include/bits/hashtable.h
	(_Hashtable(_Hashtable&& __ht, __node_alloc_type&& __a, true_type)):
	Add noexcept qualification.
	(_Hashtable(_Hashtable&&)): Fix noexcept qualification.
	(_Hashtable(_Hashtable&&, const allocator_type&)): Add noexcept
	qualification.
	* include/bits/unordered_map.h
	(unordered_map(unordered_map&&, const allocator_type&)): Add noexcept
	qualification.
	(unordered_multimap(unordered_multimap&&, const allocator_type&)):
	Likewise.
	* include/bits/unordered_set.h
	(unordered_set(unordered_set&&, const allocator_type&)): Likewise.
	(unordered_multiset(unordered_multiset&&, const allocator_type&)):
	Likewise.
	* include/debug/unordered_map
	(unordered_map(unordered_map&&, const allocator_type&)): Likewise.
	(unordered_multimap(unordered_multimap&&, const allocator_type&)):
	Likewise.
	* include/debug/unordered_set
	(unordered_set(unordered_set&&, const allocator_type&)): Likewise.
	(unordered_multiset(unordered_multiset&&, const allocator_type&)):
	Likewise.
	* testsuite/23_containers/unordered_map/allocator/default_init.cc:
	New test.
	* testsuite/23_containers/unordered_map/cons/noexcept_default_construct.cc:
	New test.
	* testsuite/23_containers/unordered_map/cons/noexcept_move_construct.cc:
	New test.
	* testsuite/23_containers/unordered_map/modifiers/move_assign.cc:
	New test.
	* testsuite/23_containers/unordered_multimap/cons/noexcept_default_construct.cc:
	New test.
	* testsuite/23_containers/unordered_multimap/cons/noexcept_move_construct.cc:
	New test.
	* testsuite/23_containers/unordered_multiset/cons/noexcept_default_construct.cc:
	New test.
	* testsuite/23_containers/unordered_multiset/cons/noexcept_move_construct.cc:
	New test.
	* testsuite/23_containers/unordered_set/allocator/default_init.cc:
	New test.
	* testsuite/23_containers/unordered_set/cons/noexcept_default_construct.cc:
	New test.
	* testsuite/23_containers/unordered_set/cons/noexcept_move_construct.cc:
	New test.
2020-07-29 11:26:42 +02:00
François Dumont
6dcf042368 libstdc++: Do not over-size hashtable buckets on range insertion
We used to consider range size on insertion but on unique keys container
not all range values might be inserted resulting in over-sizing. In this
case we just consider user reservation and if none then the container will
adapt to actually inserted elements.

libstdc++-v3/ChangeLog:

	* include/bits/hashtable.h
	(_Hashtable<>(_InputIterator, _InputIterator, size_t, const _H1&,
	const _H2&, const _Hash&, const _Equal&, const _ExtractKey&,
	const allocator_type&, true_type)): New.
	(_Hashtable<>(_InputIterator, _InputIterator, size_t, const _H1&,
	const _H2&, const _Hash&, const _Equal&, const _ExtractKey&,
	const allocator_type&, false_type)): New.
	(_Hashtable<>(_InputIterator, _InputIterator, size_t, const _H1&,
	const _H2&, const _Hash&, const _Equal&, const _ExtractKey&,
	const allocator_type&)): Delegate to latters.
	(operator=(initializer_list<value_type>)): Rehash if too small.
	(_M_insert(_Arg&&, const _NodeGenerator&, true_type)): Remove
	size_t len parameter.
	* include/bits/hashtable_policy.h (_Insert_base<>::_M_insert_range):
	Do not try to get input range distance.
	* testsuite/23_containers/unordered_set/cons/bucket_hint.cc: New test.
	* testsuite/23_containers/unordered_set/modifiers/insert.cc: New test.
2020-07-28 14:37:16 +02:00
François Dumont
f9d98fa748 libstdc++: Review _Hashtable count, equal_range _M_erase(false_type,) code
Simplify operator[] implementation using find method. Review several
_Hashtable method implementations to limit the computation of bucket index.
Introduce _M_update_bbegin to simplify code.

libstdc++-v3/ChangeLog:

	* include/bits/hashtable_policy.h (_Map_base<>::at): Use
	_Hashtable<>::find.
	(_Hashtable_base<>::_Equal_hash_code<>::_S_node_equals):New.
	(_Hashtable_base<>::_M_node_equals): New, use latter.
	(_Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
	_RehashPolicy, false>::_M_equal): Adapt to use latter.
	* include/bits/hashtable.h (_Hashtable<>::_M_update_bbegin): New.
	(_Hashtable<>::_M_assign): Use latter.
	(_Hashtable<>::_M_move_assign): Likewise.
	(_Hashtable<>(_Hashtable<>&&)): Likewise.
	(_Hashtable<>(_Hashtable<>&&, const allocator_type&)): Likewise.
	(_Hashtable<>::swap): Likewise.
	(_Hashtable<>::find): Build iterator directly from _M_find_node result.
	(_Hashtable<>::count): Use _Hashtable<>::find.
	(_Hashtable<>::equal_range): Likewise.
	(_Hashtable<>::_M_erase(false_type, const key_type&)): Use
	_M_node_equals.
2020-07-27 21:55:49 +02:00
Jonathan Wakely
a5a8a4e615 libstdc++: Constrain reverse_iterator and move_iterator conversions [LWG 3435]
libstdc++-v3/ChangeLog:

	* include/bits/stl_iterator.h (reverse_iterator): Constrain
	converting constructor and converting assignment operator.
	Access source iterator's data member directly instead of
	calling base().
	(move_iterator): Likewise.
	* testsuite/24_iterators/move_iterator/dr3435.cc: New test.
	* testsuite/24_iterators/reverse_iterator/dr3435.cc: New test.
2020-07-22 15:10:29 +01:00
Jonathan Wakely
4d1c5b4957 libstdc++: Avoid overflow in istream::get(streambuf&) [LWG 3464]
Similar to the recent changes to basic_istream::ignore, this change
ensures that _M_gcount doesn't overflow when extracting characters and
inserting them into another streambuf.

The solution used here is to use unsigned long long for the count. We
assume that the number of characters extracted won't exceed the maximum
value for that type, but even if it does we avoid any undefined
behaviour.

libstdc++-v3/ChangeLog:

	* include/bits/istream.tcc
	(basic_istream::get(__streambuf_type&, char_type): Use unsigned
	long long for counter and check if it would overflow _M_gcount.
	* testsuite/27_io/basic_istream/get/char/lwg3464.cc: New test.
	* testsuite/27_io/basic_istream/get/wchar_t/lwg3464.cc: New test.
2020-07-20 20:06:46 +01:00
Jonathan Wakely
ba8fe4b483 libstdc++: Fix istream::ignore exit conditions (PR 94749, PR 96161)
My previous fix for PR 94749 did fix the reported case, so that the next
character is not discarded if it happens to equal the delimiter when __n
characters have already been read. But it introduced a new bug, which is
that the delimiter character would *not* be discarded if the number of
characters discarded is numeric_limits<streamsize>::max() or more before
reaching the delimiter.

The new bug happens because I changed the code to check _M_gcount < __n.
But when __n == numeric_limits<streamsize>::max() that is false, and so
we don't discard the delimiter. It's not sufficient to check for the
delimiter when the __large_ignore condition is true, because there's an
edge case where the delimiter is reached when _M_gcount == __n and so
we break out of the loop without setting __large_ignore.

PR 96161 is a similar bug to the original PR 94749 report, where eofbit
is set after discarding __n characters if there happen to be no more
characters in the stream.

This patch fixes both cases (and the regression) by checking different
conditions for the __n == max case and the __n < max case. For the
former case, we know that we must have either reached the delimiter or
EOF, and the value of _M_gcount doesn't matter (except to avoid integer
overflow). For the latter case we need to check _M_gcount first and only
set eofbit or discard the delimiter if it didn't reach __n. For the
latter case overflow can't happen because _M_gcount <= __n < max.

libstdc++-v3/ChangeLog:

	PR libstdc++/94749
	PR libstdc++/96161
	* include/bits/istream.tcc (basic_istream::ignore(streamsize))
	[n == max]: Check overflow conditions on _M_gcount. Rely on
	the fact that either EOF or the delimiter was reached.
	[n < max]: Check _M_gcount < n before checking for EOF or
	delimiter.
	(basic_istream::ignore(streamsize, char_type): Likewise.
	* src/c++98/compatibility.cc (istream::ignore(streamsize))
	(wistream::ignore(streamsize)): Likewise.
	* src/c++98/istream.cc (istream::ignore(streamsize, char_type))
	(wistream::ignore(streamsize, char_type)): Likewise.
	* testsuite/27_io/basic_istream/ignore/char/94749.cc: Check that
	delimiter is discarded if the number of characters ignored
	doesn't fit in streamsize.
	* testsuite/27_io/basic_istream/ignore/wchar_t/94749.cc:
	Likewise.
	* testsuite/27_io/basic_istream/ignore/char/96161.cc: New test.
	* testsuite/27_io/basic_istream/ignore/wchar_t/96161.cc: New test.
2020-07-13 12:09:44 +01:00
François Dumont
c832cf1c1d libstdc++: Fix [multi]map/[multi]set move constructors noexcept qualification
Container move constructors shall not consider their allocator move
constructor qualification.

libstdc++-v3/ChangeLog:

	* include/bits/stl_tree.h (_Rb_tree_impl(_Rb_tree_impl&&)): Add noexcept
	qualification based only on _Compare one.
	* testsuite/23_containers/map/cons/noexcept_move_construct.cc: Add
	static asserts.
	* testsuite/23_containers/multimap/cons/noexcept_move_construct.cc:
	Likewise.
	* testsuite/23_containers/multiset/cons/noexcept_move_construct.cc:
	Likewise.
	* testsuite/23_containers/set/cons/noexcept_move_construct.cc: Likewise.
2020-07-08 08:02:16 +02:00
Jonathan Wakely
eb04805be4 libstdc++: Replace __int_limits with __numeric_traits_integer
I recently added std::__detail::__int_limits as a lightweight
alternative to std::numeric_limits, forgetting that the values it
provides (digits, min and max) are already provided by
__gnu_cxx::__numeric_traits.

This change adds __int_traits as an alias for __numeric_traits_integer.
This avoids instantiating __numeric_traits to decide whether to use
__numeric_traits_integer or __numeric_traits_floating. Then all uses of
__int_limits can be replaced with __int_traits, and __int_limits can be
removed.

libstdc++-v3/ChangeLog:

	* include/Makefile.am: Remove bits/int_limits.h.
	* include/Makefile.in: Regenerate.
	* include/bits/int_limits.h: Removed.
	* include/bits/parse_numbers.h (_Select_int_base): Replace
	__int_limits with __int_traits.
	* include/bits/range_access.h (_SSize::operator()): Likewise.
	* include/ext/numeric_traits.h (__numeric_traits_integer): Add
	static assertion.
	(__int_traits): New alias template.
	* include/std/bit (__rotl, __rotr, __countl_zero, __countl_one)
	(__countr_zero, __countr_one, __popcount, __bit_ceil)
	(__bit_floor, __bit_width) Replace __int_limits with
	__int_traits.
	* include/std/charconv (__to_chars_8, __from_chars_binary)
	(__from_chars_alpha_to_num, from_chars): Likewise.
	* include/std/memory_resource (polymorphic_allocator::allocate)
	(polymorphic_allocator::allocate_object): Likewise.
	* include/std/string_view (basic_string_view::_S_compare):
	Likewise.
	* include/std/utility (cmp_equal, cmp_less, in_range): Likewise.
2020-07-07 23:36:29 +01:00
Jonathan Wakely
0e5abeb0cb libstdc++: Fix -Wmismatched-tags warnings (PR 96063)
libstdc++-v3/ChangeLog:

	* include/bits/fs_dir.h: Use consistent tag in class-head.
	* include/bits/localefwd.h: Likwise.
	* include/bits/regex.h: Likwise.
	* include/bits/stl_map.h: Likwise.
	* include/bits/stl_multimap.h: Likwise.
	* include/bits/stl_multiset.h: Likwise.
	* include/bits/stl_set.h: Likwise.
	* include/std/complex: Likwise.
	* include/std/functional: Likwise.
	* include/std/future: Likwise.
	* include/std/system_error: Likwise.
	* include/std/thread: Likwise.
	* include/std/tuple: Likwise.
	* include/std/type_traits: Likwise.
	* include/std/valarray: Likwise.
2020-07-06 17:12:29 +01:00
Jonathan Wakely
a1a0dc4548 libstdc++: Remove noexcept from match_results comparisons (PR 94627)
These functions can't be noexcept because the iterators stored in the
sub_match objects can throw on any operation.

libstdc++-v3/ChangeLog:

	PR libstdc++/94627
	* include/bits/regex.h (operator==, operator!=): Remove noexcept
	equality comparisons for match_results.
	* testsuite/28_regex/match_results/94627.cc: New test.
2020-07-01 21:06:42 +01:00
Ville Voutilainen
2635f9e508 Revert "Add a __nonnnull__ attribute to std::string's _CharT* constructor"
This reverts commit b26fd416fb.
2020-06-30 01:59:34 +03:00
Ville Voutilainen
b26fd416fb Add a __nonnnull__ attribute to std::string's _CharT* constructor
Add a __nonnnull__ attribute to std::string's _CharT* constructor
	* include/bits/basic_string.h (string(_CharT*, const _Alloc&)):
	Add a __nonnull__ attribute.
	* testsuite/21_strings/basic_string/cons/char/nonnull.cc: New.
	* testsuite/21_strings/basic_string/cons/wchar_t/nonnull.cc: Likewise.
2020-06-29 00:47:05 +03:00
Jonathan Wakely
25920dd18a libstdc++: Fix warnings with -Wsystem-headers
libstdc++-v3/ChangeLog:

	* include/bits/stl_algobase.h (__find_if): Add FALLTHRU markers.
	* include/std/charconv (__detail::__to_chars): Avoid
	-Wsign-compare warning.
2020-06-24 12:34:17 +01:00
Jonathan Wakely
5b6215083b libstdc++: Fix some -Wsystem-headers warnings (PR 95765)
PR libstdc++/95765
	* include/bits/stl_algobase.h (__size_to_integer(float))
	(__size_to_integer(double), __size_to_integer(long double))
	(__size_to_integer(__float128)): Cast return type explicitly.
	* include/bits/stl_uninitialized.h (__uninitialized_default_1<true>):
	Remove unused typedef.
2020-06-19 18:20:05 +01:00
Jonathan Wakely
a7a3932e4b libstdc++: Remove redundant std:: qualification
* include/bits/stl_pair.h (_Index_tuple): Remove redundant
	namespace qualification.
	(pair::pair(tuple<>&, tuple<>&, _Index_tuple, _Index_tuple)):
	Likewise.
	* include/std/tuple (_Head_base, _Tuple_impl, tuple_size)
	(tuple_element, __get_helper, get, __make_tuple_impl)
	(__make_1st_indices, __tuple_concater)
	(pair::pair(tuple<>&, tuple<>&, _Index_tuple, _Index_tuple)):
	Likewise.
	* include/std/utility (tuple_element, __is_tuple_like_impl)
	(tuple_size, __pair_get, get): Likewise.
2020-06-19 15:02:54 +01:00
Jonathan Wakely
abed8b56b9 libstdc++: Define all std::function members inline
* include/bits/std_function.h (function): Define all member
	functions inline.
2020-06-19 14:37:52 +01:00
Marc Glisse
465520e3eb libstdc++: std::includes performance tweak
A small tweak to the implementation of __includes, which in my
application saves 20% of the running time. I noticed it because using
range-v3 was giving unexpected performance gains.

Some of the gain comes from pulling the 2 calls ++__first1 out of the
condition so there is just one call. And most of the gain comes from
replacing the resulting

if (__comp(__first1, __first2))
  ;
else
  ++__first2;

with

if (!__comp(__first1, __first2))
  ++__first2;

I was very surprised that the code ended up being so different for such
a change, and I still don't really understand where the extra time is
going...

Anyway, while I blame the compiler for not generating very good code
with the current implementation, I believe the change can be seen as a
simplification.

libstdc++-v3/ChangeLog:

	* include/bits/stl_algo.h (__includes): Simplify the code.
2020-06-19 13:03:45 +01:00
Jonathan Wakely
632183ddcc libstdc++: Avoid stack overflow in std::vector (PR 94540)
The std::__uninitialized_default_n algorithm used by std::vector creates
an initial object as a local variable then copies that into the
destination range. If the object is too large for the stack this
crashes. We should create the first object directly into the
destination and then copy it from there.

This doesn't fix the bug for C++98, because in that case the initial
value is created as a default argument of the vector constructor i.e. in
the user's code, not inside libstdc++. We can't prevent that.

	PR libstdc++/94540
	* include/bits/stl_uninitialized.h (__uninitialized_default_1<true>):
	Construct the first value at *__first instead of on the stack.
	(__uninitialized_default_n_1<true>): Likewise.
	Improve comments on several of the non-standard algorithms.
	* testsuite/20_util/specialized_algorithms/uninitialized_default/94540.cc:
	New test.
	* testsuite/20_util/specialized_algorithms/uninitialized_default_n/94540.cc:
	New test.
	* testsuite/20_util/specialized_algorithms/uninitialized_value_construct/94540.cc:
	New test.
	* testsuite/20_util/specialized_algorithms/uninitialized_value_construct_n/94540.cc:
	New test.
	* testsuite/23_containers/vector/cons/94540.cc: New test.
2020-06-17 22:49:06 +01:00
Jonathan Wakely
c9dce3b15e libstdc++: Handle non-integral sizes in std::uninitialized_fill_n
The std::uninitialized_fill_n algorithm uses sd::fill_n for trivial
types, but that algorithm has a stronger requirement that the Size
parameter is convertible to an integral type. As the new test shows,
there are types which are valid for std::uninitialized_fill_n but which
produce a different result when converted to an integral type, or cannot
be converted at all. Only use the std::fill_n optimization when the Size
type is already an integral type.

The std::__uninitialized_default_n extension has the same problem, and
so does C++17's std::uninitialized_value_construct_n which uses it.

	* include/bits/stl_uninitialized.h (uninitialized_fill_n): Only
	use std::fill_n when the size is an integral type.
	(__uninitialized_default_n): Likewise.
	* testsuite/20_util/specialized_algorithms/uninitialized_default_n/sizes.cc:
	New test.
	* testsuite/20_util/specialized_algorithms/uninitialized_fill_n/sizes.cc:
	New test.
	* testsuite/20_util/specialized_algorithms/uninitialized_value_construct_n/sizes.cc:
	New test.
2020-06-17 20:55:06 +01:00
Jonathan Wakely
e40b11a91c libstdc++: Strip cv-qualifiers in std::atomic<FP> (PR 95282)
This improves the previous fix for PR 95282, and extends it to also
apply to the exchange function (which has a similar problem and would
become ill-formed with my proposed fix for PR 95378).

	PR libstdc++/95282
	* include/bits/atomic_base.h (__atomic_impl::load): Use the _Val
	alias instead of deducing _Tp as an unqualified type.
	(__atomic_impl::exchange): Use the _Val alias to remove volatile
	from the reinterpret_cast result type.
2020-06-16 22:34:55 +01:00
Jonathan Wakely
b6ab9ecd55 libstdc++: Update value of __cpp_lib_constexpr_char_traits for C++20
Although not required by SD-6 or the C++20 draft, we define the macro
__cpp_lib_constexpr_char_traits to indicate support for P0432R1. This
updates the value in C++20 mode for the P1032R1 changes to char_traits.

	* include/bits/char_traits.h (__cpp_lib_constexpr_char_traits):
	Update value for C++20.
	* include/std/version (__cpp_lib_constexpr_char_traits): Likewise.
	* testsuite/21_strings/char_traits/requirements/constexpr_functions_c++17.cc:
	Update expected value.
	* testsuite/21_strings/char_traits/requirements/constexpr_functions_c++20.cc:
	Likewise.
2020-06-15 14:31:26 +01:00
Paul Keir
eb11134d0c libstdc++: Fix char_traits move with overlap
Upon constexpr evaluation, char_traits move uses copy_backward, but its
last argument should be to the range end rather than its beginning.

2020-06-12  Paul Keir  <paul.keir@uws.ac.uk>

	* include/bits/char_traits.h (char_traits::move): constexpr move with
	overlap was using copy_backward incorrectly.
	* testsuite/21_strings/char_traits/requirements/constexpr_functions_c++20.cc:
	New test.
2020-06-15 14:31:26 +01:00
Jonathan Wakely
17412a74c5 libstdc++: Make std::atomic_flag::test members const
Also fix the tests so they run without an explicit -std=gnu++2a in the
RUNTESTFLAGS, and test the new function on const-qualified objects.

	* include/bits/atomic_base.h (atomic_flag::test): Add missing
	const qualifiers.
	* testsuite/29_atomics/atomic_flag/test/explicit.cc: Add
	dg-options and verify results of test function.
	* testsuite/29_atomics/atomic_flag/test/implicit.cc: Likewise.
2020-06-12 10:31:07 +01:00
Jonathan Wakely
b32eea9c0c libstdc++: Fix istream::ignore discarding too many chars (PR 94749)
The current code assumes that if the next character in the stream is
equal to the delimiter then we stopped because we saw that delimiter,
and so discards it.  But in the testcase for the PR we stop because we
reached the maximum number of characters, and it's coincidence that the
next character equals the delimiter. We should not discard the next
character in that case.

The fix is to check that we haven't discarded __n characters already,
instead of checking whether the next character equals __delim. Because
we've already checked for EOF, if we haven't discarded __n yet then we
know we stopped because we saw the delimiter. On the other hand, if the
next character is the delimiter we don't know if that's why we stopped.

	PR libstdc++/94749
	* include/bits/istream.tcc (basic_istream::ignore(streamsize, CharT)):
	Only discard an extra character if we didn't already reach the
	maximum number.
	* src/c++98/istream.cc (istream::ignore(streamsiz, char))
	(wistream::ignore(streamsize, wchar_t)): Likewise.
	* testsuite/27_io/basic_istream/ignore/char/94749.cc: New test.
	* testsuite/27_io/basic_istream/ignore/wchar_t/94749.cc: New test.
2020-06-11 18:41:37 +01:00
Patrick Palka
a73051a0ea libstdc++: Fix some ranges algos optimizations [PR95578]
ranges::copy and a number of other ranges algorithms have unwrapping
optimizations for iterators of type __normal_iterator, move_iterator and
reverse_iterator.  But in the checks that guard these optimizations we
currently only test that the iterator of the iterator/sentinel pair has
the appropriate type before proceeding with the corresponding
optimization, and do not also test the sentinel type.

This breaks the testcase in this PR because this testcase constructs via
range adaptors a range whose begin() is a __normal_iterator and whose
end() is a custom sentinel type, and then performs ranges::copy on it.
From there we bogusly perform the __normal_iterator unwrapping
optimization on this iterator/sentinel pair, which immediately leads to
a constraint failure since the custom sentinel type does not model
sentinel_for<int*>.

This patch fixes this issue by refining each of the problematic checks
to also test that the iterator and sentinel types are the same before
applying the corresponding unwrapping optimization.  Along the way, some
code simplifications are made.

libstdc++-v3/ChangeLog:

	PR libstdc++/95578
	* include/bits/ranges_algo.h (__lexicographical_compare_fn):
	Also check that the iterator and sentinel have the same type before
	applying the unwrapping optimization for __normal_iterator.
	Split the check into two, one for the first iterator/sentinel
	pair and another for second iterator/sentinel pair.  Remove uses
	of __niter_base, and remove uses of std::move on a
	__normal_iterator.
	* include/bits/ranges_algobase.h (__equal_fn): Likewise.
	(__copy_or_move): Likewise.  Perform similar adjustments for
	the reverse_iterator and move_iterator optimizations.  Inline
	the checks into the if-constexprs, and use using-declarations to
	make them less visually noisy.  Remove uses of __niter_wrap.
	(__copy_or_move_backward): Likewise.
	* testsuite/25_algorithms/copy/95578.cc: New test.
	* testsuite/25_algorithms/copy_backward/95578.cc: New test.
	* testsuite/25_algorithms/equal/95578.cc: New test.
	* testsuite/25_algorithms/lexicographical_compare/95578.cc: New test.
	* testsuite/25_algorithms/move/95578.cc: New test.
	* testsuite/25_algorithms/move_backward/95578.cc: New test.
2020-06-10 17:37:53 -04:00
François Dumont
3a391adf7a libstdc++: Extend memcmp optimization in std::lexicographical_compare
Make the memcmp optimization work for std::deque iterators and safe
iterators.

Co-authored-by: Jonathan Wakely  <jwakely@redhat.com>

libstdc++-v3/ChangeLog:

2020-06-08  François Dumont  <fdumont@gcc.gnu.org>
	    Jonathan Wakely  <jwakely@redhat.com>

	* include/bits/deque.tcc (__lex_cmp_dit): New.
	(__lexicographical_compare_aux1): Define overloads for deque
	iterators.
	* include/bits/stl_algobase.h (__lexicographical_compare::__3way):
	New static member function.
	(__lexicographical_compare<true>::__3way): Likewise.
	(__lexicographical_compare<true>::__lc): Use __3way.
	(__lexicographical_compare_aux): Rename to
	__lexicographical_compare_aux1 and declare overloads for deque
	iterators.
	(__lexicographical_compare_aux): Define new forwarding function
	that calls __lexicographical_compare_aux1 and declare new overloads
	for safe iterators.
	(lexicographical_compare): Do not use __niter_base on
	parameters.
	* include/debug/safe_iterator.tcc
	(__lexicographical_compare_aux): Define overloads for safe
	iterators.
	* testsuite/25_algorithms/lexicographical_compare/1.cc: Add
	checks with random access iterators.
	* testsuite/25_algorithms/lexicographical_compare/deque_iterators/1.cc:
	New test.
2020-06-10 17:48:56 +01:00
Jonathan Wakely
733167f9d5 libstdc++: Define converting assignment operator for std::move_iterator
As clarified by LWG 3265, std::move_iterator is supposed to have an
assignment operator that converts from a different specialization of
std::move_iterator, which performs an assignment. That has always been
missing from libstdc++, so assigning a different type actually performs
a converting construction, then an assignment. This is non-conforming
for the (fairly contrived) case where the converting assignment is
well-formed but the converting construction is not.

	* include/bits/stl_iterator.h (move_iterator::operator=): Define.
	* testsuite/24_iterators/move_iterator/dr3265.cc: New test.
2020-06-09 22:16:24 +01:00
Jonathan Wakely
187da2ce31 libstdc++: Implement operator<< for std::unique_ptr (LWG 2948)
libstdc++-v3/ChangeLog:

	* include/bits/unique_ptr.h (operator<<): Define for C++20.
	* testsuite/20_util/unique_ptr/io/lwg2948.cc: New test.
2020-06-08 21:21:31 +01:00
Jonathan Wakely
f2242ec0d3 libstdc++: Remove workarounds for constrained nested class templates
With PR c++/92078 and PR c++/92103 both fixed, nested class templates
can now be constrained. That means a number of namespace-scope helpers
can be moved to the class scope, so they're only visible where they're
needed.

	* include/bits/iterator_concepts.h (__detail::__ptr, __detail::__ref)
	(__detail::__cat, __detail::__diff): Move to class scope in the
	relevant __iterator_traits specializations.
	(__iterator_traits<>): Use nested class templates instead of ones from
	namespace __detail.
	* include/bits/stl_iterator.h (__detail::__common_iter_ptr): Move to
	class scope in iterator_traits<common_iterator<I, S>>.
	(iterator_traits<common_iterator<I, S>>): Use nested class template
	instead of __detail::__common_iter_ptr.
2020-06-04 23:20:49 +01:00
François Dumont
4e05c918d2 libstdc++: Specialize copy/copy_n for istreambuf_iterator and deque iterators
Add __copy_n_a overloads for std::deque iterators to replace with C memmove
when possible. Expose std::copy_n implementation details in pre-C++11 modes
and use it for std::copy overloads.

libstdc++-v3/ChangeLog

	* include/bits/stl_algo.h (__copy_n_a): Move to ...
	* include/bits/stl_algobase.h (__copy_n_a): ...here. Add __strict
	parameter.
	(__copy_n_a(istreambuf_iterator<>, _Size, _Deque_iterator<>, bool)):
	Declare.
	(__niter_base(const _Safe_iterator<_Ite, _Seq,
	random_access_iterator_tag>&)): Declare.
	(__copy_move_a2(istreambuf_iterator<>, istreambuf_iterator<>,
	_Deque_iterator<>)): Declare.
	* include/bits/deque.tcc
	(__copy_move_a2(istreambuf_iterator<>, istreambuf_iterator<>,
	_Deque_iterator<>)): New.
	(__copy_n_a(istreambuf_iterator<>, _Size, _Deque_iterator<>, bool)):
	New.
	* include/bits/streambuf_iterator.h
	(__copy_n_a(istreambuf_iterator<>, _Size, _CharT*, bool)): Adapt.
	* include/debug/safe_iterator.tcc (__niter_base): New.
	* testsuite/25_algorithms/copy/streambuf_iterators/char/4.cc
	(test03): New.
	* testsuite/25_algorithms/copy/streambuf_iterators/char/debug/deque_neg.cc:
	New test.
	* testsuite/25_algorithms/copy_n/debug/istreambuf_ite_deque_neg.cc:
	New test.
	* testsuite/25_algorithms/copy_n/istreambuf_iterator/2.cc: New test.
	* testsuite/25_algorithms/copy_n/istreambuf_iterator/deque.cc:
	New test.
2020-06-04 22:27:47 +02:00
Jonathan Wakely
e1008cd1d8 libstdc++: Make std::copy_n work with negative and non-integral sizes
Since it was added in C++11, std::copy_n and std::ranges::copy_n should
do nothing given a negative size, but for random access iterators we add
the size to the iterator, possibly resulting in undefined behaviour.

Also, C++20 clarified that std::copy_n requires the Size type to be
convertible to an integral type. We previously assumed that it could be
directly used in arithmetic expressions, without conversion to an
integral type.

This also fixes a bug in the random_access_iterator_wrapper helper adds
some convenience aliases for using the iterator wrappers.

libstdc++-v3/ChangeLog:

	* include/bits/ranges_algobase.h (__copy_n_fn): Only call
	ranges::copy for positive values.
	* include/bits/stl_algo.h (copy_n): Convert Size argument to an
	integral type and only call __copy_n for positive values.
	* testsuite/util/testsuite_iterators.h
	(random_access_iterator_wrapper::operator+=): Fix range check for
	negative values.
	(output_container, input_container, forward_container)
	(bidirectional_container, random_access_container): New alias
	templates.
	* testsuite/25_algorithms/copy_n/5.cc: New test.
2020-06-04 14:21:34 +01:00
Jonathan Wakely
cd3f067b82 libstdc++: Fix filesystem::u8path for mingw targets (PR 95392)
When I refactored filesystem::path string conversions in
r11-587-584d52b088f9fcf78704b504c3f1f07e17c1cded I failed to update the
mingw-specific code in filesystem::u8path, causing a bootstrap failure.

This fixes it, and further refactors the mingw-specific code along the
same lines as the previous commit. All conversions from UTF-8 strings to
wide strings now use the same helper function, __wstr_from_utf8.

	PR libstdc++/95392
	* include/bits/fs_path.h (path::_S_to_string): Move to
	namespace-scope and rename to ...
	(__detail::__string_from_range): ... this.
	[WINDOWS] (__detail::__wstr_from_utf8): New function template to
	convert a char sequence containing UTF-8 to wstring.
	(path::_S_convert(Iter, Iter)): Adjust call to _S_to_string.
	(path::_S_convert_loc(Iter, Iter, const locale&)): Likewise.
	(u8path(InputIterator, InputIterator)) [WINDOWS]: Use
	__string_from_range to obtain a contiguous range and
	__wstr_from_utf8 to obtain a wide string.
	(u8path(const Source&)) [WINDOWS]: Use __effective_range to
	obtain a contiguous range and __wstr_from_utf8 to obtain a wide
	string.
	(path::_S_convert(const _EcharT*, const _EcharT)) [WINDOWS]:
	Use __wstr_from_utf8.
2020-06-02 00:07:05 +01:00
François Dumont
7688e5e8c4 libstdc++: Review unordered_map insert_or_assign/try_emplace (PR 95079)
Those methods are making a double lookup in case of insertion, they can
perform only one.

	PR libstdc++/95079
	* include/bits/hashtable_policy.h (_Insert_base<>::try_emplace): New.
	* include/bits/unordered_map.h (unordered_map<>::try_emplace): Adapt.
	(unordered_map<>::insert_or_assign): Adapt.
2020-05-29 13:12:36 +02:00
Jonathan Wakely
bbaec68c86 libstdc++: Fix atomic<FP>::load (PR 95282)
PR libstdc++/95282
	* include/bits/atomic_base.h (__atomic_impl::load): Add
	cv-qualifiers to parameter so that _Tp is deduced as the
	unqualified type.
	* testsuite/29_atomics/atomic_float/95282.cc: New test.
2020-05-27 22:55:21 +01:00
Jonathan Wakely
979e89a9a9 libstdc++: Fix std::reverse_iterator comparisons (PR 94354)
The std::reverse_iterator comparisons have always been implemented only
in terms of equality and less than. In C++98 that made no difference for
reasonable code, because when the underlying operators are the same type
they are required to support all comparisons anyway.

But since LWG 280 it's possible to compare reverse_iterator<X> and
reverse_iterator<Y>, and comparisons between X and Y might not support
the full set of equality and relational operators. This means that it
matters whether we implement operator!= as x.base() != y.base() or
!(x.base() == y.base()), and the current implementation is
non-conforming.

This was already fixed in GCC 10.1 for C++20, this change also fixes it
for all other -std modes.

	PR libstdc++/94354
	* include/bits/stl_iterator.h (reverse_iterator): Fix comparison
	operators to use the correct operations on the underlying
	iterators.
	* testsuite/24_iterators/reverse_iterator/rel_ops.cc: New test.
2020-05-27 21:58:56 +01:00
Patrick Palka
3bf5e7657b libstdc++: Fix common_iterator::operator-> [PR95322]
This patch fixes the definition of common_iterator::operator-> when the
underlying iterator's operator* returns a non-reference.

The first problem is that the class __detail::_Common_iter_proxy is used
unqualified.  Fixing that revealed another problem: the class's template
friend declaration of common_iterator doesn't match up with the
definition of common_iterator, because the friend declaration isn't
constrained.

If we try to make the friend declaration match up by adding constraints,
we run into frontend bug PR93467.  So we currently can't correctly
express this friend relation between __detail::_Common_iter_proxy and
common_iterator.

As a workaround to this frontend bug, this patch moves the definition of
_Common_iter_proxy into the class template of common_iterator so that we
could instead express the friend relation via the injected-class-name.

(This bug was found when attempting to use views::common to work around
the compile failure with the testcase in PR95322.)

libstdc++-v3/ChangeLog:

	PR libstdc++/95322
	* include/bits/stl_iterator.h (__detail::_Common_iter_proxy):
	Remove and instead define it ...
	(common_iterator::_Proxy): ... here.
	(common_iterator::operator->): Use it.
	* testsuite/24_iterators/common_iterator/2.cc: New test.
	* testsuite/std/ranges/adaptors/95322.cc: New test.
2020-05-26 16:17:34 -04:00
Jonathan Wakely
584d52b088 libstdc++: Refactor filesystem::path string conversions
This simplifies the logic of converting Source arguments and pairs of
InputIterator arguments into the native string format. For any input
that is a contiguous range of path::value_type (or char8_t for POSIX)
a string view can be created and the conversion can be done directly,
with no intermediate allocation. Previously some cases created a
basic_string unnecessarily, for example construction from a pair of
path::string_type::iterators, or a pair of non-const value_type*
pointers.

	* include/bits/fs_path.h (__detail::_S_range_begin)
	(__detail::_S_range_end, path::_S_string_from_iter): Replace with
	overloaded function template __detail::__effective_range.
	(__detail::__effective_range): New overloaded function template to
	create a basic_string or basic_string_view for an effective range.
	(__detail::__value_type_is_char): Use __detail::__effective_range.
	Do not use remove_const on value type.
	(__detail::__value_type_is_char_or_char8_t): Likewise.
	(path::path(const Source&, format))
	(path::path(const Source&, const locale&))
	(path::operator/=(const Source&), path::append(const Source&))
	(path::concat(const Source&)): Use __detail::__effective_range.
	(path::_S_to_string(InputIterator, InputIterator)): New function
	template to create a string view if possible, or string otherwise.
	(path::_S_convert): Add overloads that convert a string returned
	by __detail::__effective_range. Use if-constexpr to inline conversion
	logic from all overloads of _Cvt::_S_convert.
	(path::_S_convert_loc): Add overload that converts a string. Use
	_S_to_string to avoid allocation when possible.
	(path::_Cvt): Remove.
	(path::operator+=(CharT)): Remove indirection through path::concat.
	* include/experimental/bits/fs_path.h (path::_S_convert_loc): Add
	overload for non-const pointers, to avoid constructing a std::string.
	* src/c++17/fs_path.cc (path::_S_convert_loc): Replace conditional
	compilation with call to _S_convert.
2020-05-23 09:40:16 +01:00
Jonathan Wakely
00c8f2a5e3 libstdc++: Remove incorrect static specifiers
These functions were originally static members of the path class, but
the 'static' specifiers were not removed when they were moved to
namespace scope. This causes ODR violations when the functions are
called from functions defined in the header, which is incompatible with
Nathan's modules branch.  Change them to 'inline' instead.

	* include/bits/fs_path.h (__detail::_S_range_begin)
	(__detail::_S_range_end): Remove unintentional static specifiers.
	* include/experimental/bits/fs_path.h (__detail::_S_range_begin)
	(__detail::_S_range_end): Likewise.
2020-05-23 09:40:16 +01:00
Jonathan Wakely
988b853f9c libstdc++: Simplify filesystem::path SFINAE constraints
This replaces the filesystem::__detail::_Path SFINAE helper with two
separate helpers, _Path and _Path2. This avoids having one helper which
tries to check two different sets of requirements.

The _Path helper now uses variable templates instead of a set of
overloaded functions to detect specializations of basic_string or
basic_string_view.

The __not_<is_void<remove_pointer_t<_Tp1>> check is not necessary in
C++20 because iterator_traits<void*> is now empty. For C++17 replace
that check with a __safe_iterator_traits helper with partial
specializations for void pointers.

Finally, the __is_encoded_char check no longer uses remove_const_t,
which means that iterators with a const value_type will no longer be
accepted as arguments for path creation. Such iterators resulted in
undefined behaviour anyway, so it's still conforming to reject them in
the constraint checks.

	* include/bits/fs_path.h (filesystem::__detail::__is_encoded_char):
	Replace alias template with variable template. Don't remove const.
	(filesystem::__detail::__is_path_src): Replace overloaded function
	template with variable template and specializations.
	(filesystem::__detail::__is_path_iter_src): Replace alias template
	with class template.
	(filesystem::__detail::_Path): Use __is_path_src. Remove support for
	iterator pairs.
	(filesystem::__detail::_Path2): New alias template for checking
	InputIterator requirements.
	(filesystem::__detail::__constructible_from): Remove.
	(filesystem::path): Replace _Path<Iter, Iter> with _Path2<Iter>.
	* testsuite/27_io/filesystem/path/construct/80762.cc: Check with two
	constructor arguments of void and void* types.
2020-05-23 09:40:16 +01:00
Jonathan Wakely
f094665d46 libstdc++: Avoid constraint recursion with iterator_traits (PR 93983)
Checking whether a filesystem::path constructor argument is an iterator
requires instantiating std::iterator_traits. In C++20 that checks for
satisfaction of std::iterator_traits constraints, which checks if the
type is copyable, which can end up recursing back to the path
constructor. The fix in LWG 3420 is to reorder the cpp17-iterator
concept's constraints to check if the type looks vaguely like an
iterator before checking copyable. That avoids the recursion for types
which definitely aren't iterators, but isn't foolproof.

	PR libstdc++/93983
	* include/bits/iterator_concepts.h (__detail::__cpp17_iterator):
	Reorder constraints to avoid recursion when constructors use
	iterator_traits (LWG 3420).
	* testsuite/24_iterators/customization_points/lwg3420.cc: New test.
2020-05-21 07:32:15 +01:00