Index: include/array =================================================================== --- include/array +++ include/array @@ -37,20 +37,20 @@ void swap(array& a) noexcept(is_nothrow_swappable_v); // iterators: - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; - reverse_iterator rbegin() noexcept; - const_reverse_iterator rbegin() const noexcept; - reverse_iterator rend() noexcept; - const_reverse_iterator rend() const noexcept; + constexpr reverse_iterator rbegin() noexcept; + constexpr const_reverse_iterator rbegin() const noexcept; + constexpr reverse_iterator rend() noexcept; + constexpr const_reverse_iterator rend() const noexcept; - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() const noexcept; + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; + constexpr const_reverse_iterator crbegin() const noexcept; + constexpr const_reverse_iterator crend() const noexcept; // capacity: constexpr size_type size() const noexcept; @@ -58,18 +58,18 @@ constexpr bool empty() const noexcept; // element access: - reference operator[](size_type n); - const_reference operator[](size_type n) const; // constexpr in C++14 - const_reference at(size_type n) const; // constexpr in C++14 - reference at(size_type n); - - reference front(); - const_reference front() const; // constexpr in C++14 - reference back(); - const_reference back() const; // constexpr in C++14 - - T* data() noexcept; - const T* data() const noexcept; + constexpr reference operator[](size_type n); + constexpr const_reference operator[](size_type n) const; // constexpr in C++14 + constexpr const_reference at(size_type n) const; // constexpr in C++14 + constexpr reference at(size_type n); + + constexpr reference front(); + constexpr const_reference front() const; // constexpr in C++14 + constexpr reference back(); + constexpr const_reference back() const; // constexpr in C++14 + + constexpr T* data() noexcept; + constexpr const T* data() const noexcept; }; template @@ -152,31 +152,31 @@ { _VSTD::swap_ranges(__elems_, __elems_ + _Size, __a.__elems_);} // iterators: - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 iterator begin() _NOEXCEPT {return iterator(__elems_);} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_iterator begin() const _NOEXCEPT {return const_iterator(__elems_);} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 iterator end() _NOEXCEPT {return iterator(__elems_ + _Size);} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_iterator end() const _NOEXCEPT {return const_iterator(__elems_ + _Size);} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reverse_iterator rbegin() const _NOEXCEPT {return const_reverse_iterator(end());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 reverse_iterator rend() _NOEXCEPT {return reverse_iterator(begin());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reverse_iterator rend() const _NOEXCEPT {return const_reverse_iterator(begin());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_iterator cbegin() const _NOEXCEPT {return begin();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_iterator cend() const _NOEXCEPT {return end();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reverse_iterator crend() const _NOEXCEPT {return rend();} // capacity: @@ -188,23 +188,24 @@ _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT {return _Size == 0;} // element access: - _LIBCPP_INLINE_VISIBILITY reference operator[](size_type __n) {return __elems_[__n];} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 reference operator[](size_type __n) {return __elems_[__n];} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference operator[](size_type __n) const {return __elems_[__n];} - reference at(size_type __n); + _LIBCPP_CONSTEXPR_AFTER_CXX11 reference at(size_type __n); _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference at(size_type __n) const; - _LIBCPP_INLINE_VISIBILITY reference front() {return __elems_[0];} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 reference front() {return __elems_[0];} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference front() const {return __elems_[0];} - _LIBCPP_INLINE_VISIBILITY reference back() {return __elems_[_Size > 0 ? _Size-1 : 0];} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 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_CXX11 value_type* data() _NOEXCEPT {return __elems_;} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const value_type* data() const _NOEXCEPT {return __elems_;} }; template +_LIBCPP_CONSTEXPR_AFTER_CXX11 typename array<_Tp, _Size>::reference array<_Tp, _Size>::at(size_type __n) { Index: include/iterator =================================================================== --- include/iterator +++ include/iterator @@ -89,56 +89,56 @@ typedef typename iterator_traits::reference reference; typedef typename iterator_traits::pointer pointer; - reverse_iterator(); - explicit reverse_iterator(Iterator x); - template reverse_iterator(const reverse_iterator& u); - Iterator base() const; - reference operator*() const; - pointer operator->() const; - reverse_iterator& operator++(); - reverse_iterator operator++(int); - reverse_iterator& operator--(); - reverse_iterator operator--(int); - reverse_iterator operator+ (difference_type n) const; - reverse_iterator& operator+=(difference_type n); - reverse_iterator operator- (difference_type n) const; - reverse_iterator& operator-=(difference_type n); - reference operator[](difference_type n) const; + constexpr reverse_iterator(); + constexpr explicit reverse_iterator(Iterator x); + template constexpr reverse_iterator(const reverse_iterator& u); + constexpr Iterator base() const; + constexpr reference operator*() const; + constexpr pointer operator->() const; + constexpr reverse_iterator& operator++(); + constexpr reverse_iterator operator++(int); + constexpr reverse_iterator& operator--(); + constexpr reverse_iterator operator--(int); + constexpr reverse_iterator operator+ (difference_type n) const; + constexpr reverse_iterator& operator+=(difference_type n); + constexpr reverse_iterator operator- (difference_type n) const; + constexpr reverse_iterator& operator-=(difference_type n); + constexpr reference operator[](difference_type n) const; }; template -bool +constexpr bool operator==(const reverse_iterator& x, const reverse_iterator& y); template -bool +constexpr bool operator<(const reverse_iterator& x, const reverse_iterator& y); template -bool +constexpr bool operator!=(const reverse_iterator& x, const reverse_iterator& y); template -bool +constexpr bool operator>(const reverse_iterator& x, const reverse_iterator& y); template -bool +constexpr bool operator>=(const reverse_iterator& x, const reverse_iterator& y); template -bool +constexpr bool operator<=(const reverse_iterator& x, const reverse_iterator& y); template -typename reverse_iterator::difference_type +constexpr typename reverse_iterator::difference_type operator-(const reverse_iterator& x, const reverse_iterator& y); template -reverse_iterator +constexpr reverse_iterator operator+(typename reverse_iterator::difference_type n, const reverse_iterator& x); -template reverse_iterator make_reverse_iterator(Iterator i); // C++14 +template constexpr reverse_iterator make_reverse_iterator(Iterator i); // C++14 template class back_insert_iterator @@ -559,33 +559,34 @@ typedef typename iterator_traits<_Iter>::reference reference; typedef typename iterator_traits<_Iter>::pointer pointer; - _LIBCPP_INLINE_VISIBILITY reverse_iterator() : current() {} - _LIBCPP_INLINE_VISIBILITY explicit reverse_iterator(_Iter __x) : __t(__x), current(__x) {} - template _LIBCPP_INLINE_VISIBILITY reverse_iterator(const reverse_iterator<_Up>& __u) + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR reverse_iterator() : __t(), current() {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit reverse_iterator(_Iter __x) : __t(__x), current(__x) {} + template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR reverse_iterator(const reverse_iterator<_Up>& __u) : __t(__u.base()), current(__u.base()) {} - _LIBCPP_INLINE_VISIBILITY _Iter base() const {return current;} - _LIBCPP_INLINE_VISIBILITY reference operator*() const {_Iter __tmp = current; return *--__tmp;} - _LIBCPP_INLINE_VISIBILITY pointer operator->() const {return _VSTD::addressof(operator*());} - _LIBCPP_INLINE_VISIBILITY reverse_iterator& operator++() {--current; return *this;} - _LIBCPP_INLINE_VISIBILITY reverse_iterator operator++(int) + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR _Iter base() const {return current;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 reference operator*() const + {_Iter __tmp = current; return *--__tmp;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 pointer operator->() const {return _VSTD::addressof(operator*());} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 reverse_iterator& operator++() {--current; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 reverse_iterator operator++(int) {reverse_iterator __tmp(*this); --current; return __tmp;} - _LIBCPP_INLINE_VISIBILITY reverse_iterator& operator--() {++current; return *this;} - _LIBCPP_INLINE_VISIBILITY reverse_iterator operator--(int) + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 reverse_iterator& operator--() {++current; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 reverse_iterator operator--(int) {reverse_iterator __tmp(*this); ++current; return __tmp;} - _LIBCPP_INLINE_VISIBILITY reverse_iterator operator+ (difference_type __n) const + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR reverse_iterator operator+ (difference_type __n) const {return reverse_iterator(current - __n);} - _LIBCPP_INLINE_VISIBILITY reverse_iterator& operator+=(difference_type __n) + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 reverse_iterator& operator+=(difference_type __n) {current -= __n; return *this;} - _LIBCPP_INLINE_VISIBILITY reverse_iterator operator- (difference_type __n) const + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR reverse_iterator operator- (difference_type __n) const {return reverse_iterator(current + __n);} - _LIBCPP_INLINE_VISIBILITY reverse_iterator& operator-=(difference_type __n) + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 reverse_iterator& operator-=(difference_type __n) {current += __n; return *this;} - _LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR reference operator[](difference_type __n) const {return *(*this + __n);} }; template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR bool operator==(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) { @@ -593,7 +594,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR bool operator<(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) { @@ -601,7 +602,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR bool operator!=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) { @@ -609,7 +610,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR bool operator>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) { @@ -617,7 +618,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR bool operator>=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) { @@ -625,7 +626,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR bool operator<=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) { @@ -633,7 +634,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename reverse_iterator<_Iter1>::difference_type operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) { @@ -641,7 +642,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR reverse_iterator<_Iter> operator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_iterator<_Iter>& __x) { @@ -650,7 +651,7 @@ #if _LIBCPP_STD_VER > 11 template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR reverse_iterator<_Iter> make_reverse_iterator(_Iter __i) { return reverse_iterator<_Iter>(__i); Index: include/memory =================================================================== --- include/memory +++ include/memory @@ -163,7 +163,7 @@ template pair get_temporary_buffer(ptrdiff_t n) noexcept; template void return_temporary_buffer(T* p) noexcept; -template T* addressof(T& r) noexcept; +template constexpr T* addressof(T& r) noexcept; template ForwardIterator Index: test/std/containers/sequences/array/begin.pass.cpp =================================================================== --- test/std/containers/sequences/array/begin.pass.cpp +++ /dev/null @@ -1,34 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// - -// iterator begin(); - -#include -#include - -// 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() -{ - { - typedef double T; - typedef std::array C; - C c = {1, 2, 3.5}; - C::iterator i; - i = c.begin(); - assert(*i == 1); - assert(&*i == c.data()); - *i = 5.5; - assert(c[0] == 5.5); - } -} Index: test/std/containers/sequences/array/begin_end.pass.cpp =================================================================== --- /dev/null +++ test/std/containers/sequences/array/begin_end.pass.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// iterator begin(); +// iterator end(); + +#include +#include + +#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" + +#if TEST_STD_VER > 11 + +typedef std::array C; + +constexpr int test_nonconst_constexpr_begin() { + C ar = {0, 1, 2}; + C::iterator it = ar.begin(); + ++it; + return *it; +} + +constexpr int test_nonconst_constexpr_end() { + C ar = {0, 1, 2}; + C::iterator it = ar.end(); + --it; + return *it; +} + +#endif + +int main() +{ + { + typedef double T; + typedef std::array C; + C c = {1, 2, 3.5}; + C::iterator i; + i = c.begin(); + assert(*i == 1); + assert(&*i == c.data()); + *i = 5.5; + assert(c[0] == 5.5); + i = c.end(); + assert(*--i == 3.5); + *i = 4; + assert(c[2] == 4); + } +#if TEST_STD_VER > 11 + { + constexpr int a = test_nonconst_constexpr_begin(); + static_assert(a == 1, ""); + + constexpr int b = test_nonconst_constexpr_end(); + static_assert(b == 2, ""); + } +#endif +} Index: test/std/containers/sequences/array/front_back.pass.cpp =================================================================== --- test/std/containers/sequences/array/front_back.pass.cpp +++ test/std/containers/sequences/array/front_back.pass.cpp @@ -23,6 +23,24 @@ // Disable the missing braces warning for this reason. #include "disable_missing_braces_warning.h" +#if TEST_STD_VER > 11 + +typedef std::array C; + +constexpr int test_nonconst_constexpr_front() { + C ar = {0, 1, 2}; + ++ar.front(); + return ar[0]; +} + +constexpr int test_nonconst_constexpr_back() { + C ar = {0, 1, 2}; + ++ar.back(); + return ar[2]; +} + +#endif + int main() { { @@ -63,6 +81,13 @@ constexpr T t2 = c.back(); static_assert (t2 == 3.5, ""); } + { + constexpr int a = test_nonconst_constexpr_front(); + static_assert(a == 1, ""); + + constexpr int b = test_nonconst_constexpr_back(); + static_assert(b == 3, ""); + } #endif } Index: test/std/containers/sequences/array/rbegin_rend.pass.cpp =================================================================== --- /dev/null +++ test/std/containers/sequences/array/rbegin_rend.pass.cpp @@ -0,0 +1,71 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// iterator rbegin(); +// iterator rend(); + +#include +#include + +#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" + +#if TEST_STD_VER > 11 + +typedef std::array C; + +constexpr int test_nonconst_constexpr_rbegin() +{ + C ar = {0, 1, 2}; + C::reverse_iterator it = ar.rbegin(); + ++it; + return *it; +} + +constexpr int test_nonconst_constexpr_rend() +{ + C ar = {0, 1, 2}; + C::reverse_iterator it = ar.rend(); + --it; + return *it; +} + +#endif + +int main() +{ + { + typedef double T; + typedef std::array C; + C c = {1, 2, 3.5}; + C::reverse_iterator i; + i = c.rbegin(); + assert(*i == 3.5); + *i = 5.5; + assert(c[2] == 5.5); + i = c.rend(); + assert(*--i == 1); + *i = 4; + assert(c[0] == 4); + } +#if TEST_STD_VER > 11 + { + constexpr int a = test_nonconst_constexpr_rbegin(); + static_assert(a == 1, ""); + + constexpr int b = test_nonconst_constexpr_rend(); + static_assert(b == 0, ""); + } +#endif +}