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? Here's the patch, but I'm not committing it yet. * include/bits/range_access.h (begin, end, rbegin, rend, crbegin) (crend): Add constexpr specifier as per P0031R0. * include/bits/stl_iterator.h (reverse_iterator, move_iterator) (__make_reverse_iterator, make_reverse_iterator, make_move_iterator): Add _GLIBCXX_CONSTEXPR or _GLIBCXX14_CONSTEXPR as appropriate. * include/bits/stl_iterator_base_funcs.h (__distance, distance) (__advance, advance, next, prev): Likewise. * 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: Add constexpr. * testsuite/24_iterators/headers/iterator/synopsis.cc: Add constexpr to reverse_iterator operations, advance, and distance.
commit 7e46198cc511bcc8876ab9d3f11e938dbe4cfea0 Author: Jonathan Wakely <jwak...@redhat.com> Date: Fri Jul 15 22:31:16 2016 +0100 Add constexpr to iterator adaptors, array and range access * include/bits/range_access.h (begin, end, rbegin, rend, crbegin) (crend): Add constexpr specifier as per P0031R0. * include/bits/stl_iterator.h (reverse_iterator, move_iterator) (__make_reverse_iterator, make_reverse_iterator, make_move_iterator): Add _GLIBCXX_CONSTEXPR or _GLIBCXX14_CONSTEXPR as appropriate. * include/bits/stl_iterator_base_funcs.h (__distance, distance) (__advance, advance, next, prev): Likewise. * 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: Add constexpr. * testsuite/24_iterators/headers/iterator/synopsis.cc: Add constexpr to reverse_iterator operations, advance, and distance. diff --git a/libstdc++-v3/include/bits/range_access.h b/libstdc++-v3/include/bits/range_access.h index e2ec072..257122e 100644 --- a/libstdc++-v3/include/bits/range_access.h +++ b/libstdc++-v3/include/bits/range_access.h @@ -44,7 +44,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @param __cont Container. */ template<typename _Container> - inline auto + constexpr auto begin(_Container& __cont) -> decltype(__cont.begin()) { return __cont.begin(); } @@ -54,7 +54,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @param __cont Container. */ template<typename _Container> - inline auto + constexpr auto begin(const _Container& __cont) -> decltype(__cont.begin()) { return __cont.begin(); } @@ -64,7 +64,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @param __cont Container. */ template<typename _Container> - inline auto + constexpr auto end(_Container& __cont) -> decltype(__cont.end()) { return __cont.end(); } @@ -74,7 +74,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @param __cont Container. */ template<typename _Container> - inline auto + constexpr auto end(const _Container& __cont) -> decltype(__cont.end()) { return __cont.end(); } @@ -83,7 +83,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @param __arr Array. */ template<typename _Tp, size_t _Nm> - inline _GLIBCXX14_CONSTEXPR _Tp* + constexpr _Tp* begin(_Tp (&__arr)[_Nm]) { return __arr; } @@ -93,7 +93,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @param __arr Array. */ template<typename _Tp, size_t _Nm> - inline _GLIBCXX14_CONSTEXPR _Tp* + constexpr _Tp* end(_Tp (&__arr)[_Nm]) { return __arr + _Nm; } @@ -112,7 +112,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @param __cont Container. */ template<typename _Container> - inline constexpr auto + constexpr auto cbegin(const _Container& __cont) noexcept(noexcept(std::begin(__cont))) -> decltype(std::begin(__cont)) { return std::begin(__cont); } @@ -123,7 +123,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @param __cont Container. */ template<typename _Container> - inline constexpr auto + constexpr auto cend(const _Container& __cont) noexcept(noexcept(std::end(__cont))) -> decltype(std::end(__cont)) { return std::end(__cont); } @@ -134,7 +134,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @param __cont Container. */ template<typename _Container> - inline auto + constexpr auto rbegin(_Container& __cont) -> decltype(__cont.rbegin()) { return __cont.rbegin(); } @@ -144,7 +144,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @param __cont Container. */ template<typename _Container> - inline auto + constexpr auto rbegin(const _Container& __cont) -> decltype(__cont.rbegin()) { return __cont.rbegin(); } @@ -154,7 +154,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @param __cont Container. */ template<typename _Container> - inline auto + constexpr auto rend(_Container& __cont) -> decltype(__cont.rend()) { return __cont.rend(); } @@ -164,7 +164,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @param __cont Container. */ template<typename _Container> - inline auto + constexpr auto rend(const _Container& __cont) -> decltype(__cont.rend()) { return __cont.rend(); } @@ -174,7 +174,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @param __arr Array. */ template<typename _Tp, size_t _Nm> - inline reverse_iterator<_Tp*> + constexpr reverse_iterator<_Tp*> rbegin(_Tp (&__arr)[_Nm]) { return reverse_iterator<_Tp*>(__arr + _Nm); } @@ -184,7 +184,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @param __arr Array. */ template<typename _Tp, size_t _Nm> - inline reverse_iterator<_Tp*> + constexpr reverse_iterator<_Tp*> rend(_Tp (&__arr)[_Nm]) { return reverse_iterator<_Tp*>(__arr); } @@ -194,7 +194,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @param __il initializer_list. */ template<typename _Tp> - inline reverse_iterator<const _Tp*> + constexpr reverse_iterator<const _Tp*> rbegin(initializer_list<_Tp> __il) { return reverse_iterator<const _Tp*>(__il.end()); } @@ -204,7 +204,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @param __il initializer_list. */ template<typename _Tp> - inline reverse_iterator<const _Tp*> + constexpr reverse_iterator<const _Tp*> rend(initializer_list<_Tp> __il) { return reverse_iterator<const _Tp*>(__il.begin()); } @@ -214,7 +214,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @param __cont Container. */ template<typename _Container> - inline auto + constexpr auto crbegin(const _Container& __cont) -> decltype(std::rbegin(__cont)) { return std::rbegin(__cont); } @@ -224,7 +224,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @param __cont Container. */ template<typename _Container> - inline auto + 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..4175520 100644 --- a/libstdc++-v3/include/bits/stl_iterator.h +++ b/libstdc++-v3/include/bits/stl_iterator.h @@ -65,6 +65,11 @@ #include <bits/move.h> #include <bits/ptr_traits.h> +#if __cplusplus >= 201402L +// Full support for this feature depends on C++14 constexpr. +# define __cpp_lib_array_constexpr 201603 +#endif + namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION @@ -118,17 +123,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ // _GLIBCXX_RESOLVE_LIB_DEFECTS // 235 No specification of default ctor for reverse_iterator + _GLIBCXX_CONSTEXPR reverse_iterator() : current() { } /** * This %iterator will move in the opposite direction that @p x does. */ - explicit + explicit _GLIBCXX_CONSTEXPR reverse_iterator(iterator_type __x) : current(__x) { } /** * The copy constructor is normal. */ + _GLIBCXX_CONSTEXPR reverse_iterator(const reverse_iterator& __x) : current(__x.current) { } @@ -137,13 +144,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * underlying %iterator can be converted to the type of @c current. */ template<typename _Iter> + _GLIBCXX_CONSTEXPR reverse_iterator(const reverse_iterator<_Iter>& __x) : current(__x.base()) { } /** * @return @c current, the %iterator used for underlying work. */ - iterator_type + _GLIBCXX_CONSTEXPR iterator_type base() const { return current; } @@ -157,7 +165,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 + _GLIBCXX14_CONSTEXPR reference operator*() const { _Iterator __tmp = current; @@ -169,7 +177,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * * This requires that @c --current is dereferenceable. */ - pointer + _GLIBCXX14_CONSTEXPR pointer operator->() const { return &(operator*()); } @@ -178,7 +186,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * * Decrements the underlying iterator. */ - reverse_iterator& + _GLIBCXX14_CONSTEXPR reverse_iterator& operator++() { --current; @@ -190,7 +198,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * * Decrements the underlying iterator. */ - reverse_iterator + _GLIBCXX14_CONSTEXPR reverse_iterator operator++(int) { reverse_iterator __tmp = *this; @@ -203,7 +211,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * * Increments the underlying iterator. */ - reverse_iterator& + _GLIBCXX14_CONSTEXPR reverse_iterator& operator--() { ++current; @@ -215,7 +223,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * * Increments the underlying iterator. */ - reverse_iterator + _GLIBCXX14_CONSTEXPR reverse_iterator operator--(int) { reverse_iterator __tmp = *this; @@ -228,7 +236,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * * The underlying iterator must be a Random Access Iterator. */ - reverse_iterator + _GLIBCXX_CONSTEXPR reverse_iterator operator+(difference_type __n) const { return reverse_iterator(current - __n); } @@ -238,7 +246,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * Moves the underlying iterator backwards @a __n steps. * The underlying iterator must be a Random Access Iterator. */ - reverse_iterator& + _GLIBCXX14_CONSTEXPR reverse_iterator& operator+=(difference_type __n) { current -= __n; @@ -250,7 +258,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * * The underlying iterator must be a Random Access Iterator. */ - reverse_iterator + _GLIBCXX_CONSTEXPR reverse_iterator operator-(difference_type __n) const { return reverse_iterator(current + __n); } @@ -260,7 +268,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * Moves the underlying iterator forwards @a __n steps. * The underlying iterator must be a Random Access Iterator. */ - reverse_iterator& + _GLIBCXX14_CONSTEXPR reverse_iterator& operator-=(difference_type __n) { current += __n; @@ -272,7 +280,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * * The underlying iterator must be a Random Access Iterator. */ - reference + _GLIBCXX14_CONSTEXPR reference operator[](difference_type __n) const { return *(*this + __n); } }; @@ -288,49 +296,50 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * */ template<typename _Iterator> - inline bool + inline _GLIBCXX_CONSTEXPR bool operator==(const reverse_iterator<_Iterator>& __x, const reverse_iterator<_Iterator>& __y) { return __x.base() == __y.base(); } template<typename _Iterator> - inline bool + inline _GLIBCXX_CONSTEXPR bool operator<(const reverse_iterator<_Iterator>& __x, const reverse_iterator<_Iterator>& __y) { return __y.base() < __x.base(); } template<typename _Iterator> - inline bool + inline _GLIBCXX_CONSTEXPR bool operator!=(const reverse_iterator<_Iterator>& __x, const reverse_iterator<_Iterator>& __y) { return !(__x == __y); } template<typename _Iterator> - inline bool + inline _GLIBCXX_CONSTEXPR bool operator>(const reverse_iterator<_Iterator>& __x, const reverse_iterator<_Iterator>& __y) { return __y < __x; } template<typename _Iterator> - inline bool + inline _GLIBCXX_CONSTEXPR bool operator<=(const reverse_iterator<_Iterator>& __x, const reverse_iterator<_Iterator>& __y) { return !(__y < __x); } template<typename _Iterator> - inline bool + inline _GLIBCXX_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 _GLIBCXX_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 _GLIBCXX_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 +347,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 _GLIBCXX_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 _GLIBCXX_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 _GLIBCXX_CONSTEXPR bool operator!=(const reverse_iterator<_IteratorL>& __x, const reverse_iterator<_IteratorR>& __y) { return !(__x == __y); } template<typename _IteratorL, typename _IteratorR> - inline bool + inline _GLIBCXX_CONSTEXPR bool operator>(const reverse_iterator<_IteratorL>& __x, const reverse_iterator<_IteratorR>& __y) { return __y < __x; } template<typename _IteratorL, typename _IteratorR> - inline bool + inline _GLIBCXX_CONSTEXPR bool operator<=(const reverse_iterator<_IteratorL>& __x, const reverse_iterator<_IteratorR>& __y) { return !(__y < __x); } template<typename _IteratorL, typename _IteratorR> - inline bool + inline _GLIBCXX_CONSTEXPR bool operator>=(const reverse_iterator<_IteratorL>& __x, const reverse_iterator<_IteratorR>& __y) { return !(__x < __y); } @@ -376,7 +385,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _IteratorL, typename _IteratorR> #if __cplusplus >= 201103L // DR 685. - inline auto + constexpr auto operator-(const reverse_iterator<_IteratorL>& __x, const reverse_iterator<_IteratorR>& __y) -> decltype(__y.base() - __x.base()) @@ -391,7 +400,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 _GLIBCXX_CONSTEXPR reverse_iterator<_Iterator> __make_reverse_iterator(_Iterator __i) { return reverse_iterator<_Iterator>(__i); } @@ -402,7 +411,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // DR 2285. make_reverse_iterator /// Generator function for reverse_iterator. template<typename _Iterator> - inline reverse_iterator<_Iterator> + constexpr reverse_iterator<_Iterator> make_reverse_iterator(_Iterator __i) { return reverse_iterator<_Iterator>(__i); } # endif @@ -1018,37 +1027,39 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename remove_reference<__base_ref>::type&&, __base_ref>::type reference; + constexpr move_iterator() : _M_current() { } - explicit + explicit constexpr move_iterator(iterator_type __i) : _M_current(__i) { } template<typename _Iter> + constexpr move_iterator(const move_iterator<_Iter>& __i) : _M_current(__i.base()) { } - iterator_type + constexpr iterator_type base() const { return _M_current; } - reference + constexpr reference operator*() const { return static_cast<reference>(*_M_current); } - pointer + constexpr pointer operator->() const { return _M_current; } - move_iterator& + _GLIBCXX14_CONSTEXPR move_iterator& operator++() { ++_M_current; return *this; } - move_iterator + _GLIBCXX14_CONSTEXPR move_iterator operator++(int) { move_iterator __tmp = *this; @@ -1056,14 +1067,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __tmp; } - move_iterator& + _GLIBCXX14_CONSTEXPR move_iterator& operator--() { --_M_current; return *this; } - move_iterator + _GLIBCXX14_CONSTEXPR move_iterator operator--(int) { move_iterator __tmp = *this; @@ -1071,29 +1082,29 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __tmp; } - move_iterator + constexpr move_iterator operator+(difference_type __n) const { return move_iterator(_M_current + __n); } - move_iterator& + _GLIBCXX14_CONSTEXPR move_iterator& operator+=(difference_type __n) { _M_current += __n; return *this; } - move_iterator + constexpr move_iterator operator-(difference_type __n) const { return move_iterator(_M_current - __n); } - move_iterator& + _GLIBCXX14_CONSTEXPR move_iterator& operator-=(difference_type __n) { _M_current -= __n; return *this; } - reference + constexpr reference operator[](difference_type __n) const { return std::move(_M_current[__n]); } }; @@ -1102,100 +1113,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 + constexpr bool operator==(const move_iterator<_IteratorL>& __x, const move_iterator<_IteratorR>& __y) { return __x.base() == __y.base(); } template<typename _Iterator> - inline bool + 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 + constexpr bool operator!=(const move_iterator<_IteratorL>& __x, const move_iterator<_IteratorR>& __y) { return !(__x == __y); } template<typename _Iterator> - inline bool + constexpr bool operator!=(const move_iterator<_Iterator>& __x, const move_iterator<_Iterator>& __y) { return !(__x == __y); } template<typename _IteratorL, typename _IteratorR> - inline bool + constexpr bool operator<(const move_iterator<_IteratorL>& __x, const move_iterator<_IteratorR>& __y) { return __x.base() < __y.base(); } template<typename _Iterator> - inline bool + 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 + constexpr bool operator<=(const move_iterator<_IteratorL>& __x, const move_iterator<_IteratorR>& __y) { return !(__y < __x); } template<typename _Iterator> - inline bool + constexpr bool operator<=(const move_iterator<_Iterator>& __x, const move_iterator<_Iterator>& __y) { return !(__y < __x); } template<typename _IteratorL, typename _IteratorR> - inline bool + constexpr bool operator>(const move_iterator<_IteratorL>& __x, const move_iterator<_IteratorR>& __y) { return __y < __x; } template<typename _Iterator> - inline bool + constexpr bool operator>(const move_iterator<_Iterator>& __x, const move_iterator<_Iterator>& __y) { return __y < __x; } template<typename _IteratorL, typename _IteratorR> - inline bool + constexpr bool operator>=(const move_iterator<_IteratorL>& __x, const move_iterator<_IteratorR>& __y) { return !(__x < __y); } template<typename _Iterator> - inline bool + 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 + 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 + 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> + 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> + constexpr move_iterator<_Iterator> make_move_iterator(_Iterator __i) { return move_iterator<_Iterator>(__i); } @@ -1203,7 +1214,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 + constexpr _ReturnType __make_move_if_noexcept_iterator(_Iterator __i) { return _ReturnType(__i); } @@ -1212,7 +1223,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 + 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..a8ce4ed 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 _GLIBCXX14_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 _GLIBCXX14_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 _GLIBCXX14_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 _GLIBCXX14_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 73d2669..00b18bb 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 + _GLIBCXX14_CONSTEXPR iterator begin() noexcept { return iterator(data()); } - const_iterator + constexpr const_iterator begin() const noexcept { return const_iterator(data()); } - iterator + _GLIBCXX14_CONSTEXPR iterator end() noexcept { return iterator(data() + _Nm); } - const_iterator + constexpr const_iterator end() const noexcept { return const_iterator(data() + _Nm); } - reverse_iterator + _GLIBCXX14_CONSTEXPR reverse_iterator rbegin() noexcept { return reverse_iterator(end()); } - const_reverse_iterator + constexpr const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); } - reverse_iterator + _GLIBCXX14_CONSTEXPR reverse_iterator rend() noexcept { return reverse_iterator(begin()); } - const_reverse_iterator + constexpr const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); } - const_iterator + constexpr const_iterator cbegin() const noexcept { return const_iterator(data()); } - const_iterator + constexpr const_iterator cend() const noexcept { return const_iterator(data() + _Nm); } - const_reverse_iterator + constexpr const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); } - const_reverse_iterator + 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 + _GLIBCXX14_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 + _GLIBCXX14_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 + _GLIBCXX14_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 + _GLIBCXX14_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 + _GLIBCXX14_CONSTEXPR pointer data() noexcept { return _AT_Type::_S_ptr(_M_elems); } - const_pointer + 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 index b66381e..e40cfc7 100644 --- a/libstdc++-v3/testsuite/24_iterators/headers/iterator/range_access.cc +++ b/libstdc++-v3/testsuite/24_iterators/headers/iterator/range_access.cc @@ -22,12 +22,12 @@ 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> constexpr auto begin(C& c) -> decltype(c.begin()); + template<class C> constexpr 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 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> T* begin(T (&array)[N]); - template<class T, size_t N> T* end(T (&array)[N]); + template<class T, size_t N> constexpr T* begin(T (&array)[N]); + template<class T, size_t N> constexpr T* end(T (&array)[N]); } diff --git a/libstdc++-v3/testsuite/24_iterators/headers/iterator/synopsis.cc b/libstdc++-v3/testsuite/24_iterators/headers/iterator/synopsis.cc index ed01258..cd843a2 100644 --- a/libstdc++-v3/testsuite/24_iterators/headers/iterator/synopsis.cc +++ b/libstdc++-v3/testsuite/24_iterators/headers/iterator/synopsis.cc @@ -36,46 +36,54 @@ namespace std { // 24.3.4, iterator operations: template <class InputIterator, class Distance> - void + constexpr void advance(InputIterator& i, Distance n); template <class InputIterator> - typename iterator_traits<InputIterator>::difference_type + constexpr typename iterator_traits<InputIterator>::difference_type distance(InputIterator first, InputIterator last); // 24.4, predefined iterators: template <class Iterator> class reverse_iterator; template <class Iterator> + constexpr bool operator==(const reverse_iterator<Iterator>& x, const reverse_iterator<Iterator>& y); template <class Iterator> + constexpr bool operator<(const reverse_iterator<Iterator>& x, const reverse_iterator<Iterator>& y); template <class Iterator> + constexpr bool operator!=(const reverse_iterator<Iterator>& x, const reverse_iterator<Iterator>& y); template <class Iterator> + constexpr bool operator>(const reverse_iterator<Iterator>& x, const reverse_iterator<Iterator>& y); template <class Iterator> + constexpr bool operator>=(const reverse_iterator<Iterator>& x, const reverse_iterator<Iterator>& y); template <class Iterator> + constexpr bool operator<=(const reverse_iterator<Iterator>& x, const reverse_iterator<Iterator>& y); template <class Iterator> + constexpr typename reverse_iterator<Iterator>::difference_type operator-(const reverse_iterator<Iterator>& x, const reverse_iterator<Iterator>& y); template <class Iterator> + constexpr reverse_iterator<Iterator> operator+(typename reverse_iterator<Iterator>::difference_type n, const reverse_iterator<Iterator>& x);