diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2019-12-10 23:50:26 +0000 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2019-12-10 23:50:26 +0000 |
commit | cff87282f4f50c2fd471a2fe0df49312716a8caf (patch) | |
tree | 86eeb876af5718df8e8f38dd5347d6e2c594a446 /libstdc++-v3 | |
parent | a6ae300f9a019aff902cd11068af0956288d6541 (diff) |
libstdc++: Correct noexcept-specifiers on span constructors
As discussed at https://github.com/cplusplus/draft/issues/3534 two
std::span constructors specify incorrect conditions for throwing
exceptions. This patch makes those constructors have correct
noexcept-specifiers that accurately reflect what can actually throw.
(span(ContiguousIterator, Sentinel)): Add conditional noexcept.
* include/std/span (span(ContiguousIterator, size_type)): Change
noexcept to be unconditionally true.
* testsuite/23_containers/span/nothrow_cons.cc: New test.
From-SVN: r279206
Diffstat (limited to 'libstdc++-v3')
-rw-r--r-- | libstdc++-v3/ChangeLog | 7 | ||||
-rw-r--r-- | libstdc++-v3/include/std/span | 3 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/23_containers/span/nothrow_cons.cc | 59 |
3 files changed, 68 insertions, 1 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 2b8b9de8e07..3cc22a18b1c 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,10 @@ +2019-12-10 Jonathan Wakely <jwakely@redhat.com> + + (span(ContiguousIterator, Sentinel)): Add conditional noexcept. + * include/std/span (span(ContiguousIterator, size_type)): Change + noexcept to be unconditionally true. + * testsuite/23_containers/span/nothrow_cons.cc: New test. + 2019-12-10 François Dumont <fdumont@gcc.gnu.org> * include/bits/stl_algobase.h diff --git a/libstdc++-v3/include/std/span b/libstdc++-v3/include/std/span index ecce0b33b0b..6328ecbcde5 100644 --- a/libstdc++-v3/include/std/span +++ b/libstdc++-v3/include/std/span @@ -210,6 +210,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION && (!is_convertible_v<_Sentinel, size_type>) constexpr span(_ContiguousIterator __first, _Sentinel __last) + noexcept(noexcept(__last - __first)) : _M_extent(static_cast<size_type>(__last - __first)), _M_ptr(std::to_address(__first)) { @@ -221,7 +222,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION requires (__is_compatible_iterator<_ContiguousIterator>::value) constexpr span(_ContiguousIterator __first, size_type __count) - noexcept(noexcept(std::to_address(__first))) + noexcept : _M_extent(__count), _M_ptr(std::to_address(__first)) { __glibcxx_assert(_Extent == dynamic_extent || __count == _Extent); } diff --git a/libstdc++-v3/testsuite/23_containers/span/nothrow_cons.cc b/libstdc++-v3/testsuite/23_containers/span/nothrow_cons.cc new file mode 100644 index 00000000000..f28a3386aaf --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/span/nothrow_cons.cc @@ -0,0 +1,59 @@ +// Copyright (C) 2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include <span> + +using std::span; +using std::is_nothrow_constructible_v; + +static_assert( is_nothrow_constructible_v<span<int>> ); +static_assert( is_nothrow_constructible_v<span<int, 0>> ); + +static_assert( is_nothrow_constructible_v<span<int>, span<int>&> ); +static_assert( is_nothrow_constructible_v<span<const int>, span<int>&> ); +static_assert( is_nothrow_constructible_v<span<int>, span<int, 1>&> ); +static_assert( is_nothrow_constructible_v<span<const int>, span<int, 1>&> ); +static_assert( is_nothrow_constructible_v<span<int, 1>, span<int, 1>&> ); +static_assert( is_nothrow_constructible_v<span<const int, 1>, span<int, 1>&> ); + +static_assert( is_nothrow_constructible_v<span<int>, int(&)[1]> ); +static_assert( is_nothrow_constructible_v<span<int, 1>, int(&)[1]> ); +static_assert( is_nothrow_constructible_v<span<int>, std::array<int, 1>&> ); +static_assert( is_nothrow_constructible_v<span<int, 1>, std::array<int, 1>&> ); + +template<bool> +struct sentinel { int* p; }; + +template<bool B> +bool operator==(sentinel<B> s, int* p) noexcept { return s.p == p; } + +template<bool B> +std::ptrdiff_t operator-(sentinel<B> s, int* p) noexcept(B) { return s.p - p; } + +template<bool B> +std::ptrdiff_t operator-(int* p, sentinel<B> s) noexcept { return p - s.p; } + +static_assert(std::sized_sentinel_for<sentinel<true>, int*>); +static_assert(std::sized_sentinel_for<sentinel<false>, int*>); + +static_assert(is_nothrow_constructible_v<span<int>, int*, std::size_t>); +static_assert(is_nothrow_constructible_v<span<int>, int*, const int*>); +static_assert(is_nothrow_constructible_v<span<int>, int*, sentinel<true>>); +static_assert(!is_nothrow_constructible_v<span<int>, int*, sentinel<false>>); |