Author: marshall Date: Wed Jan 4 11:58:17 2017 New Revision: 290976 URL: http://llvm.org/viewvc/llvm-project?rev=290976&view=rev Log: Implement the last bit of P0031: 'A Proposal to Add Constexpr Modifiers to reverse_iterator, move_iterator, array and Range Access' for C++17
Modified: libcxx/trunk/include/array libcxx/trunk/include/iterator libcxx/trunk/test/std/containers/sequences/array/array.data/data_const.pass.cpp libcxx/trunk/test/std/containers/sequences/array/iterators.pass.cpp libcxx/trunk/test/std/iterators/iterator.range/begin-end.pass.cpp libcxx/trunk/www/cxx1z_status.html Modified: libcxx/trunk/include/array URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/array?rev=290976&r1=290975&r2=290976&view=diff ============================================================================== --- libcxx/trunk/include/array (original) +++ libcxx/trunk/include/array Wed Jan 4 11:58:17 2017 @@ -149,31 +149,31 @@ struct _LIBCPP_TYPE_VIS_ONLY array { _VSTD::swap_ranges(__elems_, __elems_ + _Size, __a.__elems_);} // iterators: - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 iterator begin() _NOEXCEPT {return iterator(__elems_);} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 const_iterator begin() const _NOEXCEPT {return const_iterator(__elems_);} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 iterator end() _NOEXCEPT {return iterator(__elems_ + _Size);} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 const_iterator end() const _NOEXCEPT {return const_iterator(__elems_ + _Size);} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 const_reverse_iterator rbegin() const _NOEXCEPT {return const_reverse_iterator(end());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reverse_iterator rend() _NOEXCEPT {return reverse_iterator(begin());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 const_reverse_iterator rend() const _NOEXCEPT {return const_reverse_iterator(begin());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 const_iterator cbegin() const _NOEXCEPT {return begin();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 const_iterator cend() const _NOEXCEPT {return end();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 const_reverse_iterator crend() const _NOEXCEPT {return rend();} // capacity: @@ -195,9 +195,9 @@ struct _LIBCPP_TYPE_VIS_ONLY array _LIBCPP_INLINE_VISIBILITY reference back() {return __elems_[_Size > 0 ? _Size-1 : 0];} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference back() const {return __elems_[_Size > 0 ? _Size-1 : 0];} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 value_type* data() _NOEXCEPT {return __elems_;} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 const value_type* data() const _NOEXCEPT {return __elems_;} }; Modified: libcxx/trunk/include/iterator URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/iterator?rev=290976&r1=290975&r2=290976&view=diff ============================================================================== --- libcxx/trunk/include/iterator (original) +++ libcxx/trunk/include/iterator Wed Jan 4 11:58:17 2017 @@ -378,25 +378,25 @@ public: bool failed() const noexcept; }; -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]); - -template <class C> auto cbegin(const C& c) -> decltype(std::begin(c)); // C++14 -template <class C> auto cend(const C& c) -> decltype(std::end(c)); // C++14 -template <class C> auto rbegin(C& c) -> decltype(c.rbegin()); // C++14 -template <class C> auto rbegin(const C& c) -> decltype(c.rbegin()); // C++14 -template <class C> auto rend(C& c) -> decltype(c.rend()); // C++14 -template <class C> auto rend(const C& c) -> decltype(c.rend()); // C++14 -template <class E> reverse_iterator<const E*> rbegin(initializer_list<E> il); // C++14 -template <class E> reverse_iterator<const E*> rend(initializer_list<E> il); // C++14 -template <class T, size_t N> reverse_iterator<T*> rbegin(T (&array)[N]); // C++14 -template <class T, size_t N> reverse_iterator<T*> rend(T (&array)[N]); // C++14 -template <class C> auto crbegin(const C& c) -> decltype(std::rbegin(c)); // C++14 -template <class C> auto crend(const C& c) -> decltype(std::rend(c)); // C++14 +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> auto constexpr cbegin(const C& c) -> decltype(std::begin(c)); // C++14 +template <class C> auto constexpr cend(const C& c) -> decltype(std::end(c)); // C++14 +template <class C> auto constexpr rbegin(C& c) -> decltype(c.rbegin()); // C++14 +template <class C> auto constexpr rbegin(const C& c) -> decltype(c.rbegin()); // C++14 +template <class C> auto constexpr rend(C& c) -> decltype(c.rend()); // C++14 +template <class C> constexpr auto rend(const C& c) -> decltype(c.rend()); // C++14 +template <class E> reverse_iterator<const E*> constexpr rbegin(initializer_list<E> il); // C++14 +template <class E> reverse_iterator<const E*> constexpr rend(initializer_list<E> il); // C++14 +template <class T, size_t N> reverse_iterator<T*> constexpr rbegin(T (&array)[N]); // C++14 +template <class T, size_t N> reverse_iterator<T*> constexpr rend(T (&array)[N]); // C++14 +template <class C> constexpr auto crbegin(const C& c) -> decltype(std::rbegin(c)); // C++14 +template <class C> constexpr auto crend(const C& c) -> decltype(std::rend(c)); // C++14 // 24.8, container access: template <class C> constexpr auto size(const C& c) -> decltype(c.size()); // C++17 @@ -1616,7 +1616,7 @@ end(_Tp (&__array)[_Np]) #if !defined(_LIBCPP_CXX03_LANG) template <class _Cp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 auto begin(_Cp& __c) -> decltype(__c.begin()) { @@ -1624,7 +1624,7 @@ begin(_Cp& __c) -> decltype(__c.begin()) } template <class _Cp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 auto begin(const _Cp& __c) -> decltype(__c.begin()) { @@ -1632,7 +1632,7 @@ begin(const _Cp& __c) -> decltype(__c.be } template <class _Cp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 auto end(_Cp& __c) -> decltype(__c.end()) { @@ -1640,7 +1640,7 @@ end(_Cp& __c) -> decltype(__c.end()) } template <class _Cp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 auto end(const _Cp& __c) -> decltype(__c.end()) { @@ -1650,28 +1650,28 @@ end(const _Cp& __c) -> decltype(__c.end( #if _LIBCPP_STD_VER > 11 template <class _Tp, size_t _Np> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reverse_iterator<_Tp*> rbegin(_Tp (&__array)[_Np]) { return reverse_iterator<_Tp*>(__array + _Np); } template <class _Tp, size_t _Np> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reverse_iterator<_Tp*> rend(_Tp (&__array)[_Np]) { return reverse_iterator<_Tp*>(__array); } template <class _Ep> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reverse_iterator<const _Ep*> rbegin(initializer_list<_Ep> __il) { return reverse_iterator<const _Ep*>(__il.end()); } template <class _Ep> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reverse_iterator<const _Ep*> rend(initializer_list<_Ep> __il) { return reverse_iterator<const _Ep*>(__il.begin()); @@ -1692,42 +1692,42 @@ auto cend(const _Cp& __c) -> decltype(_V } template <class _Cp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 auto rbegin(_Cp& __c) -> decltype(__c.rbegin()) { return __c.rbegin(); } template <class _Cp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 auto rbegin(const _Cp& __c) -> decltype(__c.rbegin()) { return __c.rbegin(); } template <class _Cp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 auto rend(_Cp& __c) -> decltype(__c.rend()) { return __c.rend(); } template <class _Cp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 auto rend(const _Cp& __c) -> decltype(__c.rend()) { return __c.rend(); } template <class _Cp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 auto crbegin(const _Cp& __c) -> decltype(_VSTD::rbegin(__c)) { return _VSTD::rbegin(__c); } template <class _Cp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 auto crend(const _Cp& __c) -> decltype(_VSTD::rend(__c)) { return _VSTD::rend(__c); Modified: libcxx/trunk/test/std/containers/sequences/array/array.data/data_const.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/sequences/array/array.data/data_const.pass.cpp?rev=290976&r1=290975&r2=290976&view=diff ============================================================================== --- libcxx/trunk/test/std/containers/sequences/array/array.data/data_const.pass.cpp (original) +++ libcxx/trunk/test/std/containers/sequences/array/array.data/data_const.pass.cpp Wed Jan 4 11:58:17 2017 @@ -14,6 +14,8 @@ #include <array> #include <cassert> +#include "test_macros.h" + // std::array is explicitly allowed to be initialized with A a = { init-list };. // Disable the missing braces warning for this reason. #include "disable_missing_braces_warning.h" @@ -36,4 +38,16 @@ int main() const T* p = c.data(); (void)p; // to placate scan-build } +#if TEST_STD_VER > 14 + { + typedef std::array<int, 5> C; + constexpr C c1{0,1,2,3,4}; + constexpr const C c2{0,1,2,3,4}; + + static_assert ( c1.data() == &c1[0], ""); + static_assert ( *c1.data() == c1[0], ""); + static_assert ( c2.data() == &c2[0], ""); + static_assert ( *c2.data() == c2[0], ""); + } +#endif } Modified: libcxx/trunk/test/std/containers/sequences/array/iterators.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/sequences/array/iterators.pass.cpp?rev=290976&r1=290975&r2=290976&view=diff ============================================================================== --- libcxx/trunk/test/std/containers/sequences/array/iterators.pass.cpp (original) +++ libcxx/trunk/test/std/containers/sequences/array/iterators.pass.cpp Wed Jan 4 11:58:17 2017 @@ -17,6 +17,10 @@ #include "test_macros.h" +// std::array is explicitly allowed to be initialized with A a = { init-list };. +// Disable the missing braces warning for this reason. +#include "disable_missing_braces_warning.h" + int main() { { @@ -109,4 +113,33 @@ int main() } } #endif +#if TEST_STD_VER > 14 + { + typedef std::array<int, 5> C; + constexpr C c{0,1,2,3,4}; + + static_assert ( c.begin() == std::begin(c), ""); + static_assert ( c.cbegin() == std::cbegin(c), ""); + static_assert ( c.end() == std::end(c), ""); + static_assert ( c.cend() == std::cend(c), ""); + + static_assert ( c.rbegin() == std::rbegin(c), ""); + static_assert ( c.crbegin() == std::crbegin(c), ""); + static_assert ( c.rend() == std::rend(c), ""); + static_assert ( c.crend() == std::crend(c), ""); + + static_assert ( std::begin(c) != std::end(c), ""); + static_assert ( std::rbegin(c) != std::rend(c), ""); + static_assert ( std::cbegin(c) != std::cend(c), ""); + static_assert ( std::crbegin(c) != std::crend(c), ""); + + static_assert ( *c.begin() == 0, ""); + static_assert ( *c.rbegin() == 4, ""); + + static_assert ( *std::begin(c) == 0, "" ); + static_assert ( *std::cbegin(c) == 0, "" ); + static_assert ( *std::rbegin(c) == 4, "" ); + static_assert ( *std::crbegin(c) == 4, "" ); + } +#endif } Modified: libcxx/trunk/test/std/iterators/iterator.range/begin-end.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/iterators/iterator.range/begin-end.pass.cpp?rev=290976&r1=290975&r2=290976&view=diff ============================================================================== --- libcxx/trunk/test/std/iterators/iterator.range/begin-end.pass.cpp (original) +++ libcxx/trunk/test/std/iterators/iterator.range/begin-end.pass.cpp Wed Jan 4 11:58:17 2017 @@ -10,12 +10,25 @@ // XFAIL: c++03, c++98 // <iterator> -// 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 E> reverse_iterator<const E*> rbegin(initializer_list<E> il); -// template <class E> reverse_iterator<const E*> rend(initializer_list<E> il); +// 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 cbegin(const C& c) -> decltype(std::begin(c)); // C++14 +// template <class C> constexpr auto cend(const C& c) -> decltype(std::end(c)); // C++14 +// 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 E> constexpr reverse_iterator<const E*> rbegin(initializer_list<E> il); +// template <class E> constexpr reverse_iterator<const E*> rend (initializer_list<E> il); +// +// template <class C> auto constexpr rbegin(C& c) -> decltype(c.rbegin()); // C++14 +// template <class C> auto constexpr rbegin(const C& c) -> decltype(c.rbegin()); // C++14 +// template <class C> auto constexpr rend(C& c) -> decltype(c.rend()); // C++14 +// template <class C> constexpr auto rend(const C& c) -> decltype(c.rend()); // C++14 +// template <class T, size_t N> reverse_iterator<T*> constexpr rbegin(T (&array)[N]); // C++14 +// template <class T, size_t N> reverse_iterator<T*> constexpr rend(T (&array)[N]); // C++14 +// template <class C> constexpr auto crbegin(const C& c) -> decltype(std::rbegin(c)); // C++14 +// template <class C> constexpr auto crend(const C& c) -> decltype(std::rend(c)); // C++14 +// +// All of these are constexpr in C++17 #include "test_macros.h" @@ -26,6 +39,10 @@ #include <list> #include <initializer_list> +// std::array is explicitly allowed to be initialized with A a = { init-list };. +// Disable the missing braces warning for this reason. +#include "disable_missing_braces_warning.h" + template<typename C> void test_const_container( const C & c, typename C::value_type val ) { assert ( std::begin(c) == c.begin()); @@ -142,4 +159,43 @@ int main(){ constexpr const int *e = std::cend(arrA); static_assert(e - b == 3, ""); #endif + +#if TEST_STD_VER > 14 + { + typedef std::array<int, 5> C; + constexpr const C c{0,1,2,3,4}; + + static_assert ( c.begin() == std::begin(c), ""); + static_assert ( c.cbegin() == std::cbegin(c), ""); + static_assert ( c.end() == std::end(c), ""); + static_assert ( c.cend() == std::cend(c), ""); + + static_assert ( c.rbegin() == std::rbegin(c), ""); + static_assert ( c.crbegin() == std::crbegin(c), ""); + static_assert ( c.rend() == std::rend(c), ""); + static_assert ( c.crend() == std::crend(c), ""); + + static_assert ( std::begin(c) != std::end(c), ""); + static_assert ( std::rbegin(c) != std::rend(c), ""); + static_assert ( std::cbegin(c) != std::cend(c), ""); + static_assert ( std::crbegin(c) != std::crend(c), ""); + + static_assert ( *c.begin() == 0, ""); + static_assert ( *c.rbegin() == 4, ""); + + static_assert ( *std::begin(c) == 0, "" ); + static_assert ( *std::cbegin(c) == 0, "" ); + static_assert ( *std::rbegin(c) == 4, "" ); + static_assert ( *std::crbegin(c) == 4, "" ); + } + + { + static constexpr const int c[] = {0,1,2,3,4}; + + static_assert ( *std::begin(c) == 0, "" ); + static_assert ( *std::cbegin(c) == 0, "" ); + static_assert ( *std::rbegin(c) == 4, "" ); + static_assert ( *std::crbegin(c) == 4, "" ); + } +#endif } Modified: libcxx/trunk/www/cxx1z_status.html URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/www/cxx1z_status.html?rev=290976&r1=290975&r2=290976&view=diff ============================================================================== --- libcxx/trunk/www/cxx1z_status.html (original) +++ libcxx/trunk/www/cxx1z_status.html Wed Jan 4 11:58:17 2017 @@ -90,7 +90,7 @@ <tr><td><a href="http://wg21.link/P0025R0">P0025R0</a></td><td>LWG</td><td>An algorithm to "clamp" a value between a pair of boundary values</td><td>Jacksonville</td><td>Complete</td><td>3.9</td></tr> <tr><td><a href="http://wg21.link/P0154R1">P0154R1</a></td><td>LWG</td><td>constexpr std::hardware_{constructive,destructive}_interference_size</td><td>Jacksonville</td><td></td><td></td></tr> <tr><td><a href="http://wg21.link/P0030R1">P0030R1</a></td><td>LWG</td><td>Proposal to Introduce a 3-Argument Overload to std::hypot</td><td>Jacksonville</td><td>Complete</td><td>3.9</td></tr> - <tr><td><a href="http://wg21.link/P0031R0">P0031R0</a></td><td>LWG</td><td>A Proposal to Add Constexpr Modifiers to reverse_iterator, move_iterator, array and Range Access</td><td>Jacksonville</td><td>In progress</td><td>4.0</td></tr> + <tr><td><a href="http://wg21.link/P0031R0">P0031R0</a></td><td>LWG</td><td>A Proposal to Add Constexpr Modifiers to reverse_iterator, move_iterator, array and Range Access</td><td>Jacksonville</td><td>Complete</td><td>4.0</td></tr> <tr><td><a href="http://wg21.link/P0272R1">P0272R1</a></td><td>LWG</td><td>Give <tt>std::string</tt> a non-const <tt>.data()</tt> member function</td><td>Jacksonville</td><td>Complete</td><td>3.9</td></tr> <tr><td><a href="http://wg21.link/P0077R2">P0077R2</a></td><td>LWG</td><td><tt>is_callable</tt>, the missing INVOKE related trait</td><td>Jacksonville</td><td>Complete</td><td>3.9</td></tr> <tr><td></td><td></td><td></td><td></td><td></td><td></td></tr> @@ -417,7 +417,7 @@ <!-- <tr><td></td><td></td><td></td><td></td></tr> --> </table> - <p>Last Updated: 3-Jan-2017</p> + <p>Last Updated: 4-Jan-2017</p> </div> </body> </html> _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits