This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: [PATCH] Add constexpr to iterator adaptors, array and range access
- From: Jonathan Wakely <jwakely at redhat dot com>
- To: Daniel Krügler <daniel dot kruegler at gmail dot com>
- Cc: libstdc++ <libstdc++ at gcc dot gnu dot org>, gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 23 Aug 2016 11:16:53 +0100
- Subject: Re: [PATCH] Add constexpr to iterator adaptors, array and range access
- Authentication-results: sourceware.org; auth=none
- References: <20160715230956.GA18883@redhat.com> <CAGNvRgD4S+bp8hWuabMDNafAGfw-U1Mm7ESB4mrrWFvrt1bhNw@mail.gmail.com>
On 16/07/16 14:55 +0200, Daniel Krügler wrote:
2016-07-16 1:09 GMT+02:00 Jonathan Wakely <jwakely@redhat.com>:
This patch implements http://wg21.link/p0031 which adds constexpr to
most operations on std::reverse_iterator, std::move_iterator,
std::array, as well as std::advance, std::distance, and the
range-access functions std::begin, std::rbegin etc.
Strictly speaking, those functions should only be constexpr in C++17
and not before, but this patch makes them constexpr whenever possible.
That means the changes are fully implemented for C++14 (and the
feature-test macro is defined) but only partially implemented for
C++11, because some of the functions can't be constexpr in C++11.
My thinking is that if the committee has decided that these functions
*should* be constexpr, and changed them for C++17, then it doesn't
serve users to make them non-constexpr in C++11 and C++14 just because
the standard says so.
How do other people feel about that?
The alternative would be to define a new _GLIBCXX17_CONSTEXPR macro
and use it in all these places, so they're only constexpr in C++17
(and probably for -std=gnu++14 too, but not -std=c++14).
How strict do we want to be about obeying the "implementors can't add
constexpr" rule in these cases?
As much as I hate the current restrictions, I tend to suggest to
follow them strictly in __STRICT_ANSI__ mode.
As there were objections to adding constexpr to C++11 and C++14 where
it's not meant to be, I'm only adding it for C++17.
We can relax that for gnu++14 (i.e. !__STRICT_ANSI__) later, but I
haven't done that for now.
Here's the patch, but I'm not committing it yet.
Since I made a similar (unintentional) omission recently myself:
Shouldn't you touch std::__debug::array as well? What about other
functions from std::__debug?
Yes, I'll fix those shortly.
Committed to trunk.
commit 4e025f534aff5a43d319b7f3f4a89d98f3dcaf53
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Fri Jul 15 22:31:16 2016 +0100
Add constexpr to <iterator> and <array> for C++17
* include/bits/c++config (_GLIBCXX17_CONSTEXPR): Define.
* include/bits/range_access.h (begin, end, rbegin, rend, crbegin)
(crend): Add _GLIBCXX17_CONSTEXPR as per P0031R0.
* include/bits/stl_iterator.h (reverse_iterator, move_iterator)
(__make_reverse_iterator, make_reverse_iterator, make_move_iterator):
Likewise.
* include/bits/stl_iterator_base_funcs.h (__distance, __advance): Add
_GLIBCXX14_CONSTEXPR.
(distance, advance, next, prev): Add _GLIBCXX17_CONSTEXPR.
* include/std/array (array::begin, array::end, array::rbegin)
(array::rend, array::cbegin, array:cend, array::crbegin)
(array::crend, array::operator[], array::at, array::front)
(array::back, array::data): Likewise.
* testsuite/24_iterators/headers/iterator/range_access.cc: Replace
with separate tests for C++11, C++14, and C++17.
* testsuite/24_iterators/headers/iterator/range_access_c++11.cc: New.
* testsuite/24_iterators/headers/iterator/range_access_c++14.cc: New.
* testsuite/24_iterators/headers/iterator/range_access_c++17.cc: New.
diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index 8d2c361..656ef78 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -111,6 +111,14 @@
# endif
#endif
+#ifndef _GLIBCXX17_CONSTEXPR
+# if __cplusplus > 201402L
+# define _GLIBCXX17_CONSTEXPR constexpr
+# else
+# define _GLIBCXX17_CONSTEXPR
+# endif
+#endif
+
// Macro for noexcept, to support in mixed 03/0x mode.
#ifndef _GLIBCXX_NOEXCEPT
# if __cplusplus >= 201103L
diff --git a/libstdc++-v3/include/bits/range_access.h b/libstdc++-v3/include/bits/range_access.h
index d6f8fa1..27cc8ed 100644
--- a/libstdc++-v3/include/bits/range_access.h
+++ b/libstdc++-v3/include/bits/range_access.h
@@ -48,7 +48,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __cont Container.
*/
template<typename _Container>
- inline auto
+ inline _GLIBCXX17_CONSTEXPR auto
begin(_Container& __cont) -> decltype(__cont.begin())
{ return __cont.begin(); }
@@ -58,7 +58,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __cont Container.
*/
template<typename _Container>
- inline auto
+ inline _GLIBCXX17_CONSTEXPR auto
begin(const _Container& __cont) -> decltype(__cont.begin())
{ return __cont.begin(); }
@@ -68,7 +68,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __cont Container.
*/
template<typename _Container>
- inline auto
+ inline _GLIBCXX17_CONSTEXPR auto
end(_Container& __cont) -> decltype(__cont.end())
{ return __cont.end(); }
@@ -78,7 +78,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __cont Container.
*/
template<typename _Container>
- inline auto
+ inline _GLIBCXX17_CONSTEXPR auto
end(const _Container& __cont) -> decltype(__cont.end())
{ return __cont.end(); }
@@ -138,7 +138,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __cont Container.
*/
template<typename _Container>
- inline auto
+ inline _GLIBCXX17_CONSTEXPR auto
rbegin(_Container& __cont) -> decltype(__cont.rbegin())
{ return __cont.rbegin(); }
@@ -148,7 +148,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __cont Container.
*/
template<typename _Container>
- inline auto
+ inline _GLIBCXX17_CONSTEXPR auto
rbegin(const _Container& __cont) -> decltype(__cont.rbegin())
{ return __cont.rbegin(); }
@@ -158,7 +158,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __cont Container.
*/
template<typename _Container>
- inline auto
+ inline _GLIBCXX17_CONSTEXPR auto
rend(_Container& __cont) -> decltype(__cont.rend())
{ return __cont.rend(); }
@@ -168,7 +168,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __cont Container.
*/
template<typename _Container>
- inline auto
+ inline _GLIBCXX17_CONSTEXPR auto
rend(const _Container& __cont) -> decltype(__cont.rend())
{ return __cont.rend(); }
@@ -178,7 +178,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __arr Array.
*/
template<typename _Tp, size_t _Nm>
- inline reverse_iterator<_Tp*>
+ inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Tp*>
rbegin(_Tp (&__arr)[_Nm])
{ return reverse_iterator<_Tp*>(__arr + _Nm); }
@@ -188,7 +188,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __arr Array.
*/
template<typename _Tp, size_t _Nm>
- inline reverse_iterator<_Tp*>
+ inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Tp*>
rend(_Tp (&__arr)[_Nm])
{ return reverse_iterator<_Tp*>(__arr); }
@@ -198,7 +198,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __il initializer_list.
*/
template<typename _Tp>
- inline reverse_iterator<const _Tp*>
+ inline _GLIBCXX17_CONSTEXPR reverse_iterator<const _Tp*>
rbegin(initializer_list<_Tp> __il)
{ return reverse_iterator<const _Tp*>(__il.end()); }
@@ -208,7 +208,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __il initializer_list.
*/
template<typename _Tp>
- inline reverse_iterator<const _Tp*>
+ inline _GLIBCXX17_CONSTEXPR reverse_iterator<const _Tp*>
rend(initializer_list<_Tp> __il)
{ return reverse_iterator<const _Tp*>(__il.begin()); }
@@ -218,7 +218,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __cont Container.
*/
template<typename _Container>
- inline auto
+ inline _GLIBCXX17_CONSTEXPR auto
crbegin(const _Container& __cont) -> decltype(std::rbegin(__cont))
{ return std::rbegin(__cont); }
@@ -228,7 +228,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __cont Container.
*/
template<typename _Container>
- inline auto
+ inline _GLIBCXX17_CONSTEXPR auto
crend(const _Container& __cont) -> decltype(std::rend(__cont))
{ return std::rend(__cont); }
diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h
index 3401cd0..037e966 100644
--- a/libstdc++-v3/include/bits/stl_iterator.h
+++ b/libstdc++-v3/include/bits/stl_iterator.h
@@ -65,6 +65,10 @@
#include <bits/move.h>
#include <bits/ptr_traits.h>
+#if __cplusplus > 201402L
+# define __cpp_lib_array_constexpr 201603
+#endif
+
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -118,17 +122,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 235 No specification of default ctor for reverse_iterator
+ _GLIBCXX17_CONSTEXPR
reverse_iterator() : current() { }
/**
* This %iterator will move in the opposite direction that @p x does.
*/
- explicit
+ explicit _GLIBCXX17_CONSTEXPR
reverse_iterator(iterator_type __x) : current(__x) { }
/**
* The copy constructor is normal.
*/
+ _GLIBCXX17_CONSTEXPR
reverse_iterator(const reverse_iterator& __x)
: current(__x.current) { }
@@ -137,13 +143,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* underlying %iterator can be converted to the type of @c current.
*/
template<typename _Iter>
+ _GLIBCXX17_CONSTEXPR
reverse_iterator(const reverse_iterator<_Iter>& __x)
: current(__x.base()) { }
/**
* @return @c current, the %iterator used for underlying work.
*/
- iterator_type
+ _GLIBCXX17_CONSTEXPR iterator_type
base() const
{ return current; }
@@ -157,7 +164,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @c *x remains valid after @c x has been modified or
* destroyed. This is a bug: http://gcc.gnu.org/PR51823
*/
- reference
+ _GLIBCXX17_CONSTEXPR reference
operator*() const
{
_Iterator __tmp = current;
@@ -169,7 +176,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*
* This requires that @c --current is dereferenceable.
*/
- pointer
+ _GLIBCXX17_CONSTEXPR pointer
operator->() const
{ return &(operator*()); }
@@ -178,7 +185,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*
* Decrements the underlying iterator.
*/
- reverse_iterator&
+ _GLIBCXX17_CONSTEXPR reverse_iterator&
operator++()
{
--current;
@@ -190,7 +197,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*
* Decrements the underlying iterator.
*/
- reverse_iterator
+ _GLIBCXX17_CONSTEXPR reverse_iterator
operator++(int)
{
reverse_iterator __tmp = *this;
@@ -203,7 +210,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*
* Increments the underlying iterator.
*/
- reverse_iterator&
+ _GLIBCXX17_CONSTEXPR reverse_iterator&
operator--()
{
++current;
@@ -215,7 +222,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*
* Increments the underlying iterator.
*/
- reverse_iterator
+ _GLIBCXX17_CONSTEXPR reverse_iterator
operator--(int)
{
reverse_iterator __tmp = *this;
@@ -228,7 +235,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*
* The underlying iterator must be a Random Access Iterator.
*/
- reverse_iterator
+ _GLIBCXX17_CONSTEXPR reverse_iterator
operator+(difference_type __n) const
{ return reverse_iterator(current - __n); }
@@ -238,7 +245,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* Moves the underlying iterator backwards @a __n steps.
* The underlying iterator must be a Random Access Iterator.
*/
- reverse_iterator&
+ _GLIBCXX17_CONSTEXPR reverse_iterator&
operator+=(difference_type __n)
{
current -= __n;
@@ -250,7 +257,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*
* The underlying iterator must be a Random Access Iterator.
*/
- reverse_iterator
+ _GLIBCXX17_CONSTEXPR reverse_iterator
operator-(difference_type __n) const
{ return reverse_iterator(current + __n); }
@@ -260,7 +267,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* Moves the underlying iterator forwards @a __n steps.
* The underlying iterator must be a Random Access Iterator.
*/
- reverse_iterator&
+ _GLIBCXX17_CONSTEXPR reverse_iterator&
operator-=(difference_type __n)
{
current += __n;
@@ -272,7 +279,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*
* The underlying iterator must be a Random Access Iterator.
*/
- reference
+ _GLIBCXX17_CONSTEXPR reference
operator[](difference_type __n) const
{ return *(*this + __n); }
};
@@ -288,49 +295,50 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*
*/
template<typename _Iterator>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator==(const reverse_iterator<_Iterator>& __x,
const reverse_iterator<_Iterator>& __y)
{ return __x.base() == __y.base(); }
template<typename _Iterator>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator<(const reverse_iterator<_Iterator>& __x,
const reverse_iterator<_Iterator>& __y)
{ return __y.base() < __x.base(); }
template<typename _Iterator>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator!=(const reverse_iterator<_Iterator>& __x,
const reverse_iterator<_Iterator>& __y)
{ return !(__x == __y); }
template<typename _Iterator>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator>(const reverse_iterator<_Iterator>& __x,
const reverse_iterator<_Iterator>& __y)
{ return __y < __x; }
template<typename _Iterator>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator<=(const reverse_iterator<_Iterator>& __x,
const reverse_iterator<_Iterator>& __y)
{ return !(__y < __x); }
template<typename _Iterator>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator>=(const reverse_iterator<_Iterator>& __x,
const reverse_iterator<_Iterator>& __y)
{ return !(__x < __y); }
template<typename _Iterator>
- inline typename reverse_iterator<_Iterator>::difference_type
+ inline _GLIBCXX17_CONSTEXPR
+ typename reverse_iterator<_Iterator>::difference_type
operator-(const reverse_iterator<_Iterator>& __x,
const reverse_iterator<_Iterator>& __y)
{ return __y.base() - __x.base(); }
template<typename _Iterator>
- inline reverse_iterator<_Iterator>
+ inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Iterator>
operator+(typename reverse_iterator<_Iterator>::difference_type __n,
const reverse_iterator<_Iterator>& __x)
{ return reverse_iterator<_Iterator>(__x.base() - __n); }
@@ -338,37 +346,37 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 280. Comparison of reverse_iterator to const reverse_iterator.
template<typename _IteratorL, typename _IteratorR>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator==(const reverse_iterator<_IteratorL>& __x,
const reverse_iterator<_IteratorR>& __y)
{ return __x.base() == __y.base(); }
template<typename _IteratorL, typename _IteratorR>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator<(const reverse_iterator<_IteratorL>& __x,
const reverse_iterator<_IteratorR>& __y)
{ return __y.base() < __x.base(); }
template<typename _IteratorL, typename _IteratorR>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator!=(const reverse_iterator<_IteratorL>& __x,
const reverse_iterator<_IteratorR>& __y)
{ return !(__x == __y); }
template<typename _IteratorL, typename _IteratorR>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator>(const reverse_iterator<_IteratorL>& __x,
const reverse_iterator<_IteratorR>& __y)
{ return __y < __x; }
template<typename _IteratorL, typename _IteratorR>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator<=(const reverse_iterator<_IteratorL>& __x,
const reverse_iterator<_IteratorR>& __y)
{ return !(__y < __x); }
template<typename _IteratorL, typename _IteratorR>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator>=(const reverse_iterator<_IteratorL>& __x,
const reverse_iterator<_IteratorR>& __y)
{ return !(__x < __y); }
@@ -376,7 +384,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _IteratorL, typename _IteratorR>
#if __cplusplus >= 201103L
// DR 685.
- inline auto
+ inline _GLIBCXX17_CONSTEXPR auto
operator-(const reverse_iterator<_IteratorL>& __x,
const reverse_iterator<_IteratorR>& __y)
-> decltype(__y.base() - __x.base())
@@ -391,7 +399,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#if __cplusplus >= 201103L
// Same as C++14 make_reverse_iterator but used in C++03 mode too.
template<typename _Iterator>
- inline reverse_iterator<_Iterator>
+ inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Iterator>
__make_reverse_iterator(_Iterator __i)
{ return reverse_iterator<_Iterator>(__i); }
@@ -402,7 +410,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// DR 2285. make_reverse_iterator
/// Generator function for reverse_iterator.
template<typename _Iterator>
- inline reverse_iterator<_Iterator>
+ inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Iterator>
make_reverse_iterator(_Iterator __i)
{ return reverse_iterator<_Iterator>(__i); }
# endif
@@ -1018,37 +1026,39 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename remove_reference<__base_ref>::type&&,
__base_ref>::type reference;
+ _GLIBCXX17_CONSTEXPR
move_iterator()
: _M_current() { }
- explicit
+ explicit _GLIBCXX17_CONSTEXPR
move_iterator(iterator_type __i)
: _M_current(__i) { }
template<typename _Iter>
+ _GLIBCXX17_CONSTEXPR
move_iterator(const move_iterator<_Iter>& __i)
: _M_current(__i.base()) { }
- iterator_type
+ _GLIBCXX17_CONSTEXPR iterator_type
base() const
{ return _M_current; }
- reference
+ _GLIBCXX17_CONSTEXPR reference
operator*() const
{ return static_cast<reference>(*_M_current); }
- pointer
+ _GLIBCXX17_CONSTEXPR pointer
operator->() const
{ return _M_current; }
- move_iterator&
+ _GLIBCXX17_CONSTEXPR move_iterator&
operator++()
{
++_M_current;
return *this;
}
- move_iterator
+ _GLIBCXX17_CONSTEXPR move_iterator
operator++(int)
{
move_iterator __tmp = *this;
@@ -1056,14 +1066,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __tmp;
}
- move_iterator&
+ _GLIBCXX17_CONSTEXPR move_iterator&
operator--()
{
--_M_current;
return *this;
}
- move_iterator
+ _GLIBCXX17_CONSTEXPR move_iterator
operator--(int)
{
move_iterator __tmp = *this;
@@ -1071,29 +1081,29 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __tmp;
}
- move_iterator
+ _GLIBCXX17_CONSTEXPR move_iterator
operator+(difference_type __n) const
{ return move_iterator(_M_current + __n); }
- move_iterator&
+ _GLIBCXX17_CONSTEXPR move_iterator&
operator+=(difference_type __n)
{
_M_current += __n;
return *this;
}
- move_iterator
+ _GLIBCXX17_CONSTEXPR move_iterator
operator-(difference_type __n) const
{ return move_iterator(_M_current - __n); }
- move_iterator&
+ _GLIBCXX17_CONSTEXPR move_iterator&
operator-=(difference_type __n)
{
_M_current -= __n;
return *this;
}
- reference
+ _GLIBCXX17_CONSTEXPR reference
operator[](difference_type __n) const
{ return std::move(_M_current[__n]); }
};
@@ -1102,100 +1112,100 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// why there are always 2 versions for most of the move_iterator
// operators.
template<typename _IteratorL, typename _IteratorR>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator==(const move_iterator<_IteratorL>& __x,
const move_iterator<_IteratorR>& __y)
{ return __x.base() == __y.base(); }
template<typename _Iterator>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator==(const move_iterator<_Iterator>& __x,
const move_iterator<_Iterator>& __y)
{ return __x.base() == __y.base(); }
template<typename _IteratorL, typename _IteratorR>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator!=(const move_iterator<_IteratorL>& __x,
const move_iterator<_IteratorR>& __y)
{ return !(__x == __y); }
template<typename _Iterator>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator!=(const move_iterator<_Iterator>& __x,
const move_iterator<_Iterator>& __y)
{ return !(__x == __y); }
template<typename _IteratorL, typename _IteratorR>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator<(const move_iterator<_IteratorL>& __x,
const move_iterator<_IteratorR>& __y)
{ return __x.base() < __y.base(); }
template<typename _Iterator>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator<(const move_iterator<_Iterator>& __x,
const move_iterator<_Iterator>& __y)
{ return __x.base() < __y.base(); }
template<typename _IteratorL, typename _IteratorR>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator<=(const move_iterator<_IteratorL>& __x,
const move_iterator<_IteratorR>& __y)
{ return !(__y < __x); }
template<typename _Iterator>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator<=(const move_iterator<_Iterator>& __x,
const move_iterator<_Iterator>& __y)
{ return !(__y < __x); }
template<typename _IteratorL, typename _IteratorR>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator>(const move_iterator<_IteratorL>& __x,
const move_iterator<_IteratorR>& __y)
{ return __y < __x; }
template<typename _Iterator>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator>(const move_iterator<_Iterator>& __x,
const move_iterator<_Iterator>& __y)
{ return __y < __x; }
template<typename _IteratorL, typename _IteratorR>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator>=(const move_iterator<_IteratorL>& __x,
const move_iterator<_IteratorR>& __y)
{ return !(__x < __y); }
template<typename _Iterator>
- inline bool
+ inline _GLIBCXX17_CONSTEXPR bool
operator>=(const move_iterator<_Iterator>& __x,
const move_iterator<_Iterator>& __y)
{ return !(__x < __y); }
// DR 685.
template<typename _IteratorL, typename _IteratorR>
- inline auto
+ inline _GLIBCXX17_CONSTEXPR auto
operator-(const move_iterator<_IteratorL>& __x,
const move_iterator<_IteratorR>& __y)
-> decltype(__x.base() - __y.base())
{ return __x.base() - __y.base(); }
template<typename _Iterator>
- inline auto
+ inline _GLIBCXX17_CONSTEXPR auto
operator-(const move_iterator<_Iterator>& __x,
const move_iterator<_Iterator>& __y)
-> decltype(__x.base() - __y.base())
{ return __x.base() - __y.base(); }
template<typename _Iterator>
- inline move_iterator<_Iterator>
+ inline _GLIBCXX17_CONSTEXPR move_iterator<_Iterator>
operator+(typename move_iterator<_Iterator>::difference_type __n,
const move_iterator<_Iterator>& __x)
{ return __x + __n; }
template<typename _Iterator>
- inline move_iterator<_Iterator>
+ inline _GLIBCXX17_CONSTEXPR move_iterator<_Iterator>
make_move_iterator(_Iterator __i)
{ return move_iterator<_Iterator>(__i); }
@@ -1203,7 +1213,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
= typename conditional<__move_if_noexcept_cond
<typename iterator_traits<_Iterator>::value_type>::value,
_Iterator, move_iterator<_Iterator>>::type>
- inline _ReturnType
+ inline _GLIBCXX17_CONSTEXPR _ReturnType
__make_move_if_noexcept_iterator(_Iterator __i)
{ return _ReturnType(__i); }
@@ -1212,7 +1222,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp, typename _ReturnType
= typename conditional<__move_if_noexcept_cond<_Tp>::value,
const _Tp*, move_iterator<_Tp*>>::type>
- inline _ReturnType
+ inline _GLIBCXX17_CONSTEXPR _ReturnType
__make_move_if_noexcept_iterator(_Tp* __i)
{ return _ReturnType(__i); }
diff --git a/libstdc++-v3/include/bits/stl_iterator_base_funcs.h b/libstdc++-v3/include/bits/stl_iterator_base_funcs.h
index a8b156d..1fc646c 100644
--- a/libstdc++-v3/include/bits/stl_iterator_base_funcs.h
+++ b/libstdc++-v3/include/bits/stl_iterator_base_funcs.h
@@ -75,7 +75,8 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
_GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _InputIterator>
- inline typename iterator_traits<_InputIterator>::difference_type
+ inline _GLIBCXX14_CONSTEXPR
+ typename iterator_traits<_InputIterator>::difference_type
__distance(_InputIterator __first, _InputIterator __last,
input_iterator_tag)
{
@@ -92,7 +93,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _RandomAccessIterator>
- inline typename iterator_traits<_RandomAccessIterator>::difference_type
+ inline _GLIBCXX14_CONSTEXPR
+ typename iterator_traits<_RandomAccessIterator>::difference_type
__distance(_RandomAccessIterator __first, _RandomAccessIterator __last,
random_access_iterator_tag)
{
@@ -131,7 +133,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* and are constant time. For other %iterator classes they are linear time.
*/
template<typename _InputIterator>
- inline typename iterator_traits<_InputIterator>::difference_type
+ inline _GLIBCXX17_CONSTEXPR
+ typename iterator_traits<_InputIterator>::difference_type
distance(_InputIterator __first, _InputIterator __last)
{
// concept requirements -- taken care of in __distance
@@ -140,7 +143,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _InputIterator, typename _Distance>
- inline void
+ inline _GLIBCXX14_CONSTEXPR void
__advance(_InputIterator& __i, _Distance __n, input_iterator_tag)
{
// concept requirements
@@ -151,7 +154,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _BidirectionalIterator, typename _Distance>
- inline void
+ inline _GLIBCXX14_CONSTEXPR void
__advance(_BidirectionalIterator& __i, _Distance __n,
bidirectional_iterator_tag)
{
@@ -167,7 +170,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _RandomAccessIterator, typename _Distance>
- inline void
+ inline _GLIBCXX14_CONSTEXPR void
__advance(_RandomAccessIterator& __i, _Distance __n,
random_access_iterator_tag)
{
@@ -190,7 +193,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* and are constant time. For other %iterator classes they are linear time.
*/
template<typename _InputIterator, typename _Distance>
- inline void
+ inline _GLIBCXX17_CONSTEXPR void
advance(_InputIterator& __i, _Distance __n)
{
// concept requirements -- taken care of in __advance
@@ -201,7 +204,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#if __cplusplus >= 201103L
template<typename _ForwardIterator>
- inline _ForwardIterator
+ inline _GLIBCXX17_CONSTEXPR _ForwardIterator
next(_ForwardIterator __x, typename
iterator_traits<_ForwardIterator>::difference_type __n = 1)
{
@@ -213,7 +216,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _BidirectionalIterator>
- inline _BidirectionalIterator
+ inline _GLIBCXX17_CONSTEXPR _BidirectionalIterator
prev(_BidirectionalIterator __x, typename
iterator_traits<_BidirectionalIterator>::difference_type __n = 1)
{
diff --git a/libstdc++-v3/include/std/array b/libstdc++-v3/include/std/array
index 73a6fbc..3ab0355 100644
--- a/libstdc++-v3/include/std/array
+++ b/libstdc++-v3/include/std/array
@@ -122,51 +122,51 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{ std::swap_ranges(begin(), end(), __other.begin()); }
// Iterators.
- iterator
+ _GLIBCXX17_CONSTEXPR iterator
begin() noexcept
{ return iterator(data()); }
- const_iterator
+ _GLIBCXX17_CONSTEXPR const_iterator
begin() const noexcept
{ return const_iterator(data()); }
- iterator
+ _GLIBCXX17_CONSTEXPR iterator
end() noexcept
{ return iterator(data() + _Nm); }
- const_iterator
+ _GLIBCXX17_CONSTEXPR const_iterator
end() const noexcept
{ return const_iterator(data() + _Nm); }
- reverse_iterator
+ _GLIBCXX17_CONSTEXPR reverse_iterator
rbegin() noexcept
{ return reverse_iterator(end()); }
- const_reverse_iterator
+ _GLIBCXX17_CONSTEXPR const_reverse_iterator
rbegin() const noexcept
{ return const_reverse_iterator(end()); }
- reverse_iterator
+ _GLIBCXX17_CONSTEXPR reverse_iterator
rend() noexcept
{ return reverse_iterator(begin()); }
- const_reverse_iterator
+ _GLIBCXX17_CONSTEXPR const_reverse_iterator
rend() const noexcept
{ return const_reverse_iterator(begin()); }
- const_iterator
+ _GLIBCXX17_CONSTEXPR const_iterator
cbegin() const noexcept
{ return const_iterator(data()); }
- const_iterator
+ _GLIBCXX17_CONSTEXPR const_iterator
cend() const noexcept
{ return const_iterator(data() + _Nm); }
- const_reverse_iterator
+ _GLIBCXX17_CONSTEXPR const_reverse_iterator
crbegin() const noexcept
{ return const_reverse_iterator(end()); }
- const_reverse_iterator
+ _GLIBCXX17_CONSTEXPR const_reverse_iterator
crend() const noexcept
{ return const_reverse_iterator(begin()); }
@@ -181,7 +181,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
empty() const noexcept { return size() == 0; }
// Element access.
- reference
+ _GLIBCXX17_CONSTEXPR reference
operator[](size_type __n) noexcept
{ return _AT_Type::_S_ref(_M_elems, __n); }
@@ -189,7 +189,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
operator[](size_type __n) const noexcept
{ return _AT_Type::_S_ref(_M_elems, __n); }
- reference
+ _GLIBCXX17_CONSTEXPR reference
at(size_type __n)
{
if (__n >= _Nm)
@@ -211,7 +211,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_AT_Type::_S_ref(_M_elems, 0));
}
- reference
+ _GLIBCXX17_CONSTEXPR reference
front() noexcept
{ return *begin(); }
@@ -219,7 +219,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
front() const noexcept
{ return _AT_Type::_S_ref(_M_elems, 0); }
- reference
+ _GLIBCXX17_CONSTEXPR reference
back() noexcept
{ return _Nm ? *(end() - 1) : *end(); }
@@ -230,11 +230,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
: _AT_Type::_S_ref(_M_elems, 0);
}
- pointer
+ _GLIBCXX17_CONSTEXPR pointer
data() noexcept
{ return _AT_Type::_S_ptr(_M_elems); }
- const_pointer
+ _GLIBCXX17_CONSTEXPR const_pointer
data() const noexcept
{ return _AT_Type::_S_ptr(_M_elems); }
};
diff --git a/libstdc++-v3/testsuite/24_iterators/headers/iterator/range_access.cc b/libstdc++-v3/testsuite/24_iterators/headers/iterator/range_access.cc
deleted file mode 100644
index 873a730..0000000
--- a/libstdc++-v3/testsuite/24_iterators/headers/iterator/range_access.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// { dg-do compile { target c++11 } }
-
-// Copyright (C) 2010-2016 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/>.
-
-#include <iterator>
-
-namespace std
-{
- template<class C> auto begin(C& c) -> decltype(c.begin());
- template<class C> auto begin(const C& c) -> decltype(c.begin());
-
- template<class C> auto end(C& c) -> decltype(c.end());
- template<class C> auto end(const C& c) -> decltype(c.end());
-
-#if __cplusplus >= 201402L
- template<class T, size_t N> constexpr T* begin(T (&array)[N]);
- template<class T, size_t N> constexpr T* end(T (&array)[N]);
-#else
- template<class T, size_t N> T* begin(T (&array)[N]);
- template<class T, size_t N> T* end(T (&array)[N]);
-#endif
-}
diff --git a/libstdc++-v3/testsuite/24_iterators/headers/iterator/range_access_c++11.cc b/libstdc++-v3/testsuite/24_iterators/headers/iterator/range_access_c++11.cc
new file mode 100644
index 0000000..6961a20
--- /dev/null
+++ b/libstdc++-v3/testsuite/24_iterators/headers/iterator/range_access_c++11.cc
@@ -0,0 +1,33 @@
+// { dg-options "-std=gnu++11" }
+// { dg-do compile }
+
+// Copyright (C) 2010-2016 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/>.
+
+#include <iterator>
+
+namespace std
+{
+ template<class C> auto begin(C& c) -> decltype(c.begin());
+ template<class C> auto begin(const C& c) -> decltype(c.begin());
+
+ template<class C> auto end(C& c) -> decltype(c.end());
+ template<class C> auto end(const C& c) -> decltype(c.end());
+
+ template<class T, size_t N> T* begin(T (&array)[N]);
+ template<class T, size_t N> T* end(T (&array)[N]);
+}
diff --git a/libstdc++-v3/testsuite/24_iterators/headers/iterator/range_access_c++14.cc b/libstdc++-v3/testsuite/24_iterators/headers/iterator/range_access_c++14.cc
new file mode 100644
index 0000000..6f39b56
--- /dev/null
+++ b/libstdc++-v3/testsuite/24_iterators/headers/iterator/range_access_c++14.cc
@@ -0,0 +1,57 @@
+// { dg-options "-std=gnu++14" }
+// { dg-do compile }
+
+// Copyright (C) 2016 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/>.
+
+#include <iterator>
+
+namespace std
+{
+ template<class C> auto begin(C& c) -> decltype(c.begin());
+ template<class C> auto begin(const C& c) -> decltype(c.begin());
+
+ template<class C> auto end(C& c) -> decltype(c.end());
+ template<class C> auto end(const C& c) -> decltype(c.end());
+
+ template<class T, size_t N> constexpr T* begin(T (&array)[N]);
+ template<class T, size_t N> constexpr T* end(T (&array)[N]);
+
+ template<class C> auto cbegin(const C& c) -> decltype(c.begin());
+ template<class C> auto cend(const C& c) -> decltype(c.end());
+
+ template<class C> auto rbegin(C& c) -> decltype(c.rbegin());
+ template<class C> auto rbegin(const C& c) -> decltype(c.rbegin());
+
+ template<class C> auto rend(C& c) -> decltype(c.rend());
+ template<class C> auto rend(const C& c) -> decltype(c.rend());
+
+ template<class T, size_t N>
+ reverse_iterator<T*> rbegin(T (&array)[N]);
+ template<class T, size_t N>
+ reverse_iterator<T*> rend(T (&array)[N]);
+
+ template<class E>
+ reverse_iterator<const E*> rbegin(initializer_list<E>);
+ template<class E>
+ reverse_iterator<const E*> rend(initializer_list<E>);
+
+ template<class C>
+ auto crbegin(const C& c) -> decltype(std::rbegin(c));
+ template<class C>
+ auto cend(const C& c) -> decltype(std::rend(c));
+}
diff --git a/libstdc++-v3/testsuite/24_iterators/headers/iterator/range_access_c++17.cc b/libstdc++-v3/testsuite/24_iterators/headers/iterator/range_access_c++17.cc
new file mode 100644
index 0000000..3318809
--- /dev/null
+++ b/libstdc++-v3/testsuite/24_iterators/headers/iterator/range_access_c++17.cc
@@ -0,0 +1,57 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile }
+
+// Copyright (C) 2016 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/>.
+
+#include <iterator>
+
+namespace std
+{
+ template<class C> constexpr auto begin(C& c) -> decltype(c.begin());
+ template<class C> constexpr auto begin(const C& c) -> decltype(c.begin());
+
+ template<class C> constexpr auto end(C& c) -> decltype(c.end());
+ template<class C> constexpr auto end(const C& c) -> decltype(c.end());
+
+ template<class T, size_t N> constexpr T* begin(T (&array)[N]);
+ template<class T, size_t N> constexpr T* end(T (&array)[N]);
+
+ template<class C> constexpr auto cbegin(const C& c) -> decltype(c.begin());
+ template<class C> constexpr auto cend(const C& c) -> decltype(c.end());
+
+ template<class C> constexpr auto rbegin(C& c) -> decltype(c.rbegin());
+ template<class C> constexpr auto rbegin(const C& c) -> decltype(c.rbegin());
+
+ template<class C> constexpr auto rend(C& c) -> decltype(c.rend());
+ template<class C> constexpr auto rend(const C& c) -> decltype(c.rend());
+
+ template<class T, size_t N>
+ constexpr reverse_iterator<T*> rbegin(T (&array)[N]);
+ template<class T, size_t N>
+ constexpr reverse_iterator<T*> rend(T (&array)[N]);
+
+ template<class E>
+ constexpr reverse_iterator<const E*> rbegin(initializer_list<E>);
+ template<class E>
+ constexpr reverse_iterator<const E*> rend(initializer_list<E>);
+
+ template<class C>
+ constexpr auto crbegin(const C& c) -> decltype(std::rbegin(c));
+ template<class C>
+ constexpr auto cend(const C& c) -> decltype(std::rend(c));
+}
diff --git a/libstdc++-v3/testsuite/ext/profile/mutex_extensions_neg.cc b/libstdc++-v3/testsuite/ext/profile/mutex_extensions_neg.cc
index e59d666..874f3de 100644
--- a/libstdc++-v3/testsuite/ext/profile/mutex_extensions_neg.cc
+++ b/libstdc++-v3/testsuite/ext/profile/mutex_extensions_neg.cc
@@ -25,7 +25,7 @@
#include <vector>
-// { dg-error "multiple inlined namespaces" "" { target *-*-* } 324 }
+// { dg-error "multiple inlined namespaces" "" { target *-*-* } 332 }
// "template argument 1 is invalid"
// { dg-prune-output "tuple:993" }