public inbox for libstdc++-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r10-9595] libstdc++: Add noexcept to std::begin etc as per LWG 2280 and 3537
@ 2021-03-29 20:03 Jonathan Wakely
0 siblings, 0 replies; only message in thread
From: Jonathan Wakely @ 2021-03-29 20:03 UTC (permalink / raw)
To: gcc-cvs, libstdc++-cvs
https://gcc.gnu.org/g:e7b2f969346435c5b460a4021b1334c0a4c11df2
commit r10-9595-ge7b2f969346435c5b460a4021b1334c0a4c11df2
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Mon Mar 22 15:15:12 2021 +0000
libstdc++: Add noexcept to std::begin etc as per LWG 2280 and 3537
This implements the proposed changes for LWG 3537 (which we're allowed
to do as an extension whatever the outcome of the issue). I noticed we
didn't implement LWG 2280 completely, as the std::begin and std::end
overloads for arrays were not noexcept.
libstdc++-v3/ChangeLog:
* include/bits/range_access.h (begin(T (&)[N]), end(T (&)[N])):
Add missing 'noexcept' as per LWG 2280.
(rbegin(T (&)[N]), rend(T (&)[N]), rbegin(initializer_list<T>))
(rend(initializer_list<T>)): Add 'noexcept' as per LWG 3537.
* testsuite/24_iterators/range_access/range_access.cc: Check for
expected noexcept specifiers. Check result types of generic
std::begin and std::end overloads.
* testsuite/24_iterators/range_access/range_access_cpp14.cc:
Check for expected noexcept specifiers.
* testsuite/24_iterators/range_access/range_access_cpp17.cc:
Likewise.
(cherry picked from commit 00b46c00c8d9003c61e8f817668ad3380e16fedb)
Diff:
---
libstdc++-v3/include/bits/range_access.h | 12 ++++-----
.../24_iterators/range_access/range_access.cc | 30 ++++++++++++++++++++++
.../range_access/range_access_cpp14.cc | 15 +++++++++++
.../range_access/range_access_cpp17.cc | 14 ++++++++++
4 files changed, 65 insertions(+), 6 deletions(-)
diff --git a/libstdc++-v3/include/bits/range_access.h b/libstdc++-v3/include/bits/range_access.h
index 3853bbf862b..c93d1e37f34 100644
--- a/libstdc++-v3/include/bits/range_access.h
+++ b/libstdc++-v3/include/bits/range_access.h
@@ -87,7 +87,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
template<typename _Tp, size_t _Nm>
inline _GLIBCXX14_CONSTEXPR _Tp*
- begin(_Tp (&__arr)[_Nm])
+ begin(_Tp (&__arr)[_Nm]) noexcept
{ return __arr; }
/**
@@ -97,7 +97,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
template<typename _Tp, size_t _Nm>
inline _GLIBCXX14_CONSTEXPR _Tp*
- end(_Tp (&__arr)[_Nm])
+ end(_Tp (&__arr)[_Nm]) noexcept
{ return __arr + _Nm; }
#if __cplusplus >= 201402L
@@ -178,7 +178,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
template<typename _Tp, size_t _Nm>
inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Tp*>
- rbegin(_Tp (&__arr)[_Nm])
+ rbegin(_Tp (&__arr)[_Nm]) noexcept
{ return reverse_iterator<_Tp*>(__arr + _Nm); }
/**
@@ -188,7 +188,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
template<typename _Tp, size_t _Nm>
inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Tp*>
- rend(_Tp (&__arr)[_Nm])
+ rend(_Tp (&__arr)[_Nm]) noexcept
{ return reverse_iterator<_Tp*>(__arr); }
/**
@@ -198,7 +198,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
template<typename _Tp>
inline _GLIBCXX17_CONSTEXPR reverse_iterator<const _Tp*>
- rbegin(initializer_list<_Tp> __il)
+ rbegin(initializer_list<_Tp> __il) noexcept
{ return reverse_iterator<const _Tp*>(__il.end()); }
/**
@@ -208,7 +208,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
template<typename _Tp>
inline _GLIBCXX17_CONSTEXPR reverse_iterator<const _Tp*>
- rend(initializer_list<_Tp> __il)
+ rend(initializer_list<_Tp> __il) noexcept
{ return reverse_iterator<const _Tp*>(__il.begin()); }
/**
diff --git a/libstdc++-v3/testsuite/24_iterators/range_access/range_access.cc b/libstdc++-v3/testsuite/24_iterators/range_access/range_access.cc
index 865e784738c..d86ea3271e2 100644
--- a/libstdc++-v3/testsuite/24_iterators/range_access/range_access.cc
+++ b/libstdc++-v3/testsuite/24_iterators/range_access/range_access.cc
@@ -27,4 +27,34 @@ test01()
int arr[3] = {1, 2, 3};
std::begin(arr);
std::end(arr);
+
+ static_assert( noexcept(std::begin(arr)), "LWG 2280" );
+ static_assert( noexcept(std::end(arr)), "LWG 2280" );
+}
+
+void
+test02()
+{
+ extern void require_int(int*);
+ extern void require_long(long*);
+
+ struct B
+ {
+ int* begin() { return nullptr; }
+ long* begin() const { return nullptr; }
+ };
+
+ B b;
+ require_int( std::begin(b) );
+ require_long( std::begin(const_cast<const B&>(b)) );
+
+ struct E
+ {
+ int* end() { return nullptr; }
+ long* end() const { return nullptr; }
+ };
+
+ E e;
+ require_int( std::end(e) );
+ require_long( std::end(const_cast<const E&>(e)) );
}
diff --git a/libstdc++-v3/testsuite/24_iterators/range_access/range_access_cpp14.cc b/libstdc++-v3/testsuite/24_iterators/range_access/range_access_cpp14.cc
index 1df05ba9c5e..e66caf97cbd 100644
--- a/libstdc++-v3/testsuite/24_iterators/range_access/range_access_cpp14.cc
+++ b/libstdc++-v3/testsuite/24_iterators/range_access/range_access_cpp14.cc
@@ -39,10 +39,21 @@ void
test02()
{
static int i[1];
+ // LWG 2280
constexpr auto b __attribute__((unused)) = std::begin(i);
constexpr auto e __attribute__((unused)) = std::end(i);
constexpr auto cb __attribute__((unused)) = std::cbegin(i);
constexpr auto ce __attribute__((unused)) = std::cend(i);
+
+ // LWG 2280
+ static_assert( noexcept(std::begin(i)), "LWG 2280" );
+ static_assert( noexcept(std::end(i)), "LWG 2280" );
+ static_assert( noexcept(std::cbegin(i)), "LWG 2280" );
+ static_assert( noexcept(std::cend(i)), "LWG 2280" );
+
+ // LWG 3537
+ static_assert( noexcept(std::rbegin(i)), "LWG 3537" );
+ static_assert( noexcept(std::rend(i)), "LWG 3537" );
}
void
@@ -55,6 +66,10 @@ test03()
VERIFY(std::rend(il) == std::reverse_iterator<const int*>(il.begin()));
VERIFY(std::crbegin(il) == std::reverse_iterator<const int*>(il.end()));
VERIFY(std::crend(il) == std::reverse_iterator<const int*>(il.begin()));
+
+ // LWG 3537
+ static_assert( noexcept(std::rbegin(il)), "LWG 3537" );
+ static_assert( noexcept(std::rend(il)), "LWG 3537" );
}
void
diff --git a/libstdc++-v3/testsuite/24_iterators/range_access/range_access_cpp17.cc b/libstdc++-v3/testsuite/24_iterators/range_access/range_access_cpp17.cc
index 00a856776f7..fe4da9a6df3 100644
--- a/libstdc++-v3/testsuite/24_iterators/range_access/range_access_cpp17.cc
+++ b/libstdc++-v3/testsuite/24_iterators/range_access/range_access_cpp17.cc
@@ -41,6 +41,16 @@ test02()
static int i[] = { 1, 2 };
static_assert(std::distance(std::begin(i), std::end(i)) == 2);
static_assert(std::distance(std::cbegin(i), std::cend(i)) == 2);
+
+ // LWG 2280
+ static_assert( noexcept(std::begin(i)), "LWG 2280" );
+ static_assert( noexcept(std::end(i)), "LWG 2280" );
+ static_assert( noexcept(std::cbegin(i)), "LWG 2280" );
+ static_assert( noexcept(std::cend(i)), "LWG 2280" );
+
+ // LWG 3537
+ static_assert( noexcept(std::rbegin(i)), "LWG 3537" );
+ static_assert( noexcept(std::rend(i)), "LWG 3537" );
}
void
@@ -54,4 +64,8 @@ test03()
static_assert(std::rend(il) == reverse_iterator<const int*>(il.begin()));
static_assert(std::crbegin(il) == reverse_iterator<const int*>(il.end()));
static_assert(std::crend(il) == reverse_iterator<const int*>(il.begin()));
+
+ // LWG 3537
+ static_assert( noexcept(std::rbegin(il)), "LWG 3537" );
+ static_assert( noexcept(std::rend(il)), "LWG 3537" );
}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2021-03-29 20:03 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-29 20:03 [gcc r10-9595] libstdc++: Add noexcept to std::begin etc as per LWG 2280 and 3537 Jonathan Wakely
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).